mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- Fixed: The save percentage for Doom's green armor was slightly too low
which caused roundoff errors that made it less than 1/3 effective. - Added support for "RRGGBB" strings to V_GetColor. - Fixed: Desaturation maps for the TEXTURES lump were calculated incorrectly. - Changed GetSpriteIndex to cache the last used sprite name so that the code using this function doesn't have to do it itself. - Moved some more code for the state parser into p_states.cpp. - Fixed: TDeletingArray should not try to delete NULL pointers. SVN r1312 (trunk)
This commit is contained in:
parent
238de9cda1
commit
081658d3d5
24 changed files with 2428 additions and 2351 deletions
|
@ -1,3 +1,13 @@
|
|||
December 7, 2008 (Changes by Graf Zahl)
|
||||
- Fixed: The save percentage for Doom's green armor was slightly too low
|
||||
which caused roundoff errors that made it less than 1/3 effective.
|
||||
- Added support for "RRGGBB" strings to V_GetColor.
|
||||
- Fixed: Desaturation maps for the TEXTURES lump were calculated incorrectly.
|
||||
- Changed GetSpriteIndex to cache the last used sprite name so that the code
|
||||
using this function doesn't have to do it itself.
|
||||
- Moved some more code for the state parser into p_states.cpp.
|
||||
- Fixed: TDeletingArray should not try to delete NULL pointers.
|
||||
|
||||
December 6, 2008
|
||||
- Added binary (b) and hexadecimal (x) cast types for ACS's various print
|
||||
statements.
|
||||
|
|
|
@ -820,31 +820,31 @@ static int PatchThing (int thingy)
|
|||
}
|
||||
|
||||
if (!strnicmp (Line1, "Initial", 7))
|
||||
statedef.AddState("Spawn", state ? state : GetDefault<AActor>()->SpawnState);
|
||||
statedef.SetStateLabel("Spawn", state ? state : GetDefault<AActor>()->SpawnState);
|
||||
else if (!strnicmp (Line1, "First moving", 12))
|
||||
statedef.AddState("See", state);
|
||||
statedef.SetStateLabel("See", state);
|
||||
else if (!strnicmp (Line1, "Injury", 6))
|
||||
statedef.AddState("Pain", state);
|
||||
statedef.SetStateLabel("Pain", state);
|
||||
else if (!strnicmp (Line1, "Close attack", 12))
|
||||
{
|
||||
if (thingy != 1) // Not for players!
|
||||
{
|
||||
statedef.AddState("Melee", state);
|
||||
statedef.SetStateLabel("Melee", state);
|
||||
}
|
||||
}
|
||||
else if (!strnicmp (Line1, "Far attack", 10))
|
||||
{
|
||||
if (thingy != 1) // Not for players!
|
||||
{
|
||||
statedef.AddState("Missile", state);
|
||||
statedef.SetStateLabel("Missile", state);
|
||||
}
|
||||
}
|
||||
else if (!strnicmp (Line1, "Death", 5))
|
||||
statedef.AddState("Death", state);
|
||||
statedef.SetStateLabel("Death", state);
|
||||
else if (!strnicmp (Line1, "Exploding", 9))
|
||||
statedef.AddState("XDeath", state);
|
||||
statedef.SetStateLabel("XDeath", state);
|
||||
else if (!strnicmp (Line1, "Respawn", 7))
|
||||
statedef.AddState("Raise", state);
|
||||
statedef.SetStateLabel("Raise", state);
|
||||
}
|
||||
else if (stricmp (Line1 + linelen - 6, " sound") == 0)
|
||||
{
|
||||
|
@ -1394,15 +1394,15 @@ static int PatchWeapon (int weapNum)
|
|||
}
|
||||
|
||||
if (strnicmp (Line1, "Deselect", 8) == 0)
|
||||
statedef.AddState("Select", state);
|
||||
statedef.SetStateLabel("Select", state);
|
||||
else if (strnicmp (Line1, "Select", 6) == 0)
|
||||
statedef.AddState("Deselect", state);
|
||||
statedef.SetStateLabel("Deselect", state);
|
||||
else if (strnicmp (Line1, "Bobbing", 7) == 0)
|
||||
statedef.AddState("Ready", state);
|
||||
statedef.SetStateLabel("Ready", state);
|
||||
else if (strnicmp (Line1, "Shooting", 8) == 0)
|
||||
statedef.AddState("Fire", state);
|
||||
statedef.SetStateLabel("Fire", state);
|
||||
else if (strnicmp (Line1, "Firing", 6) == 0)
|
||||
statedef.AddState("Flash", state);
|
||||
statedef.SetStateLabel("Flash", state);
|
||||
}
|
||||
else if (stricmp (Line1, "Ammo type") == 0)
|
||||
{
|
||||
|
|
16
src/info.cpp
16
src/info.cpp
|
@ -58,6 +58,9 @@ extern void LoadActors ();
|
|||
|
||||
int GetSpriteIndex(const char * spritename)
|
||||
{
|
||||
static char lastsprite[5];
|
||||
static int lastindex;
|
||||
|
||||
// Make sure that the string is upper case and 4 characters long
|
||||
char upper[5]={0,0,0,0,0};
|
||||
for (int i = 0; spritename[i] != 0 && i < 4; i++)
|
||||
|
@ -65,18 +68,25 @@ int GetSpriteIndex(const char * spritename)
|
|||
upper[i] = toupper (spritename[i]);
|
||||
}
|
||||
|
||||
// cache the name so if the next one is the same the function doesn't have to perform a search.
|
||||
if (!strcmp(upper, lastsprite))
|
||||
{
|
||||
return lastindex;
|
||||
}
|
||||
strcpy(lastsprite, upper);
|
||||
|
||||
for (unsigned i = 0; i < sprites.Size (); ++i)
|
||||
{
|
||||
if (strcmp (sprites[i].name, spritename) == 0)
|
||||
if (strcmp (sprites[i].name, upper) == 0)
|
||||
{
|
||||
return (int)i;
|
||||
return (lastindex = (int)i);
|
||||
}
|
||||
}
|
||||
spritedef_t temp;
|
||||
strcpy (temp.name, upper);
|
||||
temp.numframes = 0;
|
||||
temp.spriteframes = 0;
|
||||
return (int)sprites.Push (temp);
|
||||
return (lastindex = (int)sprites.Push (temp));
|
||||
}
|
||||
|
||||
|
||||
|
|
31
src/info.h
31
src/info.h
|
@ -29,37 +29,6 @@
|
|||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
** Important restrictions because of the way FState is structured:
|
||||
**
|
||||
** The range of Frame is [0,63]. Since sprite naming conventions
|
||||
** are even more restrictive than this, this isn't something to
|
||||
** really worry about.
|
||||
**
|
||||
** The range of Tics is [-1,65534]. If Misc1 is important, then
|
||||
** the range of Tics is reduced to [-1,254], because Misc1 also
|
||||
** doubles as the high byte of the tic.
|
||||
**
|
||||
** The range of Misc1 is [-128,127] and Misc2's range is [0,255].
|
||||
**
|
||||
** When compiled with Visual C++, this struct is 16 bytes. With
|
||||
** any other compiler (assuming a 32-bit architecture), it is 20 bytes.
|
||||
** This is because with VC++, I can use the charizing operator to
|
||||
** initialize the name array to exactly 4 chars. If GCC would
|
||||
** compile something like char t = "PLYR"[0]; as char t = 'P'; then GCC
|
||||
** could also use the 16-byte version. Unfortunately, GCC compiles it
|
||||
** more like:
|
||||
**
|
||||
** char t;
|
||||
** void initializer () {
|
||||
** static const char str[]="PLYR";
|
||||
** t = str[0];
|
||||
** }
|
||||
**
|
||||
** While this does allow the use of a 16-byte FState, the additional
|
||||
** code amounts to more than 4 bytes.
|
||||
**
|
||||
** If C++ would allow char name[4] = "PLYR"; without an error (as C does),
|
||||
** I could just initialize the name as a regular string and be done with it.
|
||||
*/
|
||||
|
||||
#ifndef __INFO_H__
|
||||
|
|
152
src/p_states.cpp
152
src/p_states.cpp
|
@ -366,17 +366,33 @@ FStateDefine * FStateDefinitions::FindStateAddress(const char *name)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// Adds a new state tp the curremt list
|
||||
// Adds a new state to the curremt list
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FStateDefinitions::AddState (const char *statename, FState *state, BYTE defflags)
|
||||
void FStateDefinitions::SetStateLabel (const char *statename, FState *state, BYTE defflags)
|
||||
{
|
||||
FStateDefine *std = FindStateAddress(statename);
|
||||
std->State = state;
|
||||
std->DefineFlags = defflags;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Adds a new state to the curremt list
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FStateDefinitions::AddStateLabel (const char *statename)
|
||||
{
|
||||
intptr_t index = StateArray.Size();
|
||||
FStateDefine *std = FindStateAddress(statename);
|
||||
std->State = (FState *)(index+1);
|
||||
std->DefineFlags = SDF_INDEX;
|
||||
laststate = NULL;
|
||||
lastlabel = index;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Finds the state associated with the given name
|
||||
|
@ -457,7 +473,7 @@ void FStateDefinitions::InstallStates(FActorInfo *info, AActor *defaults)
|
|||
if (state == NULL)
|
||||
{
|
||||
// A NULL spawn state will crash the engine so set it to something valid.
|
||||
AddState("Spawn", GetDefault<AActor>()->SpawnState);
|
||||
SetStateLabel("Spawn", GetDefault<AActor>()->SpawnState);
|
||||
}
|
||||
|
||||
if (info->StateList != NULL)
|
||||
|
@ -505,13 +521,17 @@ void FStateDefinitions::MakeStateList(const FStateLabels *list, TArray<FStateDef
|
|||
|
||||
void FStateDefinitions::MakeStateDefines(const PClass *cls)
|
||||
{
|
||||
if (cls->ActorInfo && cls->ActorInfo->StateList)
|
||||
StateArray.Clear();
|
||||
laststate = NULL;
|
||||
lastlabel = -1;
|
||||
|
||||
if (cls != NULL && cls->ActorInfo != NULL && cls->ActorInfo->StateList != NULL)
|
||||
{
|
||||
MakeStateList(cls->ActorInfo->StateList, StateLabels);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearStateLabels();
|
||||
StateLabels.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -559,7 +579,7 @@ void FStateDefinitions::RetargetStatePointers (intptr_t count, const char *targe
|
|||
{
|
||||
for(unsigned i = 0;i<statelist.Size(); i++)
|
||||
{
|
||||
if (statelist[i].State == (FState*)count)
|
||||
if (statelist[i].State == (FState*)count && statelist[i].DefineFlags == SDF_INDEX)
|
||||
{
|
||||
if (target == NULL)
|
||||
{
|
||||
|
@ -709,6 +729,118 @@ void FStateDefinitions::ResolveGotoLabels (FActorInfo *actor, AActor *defaults,
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SetGotoLabel
|
||||
//
|
||||
// sets a jump at the current state or retargets a label
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FStateDefinitions::SetGotoLabel(const char *string)
|
||||
{
|
||||
// copy the text - this must be resolved later!
|
||||
if (laststate != NULL)
|
||||
{ // Following a state definition: Modify it.
|
||||
laststate->NextState = (FState*)copystring(string);
|
||||
laststate->DefineFlags = SDF_LABEL;
|
||||
return true;
|
||||
}
|
||||
else if (lastlabel >= 0)
|
||||
{ // Following a label: Retarget it.
|
||||
RetargetStates (lastlabel+1, string);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SetStop
|
||||
//
|
||||
// sets a stop operation
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FStateDefinitions::SetStop()
|
||||
{
|
||||
if (laststate != NULL)
|
||||
{
|
||||
laststate->DefineFlags = SDF_STOP;
|
||||
return true;
|
||||
}
|
||||
else if (lastlabel >=0)
|
||||
{
|
||||
RetargetStates (lastlabel+1, NULL);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SetWait
|
||||
//
|
||||
// sets a wait or fail operation
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FStateDefinitions::SetWait()
|
||||
{
|
||||
if (laststate != NULL)
|
||||
{
|
||||
laststate->DefineFlags = SDF_WAIT;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SetLoop
|
||||
//
|
||||
// sets a loop operation
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FStateDefinitions::SetLoop()
|
||||
{
|
||||
if (laststate != NULL)
|
||||
{
|
||||
laststate->DefineFlags = SDF_INDEX;
|
||||
laststate->NextState = (FState*)(lastlabel+1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// AddStates
|
||||
// adds some state to the current definition set
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FStateDefinitions::AddStates(FState *state, const char *framechars)
|
||||
{
|
||||
bool error = false;
|
||||
while (*framechars)
|
||||
{
|
||||
int frame=((*framechars++)&223)-'A';
|
||||
|
||||
if (frame<0 || frame>28)
|
||||
{
|
||||
frame = 0;
|
||||
error = true;
|
||||
}
|
||||
|
||||
state->Frame=(state->Frame&(SF_FULLBRIGHT))|frame;
|
||||
StateArray.Push(*state);
|
||||
}
|
||||
laststate = &StateArray[StateArray.Size() - 1];
|
||||
return !error;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FinishStates
|
||||
|
@ -716,7 +848,7 @@ void FStateDefinitions::ResolveGotoLabels (FActorInfo *actor, AActor *defaults,
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FStateDefinitions::FinishStates (FActorInfo *actor, AActor *defaults, TArray<FState> &StateArray)
|
||||
int FStateDefinitions::FinishStates (FActorInfo *actor, AActor *defaults)
|
||||
{
|
||||
static int c=0;
|
||||
int count = StateArray.Size();
|
||||
|
@ -770,6 +902,12 @@ int FStateDefinitions::FinishStates (FActorInfo *actor, AActor *defaults, TArray
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Prints all state label info to the logfile
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DumpStateHelper(FStateLabels *StateList, const FString &prefix)
|
||||
{
|
||||
for (int i = 0; i < StateList->NumLabels; i++)
|
||||
|
|
|
@ -911,12 +911,12 @@ FString FScanner::TokenName (int token, const char *string)
|
|||
"'global'",
|
||||
"'self'",
|
||||
"'stop'",
|
||||
"'pickup'",
|
||||
"'breakable'",
|
||||
"'projectile'",
|
||||
"'#include'",
|
||||
"'fixed_t'",
|
||||
"'angle_t'",
|
||||
"'abs'",
|
||||
"'random'",
|
||||
"'random2'"
|
||||
};
|
||||
|
||||
FString work;
|
||||
|
|
10
src/sc_man.h
10
src/sc_man.h
|
@ -29,7 +29,7 @@ public:
|
|||
const SavedPos SavePos();
|
||||
void RestorePos(const SavedPos &pos);
|
||||
|
||||
FString TokenName(int token, const char *string=NULL);
|
||||
static FString TokenName(int token, const char *string=NULL);
|
||||
|
||||
bool GetString();
|
||||
void MustGetString();
|
||||
|
@ -203,14 +203,12 @@ enum
|
|||
TK_Global,
|
||||
TK_Self,
|
||||
TK_Stop,
|
||||
TK_Eval,
|
||||
TK_EvalNot,
|
||||
TK_Pickup,
|
||||
TK_Breakable,
|
||||
TK_Projectile,
|
||||
TK_Include,
|
||||
TK_Fixed_t,
|
||||
TK_Angle_t,
|
||||
TK_Abs,
|
||||
TK_Random,
|
||||
TK_Random2,
|
||||
|
||||
TK_LastToken
|
||||
};
|
||||
|
|
3799
src/sc_man_scanner.h
3799
src/sc_man_scanner.h
File diff suppressed because it is too large
Load diff
|
@ -142,11 +142,11 @@ std2:
|
|||
|
||||
/* other DECORATE top level keywords */
|
||||
'#include' { RET(TK_Include); }
|
||||
'pickup' { RET(TK_Pickup); }
|
||||
'breakable' { RET(TK_Breakable); }
|
||||
'projectile' { RET(TK_Projectile); }
|
||||
'fixed_t' { RET(TK_Fixed_t); }
|
||||
'angle_t' { RET(TK_Angle_t); }
|
||||
'abs' { RET(TK_Abs); }
|
||||
'random' { RET(TK_Random); }
|
||||
'random2' { RET(TK_Random2); }
|
||||
|
||||
L (L|D)* { RET(TK_Identifier); }
|
||||
|
||||
|
|
|
@ -299,7 +299,8 @@ public:
|
|||
{
|
||||
for (unsigned int i = 0; i < TArray<T,TT>::Size(); ++i)
|
||||
{
|
||||
delete (*this)[i];
|
||||
if ((*this)[i] != NULL)
|
||||
delete (*this)[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -443,7 +443,7 @@ BYTE * GetBlendMap(PalEntry blend, BYTE *blendwork)
|
|||
default:
|
||||
if (blend.r >= BLEND_DESATURATE1 && blend.r <= BLEND_DESATURATE31)
|
||||
{
|
||||
return DesaturateColormap[blend - BLEND_DESATURATE1];
|
||||
return DesaturateColormap[blend.r - BLEND_DESATURATE1];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -509,7 +509,7 @@ void FMultiPatchTexture::MakeTexture ()
|
|||
trans = NullMap;
|
||||
hasTranslucent = true;
|
||||
}
|
||||
else if (Parts[i].Blend != BLEND_NONE)
|
||||
else if (Parts[i].Blend != 0)
|
||||
{
|
||||
trans = GetBlendMap(Parts[i].Blend, blendwork);
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ IMPLEMENT_CLASS (AFakeInventory)
|
|||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
|
||||
FExtraInfo &extra, EDefinitionType def, FScanner &sc);
|
||||
FExtraInfo &extra, EDefinitionType def, FScanner &sc, TArray<FState> &StateArray);
|
||||
static void ParseSpriteFrames (FActorInfo *info, TArray<FState> &states, FScanner &sc);
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
@ -134,6 +134,7 @@ static const char *RenderStyles[] =
|
|||
void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
||||
{
|
||||
Baggage bag;
|
||||
TArray<FState> StateArray;
|
||||
FExtraInfo extra;
|
||||
FActorInfo *info;
|
||||
PClass *type;
|
||||
|
@ -156,9 +157,9 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
sc.MustGetStringName("{");
|
||||
|
||||
memset (&extra, 0, sizeof(extra));
|
||||
ParseInsideDecoration (bag, (AActor *)(type->Defaults), extra, def, sc);
|
||||
ParseInsideDecoration (bag, (AActor *)(type->Defaults), extra, def, sc, StateArray);
|
||||
|
||||
bag.Info->NumOwnedStates = bag.StateArray.Size();
|
||||
bag.Info->NumOwnedStates = StateArray.Size();
|
||||
if (bag.Info->NumOwnedStates == 0)
|
||||
{
|
||||
sc.ScriptError ("%s does not define any animation frames", typeName.GetChars() );
|
||||
|
@ -179,13 +180,13 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
if (extra.IceDeathEnd != 0)
|
||||
{
|
||||
// Make a copy of the final frozen frame for A_FreezeDeathChunks
|
||||
FState icecopy = bag.StateArray[extra.IceDeathEnd-1];
|
||||
bag.StateArray.Push (icecopy);
|
||||
FState icecopy = StateArray[extra.IceDeathEnd-1];
|
||||
StateArray.Push (icecopy);
|
||||
info->NumOwnedStates += 1;
|
||||
}
|
||||
|
||||
info->OwnedStates = new FState[info->NumOwnedStates];
|
||||
memcpy (info->OwnedStates, &bag.StateArray[0], info->NumOwnedStates * sizeof(info->OwnedStates[0]));
|
||||
memcpy (info->OwnedStates, &StateArray[0], info->NumOwnedStates * sizeof(info->OwnedStates[0]));
|
||||
if (info->NumOwnedStates == 1)
|
||||
{
|
||||
info->OwnedStates->Tics = -1;
|
||||
|
@ -246,7 +247,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
if (extra.DeathHeight == 0) extra.DeathHeight = ((AActor*)(type->Defaults))->height;
|
||||
info->Class->Meta.SetMetaFixed (AMETA_DeathHeight, extra.DeathHeight);
|
||||
}
|
||||
bag.statedef.AddState("Death", &info->OwnedStates[extra.DeathStart]);
|
||||
bag.statedef.SetStateLabel("Death", &info->OwnedStates[extra.DeathStart]);
|
||||
}
|
||||
|
||||
// Burn states are the same as death states, except they can optionally terminate
|
||||
|
@ -284,7 +285,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
if (extra.BurnHeight == 0) extra.BurnHeight = ((AActor*)(type->Defaults))->height;
|
||||
type->Meta.SetMetaFixed (AMETA_BurnHeight, extra.BurnHeight);
|
||||
|
||||
bag.statedef.AddState("Burn", &info->OwnedStates[extra.FireDeathStart]);
|
||||
bag.statedef.SetStateLabel("Burn", &info->OwnedStates[extra.FireDeathStart]);
|
||||
}
|
||||
|
||||
// Ice states are similar to burn and death, except their final frame enters
|
||||
|
@ -305,11 +306,11 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
info->OwnedStates[i].Tics = 1;
|
||||
info->OwnedStates[i].Misc1 = 0;
|
||||
info->OwnedStates[i].SetAction(FindGlobalActionFunction("A_FreezeDeathChunks"));
|
||||
bag.statedef.AddState("Ice", &info->OwnedStates[extra.IceDeathStart]);
|
||||
bag.statedef.SetStateLabel("Ice", &info->OwnedStates[extra.IceDeathStart]);
|
||||
}
|
||||
else if (extra.bGenericIceDeath)
|
||||
{
|
||||
bag.statedef.AddState("Ice", RUNTIME_CLASS(AActor)->ActorInfo->FindState(NAME_GenericFreezeDeath));
|
||||
bag.statedef.SetStateLabel("Ice", RUNTIME_CLASS(AActor)->ActorInfo->FindState(NAME_GenericFreezeDeath));
|
||||
}
|
||||
}
|
||||
if (def == DEF_BreakableDecoration)
|
||||
|
@ -320,7 +321,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
{
|
||||
((AActor *)(type->Defaults))->flags |= MF_DROPOFF|MF_MISSILE;
|
||||
}
|
||||
bag.statedef.AddState("Spawn", &info->OwnedStates[extra.SpawnStart]);
|
||||
bag.statedef.SetStateLabel("Spawn", &info->OwnedStates[extra.SpawnStart]);
|
||||
bag.statedef.InstallStates (info, ((AActor *)(type->Defaults)));
|
||||
}
|
||||
|
||||
|
@ -333,7 +334,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
//==========================================================================
|
||||
|
||||
static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
|
||||
FExtraInfo &extra, EDefinitionType def, FScanner &sc)
|
||||
FExtraInfo &extra, EDefinitionType def, FScanner &sc, TArray<FState> &StateArray)
|
||||
{
|
||||
AFakeInventory *const inv = static_cast<AFakeInventory *>(defaults);
|
||||
char sprite[5] = "TNT1";
|
||||
|
@ -382,31 +383,31 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
|
|||
else if (sc.Compare ("Frames"))
|
||||
{
|
||||
sc.MustGetString ();
|
||||
extra.SpawnStart = bag.StateArray.Size();
|
||||
ParseSpriteFrames (bag.Info, bag.StateArray, sc);
|
||||
extra.SpawnEnd = bag.StateArray.Size();
|
||||
extra.SpawnStart = StateArray.Size();
|
||||
ParseSpriteFrames (bag.Info, StateArray, sc);
|
||||
extra.SpawnEnd = StateArray.Size();
|
||||
}
|
||||
else if ((def == DEF_BreakableDecoration || def == DEF_Projectile) &&
|
||||
sc.Compare ("DeathFrames"))
|
||||
{
|
||||
sc.MustGetString ();
|
||||
extra.DeathStart = bag.StateArray.Size();
|
||||
ParseSpriteFrames (bag.Info, bag.StateArray, sc);
|
||||
extra.DeathEnd = bag.StateArray.Size();
|
||||
extra.DeathStart = StateArray.Size();
|
||||
ParseSpriteFrames (bag.Info, StateArray, sc);
|
||||
extra.DeathEnd = StateArray.Size();
|
||||
}
|
||||
else if (def == DEF_BreakableDecoration && sc.Compare ("IceDeathFrames"))
|
||||
{
|
||||
sc.MustGetString ();
|
||||
extra.IceDeathStart = bag.StateArray.Size();
|
||||
ParseSpriteFrames (bag.Info, bag.StateArray, sc);
|
||||
extra.IceDeathEnd = bag.StateArray.Size();
|
||||
extra.IceDeathStart = StateArray.Size();
|
||||
ParseSpriteFrames (bag.Info, StateArray, sc);
|
||||
extra.IceDeathEnd = StateArray.Size();
|
||||
}
|
||||
else if (def == DEF_BreakableDecoration && sc.Compare ("BurnDeathFrames"))
|
||||
{
|
||||
sc.MustGetString ();
|
||||
extra.FireDeathStart = bag.StateArray.Size();
|
||||
ParseSpriteFrames (bag.Info, bag.StateArray, sc);
|
||||
extra.FireDeathEnd = bag.StateArray.Size();
|
||||
extra.FireDeathStart = StateArray.Size();
|
||||
ParseSpriteFrames (bag.Info, StateArray, sc);
|
||||
extra.FireDeathEnd = StateArray.Size();
|
||||
}
|
||||
else if (def == DEF_BreakableDecoration && sc.Compare ("GenericIceDeath"))
|
||||
{
|
||||
|
@ -587,16 +588,16 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
|
|||
unsigned int i;
|
||||
int spr = GetSpriteIndex(sprite);
|
||||
|
||||
for (i = 0; i < bag.StateArray.Size(); ++i)
|
||||
for (i = 0; i < StateArray.Size(); ++i)
|
||||
{
|
||||
bag.StateArray[i].sprite = spr;
|
||||
StateArray[i].sprite = spr;
|
||||
}
|
||||
if (extra.DeathSprite[0] && extra.DeathEnd != 0)
|
||||
{
|
||||
int spr = GetSpriteIndex(extra.DeathSprite);
|
||||
for (i = extra.DeathStart; i < extra.DeathEnd; ++i)
|
||||
{
|
||||
bag.StateArray[i].sprite = spr;
|
||||
StateArray[i].sprite = spr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,8 +78,7 @@ PSymbolTable GlobalSymbols;
|
|||
// Starts a new actor definition
|
||||
//
|
||||
//==========================================================================
|
||||
FActorInfo *CreateNewActor(const FScriptPosition &sc, FName typeName, FName parentName, FName replaceName,
|
||||
int DoomEdNum, bool native)
|
||||
FActorInfo *CreateNewActor(FName typeName, FName parentName, bool native)
|
||||
{
|
||||
const PClass *replacee = NULL;
|
||||
PClass *ti = NULL;
|
||||
|
@ -93,31 +92,15 @@ FActorInfo *CreateNewActor(const FScriptPosition &sc, FName typeName, FName pare
|
|||
|
||||
if (parent == NULL)
|
||||
{
|
||||
sc.Message(MSG_FATAL, "Parent type '%s' not found in %s", parentName.GetChars(), typeName.GetChars());
|
||||
I_Error( "Parent type '%s' not found in %s", parentName.GetChars(), typeName.GetChars());
|
||||
}
|
||||
else if (!parent->IsDescendantOf(RUNTIME_CLASS(AActor)))
|
||||
{
|
||||
sc.Message(MSG_FATAL, "Parent type '%s' is not an actor in %s", parentName.GetChars(), typeName.GetChars());
|
||||
I_Error( "Parent type '%s' is not an actor in %s", parentName.GetChars(), typeName.GetChars());
|
||||
}
|
||||
else if (parent->ActorInfo == NULL)
|
||||
{
|
||||
sc.Message(MSG_FATAL, "uninitialized parent type '%s' in %s", parentName.GetChars(), typeName.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
// Check for "replaces"
|
||||
if (replaceName != NAME_None)
|
||||
{
|
||||
// Get actor name
|
||||
replacee = PClass::FindClass (replaceName);
|
||||
|
||||
if (replacee == NULL)
|
||||
{
|
||||
sc.Message(MSG_FATAL, "Replaced type '%s' not found in %s", replaceName.GetChars(), typeName.GetChars());
|
||||
}
|
||||
else if (replacee->ActorInfo == NULL)
|
||||
{
|
||||
sc.Message(MSG_FATAL, "Replaced type '%s' is not an actor in %s", replaceName.GetChars(), typeName.GetChars());
|
||||
I_Error( "uninitialized parent type '%s' in %s", parentName.GetChars(), typeName.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,15 +109,15 @@ FActorInfo *CreateNewActor(const FScriptPosition &sc, FName typeName, FName pare
|
|||
ti = (PClass*)PClass::FindClass(typeName);
|
||||
if (ti == NULL)
|
||||
{
|
||||
sc.Message(MSG_FATAL, "Unknown native class '%s'", typeName.GetChars());
|
||||
I_Error( "Unknown native class '%s'", typeName.GetChars());
|
||||
}
|
||||
else if (ti != RUNTIME_CLASS(AActor) && ti->ParentClass->NativeClass() != parent->NativeClass())
|
||||
{
|
||||
sc.Message(MSG_FATAL, "Native class '%s' does not inherit from '%s'", typeName.GetChars(), parentName.GetChars());
|
||||
I_Error( "Native class '%s' does not inherit from '%s'", typeName.GetChars(), parentName.GetChars());
|
||||
}
|
||||
else if (ti->ActorInfo != NULL)
|
||||
{
|
||||
sc.Message(MSG_FATAL, "Redefinition of internal class '%s'", typeName.GetChars());
|
||||
I_Error( "Redefinition of internal class '%s'", typeName.GetChars());
|
||||
}
|
||||
ti->InitializeActorInfo();
|
||||
info = ti->ActorInfo;
|
||||
|
@ -145,7 +128,6 @@ FActorInfo *CreateNewActor(const FScriptPosition &sc, FName typeName, FName pare
|
|||
info = ti->ActorInfo;
|
||||
}
|
||||
|
||||
info->DoomEdNum = -1;
|
||||
if (parent->ActorInfo->DamageFactors != NULL)
|
||||
{
|
||||
// copy damage factors from parent
|
||||
|
@ -158,15 +140,40 @@ FActorInfo *CreateNewActor(const FScriptPosition &sc, FName typeName, FName pare
|
|||
info->PainChances = new PainChanceList;
|
||||
*info->PainChances = *parent->ActorInfo->PainChances;
|
||||
}
|
||||
info->Replacee = info->Replacement = NULL;
|
||||
info->DoomEdNum = -1;
|
||||
return info;
|
||||
}
|
||||
|
||||
if (replacee != NULL)
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SetReplacement(FActorInfo *info, FName replaceName)
|
||||
{
|
||||
// Check for "replaces"
|
||||
if (replaceName != NAME_None)
|
||||
{
|
||||
replacee->ActorInfo->Replacement = ti->ActorInfo;
|
||||
ti->ActorInfo->Replacee = replacee->ActorInfo;
|
||||
// Get actor name
|
||||
const PClass *replacee = PClass::FindClass (replaceName);
|
||||
|
||||
if (replacee == NULL)
|
||||
{
|
||||
I_Error ("Replaced type '%s' not found in %s", replaceName.GetChars(), info->Class->TypeName.GetChars());
|
||||
}
|
||||
else if (replacee->ActorInfo == NULL)
|
||||
{
|
||||
I_Error ("Replaced type '%s' is not an actor in %s", replaceName.GetChars(), info->Class->TypeName.GetChars());
|
||||
}
|
||||
if (replacee != NULL)
|
||||
{
|
||||
replacee->ActorInfo->Replacement = info;
|
||||
info->Replacee = replacee->ActorInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (DoomEdNum > 0) info->DoomEdNum = DoomEdNum;
|
||||
return info;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -181,14 +188,14 @@ void FinishActor(const FScriptPosition &sc, FActorInfo *info, Baggage &bag)
|
|||
|
||||
try
|
||||
{
|
||||
bag.statedef.FinishStates (info, defaults, bag.StateArray);
|
||||
bag.statedef.FinishStates (info, defaults);
|
||||
}
|
||||
catch (CRecoverableError &err)
|
||||
{
|
||||
sc.Message(MSG_FATAL, "%s", err.GetMessage());
|
||||
}
|
||||
bag.statedef.InstallStates (info, defaults);
|
||||
bag.StateArray.Clear ();
|
||||
bag.statedef.MakeStateDefines(NULL);
|
||||
if (bag.DropItemSet)
|
||||
{
|
||||
if (bag.DropItemList == NULL)
|
||||
|
|
|
@ -82,6 +82,9 @@ struct FStateDefine
|
|||
class FStateDefinitions
|
||||
{
|
||||
TArray<FStateDefine> StateLabels;
|
||||
FState *laststate;
|
||||
intptr_t lastlabel;
|
||||
TArray<FState> StateArray;
|
||||
|
||||
static FStateDefine *FindStateLabelInList(TArray<FStateDefine> &list, FName name, bool create);
|
||||
static FStateLabels *CreateStateLabelList(TArray<FStateDefine> &statelist);
|
||||
|
@ -96,20 +99,28 @@ class FStateDefinitions
|
|||
|
||||
public:
|
||||
|
||||
|
||||
void ClearStateLabels()
|
||||
FStateDefinitions()
|
||||
{
|
||||
StateLabels.Clear();
|
||||
laststate = NULL;
|
||||
lastlabel = -1;
|
||||
}
|
||||
|
||||
void AddState (const char * statename, FState * state, BYTE defflags = SDF_STATE);
|
||||
void SetStateLabel (const char * statename, FState * state, BYTE defflags = SDF_STATE);
|
||||
void AddStateLabel (const char * statename);
|
||||
void InstallStates(FActorInfo *info, AActor *defaults);
|
||||
int FinishStates (FActorInfo *actor, AActor *defaults, TArray<FState> &StateArray);
|
||||
int FinishStates (FActorInfo *actor, AActor *defaults);
|
||||
|
||||
void MakeStateDefines(const PClass *cls);
|
||||
void AddStateDefines(const FStateLabels *list);
|
||||
void RetargetStates (intptr_t count, const char *target);
|
||||
|
||||
bool SetGotoLabel(const char *string);
|
||||
bool SetStop();
|
||||
bool SetWait();
|
||||
bool SetLoop();
|
||||
bool AddStates(FState *state, const char *framechars);
|
||||
int GetStateCount() const { return StateArray.Size(); }
|
||||
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -162,9 +173,10 @@ struct Baggage
|
|||
int CurrentState;
|
||||
int Lumpnum;
|
||||
FStateDefinitions statedef;
|
||||
TArray<FState> StateArray;
|
||||
|
||||
FDropItem *DropItemList;
|
||||
|
||||
FScriptPosition ScriptPosition;
|
||||
};
|
||||
|
||||
inline void ResetBaggage (Baggage *bag, const PClass *stateclass)
|
||||
|
@ -173,7 +185,6 @@ inline void ResetBaggage (Baggage *bag, const PClass *stateclass)
|
|||
bag->DropItemSet = false;
|
||||
bag->CurrentState = 0;
|
||||
bag->StateSet = false;
|
||||
bag->StateArray.Clear();
|
||||
bag->statedef.MakeStateDefines(stateclass);
|
||||
}
|
||||
|
||||
|
@ -193,7 +204,7 @@ AFuncDesc * FindFunction(const char * string);
|
|||
|
||||
|
||||
|
||||
int ParseStates(FScanner &sc, FActorInfo *actor, AActor *defaults, Baggage &bag);
|
||||
void ParseStates(FScanner &sc, FActorInfo *actor, AActor *defaults, Baggage &bag);
|
||||
|
||||
PSymbolActionFunction *FindGlobalActionFunction(const char *name);
|
||||
|
||||
|
@ -203,8 +214,8 @@ PSymbolActionFunction *FindGlobalActionFunction(const char *name);
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FActorInfo *CreateNewActor(const FScriptPosition &sc, FName typeName, FName parentName, FName replaceName,
|
||||
int DoomEdNum, bool native);
|
||||
FActorInfo *CreateNewActor(FName typeName, FName parentName, bool native);
|
||||
void SetReplacement(FActorInfo *info, FName replaceName);
|
||||
|
||||
void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *part2, int mod);
|
||||
void FinishActor(const FScriptPosition &sc, FActorInfo *info, Baggage &bag);
|
||||
|
@ -276,7 +287,7 @@ union FPropParam
|
|||
const char *s;
|
||||
};
|
||||
|
||||
typedef void (*PropHandler)(AActor *defaults, Baggage &bag, FPropParam *params);
|
||||
typedef void (*PropHandler)(AActor *defaults, FActorInfo *info, Baggage &bag, FPropParam *params);
|
||||
|
||||
enum ECategory
|
||||
{
|
||||
|
@ -307,18 +318,18 @@ int MatchString (const char *in, const char **strings);
|
|||
|
||||
|
||||
#define DEFINE_PROPERTY_BASE(name, paramlist, clas, cat) \
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, Baggage &bag, FPropParam *params); \
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, FActorInfo *info, Baggage &bag, FPropParam *params); \
|
||||
static FPropertyInfo Prop_##name##_##paramlist##_##clas = \
|
||||
{ #name, #paramlist, RUNTIME_CLASS(A##clas), (PropHandler)Handler_##name##_##paramlist##_##clas, cat }; \
|
||||
MSVC_PSEG FPropertyInfo *infoptr_##name##_##paramlist##_##clas GCC_PSEG = &Prop_##name##_##paramlist##_##clas; \
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, Baggage &bag, FPropParam *params)
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, FActorInfo *info, Baggage &bag, FPropParam *params)
|
||||
|
||||
#define DEFINE_PREFIXED_PROPERTY_BASE(prefix, name, paramlist, clas, cat) \
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, Baggage &bag, FPropParam *params); \
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, FActorInfo *info, Baggage &bag, FPropParam *params); \
|
||||
static FPropertyInfo Prop_##name##_##paramlist##_##clas = \
|
||||
{ #prefix"."#name, #paramlist, RUNTIME_CLASS(A##clas), (PropHandler)Handler_##name##_##paramlist##_##clas, cat }; \
|
||||
MSVC_PSEG FPropertyInfo *infoptr_##name##_##paramlist##_##clas GCC_PSEG = &Prop_##name##_##paramlist##_##clas; \
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, Baggage &bag, FPropParam *params)
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, FActorInfo *info, Baggage &bag, FPropParam *params)
|
||||
|
||||
|
||||
#define DEFINE_PROPERTY(name, paramlist, clas) DEFINE_PROPERTY_BASE(name, paramlist, clas, CAT_PROPERTY)
|
||||
|
|
|
@ -336,101 +336,92 @@ static FxExpression *ParseExpression0 (FScanner &sc, const PClass *cls)
|
|||
{
|
||||
return new FxConstant(sc.Float, scpos);
|
||||
}
|
||||
else if (sc.CheckToken(TK_Random))
|
||||
{
|
||||
FRandom *rng;
|
||||
|
||||
if (sc.CheckToken('['))
|
||||
{
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
rng = FRandom::StaticFindRNG(sc.String);
|
||||
sc.MustGetToken(']');
|
||||
}
|
||||
else
|
||||
{
|
||||
rng = &pr_exrandom;
|
||||
}
|
||||
sc.MustGetToken('(');
|
||||
|
||||
FxExpression *min = ParseExpressionM (sc, cls);
|
||||
sc.MustGetToken(',');
|
||||
FxExpression *max = ParseExpressionM (sc, cls);
|
||||
sc.MustGetToken(')');
|
||||
|
||||
return new FxRandom(rng, min, max, sc);
|
||||
}
|
||||
else if (sc.CheckToken(TK_Random2))
|
||||
{
|
||||
FRandom *rng;
|
||||
|
||||
if (sc.CheckToken('['))
|
||||
{
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
rng = FRandom::StaticFindRNG(sc.String);
|
||||
sc.MustGetToken(']');
|
||||
}
|
||||
else
|
||||
{
|
||||
rng = &pr_exrandom;
|
||||
}
|
||||
|
||||
sc.MustGetToken('(');
|
||||
|
||||
FxExpression *mask = NULL;
|
||||
|
||||
if (!sc.CheckToken(')'))
|
||||
{
|
||||
mask = ParseExpressionM(sc, cls);
|
||||
sc.MustGetToken(')');
|
||||
}
|
||||
return new FxRandom2(rng, mask, sc);
|
||||
}
|
||||
else if (sc.CheckToken(TK_Abs))
|
||||
{
|
||||
sc.MustGetToken('(');
|
||||
FxExpression *x = ParseExpressionM (sc, cls);
|
||||
sc.MustGetToken(')');
|
||||
return new FxAbs(x);
|
||||
}
|
||||
else if (sc.CheckToken(TK_Identifier))
|
||||
{
|
||||
FName identifier = FName(sc.String);
|
||||
switch (identifier)
|
||||
if (sc.CheckToken('('))
|
||||
{
|
||||
case NAME_Random:
|
||||
{
|
||||
FRandom *rng;
|
||||
|
||||
if (sc.CheckToken('['))
|
||||
FArgumentList *args = NULL;
|
||||
try
|
||||
{
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
rng = FRandom::StaticFindRNG(sc.String);
|
||||
sc.MustGetToken(']');
|
||||
}
|
||||
else
|
||||
{
|
||||
rng = &pr_exrandom;
|
||||
}
|
||||
sc.MustGetToken('(');
|
||||
|
||||
FxExpression *min = ParseExpressionM (sc, cls);
|
||||
sc.MustGetToken(',');
|
||||
FxExpression *max = ParseExpressionM (sc, cls);
|
||||
sc.MustGetToken(')');
|
||||
|
||||
return new FxRandom(rng, min, max, sc);
|
||||
}
|
||||
break;
|
||||
|
||||
case NAME_Random2:
|
||||
{
|
||||
FRandom *rng;
|
||||
|
||||
if (sc.CheckToken('['))
|
||||
{
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
rng = FRandom::StaticFindRNG(sc.String);
|
||||
sc.MustGetToken(']');
|
||||
}
|
||||
else
|
||||
{
|
||||
rng = &pr_exrandom;
|
||||
}
|
||||
|
||||
sc.MustGetToken('(');
|
||||
|
||||
FxExpression *mask = NULL;
|
||||
|
||||
if (!sc.CheckToken(')'))
|
||||
{
|
||||
mask = ParseExpressionM(sc, cls);
|
||||
sc.MustGetToken(')');
|
||||
}
|
||||
return new FxRandom2(rng, mask, sc);
|
||||
}
|
||||
break;
|
||||
|
||||
case NAME_Abs:
|
||||
{
|
||||
sc.MustGetToken('(');
|
||||
FxExpression *x = ParseExpressionM (sc, cls);
|
||||
sc.MustGetToken(')');
|
||||
return new FxAbs(x);
|
||||
}
|
||||
|
||||
default:
|
||||
if (sc.CheckToken('('))
|
||||
{
|
||||
FArgumentList *args = NULL;
|
||||
try
|
||||
if (!sc.CheckToken(')'))
|
||||
{
|
||||
if (!sc.CheckToken(')'))
|
||||
args = new FArgumentList;
|
||||
do
|
||||
{
|
||||
args = new FArgumentList;
|
||||
do
|
||||
{
|
||||
args->Push(ParseExpressionM (sc, cls));
|
||||
args->Push(ParseExpressionM (sc, cls));
|
||||
|
||||
}
|
||||
while (sc.CheckToken(','));
|
||||
sc.MustGetToken(')');
|
||||
}
|
||||
return new FxFunctionCall(NULL, identifier, args, sc);
|
||||
while (sc.CheckToken(','));
|
||||
sc.MustGetToken(')');
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete args;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new FxIdentifier(identifier, sc);
|
||||
return new FxFunctionCall(NULL, identifier, args, sc);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete args;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new FxIdentifier(identifier, sc);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1601,9 +1601,13 @@ ExpVal FxAbs::EvalExpression (AActor *self)
|
|||
FxRandom::FxRandom(FRandom * r, FxExpression *mi, FxExpression *ma, const FScriptPosition &pos)
|
||||
: FxExpression(pos)
|
||||
{
|
||||
if (mi != NULL && ma != NULL)
|
||||
{
|
||||
min = new FxIntCast(mi);
|
||||
max = new FxIntCast(ma);
|
||||
}
|
||||
else min = max = NULL;
|
||||
rng = r;
|
||||
min = new FxIntCast(mi);
|
||||
max = new FxIntCast(ma);
|
||||
ValueType = VAL_Int;
|
||||
}
|
||||
|
||||
|
@ -1646,18 +1650,26 @@ FxExpression *FxRandom::Resolve(FCompileContext &ctx)
|
|||
|
||||
ExpVal FxRandom::EvalExpression (AActor *self)
|
||||
{
|
||||
int minval = min->EvalExpression (self).GetInt();
|
||||
int maxval = max->EvalExpression (self).GetInt();
|
||||
|
||||
ExpVal val;
|
||||
val.Type = VAL_Int;
|
||||
|
||||
if (maxval < minval)
|
||||
if (min != NULL && max != NULL)
|
||||
{
|
||||
swap (maxval, minval);
|
||||
}
|
||||
int minval = min->EvalExpression (self).GetInt();
|
||||
int maxval = max->EvalExpression (self).GetInt();
|
||||
|
||||
val.Int = (*rng)(maxval - minval + 1) + minval;
|
||||
|
||||
if (maxval < minval)
|
||||
{
|
||||
swap (maxval, minval);
|
||||
}
|
||||
|
||||
val.Int = (*rng)(maxval - minval + 1) + minval;
|
||||
}
|
||||
else
|
||||
{
|
||||
val.Int = (*rng)();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
|
|
@ -145,6 +145,8 @@ FxExpression *ParseParameter(FScanner &sc, PClass *cls, char type, bool constant
|
|||
|
||||
case 'X':
|
||||
case 'x':
|
||||
case 'Y':
|
||||
case 'y':
|
||||
x = ParseExpression (sc, cls);
|
||||
if (constant && !x->isConstant())
|
||||
{
|
||||
|
@ -190,7 +192,7 @@ static void ParseConstant (FScanner &sc, PSymbolTable * symt, PClass *cls)
|
|||
else
|
||||
{
|
||||
sym->ValueType = VAL_Float;
|
||||
sym->Value = val.GetFloat();
|
||||
sym->Float = val.GetFloat();
|
||||
}
|
||||
if (symt->AddSymbol (sym) == NULL)
|
||||
{
|
||||
|
@ -654,7 +656,7 @@ static bool ParsePropertyParams(FScanner &sc, FPropertyInfo *prop, AActor *defau
|
|||
// call the handler
|
||||
try
|
||||
{
|
||||
prop->Handler(defaults, bag, ¶ms[0]);
|
||||
prop->Handler(defaults, bag.Info, bag, ¶ms[0]);
|
||||
}
|
||||
catch (CRecoverableError &error)
|
||||
{
|
||||
|
@ -713,7 +715,7 @@ static void ParseActorProperty(FScanner &sc, Baggage &bag)
|
|||
}
|
||||
else if (MatchString(propname, statenames) != -1)
|
||||
{
|
||||
bag.statedef.AddState(propname, CheckState (sc, bag.Info->Class));
|
||||
bag.statedef.SetStateLabel(propname, CheckState (sc, bag.Info->Class));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -782,10 +784,13 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
|
|||
{
|
||||
case TK_Bool:
|
||||
case TK_Int:
|
||||
case TK_Float:
|
||||
type = 'x';
|
||||
break;
|
||||
|
||||
case TK_Float:
|
||||
type = 'y';
|
||||
break;
|
||||
|
||||
case TK_Sound: type = 's'; break;
|
||||
case TK_String: type = 't'; break;
|
||||
case TK_Name: type = 't'; break;
|
||||
|
@ -940,7 +945,10 @@ static FActorInfo *ParseActorHeader(FScanner &sc, Baggage *bag)
|
|||
|
||||
try
|
||||
{
|
||||
FActorInfo *info = CreateNewActor(sc, typeName, parentName, replaceName, DoomEdNum, native);
|
||||
FActorInfo *info = CreateNewActor(typeName, parentName, native);
|
||||
info->DoomEdNum = DoomEdNum > 0? DoomEdNum : -1;
|
||||
SetReplacement(info, replaceName);
|
||||
|
||||
ResetBaggage (bag, info->Class->ParentClass);
|
||||
bag->Info = info;
|
||||
bag->Lumpnum = sc.LumpNum;
|
||||
|
@ -989,8 +997,6 @@ static void ParseActor(FScanner &sc)
|
|||
break;
|
||||
|
||||
case TK_Identifier:
|
||||
// other identifier related checks here
|
||||
case TK_Projectile: // special case: both keyword and property name
|
||||
ParseActorProperty(sc, bag);
|
||||
break;
|
||||
|
||||
|
@ -1047,18 +1053,6 @@ void ParseDecorate (FScanner &sc)
|
|||
ParseEnum (sc, &GlobalSymbols, NULL);
|
||||
break;
|
||||
|
||||
case TK_Pickup:
|
||||
ParseOldDecoration (sc, DEF_Pickup);
|
||||
break;
|
||||
|
||||
case TK_Breakable:
|
||||
ParseOldDecoration (sc, DEF_BreakableDecoration);
|
||||
break;
|
||||
|
||||
case TK_Projectile:
|
||||
ParseOldDecoration (sc, DEF_Projectile);
|
||||
break;
|
||||
|
||||
case TK_Native:
|
||||
ParseVariable(sc, &GlobalSymbols, NULL);
|
||||
break;
|
||||
|
@ -1079,7 +1073,18 @@ void ParseDecorate (FScanner &sc)
|
|||
ParseActor (sc);
|
||||
break;
|
||||
}
|
||||
|
||||
else if (sc.Compare("PICKUP"))
|
||||
{
|
||||
ParseOldDecoration (sc, DEF_Pickup);
|
||||
}
|
||||
else if (sc.Compare("BREAKABLE"))
|
||||
{
|
||||
ParseOldDecoration (sc, DEF_BreakableDecoration);
|
||||
}
|
||||
else if (sc.Compare("PROJECTILE"))
|
||||
{
|
||||
ParseOldDecoration (sc, DEF_Projectile);
|
||||
}
|
||||
default:
|
||||
// without the option of game filters following, anything but an opening brace
|
||||
// here means a syntax error.
|
||||
|
|
|
@ -152,31 +152,31 @@ DEFINE_INFO_PROPERTY(game, T, Actor)
|
|||
PROP_STRING_PARM(str, 0);
|
||||
if (!stricmp(str, "Doom"))
|
||||
{
|
||||
bag.Info->GameFilter |= GAME_Doom;
|
||||
info->GameFilter |= GAME_Doom;
|
||||
}
|
||||
else if (!stricmp(str, "Heretic"))
|
||||
{
|
||||
bag.Info->GameFilter |= GAME_Heretic;
|
||||
info->GameFilter |= GAME_Heretic;
|
||||
}
|
||||
else if (!stricmp(str, "Hexen"))
|
||||
{
|
||||
bag.Info->GameFilter |= GAME_Hexen;
|
||||
info->GameFilter |= GAME_Hexen;
|
||||
}
|
||||
else if (!stricmp(str, "Raven"))
|
||||
{
|
||||
bag.Info->GameFilter |= GAME_Raven;
|
||||
info->GameFilter |= GAME_Raven;
|
||||
}
|
||||
else if (!stricmp(str, "Strife"))
|
||||
{
|
||||
bag.Info->GameFilter |= GAME_Strife;
|
||||
info->GameFilter |= GAME_Strife;
|
||||
}
|
||||
else if (!stricmp(str, "Chex"))
|
||||
{
|
||||
bag.Info->GameFilter |= GAME_Chex;
|
||||
info->GameFilter |= GAME_Chex;
|
||||
}
|
||||
else if (!stricmp(str, "Any"))
|
||||
{
|
||||
bag.Info->GameFilter = GAME_Any;
|
||||
info->GameFilter = GAME_Any;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -194,7 +194,7 @@ DEFINE_INFO_PROPERTY(spawnid, I, Actor)
|
|||
{
|
||||
I_Error ("SpawnID must be in the range [0,255]");
|
||||
}
|
||||
else bag.Info->SpawnID=(BYTE)id;
|
||||
else info->SpawnID=(BYTE)id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -222,7 +222,7 @@ DEFINE_INFO_PROPERTY(conversationid, IiI, Actor)
|
|||
{
|
||||
I_Error ("ConversationID must be in the range [0,1000]");
|
||||
}
|
||||
else StrifeTypes[convid] = bag.Info->Class;
|
||||
else StrifeTypes[convid] = info->Class;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -236,9 +236,16 @@ DEFINE_INFO_PROPERTY(conversationid, IiI, Actor)
|
|||
//==========================================================================
|
||||
DEFINE_PROPERTY(skip_super, 0, Actor)
|
||||
{
|
||||
if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(AInventory)))
|
||||
if (info->Class->IsDescendantOf(RUNTIME_CLASS(AInventory)))
|
||||
{
|
||||
Printf("'skip_super' in definition of inventory item '%s' ignored.", bag.Info->Class->TypeName.GetChars() );
|
||||
bag.ScriptPosition.Message(MSG_WARNING,
|
||||
"'skip_super' in definition of inventory item '%s' ignored.", info->Class->TypeName.GetChars() );
|
||||
return;
|
||||
}
|
||||
if (bag.StateSet)
|
||||
{
|
||||
bag.ScriptPosition.Message(MSG_WARNING,
|
||||
"'skip_super' must appear before any state definitions.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -256,7 +263,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor)
|
|||
DEFINE_PROPERTY(tag, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
bag.Info->Class->Meta.SetMetaString(AMETA_StrifeName, str);
|
||||
info->Class->Meta.SetMetaString(AMETA_StrifeName, str);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -274,7 +281,7 @@ DEFINE_PROPERTY(health, I, Actor)
|
|||
DEFINE_PROPERTY(gibhealth, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (AMETA_GibHealth, id);
|
||||
info->Class->Meta.SetMetaInt (AMETA_GibHealth, id);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -283,7 +290,7 @@ DEFINE_PROPERTY(gibhealth, I, Actor)
|
|||
DEFINE_PROPERTY(woundhealth, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (AMETA_WoundHealth, id);
|
||||
info->Class->Meta.SetMetaInt (AMETA_WoundHealth, id);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -312,8 +319,8 @@ DEFINE_PROPERTY(painchance, ZI, Actor)
|
|||
if (!stricmp(str, "Normal")) painType = NAME_None;
|
||||
else painType=str;
|
||||
|
||||
if (bag.Info->PainChances == NULL) bag.Info->PainChances=new PainChanceList;
|
||||
(*bag.Info->PainChances)[painType] = (BYTE)id;
|
||||
if (info->PainChances == NULL) info->PainChances=new PainChanceList;
|
||||
(*info->PainChances)[painType] = (BYTE)id;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -478,7 +485,7 @@ DEFINE_PROPERTY(activesound, S, Actor)
|
|||
DEFINE_PROPERTY(howlsound, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (AMETA_HowlSound, S_FindSound(str));
|
||||
info->Class->Meta.SetMetaInt (AMETA_HowlSound, S_FindSound(str));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -559,7 +566,7 @@ DEFINE_PROPERTY(alpha, F, Actor)
|
|||
DEFINE_PROPERTY(obituary, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
bag.Info->Class->Meta.SetMetaString (AMETA_Obituary, str);
|
||||
info->Class->Meta.SetMetaString (AMETA_Obituary, str);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -568,7 +575,7 @@ DEFINE_PROPERTY(obituary, S, Actor)
|
|||
DEFINE_PROPERTY(hitobituary, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
bag.Info->Class->Meta.SetMetaString (AMETA_HitObituary, str);
|
||||
info->Class->Meta.SetMetaString (AMETA_HitObituary, str);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -576,7 +583,7 @@ DEFINE_PROPERTY(hitobituary, S, Actor)
|
|||
//==========================================================================
|
||||
DEFINE_PROPERTY(donthurtshooter, 0, Actor)
|
||||
{
|
||||
bag.Info->Class->Meta.SetMetaInt (ACMETA_DontHurtShooter, true);
|
||||
info->Class->Meta.SetMetaInt (ACMETA_DontHurtShooter, true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -585,7 +592,7 @@ DEFINE_PROPERTY(donthurtshooter, 0, Actor)
|
|||
DEFINE_PROPERTY(explosionradius, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (ACMETA_ExplosionRadius, id);
|
||||
info->Class->Meta.SetMetaInt (ACMETA_ExplosionRadius, id);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -594,7 +601,7 @@ DEFINE_PROPERTY(explosionradius, I, Actor)
|
|||
DEFINE_PROPERTY(explosiondamage, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (ACMETA_ExplosionDamage, id);
|
||||
info->Class->Meta.SetMetaInt (ACMETA_ExplosionDamage, id);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -605,7 +612,7 @@ DEFINE_PROPERTY(deathheight, F, Actor)
|
|||
PROP_FIXED_PARM(h, 0);
|
||||
// AActor::Die() uses a height of 0 to mean "cut the height to 1/4",
|
||||
// so if a height of 0 is desired, store it as -1.
|
||||
bag.Info->Class->Meta.SetMetaFixed (AMETA_DeathHeight, h <= 0 ? -1 : h);
|
||||
info->Class->Meta.SetMetaFixed (AMETA_DeathHeight, h <= 0 ? -1 : h);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -615,7 +622,7 @@ DEFINE_PROPERTY(burnheight, F, Actor)
|
|||
{
|
||||
PROP_FIXED_PARM(h, 0);
|
||||
// The note above for AMETA_DeathHeight also applies here.
|
||||
bag.Info->Class->Meta.SetMetaFixed (AMETA_BurnHeight, h <= 0 ? -1 : h);
|
||||
info->Class->Meta.SetMetaFixed (AMETA_BurnHeight, h <= 0 ? -1 : h);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -642,7 +649,7 @@ DEFINE_PROPERTY(meleethreshold, F, Actor)
|
|||
DEFINE_PROPERTY(meleedamage, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (ACMETA_MeleeDamage, id);
|
||||
info->Class->Meta.SetMetaInt (ACMETA_MeleeDamage, id);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -660,7 +667,7 @@ DEFINE_PROPERTY(meleerange, F, Actor)
|
|||
DEFINE_PROPERTY(meleesound, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (ACMETA_MeleeSound, S_FindSound(str));
|
||||
info->Class->Meta.SetMetaInt (ACMETA_MeleeSound, S_FindSound(str));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -669,7 +676,7 @@ DEFINE_PROPERTY(meleesound, S, Actor)
|
|||
DEFINE_PROPERTY(missiletype, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (ACMETA_MissileName, FName(str));
|
||||
info->Class->Meta.SetMetaInt (ACMETA_MissileName, FName(str));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -678,7 +685,7 @@ DEFINE_PROPERTY(missiletype, S, Actor)
|
|||
DEFINE_PROPERTY(missileheight, F, Actor)
|
||||
{
|
||||
PROP_FIXED_PARM(id, 0);
|
||||
bag.Info->Class->Meta.SetMetaFixed (ACMETA_MissileHeight, id);
|
||||
info->Class->Meta.SetMetaFixed (ACMETA_MissileHeight, id);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -691,7 +698,7 @@ DEFINE_PROPERTY(translation, L, Actor)
|
|||
if (type == 0)
|
||||
{
|
||||
PROP_INT_PARM(trans, 1);
|
||||
int max = (gameinfo.gametype==GAME_Strife || (bag.Info->GameFilter&GAME_Strife)) ? 6:2;
|
||||
int max = (gameinfo.gametype==GAME_Strife || (info->GameFilter&GAME_Strife)) ? 6:2;
|
||||
if (trans < 0 || trans > max)
|
||||
{
|
||||
I_Error ("Translation must be in the range [0,%d]", max);
|
||||
|
@ -739,7 +746,7 @@ DEFINE_PROPERTY(bloodcolor, C, Actor)
|
|||
|
||||
PalEntry pe = color;
|
||||
pe.a = CreateBloodTranslation(pe);
|
||||
bag.Info->Class->Meta.SetMetaInt (AMETA_BloodColor, pe);
|
||||
info->Class->Meta.SetMetaInt (AMETA_BloodColor, pe);
|
||||
}
|
||||
|
||||
|
||||
|
@ -754,21 +761,21 @@ DEFINE_PROPERTY(bloodtype, Sss, Actor)
|
|||
|
||||
FName blood = str;
|
||||
// normal blood
|
||||
bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType, blood);
|
||||
info->Class->Meta.SetMetaInt (AMETA_BloodType, blood);
|
||||
|
||||
if (PROP_PARM_COUNT > 1)
|
||||
{
|
||||
blood = str1;
|
||||
}
|
||||
// blood splatter
|
||||
bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType2, blood);
|
||||
info->Class->Meta.SetMetaInt (AMETA_BloodType2, blood);
|
||||
|
||||
if (PROP_PARM_COUNT > 2)
|
||||
{
|
||||
blood = str2;
|
||||
}
|
||||
// axe blood
|
||||
bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType3, blood);
|
||||
info->Class->Meta.SetMetaInt (AMETA_BloodType3, blood);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -825,13 +832,13 @@ DEFINE_PROPERTY(damagefactor, SF, Actor)
|
|||
PROP_STRING_PARM(str, 0);
|
||||
PROP_FIXED_PARM(id, 1);
|
||||
|
||||
if (bag.Info->DamageFactors == NULL) bag.Info->DamageFactors=new DmgFactors;
|
||||
if (info->DamageFactors == NULL) info->DamageFactors=new DmgFactors;
|
||||
|
||||
FName dmgType;
|
||||
if (!stricmp(str, "Normal")) dmgType = NAME_None;
|
||||
else dmgType=str;
|
||||
|
||||
(*bag.Info->DamageFactors)[dmgType]=id;
|
||||
(*info->DamageFactors)[dmgType]=id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -867,7 +874,7 @@ DEFINE_PROPERTY(maxdropoffheight, F, Actor)
|
|||
DEFINE_PROPERTY(poisondamage, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(i, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (AMETA_PoisonDamage, i);
|
||||
info->Class->Meta.SetMetaInt (AMETA_PoisonDamage, i);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -876,7 +883,7 @@ DEFINE_PROPERTY(poisondamage, I, Actor)
|
|||
DEFINE_PROPERTY(fastspeed, F, Actor)
|
||||
{
|
||||
PROP_FIXED_PARM(i, 0);
|
||||
bag.Info->Class->Meta.SetMetaFixed (AMETA_FastSpeed, i);
|
||||
info->Class->Meta.SetMetaFixed (AMETA_FastSpeed, i);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -885,7 +892,7 @@ DEFINE_PROPERTY(fastspeed, F, Actor)
|
|||
DEFINE_PROPERTY(radiusdamagefactor, F, Actor)
|
||||
{
|
||||
PROP_FIXED_PARM(i, 0);
|
||||
bag.Info->Class->Meta.SetMetaFixed (AMETA_RDFactor, i);
|
||||
info->Class->Meta.SetMetaFixed (AMETA_RDFactor, i);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -894,7 +901,7 @@ DEFINE_PROPERTY(radiusdamagefactor, F, Actor)
|
|||
DEFINE_PROPERTY(cameraheight, F, Actor)
|
||||
{
|
||||
PROP_FIXED_PARM(i, 0);
|
||||
bag.Info->Class->Meta.SetMetaFixed (AMETA_CameraHeight, i);
|
||||
info->Class->Meta.SetMetaFixed (AMETA_CameraHeight, i);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -980,7 +987,7 @@ DEFINE_CLASS_PROPERTY(backpackmaxamount, I, Ammo)
|
|||
DEFINE_CLASS_PROPERTY(dropamount, I, Ammo)
|
||||
{
|
||||
PROP_INT_PARM(i, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (AIMETA_DropAmount, i);
|
||||
info->Class->Meta.SetMetaInt (AIMETA_DropAmount, i);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1018,11 +1025,11 @@ DEFINE_CLASS_PROPERTY(saveamount, I, Armor)
|
|||
PROP_INT_PARM(i, 0);
|
||||
|
||||
// Special case here because this property has to work for 2 unrelated classes
|
||||
if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup)))
|
||||
if (info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup)))
|
||||
{
|
||||
((ABasicArmorPickup*)defaults)->SaveAmount=i;
|
||||
}
|
||||
else if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus)))
|
||||
else if (info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus)))
|
||||
{
|
||||
((ABasicArmorBonus*)defaults)->SaveAmount=i;
|
||||
}
|
||||
|
@ -1039,18 +1046,19 @@ DEFINE_CLASS_PROPERTY(savepercent, F, Armor)
|
|||
{
|
||||
PROP_FIXED_PARM(i, 0);
|
||||
|
||||
i = clamp(i, 0, 100*FRACUNIT)/100;
|
||||
// Special case here because this property has to work for 2 unrelated classes
|
||||
if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup)))
|
||||
if (info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup)))
|
||||
{
|
||||
((ABasicArmorPickup*)defaults)->SavePercent=i;
|
||||
((ABasicArmorPickup*)defaults)->SavePercent = i;
|
||||
}
|
||||
else if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus)))
|
||||
else if (info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus)))
|
||||
{
|
||||
((ABasicArmorBonus*)defaults)->SavePercent=i;
|
||||
((ABasicArmorBonus*)defaults)->SavePercent = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
I_Error("\"Armor.SavePercent\" requires an actor of type \"Armor\"");
|
||||
I_Error("\"Armor.SavePercent\" requires an actor of type \"Armor\"\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1062,11 +1070,11 @@ DEFINE_CLASS_PROPERTY(maxabsorb, I, Armor)
|
|||
PROP_INT_PARM(i, 0);
|
||||
|
||||
// Special case here because this property has to work for 2 unrelated classes
|
||||
if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup)))
|
||||
if (info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup)))
|
||||
{
|
||||
((ABasicArmorPickup*)defaults)->MaxAbsorb = i;
|
||||
}
|
||||
else if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus)))
|
||||
else if (info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus)))
|
||||
{
|
||||
((ABasicArmorBonus*)defaults)->MaxAbsorb = i;
|
||||
}
|
||||
|
@ -1084,11 +1092,11 @@ DEFINE_CLASS_PROPERTY(maxfullabsorb, I, Armor)
|
|||
PROP_INT_PARM(i, 0);
|
||||
|
||||
// Special case here because this property has to work for 2 unrelated classes
|
||||
if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup)))
|
||||
if (info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup)))
|
||||
{
|
||||
((ABasicArmorPickup*)defaults)->MaxFullAbsorb = i;
|
||||
}
|
||||
else if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus)))
|
||||
else if (info->Class->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus)))
|
||||
{
|
||||
((ABasicArmorBonus*)defaults)->MaxFullAbsorb = i;
|
||||
}
|
||||
|
@ -1119,10 +1127,11 @@ DEFINE_CLASS_PROPERTY(icon, S, Inventory)
|
|||
{
|
||||
// Don't print warnings if the item is for another game or if this is a shareware IWAD.
|
||||
// Strife's teaser doesn't contain all the icon graphics of the full game.
|
||||
if ((bag.Info->GameFilter == GAME_Any || bag.Info->GameFilter & gameinfo.gametype) &&
|
||||
if ((info->GameFilter == GAME_Any || info->GameFilter & gameinfo.gametype) &&
|
||||
!(gameinfo.flags&GI_SHAREWARE) && Wads.GetLumpFile(bag.Lumpnum) != 0)
|
||||
{
|
||||
Printf("Icon '%s' for '%s' not found\n", i, bag.Info->Class->TypeName.GetChars());
|
||||
bag.ScriptPosition.Message(MSG_WARNING,
|
||||
"Icon '%s' for '%s' not found\n", i, info->Class->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1160,7 +1169,7 @@ DEFINE_CLASS_PROPERTY(pickupflash, S, Inventory)
|
|||
DEFINE_CLASS_PROPERTY(pickupmessage, S, Inventory)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
bag.Info->Class->Meta.SetMetaString(AIMETA_PickupMessage, str);
|
||||
info->Class->Meta.SetMetaString(AIMETA_PickupMessage, str);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1196,7 +1205,7 @@ DEFINE_CLASS_PROPERTY(usesound, S, Inventory)
|
|||
DEFINE_CLASS_PROPERTY(givequest, I, Inventory)
|
||||
{
|
||||
PROP_INT_PARM(i, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt(AIMETA_GiveQuest, i);
|
||||
info->Class->Meta.SetMetaInt(AIMETA_GiveQuest, i);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1206,8 +1215,8 @@ DEFINE_CLASS_PROPERTY(lowmessage, IS, Health)
|
|||
{
|
||||
PROP_INT_PARM(i, 0);
|
||||
PROP_STRING_PARM(str, 1);
|
||||
bag.Info->Class->Meta.SetMetaInt(AIMETA_LowHealth, i);
|
||||
bag.Info->Class->Meta.SetMetaString(AIMETA_LowHealthMessage, str);
|
||||
info->Class->Meta.SetMetaInt(AIMETA_LowHealth, i);
|
||||
info->Class->Meta.SetMetaString(AIMETA_LowHealthMessage, str);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1225,7 +1234,7 @@ DEFINE_CLASS_PROPERTY(number, I, PuzzleItem)
|
|||
DEFINE_CLASS_PROPERTY(failmessage, S, PuzzleItem)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
bag.Info->Class->Meta.SetMetaString(AIMETA_PuzzFailMessage, str);
|
||||
info->Class->Meta.SetMetaString(AIMETA_PuzzFailMessage, str);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1399,11 +1408,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory)
|
|||
int alpha;
|
||||
PalEntry * pBlendColor;
|
||||
|
||||
if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(APowerup)))
|
||||
if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerup)))
|
||||
{
|
||||
pBlendColor = &((APowerup*)defaults)->BlendColor;
|
||||
}
|
||||
else if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
else if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
{
|
||||
pBlendColor = &((APowerupGiver*)defaults)->BlendColor;
|
||||
}
|
||||
|
@ -1463,11 +1472,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, duration, I, Inventory)
|
|||
{
|
||||
int *pEffectTics;
|
||||
|
||||
if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(APowerup)))
|
||||
if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerup)))
|
||||
{
|
||||
pEffectTics = &((APowerup*)defaults)->EffectTics;
|
||||
}
|
||||
else if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
else if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
{
|
||||
pEffectTics = &((APowerupGiver*)defaults)->EffectTics;
|
||||
}
|
||||
|
@ -1511,7 +1520,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, type, S, PowerupGiver)
|
|||
DEFINE_CLASS_PROPERTY_PREFIX(player, displayname, S, PlayerPawn)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
bag.Info->Class->Meta.SetMetaString (APMETA_DisplayName, str);
|
||||
info->Class->Meta.SetMetaString (APMETA_DisplayName, str);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1523,7 +1532,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, soundclass, S, PlayerPawn)
|
|||
|
||||
FString tmp = str;
|
||||
tmp.ReplaceChars (' ', '_');
|
||||
bag.Info->Class->Meta.SetMetaString (APMETA_SoundClass, tmp);
|
||||
info->Class->Meta.SetMetaString (APMETA_SoundClass, tmp);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1537,8 +1546,9 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, face, S, PlayerPawn)
|
|||
tmp.ToUpper();
|
||||
if (tmp.Len() != 3)
|
||||
{
|
||||
Printf("Invalid face '%s' for '%s';\nSTF replacement codes must be 3 characters.\n",
|
||||
tmp.GetChars(), bag.Info->Class->TypeName.GetChars ());
|
||||
bag.ScriptPosition.Message(MSG_WARNING,
|
||||
"Invalid face '%s' for '%s';\nSTF replacement codes must be 3 characters.\n",
|
||||
tmp.GetChars(), info->Class->TypeName.GetChars ());
|
||||
}
|
||||
|
||||
bool valid = (
|
||||
|
@ -1548,11 +1558,12 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, face, S, PlayerPawn)
|
|||
);
|
||||
if (!valid)
|
||||
{
|
||||
Printf("Invalid face '%s' for '%s';\nSTF replacement codes must be alphanumeric.\n",
|
||||
tmp.GetChars(), bag.Info->Class->TypeName.GetChars ());
|
||||
bag.ScriptPosition.Message(MSG_WARNING,
|
||||
"Invalid face '%s' for '%s';\nSTF replacement codes must be alphanumeric.\n",
|
||||
tmp.GetChars(), info->Class->TypeName.GetChars ());
|
||||
}
|
||||
|
||||
bag.Info->Class->Meta.SetMetaString (APMETA_Face, tmp);
|
||||
info->Class->Meta.SetMetaString (APMETA_Face, tmp);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1566,7 +1577,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorrange, I_I, PlayerPawn)
|
|||
if (start > end)
|
||||
swap (start, end);
|
||||
|
||||
bag.Info->Class->Meta.SetMetaInt (APMETA_ColorRange, (start & 255) | ((end & 255) << 8));
|
||||
info->Class->Meta.SetMetaInt (APMETA_ColorRange, (start & 255) | ((end & 255) << 8));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1691,7 +1702,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, scoreicon, S, PlayerPawn)
|
|||
defaults->ScoreIcon = TexMan.CheckForTexture(z, FTexture::TEX_MiscPatch);
|
||||
if (!defaults->ScoreIcon.isValid())
|
||||
{
|
||||
Printf("Icon '%s' for '%s' not found\n", z, bag.Info->Class->TypeName.GetChars ());
|
||||
bag.ScriptPosition.Message(MSG_WARNING,
|
||||
"Icon '%s' for '%s' not found\n", z, info->Class->TypeName.GetChars ());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1751,7 +1763,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, startitem, S_i, PlayerPawn)
|
|||
DEFINE_CLASS_PROPERTY_PREFIX(player, invulnerabilitymode, S, PlayerPawn)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (APMETA_InvulMode, (FName)str);
|
||||
info->Class->Meta.SetMetaInt (APMETA_InvulMode, (FName)str);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1760,7 +1772,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, invulnerabilitymode, S, PlayerPawn)
|
|||
DEFINE_CLASS_PROPERTY_PREFIX(player, healradiustype, S, PlayerPawn)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
bag.Info->Class->Meta.SetMetaInt (APMETA_HealingRadius, (FName)str);
|
||||
info->Class->Meta.SetMetaInt (APMETA_HealingRadius, (FName)str);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1771,7 +1783,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, hexenarmor, FFFFF, PlayerPawn)
|
|||
for (int i=0;i<5;i++)
|
||||
{
|
||||
PROP_FIXED_PARM(val, i);
|
||||
bag.Info->Class->Meta.SetMetaFixed (APMETA_Hexenarmor0+i, val);
|
||||
info->Class->Meta.SetMetaFixed (APMETA_Hexenarmor0+i, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
// creates an empty parameter list for a parameterized function call
|
||||
//
|
||||
//==========================================================================
|
||||
static int PrepareStateParameters(FState * state, int numparams, const PClass *cls)
|
||||
int PrepareStateParameters(FState * state, int numparams, const PClass *cls)
|
||||
{
|
||||
int paramindex=StateParams.Reserve(numparams, cls);
|
||||
state->ParameterIndex = paramindex+1;
|
||||
|
@ -76,7 +76,7 @@ static int PrepareStateParameters(FState * state, int numparams, const PClass *c
|
|||
// handles action specials as code pointers
|
||||
//
|
||||
//==========================================================================
|
||||
bool DoActionSpecials(FScanner &sc, FState & state, bool multistate, int * statecount, Baggage &bag)
|
||||
bool DoActionSpecials(FScanner &sc, FState & state, Baggage &bag)
|
||||
{
|
||||
int i;
|
||||
int min_args, max_args;
|
||||
|
@ -150,15 +150,10 @@ static FString ParseStateString(FScanner &sc)
|
|||
// parses a state block
|
||||
//
|
||||
//==========================================================================
|
||||
int ParseStates(FScanner &sc, FActorInfo * actor, AActor * defaults, Baggage &bag)
|
||||
void ParseStates(FScanner &sc, FActorInfo * actor, AActor * defaults, Baggage &bag)
|
||||
{
|
||||
FString statestring;
|
||||
intptr_t count = 0;
|
||||
FState state;
|
||||
FState * laststate = NULL;
|
||||
intptr_t lastlabel = -1;
|
||||
int minrequiredstate = -1;
|
||||
int spriteindex = 0;
|
||||
char lastsprite[5]="";
|
||||
|
||||
sc.MustGetStringName ("{");
|
||||
|
@ -177,17 +172,7 @@ do_goto:
|
|||
statestring += '+';
|
||||
statestring += sc.String;
|
||||
}
|
||||
// copy the text - this must be resolved later!
|
||||
if (laststate != NULL)
|
||||
{ // Following a state definition: Modify it.
|
||||
laststate->NextState = (FState*)copystring(statestring);
|
||||
laststate->DefineFlags = SDF_LABEL;
|
||||
}
|
||||
else if (lastlabel >= 0)
|
||||
{ // Following a label: Retarget it.
|
||||
bag.statedef.RetargetStates (count+1, statestring);
|
||||
}
|
||||
else
|
||||
if (!bag.statedef.SetGotoLabel(statestring))
|
||||
{
|
||||
sc.ScriptError("GOTO before first state");
|
||||
}
|
||||
|
@ -195,15 +180,7 @@ do_goto:
|
|||
else if (!statestring.CompareNoCase("STOP"))
|
||||
{
|
||||
do_stop:
|
||||
if (laststate!=NULL)
|
||||
{
|
||||
laststate->DefineFlags = SDF_STOP;
|
||||
}
|
||||
else if (lastlabel >=0)
|
||||
{
|
||||
bag.statedef.RetargetStates (count+1, NULL);
|
||||
}
|
||||
else
|
||||
if (!bag.statedef.SetStop())
|
||||
{
|
||||
sc.ScriptError("STOP before first state");
|
||||
continue;
|
||||
|
@ -211,35 +188,28 @@ do_stop:
|
|||
}
|
||||
else if (!statestring.CompareNoCase("WAIT") || !statestring.CompareNoCase("FAIL"))
|
||||
{
|
||||
if (!laststate)
|
||||
if (!bag.statedef.SetWait())
|
||||
{
|
||||
sc.ScriptError("%s before first state", sc.String);
|
||||
continue;
|
||||
}
|
||||
laststate->DefineFlags = SDF_WAIT;
|
||||
}
|
||||
else if (!statestring.CompareNoCase("LOOP"))
|
||||
{
|
||||
if (!laststate)
|
||||
if (!bag.statedef.SetLoop())
|
||||
{
|
||||
sc.ScriptError("LOOP before first state");
|
||||
continue;
|
||||
}
|
||||
laststate->NextState=(FState*)(lastlabel+1);
|
||||
laststate->DefineFlags = SDF_INDEX;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char * statestrp;
|
||||
|
||||
sc.MustGetString();
|
||||
if (sc.Compare (":"))
|
||||
{
|
||||
laststate = NULL;
|
||||
do
|
||||
{
|
||||
lastlabel = count;
|
||||
bag.statedef.AddState(statestring, (FState *) (count+1), SDF_INDEX);
|
||||
bag.statedef.AddStateLabel(statestring);
|
||||
statestring = ParseStateString(sc);
|
||||
if (!statestring.CompareNoCase("GOTO"))
|
||||
{
|
||||
|
@ -261,25 +231,11 @@ do_stop:
|
|||
sc.ScriptError ("Sprite names must be exactly 4 characters\n");
|
||||
}
|
||||
|
||||
statestring.ToUpper();
|
||||
if (strcmp(statestring, lastsprite))
|
||||
{
|
||||
strcpy(lastsprite, statestring);
|
||||
spriteindex = GetSpriteIndex(lastsprite);
|
||||
}
|
||||
|
||||
state.sprite = spriteindex;
|
||||
state.sprite = GetSpriteIndex(statestring);
|
||||
state.Misc1 = state.Misc2 = 0;
|
||||
state.ParameterIndex = 0;
|
||||
sc.MustGetString();
|
||||
statestring = (sc.String+1);
|
||||
statestrp = statestring;
|
||||
state.Frame = (*sc.String & 223)-'A';
|
||||
if ((*sc.String & 223)<'A' || (*sc.String & 223)>']')
|
||||
{
|
||||
sc.ScriptError ("Frames must be A-Z, [, \\, or ]");
|
||||
state.Frame=0;
|
||||
}
|
||||
statestring = sc.String;
|
||||
|
||||
sc.MustGetNumber();
|
||||
state.Tics = clamp<int>(sc.Number, -1, 32767);
|
||||
|
@ -307,10 +263,8 @@ do_stop:
|
|||
// Make the action name lowercase to satisfy the gperf hashers
|
||||
strlwr (sc.String);
|
||||
|
||||
int minreq = count;
|
||||
if (DoActionSpecials(sc, state, !statestring.IsEmpty(), &minreq, bag))
|
||||
if (DoActionSpecials(sc, state, bag))
|
||||
{
|
||||
if (minreq>minrequiredstate) minrequiredstate=minreq;
|
||||
goto endofstate;
|
||||
}
|
||||
|
||||
|
@ -360,7 +314,7 @@ do_stop:
|
|||
if ((*params == 'l' || *params == 'L') && sc.CheckNumber())
|
||||
{
|
||||
// Special case: State label as an offset
|
||||
if (sc.Number > 0 && strlen(statestring)>0)
|
||||
if (sc.Number > 0 && statestring.Len() > 1)
|
||||
{
|
||||
sc.ScriptError("You cannot use state jumps commands with a jump offset on multistate definitions\n");
|
||||
}
|
||||
|
@ -371,7 +325,7 @@ do_stop:
|
|||
sc.ScriptError("Negative jump offsets are not allowed");
|
||||
}
|
||||
|
||||
x = new FxStateByIndex(count+v, sc);
|
||||
x = new FxStateByIndex(bag.statedef.GetStateCount() + v, sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -420,26 +374,12 @@ do_stop:
|
|||
}
|
||||
sc.UnGet();
|
||||
endofstate:
|
||||
bag.StateArray.Push(state);
|
||||
while (*statestrp)
|
||||
if (!bag.statedef.AddStates(&state, statestring))
|
||||
{
|
||||
int frame=((*statestrp++)&223)-'A';
|
||||
|
||||
if (frame<0 || frame>28)
|
||||
{
|
||||
sc.ScriptError ("Frames must be A-Z, [, \\, or ]");
|
||||
frame=0;
|
||||
}
|
||||
|
||||
state.Frame=(state.Frame&(SF_FULLBRIGHT))|frame;
|
||||
bag.StateArray.Push(state);
|
||||
count++;
|
||||
sc.ScriptError ("Invalid frame character string '%s'", statestring.GetChars());
|
||||
}
|
||||
laststate=&bag.StateArray[count];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
sc.SetEscape(true); // re-enable escape sequences
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
@ -441,9 +441,9 @@ void InitPalette ()
|
|||
shade = DesaturateColormap[m];
|
||||
for (c = 0; c < 256; c++)
|
||||
{
|
||||
intensity = GPalette.BaseColors[c].r * 77 +
|
||||
intensity = (GPalette.BaseColors[c].r * 77 +
|
||||
GPalette.BaseColors[c].g * 143 +
|
||||
GPalette.BaseColors[c].b * 37;
|
||||
GPalette.BaseColors[c].b * 37) / 255;
|
||||
|
||||
int r = (GPalette.BaseColors[c].r * (31-m) + intensity *m) / 31;
|
||||
int g = (GPalette.BaseColors[c].g * (31-m) + intensity *m) / 31;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#ifndef __V_PALETTE_H__
|
||||
#define __V_PALETTE_H__
|
||||
|
||||
#include "basictypes.h"
|
||||
#include "doomtype.h"
|
||||
|
||||
#define MAKERGB(r,g,b) DWORD(((r)<<16)|((g)<<8)|(b))
|
||||
#define MAKEARGB(a,r,g,b) DWORD(((a)<<24)|((r)<<16)|((g)<<8)|(b))
|
||||
|
|
|
@ -454,33 +454,48 @@ int V_GetColorFromString (const DWORD *palette, const char *cstr)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Treat it as a space-delemited hexadecimal string
|
||||
for (i = 0; i < 3; ++i)
|
||||
if (strlen(cstr) == 6)
|
||||
{
|
||||
// Skip leading whitespace
|
||||
while (*cstr <= ' ' && *cstr != '\0')
|
||||
char *p;
|
||||
int color = strtol(cstr, &p, 16);
|
||||
if (*p == 0)
|
||||
{
|
||||
cstr++;
|
||||
// RRGGBB string
|
||||
c[0] = (color & 0xff0000) >> 16;
|
||||
c[1] = (color & 0xff00) >> 8;
|
||||
c[2] = (color & 0xff);
|
||||
}
|
||||
// Extract a component and convert it to eight-bit
|
||||
for (p = 0; *cstr > ' '; ++p, ++cstr)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Treat it as a space-delemited hexadecimal string
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
if (p < 2)
|
||||
// Skip leading whitespace
|
||||
while (*cstr <= ' ' && *cstr != '\0')
|
||||
{
|
||||
val[p] = *cstr;
|
||||
cstr++;
|
||||
}
|
||||
}
|
||||
if (p == 0)
|
||||
{
|
||||
c[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p == 1)
|
||||
// Extract a component and convert it to eight-bit
|
||||
for (p = 0; *cstr > ' '; ++p, ++cstr)
|
||||
{
|
||||
val[1] = val[0];
|
||||
if (p < 2)
|
||||
{
|
||||
val[p] = *cstr;
|
||||
}
|
||||
}
|
||||
if (p == 0)
|
||||
{
|
||||
c[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p == 1)
|
||||
{
|
||||
val[1] = val[0];
|
||||
}
|
||||
c[i] = ParseHex (val);
|
||||
}
|
||||
c[i] = ParseHex (val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ Actor GreenArmor : BasicArmorPickup 2018
|
|||
Height 16
|
||||
Inventory.Pickupmessage "$GOTARMOR"
|
||||
Inventory.Icon "ARM1A0"
|
||||
Armor.Savepercent 33.33333
|
||||
Armor.Saveamount 100
|
||||
Armor.SavePercent 33.335
|
||||
Armor.SaveAmount 100
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
|
@ -37,7 +37,7 @@ ACTOR LeatherArmor : BasicArmorPickup 2018
|
|||
Inventory.Icon "I_ARM2"
|
||||
Inventory.PickupMessage "$TXT_LEATHERARMOR"
|
||||
Armor.SaveAmount 100
|
||||
Armor.SavePercent 33.33333
|
||||
Armor.SavePercent 33.335
|
||||
Tag "Leather_Armor"
|
||||
States
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue