mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-04-20 09:11:01 +00:00
Implement missing functions
This commit is contained in:
parent
cea4b3227b
commit
62199f7814
5 changed files with 619 additions and 16 deletions
|
@ -183,12 +183,69 @@
|
|||
#define SECSPAC_FloorMissile 1024 // when a projectile touches the floor of this sector
|
||||
#define SECSPAC_CeilingMissile 2048 // when a projectile touches the ceiling of this sector
|
||||
|
||||
// Player powers
|
||||
|
||||
#define POWER_INVULNERABILITY 0
|
||||
#define POWER_SNEAKERS 1
|
||||
#define POWER_FLASHING 2
|
||||
#define POWER_SHIELD 3
|
||||
#define POWER_TAILSFLY 4
|
||||
#define POWER_UNDERWATER 5
|
||||
#define POWER_SPACETIME 6
|
||||
#define POWER_GRAVITYBOOTS 7
|
||||
#define POWER_EMERALDS 8
|
||||
#define POWER_NIGHTS_SUPERLOOP 9
|
||||
#define POWER_NIGHTS_HELPER 10
|
||||
#define POWER_NIGHTS_LINKFREEZE 11
|
||||
#define POWER_AUTOMATICRING 12
|
||||
#define POWER_BOUNCERING 13
|
||||
#define POWER_SCATTERRING 14
|
||||
#define POWER_GRENADERING 15
|
||||
#define POWER_EXPLOSIONRING 16
|
||||
#define POWER_RAILRING 17
|
||||
|
||||
// Player shields
|
||||
|
||||
#define SHIELD_NONE 0
|
||||
#define SHIELD_PITY 1
|
||||
#define SHIELD_WHIRLWIND 2
|
||||
#define SHIELD_ARMAGEDDON 3
|
||||
#define SHIELD_PINK 4
|
||||
|
||||
#define SHIELD_PROTECTFIRE 0x400
|
||||
#define SHIELD_PROTECTWATER 0x800
|
||||
#define SHIELD_PROTECTELECTRIC 0x1000
|
||||
#define SHIELD_PROTECTSPIKE 0x2000
|
||||
|
||||
#define SHIELD_ATTRACT (SHIELD_PITY | SHIELD_PROTECTELECTRIC)
|
||||
#define SHIELD_ELEMENTAL (SHIELD_PITY | SHIELD_PROTECTFIRE | SHIELD_PROTECTWATER)
|
||||
#define SHIELD_FLAMEAURA (SHIELD_PITY | SHIELD_PROTECTFIRE)
|
||||
#define SHIELD_BUBBLEWRAP (SHIELD_PITY | SHIELD_PROTECTWATER)
|
||||
#define SHIELD_THUNDERCOIN (SHIELD_WHIRLWIND | SHIELD_PROTECTELECTRIC)
|
||||
|
||||
#define SHIELD_FORCE 0x100
|
||||
#define SHIELD_FIREFLOWER 0x200
|
||||
|
||||
#define SHIELD_STACK SHIELD_FIREFLOWER
|
||||
#define SHIELD_NOSTACK (~SHIELD_STACK)
|
||||
|
||||
#define SHIELD_FORCEHP 0xFF
|
||||
|
||||
// Teams
|
||||
|
||||
#define NO_TEAM 0
|
||||
#define TEAM_RED 1
|
||||
#define TEAM_BLUE 2
|
||||
|
||||
// Weapons
|
||||
|
||||
#define WEAPON_AUTO 0
|
||||
#define WEAPON_BOUNCE 1
|
||||
#define WEAPON_SCATTER 2
|
||||
#define WEAPON_GRENADE 3
|
||||
#define WEAPON_EXPLODE 4
|
||||
#define WEAPON_RAIL 5
|
||||
|
||||
// Bot types
|
||||
|
||||
#define BOT_NONE 0
|
||||
|
|
|
@ -11,10 +11,13 @@ special
|
|||
-11:SetThingProperty(3),
|
||||
-100:strcmp(2,3),
|
||||
-101:strcasecmp(2,3),
|
||||
-120:PlayerRings(0),
|
||||
-122:PlayerScore(0),
|
||||
-123:PlayerSuper(0),
|
||||
-300:CountEnemies(2),
|
||||
-301:CountPushables(2),
|
||||
// -302:SkinAvailable(1),
|
||||
-303:HasUnlockable(1),
|
||||
-302:HasUnlockable(1),
|
||||
-303:SkinUnlocked(1),
|
||||
-304:PlayerSkin(0),
|
||||
-305:PlayerEmeralds(0),
|
||||
-306:PlayerBot(0),
|
||||
|
@ -34,12 +37,18 @@ special
|
|||
// -324:Thing_Spawn(1), // NOTE: would it be better to implement Spawn? (https://zdoom.org/wiki/Spawn)
|
||||
-325:Thing_TrackAngle(4,6),
|
||||
-326:Thing_StopTrackingAngle(1),
|
||||
// -327:GiveShield(1,2),
|
||||
// -328:GivePowerUp(1,2),
|
||||
-327:CheckPowerUp(1),
|
||||
-328:GivePowerUp(1,2),
|
||||
-329:CheckAmmo(1),
|
||||
-330:GiveAmmo(2),
|
||||
-331:TakeAmmo(2),
|
||||
-332:DoSuperTransformation(0,1),
|
||||
-333:DoSuperDetransformation(0),
|
||||
-500:CameraWait(1),
|
||||
-503:SetLineRenderStyle(3),
|
||||
-504:MapWarp(2),
|
||||
-505:AddBot(1, 4),
|
||||
-506:RemoveBot(1),
|
||||
-507:ExitLevel(0,1),
|
||||
-508:MusicPlay(1,2),
|
||||
-509:MusicStopAll(0,1),
|
||||
|
|
|
@ -169,7 +169,7 @@ static bool ACS_GetSpriteFromString(const char *word, spritenum_t *type)
|
|||
|
||||
for (int i = 0; i < NUMSPRITES; i++)
|
||||
{
|
||||
if (fastncmp(word, sprnames[i], 4))
|
||||
if (strcmp(word, sprnames[i]) == 0)
|
||||
{
|
||||
*type = static_cast<spritenum_t>(i);
|
||||
return true;
|
||||
|
@ -1269,6 +1269,30 @@ bool CallFunc_PlayerScore(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM:
|
|||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_PlayerScore(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Returns if the activating player is super.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_PlayerSuper(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
bool super = false;
|
||||
|
||||
(void)argV;
|
||||
(void)argC;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
super = (info->mo->player->powers[pw_super] != 0);
|
||||
}
|
||||
|
||||
thread->dataStk.push(super);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_PlayerNumber(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
|
@ -1501,6 +1525,33 @@ bool CallFunc_HasUnlockable(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSV
|
|||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_SkinUnlocked(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Checks if a certain skin has been unlocked.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_SkinUnlocked(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
bool unlocked = false;
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
(void)argC;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
INT32 skinNum;
|
||||
if (ACS_GetSkinFromString(thread->scopeMap->getString( argV[0] )->str, &skinNum) == true)
|
||||
{
|
||||
unlocked = R_SkinUsable(info->mo->player - players, skinNum);
|
||||
}
|
||||
}
|
||||
|
||||
thread->dataStk.push(unlocked);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_PlayerSkin(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
|
@ -2074,6 +2125,38 @@ bool CallFunc_AddBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word
|
|||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_RemoveBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Removes a bot.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_RemoveBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
(void)argC;
|
||||
|
||||
int playernum = argV[0];
|
||||
|
||||
if (playernum < 0 || playernum >= MAXPLAYERS)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "RemoveBot player %d out of range (expected 0 - %d).\n", playernum, MAXPLAYERS-1);
|
||||
}
|
||||
else if (playeringame[playernum])
|
||||
{
|
||||
if (players[playernum].bot == BOT_NONE)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "RemoveBot cannot remove human\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
players[playernum].removing = true;
|
||||
}
|
||||
}
|
||||
|
||||
thread->dataStk.push(0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
|
@ -3157,9 +3240,7 @@ bool CallFunc_GetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A
|
|||
#define PROP_SPR(x, y) \
|
||||
case x: \
|
||||
{ \
|
||||
char crunched[5] = {0}; \
|
||||
strncpy(crunched, sprnames[ mobj->y ], 4); \
|
||||
value = static_cast<INT32>( ~env->getString( crunched )->idx ); \
|
||||
value = static_cast<INT32>( ~env->getString( sprnames[ mobj->y ] )->idx ); \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
@ -3560,6 +3641,442 @@ bool CallFunc_SetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A
|
|||
return false;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
POWER_INVULNERABILITY,
|
||||
POWER_SNEAKERS,
|
||||
POWER_FLASHING,
|
||||
POWER_SHIELD,
|
||||
POWER_TAILSFLY,
|
||||
POWER_UNDERWATER,
|
||||
POWER_SPACETIME,
|
||||
POWER_GRAVITYBOOTS,
|
||||
POWER_EMERALDS,
|
||||
POWER_NIGHTS_SUPERLOOP,
|
||||
POWER_NIGHTS_HELPER,
|
||||
POWER_NIGHTS_LINKFREEZE,
|
||||
POWER_AUTOMATICRING,
|
||||
POWER_BOUNCERING,
|
||||
POWER_SCATTERRING,
|
||||
POWER_GRENADERING,
|
||||
POWER_EXPLOSIONRING,
|
||||
POWER_RAILRING,
|
||||
POWER__MAX
|
||||
};
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_CheckPowerUp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Checks the amount of the activator's given power-up.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_CheckPowerUp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
(void)argC;
|
||||
|
||||
INT32 value = 0;
|
||||
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
INT32 property = argV[0];
|
||||
|
||||
player_t *player = info->mo->player;
|
||||
|
||||
#define POWER(x, y) \
|
||||
case x: \
|
||||
{ \
|
||||
value = player->powers[y]; \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define WEAPON(x, y) \
|
||||
case x: \
|
||||
{ \
|
||||
value = (player->ringweapons & y) != 0; \
|
||||
break; \
|
||||
}
|
||||
|
||||
switch (property)
|
||||
{
|
||||
POWER(POWER_INVULNERABILITY, pw_invulnerability)
|
||||
POWER(POWER_SNEAKERS, pw_sneakers)
|
||||
POWER(POWER_FLASHING, pw_flashing)
|
||||
POWER(POWER_SHIELD, pw_shield)
|
||||
POWER(POWER_TAILSFLY, pw_tailsfly)
|
||||
POWER(POWER_UNDERWATER, pw_underwater)
|
||||
POWER(POWER_SPACETIME, pw_spacetime)
|
||||
POWER(POWER_GRAVITYBOOTS, pw_gravityboots)
|
||||
POWER(POWER_EMERALDS, pw_emeralds)
|
||||
POWER(POWER_NIGHTS_SUPERLOOP, pw_nights_superloop)
|
||||
POWER(POWER_NIGHTS_HELPER, pw_nights_helper)
|
||||
POWER(POWER_NIGHTS_LINKFREEZE, pw_nights_linkfreeze)
|
||||
WEAPON(POWER_AUTOMATICRING, WEP_AUTO)
|
||||
WEAPON(POWER_BOUNCERING, WEP_BOUNCE)
|
||||
WEAPON(POWER_SCATTERRING, WEP_SCATTER)
|
||||
WEAPON(POWER_GRENADERING, WEP_GRENADE)
|
||||
WEAPON(POWER_EXPLOSIONRING, WEP_EXPLODE)
|
||||
WEAPON(POWER_RAILRING, WEP_RAIL)
|
||||
default:
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "CheckPowerUp type %d out of range (expected 0 - %d).\n", property, POWER__MAX-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#undef POWER
|
||||
#undef WEAPON
|
||||
}
|
||||
|
||||
thread->dataStk.push(value);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void ACS_SetPowerUp(player_t *player, INT32 property, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Helper for CallFunc_GivePowerUp.
|
||||
--------------------------------------------------*/
|
||||
static void ACS_SetPowerUp(player_t *player, INT32 property, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
#define POWER(x, y, z) \
|
||||
case x: \
|
||||
{ \
|
||||
if (argC >= 2) \
|
||||
player->powers[y] = argV[1]; \
|
||||
else \
|
||||
player->powers[y] = z; \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define WEAPON(x, y) \
|
||||
case x: \
|
||||
{ \
|
||||
if (argC >= 2 && (argV[1] > 0)) \
|
||||
player->ringweapons |= y; \
|
||||
else \
|
||||
player->ringweapons &= ~y; \
|
||||
break; \
|
||||
}
|
||||
|
||||
switch (property)
|
||||
{
|
||||
POWER(POWER_INVULNERABILITY, pw_invulnerability, invulntics)
|
||||
POWER(POWER_SNEAKERS, pw_sneakers, sneakertics)
|
||||
POWER(POWER_FLASHING, pw_flashing, flashingtics)
|
||||
POWER(POWER_SHIELD, pw_shield, 0)
|
||||
POWER(POWER_TAILSFLY, pw_tailsfly, tailsflytics)
|
||||
POWER(POWER_UNDERWATER, pw_underwater, underwatertics)
|
||||
POWER(POWER_SPACETIME, pw_spacetime, spacetimetics)
|
||||
POWER(POWER_GRAVITYBOOTS, pw_gravityboots, 20*TICRATE)
|
||||
POWER(POWER_EMERALDS, pw_emeralds, 0)
|
||||
POWER(POWER_NIGHTS_SUPERLOOP, pw_nights_superloop, 0)
|
||||
POWER(POWER_NIGHTS_HELPER, pw_nights_helper, 0)
|
||||
POWER(POWER_NIGHTS_LINKFREEZE, pw_nights_linkfreeze, 0)
|
||||
WEAPON(POWER_AUTOMATICRING, WEP_AUTO)
|
||||
WEAPON(POWER_BOUNCERING, WEP_BOUNCE)
|
||||
WEAPON(POWER_SCATTERRING, WEP_SCATTER)
|
||||
WEAPON(POWER_GRENADERING, WEP_GRENADE)
|
||||
WEAPON(POWER_EXPLOSIONRING, WEP_EXPLODE)
|
||||
WEAPON(POWER_RAILRING, WEP_RAIL)
|
||||
default:
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "GivePowerUp type %d out of range (expected 0 - %d).\n", property, POWER__MAX-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Give the player a shield
|
||||
if (property == POWER_SHIELD && player->powers[pw_shield] != SH_NONE)
|
||||
{
|
||||
P_SpawnShieldOrb(player);
|
||||
}
|
||||
|
||||
#undef POWER
|
||||
#undef AMMO
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_GivePowerUp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Awards a power-up to the activator.
|
||||
Like GiveInventory, if this is called with no activator, this awards the power-up to all players.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_GivePowerUp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
INT32 property = argV[0];
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
ACS_SetPowerUp(info->mo->player, property, argV, argC);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UINT8 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
ACS_SetPowerUp(&players[i], property, argV, argC);
|
||||
}
|
||||
}
|
||||
|
||||
thread->dataStk.push(0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
WEAPON_AUTO,
|
||||
WEAPON_BOUNCE,
|
||||
WEAPON_SCATTER,
|
||||
WEAPON_GRENADE,
|
||||
WEAPON_EXPLODE,
|
||||
WEAPON_RAIL,
|
||||
WEAPON__MAX
|
||||
};
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_CheckAmmo(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Checks the ammo of the activator's weapon.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_CheckAmmo(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
(void)argC;
|
||||
|
||||
INT32 value = 0;
|
||||
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
INT32 weapon = argV[0];
|
||||
|
||||
player_t *player = info->mo->player;
|
||||
|
||||
#define AMMO(x, y) \
|
||||
case x: \
|
||||
{ \
|
||||
value = player->powers[y]; \
|
||||
break; \
|
||||
}
|
||||
|
||||
switch (weapon)
|
||||
{
|
||||
AMMO(WEAPON_AUTO, pw_automaticring)
|
||||
AMMO(WEAPON_BOUNCE, pw_bouncering)
|
||||
AMMO(WEAPON_SCATTER, pw_scatterring)
|
||||
AMMO(WEAPON_GRENADE, pw_grenadering)
|
||||
AMMO(WEAPON_EXPLODE, pw_explosionring)
|
||||
AMMO(WEAPON_RAIL, pw_railring)
|
||||
default:
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "GiveAmmo weapon %d out of range (expected 0 - %d).\n", weapon, WEAPON__MAX-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#undef AMMO
|
||||
}
|
||||
|
||||
thread->dataStk.push(value);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void ACS_GiveAmmo(player_t *player, INT32 weapon, INT32 value)
|
||||
|
||||
Helper for CallFunc_GiveAmmo/CallFunc_TakeAmmo.
|
||||
--------------------------------------------------*/
|
||||
static bool ACS_GiveAmmo(player_t *player, INT32 weapon, INT32 value)
|
||||
{
|
||||
#define AMMO(x, y) \
|
||||
case x: \
|
||||
{ \
|
||||
player->powers[y] += value; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
switch (weapon)
|
||||
{
|
||||
AMMO(WEAPON_AUTO, pw_automaticring)
|
||||
AMMO(WEAPON_BOUNCE, pw_bouncering)
|
||||
AMMO(WEAPON_SCATTER, pw_scatterring)
|
||||
AMMO(WEAPON_GRENADE, pw_grenadering)
|
||||
AMMO(WEAPON_EXPLODE, pw_explosionring)
|
||||
AMMO(WEAPON_RAIL, pw_railring)
|
||||
}
|
||||
|
||||
#undef AMMO
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_GiveAmmo(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Gives ammo to the activator.
|
||||
Like GiveInventory, if this is called with no activator, this awards ammo to all players.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_GiveAmmo(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
INT32 weapon = argV[0];
|
||||
INT32 value = argC >= 2 ? (argV[1]) : 0;
|
||||
|
||||
bool fail = false;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
fail = !ACS_GiveAmmo(info->mo->player, weapon, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UINT8 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
if (!ACS_GiveAmmo(&players[i], weapon, value))
|
||||
{
|
||||
fail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fail)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "GiveAmmo weapon %d out of range (expected 0 - %d).\n", weapon, WEAPON__MAX-1);
|
||||
}
|
||||
|
||||
thread->dataStk.push(0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_TakeAmmo(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Takes ammo from the activator.
|
||||
Like TakeInventory, if this is called with no activator, this takes ammo from all players.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_TakeAmmo(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
INT32 weapon = argV[0];
|
||||
INT32 value = argC >= 2 ? (argV[1]) : 0;
|
||||
|
||||
bool fail = false;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
fail = !ACS_GiveAmmo(info->mo->player, weapon, -value);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UINT8 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
if (!ACS_GiveAmmo(&players[i], weapon, -value))
|
||||
{
|
||||
fail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fail)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "TakeAmmo weapon %d out of range (expected 0 - %d).\n", weapon, WEAPON__MAX-1);
|
||||
}
|
||||
|
||||
thread->dataStk.push(0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_DoSuperTransformation(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Turns the activator super.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_DoSuperTransformation(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
bool giverings = argC >= 2 ? (argV[1] != 0) : false;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
P_DoSuperTransformation(info->mo->player, giverings);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UINT8 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
P_DoSuperTransformation(&players[i], giverings);
|
||||
}
|
||||
}
|
||||
|
||||
thread->dataStk.push(0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_DoSuperTransformation(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Detransforms the activator if super.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_DoSuperDetransformation(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
(void)argV;
|
||||
(void)argC;
|
||||
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
P_DoSuperDetransformation(info->mo->player);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UINT8 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
P_DoSuperDetransformation(&players[i]);
|
||||
}
|
||||
}
|
||||
|
||||
thread->dataStk.push(0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static angle_t ACS_GetAngle(int angle)
|
||||
|
||||
|
@ -3742,7 +4259,7 @@ bool CallFunc_OppositeColor(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSV
|
|||
|
||||
if (color < 1 || color >= numskincolors)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "OppositeColor: out of range\n");
|
||||
CONS_Alert(CONS_WARNING, "OppositeColor color %d out of range (expected 1 - %d).\n", color, numskincolors-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -63,6 +63,7 @@ bool CallFunc_EndPrintBold(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM
|
|||
bool CallFunc_PlayerTeam(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_PlayerRings(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_PlayerScore(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_PlayerSuper(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_PlayerNumber(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_ActivatorTID(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_EndLog(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
@ -73,6 +74,7 @@ bool CallFunc_strcasecmp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
|
|||
bool CallFunc_CountEnemies(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_CountPushables(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_HasUnlockable(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_SkinUnlocked(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_PlayerSkin(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_PlayerBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_PlayerExiting(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
@ -96,6 +98,7 @@ bool CallFunc_SetLineRenderStyle(ACSVM::Thread *thread, const ACSVM::Word *argV,
|
|||
|
||||
bool CallFunc_MapWarp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_AddBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_RemoveBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_MusicStopAll(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
@ -111,6 +114,16 @@ bool CallFunc_SetSectorProperty(ACSVM::Thread *thread, const ACSVM::Word *argV,
|
|||
bool CallFunc_GetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_SetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
||||
bool CallFunc_CheckPowerUp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_GivePowerUp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
||||
bool CallFunc_CheckAmmo(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_GiveAmmo(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_TakeAmmo(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
||||
bool CallFunc_DoSuperTransformation(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_DoSuperDetransformation(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
||||
bool CallFunc_Sin(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_Cos(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_Tan(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
|
|
@ -96,9 +96,6 @@ Environment::Environment()
|
|||
// Skulltag p-codes begin here
|
||||
addCodeDataACS0(118, {"", 0, addCallFunc(CallFunc_IsNetworkGame)});
|
||||
addCodeDataACS0(119, {"", 0, addCallFunc(CallFunc_PlayerTeam)});
|
||||
addCodeDataACS0(120, {"", 0, addCallFunc(CallFunc_PlayerRings)});
|
||||
|
||||
addCodeDataACS0(122, {"", 0, addCallFunc(CallFunc_PlayerScore)});
|
||||
|
||||
// 136 to 137: Implemented by ACSVM
|
||||
|
||||
|
@ -160,10 +157,14 @@ Environment::Environment()
|
|||
addFuncDataACS0( 100, addCallFunc(CallFunc_strcmp));
|
||||
addFuncDataACS0( 101, addCallFunc(CallFunc_strcasecmp));
|
||||
|
||||
addFuncDataACS0( 120, addCallFunc(CallFunc_PlayerRings));
|
||||
addFuncDataACS0( 122, addCallFunc(CallFunc_PlayerScore));
|
||||
addFuncDataACS0( 123, addCallFunc(CallFunc_PlayerSuper));
|
||||
|
||||
addFuncDataACS0( 300, addCallFunc(CallFunc_CountEnemies));
|
||||
addFuncDataACS0( 301, addCallFunc(CallFunc_CountPushables));
|
||||
// addFuncDataACS0( 302, addCallFunc(CallFunc_SkinAvailable));
|
||||
addFuncDataACS0( 303, addCallFunc(CallFunc_HasUnlockable));
|
||||
addFuncDataACS0( 302, addCallFunc(CallFunc_HasUnlockable));
|
||||
addFuncDataACS0( 303, addCallFunc(CallFunc_SkinUnlocked));
|
||||
addFuncDataACS0( 304, addCallFunc(CallFunc_PlayerSkin));
|
||||
addFuncDataACS0( 305, addCallFunc(CallFunc_PlayerEmeralds));
|
||||
addFuncDataACS0( 306, addCallFunc(CallFunc_PlayerBot));
|
||||
|
@ -183,13 +184,19 @@ Environment::Environment()
|
|||
// addFuncDataACS0( 324, addCallFunc(CallFunc_SpawnObject));
|
||||
addFuncDataACS0( 325, addCallFunc(CallFunc_TrackObjectAngle));
|
||||
addFuncDataACS0( 326, addCallFunc(CallFunc_StopTrackingObjectAngle));
|
||||
// addFuncDataACS0( 327, addCallFunc(CallFunc_GiveShield));
|
||||
// addFuncDataACS0( 328, addCallFunc(CallFunc_GivePowerUp));
|
||||
addFuncDataACS0( 327, addCallFunc(CallFunc_CheckPowerUp));
|
||||
addFuncDataACS0( 328, addCallFunc(CallFunc_GivePowerUp));
|
||||
addFuncDataACS0( 329, addCallFunc(CallFunc_CheckAmmo));
|
||||
addFuncDataACS0( 330, addCallFunc(CallFunc_GiveAmmo));
|
||||
addFuncDataACS0( 331, addCallFunc(CallFunc_TakeAmmo));
|
||||
addFuncDataACS0( 332, addCallFunc(CallFunc_DoSuperTransformation));
|
||||
addFuncDataACS0( 333, addCallFunc(CallFunc_DoSuperDetransformation));
|
||||
|
||||
addFuncDataACS0( 500, addCallFunc(CallFunc_CameraWait));
|
||||
addFuncDataACS0( 503, addCallFunc(CallFunc_SetLineRenderStyle));
|
||||
addFuncDataACS0( 504, addCallFunc(CallFunc_MapWarp));
|
||||
addFuncDataACS0( 505, addCallFunc(CallFunc_AddBot));
|
||||
addFuncDataACS0( 506, addCallFunc(CallFunc_RemoveBot));
|
||||
addFuncDataACS0( 507, addCallFunc(CallFunc_ExitLevel));
|
||||
addFuncDataACS0( 508, addCallFunc(CallFunc_MusicPlay));
|
||||
addFuncDataACS0( 509, addCallFunc(CallFunc_MusicStopAll));
|
||||
|
|
Loading…
Reference in a new issue