mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-07 07:22:54 +00:00
Merge branch 'acs-thing-count' into 'master'
ACS: Better thing counting + a couple ZDoom ports See merge request KartKrew/Kart!1398
This commit is contained in:
commit
52793f177c
3 changed files with 141 additions and 36 deletions
|
|
@ -364,7 +364,7 @@ static bool ACS_ActivatorIsLocal(ACSVM::Thread *thread)
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static UINT32 ACS_SectorThingCounter(sector_t *sec, bool (*filter)(mobj_t *))
|
||||
static UINT32 ACS_SectorThingCounter(sector_t *sec, mtag_t thingTag, bool (*filter)(mobj_t *))
|
||||
|
||||
Helper function for CallFunc_CountEnemies
|
||||
and CallFunc_CountPushables. Counts a number
|
||||
|
|
@ -372,21 +372,26 @@ static bool ACS_ActivatorIsLocal(ACSVM::Thread *thread)
|
|||
|
||||
Input Arguments:-
|
||||
sec: The sector to search in.
|
||||
thingTag: Thing tag to filter for. 0 allows any.
|
||||
filter: Filter function, total count is increased when
|
||||
this function returns true.
|
||||
|
||||
Return:-
|
||||
Numbers of things matching the filter found.
|
||||
--------------------------------------------------*/
|
||||
static UINT32 ACS_SectorThingCounter(sector_t *sec, bool (*filter)(mobj_t *))
|
||||
static UINT32 ACS_SectorThingCounter(sector_t *sec, mtag_t thingTag, bool (*filter)(mobj_t *))
|
||||
{
|
||||
msecnode_t *node = sec->touching_thinglist; // things touching this sector
|
||||
UINT32 count = 0;
|
||||
|
||||
while (node)
|
||||
for (msecnode_t *node = sec->touching_thinglist; node; node = node->m_thinglist_next) // things touching this sector
|
||||
{
|
||||
mobj_t *mo = node->m_thing;
|
||||
|
||||
if (thingTag != 0 && mo->tid != thingTag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mo->z > sec->ceilingheight
|
||||
|| mo->z + mo->height < sec->floorheight)
|
||||
{
|
||||
|
|
@ -397,61 +402,82 @@ static UINT32 ACS_SectorThingCounter(sector_t *sec, bool (*filter)(mobj_t *))
|
|||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
node = node->m_thinglist_next;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static UINT32 ACS_SectorTagThingCounter(mtag_t tag, bool (*filter)(mobj_t *))
|
||||
static UINT32 ACS_SectorTagThingCounter(mtag_t sectorTag, sector_t *activator, mtag_t thingTag, bool (*filter)(mobj_t *))
|
||||
|
||||
Helper function for CallFunc_CountEnemies
|
||||
and CallFunc_CountPushables. Counts a number
|
||||
of things in the tagged sectors.
|
||||
|
||||
Input Arguments:-
|
||||
tag: The sector tag to search in.
|
||||
sectorTag: The sector tag to search in.
|
||||
activator: The activator sector to fall back on when sectorTag is 0.
|
||||
thingTag: Thing tag to filter for. 0 allows any.
|
||||
filter: Filter function, total count is increased when
|
||||
this function returns true.
|
||||
|
||||
Return:-
|
||||
Numbers of things matching the filter found.
|
||||
--------------------------------------------------*/
|
||||
static UINT32 ACS_SectorTagThingCounter(mtag_t tag, bool (*filter)(mobj_t *))
|
||||
static UINT32 ACS_SectorIterateThingCounter(sector_t *sec, mtag_t thingTag, bool (*filter)(mobj_t *))
|
||||
{
|
||||
INT32 secnum = -1;
|
||||
UINT32 count = 0;
|
||||
boolean FOFsector = false;
|
||||
size_t i;
|
||||
|
||||
TAG_ITER_SECTORS(tag, secnum)
|
||||
if (sec == nullptr)
|
||||
{
|
||||
sector_t *sec = §ors[secnum];
|
||||
boolean FOFsector = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check the lines of this sector, to see if it is a FOF control sector.
|
||||
for (i = 0; i < sec->linecount; i++)
|
||||
// Check the lines of this sector, to see if it is a FOF control sector.
|
||||
for (i = 0; i < sec->linecount; i++)
|
||||
{
|
||||
INT32 targetsecnum = -1;
|
||||
|
||||
if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300)
|
||||
{
|
||||
INT32 targetsecnum = -1;
|
||||
|
||||
if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FOFsector = true;
|
||||
|
||||
TAG_ITER_SECTORS(sec->lines[i]->args[0], targetsecnum)
|
||||
{
|
||||
sector_t *targetsec = §ors[targetsecnum];
|
||||
count += ACS_SectorThingCounter(targetsec, filter);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FOFsector == false)
|
||||
FOFsector = true;
|
||||
|
||||
TAG_ITER_SECTORS(sec->lines[i]->args[0], targetsecnum)
|
||||
{
|
||||
count += ACS_SectorThingCounter(sec, filter);
|
||||
sector_t *targetsec = §ors[targetsecnum];
|
||||
count += ACS_SectorThingCounter(targetsec, thingTag, filter);
|
||||
}
|
||||
}
|
||||
|
||||
if (FOFsector == false)
|
||||
{
|
||||
count += ACS_SectorThingCounter(sec, thingTag, filter);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static UINT32 ACS_SectorTagThingCounter(mtag_t sectorTag, sector_t *activator, mtag_t thingTag, bool (*filter)(mobj_t *))
|
||||
{
|
||||
UINT32 count = 0;
|
||||
|
||||
if (sectorTag == 0)
|
||||
{
|
||||
count += ACS_SectorIterateThingCounter(activator, thingTag, filter);
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 secnum = -1;
|
||||
|
||||
TAG_ITER_SECTORS(sectorTag, secnum)
|
||||
{
|
||||
sector_t *sec = §ors[secnum];
|
||||
count += ACS_SectorIterateThingCounter(sec, thingTag, filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -485,6 +511,12 @@ bool CallFunc_Random(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word
|
|||
no type means indescriminate against type,
|
||||
no tid means search thru all thinkers.
|
||||
--------------------------------------------------*/
|
||||
static mobjtype_t filter_for_mobjtype = MT_NULL; // annoying but I don't wanna mess with other code
|
||||
bool ACS_ThingTypeFilter(mobj_t *mo)
|
||||
{
|
||||
return (ACS_CountThing(mo, filter_for_mobjtype));
|
||||
}
|
||||
|
||||
bool CallFunc_ThingCount(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
ACSVM::MapScope *map = NULL;
|
||||
|
|
@ -494,11 +526,10 @@ bool CallFunc_ThingCount(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
|
|||
|
||||
mobjtype_t type = MT_NULL;
|
||||
mtag_t tid = 0;
|
||||
mtag_t sectorTag = 0;
|
||||
|
||||
size_t count = 0;
|
||||
|
||||
(void)argC;
|
||||
|
||||
map = thread->scopeMap;
|
||||
str = map->getString(argV[0]);
|
||||
|
||||
|
|
@ -524,8 +555,21 @@ bool CallFunc_ThingCount(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
|
|||
|
||||
tid = argV[1];
|
||||
|
||||
if (tid != 0)
|
||||
if (argC > 2)
|
||||
{
|
||||
sectorTag = argV[2];
|
||||
}
|
||||
|
||||
if (sectorTag != 0)
|
||||
{
|
||||
// Search through sectors.
|
||||
filter_for_mobjtype = type;
|
||||
count = ACS_SectorTagThingCounter(sectorTag, nullptr, tid, ACS_ThingTypeFilter);
|
||||
filter_for_mobjtype = MT_NULL;
|
||||
}
|
||||
else if (tid != 0)
|
||||
{
|
||||
// Search through tag lists.
|
||||
mobj_t *mobj = nullptr;
|
||||
|
||||
while ((mobj = P_FindMobjFromTID(tid, mobj, nullptr)) != nullptr)
|
||||
|
|
@ -1189,6 +1233,53 @@ bool CallFunc_PlayerScore(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM:
|
|||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_PlayerNumber(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Returns the activating player's ID.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_PlayerNumber(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
INT16 playerID = -1;
|
||||
|
||||
(void)argV;
|
||||
(void)argC;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
playerID = (info->mo->player - players);
|
||||
}
|
||||
|
||||
thread->dataStk.push(playerID);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_ActivatorTID(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Returns the activating object's TID.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_ActivatorTID(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
INT16 tid = 0;
|
||||
|
||||
(void)argV;
|
||||
(void)argC;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false))
|
||||
{
|
||||
tid = info->mo->tid;
|
||||
}
|
||||
|
||||
thread->dataStk.push(tid);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_EndLog(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
|
|
@ -1300,13 +1391,17 @@ bool ACS_EnemyFilter(mobj_t *mo)
|
|||
|
||||
bool CallFunc_CountEnemies(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
mtag_t tag = 0;
|
||||
mtag_t tid = 0;
|
||||
UINT32 count = 0;
|
||||
|
||||
(void)argC;
|
||||
|
||||
tag = argV[0];
|
||||
count = ACS_SectorTagThingCounter(tag, ACS_EnemyFilter);
|
||||
tid = argV[1];
|
||||
count = ACS_SectorTagThingCounter(tag, info->sector, tid, ACS_EnemyFilter);
|
||||
|
||||
thread->dataStk.push(count);
|
||||
return false;
|
||||
|
|
@ -1325,13 +1420,17 @@ bool ACS_PushableFilter(mobj_t *mo)
|
|||
|
||||
bool CallFunc_CountPushables(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
mtag_t tag = 0;
|
||||
mtag_t tid = 0;
|
||||
UINT32 count = 0;
|
||||
|
||||
(void)argC;
|
||||
|
||||
tag = argV[0];
|
||||
count = ACS_SectorTagThingCounter(tag, ACS_PushableFilter);
|
||||
tid = argV[1];
|
||||
count = ACS_SectorTagThingCounter(tag, info->sector, tid, ACS_PushableFilter);
|
||||
|
||||
thread->dataStk.push(count);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ 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_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);
|
||||
|
||||
bool CallFunc_strcmp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
|
|
|||
|
|
@ -108,6 +108,9 @@ Environment::Environment()
|
|||
|
||||
// 225 to 243: Implemented by ACSVM
|
||||
|
||||
addCodeDataACS0(247, {"", 0, addCallFunc(CallFunc_PlayerNumber)});
|
||||
addCodeDataACS0(248, {"", 0, addCallFunc(CallFunc_ActivatorTID)});
|
||||
|
||||
// 253: Implemented by ACSVM
|
||||
|
||||
// 256 to 257: Implemented by ACSVM
|
||||
|
|
@ -160,6 +163,7 @@ Environment::Environment()
|
|||
addFuncDataACS0( 309, addCallFunc(CallFunc_EncoreMode));
|
||||
addFuncDataACS0( 310, addCallFunc(CallFunc_BreakTheCapsules));
|
||||
addFuncDataACS0( 311, addCallFunc(CallFunc_TimeAttack));
|
||||
addFuncDataACS0( 312, addCallFunc(CallFunc_ThingCount));
|
||||
|
||||
addFuncDataACS0( 500, addCallFunc(CallFunc_CameraWait));
|
||||
addFuncDataACS0( 501, addCallFunc(CallFunc_PodiumPosition));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue