From 7d78e50750744bb11d48a742ec1e7ec6bd38994c Mon Sep 17 00:00:00 2001 From: XProger Date: Tue, 11 Dec 2018 08:50:19 +0300 Subject: [PATCH] exploded parts damage for mutants --- src/controller.h | 53 ++++++++++++++++++++++++++++-------------------- src/enemy.h | 13 +++++++----- src/trigger.h | 4 ++-- src/video.h | 2 +- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/controller.h b/src/controller.h index a3ee5dc..905d60e 100644 --- a/src/controller.h +++ b/src/controller.h @@ -141,7 +141,8 @@ struct Controller { struct ExplodePart { Basis basis; vec3 velocity; - int roomIndex; + float damage; + int16 roomIndex; } *explodeParts; vec3 lastPos; @@ -1188,7 +1189,17 @@ struct Controller { } else animation.framePrev = animation.frameIndex; } - + + bool checkNear(const vec3 &p, float dist) { + vec3 d = p - pos; + if (d.x < -dist || d.x > dist || d.z < -dist || d.z > dist || d.y < -3072.0f || d.y > 3072.0f || (SQR(d.x) + SQR(d.z) > SQR(dist))) + return false; + Box box = getBoundingBoxLocal(); + if (d.y < box.min.y || (d.y - 100.0f) > box.max.y) + return false; + return true; + } + void updateExplosion() { if (!explodeMask) return; const TR::Model *model = getModel(); @@ -1201,31 +1212,28 @@ struct Controller { part.basis = Basis(part.basis.rot * q, part.basis.pos + part.velocity * (30.0f * Core::deltaTime)); vec3 p = part.basis.pos; - //TR::Room::Sector *s = level->getSector(part.roomIndex, int(p.x), int(p.y), int(p.z)); - TR::Level::FloorInfo info; - getFloorInfo(part.roomIndex, p, info); - if (info.roomNext != TR::NO_ROOM) - part.roomIndex = info.roomNext; + TR::Room::Sector *sector = level->getSector(part.roomIndex, p); + float ceiling = level->getCeiling(sector, p); + float floor = level->getFloor(sector, p); bool explode = false; - if (p.y < info.roomCeiling) { - if (info.roomAbove != TR::NO_ROOM) - part.roomIndex = info.roomAbove; - else { - if (info.roomCeiling != 0xffff8100) - p.y = (float)info.roomCeiling; - explode = true; - } + if (p.y < ceiling) { + p.y = ceiling; + part.velocity.y = -part.velocity.y; } - if (p.y > info.roomFloor) { - if (info.roomBelow != TR::NO_ROOM) - part.roomIndex = info.roomBelow; - else { - if (info.roomFloor != 0xffff8100) - p.y = (float)info.roomFloor; + if (p.y >= floor) { + p.y = floor; + part.damage = 0.0f; + explode = true; + } + + if (part.damage > 0.0f) { + Controller *lara = game->getLara(); + if (lara->checkNear(p, part.damage * 2.0f)) { + lara->hit(part.damage); explode = true; } } @@ -1330,7 +1338,7 @@ struct Controller { return matrix; } - void explode(int32 mask) { + void explode(int32 mask, float damage) { const TR::Model *model = getModel(); if (!layers) initMeshOverrides(); @@ -1355,6 +1363,7 @@ struct Controller { part.basis = joints[i]; part.basis.w = 1.0f; part.velocity = vec3(cosf(angle) * speed.x, speed.y, sinf(angle) * speed.x); + part.damage = damage; part.roomIndex = roomIndex; } } diff --git a/src/enemy.h b/src/enemy.h index 9d14eac..f499c3b 100644 --- a/src/enemy.h +++ b/src/enemy.h @@ -1874,6 +1874,7 @@ struct Raptor : Enemy { #define MUTANT_DIST_ATTACK_3 300 #define MUTANT_DIST_SHOT 3840 #define MUTANT_DIST_STALK (4096 + 512) +#define MUTANT_PART_DAMAGE 100 struct Mutant : Enemy { @@ -1927,7 +1928,7 @@ struct Mutant : Enemy { if (health <= 0.0f && !exploded) { game->playSound(TR::SND_MUTANT_DEATH, pos, Sound::PAN); - explode(0xffffffff); + explode(0xffffffff, MUTANT_PART_DAMAGE); } Enemy::update(); @@ -2108,6 +2109,7 @@ struct Mutant : Enemy { #define GIANT_MUTANT_DAMAGE_FATAL 1000 #define GIANT_MUTANT_DIST_ATTACK 2600 #define GIANT_MUTANT_DIST_FATAL 2250 +#define GIANT_MUTANT_PART_DAMAGE 250 struct GiantMutant : Enemy { @@ -2158,7 +2160,7 @@ struct GiantMutant : Enemy { if (health <= 0.0f && !exploded && animation.index == ANIM_DEATH && flags.state == TR::Entity::asInactive) { flags.state = TR::Entity::asActive; game->playSound(TR::SND_MUTANT_DEATH, pos, Sound::PAN); - explode(0xffffffff); + explode(0xffffffff, GIANT_MUTANT_PART_DAMAGE); game->checkTrigger(this, true); } @@ -2262,8 +2264,9 @@ struct GiantMutant : Enemy { } }; -#define CENTAUR_TURN_FAST (DEG2RAD * 120) -#define CENTAUR_DIST_RUN (1024 + 512) +#define CENTAUR_TURN_FAST (DEG2RAD * 120) +#define CENTAUR_DIST_RUN (1024 + 512) +#define CENTAUR_PART_DAMAGE 100 struct Centaur : Enemy { @@ -2365,7 +2368,7 @@ struct Centaur : Enemy { virtual void deactivate(bool removeFromList = false) { if (!removeFromList) { if (!explodeMask) - explode(0xffffffff); + explode(0xffffffff, CENTAUR_PART_DAMAGE); return; } Enemy::deactivate(removeFromList); diff --git a/src/trigger.h b/src/trigger.h index 887b166..f35d06f 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -1333,7 +1333,7 @@ struct CentaurStatue : Controller { } if ((pos - game->getLara(pos)->pos).length() < CENTAUR_STATUE_RANGE) { - explode(0xFFFFFFFF); + explode(0xFFFFFFFF, 0.0f); game->playSound(TR::SND_EXPLOSION, pos, Sound::PAN); Controller *enemy = game->addEntity(TR::Entity::ENEMY_CENTAUR, getRoomIndex(), pos, angle.y); if (enemy) @@ -1423,7 +1423,7 @@ struct MutantEgg : Controller { if ( flags.once || getEntity().type == TR::Entity::MUTANT_EGG_BIG || box.contains(((game->getLara(pos))->pos)) ) { animation.setState(STATE_EXPLOSION); layers[0].mask = 0xffffffff & ~(1 << 24); - explode(0x00fffe00); + explode(0x00fffe00, 0.0f); game->addEntity(enemy, getRoomIndex(), pos, angle.y); } } diff --git a/src/video.h b/src/video.h index ba692d0..74bb5e2 100644 --- a/src/video.h +++ b/src/video.h @@ -1187,7 +1187,7 @@ struct Video { virtual int decode(Sound::Frame *frames, int count) { if (audioChunkIndex >= chunksCount) { - memset(frames, 0, count); + memset(frames, 0, count * sizeof(Sound::Frame)); return count; }