- Added a compatibility option to restore the original behavior of the Invisibility

powerup.
- Changed: Weapons are no longer checked for the EXTREMEDEATH and NOEXTREMEDEATH flags.
  For all damage related actions it will always be the projectile (or puff for hitscan
  attacks) that is treated as the damage inflictor.
- Fixed: Hexen's fourth weapons made extreme death depend on the weapon the player
  is holding, not the projectile that did the kill. The WIF_EXTREME_DEATH flag
  no longer exists as a result.
- Expanded PowerSpeed so that subclasses can be derived that alter the speed factor.
- Added an MF5_USESPECIAL flag that allows using things to execute their specials.
- added MF4_FORCERADIUSDMG flag so that exploding items can be created which
  are able to hurt boss monsters.
- moved ML_BLOCK_PLAYERS to the value 0x4000 to bring it in line with Skulltag's 
  implementation.


SVN r530 (trunk)
This commit is contained in:
Christoph Oelckers 2007-05-12 11:14:09 +00:00
commit a6a5821f04
22 changed files with 794 additions and 594 deletions

View file

@ -195,6 +195,7 @@ static flagdef ActorFlags[]=
DEFINE_FLAG(MF4, CANUSEWALLS, AActor, flags4),
DEFINE_FLAG(MF4, MISSILEMORE, AActor, flags4),
DEFINE_FLAG(MF4, MISSILEEVENMORE, AActor, flags4),
DEFINE_FLAG(MF4, FORCERADIUSDMG, AActor, flags4),
DEFINE_FLAG(MF4, DONTFALL, AActor, flags4),
DEFINE_FLAG(MF4, SEESDAGGERS, AActor, flags4),
DEFINE_FLAG(MF4, INCOMBAT, AActor, flags4),
@ -227,6 +228,7 @@ static flagdef ActorFlags[]=
DEFINE_FLAG(MF5, DEHEXPLOSION, AActor, flags5),
DEFINE_FLAG(MF5, PIERCEARMOR, AActor, flags5),
DEFINE_FLAG(MF5, NOBLOODDECALS, AActor, flags5),
DEFINE_FLAG(MF5, USESPECIAL, AActor, flags5),
// Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
@ -4467,12 +4469,181 @@ void ParseClass()
}
}
bool ParseFunctionCall(Baggage &bag, FState & state)
{
// Make the action name lowercase to satisfy the gperf hashers
strlwr (sc_String);
FString funcname = sc_String;
int minreq=0;
memset(&state, 0, sizeof(state));
if (DoSpecialFunctions(state, false, &minreq, bag))
{
return true;
}
PSymbol *sym = bag.Info->Class->Symbols.FindSymbol (FName(sc_String, true), true);
if (sym != NULL && sym->SymbolType == SYM_ActionFunction)
{
PSymbolActionFunction *afd = static_cast<PSymbolActionFunction *>(sym);
state.Action = afd->Function;
if (!afd->Arguments.IsEmpty())
{
const char *params = afd->Arguments.GetChars();
int numparams = (int)afd->Arguments.Len();
int v;
if (!islower(*params))
{
SC_MustGetToken('(');
}
else
{
if (!SC_CheckToken('('))
{
return true;
}
}
int paramindex = PrepareStateParameters(&state, numparams);
int paramstart = paramindex;
bool varargs = params[numparams - 1] == '+';
if (varargs)
{
StateParameters[paramindex++] = 0;
}
while (*params)
{
switch(*params)
{
case 'I':
case 'i': // Integer
SC_MustGetNumber();
v=sc_Number;
break;
case 'F':
case 'f': // Fixed point
SC_MustGetFloat();
v=fixed_t(sc_Float*FRACUNIT);
break;
case 'S':
case 's': // Sound name
SC_MustGetString();
v=S_FindSound(sc_String);
break;
case 'M':
case 'm': // Actor name
case 'T':
case 't': // String
SC_MustGetString();
v = (int)(sc_String[0] ? FName(sc_String) : NAME_None);
break;
case 'L':
case 'l': // Jump label
SC_ScriptError("You cannot use state jump calls in action functions (%s tries to call %s)\n",
funcname.GetChars(), afd->SymbolName.GetChars());
break;
case 'C':
case 'c': // Color
SC_MustGetString ();
if (SC_Compare("none"))
{
v = -1;
}
else
{
int c = V_GetColor (NULL, sc_String);
// 0 needs to be the default so we have to mark the color.
v = MAKEARGB(1, RPART(c), GPART(c), BPART(c));
}
break;
case 'X':
case 'x':
v = ParseExpression (false, bag.Info->Class);
break;
case 'Y':
case 'y':
v = ParseExpression (true, bag.Info->Class);
break;
default:
assert(false);
v = -1;
break;
}
StateParameters[paramindex++] = v;
params++;
if (varargs)
{
StateParameters[paramstart]++;
}
if (*params)
{
if (*params == '+')
{
if (SC_CheckString(")"))
{
return true;
}
params--;
v = 0;
StateParameters.Push(v);
}
else if ((islower(*params) || *params=='!') && SC_CheckString(")"))
{
return true;
}
SC_MustGetStringName (",");
}
}
SC_MustGetStringName(")");
}
else
{
SC_MustGetString();
if (SC_Compare("("))
{
SC_ScriptError("You cannot pass parameters to '%s'\n",funcname.GetChars());
}
SC_UnGet();
}
return true;
}
return false;
}
void ParseActionFunction()
{
FState state;
Baggage bag;
bag.Info=RUNTIME_CLASS(AActor)->ActorInfo;
// for now only void functions with no parameters
SC_MustGetToken(TK_Void);
SC_MustGetString();
FName funcname = sc_String;
SC_MustGetToken('(');
SC_MustGetToken(')');
}
SC_MustGetToken('{');
// All this can do for the moment is parse a list of simple function calls, nothing more
while (SC_MustGetString(), sc_TokenType != '}');
{
ParseFunctionCall(bag, state);
SC_MustGetToken(';');
// Todo: Take the state's content and make a list of it.
}
}