This commit is contained in:
Christoph Oelckers 2015-04-29 16:27:46 +02:00
commit 21993b3481
21 changed files with 148 additions and 153 deletions

View file

@ -677,6 +677,11 @@ public:
// Removes the item from the inventory list.
virtual void RemoveInventory (AInventory *item);
// Take the amount value of an item from the inventory list.
// If nothing is left, the item may be destroyed.
// Returns true if the initial item count is positive.
virtual bool TakeInventory (const PClass *itemclass, int amount, bool fromdecorate = false, bool notakeinfinite = false);
// Uses an item and removes it from the inventory.
virtual bool UseInventory (AInventory *item);

View file

@ -1981,6 +1981,9 @@ static void D_DoomInit()
}
FRandom::StaticClearRandom ();
Printf ("M_LoadDefaults: Load system defaults.\n");
M_LoadDefaults (); // load before initing other systems
}
//==========================================================================
@ -2247,8 +2250,8 @@ void D_DoomMain (void)
iwad_man = new FIWadManager;
iwad_man->ParseIWadInfos(basewad);
Printf ("M_LoadDefaults: Load system defaults.\n");
M_LoadDefaults (iwad_man); // load before initing other systems
// Now that we have the IWADINFO, initialize the autoload ini sections.
GameConfig->DoAutoloadSetup(iwad_man);
PClass::StaticInit ();
atterm(FinalGC);

View file

@ -137,14 +137,9 @@ bool P_MorphPlayer (player_t *activator, player_t *p, const PClass *spawntype, i
hxarmor->Slots[3] = 0;
hxarmor->Slots[4] = spawntype->Meta.GetMetaFixed (APMETA_Hexenarmor0);
}
else if (item->ItemFlags & IF_KEEPDEPLETED)
{
// Set depletable armor to 0 (this includes BasicArmor).
item->Amount = 0;
}
else
{
item->Destroy ();
item->DepleteOrDestroy();
}
}
item = next;

View file

@ -1131,6 +1131,32 @@ void AInventory::Destroy ()
if (SendItemDrop == this) SendItemDrop = NULL;
}
//===========================================================================
//
// AInventory :: DepleteOrDestroy
//
// If the item is depleted, just change its amount to 0, otherwise it's destroyed.
//
//===========================================================================
void AInventory::DepleteOrDestroy ()
{
// If it's not ammo or an internal armor, destroy it.
// Ammo needs to stick around, even when it's zero for the benefit
// of the weapons that use it and to maintain the maximum ammo
// amounts a backpack might have given.
// Armor shouldn't be removed because they only work properly when
// they are the last items in the inventory.
if (ItemFlags & IF_KEEPDEPLETED)
{
Amount = 0;
}
else
{
Destroy();
}
}
//===========================================================================
//
// AInventory :: GetBlend

View file

@ -151,6 +151,7 @@ public:
virtual void MarkPrecacheSounds() const;
virtual void BeginPlay ();
virtual void Destroy ();
virtual void DepleteOrDestroy ();
virtual void Tick ();
virtual bool ShouldRespawn ();
virtual bool ShouldStay ();

View file

