scriptified the onHit block in actCheckThings.

This commit is contained in:
Christoph Oelckers 2023-10-10 19:01:29 +02:00
parent 3b39e1db99
commit 7851b686ec
16 changed files with 223 additions and 114 deletions

View file

@ -31,3 +31,4 @@ inline FGameTexture* tileGetTexture(int tile, bool animate = false)
if (animate) tileUpdatePicnum(texid);
return TexMan.GetGameTexture(texid);
}

View file

@ -120,3 +120,25 @@ int tilehasmodelorvoxel(FTextureID texid, int pal)
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int tileGetSurfType(const CollisionBase& hit)
{
switch (hit.type)
{
default:
return 0;
case kHitSector:
return tilesurface(hit.hitSector->floortexture);
case kHitWall:
return tilesurface(hit.hitWall->walltexture);
case kHitSprite:
return tilesurface(hit.hitActor->spr.spritetexture());
}
}

View file

@ -195,3 +195,6 @@ inline uint8_t tilesurface(FTextureID texid)
return GetExtInfo(texid).surftype;
}
struct CollisionBase;
int tileGetSurfType(const CollisionBase& hit);

View file

@ -1160,3 +1160,15 @@ DEFINE_ACTION_FUNCTION_NATIVE(_CollisionData, setnone, collision_setnone)
return 0;
}
void collision_getsu(CollisionBase* coll)
{
coll->type = kHitNone;
coll->hitActor = nullptr;
}
DEFINE_ACTION_FUNCTION_NATIVE(_CollisionData, getsurfacetype, tileGetSurfType)
{
PARAM_SELF_STRUCT_PROLOGUE(CollisionBase);
ACTION_RETURN_INT(tileGetSurfType(*self));
}

View file

