diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index c83ded876..2f4670046 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -1393,16 +1393,13 @@ static void actInitThings() if (!act->hasX()) continue; int nType = act->GetType() - kThingBase; - act->xspr.health = thingInfo[nType].startHealth << 4; -#ifdef NOONE_EXTENSIONS - // allow level designer to set custom clipdist. - // this is especially useful for various Gib and Explode objects which have clipdist 1 for some reason predefined, - // but what if it have voxel model...? - if (!gModernMap) -#endif - act->clipdist = thingInfo[nType].fClipdist(); - act->spr.flags = thingInfo[nType].flags; + act->xspr.health = act->IntVar("defhealth"); + // allow levels to set custom clipdist. + if (act->clipdist == 0 || !(currentLevel->featureflags & kFeatureCustomClipdist)) + act->clipdist = act->FloatVar("defclipdist"); + + act->spr.flags = act->IntVar("defflags"); if (act->spr.flags & kPhysGravity) act->spr.flags |= kPhysFalling; act->vel.Zero(); @@ -1465,18 +1462,18 @@ static void actInitDudes() } Level.setKills(TotalKills); - /////////////// - - for (int i = 0; i < kDudeMax - kDudeBase; i++) - for (int j = 0; j < 7; j++) - dudeInfo[i].damageVal[j] = MulScale(DudeDifficulty[gGameOptions.nDifficulty], dudeInfo[i].startDamage[j], 8); - it.Reset(kStatDude); while (auto act = it.Next()) { - if (!act->hasX()) continue; + /////////////// auto pDudeInfo = getDudeInfo(act); + for (int j = 0; j < 7; j++) + act->dmgControl[j] = MulScale(DudeDifficulty[gGameOptions.nDifficulty], pDudeInfo->startDamage[j], 8); + + + if (!act->hasX()) continue; + int seqStartId = pDudeInfo->seqStartID; if (!act->IsPlayerActor()) { @@ -1580,7 +1577,7 @@ static void ConcussSprite(DBloodActor* source, DBloodActor* actor, const DVector } else if (actor->GetType() >= kThingBase && actor->GetType() < kThingMax) { - mass = thingInfo[actor->GetType() - kThingBase].mass; + mass = actor->IntVar("mass"); } else { @@ -2331,12 +2328,7 @@ static int actDamageDude(DBloodActor* source, DBloodActor* actor, int damage, DA return damage >> 4; } - auto pDudeInfo = getDudeInfo(actor); - int nDamageFactor = pDudeInfo->damageVal[damageType]; -#ifdef NOONE_EXTENSIONS - if (actor->GetType() == kDudeModernCustom) - nDamageFactor = actor->genDudeExtra.dmgControl[damageType]; -#endif + int nDamageFactor = actor->dmgControl[damageType]; if (!nDamageFactor) return 0; else if (nDamageFactor != 256) damage = MulScale(damage, nDamageFactor, 8); @@ -2368,7 +2360,7 @@ static int actDamageThing(DBloodActor* source, DBloodActor* actor, int damage, D { assert(actor->IsThingActor()); int nType = actor->GetType() - kThingBase; - int nDamageFactor = thingInfo[nType].dmgControl[damageType]; + int nDamageFactor = actor->dmgControl[damageType]; if (!nDamageFactor) return 0; else if (nDamageFactor != 256) damage = MulScale(damage, nDamageFactor, 8); @@ -2533,15 +2525,16 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode) actHitcodeToData(hitCode, &gHitInfo, &actorHit, &pWallHit); - const THINGINFO* pThingInfo = nullptr; DUDEINFO* pDudeInfo = nullptr; + bool pIsThing = false; + int nThingDamage = actorHit->dmgControl[kDamageBurn]; if (hitCode == 3 && actorHit) { switch (actorHit->spr.statnum) { case kStatThing: - pThingInfo = &thingInfo[actorHit->GetType() - kThingBase]; + pIsThing = true; break; case kStatDude: pDudeInfo = getDudeInfo(actorHit); @@ -2551,13 +2544,13 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode) switch (missileActor->GetType()) { case kMissileLifeLeechRegular: - if (hitCode == 3 && actorHit && (pThingInfo || pDudeInfo)) + if (hitCode == 3 && actorHit && (pIsThing || pDudeInfo)) { DAMAGE_TYPE rand1 = (DAMAGE_TYPE)Random(7); int rand2 = (7 + Random(7)) << 4; int nDamage = actDamageSprite(missileOwner, actorHit, rand1, rand2); - if ((pThingInfo && pThingInfo->dmgControl[kDamageBurn] != 0) || (pDudeInfo && pDudeInfo->damageVal[kDamageBurn] != 0)) + if (nThingDamage != 0) actBurnSprite(missileActor->GetOwner(), actorHit, 360); // by NoOne: make Life Leech heal user, just like it was in 1.0x versions @@ -2600,7 +2593,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode) case kMissilePukeGreen: seqKill(missileActor); - if (hitCode == 3 && actorHit && (pThingInfo || pDudeInfo)) + if (hitCode == 3 && actorHit && (pIsThing || pDudeInfo)) { int nDamage = (15 + Random(7)) << 4; actDamageSprite(missileOwner, actorHit, kDamageBullet, nDamage); @@ -2613,7 +2606,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode) sfxPlay3DSectorSound(missileActor->spr.pos, 306, missileActor->sector()); GibSprite(missileActor, GIBTYPE_6, NULL, NULL); - if (hitCode == 3 && actorHit && (pThingInfo || pDudeInfo)) + if (hitCode == 3 && actorHit && (pIsThing || pDudeInfo)) { int nDamage = (25 + Random(20)) << 4; actDamageSprite(missileOwner, actorHit, kDamageSpirit, nDamage); @@ -2626,7 +2619,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode) sfxKill3DSound(missileActor, -1, -1); sfxPlay3DSectorSound(missileActor->spr.pos, 306, missileActor->sector()); - if (hitCode == 3 && actorHit && (pThingInfo || pDudeInfo)) + if (hitCode == 3 && actorHit && (pIsThing || pDudeInfo)) { int nDmgMul = (missileActor->GetType() == kMissileLifeLeechAltSmall) ? 6 : 3; int nDamage = (nDmgMul + Random(nDmgMul)) << 4; @@ -2637,9 +2630,9 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode) case kMissileFireball: case kMissileFireballNapalm: - if (hitCode == 3 && actorHit && (pThingInfo || pDudeInfo)) + if (hitCode == 3 && actorHit && (pIsThing || pDudeInfo)) { - if (pThingInfo && actorHit->GetType() == kThingTNTBarrel && actorHit->xspr.burnTime == 0) + if (pIsThing && actorHit->GetType() == kThingTNTBarrel && actorHit->xspr.burnTime == 0) evPostActor(actorHit, 0, AF(fxFlameLick)); int nDamage = (50 + Random(50)) << 4; @@ -2655,11 +2648,11 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode) case kMissileFlareRegular: sfxKill3DSound(missileActor, -1, -1); - if ((hitCode == 3 && actorHit) && (pThingInfo || pDudeInfo)) + if ((hitCode == 3 && actorHit) && (pIsThing || pDudeInfo)) { - if ((pThingInfo && pThingInfo->dmgControl[kDamageBurn] != 0) || (pDudeInfo && pDudeInfo->damageVal[kDamageBurn] != 0)) + if (nThingDamage != 0) { - if (pThingInfo && actorHit->GetType() == kThingTNTBarrel && actorHit->xspr.burnTime == 0) + if (pIsThing && actorHit->GetType() == kThingTNTBarrel && actorHit->xspr.burnTime == 0) evPostActor(actorHit, 0, AF(fxFlameLick)); actBurnSprite(missileOwner, actorHit, 480); @@ -2875,10 +2868,9 @@ static void checkCeilHit(DBloodActor* actor) if (actor2->spr.statnum == kStatThing) { - int nType = actor2->GetType() - kThingBase; - const THINGINFO* pThingInfo = &thingInfo[nType]; - if (pThingInfo->flags & 1) actor2->spr.flags |= 1; - if (pThingInfo->flags & 2) actor2->spr.flags |= 4; + auto flags = actor2->IntVar("defflags"); + if (flags & 1) actor2->spr.flags |= 1; + if (flags & 2) actor2->spr.flags |= 4; } else { @@ -3228,7 +3220,6 @@ static Collision MoveThing(DBloodActor* actor) { assert(actor->hasX()); assert(actor->GetType() >= kThingBase && actor->GetType() < kThingMax); - const THINGINFO* pThingInfo = &thingInfo[actor->GetType() - kThingBase]; auto pSector = actor->sector(); assert(pSector); double top, bottom; @@ -3257,7 +3248,7 @@ static Collision MoveThing(DBloodActor* actor) auto& coll = actor->hit.hit; if (coll.type == kHitWall) { - actWallBounceVector(actor, coll.hitWall, FixedToFloat(pThingInfo->elastic)); + actWallBounceVector(actor, coll.hitWall, actor->FloatVar("bouncefactor")); switch (actor->GetType()) { case kThingZombieHead: @@ -3316,11 +3307,11 @@ static Collision MoveThing(DBloodActor* actor) { actor->spr.flags |= 4; - auto vec4 = actFloorBounceVector(actor, veldiff, actor->sector(), FixedToFloat(pThingInfo->elastic)); + auto vec4 = actFloorBounceVector(actor, veldiff, actor->sector(), actor->FloatVar("bouncefactor")); actor->vel.XY() = vec4.XY(); int vax = FloatToFixed(vec4.W); - int nDamage = MulScale(vax, vax, 30) - pThingInfo->dmgResist; + int nDamage = MulScale(vax, vax, 30) - actor->IntVar("dmgresist"); if (nDamage > 0) actDamageSprite(actor, actor, kDamageFall, nDamage); actor->vel.Z = vec4.Z; @@ -4117,7 +4108,7 @@ void actExplodeSprite(DBloodActor* actor) if (actCheckRespawn(actor)) { actor->xspr.state = 1; - actor->xspr.health = thingInfo[0].startHealth << 4; + actor->xspr.health = actor->IntVar("defhealth") << 4; } else actPostSprite(actor, kStatFree); @@ -4339,10 +4330,9 @@ static void actCheckThings() XSECTOR* pXSector = pSector->hasX() ? &pSector->xs() : nullptr; if (pXSector && pXSector->panVel && (pXSector->panAlways || pXSector->state || pXSector->busy)) { - int nType = actor->GetType() - kThingBase; - const THINGINFO* pThingInfo = &thingInfo[nType]; - if (pThingInfo->flags & 1) actor->spr.flags |= 1; - if (pThingInfo->flags & 2) actor->spr.flags |= 4; + auto flags = actor->IntVar("defflags"); + if (flags & 1) actor->spr.flags |= 1; + if (flags & 2) actor->spr.flags |= 4; } if (actor->spr.flags & 3) @@ -4984,17 +4974,13 @@ DBloodActor* actSpawnThing(sectortype* pSector, const DVector3& pos, int nThingT int nType = nThingType - kThingBase; actor->ChangeType(nThingType); assert(actor->hasX()); - const THINGINFO* pThingInfo = &thingInfo[nType]; - actor->xspr.health = pThingInfo->startHealth << 4; - actor->clipdist = pThingInfo->fClipdist(); - actor->spr.flags = pThingInfo->flags; + actor->xspr.health = actor->IntVar("defhealth") << 4; + actor->clipdist = actor->FloatVar("defclipdist"); + actor->spr.flags = actor->IntVar("defflags"); if (actor->spr.flags & 2) actor->spr.flags |= 4; - actor->spr.cstat |= pThingInfo->cstat; - actor->spr.setspritetexture(pThingInfo->textureID()); - actor->spr.shade = pThingInfo->shade; - actor->spr.pal = pThingInfo->pal; - if (pThingInfo->xrepeat) actor->spr.scale.X = (pThingInfo->xrepeat * REPEAT_SCALE); - if (pThingInfo->yrepeat) actor->spr.scale.Y = (pThingInfo->yrepeat * REPEAT_SCALE); + actor->spr.cstat |= ESpriteFlags::FromInt(actor->IntVar("defcstat")); + actor->spr.shade = actor->IntVar("defshade"); + actor->spr.pal = actor->IntVar("defpal"); actor->spr.cstat2 |= CSTAT2_SPRITE_MAPPED; switch (nThingType) { @@ -5244,7 +5230,7 @@ void actFireVector(DBloodActor* shooter, double offset, double zoffset, DVector3 if (actor->spr.statnum == kStatThing) { - int mass = thingInfo[actor->GetType() - kThingBase].mass; + int mass = actor->IntVar("mass"); if (mass > 0 && pVectorData->impulse) { double thrust = double(pVectorData->impulse) / (mass * 1024); @@ -5438,7 +5424,7 @@ void TreeToGibCallback(DBloodActor* actor) actor->xspr.data1 = 15; actor->xspr.data2 = 0; actor->xspr.data3 = 0; - actor->xspr.health = thingInfo[17].startHealth; + actor->xspr.health = GetDefaultByType(actor->GetClass())->IntVar("defhealth"); actor->xspr.data4 = 312; actor->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL; } @@ -5449,7 +5435,7 @@ void DudeToGibCallback1(DBloodActor* actor) actor->xspr.data1 = 8; actor->xspr.data2 = 0; actor->xspr.data3 = 0; - actor->xspr.health = thingInfo[26].startHealth; + actor->xspr.health = GetDefaultByType(actor->GetClass())->IntVar("defhealth"); actor->xspr.data4 = 319; actor->xspr.triggerOnce = 0; actor->xspr.isTriggered = 0; @@ -5464,7 +5450,7 @@ void DudeToGibCallback2(DBloodActor* actor) actor->xspr.data1 = 3; actor->xspr.data2 = 0; actor->xspr.data3 = 0; - actor->xspr.health = thingInfo[26].startHealth; + actor->xspr.health = GetDefaultByType(actor->GetClass())->IntVar("defhealth"); actor->xspr.data4 = 319; actor->xspr.triggerOnce = 0; actor->xspr.isTriggered = 0; @@ -5576,14 +5562,5 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, SPRITEHIT& w, SPRI return arc; } -void SerializeActor(FSerializer& arc) -{ - if (arc.isReading() && gGameOptions.nMonsterSettings != 0) - { - for (int i = 0; i < kDudeMax - kDudeBase; i++) - for (int j = 0; j < 7; j++) - dudeInfo[i].damageVal[j] = MulScale(DudeDifficulty[gGameOptions.nDifficulty], dudeInfo[i].startDamage[j], 8); - } -} END_BLD_NS diff --git a/source/games/blood/src/actor.h b/source/games/blood/src/actor.h index b0a50b742..6e7173c3f 100644 --- a/source/games/blood/src/actor.h +++ b/source/games/blood/src/actor.h @@ -66,19 +66,19 @@ enum VECTOR_TYPE { struct THINGINFO { - int16_t startHealth; + int16_t startHealth; // defhealth int16_t mass; - uint8_t clipdist; - int16_t flags; - int32_t elastic; + uint8_t clipdist; // defclipdist + int16_t flags; // defflags + int32_t elastic;// fixed, bouncefactor int32_t dmgResist; - ESpriteFlags cstat; + ESpriteFlags cstat; // defcstat int16_t picno; int8_t shade; uint8_t pal; uint8_t xrepeat; uint8_t yrepeat; - int dmgControl[kDamageMax]; // damage + int16_t dmgControl[kDamageMax]; // damage, also for dudes, rename there. FTextureID textureID() const { return tileGetTextureID(picno); } double fClipdist() const { return clipdist * 0.25; } diff --git a/source/games/blood/src/ai.cpp b/source/games/blood/src/ai.cpp index 83bac4ddd..383c2620a 100644 --- a/source/games/blood/src/ai.cpp +++ b/source/games/blood/src/ai.cpp @@ -111,11 +111,11 @@ static bool isImmune(DBloodActor* actor, int dmgType, int minScale) { int type = actor->GetType(); if (type >= kThingBase && type < kThingMax) - return (thingInfo[type - kThingBase].dmgControl[dmgType] <= minScale); + return (actor->dmgControl[dmgType] <= minScale); else if (actor->IsDudeActor()) { if (actor->IsPlayerActor()) return (getPlayer(type - kDudePlayer1)->godMode || getPlayer(type - kDudePlayer1)->damageControl[dmgType] <= minScale); - else return (dudeInfo[type - kDudeBase].damageVal[dmgType] <= minScale); + else return (actor->dmgControl[dmgType] <= minScale); } } return true; diff --git a/source/games/blood/src/aiunicult.cpp b/source/games/blood/src/aiunicult.cpp index 0466dca03..8161178c1 100644 --- a/source/games/blood/src/aiunicult.cpp +++ b/source/games/blood/src/aiunicult.cpp @@ -152,7 +152,7 @@ static bool genDudeAdjustSlope(DBloodActor* actor, double dist, int weaponType, else if (weaponType == kGenDudeWeaponMissile) { auto type = GetSpawnType(pExtra->curWeapon); - auto clipdist = GetDefaultByType(type)->FloatVar("clipdist"); + auto clipdist = GetDefaultByType(type)->FloatVar("defclipdist"); actor->dudeSlope = (fStart - ((fStart - fEnd) * 0.25)) - clipdist / 2048; } return true; @@ -303,7 +303,6 @@ static void ThrowThing(DBloodActor* actor, bool impact) int weaponType = actor->genDudeExtra.weaponType; if (weaponType != kGenDudeWeaponThrow) return; - const THINGINFO* pThinkInfo = &thingInfo[curWeapon - kThingBase]; if (!gThingInfoExtra[curWeapon - kThingBase].allowThrow) return; else if (!playGenDudeSound(actor, kGenDudeSndAttackThrow)) sfxPlay3DSound(actor, 455, -1, 0); @@ -326,8 +325,6 @@ static void ThrowThing(DBloodActor* actor, bool impact) DBloodActor* spawned = nullptr; if ((spawned = actFireThing(actor, 0., 0., (dv.Z / 32768.) - zThrow, curWeapon, dist * (2048. / 64800))) == nullptr) return; - if (pThinkInfo->picno < 0 && spawned->GetType() != kModernThingThrowableRock) spawned->spr.setspritetexture(FNullTextureID()); - spawned->SetOwner(actor); switch (curWeapon) { @@ -364,7 +361,7 @@ static void ThrowThing(DBloodActor* actor, bool impact) return; case kModernThingEnemyLifeLeech: if (actLeech != nullptr) spawned->xspr.health = actLeech->xspr.health; - else spawned->xspr.health = ((pThinkInfo->startHealth << 4) * gGameOptions.nDifficulty) >> 1; + else spawned->xspr.health = ((spawned->IntVar("health") << 4) * gGameOptions.nDifficulty) >> 1; sfxPlay3DSound(actor, 490, -1, 0); @@ -1452,7 +1449,7 @@ static void scaleDamage(DBloodActor* actor) { int curWeapon = actor->genDudeExtra.curWeapon; int weaponType = actor->genDudeExtra.weaponType; - signed short* curScale = actor->genDudeExtra.dmgControl; + signed short* curScale = actor->dmgControl; for (int i = 0; i < kDmgMax; i++) curScale[i] = getDudeInfo(kDudeModernCustom)->startDamage[i]; diff --git a/source/games/blood/src/aiunicult.h b/source/games/blood/src/aiunicult.h index 5005faf31..168e51bdd 100644 --- a/source/games/blood/src/aiunicult.h +++ b/source/games/blood/src/aiunicult.h @@ -172,7 +172,6 @@ struct GENDUDEEXTRA uint16_t slaveCount; // how many dudes is summoned TObjPtr pLifeLeech; // spritenum of dropped dude's leech TObjPtr slave[kGenDudeMaxSlaves]; // index of the ones dude is summon - signed short dmgControl[kDamageMax]; // depends of current weapon, drop armor item, sprite repeat and surface type bool updReq[kGenDudePropertyMax]; // update requests union { diff --git a/source/games/blood/src/blood.cpp b/source/games/blood/src/blood.cpp index cdca80452..8355f1f99 100644 --- a/source/games/blood/src/blood.cpp +++ b/source/games/blood/src/blood.cpp @@ -50,6 +50,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "vm.h" #include "tilesetbuilder.h" #include "nnexts.h" +#include "thingdef.h" BEGIN_BLD_NS @@ -765,4 +766,13 @@ void RegisterClasses() } } +DEFINE_PROPERTY(dmgcontrol, IIIIIII, BloodActor) +{ + for (int i = 0; i < kDamageMax; i++) + { + PROP_INT_PARM(j, i); + defaults->dmgControl[i] = (int16_t)clamp(j, -32768, 32767); + } +} + END_BLD_NS diff --git a/source/games/blood/src/blood.h b/source/games/blood/src/blood.h index 5eaaa02c9..075773370 100644 --- a/source/games/blood/src/blood.h +++ b/source/games/blood/src/blood.h @@ -278,6 +278,7 @@ enum EFeatureFlags { kFeatureCustomAmmoCount = 1, kFeatureEnemyAttacks = 2, + kFeatureCustomClipdist = 4, }; constexpr int BMAX_PATH = 260; diff --git a/source/games/blood/src/bloodactor.h b/source/games/blood/src/bloodactor.h index 5ace074e2..ba6393bfd 100644 --- a/source/games/blood/src/bloodactor.h +++ b/source/games/blood/src/bloodactor.h @@ -34,6 +34,7 @@ public: TObjPtr prevmarker; // needed by the nnext marker code. This originally hijacked targetX in XSPRITE DVector3 basePoint; EventObject condition[2]; + int16_t dmgControl[kDamageMax]; // combination of the ones in DUDEINFO, THINGINFO and GENDUDEEXTRA, needs to be modifiable // transient data (not written to savegame) int cumulDamage; diff --git a/source/games/blood/src/dude.cpp b/source/games/blood/src/dude.cpp index ab3a5ca19..58d98aa59 100644 --- a/source/games/blood/src/dude.cpp +++ b/source/games/blood/src/dude.cpp @@ -53,7 +53,6 @@ DUDEINFO dudeInfo[kDudeMax - kDudeBase] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0 }, diff --git a/source/games/blood/src/dude.h b/source/games/blood/src/dude.h index d31c9f189..dc76b66b8 100644 --- a/source/games/blood/src/dude.h +++ b/source/games/blood/src/dude.h @@ -48,8 +48,8 @@ struct DUDEINFO { int backSpeed; // backward speed (unused) int angSpeed; // turn speed int nGibType[3]; // which gib used when explode dude - int startDamage[7]; // start damage shift - int damageVal[7]; // real damage? Hmm? + int16_t startDamage[7]; // start damage shift + int16_t __filler__[7]; // not used anymore int at8c; // unused ? int at90; // unused ? diff --git a/source/games/blood/src/loadsave.cpp b/source/games/blood/src/loadsave.cpp index e2af8c388..c399386eb 100644 --- a/source/games/blood/src/loadsave.cpp +++ b/source/games/blood/src/loadsave.cpp @@ -480,7 +480,8 @@ void DBloodActor::Serialize(FSerializer& arc) ("dudeextra", dudeExtra) ("explosionflag", explosionhackflag) ("spritehit", hit) - ("owneractor", ownerActor); + ("owneractor", ownerActor) + .Array("dmgcontrol", dmgControl, kDamageMax); } @@ -717,7 +718,6 @@ void SerializeEvents(FSerializer& arc); void SerializeSequences(FSerializer& arc); void SerializeWarp(FSerializer& arc); void SerializeTriggers(FSerializer& arc); -void SerializeActor(FSerializer& arc); void SerializePlayers(FSerializer& arc); void SerializeView(FSerializer& arc); void SerializeNNExts(FSerializer& arc); @@ -741,7 +741,6 @@ void GameInterface::SerializeGameState(FSerializer& arc) seqKillAll(); } SerializeState(arc); - SerializeActor(arc); SerializePlayers(arc); SerializeEvents(arc); SerializeSequences(arc); diff --git a/source/games/blood/src/namelist.h b/source/games/blood/src/namelist.h index bc629eaf7..d09cf3f14 100644 --- a/source/games/blood/src/namelist.h +++ b/source/games/blood/src/namelist.h @@ -275,3 +275,27 @@ x(Fireball, 3056) x(Teslaball, 2130) x(EctoSkull, 870) x(LeechBall, 2446) + +x(TNTBarrel, 907) +x(ProxBomb, 3444) +x(ArmedRemote, 3457) +x(Vase1, 739) +x(Vase2, 642) +x(CreateFace, 462) +x(GlassWindow, 266) +x(Fluorescent, 796) +x(WallCrack, 1127) +x(WoodBeam, 1142) +x(SpiderWeb, 1069) +x(MetalGrate, 483) +x(ArmedTNT, 3422) +x(ArmedTNTBundle, 3433) +x(ArmedSpray, 3467) +x(Bone, 1462) +x(DripWater, 1147) +x(DripBlood, 1160) +x(ZombieHead, 3405) +x(NapalmBall, 3281) +x(PodFireball, 2020) +x(PodGreenBall, 1860) +x(VoodooHead, 2443) \ No newline at end of file diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 89a157c6c..04956dfef 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -338,13 +338,12 @@ bool nnExtIsImmune(DBloodActor* actor, int dmgType, int minScale) { if (actor->GetType() >= kThingBase && actor->GetType() < kThingMax) { - return (thingInfo[actor->GetType() - kThingBase].dmgControl[dmgType] <= minScale); + return (actor->dmgControl[dmgType] <= minScale); } else if (actor->IsDudeActor()) { if (actor->IsPlayerActor()) return (getPlayer(actor)->damageControl[dmgType]); - else if (actor->GetType() == kDudeModernCustom) return (actor->genDudeExtra.dmgControl[dmgType] <= minScale); - else return (getDudeInfo(actor)->damageVal[dmgType] <= minScale); + return (actor->dmgControl[dmgType] <= minScale); } } @@ -4693,7 +4692,7 @@ bool condCheckSprite(DBloodActor* aCond, int cmpOp, bool PUSH) case 50: // compare hp (in %) if (objActor->IsDudeActor()) var = (objActor->xspr.sysData2 > 0) ? ClipRange(objActor->xspr.sysData2 << 4, 1, 65535) : getDudeInfo(objActor)->startHealth << 4; else if (objActor->GetType() == kThingBloodChunks) return condCmp(0, arg1, arg2, cmpOp); - else if (objActor->GetType() >= kThingBase && objActor->GetType() < kThingMax) var = thingInfo[objActor->GetType() - kThingBase].startHealth << 4; + else if (objActor->GetType() >= kThingBase && objActor->GetType() < kThingMax) var = objActor->IntVar("defhealth") << 4; return condCmp((kPercFull * objActor->xspr.health) / ClipLow(var, 1), arg1, arg2, cmpOp); case 55: // touching ceil of sector? if (objActor->hit.ceilhit.type != kHitSector) return false; @@ -9407,7 +9406,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, GENDUDEEXTRA& w, G ("slavecount", w.slaveCount) ("lifeleech", w.pLifeLeech) .Array("slaves", w.slave, w.slaveCount) - .Array("dmgcontrol", w.dmgControl, kDamageMax) .Array("updreq", w.updReq, kGenDudePropertyMax) ("flags", w.flags) .EndObject(); diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index 6b78a31a4..0e7deb1e4 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -694,7 +694,7 @@ void playerSetRace(DBloodPlayer* pPlayer, int nLifeMode) pPlayer->GetActor()->clipdist = pDudeInfo->fClipdist(); for (int i = 0; i < 7; i++) - pDudeInfo->damageVal[i] = MulScale(Handicap[gSkill], pDudeInfo->startDamage[i], 8); + pPlayer->GetActor()->dmgControl[i] = MulScale(Handicap[gSkill], pDudeInfo->startDamage[i], 8); } //--------------------------------------------------------------------------- @@ -2410,7 +2410,7 @@ void DBloodPlayer::Serialize(FSerializer& arc) .Array("haskey", hasKey, 8) ("hasflag", hasFlag) .Array("ctfflagstate", ctfFlagState, 2) - .Array("dmgcontrol", damageControl, 7) + .Array("dmgcontrol", damageControl, kDamageMax) ("curweapon", curWeapon) ("nextweapon", nextWeapon) ("weapontimer", weaponTimer) diff --git a/wadsrc/static/filter/blood/rmapinfo.spawnclasses b/wadsrc/static/filter/blood/rmapinfo.spawnclasses index bc7ceaeed..4a9301e13 100644 --- a/wadsrc/static/filter/blood/rmapinfo.spawnclasses +++ b/wadsrc/static/filter/blood/rmapinfo.spawnclasses @@ -171,10 +171,13 @@ spawnclasses 400 = BloodThingTNTBarrel 401 = BloodThingArmedProxBomb 402 = BloodThingArmedRemoteBomb + 403 = BloodThingVase1 + 404 = BloodThingVase2 405 = BloodThingCrateFace 406 = BloodThingGlassWindow 407 = BloodThingFluorescent 408 = BloodThingWallCrack + 409 = BloodThingWoodBeam 410 = BloodThingSpiderWeb 411 = BloodThingMetalGrate 412 = BloodThingFlammableTree @@ -187,6 +190,7 @@ spawnclasses 419 = BloodThingArmedTNTBundle 420 = BloodThingArmedSpray 421 = BloodThingBone + 422 = BloodThing422 423 = BloodThingDripWater 424 = BloodThingDripBlood 425 = BloodThingBloodBits @@ -197,6 +201,9 @@ spawnclasses 430 = BloodThingPodGreenBall 431 = BloodThingDroppedLifeLeech 432 = BloodThingVoodooHead + 433 = BloodThingTNTProx + 434 = BloodThingThrowableRock + 435 = BloodThingEnemyLifeLeech // traps 452 = BloodTrapFlame diff --git a/wadsrc/static/zscript/games/blood/actors/missiles.zs b/wadsrc/static/zscript/games/blood/actors/missiles.zs index 10d74d233..2c86f20b8 100644 --- a/wadsrc/static/zscript/games/blood/actors/missiles.zs +++ b/wadsrc/static/zscript/games/blood/actors/missiles.zs @@ -1,7 +1,6 @@ class BloodMissileBase : BloodActor { meta double speed; - meta double defclipdist; meta double angleofs; meta VMFunction callback; meta int spawnsoundID; @@ -14,7 +13,6 @@ class BloodMissileBase : BloodActor property prefix: none; property speed: speed; - property clipdist: defclipdist; property angleofs: angleofs; property callback: callback; property spawnsound: spawnsound; diff --git a/wadsrc/static/zscript/games/blood/actors/things.zs b/wadsrc/static/zscript/games/blood/actors/things.zs index bee345f66..105576833 100644 --- a/wadsrc/static/zscript/games/blood/actors/things.zs +++ b/wadsrc/static/zscript/games/blood/actors/things.zs @@ -1,38 +1,555 @@ -// things -class BloodThingBase : BloodActor {} -class BloodThingTNTBarrel : BloodActor {} -class BloodThingArmedProxBomb : BloodActor {} -class BloodThingArmedRemoteBomb : BloodActor {} -class BloodThingCrateFace : BloodActor {} -class BloodThingGlassWindow : BloodActor {} -class BloodThingFluorescent : BloodActor {} -class BloodThingWallCrack : BloodActor {} -class BloodThingSpiderWeb : BloodActor {} -class BloodThingMetalGrate : BloodActor {} -class BloodThingFlammableTree : BloodActor {} -class BloodTrapMachinegun : BloodActor {} -class BloodThingFallingRock : BloodActor {} -class BloodThingKickablePail : BloodActor {} -class BloodThingObjectGib : BloodActor {} -class BloodThingObjectExplode : BloodActor {} -class BloodThingArmedTNTStick : BloodActor {} -class BloodThingArmedTNTBundle : BloodActor {} -class BloodThingArmedSpray : BloodActor {} -class BloodThingBone : BloodActor {} -class BloodThingDripWater : BloodActor {} -class BloodThingDripBlood : BloodActor {} -class BloodThingBloodBits : BloodActor {} -class BloodThingBloodChunks : BloodActor {} -class BloodThingZombieHead : BloodActor {} -class BloodThingNapalmBall : BloodActor {} -class BloodThingPodFireBall : BloodActor {} -class BloodThingPodGreenBall : BloodActor {} -class BloodThingDroppedLifeLeech : BloodActor {} -class BloodThingVoodooHead : BloodActor {} // unused -class BloodThingMax : BloodActor {} +class BloodThingBase : BloodActor +{ + meta int defhealth; + meta int mass; + meta int defflags; + meta int bouncefactor; + meta int dmgResist; + meta int defcstat; + + property prefix: none; + property health: defhealth; + property mass: mass; + property flags: defflags; + property bouncefactor: bouncefactor; + property dmgResist: dmgResist; + property cstat: defcstat; +} + +class BloodThingTNTBarrel : BloodThingBase +{ + default + { + health 25; + mass 250; + clipdist 8.000000; + flags 11; + bouncefactor 4096; + dmgResist 80; + cstat CSTAT_SPRITE_YCENTER | CSTAT_SPRITE_BLOCK_HITSCAN; + pic "TNTBarrel"; + dmgcontrol 256, 256, 128, 64, 0, 0, 128; + } +} + +class BloodThingArmedProxBomb : BloodThingBase +{ + default + { + health 5; + mass 5; + clipdist 4.000000; + flags 3; + bouncefactor 24576; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + pic "ProxBomb"; + shade -16; + scale 0.500000, 0.500000; + dmgcontrol 256, 256, 256, 64, 0, 0, 512; + } +} + +class BloodThingArmedRemoteBomb : BloodThingBase +{ + default + { + health 5; + mass 5; + clipdist 4.000000; + flags 3; + bouncefactor 24576; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + pic "ArmedRemote"; + shade -16; + scale 0.500000, 0.500000; + dmgcontrol 256, 256, 256, 64, 0, 0, 512; + } +} + +class BloodThingVase1 : BloodThingBase +{ + default + { + health 1; + mass 20; + clipdist 8.000000; + flags 3; + bouncefactor 32768; + dmgResist 80; + pic "Vase1"; + dmgcontrol 256, 0, 256, 128, 0, 0, 0; + } +} + +class BloodThingVase2 : BloodThingBase +{ + default + { + health 1; + mass 150; + clipdist 8.000000; + flags 3; + bouncefactor 32768; + dmgResist 80; + pic "Vase2"; + dmgcontrol 256, 256, 256, 128, 0, 0, 0; + } +} + +class BloodThingCrateFace : BloodThingBase +{ + default + { + health 10; + clipdist 0.000000; + pic "CreateFace"; + dmgcontrol 0, 0, 0, 256, 0, 0, 0; + } +} + +class BloodThingGlassWindow : BloodThingBase +{ + default + { + health 1; + clipdist 0.000000; + pic "GlassWindow"; + dmgcontrol 256, 0, 256, 256, 0, 0, 0; + } +} + +class BloodThingFluorescent : BloodThingBase +{ + default + { + health 1; + clipdist 0.000000; + pic "Fluorescent"; + dmgcontrol 256, 0, 256, 256, 0, 0, 512; + } +} + +class BloodThingWallCrack : BloodThingBase +{ + default + { + health 50; + clipdist 0.000000; + pic "WallCrack"; + dmgcontrol 0, 0, 0, 256, 0, 0, 0; + } +} + +class BloodThingWoodBeam : BloodThingBase +{ + default + { + health 8; + clipdist 0.000000; + pic "WoodBeam"; + dmgcontrol 256, 0, 256, 128, 0, 0, 0; + } +} + +class BloodThingSpiderWeb : BloodThingBase +{ + default + { + health 4; + clipdist 0.000000; + pic "SpiderWeb"; + dmgcontrol 256, 256, 64, 256, 0, 0, 128; + } +} + +class BloodThingMetalGrate : BloodThingBase +{ + default + { + health 40; + clipdist 0.000000; + pic "MetalGrate"; + dmgcontrol 64, 0, 128, 256, 0, 0, 0; + } +} + +class BloodThingFlammableTree : BloodThingBase +{ + default + { + health 1; + clipdist 0.000000; + dmgcontrol 0, 256, 0, 256, 0, 0, 128; + } +} + +class BloodTrapMachinegun : BloodThingBase +{ + default + { + health 1000; + clipdist 0.000000; + flags 8; + dmgcontrol 0, 0, 128, 256, 0, 0, 512; + } +} + +class BloodThingFallingRock : BloodThingBase +{ + default + { + mass 15; + clipdist 2.000000; + flags 3; + bouncefactor 32768; + } +} + +class BloodThingKickablePail : BloodThingBase +{ + default + { + mass 8; + clipdist 12.000000; + flags 3; + bouncefactor 49152; + } +} + +class BloodThingObjectGib : BloodThingBase +{ + default + { + health 10; + mass 2; + clipdist 0.000000; + bouncefactor 32768; + dmgcontrol 256, 0, 256, 256, 0, 0, 128; + } +} + +class BloodThingObjectExplode : BloodThingBase +{ + default + { + health 20; + mass 2; + clipdist 0.000000; + bouncefactor 32768; + dmgcontrol 0, 0, 0, 256, 0, 0, 128; + } +} + +class BloodThingArmedTNTStick : BloodThingBase +{ + default + { + health 5; + mass 14; + clipdist 4.000000; + flags 3; + bouncefactor 24576; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + pic "ArmedTNT"; + shade -32; + scale 0.500000, 0.500000; + dmgcontrol 64, 256, 128, 64, 0, 0, 256; + } +} + +class BloodThingArmedTNTBundle : BloodThingBase +{ + default + { + health 5; + mass 14; + clipdist 4.000000; + flags 3; + bouncefactor 24576; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + pic "ArmedTNTBundle"; + shade -32; + scale 0.500000, 0.500000; + dmgcontrol 64, 256, 128, 64, 0, 0, 256; + } +} + +class BloodThingArmedSpray : BloodThingBase +{ + default + { + health 5; + mass 14; + clipdist 4.000000; + flags 3; + bouncefactor 32768; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + pic "ArmedSpray"; + shade -128; + scale 0.500000, 0.500000; + dmgcontrol 64, 256, 128, 64, 0, 0, 256; + } +} + +class BloodThingBone : BloodThingBase +{ + default + { + health 5; + mass 6; + clipdist 4.000000; + flags 3; + bouncefactor 32768; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + pic "Bone"; + scale 0.500000, 0.500000; + } +} + +class BloodThing422 : BloodThingBase +{ + default + { + health 8; + mass 3; + clipdist 4.000000; + flags 11; + bouncefactor 32768; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + dmgcontrol 256, 0, 256, 256, 0, 0, 0; + } +} + +class BloodThingDripWater : BloodThingBase +{ + default + { + mass 1; + clipdist 0.250000; + flags 2; + pic "DripWater"; + pal 10; + } +} + +class BloodThingDripBlood : BloodThingBase +{ + default + { + mass 1; + clipdist 0.250000; + flags 2; + pic "DripBlood"; + pal 2; + } +} + +class BloodThingBloodBits : BloodThingBase +{ + default + { + health 15; + mass 4; + clipdist 1.000000; + flags 3; + bouncefactor 24576; + cstat CSTAT_SPRITE_BLOCK_ALL; + dmgcontrol 128, 64, 256, 256, 0, 0, 256; + } +} + +class BloodThingBloodChunks : BloodThingBase +{ + default + { + health 30; + mass 30; + clipdist 2.000000; + flags 3; + bouncefactor 8192; + cstat CSTAT_SPRITE_BLOCK_ALL; + dmgcontrol 128, 64, 256, 256, 0, 0, 64; + } +} + +class BloodThingZombieHead : BloodThingBase +{ + default + { + health 60; + mass 5; + clipdist 8.000000; + flags 3; + bouncefactor 40960; + dmgResist 1280; + cstat CSTAT_SPRITE_BLOCK_ALL; + pic "ZombieHead"; + scale 0.625000, 0.625000; + dmgcontrol 128, 64, 256, 256, 0, 0, 64; + } +} + +class BloodThingNapalmBall : BloodThingBase +{ + default + { + health 80; + mass 30; + clipdist 8.000000; + flags 3; + bouncefactor 57344; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + pic "NapalmBall"; + shade -128; + scale 0.500000, 0.500000; + } +} + +class BloodThingPodFireBall : BloodThingBase +{ + default + { + health 80; + mass 30; + clipdist 8.000000; + flags 3; + bouncefactor 57344; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + pic "PodFireball"; + shade -128; + scale 0.500000, 0.500000; + dmgcontrol 256, 0, 256, 256, 0, 0, 0; + } +} + +class BloodThingPodGreenBall : BloodThingBase +{ + default + { + health 80; + mass 30; + clipdist 8.000000; + flags 3; + bouncefactor 57344; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + pic "PodGreenBall"; + shade -128; + scale 0.500000, 0.500000; + dmgcontrol 256, 0, 256, 256, 0, 0, 0; + } +} + +class BloodThingDroppedLifeLeech : BloodThingBase +{ + default + { + health 150; + mass 30; + clipdist 12.000000; + flags 3; + bouncefactor 32768; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_ALL; + pic "ICONLEECH"; + shade -128; + scale 0.750000, 0.750000; + dmgcontrol 64, 64, 112, 64, 0, 96, 96; + } +} + +class BloodThingVoodooHead : BloodThingBase +{ + default + { + health 1; + mass 30; + clipdist 12.000000; + flags 3; + bouncefactor 32768; + dmgResist 1600; + pic "VoodooHead"; + shade -128; + scale 0.250000, 0.250000; + } +} + +class BloodThingTNTProx : BloodThingBase +{ + default + { + health 5; + mass 5; + clipdist 4.000000; + flags 3; + bouncefactor 24576; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + pic "ProxBomb"; + shade -16; + pal 7; + scale 0.500000, 0.500000; + dmgcontrol 256, 256, 256, 64, 0, 0, 512; + } +} + +class BloodThingThrowableRock : BloodThingBase +{ + default + { + health 5; + mass 6; + clipdist 4.000000; + flags 3; + bouncefactor 32768; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_HITSCAN; + pic "Bone"; + scale 0.500000, 0.500000; + } +} + +class BloodThingEnemyLifeLeech : BloodThingBase +{ + default + { + health 150; + mass 30; + clipdist 12.000000; + flags 3; + bouncefactor 32768; + dmgResist 1600; + cstat CSTAT_SPRITE_BLOCK_ALL; + pic "ICONLEECH"; + shade -128; + scale 0.687500, 0.687500; + dmgcontrol 0, 1024, 512, 1024, 0, 64, 512; + } +} // traps -class BloodTrapFlame : BloodActor {} -class BloodTrapSawCircular : BloodActor {} -class BloodTrapZapSwitchable : BloodActor {} -class BloodTrapExploder : BloodActor {} +class BloodTrapFlame : BloodActor +{ +} + +class BloodTrapSawCircular : BloodActor +{ +} + +class BloodTrapZapSwitchable : BloodActor +{ +} + +class BloodTrapExploder : BloodActor +{ +} + diff --git a/wadsrc/static/zscript/games/blood/bloodactor.zs b/wadsrc/static/zscript/games/blood/bloodactor.zs index ec33e0055..ff3e87c19 100644 --- a/wadsrc/static/zscript/games/blood/bloodactor.zs +++ b/wadsrc/static/zscript/games/blood/bloodactor.zs @@ -92,9 +92,11 @@ class BloodActor : CoreActor native { meta int defshade; meta int defpal; + meta double defclipdist; Property prefix: none; property shade: defshade; property pal: defpal; + property clipdist: defclipdist; enum STAT_ID { kStatDecoration = 0,