@ -76,7 +76,7 @@ EXTERN_CVAR (Color, am_cdwallcolor)
EXTERN_CVAR (Float, spc_amp)
EXTERN_CVAR (Bool, wi_percents)
FGameConfigFile::FGameConfigFile (FIWadManager *iwad_man)
FGameConfigFile::FGameConfigFile ()
{
#ifdef __APPLE__
FString user_docs, user_app_support, local_app_support;
@ -161,6 +161,27 @@ FGameConfigFile::FGameConfigFile (FIWadManager *iwad_man)
SetValueForKey ("Path", "$DOOMWADDIR", true);
}
// Add some self-documentation.
SetSectionNote("IWADSearch.Directories",
"# These are the directories to automatically search for IWADs.\n"
"# Each directory should be on a separate line, preceded by Path=\n");
SetSectionNote("FileSearch.Directories",
"# These are the directories to search for wads added with the -file\n"
"# command line parameter, if they cannot be found with the path\n"
"# as-is. Layout is the same as for IWADSearch.Directories\n");
}
FGameConfigFile::~FGameConfigFile ()
{
}
void FGameConfigFile::WriteCommentHeader (FILE *file) const
{
fprintf (file, "# This file was generated by " GAMENAME " %s on %s\n", GetVersionString(), myasctime());
}
void FGameConfigFile::DoAutoloadSetup (FIWadManager *iwad_man)
{
// Create auto-load sections, so users know what's available.
// Note that this totem pole is the reverse of the order that
// they will appear in the file.
@ -220,14 +241,6 @@ FGameConfigFile::FGameConfigFile (FIWadManager *iwad_man)
MoveSectionToStart("FileSearch.Directories");
MoveSectionToStart("IWADSearch.Directories");
// Add some self-documentation.
SetSectionNote("IWADSearch.Directories",
"# These are the directories to automatically search for IWADs.\n"
"# Each directory should be on a separate line, preceded by Path=\n");
SetSectionNote("FileSearch.Directories",
"# These are the directories to search for wads added with the -file\n"
"# command line parameter, if they cannot be found with the path\n"
"# as-is. Layout is the same as for IWADSearch.Directories\n");
SetSectionNote("Doom.AutoExec",
"# Files to automatically execute when running the corresponding game.\n"
"# Each file should be on its own line, preceded by Path=\n\n");
@ -245,15 +258,6 @@ FGameConfigFile::FGameConfigFile (FIWadManager *iwad_man)
"# 'doom.doom2.commercial.Autoload' only when playing doom2.wad.\n\n");
}
FGameConfigFile::~FGameConfigFile ()
{
}
void FGameConfigFile::WriteCommentHeader (FILE *file) const
{
fprintf (file, "# This file was generated by " GAMENAME " %s on %s\n", GetVersionString(), myasctime());
}
void FGameConfigFile::DoGlobalSetup ()
{
if (SetSection ("GlobalSettings.Unknown"))

View file

@ -43,9 +43,10 @@ class FIWadManager;
class FGameConfigFile : public FConfigFile
{
public:
FGameConfigFile (FIWadManager *iwad_man);
FGameConfigFile ();
~FGameConfigFile ();
void DoAutoloadSetup (FIWadManager *iwad_man);
void DoGlobalSetup ();
void DoGameSetup (const char *gamename);
void DoKeySetup (const char *gamename);

View file

@ -768,11 +768,8 @@ void cht_Give (player_t *player, const char *name, int amount)
type->GetReplacement()->IsDescendantOf(RUNTIME_CLASS(ADehackedPickup))))
{
// Give the weapon only if it belongs to the current game or
// is in a weapon slot.
if (type->ActorInfo->GameFilter == GAME_Any ||
(type->ActorInfo->GameFilter & gameinfo.gametype) ||
player->weapons.LocateWeapon(type, NULL, NULL))
// Give the weapon only if it is in a weapon slot.
if (player->weapons.LocateWeapon(type, NULL, NULL))
{
AWeapon *def = (AWeapon*)GetDefaultByType (type);
if (giveall == ALL_YESYES || !(def->WeaponFlags & WIF_CHEATNOTWEAPON))
@ -1052,24 +1049,7 @@ void cht_Take (player_t *player, const char *name, int amount)
}
else
{
AInventory *inventory = player->mo->FindInventory (type);
if (inventory != NULL)
{
inventory->Amount -= amount ? amount : 1;
if (inventory->Amount <= 0)
{
if (inventory->ItemFlags & IF_KEEPDEPLETED)
{
inventory->Amount = 0;
}
else
{
inventory->Destroy ();
}
}
}
player->mo->TakeInventory(type, amount ? amount : 1);
}
return;
}

View file

@ -410,9 +410,9 @@ CCMD (writeini)
// M_LoadDefaults
//
void M_LoadDefaults (FIWadManager *iwad_man)
void M_LoadDefaults ()
{
GameConfig = new FGameConfigFile(iwad_man);
GameConfig = new FGameConfigFile;
GameConfig->DoGlobalSetup ();
atterm (M_SaveDefaultsFinal);
}

View file

@ -41,7 +41,7 @@ void M_FindResponseFile (void);
// Pass a NULL to get the original behavior.
void M_ScreenShot (const char *filename);
void M_LoadDefaults (FIWadManager *iwad_man);
void M_LoadDefaults ();
bool M_SaveDefaults (const char *filename);
void M_SaveCustomKeys (FConfigFile *config, char *section, char *subsection, size_t sublen);

View file

@ -1131,40 +1131,6 @@ static void GiveInventory (AActor *activator, const char *type, int amount)
}
}
//============================================================================
//
// DoTakeInv
//
// Takes an item from a single actor.
//
//============================================================================
static void DoTakeInv (AActor *actor, const PClass *info, int amount)
{
AInventory *item = actor->FindInventory (info);
if (item != NULL)
{
item->Amount -= amount;
if (item->Amount <= 0)
{
// If it's not ammo or an internal armor, destroy it.
// Ammo needs to stick around, even when it's zero for the benefit
// of the weapons that use it and to maintain the maximum ammo
// amounts a backpack might have given.
// Armor shouldn't be removed because they only work properly when
// they are the last items in the inventory.
if (item->ItemFlags & IF_KEEPDEPLETED)
{
item->Amount = 0;
}
else
{
item->Destroy ();
}
}
}
}
//============================================================================
//
// TakeInventory
@ -1199,12 +1165,12 @@ static void TakeInventory (AActor *activator, const char *type, int amount)
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i])
DoTakeInv (players[i].mo, info, amount);
players[i].mo->TakeInventory(info, amount);
}
}
else
{
DoTakeInv (activator, info, amount);
activator->TakeInventory(info, amount);
}
}
@ -2302,8 +2268,8 @@ void FBehavior::LoadScriptsDirectory ()
}
// [EP] Clang 3.5.0 optimizer miscompiles this function and causes random
// crashes in the program. I hope that Clang 3.5.x will fix this.
#if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ >= 5
// crashes in the program. This is fixed in 3.5.1 onwards.
#if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 5 && __clang_patchlevel__ == 0
asm("" : "+g" (NumScripts));
#endif
for (i = 0; i < NumScripts; ++i)
@ -4789,8 +4755,8 @@ static void SetActorTeleFog(AActor *activator, int tid, FString telefogsrc, FStr
FActorIterator iterator(tid);
AActor *actor;
const PClass * const src = telefogsrc.IsNotEmpty() ? PClass::FindClass(telefogsrc) : NULL;
const PClass * const dest = telefogdest.IsNotEmpty() ? PClass::FindClass(telefogdest) : NULL;
const PClass *src = PClass::FindClass(telefogsrc);
const PClass * dest = PClass::FindClass(telefogdest);
while ((actor = iterator.Next()))
{
if (telefogsrc.IsNotEmpty())

View file

@ -649,22 +649,7 @@ static void TakeStrifeItem (player_t *player, const PClass *itemtype, int amount
if (itemtype == RUNTIME_CLASS(ASigil))
return;
AInventory *item = player->mo->FindInventory (itemtype);
if (item != NULL)
{
item->Amount -= amount;
if (item->Amount <= 0)
{
if (item->ItemFlags & IF_KEEPDEPLETED)
{
item->Amount = 0;
}
else
{
item->Destroy ();
}
}
}
player->mo->TakeInventory(itemtype, amount);
}
CUSTOM_CVAR(Float, dlg_musicvolume, 1.0f, CVAR_ARCHIVE)

View file

@ -944,13 +944,13 @@ bool P_LoadGLNodes(MapData * map)
result=true;
for(unsigned i=0; i<4;i++)
{
if (strnicmp(f_gwa->GetLump(i+1)->Name, check[i], 8))
if (strnicmp(f_gwa->GetLump(li+i+1)->Name, check[i], 8))
{
result=false;
break;
}
else
gwalumps[i] = f_gwa->GetLump(i+1)->NewReader();
gwalumps[i] = f_gwa->GetLump(li+i+1)->NewReader();
}
if (result) result = DoLoadGLNodes(gwalumps);
}

View file

@ -804,10 +804,7 @@ static int UseHealthItems(TArray<AInventory *> &Items, int &saveHealth)
saveHealth -= maxhealth;
if (--Items[index]->Amount == 0)
{
if (!(Items[index]->ItemFlags & IF_KEEPDEPLETED))
{
Items[index]->Destroy ();
}
Items[index]->DepleteOrDestroy ();
Items.Delete(index);
break;
}

View file

@ -1034,7 +1034,7 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
// Both things overlap in x or y direction
bool unblocking = false;
if (tm.FromPMove || tm.thing->player != NULL)
if ((tm.FromPMove || tm.thing->player != NULL) && thing->flags&MF_SOLID)
{
// Both actors already overlap. To prevent them from remaining stuck allow the move if it
// takes them further apart or the move does not change the position (when called from P_ChangeSector.)
@ -1042,7 +1042,9 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
{
unblocking = true;
}
else
else if (abs(thing->x - tm.thing->x) < (thing->radius+tm.thing->radius)/2 &&
abs(thing->y - tm.thing->y) < (thing->radius+tm.thing->radius)/2)
{
fixed_t newdist = P_AproxDistance(thing->x - tm.x, thing->y - tm.y);
fixed_t olddist = P_AproxDistance(thing->x - tm.thing->x, thing->y - tm.thing->y);

View file

@ -591,6 +591,57 @@ void AActor::RemoveInventory(AInventory *item)
}
}
//============================================================================
//
// AActor :: TakeInventory
//
//============================================================================
bool AActor::TakeInventory(const PClass *itemclass, int amount, bool fromdecorate, bool notakeinfinite)
{
AInventory *item = FindInventory(itemclass);
if (item == NULL)
return false;
if (!fromdecorate)
{
item->Amount -= amount;
if (item->Amount <= 0)
{
item->DepleteOrDestroy();
}
// It won't be used in non-decorate context, so return false here
return false;
}
bool result = false;
if (item->Amount > 0)
{
result = true;
}
if (item->IsKindOf(RUNTIME_CLASS(AHexenArmor)))
return false;
// Do not take ammo if the "no take infinite/take as ammo depletion" flag is set
// and infinite ammo is on
if (notakeinfinite &&
((dmflags & DF_INFINITE_AMMO) || (player && player->cheats & CF_INFINITEAMMO)) &&
item->IsKindOf(RUNTIME_CLASS(AAmmo)))
{
// Nothing to do here, except maybe res = false;? Would it make sense?
}
else if (!amount || amount>=item->Amount)
{
item->DepleteOrDestroy();
}
else item->Amount-=amount;
return result;
}
//============================================================================
//
// AActor :: DestroyAllInventory
@ -658,9 +709,9 @@ bool AActor::UseInventory (AInventory *item)
if (dmflags2 & DF2_INFINITE_INVENTORY)
return true;
if (--item->Amount <= 0 && !(item->ItemFlags & IF_KEEPDEPLETED))
if (--item->Amount <= 0)
{
item->Destroy ();
item->DepleteOrDestroy ();
}
return true;
}

