mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-08 16:52:01 +00:00
Check all ACS functions for minimum number of arguments.
Also fixes SpawnForced not respecting the minimum declared in zspecial.acs. (https://forum.zdoom.org/viewtopic.php?t=77027)
This commit is contained in:
parent
dd7cb8649f
commit
258f4b6786
1 changed files with 144 additions and 86 deletions
|
@ -748,7 +748,7 @@ protected:
|
|||
int DoSpawnSpot(int type, int spot, int tid, int angle, bool forced);
|
||||
int DoSpawnSpotFacing(int type, int spot, int tid, bool forced);
|
||||
int DoClassifyActor(int tid);
|
||||
int CallFunction(int argCount, int funcIndex, int32_t *args);
|
||||
int CallFunction(int argCount, int funcIndex, int32_t *args, int &needCount);
|
||||
|
||||
void DoFadeTo(int r, int g, int b, int a, int time);
|
||||
void DoFadeRange(int r1, int g1, int b1, int a1, int r2, int g2, int b2, int a2, int time);
|
||||
|
@ -5323,46 +5323,60 @@ int DLevelScript::SwapActorTeleFog(AActor *activator, int tid)
|
|||
return retval;
|
||||
}
|
||||
|
||||
int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
||||
// Macro for CallFunction. Checks passed number of arguments with minimum required. Sets needCount and returns if not enough.
|
||||
#define MIN_ARG_COUNT(minCount) do { if (argCount < minCount) { needCount = minCount; return 0; } } while(0)
|
||||
|
||||
int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args, int &needCount)
|
||||
{
|
||||
AActor *actor;
|
||||
switch(funcIndex)
|
||||
{
|
||||
case ACSF_GetLineUDMFInt:
|
||||
MIN_ARG_COUNT(2);
|
||||
return GetUDMFInt(Level, UDMF_Line, LineFromID(args[0]), Level->Behaviors.LookupString(args[1]));
|
||||
|
||||
case ACSF_GetLineUDMFFixed:
|
||||
MIN_ARG_COUNT(2);
|
||||
return DoubleToACS(GetUDMFFloat(Level, UDMF_Line, LineFromID(args[0]), Level->Behaviors.LookupString(args[1])));
|
||||
|
||||
case ACSF_GetThingUDMFInt:
|
||||
case ACSF_GetThingUDMFFixed:
|
||||
MIN_ARG_COUNT(2);
|
||||
return 0; // Not implemented yet
|
||||
|
||||
case ACSF_GetSectorUDMFInt:
|
||||
MIN_ARG_COUNT(2);
|
||||
return GetUDMFInt(Level, UDMF_Sector, Level->FindFirstSectorFromTag(args[0]), Level->Behaviors.LookupString(args[1]));
|
||||
|
||||
case ACSF_GetSectorUDMFFixed:
|
||||
MIN_ARG_COUNT(2);
|
||||
return DoubleToACS(GetUDMFFloat(Level, UDMF_Sector, Level->FindFirstSectorFromTag(args[0]), Level->Behaviors.LookupString(args[1])));
|
||||
|
||||
case ACSF_GetSideUDMFInt:
|
||||
MIN_ARG_COUNT(3);
|
||||
return GetUDMFInt(Level, UDMF_Side, SideFromID(args[0], args[1]), Level->Behaviors.LookupString(args[2]));
|
||||
|
||||
case ACSF_GetSideUDMFFixed:
|
||||
MIN_ARG_COUNT(3);
|
||||
return DoubleToACS(GetUDMFFloat(Level, UDMF_Side, SideFromID(args[0], args[1]), Level->Behaviors.LookupString(args[2])));
|
||||
|
||||
case ACSF_GetActorVelX:
|
||||
MIN_ARG_COUNT(1);
|
||||
actor = Level->SingleActorFromTID(args[0], activator);
|
||||
return actor != NULL? DoubleToACS(actor->Vel.X) : 0;
|
||||
|
||||
case ACSF_GetActorVelY:
|
||||
MIN_ARG_COUNT(1);
|
||||
actor = Level->SingleActorFromTID(args[0], activator);
|
||||
return actor != NULL? DoubleToACS(actor->Vel.Y) : 0;
|
||||
|
||||
case ACSF_GetActorVelZ:
|
||||
MIN_ARG_COUNT(1);
|
||||
actor = Level->SingleActorFromTID(args[0], activator);
|
||||
return actor != NULL? DoubleToACS(actor->Vel.Z) : 0;
|
||||
|
||||
case ACSF_SetPointer:
|
||||
MIN_ARG_COUNT(2);
|
||||
if (activator)
|
||||
{
|
||||
AActor *ptr = Level->SingleActorFromTID(args[1], activator);
|
||||
|
@ -5377,6 +5391,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
return 0;
|
||||
|
||||
case ACSF_SetActivator:
|
||||
MIN_ARG_COUNT(1);
|
||||
if (argCount > 1 && args[1] != AAPTR_DEFAULT) // condition (x != AAPTR_DEFAULT) is essentially condition (x).
|
||||
{
|
||||
activator = COPY_AAPTREX(Level, Level->SingleActorFromTID(args[0], activator), args[1]);
|
||||
|
@ -5388,6 +5403,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
return activator != NULL;
|
||||
|
||||
case ACSF_SetActivatorToTarget:
|
||||
MIN_ARG_COUNT(1);
|
||||
// [KS] I revised this a little bit
|
||||
actor = Level->SingleActorFromTID(args[0], activator);
|
||||
if (actor != NULL)
|
||||
|
@ -5411,6 +5427,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
return 0;
|
||||
|
||||
case ACSF_GetActorViewHeight:
|
||||
MIN_ARG_COUNT(1);
|
||||
actor = Level->SingleActorFromTID(args[0], activator);
|
||||
if (actor != NULL)
|
||||
{
|
||||
|
@ -5426,6 +5443,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
else return 0;
|
||||
|
||||
case ACSF_GetChar:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
const char *p = Level->Behaviors.LookupString(args[0]);
|
||||
if (p != NULL && args[1] >= 0 && args[1] < int(strlen(p)))
|
||||
|
@ -5439,6 +5457,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_GetAirSupply:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
if (args[0] < 0 || args[0] >= MAXPLAYERS || !Level->PlayerInGame(args[0]))
|
||||
{
|
||||
|
@ -5451,6 +5470,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_SetAirSupply:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
if (args[0] < 0 || args[0] >= MAXPLAYERS || !Level->PlayerInGame(args[0]))
|
||||
{
|
||||
|
@ -5464,6 +5484,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_SetSkyScrollSpeed:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
if (args[0] == 1) Level->skyspeed1 = ACSToFloat(args[1]);
|
||||
else if (args[0] == 2) Level->skyspeed2 = ACSToFloat(args[1]);
|
||||
|
@ -5471,6 +5492,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_GetArmorType:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
if (args[1] < 0 || args[1] >= MAXPLAYERS || !Level->PlayerInGame(args[1]))
|
||||
{
|
||||
|
@ -5486,6 +5508,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_GetArmorInfo:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
if (activator == NULL || activator->player == NULL) return 0;
|
||||
|
||||
|
@ -5521,15 +5544,19 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_SpawnSpotForced:
|
||||
MIN_ARG_COUNT(4);
|
||||
return DoSpawnSpot(args[0], args[1], args[2], args[3], true);
|
||||
|
||||
case ACSF_SpawnSpotFacingForced:
|
||||
MIN_ARG_COUNT(3);
|
||||
return DoSpawnSpotFacing(args[0], args[1], args[2], true);
|
||||
|
||||
case ACSF_CheckActorProperty:
|
||||
MIN_ARG_COUNT(3);
|
||||
return (CheckActorProperty(args[0], args[1], args[2]));
|
||||
|
||||
case ACSF_SetActorVelocity:
|
||||
MIN_ARG_COUNT(6);
|
||||
{
|
||||
DVector3 vel(ACSToDouble(args[1]), ACSToDouble(args[2]), ACSToDouble(args[3]));
|
||||
if (args[0] == 0)
|
||||
|
@ -5549,6 +5576,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_SetUserVariable:
|
||||
MIN_ARG_COUNT(3);
|
||||
{
|
||||
int cnt = 0;
|
||||
FName varname(Level->Behaviors.LookupString(args[1]), true);
|
||||
|
@ -5577,6 +5605,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_GetUserVariable:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
FName varname(Level->Behaviors.LookupString(args[1]), true);
|
||||
if (varname != NAME_None)
|
||||
|
@ -5588,6 +5617,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_SetUserArray:
|
||||
MIN_ARG_COUNT(4);
|
||||
{
|
||||
int cnt = 0;
|
||||
FName varname(Level->Behaviors.LookupString(args[1]), true);
|
||||
|
@ -5616,6 +5646,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_GetUserArray:
|
||||
MIN_ARG_COUNT(3);
|
||||
{
|
||||
FName varname(Level->Behaviors.LookupString(args[1]), true);
|
||||
if (varname != NAME_None)
|
||||
|
@ -5627,22 +5658,26 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_Radius_Quake2:
|
||||
MIN_ARG_COUNT(6);
|
||||
P_StartQuake(Level, activator, args[0], (double)args[1], args[2], args[3], args[4], S_FindSound(Level->Behaviors.LookupString(args[5])));
|
||||
break;
|
||||
|
||||
case ACSF_CheckActorClass:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
AActor *a = Level->SingleActorFromTID(args[0], activator);
|
||||
return a == NULL ? false : a->GetClass()->TypeName == FName(Level->Behaviors.LookupString(args[1]));
|
||||
}
|
||||
|
||||
case ACSF_GetActorClass:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
AActor *a = Level->SingleActorFromTID(args[0], activator);
|
||||
return GlobalACSStrings.AddString(a == NULL ? "None" : a->GetClass()->TypeName.GetChars());
|
||||
}
|
||||
|
||||
case ACSF_SoundSequenceOnActor:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
const char *seqname = Level->Behaviors.LookupString(args[1]);
|
||||
if (seqname != NULL)
|
||||
|
@ -5669,6 +5704,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
break;
|
||||
|
||||
case ACSF_SoundSequenceOnSector:
|
||||
MIN_ARG_COUNT(3);
|
||||
{
|
||||
const char *seqname = Level->Behaviors.LookupString(args[1]);
|
||||
int space = args[2] < CHAN_FLOOR || args[2] > CHAN_INTERIOR ? CHAN_FULLHEIGHT : args[2];
|
||||
|
@ -5685,6 +5721,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
break;
|
||||
|
||||
case ACSF_SoundSequenceOnPolyobj:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
const char *seqname = Level->Behaviors.LookupString(args[1]);
|
||||
if (seqname != NULL)
|
||||
|
@ -5699,6 +5736,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
break;
|
||||
|
||||
case ACSF_GetPolyobjX:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
FPolyObj *poly = Level->GetPolyobj(args[0]);
|
||||
if (poly != NULL)
|
||||
|
@ -5709,6 +5747,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
return FIXED_MAX;
|
||||
|
||||
case ACSF_GetPolyobjY:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
FPolyObj *poly = Level->GetPolyobj(args[0]);
|
||||
if (poly != NULL)
|
||||
|
@ -5719,6 +5758,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
return FIXED_MAX;
|
||||
|
||||
case ACSF_CheckSight:
|
||||
MIN_ARG_COUNT(3);
|
||||
{
|
||||
AActor *source;
|
||||
AActor *dest;
|
||||
|
@ -5764,7 +5804,8 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
}
|
||||
|
||||
case ACSF_SpawnForced:
|
||||
return DoSpawn(args[0], args[1], args[2], args[3], args[4], args[5], true);
|
||||
MIN_ARG_COUNT(4);
|
||||
return DoSpawn(args[0], args[1], args[2], args[3], argCount > 4 ? args[4] : 0, argCount > 5 ? args[5] : 0, true);
|
||||
|
||||
case ACSF_ACS_NamedExecute:
|
||||
case ACSF_ACS_NamedSuspend:
|
||||
|
@ -5773,6 +5814,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
case ACSF_ACS_NamedLockedExecuteDoor:
|
||||
case ACSF_ACS_NamedExecuteWithResult:
|
||||
case ACSF_ACS_NamedExecuteAlways:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
int scriptnum = -FName(Level->Behaviors.LookupString(args[0])).GetIndex();
|
||||
int arg1 = argCount > 1 ? args[1] : 0;
|
||||
|
@ -5789,15 +5831,19 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
return Level->FindUniqueTID(argCount > 0 ? args[0] : 0, (argCount > 1 && args[1] >= 0) ? args[1] : 0);
|
||||
|
||||
case ACSF_IsTIDUsed:
|
||||
MIN_ARG_COUNT(1);
|
||||
return Level->IsTIDUsed(args[0]);
|
||||
|
||||
case ACSF_Sqrt:
|
||||
MIN_ARG_COUNT(1);
|
||||
return xs_FloorToInt(g_sqrt(double(args[0])));
|
||||
|
||||
case ACSF_FixedSqrt:
|
||||
MIN_ARG_COUNT(1);
|
||||
return DoubleToACS(g_sqrt(ACSToDouble(args[0])));
|
||||
|
||||
case ACSF_VectorLength:
|
||||
MIN_ARG_COUNT(2);
|
||||
return DoubleToACS(DVector2(ACSToDouble(args[0]), ACSToDouble(args[1])).Length());
|
||||
|
||||
case ACSF_SetHUDClipRect:
|
||||
|
@ -5814,56 +5860,36 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
break;
|
||||
|
||||
case ACSF_GetCVarString:
|
||||
if (argCount == 1)
|
||||
{
|
||||
return DoGetCVar(GetCVar(activator && activator->player ? int(activator->player - players) : -1, Level->Behaviors.LookupString(args[0])), true);
|
||||
}
|
||||
break;
|
||||
MIN_ARG_COUNT(1);
|
||||
return DoGetCVar(GetCVar(activator && activator->player ? int(activator->player - players) : -1, Level->Behaviors.LookupString(args[0])), true);
|
||||
|
||||
case ACSF_SetCVar:
|
||||
if (argCount == 2)
|
||||
{
|
||||
return SetCVar(activator, Level->Behaviors.LookupString(args[0]), args[1], false);
|
||||
}
|
||||
break;
|
||||
MIN_ARG_COUNT(2);
|
||||
return SetCVar(activator, Level->Behaviors.LookupString(args[0]), args[1], false);
|
||||
|
||||
case ACSF_SetCVarString:
|
||||
if (argCount == 2)
|
||||
{
|
||||
return SetCVar(activator, Level->Behaviors.LookupString(args[0]), args[1], true);
|
||||
}
|
||||
break;
|
||||
MIN_ARG_COUNT(2);
|
||||
return SetCVar(activator, Level->Behaviors.LookupString(args[0]), args[1], true);
|
||||
|
||||
case ACSF_GetUserCVar:
|
||||
if (argCount == 2)
|
||||
{
|
||||
return DoGetCVar(G_GetUserCVar(args[0], Level->Behaviors.LookupString(args[1])), false);
|
||||
}
|
||||
break;
|
||||
MIN_ARG_COUNT(2);
|
||||
return DoGetCVar(G_GetUserCVar(args[0], Level->Behaviors.LookupString(args[1])), false);
|
||||
|
||||
case ACSF_GetUserCVarString:
|
||||
if (argCount == 2)
|
||||
{
|
||||
return DoGetCVar(G_GetUserCVar(args[0], Level->Behaviors.LookupString(args[1])), true);
|
||||
}
|
||||
break;
|
||||
MIN_ARG_COUNT(2);
|
||||
return DoGetCVar(G_GetUserCVar(args[0], Level->Behaviors.LookupString(args[1])), true);
|
||||
|
||||
case ACSF_SetUserCVar:
|
||||
if (argCount == 3)
|
||||
{
|
||||
return SetUserCVar(args[0], Level->Behaviors.LookupString(args[1]), args[2], false);
|
||||
}
|
||||
break;
|
||||
MIN_ARG_COUNT(3);
|
||||
return SetUserCVar(args[0], Level->Behaviors.LookupString(args[1]), args[2], false);
|
||||
|
||||
case ACSF_SetUserCVarString:
|
||||
if (argCount == 3)
|
||||
{
|
||||
return SetUserCVar(args[0], Level->Behaviors.LookupString(args[1]), args[2], true);
|
||||
}
|
||||
break;
|
||||
MIN_ARG_COUNT(3);
|
||||
return SetUserCVar(args[0], Level->Behaviors.LookupString(args[1]), args[2], true);
|
||||
|
||||
//[RC] A bullet firing function for ACS. Thanks to DavidPH.
|
||||
case ACSF_LineAttack:
|
||||
MIN_ARG_COUNT(4);
|
||||
{
|
||||
DAngle angle = ACSToAngle(args[1]);
|
||||
DAngle pitch = ACSToAngle(args[2]);
|
||||
|
@ -5906,6 +5932,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
|||
case ACSF_PlaySound:
|
||||
case ACSF_PlayActorSound:
|
||||
// PlaySound(tid, "SoundName", channel, volume, looping, attenuation, local)
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
FSoundID sid = NO_SOUND;
|
||||
|
||||
|
@ -5952,6 +5979,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
break;
|
||||
|
||||
case ACSF_StopSound:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
int chan = argCount > 1 ? args[1] : CHAN_BODY;
|
||||
|
||||
|
@ -5974,6 +6002,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
|
||||
case ACSF_SoundVolume:
|
||||
// SoundVolume(int tid, int channel, fixed volume)
|
||||
MIN_ARG_COUNT(3);
|
||||
{
|
||||
int chan = args[1];
|
||||
double volume = ACSToDouble(args[2]);
|
||||
|
@ -5997,7 +6026,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
|
||||
case ACSF_strcmp:
|
||||
case ACSF_stricmp:
|
||||
if (argCount >= 2)
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
const char *a, *b;
|
||||
// If the string indicies are the same, then they are the same string.
|
||||
|
@ -6026,7 +6055,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
|
||||
case ACSF_StrLeft:
|
||||
case ACSF_StrRight:
|
||||
if (argCount >= 2)
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
const char *oldstr = Level->Behaviors.LookupString(args[0]);
|
||||
if (oldstr == NULL || *oldstr == '\0')
|
||||
|
@ -6046,7 +6075,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
break;
|
||||
|
||||
case ACSF_StrMid:
|
||||
if (argCount >= 3)
|
||||
MIN_ARG_COUNT(3);
|
||||
{
|
||||
const char *oldstr = Level->Behaviors.LookupString(args[0]);
|
||||
if (oldstr == NULL || *oldstr == '\0')
|
||||
|
@ -6083,6 +6112,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
case ACSF_SpawnDecal:
|
||||
// int SpawnDecal(int tid, str decalname, int flags, fixed angle, int|fixed zoffset, int|fixed distance)
|
||||
// Returns number of decals spawned (not including spreading)
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
int count = 0;
|
||||
const FDecalTemplate *tpl = DecalLibrary.GetDecalByName(Level->Behaviors.LookupString(args[1]));
|
||||
|
@ -6117,9 +6147,11 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
|
||||
case ACSF_CheckFont:
|
||||
// bool CheckFont(str fontname)
|
||||
MIN_ARG_COUNT(1);
|
||||
return V_GetFont(Level->Behaviors.LookupString(args[0])) != NULL;
|
||||
|
||||
case ACSF_DropItem:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
const char *type = Level->Behaviors.LookupString(args[1]);
|
||||
int amount = argCount >= 3? args[2] : -1;
|
||||
|
@ -6153,6 +6185,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_DropInventory:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
const char *type = Level->Behaviors.LookupString(args[1]);
|
||||
AActor *inv;
|
||||
|
@ -6189,6 +6222,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_CheckFlag:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
AActor *actor = Level->SingleActorFromTID(args[0], activator);
|
||||
if (actor != NULL)
|
||||
|
@ -6199,6 +6233,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_QuakeEx:
|
||||
MIN_ARG_COUNT(8);
|
||||
{
|
||||
return P_StartQuakeXYZ(Level, activator, args[0], args[1], args[2], args[3], args[4], args[5], args[6], S_FindSound(Level->Behaviors.LookupString(args[7])),
|
||||
argCount > 8 ? args[8] : 0,
|
||||
|
@ -6212,11 +6247,11 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_SetLineActivation:
|
||||
if (argCount >= 2)
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
int line;
|
||||
auto itr = Level->GetLineIdIterator(args[0]);
|
||||
int repeat = argCount > 2? args[2] : -1;
|
||||
int repeat = argCount > 2 ? args[2] : -1;
|
||||
while ((line = itr.Next()) >= 0)
|
||||
{
|
||||
Level->lines[line].activation = args[1];
|
||||
|
@ -6227,7 +6262,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
break;
|
||||
|
||||
case ACSF_GetLineActivation:
|
||||
if (argCount > 0)
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
int line = Level->FindFirstLineFromID(args[0]);
|
||||
return line >= 0 ? Level->lines[line].activation : 0;
|
||||
|
@ -6235,7 +6270,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
break;
|
||||
|
||||
case ACSF_GetActorPowerupTics:
|
||||
if (argCount >= 2)
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
PClassActor *powerupclass = PClass::FindActor(Level->Behaviors.LookupString(args[1]));
|
||||
if (powerupclass == NULL || !powerupclass->IsDescendantOf(NAME_Powerup))
|
||||
|
@ -6256,32 +6291,26 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
break;
|
||||
|
||||
case ACSF_ChangeActorAngle:
|
||||
if (argCount >= 2)
|
||||
{
|
||||
SetActorAngle(activator, args[0], args[1], argCount > 2 ? !!args[2] : false);
|
||||
}
|
||||
MIN_ARG_COUNT(2);
|
||||
SetActorAngle(activator, args[0], args[1], argCount > 2 ? !!args[2] : false);
|
||||
break;
|
||||
|
||||
case ACSF_ChangeActorPitch:
|
||||
if (argCount >= 2)
|
||||
{
|
||||
SetActorPitch(activator, args[0], args[1], argCount > 2 ? !!args[2] : false);
|
||||
}
|
||||
MIN_ARG_COUNT(2);
|
||||
SetActorPitch(activator, args[0], args[1], argCount > 2 ? !!args[2] : false);
|
||||
break;
|
||||
|
||||
case ACSF_SetActorTeleFog:
|
||||
if (argCount >= 3)
|
||||
{
|
||||
SetActorTeleFog(activator, args[0], Level->Behaviors.LookupString(args[1]), Level->Behaviors.LookupString(args[2]));
|
||||
}
|
||||
MIN_ARG_COUNT(3);
|
||||
SetActorTeleFog(activator, args[0], Level->Behaviors.LookupString(args[1]), Level->Behaviors.LookupString(args[2]));
|
||||
break;
|
||||
|
||||
case ACSF_SwapActorTeleFog:
|
||||
if (argCount >= 1)
|
||||
{
|
||||
return SwapActorTeleFog(activator, args[0]);
|
||||
}
|
||||
break;
|
||||
MIN_ARG_COUNT(1);
|
||||
return SwapActorTeleFog(activator, args[0]);
|
||||
|
||||
case ACSF_PickActor:
|
||||
if (argCount >= 5)
|
||||
MIN_ARG_COUNT(5);
|
||||
{
|
||||
actor = Level->SingleActorFromTID(args[0], activator);
|
||||
if (actor == NULL)
|
||||
|
@ -6326,6 +6355,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
break;
|
||||
|
||||
case ACSF_IsPointerEqual:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
int tid1 = 0, tid2 = 0;
|
||||
switch (argCount)
|
||||
|
@ -6342,7 +6372,8 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
break;
|
||||
|
||||
case ACSF_CanRaiseActor:
|
||||
if (argCount >= 1) {
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
if (args[0] == 0) {
|
||||
actor = Level->SingleActorFromTID(args[0], activator);
|
||||
if (actor != NULL) {
|
||||
|
@ -6354,7 +6385,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
bool canraiseall = true;
|
||||
while ((actor = iterator.Next()))
|
||||
{
|
||||
canraiseall = P_Thing_CanRaise(actor) & canraiseall;
|
||||
canraiseall &= P_Thing_CanRaise(actor);
|
||||
}
|
||||
|
||||
return canraiseall;
|
||||
|
@ -6363,22 +6394,23 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
|
||||
// [Nash] Actor roll functions. Let's roll!
|
||||
case ACSF_SetActorRoll:
|
||||
MIN_ARG_COUNT(2);
|
||||
SetActorRoll(activator, args[0], args[1], false);
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case ACSF_ChangeActorRoll:
|
||||
if (argCount >= 2)
|
||||
{
|
||||
SetActorRoll(activator, args[0], args[1], argCount > 2 ? !!args[2] : false);
|
||||
}
|
||||
MIN_ARG_COUNT(2);
|
||||
SetActorRoll(activator, args[0], args[1], argCount > 2 ? !!args[2] : false);
|
||||
break;
|
||||
|
||||
case ACSF_GetActorRoll:
|
||||
MIN_ARG_COUNT(1);
|
||||
actor = Level->SingleActorFromTID(args[0], activator);
|
||||
return actor != NULL? AngleToACS(actor->Angles.Roll) : 0;
|
||||
|
||||
// [ZK] A_Warp in ACS
|
||||
case ACSF_Warp:
|
||||
MIN_ARG_COUNT(6);
|
||||
{
|
||||
if (nullptr == activator)
|
||||
{
|
||||
|
@ -6430,6 +6462,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
return true;
|
||||
}
|
||||
case ACSF_GetMaxInventory:
|
||||
MIN_ARG_COUNT(2);
|
||||
actor = Level->SingleActorFromTID(args[0], activator);
|
||||
if (actor != NULL)
|
||||
{
|
||||
|
@ -6438,7 +6471,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
break;
|
||||
|
||||
case ACSF_SetSectorDamage:
|
||||
if (argCount >= 2)
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
auto it = Level->GetSectorTagIterator(args[0]);
|
||||
int s;
|
||||
|
@ -6455,7 +6488,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
break;
|
||||
|
||||
case ACSF_SetSectorTerrain:
|
||||
if (argCount >= 3)
|
||||
MIN_ARG_COUNT(3);
|
||||
{
|
||||
if (args[1] == sector_t::floor || args[1] == sector_t::ceiling)
|
||||
{
|
||||
|
@ -6471,6 +6504,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
break;
|
||||
|
||||
case ACSF_SpawnParticle:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
PalEntry color = args[0];
|
||||
bool fullbright = argCount > 1 ? !!args[1] : false;
|
||||
|
@ -6503,10 +6537,12 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
break;
|
||||
|
||||
case ACSF_SetMusicVolume:
|
||||
MIN_ARG_COUNT(1);
|
||||
Level->SetMusicVolume(ACSToFloat(args[0]));
|
||||
break;
|
||||
|
||||
case ACSF_CheckProximity:
|
||||
MIN_ARG_COUNT(3);
|
||||
{
|
||||
// [zombie] ACS version of A_CheckProximity
|
||||
actor = Level->SingleActorFromTID(args[0], activator);
|
||||
|
@ -6519,6 +6555,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_CheckActorState:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
actor = Level->SingleActorFromTID(args[0], activator);
|
||||
const char *statename = Level->Behaviors.LookupString(args[1]);
|
||||
|
@ -6531,12 +6568,14 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_CheckClass:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
const char *clsname = Level->Behaviors.LookupString(args[0]);
|
||||
return !!PClass::FindActor(clsname);
|
||||
}
|
||||
|
||||
case ACSF_DamageActor: // [arookas] wrapper around P_DamageMobj
|
||||
MIN_ARG_COUNT(6);
|
||||
{
|
||||
// (target, ptr_select1, inflictor, ptr_select2, amount, damagetype)
|
||||
AActor* target = COPY_AAPTREX(Level, Level->SingleActorFromTID(args[0], activator), args[1]);
|
||||
|
@ -6546,6 +6585,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_SetActorFlag:
|
||||
MIN_ARG_COUNT(3);
|
||||
{
|
||||
int tid = args[0];
|
||||
FString flagname = Level->Behaviors.LookupString(args[1]);
|
||||
|
@ -6574,6 +6614,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_SetTranslation:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
int tid = args[0];
|
||||
const char *trname = Level->Behaviors.LookupString(args[1]);
|
||||
|
@ -6595,6 +6636,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
|
||||
// OpenGL exclusive functions
|
||||
case ACSF_SetSectorGlow:
|
||||
MIN_ARG_COUNT(6);
|
||||
{
|
||||
int which = !!args[1];
|
||||
PalEntry color(args[2], args[3], args[4]);
|
||||
|
@ -6612,6 +6654,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_SetFogDensity:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
auto it = Level->GetSectorTagIterator(args[0]);
|
||||
int s;
|
||||
|
@ -6624,6 +6667,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_GetActorFloorTexture:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
auto a = Level->SingleActorFromTID(args[0], activator);
|
||||
if (a != nullptr)
|
||||
|
@ -6638,6 +6682,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_GetActorFloorTerrain:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
auto a = Level->SingleActorFromTID(args[0], activator);
|
||||
if (a != nullptr)
|
||||
|
@ -6652,25 +6697,32 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_StrArg:
|
||||
MIN_ARG_COUNT(1);
|
||||
return -FName(Level->Behaviors.LookupString(args[0])).GetIndex();
|
||||
|
||||
case ACSF_Floor:
|
||||
MIN_ARG_COUNT(1);
|
||||
return args[0] & ~0xffff;
|
||||
|
||||
case ACSF_Ceil:
|
||||
MIN_ARG_COUNT(1);
|
||||
return (args[0] & ~0xffff) + 0x10000;
|
||||
|
||||
case ACSF_Round:
|
||||
MIN_ARG_COUNT(1);
|
||||
return (args[0] + 32768) & ~0xffff;
|
||||
|
||||
case ACSF_ScriptCall:
|
||||
MIN_ARG_COUNT(1);
|
||||
return ScriptCall(activator, argCount, args);
|
||||
|
||||
case ACSF_StartSlideshow:
|
||||
MIN_ARG_COUNT(1);
|
||||
G_StartSlideshow(Level, FName(Level->Behaviors.LookupString(args[0])));
|
||||
break;
|
||||
|
||||
case ACSF_GetSectorHealth:
|
||||
MIN_ARG_COUNT(2);
|
||||
{
|
||||
int part = args[1];
|
||||
auto it = Level->GetSectorTagIterator(args[0]);
|
||||
|
@ -6698,6 +6750,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_GetLineHealth:
|
||||
MIN_ARG_COUNT(1);
|
||||
{
|
||||
auto it = Level->GetLineIdIterator(args[0]);
|
||||
int l = it.Next();
|
||||
|
@ -6715,6 +6768,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
|
||||
case ACSF_GetLineX:
|
||||
case ACSF_GetLineY:
|
||||
MIN_ARG_COUNT(3);
|
||||
{
|
||||
auto it = Level->GetLineIdIterator(args[0]);
|
||||
int lineno = it.Next();
|
||||
|
@ -6730,22 +6784,20 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
|
||||
case ACSF_SetSubtitleNumber:
|
||||
if (argCount >= 2)
|
||||
MIN_ARG_COUNT(2);
|
||||
// only players allowed as activator
|
||||
if (activator != nullptr && activator->player != nullptr)
|
||||
{
|
||||
// only players allowed as activator
|
||||
if (activator != nullptr && activator->player != nullptr)
|
||||
int logNum = args[0];
|
||||
FSoundID sid = NO_SOUND;
|
||||
|
||||
const char* lookup = Level->Behaviors.LookupString(args[1]);
|
||||
if (lookup != nullptr)
|
||||
{
|
||||
int logNum = args[0];
|
||||
FSoundID sid = NO_SOUND;
|
||||
|
||||
const char* lookup = Level->Behaviors.LookupString(args[1]);
|
||||
if (lookup != nullptr)
|
||||
{
|
||||
sid = S_FindSound(lookup);
|
||||
}
|
||||
|
||||
activator->player->SetSubtitle(logNum, sid);
|
||||
sid = S_FindSound(lookup);
|
||||
}
|
||||
|
||||
activator->player->SetSubtitle(logNum, sid);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -6754,6 +6806,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#undef MIN_ARG_COUNT
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -7167,7 +7220,12 @@ int DLevelScript::RunScript()
|
|||
int argCount = NEXTBYTE;
|
||||
int funcIndex = NEXTSHORT;
|
||||
|
||||
int retval = CallFunction(argCount, funcIndex, &STACK(argCount));
|
||||
int retval, minCount = 0;
|
||||
retval = CallFunction(argCount, funcIndex, &STACK(argCount), minCount);
|
||||
if (minCount != 0)
|
||||
{
|
||||
Printf("Called ACS function index %d with too few args: %d (need %d)\n", funcIndex, argCount, minCount);
|
||||
}
|
||||
sp -= argCount-1;
|
||||
STACK(1) = retval;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue