diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index b602e5c44..1085c6ca7 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1238,8 +1238,8 @@ static int PatchThing (int thingy) else info->renderflags &= ~RF_INVISIBLE; } - DPrintf ("Bits: %d,%d (0x%08x,0x%08x)\n", info->flags, info->flags2, - info->flags, info->flags2); + DPrintf ("Bits: %d,%d (0x%08x,0x%08x)\n", info->flags.GetValue(), info->flags2.GetValue(), + info->flags.GetValue(), info->flags2.GetValue()); } else if (stricmp (Line1, "ID #") == 0) { diff --git a/src/p_acs.cpp b/src/p_acs.cpp index de484a5dd..5bbb657b2 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1391,7 +1391,7 @@ void FBehavior::StaticLoadDefaultModules () } else { - Printf ("Could not find autoloaded ACS library %s\n", sc.String); + Printf (TEXTCOLOR_RED "Could not find autoloaded ACS library %s\n", sc.String); } } } @@ -1409,7 +1409,17 @@ FBehavior *FBehavior::StaticLoadModule (int lumpnum, FileReader *fr, int len) } } - return new FBehavior (lumpnum, fr, len); + FBehavior * behavior = new FBehavior (); + if (behavior->Init(lumpnum, fr, len)) + { + return behavior; + } + else + { + delete behavior; + Printf(TEXTCOLOR_RED "%s: invalid ACS module", Wads.GetLumpFullName(lumpnum)); + return NULL; + } } bool FBehavior::StaticCheckAllGood () @@ -1668,11 +1678,8 @@ static int ParseLocalArrayChunk(void *chunk, ACSLocalArrays *arrays, int offset) return offset; } -FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) +FBehavior::FBehavior() { - BYTE *object; - int i; - NumScripts = 0; NumFunctions = 0; NumArrays = 0; @@ -1684,11 +1691,21 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) Chunks = NULL; Data = NULL; Format = ACS_Unknown; - LumpNum = lumpnum; + LumpNum = -1; memset (MapVarStore, 0, sizeof(MapVarStore)); ModuleName[0] = 0; FunctionProfileData = NULL; +} + + +bool FBehavior::Init(int lumpnum, FileReader * fr, int len) +{ + BYTE *object; + int i; + + LumpNum = lumpnum; + // Now that everything is set up, record this module as being among the loaded modules. // We need to do this before resolving any imports, because an import might (indirectly) // need to resolve exports in this module. The only things that can be exported are @@ -1699,7 +1716,6 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) // 1. If not, corrupt modules cause memory leaks // 2. Corrupt modules won't be reported when a level is being loaded if this function quits before // adding it to the list. - LibraryID = StaticModules.Push (this) << LIBRARYID_SHIFT; if (fr == NULL) len = Wads.LumpLength (lumpnum); @@ -1711,7 +1727,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) // has 24 bytes if it is completely empty. An empty SPTR chunk adds 8 bytes.) if (len < 32) { - return; + return false; } object = new BYTE[len]; @@ -1727,7 +1743,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) if (object[0] != 'A' || object[1] != 'C' || object[2] != 'S') { delete[] object; - return; + return false; } switch (object[3]) @@ -1743,8 +1759,9 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) break; default: delete[] object; - return; + return false; } + LibraryID = StaticModules.Push (this) << LIBRARYID_SHIFT; if (fr == NULL) { @@ -2027,7 +2044,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) int lump = Wads.CheckNumForName (&parse[i], ns_acslibrary); if (lump < 0) { - Printf ("Could not find ACS library %s.\n", &parse[i]); + Printf (TEXTCOLOR_RED "Could not find ACS library %s.\n", &parse[i]); } else { @@ -2068,7 +2085,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) func->ImportNum = i+1; if (realfunc->ArgCount != func->ArgCount) { - Printf ("Function %s in %s has %d arguments. %s expects it to have %d.\n", + Printf (TEXTCOLOR_ORANGE "Function %s in %s has %d arguments. %s expects it to have %d.\n", (char *)(chunk + 2) + chunk[3+j], lib->ModuleName, realfunc->ArgCount, ModuleName, func->ArgCount); Format = ACS_Unknown; @@ -2121,7 +2138,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) if (lib->ArrayStore[impNum].ArraySize != expectedSize) { Format = ACS_Unknown; - Printf ("The array %s in %s has %u elements, but %s expects it to only have %u.\n", + Printf (TEXTCOLOR_ORANGE "The array %s in %s has %u elements, but %s expects it to only have %u.\n", parse, lib->ModuleName, lib->ArrayStore[impNum].ArraySize, ModuleName, expectedSize); } @@ -2135,6 +2152,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) } DPrintf ("Loaded %d scripts, %d functions\n", NumScripts, NumFunctions); + return true; } FBehavior::~FBehavior () @@ -2293,7 +2311,7 @@ void FBehavior::LoadScriptsDirectory () { if (Scripts[i].Number == Scripts[i+1].Number) { - Printf("%s appears more than once.\n", + Printf(TEXTCOLOR_ORANGE "%s appears more than once.\n", ScriptPresentation(Scripts[i].Number).GetChars()); // Make the closed version the first one. if (Scripts[i+1].Type == SCRIPT_Closed) @@ -2490,7 +2508,7 @@ bool FBehavior::IsGood () if (funcdef->Address == 0 && funcdef->ImportNum == 0) { DWORD *chunk = (DWORD *)FindChunk (MAKE_ID('F','N','A','M')); - Printf ("Could not find ACS function %s for use in %s.\n", + Printf (TEXTCOLOR_RED "Could not find ACS function %s for use in %s.\n", (char *)(chunk + 2) + chunk[3+i], ModuleName); bad = true; } @@ -2501,7 +2519,7 @@ bool FBehavior::IsGood () { if (Imports[i] == NULL) { - Printf ("Not all the libraries used by %s could be found.\n", ModuleName); + Printf (TEXTCOLOR_RED "Not all the libraries used by %s could be found.\n", ModuleName); return false; } } diff --git a/src/p_acs.h b/src/p_acs.h index 88016f0db..d5971e349 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -283,8 +283,9 @@ enum ACSFormat { ACS_Old, ACS_Enhanced, ACS_LittleEnhanced, ACS_Unknown }; class FBehavior { public: - FBehavior (int lumpnum, FileReader * fr=NULL, int len=0); + FBehavior (); ~FBehavior (); + bool Init(int lumpnum, FileReader * fr = NULL, int len = 0); bool IsGood (); BYTE *FindChunk (DWORD id) const; diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index b68c4601d..d649ac671 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -655,7 +655,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) FState *diestate = NULL; int gibhealth = GetGibHealth(); - int iflags4 = inflictor == NULL ? 0 : inflictor->flags4; + ActorFlags4 iflags4 = inflictor == NULL ? ActorFlags4::FromInt(0) : inflictor->flags4; bool extremelydead = ((health < gibhealth || iflags4 & MF4_EXTREMEDEATH) && !(iflags4 & MF4_NOEXTREMEDEATH)); // Special check for 'extreme' damage type to ensure that it gets recorded properly as an extreme death for subsequent checks. diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 36d38dbd4..da2bef5a5 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6562,35 +6562,35 @@ void PrintMiscActorInfo(AActor *query) "OptFuzzy", "Stencil", "Translucent", "Add", "Shaded", "TranslucentStencil", "Shadow", "Subtract", "AddStencil", "AddShaded"}; - Printf("%s @ %p has the following flags:\n flags: %x", query->GetTag(), query, query->flags); + Printf("%s @ %p has the following flags:\n flags: %x", query->GetTag(), query, query->flags.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags & 1<flags2); + Printf("\n flags2: %x", query->flags2.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags2 & 1<flags3); + Printf("\n flags3: %x", query->flags3.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags3 & 1<flags4); + Printf("\n flags4: %x", query->flags4.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags4 & 1<flags5); + Printf("\n flags5: %x", query->flags5.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags5 & 1<flags6); + Printf("\n flags6: %x", query->flags6.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags6 & 1<flags7); + Printf("\n flags7: %x", query->flags7.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags7 & 1<BounceFlags, FIXED2FLOAT(query->bouncefactor), + query->BounceFlags.GetValue(), FIXED2FLOAT(query->bouncefactor), FIXED2FLOAT(query->wallbouncefactor)); /*for (flagi = 0; flagi < 31; flagi++) if (query->BounceFlags & 1<alpha), query->renderflags); + FIXED2FLOAT(query->alpha), query->renderflags.GetValue()); /*for (flagi = 0; flagi < 31; flagi++) if (query->renderflags & 1<RenderStyle = self->RenderStyle; } - if (flags & SIXF_TRANSFERSPRITEFRAME) - { - mo->sprite = self->sprite; - mo->frame = self->frame; + if (flags & SIXF_TRANSFERSPRITEFRAME) + { + mo->sprite = self->sprite; + mo->frame = self->frame; } if (flags & SIXF_TRANSFERROLL) @@ -6195,6 +6195,42 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ResetHealth) return 0; } +//=========================================================================== +// A_JumpIfHigherOrLower +// +// Jumps if a target, master, or tracer is higher or lower than the calling +// actor. Can also specify how much higher/lower the actor needs to be than +// itself. Can also take into account the height of the actor in question, +// depending on which it's checking. This means adding height of the +// calling actor's self if the pointer is higher, or height of the pointer +// if its lower. +//=========================================================================== + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHigherOrLower) +{ + PARAM_ACTION_PROLOGUE; + PARAM_STATE(high); + PARAM_STATE(low); + PARAM_FIXED_OPT(offsethigh) { offsethigh = 0; } + PARAM_FIXED_OPT(offsetlow) { offsetlow = 0; } + PARAM_BOOL_OPT(includeHeight) { includeHeight = true; } + PARAM_INT_OPT(ptr) { ptr = AAPTR_TARGET; } + + AActor *mobj = COPY_AAPTR(self, ptr); + + + ACTION_SET_RESULT(false); //No inventory jump chains please. + if (mobj != NULL && mobj != self) //AAPTR_DEFAULT is completely useless in this regard. + { + if ((high) && (mobj->z > ((includeHeight ? self->height : 0) + self->z + offsethigh))) + ACTION_JUMP(high); + else if ((low) && (mobj->z + (includeHeight ? mobj->height : 0)) < (self->z + offsetlow)) + ACTION_JUMP(low); + } + return numret; +} + + //=========================================================================== // // A_SetRipperLevel(int level) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index b544128cb..9ee768749 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -437,7 +437,8 @@ struct acttab { #define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) /* Free all memory associated with the given acttab */ -void acttab_free(acttab *p){ +void acttab_free(acttab **pp){ + acttab *p = *pp; free( p->aAction ); free( p->aLookahead ); free( p ); @@ -3127,9 +3128,11 @@ struct lemon *lemp; in = fopen(tpltname,"rb"); if( in==0 ){ fprintf(stderr,"Can't open the template file \"%s\".\n",templatename); + free(tpltname); lemp->errorcnt++; return 0; } + free(tpltname); return in; } @@ -4016,6 +4019,7 @@ int mhflag; /* Output in makeheaders format if true */ /* Append any addition code the user desires */ tplt_print(out,lemp,lemp->extracode,&lineno); + acttab_free(&pActtab); fclose(in); fclose(out); return; diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index ee07b270a..ccb66ab3f 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -298,6 +298,7 @@ ACTOR Actor native //: Thinker action native A_SetFloatBobPhase(int bob); action native A_SetHealth(int health, int ptr = AAPTR_DEFAULT); action native A_ResetHealth(int ptr = AAPTR_DEFAULT); + action native A_JumpIfHigherOrLower(state high, state low, float offsethigh = 0, float offsetlow = 0, bool includeHeight = true, int ptr = AAPTR_TARGET); action native A_SetRipperLevel(int level); action native A_SetRipMin(int min); action native A_SetRipMax(int max);