View file

@ -1833,6 +1833,11 @@ void P_LoadThings2 (MapData * map)
mti[i].SkillFilter = MakeSkill(mti[i].flags);
mti[i].ClassFilter = (mti[i].flags & MTF_CLASS_MASK) >> MTF_CLASS_SHIFT;
mti[i].flags &= ~(MTF_SKILLMASK|MTF_CLASS_MASK);
if (level.flags2 & LEVEL2_HEXENHACK)
{
mti[i].flags &= 0x7ff; // mask out Strife flags if playing an original Hexen map.
}
mti[i].gravity = FRACUNIT;
mti[i].RenderStyle = STYLE_Count;
mti[i].alpha = -1;

View file

@ -314,7 +314,7 @@ int FSectorTagIterator::Next()
while (start >= 0 && tagManager.allTags[start].tag != searchtag) start = tagManager.allTags[start].nexttag;
if (start == -1) return -1;
ret = tagManager.allTags[start].target;
start = start = tagManager.allTags[start].nexttag;
start = tagManager.allTags[start].nexttag;
}
return ret;
}
@ -348,6 +348,6 @@ int FLineIdIterator::Next()
while (start >= 0 && tagManager.allIDs[start].tag != searchtag) start = tagManager.allIDs[start].nexttag;
if (start == -1) return -1;
int ret = tagManager.allIDs[start].target;
start = start = tagManager.allIDs[start].nexttag;
start = tagManager.allIDs[start].nexttag;
return ret;
}

