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),
|
void { 55, 56}:Delay(int),
|
||||||
int { 57, 58}:Random(int, int),
|
int { 57, 58}:Random(int, int),
|
||||||
fixed { 57, 58}:RandomFixed(fixed, fixed),
|
fixed { 57, 58}:RandomFixed(fixed, fixed),
|
||||||
int { 59, 60}:ThingCount(int, int),
|
int { 59, 60}:ThingCount(str, int),
|
||||||
void { 61, 62}:TagWait(int),
|
void { 61, 62}:TagWait(int),
|
||||||
void { 63, 64}:PolyWait(int),
|
void { 63, 64}:PolyWait(int),
|
||||||
void { 65, 66}:ChangeFloor(int, str),
|
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 "r_state.h"
|
||||||
#include "p_polyobj.h"
|
#include "p_polyobj.h"
|
||||||
#include "taglist.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)
|
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;
|
(void)argC;
|
||||||
|
|
||||||
low = (INT32)argV[0];
|
low = argV[0];
|
||||||
high = (INT32)argV[1];
|
high = argV[1];
|
||||||
|
|
||||||
ACSVM_Thread_DataStk_Push(thread, P_RandomRange(PR_ACS, low, high));
|
ACSVM_Thread_DataStk_Push(thread, P_RandomRange(PR_ACS, low, high));
|
||||||
return false;
|
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)
|
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;
|
const char *texName = NULL;
|
||||||
|
|
||||||
INT32 secnum = -1;
|
INT32 secnum = -1;
|
||||||
INT32 tag = 0;
|
mtag_t tag = 0;
|
||||||
|
|
||||||
(void)argC;
|
(void)argC;
|
||||||
|
|
||||||
|
|
@ -130,7 +296,7 @@ bool ACS_CF_ChangeCeiling(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Wo
|
||||||
const char *texName = NULL;
|
const char *texName = NULL;
|
||||||
|
|
||||||
INT32 secnum = -1;
|
INT32 secnum = -1;
|
||||||
INT32 tag = 0;
|
mtag_t tag = 0;
|
||||||
|
|
||||||
(void)argC;
|
(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
|
// Not that we're adding any modules to it, though. :p
|
||||||
ACSVM_GlobalScope_SetActive(global, true);
|
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:
|
// See also:
|
||||||
// - https://doomwiki.org/wiki/ACS0_instruction_set
|
// - https://doomwiki.org/wiki/ACS0_instruction_set
|
||||||
// - https://github.com/DavidPH/ACSVM/blob/master/ACSVM/CodeData.hpp
|
// - 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
|
// 0 to 56: Implemented by ACSVM
|
||||||
ACS_AddCodeDataCallFunc(env, 57, "", 2, ACS_CF_Random);
|
ACS_AddCodeDataCallFunc(env, 57, "", 2, ACS_CF_Random);
|
||||||
ACS_AddCodeDataCallFunc(env, 58, "WW", 0, 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, 61, "", 1, ACS_CF_TagWait);
|
||||||
ACS_AddCodeDataCallFunc(env, 62, "W", 0, ACS_CF_TagWait);
|
ACS_AddCodeDataCallFunc(env, 62, "W", 0, ACS_CF_TagWait);
|
||||||
ACS_AddCodeDataCallFunc(env, 63, "", 1, ACS_CF_PolyWait);
|
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_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_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_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);
|
bool ACS_CF_ChangeFloor(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue