1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
#include "BirdCage.h"
#include "../../ILevelHandler.h"
#include "../../Events/EventMap.h"
#include "../Explosion.h"
#include "../Player.h"
#include "../Weapons/ShotBase.h"
#include "../Weapons/TNT.h"
namespace Jazz2::Actors::Environment
{
BirdCage::BirdCage()
:
_activated(false)
{
}
void BirdCage::Preload(const ActorActivationDetails& details)
{
uint8_t type = details.Params[0];
switch (type) {
case 0: // Chuck (red)
PreloadMetadataAsync("Object/BirdCageChuck"_s);
PreloadMetadataAsync("Object/BirdChuck"_s);
break;
case 1: // Birdy (yellow)
PreloadMetadataAsync("Object/BirdCageBirdy"_s);
PreloadMetadataAsync("Object/BirdBirdy"_s);
break;
}
}
Task<bool> BirdCage::OnActivatedAsync(const ActorActivationDetails& details)
{
_renderer.setLayer(_renderer.layer() - 16);
_type = details.Params[0];
_activated = (details.Params[1] != 0);
SetState(ActorState::CollideWithSolidObjects | ActorState::IsSolidObject, !_activated);
switch (_type) {
case 0: // Chuck (red)
async_await RequestMetadataAsync("Object/BirdCageChuck"_s);
break;
case 1: // Birdy (yellow)
async_await RequestMetadataAsync("Object/BirdCageBirdy"_s);
break;
}
SetAnimation(_activated ? AnimState::Activated : AnimState::Idle);
async_return true;
}
bool BirdCage::OnHandleCollision(std::shared_ptr<ActorBase> other)
{
if (!_activated) {
if (auto* shotBase = runtime_cast<Weapons::ShotBase>(other.get())) {
if (shotBase->GetStrength() > 0) {
auto owner = shotBase->GetOwner();
if (owner != nullptr && TryApplyToPlayer(owner)) {
shotBase->DecreaseHealth(1);
return true;
}
}
} else if (auto* tnt = runtime_cast<Weapons::TNT>(other.get())) {
auto owner = tnt->GetOwner();
if (owner != nullptr && TryApplyToPlayer(owner)) {
return true;
}
} else if (auto* player = runtime_cast<Player>(other.get())) {
if (player->CanBreakSolidObjects() && TryApplyToPlayer(player)) {
return true;
}
}
}
return ActorBase::OnHandleCollision(std::move(other));
}
bool BirdCage::CanCauseDamage(ActorBase* collider)
{
return _levelHandler->IsReforged() || runtime_cast<Weapons::TNT>(collider);
}
bool BirdCage::TryApplyToPlayer(Player* player)
{
if (!player->SpawnBird(_type, _pos)) {
return false;
}
_activated = true;
SetState(ActorState::CollideWithSolidObjects | ActorState::IsSolidObject, false);
SetAnimation(AnimState::Activated);
PlaySfx("Break"_s);
Explosion::Create(_levelHandler, Vector3i((std::int32_t)(_pos.X - 12.0f), (std::int32_t)(_pos.Y - 6.0f), _renderer.layer() + 90), Explosion::Type::SmokeBrown);
Explosion::Create(_levelHandler, Vector3i((std::int32_t)(_pos.X - 8.0f), (std::int32_t)(_pos.Y + 28.0f), _renderer.layer() + 90), Explosion::Type::SmokeBrown);
Explosion::Create(_levelHandler, Vector3i((std::int32_t)(_pos.X + 12.0f), (std::int32_t)(_pos.Y + 10.0f), _renderer.layer() + 90), Explosion::Type::SmokeBrown);
Explosion::Create(_levelHandler, Vector3i((std::int32_t)_pos.X, (std::int32_t)(_pos.Y + 12.0f), _renderer.layer() + 110), Explosion::Type::SmokePoof);
// Deactivate event in map
auto eventMap = _levelHandler->EventMap();
if (eventMap != nullptr) {
uint8_t eventParams[16] = { _type, 1 };
eventMap->StoreTileEvent(_originTile.X, _originTile.Y, EventType::BirdCage, ActorState::None, eventParams);
}
return true;
}
}
|