View file

@ -304,7 +304,7 @@ class FMODStreamCapsule : public SoundStream
public:
FMODStreamCapsule(FMOD::Sound *stream, FMODSoundRenderer *owner, const char *url)
: Owner(owner), Stream(NULL), Channel(NULL),
UserData(NULL), Callback(NULL), URL(url), Reader(NULL), Ended(false)
UserData(NULL), Callback(NULL), Reader(NULL), URL(url), Ended(false)
{
SetStream(stream);
}

View file

@ -1783,31 +1783,7 @@ void DoTakeInventory(AActor * receiver, bool use_aaptr, DECLARE_PARAMINFO)
COPY_AAPTR_NOT_NULL(receiver, receiver, setreceiver);
}
bool res = false;
AInventory * inv = receiver->FindInventory(item);
if (inv && !inv->IsKindOf(RUNTIME_CLASS(AHexenArmor)))
{
if (inv->Amount > 0)
{
res = true;
}
// Do not take ammo if the "no take infinite/take as ammo depletion" flag is set
// and infinite ammo is on
if (flags & TIF_NOTAKEINFINITE &&
((dmflags & DF_INFINITE_AMMO) || (receiver->player->cheats & CF_INFINITEAMMO)) &&
inv->IsKindOf(RUNTIME_CLASS(AAmmo)))
{
// Nothing to do here, except maybe res = false;? Would it make sense?
}
else if (!amount || amount>=inv->Amount)
{
if (inv->ItemFlags&IF_KEEPDEPLETED) inv->Amount=0;
else inv->Destroy();
}
else inv->Amount-=amount;
}
bool res = receiver->TakeInventory(item, amount, true, (flags & TIF_NOTAKEINFINITE) != 0);
ACTION_SET_RESULT(res);
}

View file

@ -1410,8 +1410,7 @@ DEFINE_PROPERTY(stamina, I, Actor)
DEFINE_PROPERTY(telefogsourcetype, S, Actor)
{
PROP_STRING_PARM(str, 0);
if (!stricmp(str, "") || !stricmp(str, "none")) defaults->TeleFogSourceType = NULL;
else defaults->TeleFogSourceType = FindClassTentative(str,"TeleportFog");
defaults->TeleFogSourceType = FindClassTentative(str,"Actor");
}
//==========================================================================
@ -1420,8 +1419,7 @@ DEFINE_PROPERTY(telefogsourcetype, S, Actor)
DEFINE_PROPERTY(telefogdesttype, S, Actor)
{
PROP_STRING_PARM(str, 0);
if (!stricmp(str, "") || !stricmp(str, "none")) defaults->TeleFogDestType = NULL;
else defaults->TeleFogDestType = FindClassTentative(str, "TeleportFog");
defaults->TeleFogDestType = FindClassTentative(str, "Actor");
}
//==========================================================================