@ -3712,48 +3712,7 @@ static void actCheckThings()
if (hit.type)
{
if (actor->xspr.Impact) trTriggerSprite(actor, kCmdOff, hit.type == kHitSprite? hit.safeActor() : nullptr);
switch (actor->GetType())
{
case kThingDripWater:
case kThingDripBlood:
MakeSplash(actor);
break;
#ifdef NOONE_EXTENSIONS
case kModernThingThrowableRock:
seqSpawn(24, actor);
if (hit.type == kHitSprite)
{
actor->spr.scale = DVector2(0.5, 0.5);
actDamageSprite(actor->GetOwner(), hit.actor(), kDamageFall, actor->xspr.data1);
}
break;
#endif
case kThingBone:
seqSpawn(24, actor);
if (hit.type == kHitSprite)
{
actDamageSprite(actor->GetOwner(), hit.actor(), kDamageFall, 12);
}
break;
case kThingPodGreenBall:
if (hit.type == kHitSector)
{
actRadiusDamage(actor->GetOwner(), actor->spr.pos, actor->sector(), 200, 1, 20, kDamageExplode, 6, 0);
evPostActor(actor, 0, AF(fxPodBloodSplat));
}
else if (hit.type == kHitSprite)
{
actDamageSprite(actor->GetOwner(), hit.actor(), kDamageFall, 12);
evPostActor(actor, 0, AF(fxPodBloodSplat));
}
break;
case kThingPodFireBall:
actExplodeSprite(actor);
break;
}
actOnHit(actor, hit);
}
}
}
@ -4777,39 +4736,6 @@ void actPostProcess(void)
gPost.Clear();
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void MakeSplash(DBloodActor* actor)
{
actor->spr.flags &= ~2;
actor->spr.pos.Z -= 4;
int nSurface = tileGetSurfType(actor->hit.florhit);
switch (actor->GetType())
{
case kThingDripWater:
switch (nSurface)
{
case kSurfWater:
seqSpawn(6, actor);
sfxPlay3DSound(actor, 356, -1, 0);
break;
default:
seqSpawn(7, actor);
sfxPlay3DSound(actor, 354, -1, 0);
break;
}
break;
case kThingDripBlood:
seqSpawn(8, actor);
sfxPlay3DSound(actor, 354, -1, 0);
break;
}
}
void actBurnSprite(DBloodActor* pSource, DBloodActor* pTarget, int nTime)
{
pTarget->xspr.burnTime = ClipHigh(pTarget->xspr.burnTime + nTime, pTarget->spr.statnum == kStatDude ? 2400 : 1200);

View file

@ -140,9 +140,10 @@ bool actCheckRespawn(DBloodActor *pSprite);
void actFireVector(DBloodActor* shooter, double offset, double zoffset, DVector3 dv, VECTOR_TYPE vectorType, double nRange = -1);
void actPostSprite(DBloodActor* actor, int status);
void actPostProcess(void);
void MakeSplash(DBloodActor *actor);
void actOnHit(DBloodActor *actor, Collision& hit);
void callActorFunction(VMFunction* funcID, DBloodActor* actor);
extern const int16_t DudeDifficulty[];

View file

@ -2667,5 +2667,15 @@ case kDudePodMother: // FakeDude type (no seq, custom flags, clipdist and cstat
[[fallthrough]];
*/
/* onHit
case kModernThingThrowableRock:
seqSpawn(24, actor);
if (hit.type == kHitSprite)
{
self.scale = DVector2(0.5, 0.5);
actDamageSprite(self.GetOwner(), hit.actor(), kDamageFall, self.xspr.data1);
}
break;
*/
END_BLD_NS
#endif

View file

@ -446,17 +446,6 @@ enum
kPhysGravity = 0x0002, // affected by gravity
kPhysFalling = 0x0004, // currently in z-motion
// sector cstat
kSecCParallax = 0x01,
kSecCSloped = 0x02,
kSecCSwapXY = 0x04,
kSecCExpand = 0x08,
kSecCFlipX = 0x10,
kSecCFlipY = 0x20,
kSecCFlipMask = 0x34,
kSecCRelAlign = 0x40,
kSecCFloorShade = 0x8000,
kAng5 = 28,
kAng15 = 85,
kAng30 = 170,

View file

@ -98,6 +98,4 @@ inline FTextureID mirrortile;
void tilePrecacheTile(FTextureID nTile, int nType, int palette);
int tileGetSurfType(CollisionBase& hit);
END_BLD_NS

View file

@ -111,25 +111,4 @@ void GameInterface::SetupSpecialTextures(TilesetBuildInfo& info)
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int tileGetSurfType(CollisionBase& hit)
{
switch (hit.type)
{
default:
return 0;
case kHitSector:
return GetExtInfo(hit.hitSector->floortexture).surftype;
case kHitWall:
return GetExtInfo(hit.hitWall->walltexture).surftype;
case kHitSprite:
return GetExtInfo(hit.hitActor->spr.spritetexture()).surftype;
}
}
END_BLD_NS

View file

@ -354,6 +354,49 @@ DEFINE_ACTION_FUNCTION_NATIVE(DBloodActor, impactMissile, actImpactMissile)
return 0;
}
static int blood_DamageSprite(DBloodActor* actor, DBloodActor* source, int damageType, int damage)
{
return actDamageSprite(source, actor, DAMAGE_TYPE(damageType), damage);
}
DEFINE_ACTION_FUNCTION_NATIVE(DBloodActor, damageSprite, blood_DamageSprite)
{
PARAM_SELF_PROLOGUE(DBloodActor);
PARAM_POINTER(source, DBloodActor);
PARAM_INT(damagetype);
PARAM_INT(damage);
ACTION_RETURN_INT(blood_DamageSprite(source, self, damagetype, damage));
}
DEFINE_ACTION_FUNCTION_NATIVE(DBloodActor, explodeSprite, actExplodeSprite)
{
PARAM_SELF_PROLOGUE(DBloodActor);
actExplodeSprite(self);
return 0;
}
static void blood_RadiusDamage(DBloodActor* source, double x, double y, double z, sectortype* pSector, int dist, int basedmg, int distdmg, int dmgtype, int flags, int burn)
{
actRadiusDamage(source, DVector3(x, y, z), pSector, dist, basedmg, distdmg, DAMAGE_TYPE(dmgtype), flags, burn);
}
DEFINE_ACTION_FUNCTION_NATIVE(DBloodActor, radiusDamage, blood_RadiusDamage)
{
PARAM_SELF_PROLOGUE(DBloodActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
PARAM_POINTER(sector, sectortype);
PARAM_INT(dist);
PARAM_INT(basedmg);
PARAM_INT(distdmg);
PARAM_INT(dmgtype);
PARAM_INT(flags);
PARAM_INT(burn);
actRadiusDamage(self, DVector3(x, y, z), sector, dist, basedmg, distdmg, DAMAGE_TYPE(dmgtype), flags, burn);
return 0;
}
//---------------------------------------------------------------------------
//
//
@ -434,12 +477,27 @@ DBloodActor* actSpawnThing(sectortype* pSector, const DVector3& pos, int nThingT
return nullptr;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void actOnHit(DBloodActor* actor, Collision& hit)
{
IFVIRTUALPTR(actor, DBloodActor, onHit)
{
VMValue param[] = { actor, &hit };
VMCall(func, param, 1, nullptr, 0);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void callActorFunction(VMFunction* funcID, DBloodActor* actor)
{
if (funcID)

View file

@ -35,7 +35,7 @@ class BloodMissileBase : BloodActor
self.shade = self.defshade;
self.pal = self.defpal;
self.clipdist = clipdist;
self.flags = 1;
self.flags = kPhysMove;
self.Angle = spawner.angle + self.angleofs;
self.ownerActor = spawner;

View file

@ -1,3 +1,4 @@
class BloodThingBase : BloodActor
{
meta int defhealth;
@ -36,7 +37,7 @@ class BloodThingBase : BloodActor
self.xspr.health = self.defhealth << 4;
self.clipdist = self.defclipdist;
self.flags = self.defflags;
if (self.flags & 2) self.flags |= 4;
if (self.flags & kPhysGravity) self.flags |= kPhysFalling;
self.cstat |= self.defcstat;
self.shade = self.defshade;
self.pal = self.defpal;
@ -361,6 +362,17 @@ class BloodThingBone : BloodThingBase
pic "Bone";
scale 0.500000, 0.500000;
}
override void onHit(CollisionData hit)
{
self.seqSpawnID(24);
if (hit.type == kHitSprite)
{
let victim = BloodActor(hit.hitActor());
if (victim != null)
victim.damageSprite(self.ownerActor, Blood.kDamageFall, 12);
}
}
}
class BloodThing422 : BloodThingBase
@ -388,6 +400,23 @@ class BloodThingDripWater : BloodThingBase
pic "DripWater";
pal 10;
}
override void onHit(CollisionData hit)
{
self.flags &= ~kPhysGravity;
self.pos.Z -= 4;
int nSurface = self.hit.florhit.getSurfaceType(); // this really checks the actor's hit, not the passed parameter!
if (nSurface == Blood.kSurfWater)
{
self.seqSpawnID(6);
self.play3DSoundID(356, -1, 0);
}
else
{
self.seqSpawnID(7);
self.play3DSoundID(354, -1, 0);
}
}
}
class BloodThingDripBlood : BloodThingBase
@ -400,6 +429,14 @@ class BloodThingDripBlood : BloodThingBase
pic "DripBlood";
pal 2;
}
override void onHit(CollisionData hit)
{
self.flags &= ~kPhysGravity;
self.pos.Z -= 4;
self.seqSpawnID(8);
self.play3DSoundID(354, -1, 0);
}
}
class BloodThingBloodBits : BloodThingBase
@ -509,6 +546,12 @@ class BloodThingPodFireBall : BloodThingBase
scale 0.500000, 0.500000;
dmgcontrol 256, 0, 256, 256, 0, 0, 0;
}
override void onHit(CollisionData hit)
{
self.ExplodeSprite();
}
}
class BloodThingPodGreenBall : BloodThingBase
@ -527,6 +570,22 @@ class BloodThingPodGreenBall : BloodThingBase
scale 0.500000, 0.500000;
dmgcontrol 256, 0, 256, 256, 0, 0, 0;
}
override void onHit(CollisionData hit)
{
if (hit.type == kHitSector)
{
self.ownerActor.radiusDamage(self.pos, self.sector, 200, 1, 20, Blood.kDamageExplode, 6, 0);
self.evPostActorCallback(0, fxPodBloodSplat);
}
else if (hit.type == kHitSprite)
{
let victim = BloodActor(hit.hitActor());
if (victim != null)
victim.damageSprite(self.ownerActor, Blood.kDamageFall, 12);
self.evPostActorCallback(0, fxPodBloodSplat);
}
}
}
class BloodThingDroppedLifeLeech : BloodThingBase

