Henrique Gemignani Passos Lima a6ee5c2836 Add CPowerBomb
Former-commit-id: 70e69ea33bad0a9b90db6fcd0a5ade9463f82c77
2022-11-10 01:45:24 +02:00

116 lines
3.4 KiB
C++

#include "MetroidPrime/Weapons/CWeapon.hpp"
#include "MetroidPrime/CActorParameters.hpp"
#include "MetroidPrime/CFluidPlaneCPU.hpp"
#include "MetroidPrime/CFluidPlaneManager.hpp"
#include "MetroidPrime/ScriptObjects/CScriptWater.hpp"
#include <rstl/math.hpp>
CWeapon::CWeapon(TUniqueId uid, TAreaId areaId, bool active, TUniqueId owner, EWeaponType type,
const rstl::string& name, const CTransform4f& xf, const CMaterialFilter& filter,
const CMaterialList& mList, const CDamageInfo& dInfo, EProjectileAttrib attribs,
const CModelData& mData)
: CActor(uid, active, name, CEntityInfo(areaId, CEntity::NullConnectionList), xf, mData, mList,
CActorParameters::None().HotInThermal(true), kInvalidUniqueId)
, xe8_projectileAttribs(attribs)
, xec_ownerId(owner)
, xf0_weaponType(type)
, xf8_filter(filter)
, x110_origDamageInfo(dInfo)
, x12c_curDamageInfo(dInfo)
, x148_curTime(0.f)
, x14c_damageFalloffSpeed(0.f)
, x150_damageDuration(0.f)
, x154_interferenceDuration(0.f) {}
CWeapon::~CWeapon() {}
void CWeapon::SetDamageFalloffSpeed(float speed) {
if (speed > 0.f) {
x14c_damageFalloffSpeed = 1.f / speed;
}
}
void CWeapon::Think(float dt, CStateManager& mgr) {
x148_curTime += dt;
if ((xe8_projectileAttribs & kPA_DamageFalloff) == kPA_DamageFalloff) {
float max = 1.f - x148_curTime * x14c_damageFalloffSpeed;
float scale = CMath::Max(0.f, max);
float damage = scale * x110_origDamageInfo.GetDamage();
float radius = scale * x110_origDamageInfo.GetRadius();
float knockback = scale * x110_origDamageInfo.GetKnockBackPower();
x12c_curDamageInfo =
CDamageInfo(x110_origDamageInfo.GetWeaponMode(), damage, radius, knockback);
} else {
x12c_curDamageInfo = x110_origDamageInfo;
}
CEntity::Think(dt, mgr);
}
void CWeapon::FluidFXThink(EFluidState state, CScriptWater& water, CStateManager& mgr) {
bool doRipple = true;
float mag = 0.f;
switch (xf0_weaponType) {
case kWT_Power:
mag = 0.1f;
break;
case kWT_Ice:
mag = 0.3f;
break;
case kWT_Wave:
mag = 0.1f;
break;
case kWT_Plasma:
mag = 0.f;
break;
case kWT_Missile:
mag = 0.5f;
break;
case kWT_Phazon:
mag = 0.1f;
break;
default:
doRipple = false;
break;
}
if ((xe8_projectileAttribs & kPA_ComboShot) != 0 && state != kFS_InFluid) {
mag += 0.5f;
}
if ((xe8_projectileAttribs & kPA_Charged) != 0) {
mag += 0.25f;
}
if (mag > 1.f) {
mag = 1.f;
}
if (doRipple) {
CVector3f pos(GetTranslation().GetX(), GetTranslation().GetY(), water.GetSurfaceZ());
if ((xe8_projectileAttribs & kPA_ComboShot) != 0) {
if (!water.CanRippleAtPoint(pos)) {
doRipple = false;
}
} else if (state == kFS_InFluid) {
doRipple = false;
}
if (doRipple) {
bool sfx = state == kFS_EnteredFluid || state == kFS_LeftFluid;
water.FluidPlane().AddRipple(mag, GetUniqueId(), pos, water, mgr);
mgr.FluidPlaneManager()->CreateSplash(GetUniqueId(), mgr, water, pos, mag, sfx);
}
}
}
void CWeapon::Render(const CStateManager& mgr) const {}
EWeaponCollisionResponseTypes CWeapon::GetCollisionResponseType(const CVector3f& pos,
const CVector3f& dir,
const CWeaponMode& wMode,
int) const {
return kWCR_Projectile;
}