diff --git a/source/common/scripting/vm/vm.h b/source/common/scripting/vm/vm.h index 73c4b48bb..6442034c1 100644 --- a/source/common/scripting/vm/vm.h +++ b/source/common/scripting/vm/vm.h @@ -724,6 +724,11 @@ struct AFuncDesc extern FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr; \ MSVC_FSEG FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr GCC_FSEG = &VMField_##cls##_##scriptname; +#define DEFINE_FIELD_NAMED_UNSIZED(cls, name, scriptname) \ + static const FieldDesc VMField_##cls##_##scriptname = { #cls, #scriptname, (unsigned)myoffsetof(cls, name), ~0u, 0 }; \ + extern FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr; \ + MSVC_FSEG FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr GCC_FSEG = &VMField_##cls##_##scriptname; + #define DEFINE_FIELD_BIT(cls, name, scriptname, bitval) \ static const FieldDesc VMField_##cls##_##scriptname = { #cls, #scriptname, (unsigned)myoffsetof(cls, name), (unsigned)sizeof(cls::name), bitval }; \ extern FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr; \ diff --git a/source/core/thingdef_data.cpp b/source/core/thingdef_data.cpp index b51e3d3c3..4bcffd7be 100644 --- a/source/core/thingdef_data.cpp +++ b/source/core/thingdef_data.cpp @@ -443,7 +443,6 @@ void InitThingdef() collstruct->Size = sizeof(CollisionBase); collstruct->Align = alignof(CollisionBase); - auto sidestruct = NewStruct("tspritetype", nullptr, true); sidestruct->Size = sizeof(tspritetype); sidestruct->Align = alignof(tspritetype); diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index 122631263..36f26b7fe 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -3472,17 +3472,17 @@ void actKillDude(DBloodActor* killerActor, DBloodActor* actor, DAMAGE_TYPE damag break; case kDudeSpiderBrown: - if (Owner) Owner->dudeExtra.stats.birthCounter--; + if (Owner) Owner->dudeExtra.birthCounter--; genericDeath(actor, nSeq, 1803, pDudeInfo->seqStartID + nSeq); break; case kDudeSpiderRed: - if (Owner) Owner->dudeExtra.stats.birthCounter--; + if (Owner) Owner->dudeExtra.birthCounter--; genericDeath(actor, nSeq, 1803, pDudeInfo->seqStartID + nSeq); break; case kDudeSpiderBlack: - if (Owner) Owner->dudeExtra.stats.birthCounter--; + if (Owner) Owner->dudeExtra.birthCounter--; genericDeath(actor, nSeq, 1803, pDudeInfo->seqStartID + nSeq); break; diff --git a/source/games/blood/src/ai.cpp b/source/games/blood/src/ai.cpp index 400470706..4fc1e2dc6 100644 --- a/source/games/blood/src/ai.cpp +++ b/source/games/blood/src/ai.cpp @@ -360,9 +360,9 @@ void aiActivateDude(DBloodActor* actor) { case kDudePhantasm: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 0; - pDudeExtraE->active = 1; + + actor->dudeExtra.thinkTime = 0; + actor->dudeExtra.active = 1; if (actor->GetTarget() == nullptr) aiNewState(actor, &ghostSearch); else @@ -378,8 +378,8 @@ void aiActivateDude(DBloodActor* actor) case kDudeCultistTNT: case kDudeCultistBeast: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->active = 1; + + actor->dudeExtra.active = 1; if (actor->GetTarget() == nullptr) { switch (actor->xspr.medium) @@ -422,8 +422,8 @@ void aiActivateDude(DBloodActor* actor) #ifdef NOONE_EXTENSIONS case kDudeModernCustom: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->active = 1; + + actor->dudeExtra.active = 1; if (actor->GetTarget() == nullptr) { if (spriteIsUnderwater(actor, false)) aiGenDudeNewState(actor, &genDudeSearchW); @@ -444,8 +444,8 @@ void aiActivateDude(DBloodActor* actor) #endif case kDudeCultistTommyProne: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->active = 1; + + actor->dudeExtra.active = 1; actor->ChangeType(kDudeCultistTommy); if (actor->GetTarget() == nullptr) { @@ -481,8 +481,8 @@ void aiActivateDude(DBloodActor* actor) } case kDudeCultistShotgunProne: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->active = 1; + + actor->dudeExtra.active = 1; actor->ChangeType(kDudeCultistShotgun); if (actor->GetTarget() == nullptr) { @@ -524,9 +524,9 @@ void aiActivateDude(DBloodActor* actor) break; case kDudeBat: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 0; - pDudeExtraE->active = 1; + + actor->dudeExtra.thinkTime = 0; + actor->dudeExtra.active = 1; if (!actor->spr.flags) actor->spr.flags = 9; if (actor->GetTarget() == nullptr) @@ -541,9 +541,9 @@ void aiActivateDude(DBloodActor* actor) } case kDudeBoneEel: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 0; - pDudeExtraE->active = 1; + + actor->dudeExtra.thinkTime = 0; + actor->dudeExtra.active = 1; if (actor->GetTarget() == nullptr) aiNewState(actor, &eelSearch); else @@ -558,11 +558,11 @@ void aiActivateDude(DBloodActor* actor) } case kDudeGillBeast: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; + XSECTOR* pXSector = actor->sector()->hasX()? &actor->sector()->xs() : nullptr; - pDudeExtraE->thinkTime = 0; - pDudeExtraE->active = 1; + actor->dudeExtra.thinkTime = 0; + actor->dudeExtra.active = 1; if (actor->GetTarget() == nullptr) { if (pXSector && pXSector->Underwater) @@ -585,8 +585,8 @@ void aiActivateDude(DBloodActor* actor) } case kDudeZombieAxeNormal: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 1; + + actor->dudeExtra.thinkTime = 1; if (actor->GetTarget() == nullptr) aiNewState(actor, &zombieASearch); else @@ -614,22 +614,22 @@ void aiActivateDude(DBloodActor* actor) } case kDudeZombieAxeBuried: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 1; + + actor->dudeExtra.thinkTime = 1; if (actor->xspr.aiState == &zombieEIdle) aiNewState(actor, &zombieEUp); break; } case kDudeZombieAxeLaying: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 1; + + actor->dudeExtra.thinkTime = 1; if (actor->xspr.aiState == &zombieSIdle) aiNewState(actor, &zombie13AC2C); break; } case kDudeZombieButcher: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 1; + + actor->dudeExtra.thinkTime = 1; if (actor->GetTarget() == nullptr) aiNewState(actor, &zombieFSearch); else @@ -655,9 +655,9 @@ void aiActivateDude(DBloodActor* actor) aiNewState(actor, &zombieFBurnChase); break; case kDudeGargoyleFlesh: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 0; - pDudeExtraE->active = 1; + + actor->dudeExtra.thinkTime = 0; + actor->dudeExtra.active = 1; if (actor->GetTarget() == nullptr) aiNewState(actor, &gargoyleFSearch); else @@ -672,9 +672,9 @@ void aiActivateDude(DBloodActor* actor) } case kDudeGargoyleStone: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 0; - pDudeExtraE->active = 1; + + actor->dudeExtra.thinkTime = 0; + actor->dudeExtra.active = 1; if (actor->GetTarget() == nullptr) aiNewState(actor, &gargoyleFSearch); else @@ -792,8 +792,8 @@ void aiActivateDude(DBloodActor* actor) break; case kDudeSpiderMother: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->active = 1; + + actor->dudeExtra.active = 1; actor->spr.flags |= 2; actor->spr.cstat &= ~CSTAT_SPRITE_YFLIP; if (actor->GetTarget() == nullptr) @@ -807,8 +807,8 @@ void aiActivateDude(DBloodActor* actor) } case kDudeTinyCaleb: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 1; + + actor->dudeExtra.thinkTime = 1; if (actor->GetTarget() == nullptr) { switch (actor->xspr.medium) @@ -839,8 +839,8 @@ void aiActivateDude(DBloodActor* actor) } case kDudeBeast: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 1; + + actor->dudeExtra.thinkTime = 1; if (actor->GetTarget() == nullptr) { switch (actor->xspr.medium) @@ -1669,11 +1669,11 @@ void aiInitSprite(DBloodActor* actor) XSECTOR* pXSector = actor->sector()->hasX() ? &actor->sector()->xs() : nullptr; DUDEEXTRA* pDudeExtra = &actor->dudeExtra; - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; + pDudeExtra->teslaHit = 0; pDudeExtra->time = 0; - pDudeExtraE->thinkTime = 0; - pDudeExtraE->active = 0; + actor->dudeExtra.thinkTime = 0; + actor->dudeExtra.active = 0; #ifdef NOONE_EXTENSIONS unsigned int stateTimer = 0; @@ -1701,49 +1701,49 @@ void aiInitSprite(DBloodActor* actor) case kDudeCultistTNT: case kDudeCultistBeast: { - pDudeExtraE->active = 0; + actor->dudeExtra.active = 0; aiNewState(actor, &cultistIdle); break; } case kDudeCultistTommyProne: { - pDudeExtraE->active = 0; + actor->dudeExtra.active = 0; aiNewState(actor, &fanaticProneIdle); break; } case kDudeCultistShotgunProne: { - pDudeExtraE->active = 0; + actor->dudeExtra.active = 0; aiNewState(actor, &cultistProneIdle); break; } case kDudeZombieButcher: { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiNewState(actor, &zombieFIdle); break; } case kDudeZombieAxeNormal: { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiNewState(actor, &zombieAIdle); break; } case kDudeZombieAxeLaying: { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiNewState(actor, &zombieSIdle); actor->spr.flags &= ~1; break; } case kDudeZombieAxeBuried: { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiNewState(actor, &zombieEIdle); actor->spr.flags &= ~1; break; } case kDudeGargoyleFlesh: case kDudeGargoyleStone: { - pDudeExtraE->thinkTime = 0; - pDudeExtraE->active = 0; + actor->dudeExtra.thinkTime = 0; + actor->dudeExtra.active = 0; aiNewState(actor, &gargoyleFIdle); break; } @@ -1752,13 +1752,13 @@ void aiInitSprite(DBloodActor* actor) aiNewState(actor, &gargoyleStatueIdle); break; case kDudeCerberusTwoHead: { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiNewState(actor, &cerberusIdle); break; } case kDudeCerberusOneHead: { if (!VanillaMode()) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiNewState(actor, &cerberus2Idle); break; } @@ -1773,8 +1773,8 @@ void aiInitSprite(DBloodActor* actor) break; case kDudePhantasm: { - pDudeExtraE->thinkTime = 0; - pDudeExtraE->active = 0; + actor->dudeExtra.thinkTime = 0; + actor->dudeExtra.active = 0; aiNewState(actor, &ghostIdle); break; } @@ -1786,8 +1786,8 @@ void aiInitSprite(DBloodActor* actor) break; case kDudeBoneEel: { - pDudeExtraE->thinkTime = 0; - pDudeExtraE->active = 0; + actor->dudeExtra.thinkTime = 0; + actor->dudeExtra.active = 0; aiNewState(actor, &eelIdle); break; } @@ -1796,8 +1796,8 @@ void aiInitSprite(DBloodActor* actor) break; case kDudeBat: { - pDudeExtraE->thinkTime = 0; - pDudeExtraE->active = 0; + actor->dudeExtra.thinkTime = 0; + actor->dudeExtra.active = 0; aiNewState(actor, &batIdle); break; } @@ -1805,22 +1805,22 @@ void aiInitSprite(DBloodActor* actor) case kDudeSpiderRed: case kDudeSpiderBlack: { - pDudeExtraE->active = 0; - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.active = 0; + actor->dudeExtra.thinkTime = 0; aiNewState(actor, &spidIdle); break; } case kDudeSpiderMother: { - pDudeExtraE->active = 0; - pDudeExtraE->birthCounter = 0; + actor->dudeExtra.active = 0; + actor->dudeExtra.birthCounter = 0; aiNewState(actor, &spidIdle); break; } case kDudeTchernobog: { - pDudeExtraE->active = 0; - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.active = 0; + actor->dudeExtra.thinkTime = 0; aiNewState(actor, &tchernobogIdle); break; } diff --git a/source/games/blood/src/ai.h b/source/games/blood/src/ai.h index 5f34acf9d..fb5988acb 100644 --- a/source/games/blood/src/ai.h +++ b/source/games/blood/src/ai.h @@ -50,23 +50,6 @@ enum AI_SFX_PRIORITY { }; -struct DUDEEXTRA_STATS -{ - union { - int thinkTime; - int birthCounter; - }; - uint8_t active; -}; - -struct DUDEEXTRA -{ - int time; - uint8_t teslaHit; - int prio; - DUDEEXTRA_STATS stats; -}; - struct TARGETTRACK { int TotalKills; int Kills; diff --git a/source/games/blood/src/aibat.cpp b/source/games/blood/src/aibat.cpp index b105fc2f5..0bc9eea51 100644 --- a/source/games/blood/src/aibat.cpp +++ b/source/games/blood/src/aibat.cpp @@ -79,12 +79,12 @@ static void batThinkTarget(DBloodActor* actor) { assert(actor->IsDudeActor()); DUDEINFO* pDudeInfo = getDudeInfo(actor); - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - if (pDudeExtraE->active && pDudeExtraE->thinkTime < 10) - pDudeExtraE->thinkTime++; - else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) + + if (actor->dudeExtra.active && actor->dudeExtra.thinkTime < 10) + actor->dudeExtra.thinkTime++; + else if (actor->dudeExtra.thinkTime >= 10 && actor->dudeExtra.active) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); aiNewState(actor, &batTurn); @@ -370,8 +370,8 @@ void batMoveToCeil(DBloodActor* actor) { if (actor->spr.pos.Z - actor->xspr.TargetPos.Z < 0x10) { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->thinkTime = 0; + + actor->dudeExtra.thinkTime = 0; actor->spr.flags = 0; aiNewState(actor, &batIdle); } diff --git a/source/games/blood/src/aiboneel.cpp b/source/games/blood/src/aiboneel.cpp index b53fc8e88..24b9cef64 100644 --- a/source/games/blood/src/aiboneel.cpp +++ b/source/games/blood/src/aiboneel.cpp @@ -91,12 +91,12 @@ static void eelThinkTarget(DBloodActor* actor) { assert(actor->IsDudeActor()); DUDEINFO* pDudeInfo = getDudeInfo(actor); - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - if (pDudeExtraE->active && pDudeExtraE->thinkTime < 10) - pDudeExtraE->thinkTime++; - else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) + + if (actor->dudeExtra.active && actor->dudeExtra.thinkTime < 10) + actor->dudeExtra.thinkTime++; + else if (actor->dudeExtra.thinkTime >= 10 && actor->dudeExtra.active) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); aiNewState(actor, &eelTurn); @@ -121,13 +121,13 @@ static void eelThinkTarget(DBloodActor* actor) DAngle nDeltaAngle = absangle(actor->spr.Angles.Yaw, dvect.Angle()); if (nDist < pDudeInfo->SeeDist() && nDeltaAngle <= pDudeInfo->Periphery()) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiSetTarget(actor, pPlayer->actor); aiActivateDude(actor); } else if (nDist < pDudeInfo->HearDist()) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiSetTarget(actor, ppos); aiActivateDude(actor); } @@ -375,8 +375,8 @@ void eelMoveToCeil(DBloodActor* actor) { if (actor->spr.pos.Z - actor->xspr.TargetPos.Z < 0x10) { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->active = 0; + + actor->dudeExtra.active = 0; actor->spr.flags = 0; aiNewState(actor, &eelIdle); } diff --git a/source/games/blood/src/aicerber.cpp b/source/games/blood/src/aicerber.cpp index cbe112199..22148283f 100644 --- a/source/games/blood/src/aicerber.cpp +++ b/source/games/blood/src/aicerber.cpp @@ -220,10 +220,10 @@ static void cerberusThinkTarget(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor); - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - if (pDudeExtraE->active && pDudeExtraE->thinkTime < 10) - pDudeExtraE->thinkTime++; - else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) + + if (actor->dudeExtra.active && actor->dudeExtra.thinkTime < 10) + actor->dudeExtra.thinkTime++; + else if (actor->dudeExtra.thinkTime >= 10 && actor->dudeExtra.active) { actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); @@ -252,13 +252,13 @@ static void cerberusThinkTarget(DBloodActor* actor) DAngle nDeltaAngle = absangle(actor->spr.Angles.Yaw, dvect.Angle()); if (nDist < pDudeInfo->SeeDist() && nDeltaAngle <= pDudeInfo->Periphery()) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiSetTarget(actor, pPlayer->actor); aiActivateDude(actor); } else if (nDist < pDudeInfo->HearDist()) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiSetTarget(actor, ppos); aiActivateDude(actor); } diff --git a/source/games/blood/src/aigarg.cpp b/source/games/blood/src/aigarg.cpp index a506ba99d..432162a56 100644 --- a/source/games/blood/src/aigarg.cpp +++ b/source/games/blood/src/aigarg.cpp @@ -179,10 +179,10 @@ static void gargThinkTarget(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor); - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - if (pDudeExtraE->active && pDudeExtraE->thinkTime < 10) - pDudeExtraE->thinkTime++; - else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) + + if (actor->dudeExtra.active && actor->dudeExtra.thinkTime < 10) + actor->dudeExtra.thinkTime++; + else if (actor->dudeExtra.thinkTime >= 10 && actor->dudeExtra.active) { actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); @@ -208,13 +208,13 @@ static void gargThinkTarget(DBloodActor* actor) DAngle nDeltaAngle = absangle(actor->spr.Angles.Yaw, dvect.Angle()); if (nDist < pDudeInfo->SeeDist() && nDeltaAngle <= pDudeInfo->Periphery()) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiSetTarget(actor, pPlayer->actor); aiActivateDude(actor); } else if (nDist < pDudeInfo->HearDist()) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiSetTarget(actor, ppos); aiActivateDude(actor); } diff --git a/source/games/blood/src/aighost.cpp b/source/games/blood/src/aighost.cpp index 5d3859b30..161a230e5 100644 --- a/source/games/blood/src/aighost.cpp +++ b/source/games/blood/src/aighost.cpp @@ -160,10 +160,10 @@ static void ghostThinkTarget(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor); - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - if (pDudeExtraE->active && pDudeExtraE->thinkTime < 10) - pDudeExtraE->thinkTime++; - else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) + + if (actor->dudeExtra.active && actor->dudeExtra.thinkTime < 10) + actor->dudeExtra.thinkTime++; + else if (actor->dudeExtra.thinkTime >= 10 && actor->dudeExtra.active) { actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); @@ -189,14 +189,14 @@ static void ghostThinkTarget(DBloodActor* actor) DAngle nDeltaAngle = absangle(actor->spr.Angles.Yaw, dvect.Angle()); if (nDist < pDudeInfo->SeeDist() && nDeltaAngle <= pDudeInfo->Periphery()) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiSetTarget(actor, pPlayer->actor); aiActivateDude(actor); return; } else if (nDist < pDudeInfo->HearDist()) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiSetTarget(actor, ppos); aiActivateDude(actor); return; diff --git a/source/games/blood/src/aispid.cpp b/source/games/blood/src/aispid.cpp index bd6823e48..930ae86bb 100644 --- a/source/games/blood/src/aispid.cpp +++ b/source/games/blood/src/aispid.cpp @@ -135,13 +135,13 @@ void SpidBirthSeqCallback(int, DBloodActor* actor) DUDEINFO* pDudeInfo = getDudeInfo(actor); if (!actor->ValidateTarget(__FUNCTION__)) return; auto target = actor->GetTarget(); - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; + auto dvec = actor->xspr.TargetPos.XY() - actor->spr.pos.XY(); DAngle nAngle = dvec.Angle(); double nDist = dvec.Length(); DBloodActor* spawned = nullptr; - if (target->IsPlayerActor() && pDudeExtraE->birthCounter < 10) + if (target->IsPlayerActor() && actor->dudeExtra.birthCounter < 10) { DAngle nDeltaAngle = absangle(actor->spr.Angles.Yaw, nAngle); if (nDist < 0x1a0 && nDist > 0x140 && nDeltaAngle < pDudeInfo->Periphery()) @@ -153,7 +153,7 @@ void SpidBirthSeqCallback(int, DBloodActor* actor) if (spawned) { - pDudeExtraE->birthCounter++; + actor->dudeExtra.birthCounter++; spawned->SetOwner(spawned); if (AllowedKillType(spawned)) Level.addKillCount(); } diff --git a/source/games/blood/src/aitchern.cpp b/source/games/blood/src/aitchern.cpp index a710691f3..3788721e0 100644 --- a/source/games/blood/src/aitchern.cpp +++ b/source/games/blood/src/aitchern.cpp @@ -184,10 +184,10 @@ static void sub_725A4(DBloodActor* actor) return; } DUDEINFO* pDudeInfo = getDudeInfo(actor); - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - if (pDudeExtraE->active && pDudeExtraE->thinkTime < 10) - pDudeExtraE->thinkTime++; - else if (pDudeExtraE->thinkTime >= 10 && pDudeExtraE->active) + + if (actor->dudeExtra.active && actor->dudeExtra.thinkTime < 10) + actor->dudeExtra.thinkTime++; + else if (actor->dudeExtra.thinkTime >= 10 && actor->dudeExtra.active) { actor->xspr.goalAng += DAngle45; aiSetTarget(actor, actor->basePoint); @@ -215,13 +215,13 @@ static void sub_725A4(DBloodActor* actor) DAngle nDeltaAngle = absangle(actor->spr.Angles.Yaw, nAngle); if (nDist < pDudeInfo->SeeDist() && abs(nDeltaAngle) <= pDudeInfo->Periphery()) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiSetTarget(actor, pPlayer->actor); aiActivateDude(actor); } else if (nDist < pDudeInfo->HearDist()) { - pDudeExtraE->thinkTime = 0; + actor->dudeExtra.thinkTime = 0; aiSetTarget(actor, ppos); aiActivateDude(actor); } diff --git a/source/games/blood/src/aiunicult.cpp b/source/games/blood/src/aiunicult.cpp index 0d42ddf8b..07f90bc56 100644 --- a/source/games/blood/src/aiunicult.cpp +++ b/source/games/blood/src/aiunicult.cpp @@ -2501,8 +2501,8 @@ void aiGenDudeInitSprite(DBloodActor* actor) { case kDudeModernCustom: { - DUDEEXTRA_STATS* pDudeExtraE = &actor->dudeExtra.stats; - pDudeExtraE->active = pDudeExtraE->thinkTime = 0; + + actor->dudeExtra.active = actor->dudeExtra.thinkTime = 0; aiGenDudeNewState(actor, &genDudeIdleL); break; } diff --git a/source/games/blood/src/bloodactor.h b/source/games/blood/src/bloodactor.h index 42893c617..7938bc9ea 100644 --- a/source/games/blood/src/bloodactor.h +++ b/source/games/blood/src/bloodactor.h @@ -5,7 +5,6 @@ BEGIN_BLD_NS -class DBloodActor; struct SPRITEHIT { @@ -13,6 +12,8 @@ struct SPRITEHIT Collision hit, ceilhit, florhit; }; +class DBloodActor; + class DBloodActor : public DCoreActor { DECLARE_CLASS(DBloodActor, DCoreActor) @@ -21,16 +22,18 @@ class DBloodActor : public DCoreActor public: double dudeSlope; // Q18.14 format bool hasx; + bool explosionhackflag; // this originally hijacked the target field which is not safe when working with pointers. XSPRITE xspr; SPRITEHIT hit; DUDEEXTRA dudeExtra; + TObjPtr ownerActor; // was previously stored in the sprite's owner field. + + // nnext stuff. For now not exported to scripting. SPRITEMASS spriteMass; GENDUDEEXTRA genDudeExtra; TObjPtr prevmarker; // needed by the nnext marker code. This originally hijacked targetX in XSPRITE - TObjPtr ownerActor; // was previously stored in the sprite's owner field. DVector3 basePoint; EventObject condition[2]; - bool explosionhackflag; // this originally hijacked the target field which is not safe when working with pointers. // transient data (not written to savegame) int cumulDamage; diff --git a/source/games/blood/src/loadsave.cpp b/source/games/blood/src/loadsave.cpp index 40ba42072..51651b787 100644 --- a/source/games/blood/src/loadsave.cpp +++ b/source/games/blood/src/loadsave.cpp @@ -448,12 +448,12 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, DUDEEXTRA& w, DUDE if (arc.BeginObject(keyname)) { - // Note: birthCounter/thinkTime are a union and share the same value (this is used for savefile backwards compatibility - see correct implementation below) arc("time", w.time, &empty) ("teslaHit", w.teslaHit, &empty2) ("prio", w.prio, &empty) - ("thinkTime", w.stats.thinkTime, &empty) - ("active", w.stats.active, &empty2) + ("thinkTime", w.thinkTime, &empty) + ("birthCounter", w.birthCounter, &empty) + ("active", w.active, &empty2) .EndObject(); } return arc; diff --git a/source/games/blood/src/mapstructs.h b/source/games/blood/src/mapstructs.h index d5f924b96..f873e10af 100644 --- a/source/games/blood/src/mapstructs.h +++ b/source/games/blood/src/mapstructs.h @@ -1,4 +1,4 @@ -// This is separate because the map loader needs knowledge about these types to allocate their instances. +// This is separate because the map loader and script compiler needs knowledge about these types to allocate their instances so it needs to be usable from shared code. #pragma once #include "ns.h" @@ -266,4 +266,15 @@ struct XWALL { uint8_t key; // Key }; +struct DUDEEXTRA +{ + int time; + uint8_t teslaHit; + uint8_t active; + int prio; + int thinkTime; + int birthCounter; +}; + + END_BLD_NS diff --git a/source/games/blood/src/vmexports.cpp b/source/games/blood/src/vmexports.cpp index 5db47d3d2..b94520553 100644 --- a/source/games/blood/src/vmexports.cpp +++ b/source/games/blood/src/vmexports.cpp @@ -76,6 +76,64 @@ DEFINE_FIELD_NAMED_X(XWALL, XWALL, panVel.X, panVelX) // VM does not support int DEFINE_FIELD_NAMED_X(XWALL, XWALL, panVel.Y, panVelY) DEFINE_FIELD_X(XWALL, XWALL, key) +DEFINE_FIELD_X(XSPRITE, XSPRITE, aiState) +DEFINE_FIELD_X(XSPRITE, XSPRITE, flags) +DEFINE_FIELD_X(XSPRITE, XSPRITE, target) +DEFINE_FIELD_X(XSPRITE, XSPRITE, burnSource) +DEFINE_FIELD_X(XSPRITE, XSPRITE, TargetPos) +DEFINE_FIELD_X(XSPRITE, XSPRITE, goalAng) +DEFINE_FIELD_X(XSPRITE, XSPRITE, sysData1) +DEFINE_FIELD_X(XSPRITE, XSPRITE, sysData2) +DEFINE_FIELD_X(XSPRITE, XSPRITE, scale) +DEFINE_FIELD_X(XSPRITE, XSPRITE, physAttr) +DEFINE_FIELD_X(XSPRITE, XSPRITE, health) +DEFINE_FIELD_X(XSPRITE, XSPRITE, busy) +DEFINE_FIELD_X(XSPRITE, XSPRITE, data1) +DEFINE_FIELD_X(XSPRITE, XSPRITE, data2) +DEFINE_FIELD_X(XSPRITE, XSPRITE, data3) +DEFINE_FIELD_X(XSPRITE, XSPRITE, txID) +DEFINE_FIELD_X(XSPRITE, XSPRITE, rxID) +DEFINE_FIELD_X(XSPRITE, XSPRITE, command) +DEFINE_FIELD_X(XSPRITE, XSPRITE, busyTime) +DEFINE_FIELD_X(XSPRITE, XSPRITE, waitTime) +DEFINE_FIELD_X(XSPRITE, XSPRITE, data4) +DEFINE_FIELD_X(XSPRITE, XSPRITE, burnTime) +DEFINE_FIELD_X(XSPRITE, XSPRITE, height) +DEFINE_FIELD_X(XSPRITE, XSPRITE, stateTimer) +DEFINE_FIELD_X(XSPRITE, XSPRITE, respawnPending) +DEFINE_FIELD_X(XSPRITE, XSPRITE, dropMsg) +DEFINE_FIELD_X(XSPRITE, XSPRITE, key) +DEFINE_FIELD_X(XSPRITE, XSPRITE, lSkill) +DEFINE_FIELD_X(XSPRITE, XSPRITE, lockMsg) +DEFINE_FIELD_X(XSPRITE, XSPRITE, dodgeDir) +DEFINE_FIELD_X(XSPRITE, XSPRITE, wave) +DEFINE_FIELD_X(XSPRITE, XSPRITE, medium) +DEFINE_FIELD_X(XSPRITE, XSPRITE, respawn) +DEFINE_FIELD_X(XSPRITE, XSPRITE, modernFlags) +DEFINE_FIELD_X(XSPRITE, XSPRITE, sightstuff) +DEFINE_FIELD_X(XSPRITE, XSPRITE, patrolturndelay) + +DEFINE_FIELD_X(DUDEEXTRA, DUDEEXTRA, time) +DEFINE_FIELD_X(DUDEEXTRA, DUDEEXTRA, teslaHit) +DEFINE_FIELD_X(DUDEEXTRA, DUDEEXTRA, active) +DEFINE_FIELD_X(DUDEEXTRA, DUDEEXTRA, prio) +DEFINE_FIELD_X(DUDEEXTRA, DUDEEXTRA, thinkTime) +DEFINE_FIELD_X(DUDEEXTRA, DUDEEXTRA, birthCounter) + +DEFINE_FIELD_UNSIZED(SPRITEHIT, SPRITEHIT, hit) +DEFINE_FIELD_UNSIZED(SPRITEHIT, SPRITEHIT, ceilhit) +DEFINE_FIELD_UNSIZED(SPRITEHIT, SPRITEHIT, florhit) + +DEFINE_FIELD(DBloodActor, dudeSlope) +DEFINE_FIELD(DBloodActor, hasx) +DEFINE_FIELD(DBloodActor, explosionhackflag) +DEFINE_FIELD_UNSIZED(BloodActor, DBloodActor, hit) +DEFINE_FIELD_UNSIZED(BloodActor, DBloodActor, dudeExtra) +DEFINE_FIELD_UNSIZED(BloodActor, DBloodActor, xspr) +DEFINE_FIELD(DBloodActor, ownerActor) +DEFINE_FIELD(DBloodActor, cumulDamage) +DEFINE_FIELD(DBloodActor, interpolated) + void Blood_ChangeType(DBloodActor* self, PClassActor* type) { diff --git a/wadsrc/static/zscript/games/blood/bloodactor.zs b/wadsrc/static/zscript/games/blood/bloodactor.zs index a6b14c67a..78732dd59 100644 --- a/wadsrc/static/zscript/games/blood/bloodactor.zs +++ b/wadsrc/static/zscript/games/blood/bloodactor.zs @@ -1,5 +1,115 @@ + +struct XSPRITE { + + //AISTATE* aiState; // ai + uint flags; + + native BloodActor target; // target sprite + native BloodActor burnSource; + + native Vector3 TargetPos; + native double goalAng; // Dude goal ang + + native int sysData1; // used to keep here various system data, so user can't change it in map editor + native int sysData2; // + native int scale; // used for scaling SEQ size on sprites + native uint physAttr; // currently used by additional physics sprites to keep its attributes. + native uint health; + native uint busy; + + native int16 data1; // Data 1 + native int16 data2; // Data 2 + native int16 data3; // Data 3 + native uint16 txID; // TX ID + native uint16 rxID; // RX ID + native uint16 command; // Cmd + native uint16 busyTime; // busyTime + native uint16 waitTime; // waitTime + native uint16 data4; // Data 4 + native uint16 burnTime; + native uint16 height; + native uint16 stateTimer; // ai timer + + native uint8 respawnPending; // respawnPending + native uint8 dropMsg; // Drop Item + native uint8 key; // Key + native uint8 lSkill; // Launch 12345 + native uint8 lockMsg; // Lock msg + native int8 dodgeDir; // Dude dodge direction + native uint8 wave; // Wave + native uint8 medium; // medium + native uint8 respawn; // Respawn option + + native uint8 modernFlags; // modern flags + native uint8 sightstuff; // something about sight checks + native uint8 patrolturndelay; // patrol turn delay + + flagdef internal state: flags, 0; + flagdef internal triggerOn: flags, 1; + flagdef internal triggerOff: flags, 2; + flagdef internal restState: flags, 3; + flagdef internal interruptable: flags, 4; + flagdef internal Decoupled: flags, 5; + flagdef internal triggerOnce: flags, 6; + flagdef internal isTriggered: flags, 7; + flagdef internal Push: flags, 8; + flagdef internal Vector: flags, 9; + flagdef internal Impact: flags, 10; + flagdef internal Pickup: flags, 11; + flagdef internal Touch: flags, 12; + flagdef internal Sight: flags, 13; + flagdef internal Proximity: flags, 14; + flagdef internal lS: flags, 15; + flagdef internal lB: flags, 16; + flagdef internal lT: flags, 17; + flagdef internal lC: flags, 18; + flagdef internal DudeLockout: flags, 19; + flagdef internal locked: flags, 20; + flagdef internal dudeDeaf: flags, 21; + flagdef internal dudeAmbush: flags, 22; + flagdef internal dudeGuard: flags, 23; + flagdef internal dudeFlag4: flags, 24; + flagdef internal patrolstate: flags, 25; +} + +struct SPRITEHIT +{ + native CollisionData hit, ceilhit, florhit; +} + +struct DUDEEXTRA +{ + native int time; + native uint8 teslaHit; + native uint8 active; + native int prio; + native int thinkTime; + native int birthCounter; +} + + class BloodActor : CoreActor native { + native double dudeSlope; + native readonly bool hasx; + native bool explosionhackflag; // this originally hijacked the target field which is not safe when working with pointers. + native XSPRITE xspr; + native SPRITEHIT hit; + native DUDEEXTRA dudeExtra; + native BloodActor ownerActor; // was previously stored in the sprite's owner field. + + // nnext stuff. For now not exported to scripting. + //SPRITEMASS spriteMass; + //GENDUDEEXTRA genDudeExtra; + //TObjPtr prevmarker; // needed by the nnext marker code. This originally hijacked targetX in XSPRITE + //DVector3 basePoint; + //EventObject condition[2]; + + // transient data (not written to savegame) + native int cumulDamage; + native bool interpolated; + + native void ChangeType(class newtype); } diff --git a/wadsrc/static/zscript/games/maptypes.zs b/wadsrc/static/zscript/games/maptypes.zs index 1afd1cc43..f84688925 100644 --- a/wadsrc/static/zscript/games/maptypes.zs +++ b/wadsrc/static/zscript/games/maptypes.zs @@ -338,8 +338,8 @@ struct sectortype native //============================================================================= -struct XWALL native { - +struct XWALL native +{ native uint flags; native uint busy; native int16 data;