View file

@ -119,6 +119,21 @@ class BloodActor : CoreActor native
kStatPathMarker = 16,
kStatFree = 1024,
};
enum BloodFlags
{
// sprite attributes
kHitagAutoAim = 0x0008,
kHitagRespawn = 0x0010,
kHitagFree = 0x0020,
kHitagSmoke = 0x0100,
// sprite physics attributes
kPhysMove = 0x0001, // affected by movement physics
kPhysGravity = 0x0002, // affected by gravity
kPhysFalling = 0x0004, // currently in z-motion
};
states
{
@ -361,10 +376,16 @@ native void callbackMissileBurst();
native double, double getActorExtents();
native int HitScan(double z, vector3 xyz, int clipmask, double clipdist);
native void impactMissile(int hitcode);
native int damageSprite(BloodActor source, int damageType, int damage);
native void explodeSprite();
native void radiusDamage(Vector3 pos, sectortype pSector, int dist, int basedmg, int distdmg, int dmgtype, int flags, int burn);
native void play3DSoundID(int soundId, int a3 = -1, int a4 = 0);
native void seqSpawnID(int seqID, VMFunction seqCallbackID);
native void seqSpawnID(int seqID, VMFunction seqCallbackID = null);
virtual void onHit(CollisionData hit)
{
}
virtual int getRespawnTime()
{

View file

@ -81,6 +81,35 @@ struct Blood native
kWeapMax = 14,
};
enum DAMAGE_TYPE {
kDamageFall = 0,
kDamageBurn,
kDamageBullet,
kDamageExplode,
kDamageDrown,
kDamageSpirit,
kDamageTesla,
kDamageMax = 7,
};
enum SurfaceType {
kSurfNone = 0,
kSurfStone,
kSurfMetal,
kSurfWood,
kSurfFlesh,
kSurfWater,
kSurfDirt,
kSurfClay,
kSurfSnow,
kSurfIce,
kSurfLeaves,
kSurfCloth,
kSurfPlant,
kSurfGoo,
kSurfLava,
kSurfMax
};
native static void PlayIntroMusic();
native static bool OriginalLoadScreen(); // doing it generically would necessitate exporting the tile manage which we do not want.

View file

@ -177,7 +177,7 @@ struct CollisionData
{
int type;
int exbits;
voidptr hit; // do not access!
private voidptr hit; // do not access!
native walltype hitWall();
native sectortype hitSector();
native CoreActor hitActor();
@ -186,6 +186,7 @@ struct CollisionData
native void setActor(CoreActor a);
native void setVoid();
native void setNone();
native int getSurfaceType();
}
struct HitInfo