Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Jisk/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
117 results
Select Git revision
Show changes
Commits on Source (17)
...@@ -39,6 +39,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 ...@@ -39,6 +39,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
m_queue.c m_queue.c
m_vector.c m_vector.c
info.c info.c
p_action.c
p_ceilng.c p_ceilng.c
p_enemy.c p_enemy.c
p_floor.c p_floor.c
......
...@@ -33,6 +33,7 @@ m_tokenizer.c ...@@ -33,6 +33,7 @@ m_tokenizer.c
m_queue.c m_queue.c
m_vector.c m_vector.c
info.c info.c
p_action.c
p_ceilng.c p_ceilng.c
p_enemy.c p_enemy.c
p_floor.c p_floor.c
......
...@@ -23,6 +23,46 @@ ...@@ -23,6 +23,46 @@
#pragma interface #pragma interface
#endif #endif
enum
{
ACTION_VAL_NULL,
ACTION_VAL_INTEGER,
ACTION_VAL_BOOLEAN,
ACTION_VAL_STRING
};
typedef struct
{
unsigned length;
char *chars;
UINT32 hash;
} action_string_t;
typedef struct
{
UINT8 type;
union
{
INT32 v_integer;
boolean v_bool;
UINT32 v_string_id;
};
} action_val_t;
#define ACTION_VAL_IS_NULL(val) ((val).type == ACTION_VAL_NULL)
#define ACTION_VAL_IS_INTEGER(val) ((val).type == ACTION_VAL_INTEGER)
#define ACTION_VAL_IS_BOOLEAN(val) ((val).type == ACTION_VAL_BOOLEAN)
#define ACTION_VAL_IS_STRING(val) ((val).type == ACTION_VAL_STRING)
#define ACTION_NULL_VAL (action_val_t){ .type = ACTION_VAL_NULL }
#define ACTION_INTEGER_VAL(val) (action_val_t){ .type = ACTION_VAL_INTEGER, .v_integer = (val) }
#define ACTION_BOOLEAN_VAL(val) (action_val_t){ .type = ACTION_VAL_BOOLEAN, .v_bool = (val) }
#define ACTION_STRING_VAL(val) (action_val_t){ .type = ACTION_VAL_STRING, .v_string_id = (val) }
#define ACTION_VAL_AS_INTEGER(val) ((val).v_integer)
#define ACTION_VAL_AS_BOOLEAN(val) ((val).v_bool)
#define ACTION_VAL_AS_STRING(val) ((val).v_string_id)
// //
// Experimental stuff. // Experimental stuff.
// To compile this as "ANSI C with classes" we will need to handle the various // To compile this as "ANSI C with classes" we will need to handle the various
...@@ -30,11 +70,13 @@ ...@@ -30,11 +70,13 @@
// //
typedef void (*actionf_v)(); typedef void (*actionf_v)();
typedef void (*actionf_p1)(void *); typedef void (*actionf_p1)(void *);
typedef void (*actionf_script)(void *, action_val_t*, unsigned);
typedef union typedef union
{ {
actionf_v acv; actionf_v acv;
actionf_p1 acp1; actionf_p1 acp1;
actionf_script acpscr;
} actionf_t; } actionf_t;
// Historically, "think_t" is yet another function pointer to a routine // Historically, "think_t" is yet another function pointer to a routine
......
...@@ -184,21 +184,37 @@ static inline int lib_freeslot(lua_State *L) ...@@ -184,21 +184,37 @@ static inline int lib_freeslot(lua_State *L)
} }
// Wrapper for ALL A_Action functions. // Wrapper for ALL A_Action functions.
// Arguments: mobj_t actor, int var1, int var2
static int action_call(lua_State *L) static int action_call(lua_State *L)
{ {
actionf_t *action = *((actionf_t **)luaL_checkudata(L, 1, META_ACTION)); actionf_t *action = *((actionf_t **)luaL_checkudata(L, 1, META_ACTION));
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
var1 = (INT32)luaL_optinteger(L, 3, 0); action_val_t *call_args = NULL;
var2 = (INT32)luaL_optinteger(L, 4, 0);
if (!actor) int n = lua_gettop(L);
int num_action_args = n - 2;
if (num_action_args > 0)
{ {
return LUA_ErrInvalid(L, "mobj_t"); call_args = Z_Calloc(num_action_args * sizeof(action_val_t), PU_STATIC, NULL);
for (int i = 3, j = 0; i <= n; i++)
{
if (!LUA_ValueIsValidActionVal(L, i))
{
Z_Free(call_args);
return luaL_error(L, va("value of type %s cannot be passed to an action", luaL_typename(L, i)));
}
LUA_ValueToActionVal(L, i, &call_args[j++]);
}
} }
action->acp1(actor); action->acpscr(actor, call_args, num_action_args);
Z_Free(call_args);
return 0; return 0;
} }
......
...@@ -66,6 +66,116 @@ fixed_t get_number(const char *word) ...@@ -66,6 +66,116 @@ fixed_t get_number(const char *word)
return i;*/ return i;*/
} }
static boolean check_string_token(char *word)
{
word++;
while (*word != '"' && *word != 0)
{
if (*word == '\\')
word++;
word++;
}
if (*word == 0)
{
deh_warning("Unterminated string");
return false;
}
return true;
}
static boolean parse_string_token(char **string_chars, unsigned *string_length, char *word)
{
int token_length = strlen(word);
int length = token_length - 2;
if (length <= 0)
return false;
*string_chars = Z_Calloc(length + 1, PU_STATIC, NULL);
*string_length = 0;
char *chars = *string_chars;
char *str = word + 1;
char *str_end = word + token_length - 1;
while (str < str_end)
{
// Parse escape characters
if (*str == '\\')
{
str++;
if (*str == 'n')
*chars = '\n';
else if (*str == '"')
*chars = '"';
else if (*str == '\\')
*chars = '\\';
else
{
Z_Free(*string_chars);
deh_warning("Invalid escape character in string token");
return false;
}
}
else
*chars = *str;
(*string_length)++;
chars++;
str++;
}
return true;
}
static boolean parse_word(action_val_t *value, char *word)
{
if (*word == '"')
{
if (!check_string_token(word))
{
*value = ACTION_NULL_VAL;
return false;
}
char *string_chars = NULL;
unsigned string_length = 0;
if (!parse_string_token(&string_chars, &string_length, word))
{
*value = ACTION_NULL_VAL;
return false;
}
*value = ACTION_STRING_VAL(Action_AddString(string_chars, string_length));
Z_Free(string_chars);
}
else if (fastcmp(word, "true"))
{
*value = ACTION_BOOLEAN_VAL(true);
}
else if (fastcmp(word, "false"))
{
*value = ACTION_BOOLEAN_VAL(false);
}
else if (fastcmp(word, "null"))
{
*value = ACTION_NULL_VAL;
}
else
{
strupr(word);
*value = ACTION_INTEGER_VAL(get_number(word));
}
return true;
}
#define PARAMCHECK(n) do { if (!params[n]) { deh_warning("Too few parameters, need %d", n); return; }} while (0) #define PARAMCHECK(n) do { if (!params[n]) { deh_warning("Too few parameters, need %d", n); return; }} while (0)
/* ======================================================================== */ /* ======================================================================== */
...@@ -2736,51 +2846,32 @@ void readframe(MYFILE *f, INT32 num) ...@@ -2736,51 +2846,32 @@ void readframe(MYFILE *f, INT32 num)
if (s[0] == '\n') if (s[0] == '\n')
break; break;
// First remove trailing newline, if there is one
tmp = strchr(s, '\n');
if (tmp)
*tmp = '\0';
tmp = strchr(s, '#'); tmp = strchr(s, '#');
if (tmp) if (tmp)
*tmp = '\0'; *tmp = '\0';
if (s == tmp) if (s == tmp)
continue; // Skip comment lines, but don't break. continue; // Skip comment lines, but don't break.
word1 = strtok(s, " "); // Set / reset word
if (word1) word1 = s;
strupr(word1);
else
break;
word2 = strtok(NULL, " = "); // Get the part before the " = "
if (word2) tmp = strchr(s, '=');
strupr(word2); if (tmp)
*(tmp-1) = '\0';
else else
break; break;
if (word2[strlen(word2)-1] == '\n') strupr(word1);
word2[strlen(word2)-1] = '\0';
if (fastcmp(word1, "SPRITENUMBER") || fastcmp(word1, "SPRITENAME")) // Now get the part after
{ word2 = tmp += 2;
states[num].sprite = get_sprite(word2);
} if (fastcmp(word1, "ACTION"))
else if (fastcmp(word1, "SPRITESUBNUMBER") || fastcmp(word1, "SPRITEFRAME"))
{
states[num].frame = (INT32)get_number(word2); // So the FF_ flags get calculated
}
else if (fastcmp(word1, "DURATION"))
{
states[num].tics = (INT32)get_number(word2); // So TICRATE can be used
}
else if (fastcmp(word1, "NEXT"))
{
states[num].nextstate = get_state(word2);
}
else if (fastcmp(word1, "VAR1"))
{
states[num].var1 = (INT32)get_number(word2);
}
else if (fastcmp(word1, "VAR2"))
{
states[num].var2 = (INT32)get_number(word2);
}
else if (fastcmp(word1, "ACTION"))
{ {
size_t z; size_t z;
boolean found = false; boolean found = false;
...@@ -2826,8 +2917,36 @@ void readframe(MYFILE *f, INT32 num) ...@@ -2826,8 +2917,36 @@ void readframe(MYFILE *f, INT32 num)
free(actiontocompare); free(actiontocompare);
} }
else if (!strnicmp(word1, "VAR", 3)
&& strlen(word1) == 4
&& word1[3] >= '1' && word1[3] <= '8')
{
unsigned varSlot = (word1[3] - 0x30) - 1;
parse_word(&states[num].vars[varSlot], word2);
}
else else
deh_warning("Frame %d: unknown word '%s'", num, word1); {
strupr(word2);
if (fastcmp(word1, "SPRITENUMBER") || fastcmp(word1, "SPRITENAME"))
{
states[num].sprite = get_sprite(word2);
}
else if (fastcmp(word1, "SPRITESUBNUMBER") || fastcmp(word1, "SPRITEFRAME"))
{
states[num].frame = (INT32)get_number(word2); // So the FF_ flags get calculated
}
else if (fastcmp(word1, "DURATION"))
{
states[num].tics = (INT32)get_number(word2); // So TICRATE can be used
}
else if (fastcmp(word1, "NEXT"))
{
states[num].nextstate = get_state(word2);
}
else
deh_warning("Frame %d: unknown word '%s'", num, word1);
}
} }
} while (!myfeof(f)); } while (!myfeof(f));
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "m_menu.h" // Menu constants #include "m_menu.h" // Menu constants
#include "y_inter.h" // Intermission constants #include "y_inter.h" // Intermission constants
#include "p_local.h" // some more constants #include "p_local.h" // some more constants
#include "p_action.h" // Actions
#include "r_draw.h" // Colormap constants #include "r_draw.h" // Colormap constants
#include "lua_script.h" // Lua stuff #include "lua_script.h" // Lua stuff
#include "m_cond.h" // Emblem constants #include "m_cond.h" // Emblem constants
......
...@@ -1414,7 +1414,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) ...@@ -1414,7 +1414,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
if (spr->mobj->frame & FF_ANIMATE) if (spr->mobj->frame & FF_ANIMATE)
{ {
// set duration and tics to be the correct values for FF_ANIMATE states // set duration and tics to be the correct values for FF_ANIMATE states
durs = (float)spr->mobj->state->var2; INT32 var2 = Action_ValueToInteger(spr->mobj->state->vars[1]);
durs = (float)var2;
tics = (float)spr->mobj->anim_duration; tics = (float)spr->mobj->anim_duration;
} }
...@@ -1477,7 +1478,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) ...@@ -1477,7 +1478,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
if (spr->mobj->frame & FF_ANIMATE) if (spr->mobj->frame & FF_ANIMATE)
{ {
nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1;
if (nextFrame >= (INT32)(spr->mobj->state->var1 + (spr->mobj->state->frame & FF_FRAMEMASK))) if (nextFrame >= (INT32)(Action_ValueToInteger(spr->mobj->state->vars[0]) + (spr->mobj->state->frame & FF_FRAMEMASK)))
nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK) % mod; nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK) % mod;
} }
else else
......
This diff is collapsed.
...@@ -298,277 +298,6 @@ enum actionnum ...@@ -298,277 +298,6 @@ enum actionnum
NUMACTIONS NUMACTIONS
}; };
// IMPORTANT NOTE: If you add/remove from this list of action
// functions, don't forget to update them in deh_tables.c!
void A_Explode();
void A_Pain();
void A_Fall();
void A_MonitorPop();
void A_GoldMonitorPop();
void A_GoldMonitorRestore();
void A_GoldMonitorSparkle();
void A_Look();
void A_Chase();
void A_FaceStabChase();
void A_FaceStabRev();
void A_FaceStabHurl();
void A_FaceStabMiss();
void A_StatueBurst();
void A_FaceTarget();
void A_FaceTracer();
void A_Scream();
void A_BossDeath();
void A_SetShadowScale();
void A_ShadowScream(); // MARIA!!!!!!
void A_CustomPower(); // Use this for a custom power
void A_GiveWeapon(); // Gives the player weapon(s)
void A_RingBox(); // Obtained Ring Box Tails
void A_Invincibility(); // Obtained Invincibility Box
void A_SuperSneakers(); // Obtained Super Sneakers Box
void A_BunnyHop(); // have bunny hop tails
void A_BubbleSpawn(); // Randomly spawn bubbles
void A_FanBubbleSpawn();
void A_BubbleRise(); // Bubbles float to surface
void A_BubbleCheck(); // Don't draw if not underwater
void A_AwardScore();
void A_ExtraLife(); // Extra Life
void A_GiveShield(); // Obtained Shield
void A_GravityBox();
void A_ScoreRise(); // Rise the score logo
void A_AttractChase(); // Ring Chase
void A_DropMine(); // Drop Mine from Skim or Jetty-Syn Bomber
void A_FishJump(); // Fish Jump
void A_ThrownRing(); // Sparkle trail for red ring
void A_SetSolidSteam();
void A_UnsetSolidSteam();
void A_SignSpin();
void A_SignPlayer();
void A_OverlayThink();
void A_JetChase();
void A_JetbThink(); // Jetty-Syn Bomber Thinker
void A_JetgThink(); // Jetty-Syn Gunner Thinker
void A_JetgShoot(); // Jetty-Syn Shoot Function
void A_ShootBullet(); // JetgShoot without reactiontime setting
void A_MinusDigging();
void A_MinusPopup();
void A_MinusCheck();
void A_ChickenCheck();
void A_MouseThink(); // Mouse Thinker
void A_DetonChase(); // Deton Chaser
void A_CapeChase(); // Fake little Super Sonic cape
void A_RotateSpikeBall(); // Spike ball rotation
void A_SlingAppear();
void A_UnidusBall();
void A_RockSpawn();
void A_SetFuse();
void A_CrawlaCommanderThink(); // Crawla Commander
void A_SmokeTrailer();
void A_RingExplode();
void A_OldRingExplode();
void A_MixUp();
void A_RecyclePowers();
void A_BossScream();
void A_Boss2TakeDamage();
void A_GoopSplat();
void A_Boss2PogoSFX();
void A_Boss2PogoTarget();
void A_EggmanBox();
void A_TurretFire();
void A_SuperTurretFire();
void A_TurretStop();
void A_JetJawRoam();
void A_JetJawChomp();
void A_PointyThink();
void A_CheckBuddy();
void A_HoodFire();
void A_HoodThink();
void A_HoodFall();
void A_ArrowBonks();
void A_SnailerThink();
void A_SharpChase();
void A_SharpSpin();
void A_SharpDecel();
void A_CrushstaceanWalk();
void A_CrushstaceanPunch();
void A_CrushclawAim();
void A_CrushclawLaunch();
void A_VultureVtol();
void A_VultureCheck();
void A_VultureHover();
void A_VultureBlast();
void A_VultureFly();
void A_SkimChase();
void A_SkullAttack();
void A_LobShot();
void A_FireShot();
void A_SuperFireShot();
void A_BossFireShot();
void A_Boss7FireMissiles();
void A_Boss1Laser();
void A_FocusTarget();
void A_Boss4Reverse();
void A_Boss4SpeedUp();
void A_Boss4Raise();
void A_SparkFollow();
void A_BuzzFly();
void A_GuardChase();
void A_EggShield();
void A_SetReactionTime();
void A_Boss1Spikeballs();
void A_Boss3TakeDamage();
void A_Boss3Path();
void A_Boss3ShockThink();
void A_Shockwave();
void A_LinedefExecute();
void A_LinedefExecuteFromArg();
void A_PlaySeeSound();
void A_PlayAttackSound();
void A_PlayActiveSound();
void A_1upThinker();
void A_BossZoom(); //Unused
void A_Boss1Chase();
void A_Boss2Chase();
void A_Boss2Pogo();
void A_Boss7Chase();
void A_BossJetFume();
void A_SpawnObjectAbsolute();
void A_SpawnObjectRelative();
void A_ChangeAngleRelative();
void A_ChangeAngleAbsolute();
void A_RollAngle();
void A_ChangeRollAngleRelative();
void A_ChangeRollAngleAbsolute();
void A_PlaySound();
void A_FindTarget();
void A_FindTracer();
void A_SetTics();
void A_SetRandomTics();
void A_ChangeColorRelative();
void A_ChangeColorAbsolute();
void A_Dye();
void A_SetTranslation();
void A_MoveRelative();
void A_MoveAbsolute();
void A_Thrust();
void A_ZThrust();
void A_SetTargetsTarget();
void A_SetObjectFlags();
void A_SetObjectFlags2();
void A_RandomState();
void A_RandomStateRange();
void A_StateRangeByAngle();
void A_StateRangeByParameter();
void A_DualAction();
void A_RemoteAction();
void A_ToggleFlameJet();
void A_OrbitNights();
void A_GhostMe();
void A_SetObjectState();
void A_SetObjectTypeState();
void A_KnockBack();
void A_PushAway();
void A_RingDrain();
void A_SplitShot();
void A_MissileSplit();
void A_MultiShot();
void A_InstaLoop();
void A_Custom3DRotate();
void A_SearchForPlayers();
void A_CheckRandom();
void A_CheckTargetRings();
void A_CheckRings();
void A_CheckTotalRings();
void A_CheckHealth();
void A_CheckRange();
void A_CheckHeight();
void A_CheckTrueRange();
void A_CheckThingCount();
void A_CheckAmbush();
void A_CheckCustomValue();
void A_CheckCusValMemo();
void A_SetCustomValue();
void A_UseCusValMemo();
void A_RelayCustomValue();
void A_CusValAction();
void A_ForceStop();
void A_ForceWin();
void A_SpikeRetract();
void A_InfoState();
void A_Repeat();
void A_SetScale();
void A_RemoteDamage();
void A_HomingChase();
void A_TrapShot();
void A_VileTarget();
void A_VileAttack();
void A_VileFire();
void A_BrakChase();
void A_BrakFireShot();
void A_BrakLobShot();
void A_NapalmScatter();
void A_SpawnFreshCopy();
void A_FlickySpawn();
void A_FlickyCenter();
void A_FlickyAim();
void A_FlickyFly();
void A_FlickySoar();
void A_FlickyCoast();
void A_FlickyHop();
void A_FlickyFlounder();
void A_FlickyCheck();
void A_FlickyHeightCheck();
void A_FlickyFlutter();
void A_FlameParticle();
void A_FadeOverlay();
void A_Boss5Jump();
void A_LightBeamReset();
void A_MineExplode();
void A_MineRange();
void A_ConnectToGround();
void A_SpawnParticleRelative();
void A_MultiShotDist();
void A_WhoCaresIfYourSonIsABee();
void A_ParentTriesToSleep();
void A_CryingToMomma();
void A_CheckFlags2();
void A_Boss5FindWaypoint();
void A_DoNPCSkid();
void A_DoNPCPain();
void A_PrepareRepeat();
void A_Boss5ExtraRepeat();
void A_Boss5Calm();
void A_Boss5CheckOnGround();
void A_Boss5CheckFalling();
void A_Boss5PinchShot();
void A_Boss5MakeItRain();
void A_Boss5MakeJunk();
void A_LookForBetter();
void A_Boss5BombExplode();
void A_DustDevilThink();
void A_TNTExplode();
void A_DebrisRandom();
void A_TrainCameo();
void A_TrainCameo2();
void A_CanarivoreGas();
void A_KillSegments();
void A_SnapperSpawn();
void A_SnapperThinker();
void A_SaloonDoorSpawn();
void A_MinecartSparkThink();
void A_ModuloToState();
void A_LavafallRocks();
void A_LavafallLava();
void A_FallingLavaCheck();
void A_FireShrink();
void A_SpawnPterabytes();
void A_PterabyteHover();
void A_RolloutSpawn();
void A_RolloutRock();
void A_DragonbomberSpawn();
void A_DragonWing();
void A_DragonSegment();
void A_ChangeHeight();
extern int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION]; extern int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION];
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1 // ratio of states to sprites to mobj types is roughly 6 : 1 : 1
...@@ -4371,14 +4100,15 @@ typedef enum state ...@@ -4371,14 +4100,15 @@ typedef enum state
NUMSTATES NUMSTATES
} statenum_t; } statenum_t;
#define MAX_ACTION_VARS 8
typedef struct typedef struct
{ {
spritenum_t sprite; spritenum_t sprite;
UINT32 frame; // we use the upper 16 bits for translucency and other shade effects UINT32 frame; // we use the upper 16 bits for translucency and other shade effects
INT32 tics; INT32 tics;
actionf_t action; actionf_t action;
INT32 var1; action_val_t vars[MAX_ACTION_VARS];
INT32 var2;
statenum_t nextstate; statenum_t nextstate;
} state_t; } state_t;
......
...@@ -151,6 +151,7 @@ static const struct { ...@@ -151,6 +151,7 @@ static const struct {
const char *utype; const char *utype;
} meta2utype[] = { } meta2utype[] = {
{META_STATE, "state_t"}, {META_STATE, "state_t"},
{META_STATEVARS, "state_t.vars"},
{META_MOBJINFO, "mobjinfo_t"}, {META_MOBJINFO, "mobjinfo_t"},
{META_SFXINFO, "sfxinfo_t"}, {META_SFXINFO, "sfxinfo_t"},
{META_SKINCOLOR, "skincolor_t"}, {META_SKINCOLOR, "skincolor_t"},
......
...@@ -31,9 +31,98 @@ ...@@ -31,9 +31,98 @@
#include "lua_hud.h" // hud_running errors #include "lua_hud.h" // hud_running errors
#include "lua_hook.h" // hook_cmd_running errors #include "lua_hook.h" // hook_cmd_running errors
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor); extern CV_PossibleValue_t Color_cons_t[];
state_t *astate; state_t *astate;
boolean LUA_ValueIsValidActionVal(lua_State *L, int i)
{
switch (lua_type(L, i))
{
case LUA_TNUMBER:
case LUA_TBOOLEAN:
case LUA_TSTRING:
case LUA_TNIL:
return true;
}
return false;
}
#define CHECK_ACTION_VAL_TYPE(n) \
if (!LUA_ValueIsValidActionVal(L, n)) \
return luaL_error(L, va("values of type %s cannot be passed to actions as an argument", luaL_typename(L, n)))
void LUA_ValueToActionVal(lua_State *L, int i, action_val_t *val)
{
action_val_t value;
switch (lua_type(L, i))
{
case LUA_TNUMBER:
value = ACTION_INTEGER_VAL((INT32)luaL_optinteger(L, i, 0));
break;
case LUA_TBOOLEAN:
value = ACTION_BOOLEAN_VAL(lua_toboolean(L, i));
break;
case LUA_TSTRING:
{
size_t string_length = 0;
const char *string = lua_tolstring(L, i, &string_length);
value = ACTION_STRING_VAL(Action_AddString(string, string_length));
break;
}
default:
value = ACTION_NULL_VAL;
break;
}
memcpy(val, &value, sizeof(action_val_t));
}
#define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to states[] (%s)", e)
#define TYPEERROR(f, t1, t2) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t1), lua_typename(L, t2)))
static boolean GetActionValuesFromTable(lua_State *L, action_val_t *vars, int n)
{
lua_Integer i = 0;
if (lua_istable(L, n))
{
lua_pushnil(L);
while (lua_next(L, n))
{
if (lua_isnumber(L, n + 1))
{
i = lua_tointeger(L, n + 1);
if (i < 1 || i > MAX_ACTION_VARS)
{
FIELDERROR("vars", va("var %d is invalid", i));
return false;
}
i--;
}
else
{
FIELDERROR("vars", "vars table requires keys to be numbers");
}
CHECK_ACTION_VAL_TYPE(n + 2);
LUA_ValueToActionVal(L, n + 2, &vars[i]);
lua_pop(L, 1);
}
}
else
{
FIELDERROR("vars", va("%s expected, got %s", lua_typename(L, LUA_TTABLE), luaL_typename(L, -1)));
return false;
}
return true;
}
#undef FIELDERROR
#undef TYPEERROR
enum sfxinfo_read { enum sfxinfo_read {
sfxinfor_name = 0, sfxinfor_name = 0,
sfxinfor_singular, sfxinfor_singular,
...@@ -619,9 +708,33 @@ static int framepivot_num(lua_State *L) ...@@ -619,9 +708,33 @@ static int framepivot_num(lua_State *L)
// STATE INFO // // STATE INFO //
//////////////// ////////////////
static void PushActionValue(lua_State *L, action_val_t arg)
{
if (ACTION_VAL_IS_INTEGER(arg))
lua_pushinteger(L, ACTION_VAL_AS_INTEGER(arg));
else if (ACTION_VAL_IS_BOOLEAN(arg))
lua_pushboolean(L, ACTION_VAL_AS_BOOLEAN(arg));
else if (ACTION_VAL_IS_STRING(arg))
{
action_string_t *string = Action_GetString(ACTION_VAL_AS_STRING(arg));
if (string)
lua_pushlstring(L, string->chars, string->length);
else
lua_pushnil(L);
}
else if (ACTION_VAL_IS_NULL(arg))
lua_pushnil(L);
}
static void PushActionArguments(lua_State *L, action_val_t *args, unsigned argcount)
{
for (unsigned i = 0; i < argcount; i++)
PushActionValue(L, args[i]);
}
// Uses astate to determine which state is calling it // Uses astate to determine which state is calling it
// Then looks up which Lua action is assigned to that state and calls it // Then looks up which Lua action is assigned to that state and calls it
static void A_Lua(mobj_t *actor) static void A_Lua(mobj_t *actor, action_val_t *args, unsigned argcount)
{ {
boolean found = false; boolean found = false;
I_Assert(actor != NULL); I_Assert(actor != NULL);
...@@ -655,9 +768,8 @@ static void A_Lua(mobj_t *actor) ...@@ -655,9 +768,8 @@ static void A_Lua(mobj_t *actor)
lua_pop(gL, 1); // pop LREG_ACTION lua_pop(gL, 1); // pop LREG_ACTION
LUA_PushUserdata(gL, actor, META_MOBJ); LUA_PushUserdata(gL, actor, META_MOBJ);
lua_pushinteger(gL, var1); PushActionArguments(gL, args, argcount);
lua_pushinteger(gL, var2); LUA_Call(gL, 1 + argcount, 0, 1);
LUA_Call(gL, 3, 0, 1);
if (found) if (found)
{ {
...@@ -750,20 +862,25 @@ static int lib_setState(lua_State *L) ...@@ -750,20 +862,25 @@ static int lib_setState(lua_State *L)
lua_pushvalue(L, 3); // Bring it to the top of the stack lua_pushvalue(L, 3); // Bring it to the top of the stack
lua_rawset(L, -3); // Set it in the registry lua_rawset(L, -3); // Set it in the registry
lua_pop(L, 1); // pop LREG_STATEACTION lua_pop(L, 1); // pop LREG_STATEACTION
state->action.acp1 = (actionf_p1)A_Lua; // Set the action for the userdata. state->action.acpscr = (actionf_script)A_Lua; // Set the action for the userdata.
break; break;
default: // ?! default: // ?!
return luaL_typerror(L, 3, "function"); return luaL_typerror(L, 3, "function");
} }
} else if (i == 5 || (str && fastcmp(str, "var1"))) { } else if (i == 5 || (str && fastcmp(str, "var1"))) {
state->var1 = (INT32)luaL_checkinteger(L, 3); CHECK_ACTION_VAL_TYPE(3);
LUA_ValueToActionVal(L, 3, &state->vars[0]);
} else if (i == 6 || (str && fastcmp(str, "var2"))) { } else if (i == 6 || (str && fastcmp(str, "var2"))) {
state->var2 = (INT32)luaL_checkinteger(L, 3); CHECK_ACTION_VAL_TYPE(3);
LUA_ValueToActionVal(L, 3, &state->vars[1]);
} else if (i == 7 || (str && fastcmp(str, "nextstate"))) { } else if (i == 7 || (str && fastcmp(str, "nextstate"))) {
value = luaL_checkinteger(L, 3); value = luaL_checkinteger(L, 3);
if (value < S_NULL || value >= NUMSTATES) if (value < S_NULL || value >= NUMSTATES)
return luaL_error(L, "nextstate number %d is invalid.", value); return luaL_error(L, "nextstate number %d is invalid.", value);
state->nextstate = (statenum_t)value; state->nextstate = (statenum_t)value;
} else if (str && fastcmp(str, "vars")) {
if (!GetActionValuesFromTable(L, state->vars, 3))
return 0;
} }
lua_pop(L, 1); lua_pop(L, 1);
} }
...@@ -808,12 +925,13 @@ boolean LUA_SetLuaAction(void *stv, const char *action) ...@@ -808,12 +925,13 @@ boolean LUA_SetLuaAction(void *stv, const char *action)
lua_pop(gL, 1); // pop LREG_STATEACTION lua_pop(gL, 1); // pop LREG_STATEACTION
lua_pop(gL, 2); // pop the function and LREG_ACTIONS lua_pop(gL, 2); // pop the function and LREG_ACTIONS
st->action.acp1 = (actionf_p1)A_Lua; // Set the action for the userdata. st->action.acpscr = (actionf_script)A_Lua; // Set the action for the userdata.
return true; // action successfully set. return true; // action successfully set.
} }
static UINT8 superstack[NUMACTIONS]; static UINT8 superstack[NUMACTIONS];
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor)
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor, action_val_t *args, unsigned argcount)
{ {
I_Assert(actor != NULL); I_Assert(actor != NULL);
...@@ -875,16 +993,17 @@ boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor) ...@@ -875,16 +993,17 @@ boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor)
} }
// Found a function. // Found a function.
// Call it with (actor, var1, var2) // Call it with (actor, ...)
I_Assert(lua_isfunction(gL, -1)); I_Assert(lua_isfunction(gL, -1));
LUA_PushUserdata(gL, actor, META_MOBJ); LUA_PushUserdata(gL, actor, META_MOBJ);
lua_pushinteger(gL, var1); PushActionArguments(gL, args, argcount);
lua_pushinteger(gL, var2);
int nargs = 1 + argcount;
luaactions[luaactionstack] = actionpointers[actionnum].name; luaactions[luaactionstack] = actionpointers[actionnum].name;
++luaactionstack; ++luaactionstack;
LUA_Call(gL, 3, 0, -(2 + 3)); LUA_Call(gL, nargs, 0, -(2 + nargs));
lua_pop(gL, -1); // Error handler lua_pop(gL, -1); // Error handler
if (superstack[actionnum]) if (superstack[actionnum])
...@@ -913,9 +1032,9 @@ static int state_get(lua_State *L) ...@@ -913,9 +1032,9 @@ static int state_get(lua_State *L)
number = st->tics; number = st->tics;
else if (fastcmp(field,"action")) { else if (fastcmp(field,"action")) {
const char *name; const char *name;
if (!st->action.acp1) // Action is NULL. if (!st->action.acpscr) // Action is NULL.
return 0; // return nil. return 0; // return nil.
if (st->action.acp1 == (actionf_p1)A_Lua) { // This is a Lua function? if (st->action.acpscr == (actionf_script)A_Lua) { // This is a Lua function?
lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION); lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION);
I_Assert(lua_istable(L, -1)); I_Assert(lua_istable(L, -1));
lua_pushlightuserdata(L, st); // Push the state pointer and lua_pushlightuserdata(L, st); // Push the state pointer and
...@@ -930,10 +1049,18 @@ static int state_get(lua_State *L) ...@@ -930,10 +1049,18 @@ static int state_get(lua_State *L)
// because the metatable will trigger. // because the metatable will trigger.
lua_getglobal(L, name); // actually gets from LREG_ACTIONS if applicable, and pushes a META_ACTION userdata if not. lua_getglobal(L, name); // actually gets from LREG_ACTIONS if applicable, and pushes a META_ACTION userdata if not.
return 1; // return just the function return 1; // return just the function
} else if (fastcmp(field,"var1")) } else if (fastcmp(field,"var1")) {
number = st->var1; PushActionValue(L, st->vars[0]);
else if (fastcmp(field,"var2")) return 1;
number = st->var2; }
else if (fastcmp(field,"var2")) {
PushActionValue(L, st->vars[1]);
return 1;
}
else if (fastcmp(field,"vars")) {
LUA_PushUserdata(L, st->vars, META_STATEVARS);
return 1;
}
else if (fastcmp(field,"nextstate")) else if (fastcmp(field,"nextstate"))
number = st->nextstate; number = st->nextstate;
else if (devparm) else if (devparm)
...@@ -970,7 +1097,7 @@ static int state_set(lua_State *L) ...@@ -970,7 +1097,7 @@ static int state_set(lua_State *L)
switch(lua_type(L, 3)) switch(lua_type(L, 3))
{ {
case LUA_TNIL: // Null? Set the action to nothing, then. case LUA_TNIL: // Null? Set the action to nothing, then.
st->action.acp1 = NULL; st->action.acpscr = NULL;
break; break;
case LUA_TSTRING: // It's a string, expect the name of a built-in action case LUA_TSTRING: // It's a string, expect the name of a built-in action
LUA_SetActionByName(st, lua_tostring(L, 3)); LUA_SetActionByName(st, lua_tostring(L, 3));
...@@ -983,8 +1110,6 @@ static int state_set(lua_State *L) ...@@ -983,8 +1110,6 @@ static int state_set(lua_State *L)
return luaL_error(L, "not a valid action?"); return luaL_error(L, "not a valid action?");
st->action = *action; st->action = *action;
st->action.acv = action->acv;
st->action.acp1 = action->acp1;
break; break;
} }
case LUA_TFUNCTION: // It's a function (a Lua function or a C function? either way!) case LUA_TFUNCTION: // It's a function (a Lua function or a C function? either way!)
...@@ -994,15 +1119,23 @@ static int state_set(lua_State *L) ...@@ -994,15 +1119,23 @@ static int state_set(lua_State *L)
lua_pushvalue(L, 3); // Bring it to the top of the stack lua_pushvalue(L, 3); // Bring it to the top of the stack
lua_rawset(L, -3); // Set it in the registry lua_rawset(L, -3); // Set it in the registry
lua_pop(L, 1); // pop LREG_STATEACTION lua_pop(L, 1); // pop LREG_STATEACTION
st->action.acp1 = (actionf_p1)A_Lua; // Set the action for the userdata. st->action.acpscr = (actionf_script)A_Lua; // Set the action for the userdata.
break; break;
default: // ?! default: // Something else
return luaL_typerror(L, 3, "function"); return luaL_typerror(L, 3, "function");
} }
} else if (fastcmp(field,"var1")) } else if (fastcmp(field,"var1")) {
st->var1 = (INT32)luaL_checknumber(L, 3); CHECK_ACTION_VAL_TYPE(3);
else if (fastcmp(field,"var2")) LUA_ValueToActionVal(L, 3, &st->vars[0]);
st->var2 = (INT32)luaL_checknumber(L, 3); }
else if (fastcmp(field,"var2")) {
CHECK_ACTION_VAL_TYPE(3);
LUA_ValueToActionVal(L, 3, &st->vars[1]);
}
else if (fastcmp(field,"vars")) {
if (!GetActionValuesFromTable(L, st->vars, 3))
return 0;
}
else if (fastcmp(field,"nextstate")) { else if (fastcmp(field,"nextstate")) {
value = luaL_checkinteger(L, 3); value = luaL_checkinteger(L, 3);
if (value < S_NULL || value >= NUMSTATES) if (value < S_NULL || value >= NUMSTATES)
...@@ -1022,6 +1155,33 @@ static int state_num(lua_State *L) ...@@ -1022,6 +1155,33 @@ static int state_num(lua_State *L)
return 1; return 1;
} }
static int statevars_get(lua_State *L)
{
action_val_t *vars = *((action_val_t **)luaL_checkudata(L, 1, META_STATEVARS));
int n = luaL_checkinteger(L, 2);
if (n <= 0 || n > MAX_ACTION_VARS)
return luaL_error(L, LUA_QL("state_t") " field 'vars' index %d out of range (1 - %d)", n, MAX_ACTION_VARS);
PushActionValue(L, vars[n-1]);
return 1;
}
static int statevars_set(lua_State *L)
{
action_val_t *vars = *((action_val_t **)luaL_checkudata(L, 1, META_STATEVARS));
int n = luaL_checkinteger(L, 2);
if (n <= 0 || n > MAX_ACTION_VARS)
return luaL_error(L, LUA_QL("state_t") " field 'vars' index %d out of range (1 - %d)", n, MAX_ACTION_VARS);
n--;
LUA_ValueToActionVal(L, 3, &vars[n]);
return 0;
}
static int statevars_len(lua_State *L)
{
lua_pushinteger(L, MAX_ACTION_VARS);
return 1;
}
/////////////// ///////////////
// MOBJ INFO // // MOBJ INFO //
/////////////// ///////////////
...@@ -1916,6 +2076,7 @@ int LUA_InfoLib(lua_State *L) ...@@ -1916,6 +2076,7 @@ int LUA_InfoLib(lua_State *L)
lua_setfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS); lua_setfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS);
LUA_RegisterUserdataMetatable(L, META_STATE, state_get, state_set, state_num); LUA_RegisterUserdataMetatable(L, META_STATE, state_get, state_set, state_num);
LUA_RegisterUserdataMetatable(L, META_STATEVARS, statevars_get, statevars_set, statevars_len);
LUA_RegisterUserdataMetatable(L, META_MOBJINFO, mobjinfo_get, mobjinfo_set, mobjinfo_num); LUA_RegisterUserdataMetatable(L, META_MOBJINFO, mobjinfo_get, mobjinfo_set, mobjinfo_num);
LUA_RegisterUserdataMetatable(L, META_SKINCOLOR, skincolor_get, skincolor_set, skincolor_num); LUA_RegisterUserdataMetatable(L, META_SKINCOLOR, skincolor_get, skincolor_set, skincolor_num);
LUA_RegisterUserdataMetatable(L, META_COLORRAMP, colorramp_get, colorramp_set, colorramp_len); LUA_RegisterUserdataMetatable(L, META_COLORRAMP, colorramp_get, colorramp_set, colorramp_len);
......
...@@ -24,6 +24,7 @@ extern boolean ignoregameinputs; ...@@ -24,6 +24,7 @@ extern boolean ignoregameinputs;
#define LREG_METATABLES "METATABLES" #define LREG_METATABLES "METATABLES"
#define META_STATE "STATE_T*" #define META_STATE "STATE_T*"
#define META_STATEVARS "STATE_T*VARS"
#define META_MOBJINFO "MOBJINFO_T*" #define META_MOBJINFO "MOBJINFO_T*"
#define META_SFXINFO "SFXINFO_T*" #define META_SFXINFO "SFXINFO_T*"
#define META_SKINCOLOR "SKINCOLOR_T*" #define META_SKINCOLOR "SKINCOLOR_T*"
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "doomtype.h" #include "doomtype.h"
#include "d_player.h" #include "d_player.h"
#include "g_state.h" #include "g_state.h"
#include "p_action.h"
#include "taglist.h" #include "taglist.h"
#include "blua/lua.h" #include "blua/lua.h"
...@@ -45,6 +46,9 @@ extern INT32 lua_lumploading; // is LUA_LoadLump being called? ...@@ -45,6 +46,9 @@ extern INT32 lua_lumploading; // is LUA_LoadLump being called?
int LUA_GetErrorMessage(lua_State *L); int LUA_GetErrorMessage(lua_State *L);
int LUA_Call(lua_State *L, int nargs, int nresults, int errorhandlerindex); int LUA_Call(lua_State *L, int nargs, int nresults, int errorhandlerindex);
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor, action_val_t *args, unsigned argcount);
boolean LUA_ValueIsValidActionVal(lua_State *L, int i);
void LUA_ValueToActionVal(lua_State *L, int i, action_val_t *val);
boolean LUA_LoadLump(UINT16 wad, UINT16 lump); boolean LUA_LoadLump(UINT16 wad, UINT16 lump);
void LUA_DoLump(UINT16 wad, UINT16 lump, boolean noresults); void LUA_DoLump(UINT16 wad, UINT16 lump, boolean noresults);
#ifdef LUA_ALLOW_BYTECODE #ifdef LUA_ALLOW_BYTECODE
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "g_game.h" #include "g_game.h"
#include "m_random.h" #include "m_random.h"
#include "p_local.h" #include "p_local.h"
#include "p_action.h"
#include "s_sound.h" #include "s_sound.h"
#include "r_main.h" #include "r_main.h"
#include "st_stuff.h" #include "st_stuff.h"
...@@ -478,8 +479,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) ...@@ -478,8 +479,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_SetMobjState(special, S_FANG_PINCHPATHINGSTART2); P_SetMobjState(special, S_FANG_PINCHPATHINGSTART2);
else else
{ {
var1 = var2 = 4; action_val_t args[2] = {
A_Boss5ExtraRepeat(special); ACTION_INTEGER_VAL(4),
ACTION_INTEGER_VAL(4)
};
A_Boss5ExtraRepeat(special, args, 2);
P_SetMobjState(special, S_FANG_PATHINGCONT2); //S_FANG_PATHINGCONT1 if you want him to drop a bomb on the player P_SetMobjState(special, S_FANG_PATHINGCONT2); //S_FANG_PATHINGCONT1 if you want him to drop a bomb on the player
} }
if (special->eflags & MFE_VERTICALFLIP) if (special->eflags & MFE_VERTICALFLIP)
...@@ -2894,7 +2898,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget ...@@ -2894,7 +2898,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
break; break;
case MT_MINECART: case MT_MINECART:
A_Scream(target); A_Scream(target, NULL, 0);
target->momx = target->momy = target->momz = 0; target->momx = target->momy = target->momz = 0;
if (target->target && target->target->health) if (target->target && target->target->health)
P_KillMobj(target->target, target, source, 0); P_KillMobj(target->target, target, source, 0);
......
...@@ -367,10 +367,6 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration); ...@@ -367,10 +367,6 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration);
// main player in game // main player in game
extern player_t *stplyr; // for splitscreen correct palette changes and overlay extern player_t *stplyr; // for splitscreen correct palette changes and overlay
// Is there a better place for these?
extern INT32 var1;
extern INT32 var2;
boolean P_CheckMeleeRange(mobj_t *actor); boolean P_CheckMeleeRange(mobj_t *actor);
boolean P_JetbCheckMeleeRange(mobj_t *actor); boolean P_JetbCheckMeleeRange(mobj_t *actor);
boolean P_FaceStabCheckMeleeRange(mobj_t *actor); boolean P_FaceStabCheckMeleeRange(mobj_t *actor);
...@@ -379,6 +375,7 @@ boolean P_CheckMissileRange(mobj_t *actor); ...@@ -379,6 +375,7 @@ boolean P_CheckMissileRange(mobj_t *actor);
void P_NewChaseDir(mobj_t *actor); void P_NewChaseDir(mobj_t *actor);
boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed_t dist); boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed_t dist);
boolean P_LookForShield(mobj_t *actor);
mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers, SINT8 moveforward); mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers, SINT8 moveforward);
void P_InternalFlickySetColor(mobj_t *actor, UINT8 color); void P_InternalFlickySetColor(mobj_t *actor, UINT8 color);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "m_random.h" #include "m_random.h"
#include "p_local.h" #include "p_local.h"
#include "p_setup.h" // NiGHTS stuff #include "p_setup.h" // NiGHTS stuff
#include "p_action.h"
#include "r_fps.h" #include "r_fps.h"
#include "r_state.h" #include "r_state.h"
#include "r_main.h" #include "r_main.h"
...@@ -714,8 +715,7 @@ static void P_SlapStick(mobj_t *fang, mobj_t *pole) ...@@ -714,8 +715,7 @@ static void P_SlapStick(mobj_t *fang, mobj_t *pole)
pole->tracer->tracer->tics = pole->tracer->tics = pole->tics = fang->tics; pole->tracer->tracer->tics = pole->tracer->tics = pole->tics = fang->tics;
var1 = var2 = 0; A_Scream(pole->tracer->tracer, NULL, 0);
A_Scream(pole->tracer->tracer);
S_StartSound(fang, sfx_altdi1); S_StartSound(fang, sfx_altdi1);
P_SetTarget(&pole->tracer->tracer, NULL); P_SetTarget(&pole->tracer->tracer, NULL);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "hu_stuff.h" #include "hu_stuff.h"
#include "p_local.h" #include "p_local.h"
#include "p_setup.h" #include "p_setup.h"
#include "p_action.h"
#include "r_fps.h" #include "r_fps.h"
#include "r_main.h" #include "r_main.h"
#include "r_skins.h" #include "r_skins.h"
...@@ -59,11 +60,11 @@ void P_RunCachedActions(void) ...@@ -59,11 +60,11 @@ void P_RunCachedActions(void)
for (ac = actioncachehead.next; ac != &actioncachehead; ac = next) for (ac = actioncachehead.next; ac != &actioncachehead; ac = next)
{ {
var1 = states[ac->statenum].var1;
var2 = states[ac->statenum].var2;
astate = &states[ac->statenum];
if (ac->mobj && !P_MobjWasRemoved(ac->mobj)) // just in case... if (ac->mobj && !P_MobjWasRemoved(ac->mobj)) // just in case...
states[ac->statenum].action.acp1(ac->mobj); {
astate = &states[ac->statenum];
states[ac->statenum].action.acpscr(ac->mobj, states[ac->statenum].vars, MAX_ACTION_VARS);
}
next = ac->next; next = ac->next;
Z_Free(ac); Z_Free(ac);
} }
...@@ -87,31 +88,33 @@ static void P_SetupStateAnimation(mobj_t *mobj, state_t *st) ...@@ -87,31 +88,33 @@ static void P_SetupStateAnimation(mobj_t *mobj, state_t *st)
{ {
INT32 animlength = (mobj->sprite == SPR_PLAY && mobj->skin) INT32 animlength = (mobj->sprite == SPR_PLAY && mobj->skin)
? (INT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes) - 1 ? (INT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes) - 1
: st->var1; : Action_ValueToInteger(st->vars[0]);
if (!(st->frame & FF_ANIMATE)) if (!(st->frame & FF_ANIMATE))
return; return;
if (animlength <= 0 || st->var2 == 0) INT32 var2 = Action_ValueToInteger(st->vars[1]);
if (animlength <= 0 || var2 == 0)
{ {
mobj->frame &= ~FF_ANIMATE; mobj->frame &= ~FF_ANIMATE;
return; // Crash/stupidity prevention return; // Crash/stupidity prevention
} }
mobj->anim_duration = (UINT16)st->var2; mobj->anim_duration = (UINT16)var2;
if (st->frame & FF_GLOBALANIM) if (st->frame & FF_GLOBALANIM)
{ {
// Attempt to account for the pre-ticker for objects spawned on load // Attempt to account for the pre-ticker for objects spawned on load
if (!leveltime) return; if (!leveltime) return;
mobj->anim_duration -= (leveltime + 2) % st->var2; // Duration synced to timer mobj->anim_duration -= (leveltime + 2) % var2; // Duration synced to timer
mobj->frame += ((leveltime + 2) / st->var2) % (animlength + 1); // Frame synced to timer (duration taken into account) mobj->frame += ((leveltime + 2) / var2) % (animlength + 1); // Frame synced to timer (duration taken into account)
} }
else if (st->frame & FF_RANDOMANIM) else if (st->frame & FF_RANDOMANIM)
{ {
mobj->frame += P_RandomKey(animlength + 1); // Random starting frame mobj->frame += P_RandomKey(animlength + 1); // Random starting frame
mobj->anim_duration -= P_RandomKey(st->var2); // Random duration for first frame mobj->anim_duration -= P_RandomKey(var2); // Random duration for first frame
} }
} }
...@@ -124,14 +127,15 @@ FUNCINLINE static ATTRINLINE void P_CycleStateAnimation(mobj_t *mobj) ...@@ -124,14 +127,15 @@ FUNCINLINE static ATTRINLINE void P_CycleStateAnimation(mobj_t *mobj)
if (!(mobj->frame & FF_ANIMATE) || --mobj->anim_duration != 0) if (!(mobj->frame & FF_ANIMATE) || --mobj->anim_duration != 0)
return; return;
mobj->anim_duration = (UINT16)mobj->state->var2; mobj->anim_duration = Action_ValueToInteger(mobj->state->vars[1]);
if (mobj->sprite != SPR_PLAY) if (mobj->sprite != SPR_PLAY)
{ {
// compare the current sprite frame to the one we started from // compare the current sprite frame to the one we started from
// if more than var1 away from it, swap back to the original // if more than var1 away from it, swap back to the original
// else just advance by one // else just advance by one
if (((++mobj->frame) & FF_FRAMEMASK) - (mobj->state->frame & FF_FRAMEMASK) > (UINT32)mobj->state->var1) UINT32 var1 = Action_ValueToInteger(mobj->state->vars[0]);
if (((++mobj->frame) & FF_FRAMEMASK) - (mobj->state->frame & FF_FRAMEMASK) > var1)
mobj->frame = (mobj->state->frame & FF_FRAMEMASK) | (mobj->frame & ~FF_FRAMEMASK); mobj->frame = (mobj->state->frame & FF_FRAMEMASK) | (mobj->frame & ~FF_FRAMEMASK);
return; return;
...@@ -446,13 +450,14 @@ static boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) ...@@ -446,13 +450,14 @@ static boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
{ {
if (st->frame & FF_SPR2ENDSTATE) // no frame advancement if (st->frame & FF_SPR2ENDSTATE) // no frame advancement
{ {
if (st->var1 == mobj->state-states) INT32 var1 = Action_ValueToInteger(st->vars[0]);
if (var1 == mobj->state-states)
frame--; frame--;
else else
{ {
if (mobj->frame & FF_FRAMEMASK) if (mobj->frame & FF_FRAMEMASK)
mobj->frame--; mobj->frame--;
return P_SetPlayerMobjState(mobj, st->var1); return P_SetPlayerMobjState(mobj, var1);
} }
} }
else else
...@@ -475,13 +480,10 @@ static boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) ...@@ -475,13 +480,10 @@ static boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
// Modified handling. // Modified handling.
// Call action functions when the state is set // Call action functions when the state is set
if (st->action.acpscr)
if (st->action.acp1)
{ {
var1 = st->var1;
var2 = st->var2;
astate = st; astate = st;
st->action.acp1(mobj); st->action.acpscr(mobj, st->vars, MAX_ACTION_VARS);
// woah. a player was removed by an action. // woah. a player was removed by an action.
// this sounds like a VERY BAD THING, but there's nothing we can do now... // this sounds like a VERY BAD THING, but there's nothing we can do now...
...@@ -585,13 +587,14 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) ...@@ -585,13 +587,14 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
{ {
if (st->frame & FF_SPR2ENDSTATE) // no frame advancement if (st->frame & FF_SPR2ENDSTATE) // no frame advancement
{ {
if (st->var1 == mobj->state-states) INT32 var1 = Action_ValueToInteger(st->vars[0]);
if (var1 == mobj->state-states)
frame--; frame--;
else else
{ {
if (mobj->frame & FF_FRAMEMASK) if (mobj->frame & FF_FRAMEMASK)
mobj->frame--; mobj->frame--;
return P_SetMobjState(mobj, st->var1); return P_SetMobjState(mobj, var1);
} }
} }
else else
...@@ -612,13 +615,10 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) ...@@ -612,13 +615,10 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
// Modified handling. // Modified handling.
// Call action functions when the state is set // Call action functions when the state is set
if (st->action.acpscr)
if (st->action.acp1)
{ {
var1 = st->var1;
var2 = st->var2;
astate = st; astate = st;
st->action.acp1(mobj); st->action.acpscr(mobj, st->vars, MAX_ACTION_VARS);
if (P_MobjWasRemoved(mobj)) if (P_MobjWasRemoved(mobj))
return false; return false;
} }
...@@ -4260,8 +4260,8 @@ static void P_Boss1Thinker(mobj_t *mobj) ...@@ -4260,8 +4260,8 @@ static void P_Boss1Thinker(mobj_t *mobj)
if (!mobj->tracer) if (!mobj->tracer)
{ {
var1 = 0; action_val_t args[1] = { ACTION_INTEGER_VAL(0) };
A_BossJetFume(mobj); A_BossJetFume(mobj, args, 1);
} }
if (!mobj->target || !(mobj->target->flags & MF_SHOOTABLE)) if (!mobj->target || !(mobj->target->flags & MF_SHOOTABLE))
...@@ -4311,8 +4311,8 @@ static void P_Boss2Thinker(mobj_t *mobj) ...@@ -4311,8 +4311,8 @@ static void P_Boss2Thinker(mobj_t *mobj)
if (!mobj->tracer) if (!mobj->tracer)
{ {
var1 = 0; action_val_t args[1] = { 0 };
A_BossJetFume(mobj); A_BossJetFume(mobj, args, 1);
} }
if (mobj->health <= mobj->info->damage && (!mobj->target || !(mobj->target->flags & MF_SHOOTABLE))) if (mobj->health <= mobj->info->damage && (!mobj->target || !(mobj->target->flags & MF_SHOOTABLE)))
...@@ -4328,11 +4328,11 @@ static void P_Boss2Thinker(mobj_t *mobj) ...@@ -4328,11 +4328,11 @@ static void P_Boss2Thinker(mobj_t *mobj)
} }
if (mobj->state == &states[mobj->info->spawnstate] && mobj->health > mobj->info->damage) if (mobj->state == &states[mobj->info->spawnstate] && mobj->health > mobj->info->damage)
A_Boss2Chase(mobj); A_Boss2Chase(mobj, NULL, 0);
else if (mobj->health > 0 && mobj->state != &states[mobj->info->painstate] && mobj->state != &states[mobjinfo[mobj->info->missilestate].raisestate]) else if (mobj->health > 0 && mobj->state != &states[mobj->info->painstate] && mobj->state != &states[mobjinfo[mobj->info->missilestate].raisestate])
{ {
mobj->flags &= ~MF_NOGRAVITY; mobj->flags &= ~MF_NOGRAVITY;
A_Boss2Pogo(mobj); A_Boss2Pogo(mobj, NULL, 0);
if (mobj->spawnpoint) if (mobj->spawnpoint)
P_LinedefExecute(mobj->spawnpoint->args[4], mobj, NULL); P_LinedefExecute(mobj->spawnpoint->args[4], mobj, NULL);
} }
...@@ -4953,7 +4953,7 @@ static void P_Boss4Thinker(mobj_t *mobj) ...@@ -4953,7 +4953,7 @@ static void P_Boss4Thinker(mobj_t *mobj)
if (!mobj->target || !mobj->target->health) if (!mobj->target || !mobj->target->health)
P_SupermanLook4Players(mobj); P_SupermanLook4Players(mobj);
//A_FaceTarget(mobj); //A_FaceTarget(mobj, NULL, 0);
return; return;
} }
...@@ -5008,8 +5008,8 @@ static void P_Boss4Thinker(mobj_t *mobj) ...@@ -5008,8 +5008,8 @@ static void P_Boss4Thinker(mobj_t *mobj)
if (mobj->spawnpoint) if (mobj->spawnpoint)
P_LinedefExecute(mobj->spawnpoint->args[4], mobj, NULL); P_LinedefExecute(mobj->spawnpoint->args[4], mobj, NULL);
P_Boss4MoveSpikeballs(mobj, FixedAngle(mobj->movecount), 0); P_Boss4MoveSpikeballs(mobj, FixedAngle(mobj->movecount), 0);
var1 = 3; action_val_t args[1] = { ACTION_INTEGER_VAL(3) };
A_BossJetFume(mobj); A_BossJetFume(mobj, args, 1);
return; return;
} }
if (mobj->spawnpoint) if (mobj->spawnpoint)
...@@ -5047,15 +5047,15 @@ static void P_Boss4Thinker(mobj_t *mobj) ...@@ -5047,15 +5047,15 @@ static void P_Boss4Thinker(mobj_t *mobj)
mobj->movedir = 3; mobj->movedir = 3;
if (mobj->spawnpoint) if (mobj->spawnpoint)
P_LinedefExecute(mobj->spawnpoint->args[4], mobj, NULL); P_LinedefExecute(mobj->spawnpoint->args[4], mobj, NULL);
var1 = 3; action_val_t args[1] = { ACTION_INTEGER_VAL(3) };
A_BossJetFume(mobj); A_BossJetFume(mobj, args, 1);
return; return;
} }
mobj->reactiontime = 0; // Drop the cage if it hasn't been dropped already. mobj->reactiontime = 0; // Drop the cage if it hasn't been dropped already.
if (!mobj->target || !mobj->target->health) if (!mobj->target || !mobj->target->health)
P_SupermanLook4Players(mobj); P_SupermanLook4Players(mobj);
A_FaceTarget(mobj); A_FaceTarget(mobj, NULL, 0);
} }
// //
...@@ -5108,8 +5108,8 @@ static void P_Boss5Thinker(mobj_t *mobj) ...@@ -5108,8 +5108,8 @@ static void P_Boss5Thinker(mobj_t *mobj)
{ {
mobj_t *prevtarget = mobj->target; mobj_t *prevtarget = mobj->target;
P_SetTarget(&mobj->target, NULL); P_SetTarget(&mobj->target, NULL);
var1 = var2 = 0; action_val_t args[2] = { ACTION_INTEGER_VAL(0), ACTION_INTEGER_VAL(0) };
A_DoNPCPain(mobj); A_DoNPCPain(mobj, args, 2);
P_SetTarget(&mobj->target, prevtarget); P_SetTarget(&mobj->target, prevtarget);
P_SetMobjState(mobj, S_FANG_WALLHIT); P_SetMobjState(mobj, S_FANG_WALLHIT);
mobj->extravalue2++; mobj->extravalue2++;
...@@ -5153,10 +5153,10 @@ static void P_Boss7Thinker(mobj_t *mobj) ...@@ -5153,10 +5153,10 @@ static void P_Boss7Thinker(mobj_t *mobj)
mobj->reactiontime /= 4; mobj->reactiontime /= 4;
} }
else if (mobj->state == &states[S_BLACKEGG_DIE4] && mobj->tics == mobj->state->tics) else if (mobj->state == &states[S_BLACKEGG_DIE4] && mobj->tics == mobj->state->tics)
A_BossDeath(mobj); A_BossDeath(mobj, NULL, 0);
else if (mobj->state >= &states[S_BLACKEGG_WALK1] else if (mobj->state >= &states[S_BLACKEGG_WALK1]
&& mobj->state <= &states[S_BLACKEGG_WALK6]) && mobj->state <= &states[S_BLACKEGG_WALK6])
A_Boss7Chase(mobj); A_Boss7Chase(mobj, NULL, 0);
else if (mobj->state == &states[S_BLACKEGG_PAIN1] && mobj->tics == mobj->state->tics) else if (mobj->state == &states[S_BLACKEGG_PAIN1] && mobj->tics == mobj->state->tics)
{ {
if (mobj->health > 0) if (mobj->health > 0)
...@@ -5241,11 +5241,11 @@ static void P_Boss7Thinker(mobj_t *mobj) ...@@ -5241,11 +5241,11 @@ static void P_Boss7Thinker(mobj_t *mobj)
if ((leveltime & 15) == 0) if ((leveltime & 15) == 0)
{ {
var1 = MT_CANNONBALL; action_val_t args[2] = {
ACTION_INTEGER_VAL(MT_CANNONBALL),
var2 = 2*TICRATE + (80<<16); ACTION_INTEGER_VAL(2*TICRATE + (80<<16))
};
A_LobShot(mobj); A_LobShot(mobj, args, 2);
S_StartSound(0, sfx_begoop); S_StartSound(0, sfx_begoop);
} }
} }
...@@ -5260,7 +5260,7 @@ static void P_Boss7Thinker(mobj_t *mobj) ...@@ -5260,7 +5260,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
return; return;
} }
A_FaceTarget(mobj); A_FaceTarget(mobj, NULL, 0);
missile = P_SpawnXYZMissile(mobj, mobj->target, MT_BLACKEGGMAN_GOOPFIRE, missile = P_SpawnXYZMissile(mobj, mobj->target, MT_BLACKEGGMAN_GOOPFIRE,
mobj->x + P_ReturnThrustX(mobj, mobj->angle-ANGLE_90, FixedDiv(mobj->radius, 3*FRACUNIT/2)+(4*FRACUNIT)), mobj->x + P_ReturnThrustX(mobj, mobj->angle-ANGLE_90, FixedDiv(mobj->radius, 3*FRACUNIT/2)+(4*FRACUNIT)),
...@@ -5487,8 +5487,8 @@ static void P_Boss9Thinker(mobj_t *mobj) ...@@ -5487,8 +5487,8 @@ static void P_Boss9Thinker(mobj_t *mobj)
mobj->threshold = 0; mobj->threshold = 0;
mobj->reactiontime = 0; mobj->reactiontime = 0;
mobj->watertop = mobj->floorz + 32*FRACUNIT; mobj->watertop = mobj->floorz + 32*FRACUNIT;
var1 = 2; action_val_t args[1] = { ACTION_INTEGER_VAL(2) };
A_BossJetFume(mobj); A_BossJetFume(mobj, args, 1);
// Run through the thinkers ONCE and find all of the MT_BOSS9GATHERPOINT in the map. // Run through the thinkers ONCE and find all of the MT_BOSS9GATHERPOINT in the map.
// Build a hoop linked list of 'em! // Build a hoop linked list of 'em!
...@@ -5783,7 +5783,7 @@ static void P_Boss9Thinker(mobj_t *mobj) ...@@ -5783,7 +5783,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
else else
mobj->reactiontime = TICRATE/8; mobj->reactiontime = TICRATE/8;
A_FaceTarget(mobj); A_FaceTarget(mobj, NULL, 0);
missile = P_SpawnMissile(mobj, mobj->target, mobj->info->speed); missile = P_SpawnMissile(mobj, mobj->target, mobj->info->speed);
if (!P_MobjWasRemoved(missile)) if (!P_MobjWasRemoved(missile))
{ {
...@@ -5952,9 +5952,11 @@ static void P_Boss9Thinker(mobj_t *mobj) ...@@ -5952,9 +5952,11 @@ static void P_Boss9Thinker(mobj_t *mobj)
if (mobj->health <= mobj->info->damage && mobj->fuse && !(mobj->fuse%TICRATE)) if (mobj->health <= mobj->info->damage && mobj->fuse && !(mobj->fuse%TICRATE))
{ {
var1 = 1; action_val_t args[2] = {
var2 = 0; ACTION_INTEGER_VAL(1),
A_BossScream(mobj); ACTION_INTEGER_VAL(0)
};
A_BossScream(mobj, args, 2);
} }
// Don't move if we're still in pain! // Don't move if we're still in pain!
...@@ -6042,7 +6044,7 @@ static void P_Boss9Thinker(mobj_t *mobj) ...@@ -6042,7 +6044,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
mobj->flags |= MF_PAIN; mobj->flags |= MF_PAIN;
if (mobj->info->attacksound) if (mobj->info->attacksound)
S_StartSound(mobj, mobj->info->attacksound); S_StartSound(mobj, mobj->info->attacksound);
A_FaceTarget(mobj); A_FaceTarget(mobj, NULL, 0);
break; break;
...@@ -6131,7 +6133,7 @@ static void P_Boss9Thinker(mobj_t *mobj) ...@@ -6131,7 +6133,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
mobj->angle += angle/8; mobj->angle += angle/8;
else else
mobj->angle -= InvAngle(angle)/8; mobj->angle -= InvAngle(angle)/8;
//A_FaceTarget(mobj); //A_FaceTarget(mobj, NULL, 0);
if (mobj->flags2 & MF2_CLASSICPUSH) if (mobj->flags2 & MF2_CLASSICPUSH)
mobj->flags2 &= ~MF2_CLASSICPUSH; // a missile caught us in PIT_CheckThing! mobj->flags2 &= ~MF2_CLASSICPUSH; // a missile caught us in PIT_CheckThing!
...@@ -6922,7 +6924,7 @@ void P_RunOverlays(void) ...@@ -6922,7 +6924,7 @@ void P_RunOverlays(void)
mo->old_angle = (mo->target->player ? mo->target->player->old_drawangle : mo->target->old_angle) + mo->movedir; mo->old_angle = (mo->target->player ? mo->target->player->old_drawangle : mo->target->old_angle) + mo->movedir;
if (!(mo->state->frame & FF_ANIMATE)) if (!(mo->state->frame & FF_ANIMATE))
zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale); zoffs = FixedMul(Action_ValueToInteger(mo->state->vars[1])*FRACUNIT, mo->scale);
// if you're using FF_ANIMATE on an overlay, // if you're using FF_ANIMATE on an overlay,
// then you're on your own. // then you're on your own.
else else
...@@ -6948,8 +6950,11 @@ void P_RunOverlays(void) ...@@ -6948,8 +6950,11 @@ void P_RunOverlays(void)
mo->z = mo->target->z + zoffs; mo->z = mo->target->z + zoffs;
mo->old_z = mo->target->old_z + zoffs; mo->old_z = mo->target->old_z + zoffs;
} }
if (!(mo->state->frame & FF_ANIMATE) && mo->state->var1) if (!(mo->state->frame & FF_ANIMATE))
P_SetUnderlayPosition(mo); {
if (Action_ValueToInteger(mo->state->vars[0]))
P_SetUnderlayPosition(mo);
}
else else
P_SetThingPosition(mo); P_SetThingPosition(mo);
P_CheckPosition(mo, mo->x, mo->y); P_CheckPosition(mo, mo->x, mo->y);
...@@ -7467,7 +7472,7 @@ static void P_RosySceneryThink(mobj_t *mobj) ...@@ -7467,7 +7472,7 @@ static void P_RosySceneryThink(mobj_t *mobj)
P_SetMobjState(mobj, stat); P_SetMobjState(mobj, stat);
} }
else if (P_MobjFlip(mobj)*mobj->momz < 0) else if (P_MobjFlip(mobj)*mobj->momz < 0)
mobj->frame = mobj->state->frame + mobj->state->var1; mobj->frame = mobj->state->frame + Action_ValueToInteger(mobj->state->vars[0]);
} }
if (!player) if (!player)
...@@ -7519,7 +7524,7 @@ static void P_RosySceneryThink(mobj_t *mobj) ...@@ -7519,7 +7524,7 @@ static void P_RosySceneryThink(mobj_t *mobj)
max = pdist; max = pdist;
if ((--mobj->extravalue1) <= 0) if ((--mobj->extravalue1) <= 0)
{ {
if (++mobj->frame > mobj->state->frame + mobj->state->var1) if (++mobj->frame > mobj->state->frame + Action_ValueToInteger(mobj->state->vars[0]))
mobj->frame = mobj->state->frame; mobj->frame = mobj->state->frame;
if (mom > 12*mobj->scale) if (mom > 12*mobj->scale)
mobj->extravalue1 = 2; mobj->extravalue1 = 2;
...@@ -7580,8 +7585,11 @@ static void P_RosySceneryThink(mobj_t *mobj) ...@@ -7580,8 +7585,11 @@ static void P_RosySceneryThink(mobj_t *mobj)
} }
else else
P_SetMobjState(mobj, (stat = S_ROSY_JUMP)); P_SetMobjState(mobj, (stat = S_ROSY_JUMP));
var1 = var2 = 0; action_val_t args[2] = {
A_DoNPCPain(mobj); ACTION_INTEGER_VAL(0),
ACTION_INTEGER_VAL(0)
};
A_DoNPCPain(mobj, args, 2);
mobj->cvmem -= TICRATE; mobj->cvmem -= TICRATE;
} }
break; break;
...@@ -8223,9 +8231,11 @@ static boolean P_MobjBossThink(mobj_t *mobj) ...@@ -8223,9 +8231,11 @@ static boolean P_MobjBossThink(mobj_t *mobj)
{ {
if (!(mobj->tics & 1)) if (!(mobj->tics & 1))
{ {
var1 = 2; action_val_t args[2] = {
var2 = 0; ACTION_INTEGER_VAL(2),
A_BossScream(mobj); ACTION_INTEGER_VAL(0)
};
A_BossScream(mobj, args, 2);
} }
if (P_CheckDeathPitCollide(mobj)) if (P_CheckDeathPitCollide(mobj))
{ {
...@@ -8544,7 +8554,7 @@ static boolean P_HangsterThink(mobj_t *mobj) ...@@ -8544,7 +8554,7 @@ static boolean P_HangsterThink(mobj_t *mobj)
//swoop arc movement stuff //swoop arc movement stuff
if (st == S_HANGSTER_ARC1) if (st == S_HANGSTER_ARC1)
{ {
A_FaceTarget(mobj); A_FaceTarget(mobj, NULL, 0);
P_Thrust(mobj, mobj->angle, 1*FRACUNIT); P_Thrust(mobj, mobj->angle, 1*FRACUNIT);
} }
else if (st == S_HANGSTER_ARC2) else if (st == S_HANGSTER_ARC2)
...@@ -8675,8 +8685,8 @@ static boolean P_EggRobo1Think(mobj_t *mobj) ...@@ -8675,8 +8685,8 @@ static boolean P_EggRobo1Think(mobj_t *mobj)
mobj->threshold += (mobj->ceilingz - mobj->height); mobj->threshold += (mobj->ceilingz - mobj->height);
else else
mobj->threshold += mobj->floorz; mobj->threshold += mobj->floorz;
var1 = 4; action_val_t args[1] = { ACTION_INTEGER_VAL(4) };
A_BossJetFume(mobj); A_BossJetFume(mobj, args, 1);
mobj->flags2 |= MF2_STRONGBOX; mobj->flags2 |= MF2_STRONGBOX;
} }
...@@ -9211,9 +9221,11 @@ static void P_PterabyteThink(mobj_t *mobj) ...@@ -9211,9 +9221,11 @@ static void P_PterabyteThink(mobj_t *mobj)
fixed_t hspeed = 3*mobj->info->speed; fixed_t hspeed = 3*mobj->info->speed;
angle_t fa; angle_t fa;
var1 = 1; action_val_t args[2] = {
var2 = 0; ACTION_INTEGER_VAL(1),
A_CapeChase(mobj); ACTION_INTEGER_VAL(0)
};
A_CapeChase(mobj, args, 2);
if (mobj->target) if (mobj->target)
return; // Still carrying a player or in cooldown return; // Still carrying a player or in cooldown
...@@ -9279,9 +9291,11 @@ static void P_PterabyteThink(mobj_t *mobj) ...@@ -9279,9 +9291,11 @@ static void P_PterabyteThink(mobj_t *mobj)
} }
else // Returning else // Returning
{ {
var1 = 2*mobj->info->speed; action_val_t args[2] = {
var2 = 1; ACTION_INTEGER_VAL(2*mobj->info->speed),
A_HomingChase(mobj); ACTION_INTEGER_VAL(1)
};
A_HomingChase(mobj, args, 2);
if (P_AproxDistance(mobj->x - mobj->tracer->x, mobj->y - mobj->tracer->y) <= mobj->info->speed) if (P_AproxDistance(mobj->x - mobj->tracer->x, mobj->y - mobj->tracer->y) <= mobj->info->speed)
{ {
mobj->extravalue1 -= 2; mobj->extravalue1 -= 2;
...@@ -9545,11 +9559,13 @@ static boolean P_MobjRegularThink(mobj_t *mobj) ...@@ -9545,11 +9559,13 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0
&& P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius*16) && P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius*16)
{ {
var1 = mobj->info->speed; action_val_t args[2] = {
var2 = 1; ACTION_INTEGER_VAL(mobj->info->speed),
ACTION_INTEGER_VAL(1)
};
// Home in on the target. // Home in on the target.
A_HomingChase(mobj); A_HomingChase(mobj, args, 2);
if (mobj->z < mobj->floorz) if (mobj->z < mobj->floorz)
mobj->z = mobj->floorz; mobj->z = mobj->floorz;
...@@ -9823,7 +9839,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) ...@@ -9823,7 +9839,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->flags2 & MF2_NIGHTSPULL) if (mobj->flags2 & MF2_NIGHTSPULL)
P_NightsItemChase(mobj); P_NightsItemChase(mobj);
else if (mobj->type != MT_BOMBSPHERE) // prevent shields from attracting bomb spheres else if (mobj->type != MT_BOMBSPHERE) // prevent shields from attracting bomb spheres
A_AttractChase(mobj); A_AttractChase(mobj, NULL, 0);
return false; return false;
// Flung items // Flung items
case MT_FLINGRING: case MT_FLINGRING:
...@@ -9837,7 +9853,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) ...@@ -9837,7 +9853,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->flags2 & MF2_NIGHTSPULL) if (mobj->flags2 & MF2_NIGHTSPULL)
P_NightsItemChase(mobj); P_NightsItemChase(mobj);
else else
A_AttractChase(mobj); A_AttractChase(mobj, NULL, 0);
break; break;
case MT_EMBLEM: case MT_EMBLEM:
if (P_EmblemWasCollected(mobj->health - 1) || !P_CanPickupEmblem(&players[consoleplayer], mobj->health - 1)) if (P_EmblemWasCollected(mobj->health - 1) || !P_CanPickupEmblem(&players[consoleplayer], mobj->health - 1))
...@@ -10021,13 +10037,16 @@ static void P_FiringThink(mobj_t *mobj) ...@@ -10021,13 +10037,16 @@ static void P_FiringThink(mobj_t *mobj)
if (mobj->health <= 0) if (mobj->health <= 0)
return; return;
if (mobj->state->action.acp1 == (actionf_p1)A_Boss1Laser) if (mobj->state->action.acpscr == (actionf_script)A_Boss1Laser)
{ {
if (mobj->state->tics > 1) if (mobj->state->tics > 1)
{ {
var1 = mobj->state->var1; INT32 var2 = Action_ValueToInteger(mobj->state->vars[1]);
var2 = mobj->state->var2 & 65535; action_val_t args[2] = {
mobj->state->action.acp1(mobj); mobj->state->vars[0],
ACTION_INTEGER_VAL(var2 & 65535)
};
mobj->state->action.acpscr(mobj, args, 2);
} }
} }
else if (leveltime & 1) // Fire mode else if (leveltime & 1) // Fire mode
...@@ -10196,9 +10215,8 @@ static boolean P_FuseThink(mobj_t *mobj) ...@@ -10196,9 +10215,8 @@ static boolean P_FuseThink(mobj_t *mobj)
case MT_FANG: case MT_FANG:
if (mobj->flags2 & MF2_SLIDEPUSH) if (mobj->flags2 & MF2_SLIDEPUSH)
{ {
var1 = 0; action_val_t args[2] = { ACTION_INTEGER_VAL(0), ACTION_INTEGER_VAL(0) };
var2 = 0; A_BossDeath(mobj, args, 2);
A_BossDeath(mobj);
return false; return false;
} }
P_SetMobjState(mobj, mobj->state->nextstate); P_SetMobjState(mobj, mobj->state->nextstate);
...@@ -10958,9 +10976,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...) ...@@ -10958,9 +10976,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
P_SetTarget(&ball->target, mobj); P_SetTarget(&ball->target, mobj);
ball->movedir = FixedAngle(FixedMul(FixedDiv(i<<FRACBITS, mobj->info->damage<<FRACBITS), 360<<FRACBITS)); ball->movedir = FixedAngle(FixedMul(FixedDiv(i<<FRACBITS, mobj->info->damage<<FRACBITS), 360<<FRACBITS));
ball->threshold = ball->radius + mobj->radius + FixedMul(ball->info->painchance, ball->scale); ball->threshold = ball->radius + mobj->radius + FixedMul(ball->info->painchance, ball->scale);
ball->state->action.acpscr(ball, ball->state->vars, MAX_ACTION_VARS);
var1 = ball->state->var1, var2 = ball->state->var2;
ball->state->action.acp1(ball);
} }
} }
break; break;
...@@ -11205,10 +11221,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...) ...@@ -11205,10 +11221,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
} }
else else
{ {
var1 = st->var1;
var2 = st->var2;
astate = st; astate = st;
st->action.acp1(mobj); st->action.acpscr(mobj, st->vars, MAX_ACTION_VARS);
// DANGER! This can cause P_SpawnMobj to return NULL! // DANGER! This can cause P_SpawnMobj to return NULL!
// Avoid using MF_RUNSPAWNFUNC on mobjs whose spawn state expects target or tracer to already be set! // Avoid using MF_RUNSPAWNFUNC on mobjs whose spawn state expects target or tracer to already be set!
if (P_MobjWasRemoved(mobj)) if (P_MobjWasRemoved(mobj))
......