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
|
#include "AmmoBarrel.h"
#include "../../ILevelHandler.h"
#include "../../Tiles/TileMap.h"
#include "../Player.h"
#include "../Weapons/ShotBase.h"
#include "../Weapons/TNT.h"
#include "../../../nCine/Base/Random.h"
namespace Jazz2::Actors::Solid
{
AmmoBarrel::AmmoBarrel()
{
}
void AmmoBarrel::Preload(const ActorActivationDetails& details)
{
PreloadMetadataAsync("Object/BarrelContainer"_s);
}
Task<bool> AmmoBarrel::OnActivatedAsync(const ActorActivationDetails& details)
{
Movable = true;
WeaponType weaponType = (WeaponType)details.Params[0];
if (weaponType != WeaponType::Blaster) {
AddContent(EventType::Ammo, 5, &details.Params[0], 1);
}
async_await RequestMetadataAsync("Object/BarrelContainer"_s);
SetAnimation(AnimState::Idle);
async_return true;
}
bool AmmoBarrel::OnHandleCollision(std::shared_ptr<ActorBase> other)
{
if (_health == 0) {
return GenericContainer::OnHandleCollision(other);
}
if (auto* shotBase = runtime_cast<Weapons::ShotBase>(other.get())) {
WeaponType weaponType = shotBase->GetWeaponType();
if (_levelHandler->IsReforged() &&
(weaponType == WeaponType::RF || weaponType == WeaponType::Seeker ||
weaponType == WeaponType::Pepper || weaponType == WeaponType::Electro)) {
DecreaseHealth(shotBase->GetStrength(), shotBase);
shotBase->DecreaseHealth(INT32_MAX);
} else {
shotBase->TriggerRicochet(this);
}
return true;
} else if (auto* tnt = runtime_cast<Weapons::TNT>(other.get())) {
DecreaseHealth(INT32_MAX, tnt);
return true;
} else if (auto* player = runtime_cast<Player>(other.get())) {
if (player->CanBreakSolidObjects()) {
DecreaseHealth(INT32_MAX, player);
return true;
}
}
return GenericContainer::OnHandleCollision(std::move(other));
}
bool AmmoBarrel::OnPerish(ActorBase* collider)
{
if (_content.empty()) {
// Random Ammo create
SmallVector<WeaponType, (std::int32_t)WeaponType::Count> weaponTypes;
auto players = _levelHandler->GetPlayers();
for (auto* player : players) {
const auto playerAmmo = player->GetWeaponAmmo();
for (std::int32_t i = 1; i < (std::int32_t)WeaponType::Count; i++) {
if (playerAmmo[i] > 0) {
weaponTypes.push_back((WeaponType)i);
}
}
}
if (weaponTypes.empty()) {
weaponTypes.push_back(WeaponType::Bouncer);
}
std::int32_t n = Random().Next(4, 7);
for (std::int32_t i = 0; i < n; i++) {
std::uint8_t weaponType = (std::uint8_t)weaponTypes[Random().Next(0, (std::uint32_t)weaponTypes.size())];
AddContent(EventType::Ammo, 1, &weaponType, sizeof(weaponType));
}
}
PlaySfx("Break"_s);
CreateParticleDebrisOnPerish(ParticleDebrisEffect::Standard, Vector2f::Zero);
CreateSpriteDebris((AnimState)1, 3);
CreateSpriteDebris((AnimState)2, 3);
CreateSpriteDebris((AnimState)3, 2);
CreateSpriteDebris((AnimState)4, 1);
return GenericContainer::OnPerish(collider);
}
}
|