mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Add ThingCount
Hexen implements this as ThingCount(int, int), and ZDoom adds ThingCountName(str, int). I decided on simplifying down to ThingCount(str, int).
This commit is contained in:
parent
1d373d2c81
commit
a315482aa4
4 changed files with 180 additions and 7 deletions
|
|
@ -205,7 +205,7 @@ special
|
|||
void { 55, 56}:Delay(int),
|
||||
int { 57, 58}:Random(int, int),
|
||||
fixed { 57, 58}:RandomFixed(fixed, fixed),
|
||||
int { 59, 60}:ThingCount(int, int),
|
||||
int { 59, 60}:ThingCount(str, int),
|
||||
void { 61, 62}:TagWait(int),
|
||||
void { 63, 64}:PolyWait(int),
|
||||
void { 65, 66}:ChangeFloor(int, str),
|
||||
|
|
|
|||
174
src/k_acs-func.c
174
src/k_acs-func.c
|
|
@ -27,6 +27,93 @@
|
|||
#include "r_state.h"
|
||||
#include "p_polyobj.h"
|
||||
#include "taglist.h"
|
||||
#include "p_local.h"
|
||||
#include "deh_tables.h"
|
||||
#include "fastcmp.h"
|
||||
|
||||
/*--------------------------------------------------
|
||||
static bool ACS_GetMobjTypeFromString(const char *word, mobjtype_t *type)
|
||||
|
||||
Helper function for ACS_CF_ThingCount. Gets
|
||||
an object type from a string.
|
||||
|
||||
Input Arguments:-
|
||||
word: The mobj class string.
|
||||
type: Variable to store the result in.
|
||||
|
||||
Return:-
|
||||
true if successful, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
static bool ACS_GetMobjTypeFromString(const char *word, mobjtype_t *type)
|
||||
{
|
||||
mobjtype_t i;
|
||||
|
||||
if (fastncmp("MT_", word, 3))
|
||||
{
|
||||
// take off the MT_
|
||||
word += 3;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMMOBJFREESLOTS; i++)
|
||||
{
|
||||
if (!FREE_MOBJS[i])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (fastcmp(word, FREE_MOBJS[i]))
|
||||
{
|
||||
*type = MT_FIRSTFREESLOT+i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MT_FIRSTFREESLOT; i++)
|
||||
{
|
||||
if (fastcmp(word, MOBJTYPE_LIST[i]+3))
|
||||
{
|
||||
*type = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static bool ACS_CountThing(mobj_t *mobj, mobjtype_t type)
|
||||
|
||||
Helper function for ACS_CF_ThingCount.
|
||||
Returns whenever or not to add this thing
|
||||
to the thing count.
|
||||
|
||||
Input Arguments:-
|
||||
mobj: The mobj we want to count.
|
||||
type: Type exclusion.
|
||||
|
||||
Return:-
|
||||
true if successful, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
static bool ACS_CountThing(mobj_t *mobj, mobjtype_t type)
|
||||
{
|
||||
if (type == MT_NULL || mobj->type == type)
|
||||
{
|
||||
// Don't count dead monsters
|
||||
if (mobj->info->spawnhealth > 0 && mobj->health <= 0)
|
||||
{
|
||||
// Note: Hexen checks for COUNTKILL.
|
||||
// SRB2 does not have an equivalent, so I'm checking
|
||||
// spawnhealth. Feel free to replace this condition
|
||||
// with literally anything else.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Count this object.
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool ACS_CF_Random(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
|
|
@ -40,13 +127,92 @@ bool ACS_CF_Random(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC
|
|||
|
||||
(void)argC;
|
||||
|
||||
low = (INT32)argV[0];
|
||||
high = (INT32)argV[1];
|
||||
low = argV[0];
|
||||
high = argV[1];
|
||||
|
||||
ACSVM_Thread_DataStk_Push(thread, P_RandomRange(PR_ACS, low, high));
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool ACS_CF_ThingCount(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
|
||||
Counts the number of things of a particular
|
||||
type and tid. Both fields are optional;
|
||||
no type means indescriminate against type,
|
||||
no tid means search thru all thinkers.
|
||||
--------------------------------------------------*/
|
||||
bool ACS_CF_ThingCount(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
{
|
||||
ACSVM_MapScope *map = NULL;
|
||||
ACSVM_String *str = NULL;
|
||||
const char *className = NULL;
|
||||
size_t classLen = 0;
|
||||
|
||||
mobjtype_t type = MT_NULL;
|
||||
mtag_t tid = 0;
|
||||
|
||||
size_t count = 0;
|
||||
|
||||
(void)argC;
|
||||
|
||||
map = ACSVM_Thread_GetScopeMap(thread);
|
||||
str = ACSVM_MapScope_GetString(map, argV[0]);
|
||||
|
||||
className = ACSVM_String_GetStr(str);
|
||||
classLen = ACSVM_String_GetLen(str);
|
||||
|
||||
if (classLen > 0)
|
||||
{
|
||||
bool success = ACS_GetMobjTypeFromString(className, &type);
|
||||
|
||||
if (success == false)
|
||||
{
|
||||
// Exit early.
|
||||
|
||||
CONS_Alert(CONS_WARNING,
|
||||
"Couldn't find object type \"%s\" for ThingCount.\n",
|
||||
className
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
tid = argV[1];
|
||||
|
||||
if (tid != 0)
|
||||
{
|
||||
// TODO: Even in SRB2 next's UDMF, tag lists
|
||||
// still aren't attached to mobj_t, only
|
||||
// mapthing_t. Fix this.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Search thinkers instead of tag lists.
|
||||
thinker_t *th = NULL;
|
||||
mobj_t *mobj = NULL;
|
||||
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
mobj = (mobj_t *)th;
|
||||
|
||||
if (ACS_CountThing(mobj, type) == true)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ACSVM_Thread_DataStk_Push(thread, count);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool ACS_CF_TagWait(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
|
||||
|
|
@ -99,7 +265,7 @@ bool ACS_CF_ChangeFloor(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word
|
|||
const char *texName = NULL;
|
||||
|
||||
INT32 secnum = -1;
|
||||
INT32 tag = 0;
|
||||
mtag_t tag = 0;
|
||||
|
||||
(void)argC;
|
||||
|
||||
|
|
@ -130,7 +296,7 @@ bool ACS_CF_ChangeCeiling(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Wo
|
|||
const char *texName = NULL;
|
||||
|
||||
INT32 secnum = -1;
|
||||
INT32 tag = 0;
|
||||
mtag_t tag = 0;
|
||||
|
||||
(void)argC;
|
||||
|
||||
|
|
|
|||
10
src/k_acs.c
10
src/k_acs.c
|
|
@ -202,7 +202,12 @@ static void ACS_EnvConstruct(ACSVM_Environment *env)
|
|||
// Not that we're adding any modules to it, though. :p
|
||||
ACSVM_GlobalScope_SetActive(global, true);
|
||||
|
||||
// Add the data & function pointers
|
||||
// Add the data & function pointers.
|
||||
|
||||
// Starting with raw ACS0 codes. I'm using this classic-style
|
||||
// format here to have a blueprint for what needs implementing,
|
||||
// but it'd also be fine to move these to new style.
|
||||
|
||||
// See also:
|
||||
// - https://doomwiki.org/wiki/ACS0_instruction_set
|
||||
// - https://github.com/DavidPH/ACSVM/blob/master/ACSVM/CodeData.hpp
|
||||
|
|
@ -211,7 +216,8 @@ static void ACS_EnvConstruct(ACSVM_Environment *env)
|
|||
// 0 to 56: Implemented by ACSVM
|
||||
ACS_AddCodeDataCallFunc(env, 57, "", 2, ACS_CF_Random);
|
||||
ACS_AddCodeDataCallFunc(env, 58, "WW", 0, ACS_CF_Random);
|
||||
|
||||
ACS_AddCodeDataCallFunc(env, 59, "", 2, ACS_CF_ThingCount);
|
||||
ACS_AddCodeDataCallFunc(env, 60, "WW", 0, ACS_CF_ThingCount);
|
||||
ACS_AddCodeDataCallFunc(env, 61, "", 1, ACS_CF_TagWait);
|
||||
ACS_AddCodeDataCallFunc(env, 62, "W", 0, ACS_CF_TagWait);
|
||||
ACS_AddCodeDataCallFunc(env, 63, "", 1, ACS_CF_PolyWait);
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ void ACS_Tick(void);
|
|||
--------------------------------------------------*/
|
||||
|
||||
bool ACS_CF_Random(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_ThingCount(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_TagWait(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_PolyWait(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_ChangeFloor(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue