Files
tww/src/d/actor/d_a_bomb3.inc
T
2023-12-30 13:57:57 -08:00

1454 lines
37 KiB
C++

// daBomb_c::createHeap's asserts tell us that function is inside d_a_bomb3.inc instead of d_a_bomb.cpp.
// Furthermore, the symbol maps show that d_a_bomb.o's first .text section is 0 bytes large, with everything going in
// its second .text section, which suggests that d_a_bomb.cpp is empty except including d_a_bomb3.inc.
#include "d/actor/d_a_bomb.h"
#include "SSystem/SComponent/c_counter.h"
#include "d/d_com_inf_game.h"
#include "d/d_procname.h"
#include "d/actor/d_a_player_main.h"
#include "d/actor/d_a_sea.h"
#include "d/d_kankyo_wether.h"
#include "f_op/f_op_camera_mng.h"
#include "f_op/f_op_kankyo_mng.h"
#include "m_Do/m_Do_mtx.h"
#include "m_Do/m_Do_lib.h"
// Needed for the .data section to match.
static f32 dummy1[3] = {1.0f, 1.0f, 1.0f};
static f32 dummy2[3] = {1.0f, 1.0f, 1.0f};
namespace {
enum AttrSt_e {
ATTR_STATE_0 = 0x00,
ATTR_STATE_1 = 0x01,
ATTR_STATE_2 = 0x02,
ATTR_STATE_4 = 0x04,
ATTR_STATE_8 = 0x08,
ATTR_STATE_10 = 0x10,
ATTR_STATE_20 = 0x20,
ATTR_STATE_80 = 0x80,
ATTR_STATE_100 = 0x100,
ATTR_STATE_200 = 0x200,
ATTR_STATE_1C = ATTR_STATE_10 | ATTR_STATE_8 | ATTR_STATE_4,
ATTR_STATE_21 = ATTR_STATE_20 | ATTR_STATE_1,
ATTR_STATE_9C = ATTR_STATE_80 | ATTR_STATE_10 | ATTR_STATE_8 | ATTR_STATE_4,
ATTR_STATE_A1 = ATTR_STATE_80 | ATTR_STATE_20 | ATTR_STATE_1,
ATTR_STATE_20C = ATTR_STATE_200 | ATTR_STATE_8 | ATTR_STATE_4,
ATTR_STATE_300 = ATTR_STATE_200 | ATTR_STATE_100
};
//game has this with global visibility somehow
const AttrSt_e L_attrState[] = {
ATTR_STATE_A1,
ATTR_STATE_1C,
ATTR_STATE_9C,
ATTR_STATE_9C,
ATTR_STATE_20C,
ATTR_STATE_300,
ATTR_STATE_200,
ATTR_STATE_2,
ATTR_STATE_21,
ATTR_STATE_0
};
bool chk_attrState(const daBomb_c* i_this, AttrSt_e mask) {
return cLib_checkBit(L_attrState[i_this->prm_get_state()], mask); // register order is wrong in the and
}
}
const daBomb_c::Attr_c daBomb_c::m_attrType[] = {
{"Link", 0x8E0},
{"VbakH", 0x800},
{"Link", 0x8E0},
};
/* 800D9364-800D977C .text executeAfter__25daBomb_fuseSmokeEcallBackFP14JPABaseEmitter */
void daBomb_fuseSmokeEcallBack::executeAfter(JPABaseEmitter* emitter) {
JGeometry::TVec3<f32> vec1;
vec1.set(*field_0x0C);
JGeometry::TVec3<f32> vec2;
vec2.set(*mpPos);
emitter->mGlobalTranslation.set(vec2);
f32 temp = mpPos->abs(*field_0x0C);
s16 temp2 = (20.0f - temp) * 0.5f + 10.0f;
if(temp2 < 10) {
temp2 = 10;
}
emitter->mLifeTime = temp2;
JGeometry::TVec3<f32> vec3;
vec3.z = 0.5f * (vec2.x - vec1.x);
vec3.y = 0.5f * (vec2.y - vec1.y);
vec3.x = 0.5f * (vec2.z - vec1.z);
JGeometry::TVec3<f32> vec4;
vec4.x = 0.5f * (vec1.x - field_0x10->x);
vec4.y = 0.5f * (vec1.y - field_0x10->y);
vec4.z = 0.5f * (vec1.z - field_0x10->z);
f32 temp5 = mpPos->abs(*field_0x0C);
if(temp5 * 0.1f > 1.0f) {
f32 step = 1.0f / (temp5 * 0.1f);
s16 temp7 = step * (field_0x04 - temp2);
s16 temp8 = temp2 + temp7;
for(f32 i = step; i < 1.0f; i += step, temp8 += temp7) {
JGeometry::TVec3<f32> vec5;
vec5.cubic<f32>(vec1, vec2, vec3, vec4, i);
emitter->mLifeTime = temp8;
JPABaseParticle* particle = emitter->createParticle();
if(particle) {
particle->setOffsetPosition(vec5);
}
}
}
field_0x04 = temp2;
}
void daBomb_fuseSparksEcallBack::execute(JPABaseEmitter* emitter) {
f32 x = mpPos->x;
f32 y = mpPos->y;
f32 z = mpPos->z;
emitter->mGlobalTranslation.set(x, y, z);
JSUPtrLink* link = emitter->mActiveParticles.getFirstLink();
while(link != 0) {
JSUPtrLink* next = link->getNext();
JPABaseParticle* ptcl = (JPABaseParticle*)link->getObjectPtr();
ptcl->mGlobalPosition.set(x, y, z);
link = next;
}
}
void daBomb_c::draw_norm() {
J3DAnmTevRegKey* bombBrk = daPy_getPlayerLinkActorClass()->getBombBrk();
s16 end = bombBrk->getFrameMax();
f32 frame = end - mRestTime + 2;
if(frame < 0.0f) {
frame = 0.0f;
}
else if(frame >= end) {
frame = end - 0.001f;
}
bombBrk->setFrame(frame);
end = mBck0.getBckAnm()->getFrameMax();
frame = end - mRestTime;
if(frame < 0.0f) {
frame = 0.0f;
}
else if(frame >= end) {
frame = end - 0.001f;
}
mBck0.entry(mpModel->getModelData(), frame);
dComIfGd_setListP1();
mDoExt_modelUpdateDL(mpModel);
dComIfGd_setList();
}
/* 800D9950-800D9A48 .text draw_nut__8daBomb_cFv */
void daBomb_c::draw_nut() {
if(chk_state(STATE_5) || chk_state(STATE_6)) {
mBck0.entry(mpModel->getModelData());
mBrk0.entry(mpModel->getModelData());
}
else {
mBck1.entry(mpModel->getModelData());
mBrk1.entry(mpModel->getModelData());
}
dComIfGd_setListP1();
mDoExt_modelUpdateDL(mpModel);
dComIfGd_setList();
}
BOOL daBomb_c::draw() {
if(chk_attrState(this, ATTR_STATE_20)) {
return true;
}
if(chk_state(STATE_4) && field_0x77D == 1) {
return true;
}
if(mDoLib_clipper::clip(j3dSys.getViewMtx(), current.pos, 80.0f)) {
return true;
}
if(field_0x7C8 > 0) {
return true;
}
g_env_light.settingTevStruct(TEV_TYPE_ACTOR, &current.pos, &mTevStr);
g_env_light.setLightTevColorType(mpModel, &mTevStr);
if(mType == 1) {
draw_nut();
}
else {
draw_norm();
}
if(fopAcM_GetModel(this) == 0 && mAcch.GetGroundH() != -1.0e9f) {
cM3dGPla* pNormal = dComIfG_Bgsp()->GetTriPla(mAcch.m_gnd);
if(pNormal) {
dComIfGd_setSimpleShadow(&current.pos, mAcch.GetGroundH(), 25.0f, &pNormal->mNormal, 0, 1.0f, dDlst_shadowControl_c::getSimpleTex());
}
}
return true;
}
static BOOL daBomb_Draw(daBomb_c* i_this) {
return i_this->draw();
}
bool daBomb_c::checkExplodeCc_norm() {
bool explode = false;
if(mSph.ChkTgHit()) {
cCcD_Obj* obj = mSph.GetTgHitObj();
if(obj) {
if(obj->ChkAtType(AT_TYPE_BOMB)) {
explode = true;
}
else if(!obj->ChkAtType(AT_TYPE_LEAF_WIND)) {
explode = true;
}
}
mSph.ClrTgHit();
}
if(explode) {
explode = procExplode_init();
}
else {
explode = false;
}
return explode;
}
bool daBomb_c::checkExplodeCc_nut() {
bool explode = false;
bool hit = false;
if(mSph.ChkTgHit()) {
cCcD_Obj* obj = mSph.GetTgHitObj();
if(obj) {
if(obj->ChkAtType(AT_TYPE_BOMB)) {
explode = true;
}
else if(!obj->ChkAtType(AT_TYPE_LEAF_WIND)) {
hit = true;
}
}
mSph.ClrTgHit();
}
if(mSph.ChkCoHit()) {
if(field_0x780) {
hit = true;
}
mSph.ClrCoHit();
}
bool ret = false;
if(explode) {
ret = procExplode_init();
}
else if(hit) {
change_state(STATE_1);
setFuseEffect();
if(30 < mRestTime) {
mRestTime = 30;
mBck1.setFrame(105.0f);
mBrk1.setFrame(105.0f);
}
}
return ret;
}
bool daBomb_c::checkExplodeCc_cannon() {
bool explode = false;
if(mSph.ChkTgHit()) {
cCcD_Obj* obj = mSph.GetTgHitObj();
if(obj) {
if(!obj->ChkAtType(AT_TYPE_LEAF_WIND)) {
explode = true;
}
}
mSph.ClrTgHit();
}
if(mSph.ChkCoHit()) {
explode = true;
mSph.ClrCoHit();
}
if(explode) {
explode = procExplode_init();
}
else {
explode = false;
}
return explode;
}
bool daBomb_c::checkExplodeCc() {
if(0 < mRestTime) {
typedef bool(daBomb_c::*checkFunc)();
static checkFunc proc[] = {
&daBomb_c::checkExplodeCc_norm,
&daBomb_c::checkExplodeCc_nut,
&daBomb_c::checkExplodeCc_cannon
};
return (this->*proc[mType])();
}
return false;
}
bool daBomb_c::checkExplodeTimer() {
bool explode = false;
if(!chk_attrState(this, ATTR_STATE_200)) {
if(0 < mRestTime) {
if(--mRestTime == 0) {
explode = procExplode_init();
}
}
}
return explode;
}
bool daBomb_c::checkExplode() {
return checkExplodeCc() || checkExplodeTimer();
}
bool daBomb_c::checkExplodeBg_norm() {
bool sink = chk_water_sink();
bool land = chk_water_land();
bool burn = chk_lava_hit();
if(sink) {
field_0x781 = true;
}
if(land) {
eff_water_splash();
}
if(burn) {
return procExplode_init();
}
return false;
}
/* 800DA098-800DA1A4 .text checkExplodeBg_nut__8daBomb_cFv */
bool daBomb_c::checkExplodeBg_nut() {
bool sink = chk_water_in();
bool burn = chk_lava_hit();
bool hit = mAcch.ChkWallHit() || mAcch.ChkGroundHit() || mAcch.ChkRoofHit();
bool ret = false;
if(burn) {
ret = procExplode_init();
}
else {
if(sink) {
makeWaterEffect();
field_0x781 = true;
}
else if(hit && field_0x780) {
change_state(STATE_1);
setFuseEffect();
if(30 < mRestTime) {
mRestTime = 30;
mBck1.setFrame(105.0f);
mBrk1.setFrame(105.0f);
}
}
}
return ret;
}
/* 800DA1A4-800DA284 .text checkExplodeBg_cannon__8daBomb_cFv */
bool daBomb_c::checkExplodeBg_cannon() {
bool sink = chk_water_in();
bool burn = chk_lava_hit();
bool hit = mAcch.ChkWallHit() || mAcch.ChkGroundHit() || mAcch.ChkRoofHit();
bool dead = chk_dead_zone();
bool ret = false;
if(burn || hit) {
ret = procExplode_init();
}
else {
if(sink) {
makeWaterEffect();
field_0x781 = true;
}
else if(dead) {
field_0x781 = true;
}
}
return ret;
}
/* 800DA284-800DA320 .text checkExplodeBg__8daBomb_cFv */
bool daBomb_c::checkExplodeBg() {
typedef bool(daBomb_c::*checkFunc)();
static checkFunc proc[] = {
&daBomb_c::checkExplodeBg_norm,
&daBomb_c::checkExplodeBg_nut,
&daBomb_c::checkExplodeBg_cannon
};
return (this->*proc[mType])();
}
/* 800DA320-800DA3A0 .text water_tention__8daBomb_cFv */
void daBomb_c::water_tention() {
if(chk_water_in()) {
if(field_0x554.y != -1.0e9f && field_0x554.z != -1.0e9f) {
f32 temp = field_0x554.y - field_0x554.z;
current.pos.y += temp < 0.0f ? 0.8f * temp : 0.2f * temp;
}
}
}
/* 800DA3A0-800DA520 .text posMoveF__8daBomb_cFv */
void daBomb_c::posMoveF() {
cM3dGPla* tri;
bool temp = mNoGravityTime > 0;
f32 gravity;
if(temp) {
gravity = mGravity;
mGravity = 0.0f;
}
if(mType == 0 && chk_water_in()) {
speed.y *= 0.9f;
speedF *= 0.9f;
}
if(!chk_state(STATE_5) && !chk_state(STATE_6) && field_0x6F3 != 1) {
water_tention();
tri = dComIfG_Bgsp()->GetTriPla(mAcch.m_gnd);
f32 mag = mWindVec.getSquareMag();
if(mag > 0.01f) {
f32 temp2;
cXyz* norm;
if(tri) {
norm = &tri->mNormal;
mag = 0.06f;
temp2 = cM_scos(0xA4F);
}
else {
norm = 0;
mag = 0.0f;
temp2 = 0.0f;
}
daObj::posMoveF_grade(this, mStts.GetCCMoveP(), &mWindVec, 0.002f, 0.0005f, norm, mag, temp2, 0);
}
else {
fopAcM_posMoveF(this, mStts.GetCCMoveP());
}
}
if(temp) {
mGravity = gravity;
mNoGravityTime--;
}
}
void daBomb_c::bgCrrPos() {
mAcch.CrrPos(*dComIfG_Bgsp());
bgCrrPos_lava();
bgCrrPos_water();
setRoomInfo();
}
void daBomb_c::bgCrrPos_lava() {
cXyz temp(current.pos.x, next.pos.y + 1.0f, current.pos.z);
mGndChk.SetPos(&temp);
field_0x554.x = dComIfG_Bgsp()->GroundCross(&mGndChk);
}
/* 800DA5E0-800DA700 .text bgCrrPos_water__8daBomb_cFv */
void daBomb_c::bgCrrPos_water() {
f32 f31 = mAcch.m_wtr.GetHeight();
bool r31 = daSea_ChkArea(current.pos.x, current.pos.z);
f32 f1 = daSea_calcWave(current.pos.x, current.pos.z);
bool r4 = mAcch.ChkWaterIn();
bool r3 = r31 && current.pos.y < f1;
bool r5 = false;
field_0x554.z = field_0x554.y;
if (r4 && r3) {
if (f31 > f1) {
r3 = 0;
} else {
r4 = 0;
}
}
if (r4) {
field_0x554.y = f31;
r5 = true;
field_0x562 = 0;
} else if (r3) {
field_0x554.y = f1;
r5 = true;
field_0x562 = 1;
} else {
field_0x554.y = -1e9f;
field_0x562 = 0;
}
field_0x560 = r5 && !mbWaterIn;
mbWaterIn = r5;
}
bool daBomb_c::chk_water_land() {
return field_0x560;
}
bool daBomb_c::chk_water_in() {
return mbWaterIn;
}
bool daBomb_c::chk_water_sink() {
bool water = chk_water_in();
return water && field_0x554.y - current.pos.y > 30.0f;
}
bool daBomb_c::chk_lava_hit() {
if(field_0x554.x == -1.0e9f) {
return false;
}
return current.pos.y < field_0x554.x;
}
bool daBomb_c::chk_dead_zone() {
return mAcch.GetGroundH() == -1.0e9f && field_0x554.y == -1.0e9f && field_0x554.x == -1.0e9f;
}
/* 800DA7CC-800DA8C8 .text bound__8daBomb_cFf */
void daBomb_c::bound(f32 param_1) {
if(mAcch.ChkWallHit()) {
speedF *= 0.8f;
current.angle.y = (mCir.GetWallAngleY() * 2) - (current.angle.y + 0x8000);
}
if(mAcch.ChkGroundLanding()) {
daObj::make_land_effect(this, &mAcch.m_gnd, 0.6f);
param_1 *= -0.6f;
if(param_1 < 19.5f) {
field_0x780 = 0;
}
else {
speedF *= 0.9f;
if(param_1 > 13.0f) {
speed.y = 13.0f;
}
else {
speed.y = param_1;
}
}
}
else {
if(mAcch.ChkGroundHit()) {
cLib_addCalc(&speedF, 0.0f, 0.5f, 5.0f, 1.0f);
}
}
}
/* 800DA8C8-800DA9DC .text set_real_shadow_flag__8daBomb_cFv */
void daBomb_c::set_real_shadow_flag() {
bool r31 = chk_state(STATE_2);
bool r3 = chk_state(STATE_3);
bool r30 = false;
if (field_0x7C8 <= 1 && (r31 || r3)) {
if (model) {
r30 = true;
} else if (r3) {
r30 = true;
} else if (field_0x7C8 == 1) {
r30 = true;
} else {
daPy_py_c* player = (daPy_py_c*)dComIfGp_getPlayer(0);
if (player->getGrabActorID() == fopAcM_GetID(this) && player->getGrabUpStart()) {
r30 = true;
}
}
}
if (field_0x7C8 > 0) {
field_0x7C8--;
}
model = r30 ? mpModel : NULL;
}
void daBomb_c::setRoomInfo() {
s32 roomNo;
if(mAcch.GetGroundH() != -1.0e9f) {
roomNo = dComIfG_Bgsp()->GetRoomId(mAcch.m_gnd);
mTevStr.mEnvrIdxOverride = dComIfG_Bgsp()->GetPolyColor(mAcch.m_gnd);
}
else {
roomNo = dComIfGp_roomControl_getStayNo();
}
mTevStr.mRoomNo = roomNo;
mStts.SetRoomId(roomNo);
current.roomNo = roomNo;
}
void daBomb_c::makeFireEffect(cXyz& pos, csXyz& rotation) {
camera_class* cam = dComIfGp_getCamera(dComIfGp_getPlayerCameraID(0));
cXyz scale;
scale.setall(0.3f);
csXyz rot;
rot.x = -cam->mAngle.x;
rot.y = cam->mAngle.y + 0x8000;
rot.z = 0;
rotation.x = rotation.x + 0x4000;
rotation.z = rotation.z;
dComIfGp_particle_setBombSmoke(dPa_name::ID_COMMON_SMOKE_CIRCLE, &pos, &rotation, &scale);
dComIfGp_getVibration().StartShock(7, -0x21, cXyz(0.0f, 1.0f, 0.0f));
}
void daBomb_c::makeWaterEffect() {
if(field_0x77D == 0) {
fopAcM_seStart(this, JA_SE_OBJ_BOMB_WATER, 0);
fopKyM_createWpillar(&current.pos, 1.0f, 1.0f, 1);
mSph.OffTgSPrmBit(TG_SPRM_SET);
mSph.OffCoSPrmBit(CO_SPRM_SET);
mSph.OnAtSPrmBit(AT_SPRM_SET);
mSph.SetR(200.0f);
mSph.SetC(current.pos);
if(mMassCounter != g_Counter.mCounter0) {
dComIfG_Ccsp()->Set(&mSph);
//using inline breaks match
//dComIfG_Ccsp()->SetMass(&mSph, 3);
g_dComIfG_gameInfo.play.mCcS.SetMass(&mSph, 3);
mMassCounter = g_Counter.mCounter0;
field_0x782 = 1;
}
field_0x77D = 1;
}
}
void daBomb_c::setFuseEffect() {
if(field_0x77E == 0) {
field_0x77E = 1;
mFusePos.x = current.pos.x;
mFusePos.y = current.pos.y + 60.0f;
mFusePos.z = current.pos.z;
mFusePos2 = mFusePos;
mFusePos3 = mFusePos;
dComIfGp_particle_setP1(dPa_name::ID_COMMON_FUSE_SPARKS, &mFusePos, NULL, &mScale, 0xFF, &mSparks);
dComIfGp_particle_setToonP1(0x2012, &mFusePos, NULL, &mScale, 0xDC, &mSmoke);
mSmoke.field_0x0C = &mFusePos2;
mSmoke.field_0x10 = &mFusePos3;
mSmoke.field_0x04 = 0x14;
}
}
void daBomb_c::eff_explode_normal(const csXyz* rotation) {
dComIfGp_particle_setP1(dPa_name::ID_COMMON_LIGHT_FLASH, &current.pos, rotation, &mScale);
dComIfGp_particle_setBombSmoke(dPa_name::ID_COMMON_SMOKE_CLOUD, &current.pos, NULL, &mScale);
dComIfGp_particle_setBombSmoke(dPa_name::ID_COMMON_SMOKE_CIRCLE, &current.pos, NULL, &mScale);
dComIfGp_particle_setToonP1(dPa_name::ID_COMMON_SMOKE_DEBRIS, &current.pos, NULL, &mScale);
}
void daBomb_c::eff_explode_cheap(const csXyz* rotation) {
JPABaseEmitter* emitter = dComIfGp_particle_setP1(dPa_name::ID_COMMON_LIGHT_FLASH, &current.pos, rotation, &mScale);
if(emitter) {
emitter->mLifeTime = 0xC;
JGeometry::TVec3<f32> vec(0.5f, 0.67f, 1.0f);
emitter->setGlobalParticleScale(vec);
}
dComIfGp_particle_setBombSmoke(0x232A, &current.pos, NULL, &mScale);
emitter = dComIfGp_particle_setBombSmoke(dPa_name::ID_COMMON_SMOKE_CIRCLE, &current.pos, NULL, &mScale);
if(emitter) {
emitter->mLifeTime = 0x46;
}
emitter = dComIfGp_particle_setToonP1(dPa_name::ID_COMMON_SMOKE_DEBRIS, &current.pos, NULL, &mScale);
if(emitter) {
emitter->mLifeTime = 0x46;
emitter->mInitialVelAxis = 25.0f;
emitter->mInitialVelDir = 35.0f;
}
}
void daBomb_c::eff_explode() {
camera_class* cam = dComIfGp_getCamera(dComIfGp_getPlayerCameraID(0));
csXyz rot;
rot.x = -cam->mAngle.x;
rot.y = cam->mAngle.y + 0x8000;
rot.z = 0;
if(prm_get_cheapEff()) {
eff_explode_cheap(&rot);
}
else {
eff_explode_normal(&rot);
}
}
int daBomb_c::procExplode_init() {
camera_class* camera = dComIfGp_getCamera(dComIfGp_getPlayerCameraID(0));
camera->mCamera.ForceLockOff(fopAcM_GetID(this));
s32 temp;
if(chk_state(STATE_8)) {
f32 temp2;
temp = fopAcM_getWaterY(&current.pos, &temp2);
if(temp) {
cXyz temp3;
dBgS_ObjGndChk gndCheck;
temp3.set(current.pos.x, current.pos.y + 1.0f, current.pos.z);
gndCheck.SetPos(&temp3);
if(dComIfG_Bgsp()->GroundCross(&gndCheck) > temp2 || current.pos.y > temp2 + 50.0f) {
temp = 0;
}
}
}
else {
temp = 0;
}
if(temp == 0) {
eff_explode();
}
else {
fopKyM_createWpillar(&current.pos, 1.0f, 1.0f, 1);
}
if(mSmoke.mpEmitter) {
mSmoke.mpEmitter->mpEmitterCallBack = 0;
mSmoke.mpEmitter->becomeInvalidEmitter();
}
mSmoke.mpEmitter = 0;
if(mSparks.mpEmitter) {
mSparks.mpEmitter->mpEmitterCallBack = 0;
mSparks.mpEmitter->becomeInvalidEmitter();
}
mSparks.mpEmitter = 0;
mPntLight.mPos = current.pos;
mPntLight.mPos.y += 100.0f;
mPntLight.mColor.r = 200;
mPntLight.mColor.g = 200;
mPntLight.mColor.b = 160;
mPntLight.mPower = 600.0f;
mPntLight.mFluctuation = 100.0f;
dKy_efplight_set(&mPntLight);
mPntWind.mPos = current.pos;
mPntWind.mDir.x = 0.0f;
mPntWind.mDir.y = 1.0f;
mPntWind.mDir.z = 0.0f;
mPntWind.mRadius = 500.0f;
mPntWind.field_0x20 = 0.0f;
mPntWind.mStrength = 0.5f;
dKyw_pntwind_set(&mPntWind);
field_0x774 = 0;
field_0x778 = 0.0f;
mFunc = &daBomb_c::procExplode;
speedF = 0.0f;
speed = cXyz::Zero;
mGravity = 0.0f;
if(!chk_state(STATE_8)) {
change_state(STATE_0);
}
mAttentionInfo.mFlags &= ~fopAc_Attn_ACTION_CARRY_e;
if(field_0x6F0) {
if(daPy_getPlayerLinkActorClass()->mActivePlayerBombs != 0) {
daPy_getPlayerLinkActorClass()->mActivePlayerBombs -= 1;
}
field_0x6F0 = 0;
}
mSph.OffTgSPrmBit(TG_SPRM_SET);
mSph.OffCoSPrmBit(CO_SPRM_SET);
mSph.OnAtSPrmBit(AT_SPRM_SET);
mSph.SetR(200.0f);
mSph.SetC(current.pos);
if(mMassCounter != g_Counter.mCounter0) {
dComIfG_Ccsp()->Set(&mSph);
//using inline breaks match
//dComIfG_Ccsp()->SetMass(&mSph, 3);
g_dComIfG_gameInfo.play.mCcS.SetMass(&mSph, 3);
field_0x782 = 1;
mMassCounter = g_Counter.mCounter0;
}
if(temp) {
fopAcM_seStart(this, JA_SE_OBJ_BOMB_WATER, 0);
}
else {
fopAcM_seStart(this, JA_SE_OBJ_BOMB_EXPLODE, 0);
}
fopAcM_cancelCarryNow(this);
dKy_Sound_set(current.pos, 0xFF, fopAcM_GetID(this), 0xA);
mRestTime = 0;
field_0x6FE = 2;
dComIfGp_getVibration().StartShock(7, -0x21, cXyz(0.0f, 1.0f, 0.0f));
se_cannon_fly_stop();
return true;
}
/* 800DB630-800DB880 .text procExplode__8daBomb_cFv */
bool daBomb_c::procExplode() {
camera_class* camera = dComIfGp_getCamera(0);
f32 temp2 = 0.0f;
mPntLight.mPower = field_0x778 * 1500.0f;
mPntWind.mStrength = field_0x778;
f32 temp = current.pos.abs(camera->mLookat.mEye);
if(temp < 1500.0f) {
temp2 = 1.0f - (temp / 1500.0f);
}
dKy_actor_addcol_amb_set(200, 180, 100, field_0x778 * temp2);
dKy_bg_addcol_amb_set(180, 160, 60, field_0x778 * temp2);
dKy_bg_addcol_dif_set(255, 225, 120, field_0x778 * temp2);
switch(field_0x774) {
case 0:
cLib_addCalc(&field_0x778, 1.0f, 0.5f, 0.4f, 0.01f);
if(field_0x778 >= 0.99f) {
field_0x774 += 1;
}
break;
case 1:
cLib_addCalc(&field_0x778, 0.0f, 0.05f, 0.04f, 0.001f);
if(field_0x778 <= 0.01f) {
field_0x774 += 1;
}
break;
}
if(field_0x6FE) {
field_0x6FE -= 1;
mSph.SetC(current.pos);
if(mMassCounter != g_Counter.mCounter0) {
dComIfG_Ccsp()->Set(&mSph);
//using inline breaks match
//dComIfG_Ccsp()->SetMass(&mSph, 3);
g_dComIfG_gameInfo.play.mCcS.SetMass(&mSph, 3);
mMassCounter = g_Counter.mCounter0;
field_0x782 = 1;
}
}
else {
if(1 < field_0x774) {
field_0x781 = 1;
}
}
return true;
}
bool daBomb_c::procCarry_init() {
if(chk_attrState(this, ATTR_STATE_100)) {
setFuseEffect();
}
mFunc = &daBomb_c::procCarry;
change_state(STATE_2);
speedF = 0.0f;
speed.set(cXyz::Zero);
mAttentionInfo.mFlags &= ~fopAc_Attn_ACTION_CARRY_e;
mSph.OffCoSPrmBit(CO_SPRM_SET);
return true;
}
bool daBomb_c::procCarry() {
if(!fopAcM_checkCarryNow(this)) {
if(speedF > 0.0f) {
field_0x780 = 1;
}
procWait_init();
return procWait();
}
else {
if(checkExplode()) {
return true;
}
else {
cXyz curPos(current.pos);
bgCrrPos();
current.pos.set(curPos);
return true;
}
}
}
bool daBomb_c::procWait_init() {
mFunc = &daBomb_c::procWait;
if(chk_attrState(this, ATTR_STATE_80)) {
change_state(STATE_1);
}
mSph.OnCoSPrmBit(CO_SPRM_SET);
return true;
}
bool daBomb_c::procWait() {
if(checkExplode()) {
return true;
}
else {
if(fopAcM_checkCarryNow(this)) {
return procCarry_init();
}
else {
posMoveF();
f32 y_vel = speed.y;
bgCrrPos();
bool temp = false;
if(checkExplodeBg()) {
temp = true;
}
else {
if(chk_state(STATE_4)) {
if(waitState_cannon()) {
temp = true;
}
}
else {
if(chk_state(STATE_7)) {
waitState_bomtyu();
}
}
}
if(!temp && !field_0x781) {
bound(y_vel);
if((mAcch.ChkGroundHit() || chk_state(STATE_5)) && !mAcch.ChkGroundLanding()) {
mAttentionInfo.mFlags |= fopAc_Attn_ACTION_CARRY_e;
}
else {
mAttentionInfo.mFlags &= ~fopAc_Attn_ACTION_CARRY_e;
}
}
return true;
}
}
}
bool daBomb_c::waitState_cannon() {
se_cannon_fly_set();
return false;
}
void daBomb_c::waitState_bomtyu() {
cLib_chaseF(&mScale.x, 1.0f, 0.05f);
cLib_chaseF(&mScale.y, 1.0f, 0.05f);
cLib_chaseF(&mScale.z, 1.0f, 0.05f);
if(field_0x6F2) {
setFuseEffect();
field_0x6F2 = 0;
field_0x6F4 = 1;
change_state(STATE_1);
}
}
bool daBomb_c::procSink() {
field_0x781 = 1;
return true;
}
/* 800DBC5C-800DBF24 .text execute__8daBomb_cFv */
BOOL daBomb_c::execute() {
static cXyz fuse_offset(0.0f, 60.0f, 5.0f);
if(chk_state(STATE_4) && !field_0x77C) {
field_0x77C = 1;
cXyz pos(current.pos);
pos.y += 20.0f;
makeFireEffect(pos, shape_angle);
}
set_wind_vec();
if(mFunc) {
(this->*mFunc)();
}
if(field_0x781) {
fopAcM_delete(this);
}
else {
set_real_shadow_flag();
if(mType == 1) {
anm_play_nut();
}
mStts.Move();
mAttentionInfo.mPosition.x = current.pos.x;
mAttentionInfo.mPosition.y = current.pos.y + 50.0f;
mAttentionInfo.mPosition.z = current.pos.z;
mEyePos = mAttentionInfo.mPosition;
if(!chk_attrState(this, ATTR_STATE_20)) {
set_mtx();
mFusePos3 = mFusePos2;
mFusePos2 = mFusePos;
mDoMtx_stack_c::multVec(&fuse_offset, &mFusePos);
cXyz pos;
pos.x = current.pos.x;
pos.y = current.pos.y + 30.0f;
pos.z = current.pos.z;
mSph.SetC(pos);
mSph.SetR(mScale.x * 30.0f);
if(mMassCounter != g_Counter.mCounter0) {
dComIfG_Ccsp()->Set(&mSph);
//using inline breaks match
//dComIfG_Ccsp()->SetMass(&mSph, 3);
g_dComIfG_gameInfo.play.mCcS.SetMass(&mSph, 3);
mMassCounter = g_Counter.mCounter0;
}
}
if(chk_attrState(this, ATTR_STATE_10) || field_0x6F4 == 1) {
fopAcM_seStart(this, JA_SE_OBJ_BOMB_IGNITION, 0);
}
}
if(field_0x782) {
field_0x784++;
}
return true;
}
static BOOL daBomb_Execute(daBomb_c* i_this) {
return i_this->execute();
}
/* 800DBF44-800DC250 .text set_wind_vec__8daBomb_cFv */
void daBomb_c::set_wind_vec() {
mWindVec *= 0.95f;
if (mWindVec.abs2() < 0.1f)
mWindVec.setall(0.0f);
if (!mSph.ChkTgHit())
return;
cCcD_Obj* hitObj = mSph.GetTgHitObj();
if (hitObj == NULL)
return;
if (!(hitObj->GetAtType() & AT_TYPE_LEAF_WIND))
return;
cXyz sp48 = *mSph.GetTgRVecP();
f32 f31 = sp48.abs2();
if (f31 > 180.0f*180.0f) {
sp48 *= 180.0f / sqrtf(f31);;
}
cCcD_ShapeAttr* hitShapeAttr = hitObj->GetShapeAttr();
cXyz hitNormal = cXyz::Zero;
f32 f30 = 1.0f;
f32 f29 = 1.0f;
if (hitShapeAttr->GetNVec(current.pos, &hitNormal)) {
hitNormal *= 50.0f;
mWindVec.abs2();
fopAc_ac_c* hitActor = mSph.GetTgHitAc();
if (hitActor && fpcM_GetProfName(hitActor) == PROC_PLAYER) {
s16 hitObjAngleY = cM_atan2s(hitNormal.x, hitNormal.z);
f32 f2 = cM_scos(hitActor->shape_angle.y - hitObjAngleY);
if (f2 > 0.0f) {
f30 = 1.0f + 2.0f*f2;
f29 = 1.0f + 0.3f*f2;
}
}
}
f32 f28;
if (f31 > 0.01f) {
f31 = 0.9f;
f28 = 0.1f;
} else {
f31 = 0.0f;
f28 = 1.0f;
}
mWindVec = sp48 * f31 + hitNormal * f28 * f30;
if (fabsf(mWindVec.y) < 5.0f) {
mWindVec.y += f29*(100.0f*f28) + 140.0f*f31;
}
}
/* 800DC250-800DC2D0 .text anm_play_nut__8daBomb_cFv */
void daBomb_c::anm_play_nut() {
if(chk_state(STATE_5) || chk_state(STATE_6)) {
mBck0.play();
mBrk0.play();
}
else {
if(mRestTime + 2 <= 0x87) {
mBck1.play();
mBrk1.play();
}
}
}
void daBomb_c::set_mtx() {
mpModel->setBaseScale(mScale);
mDoMtx_stack_c::transS(current.pos);
if(prm_get_angXZero()) {
mDoMtx_stack_c::ZXYrotM(0, shape_angle.y, shape_angle.z);
}
else {
mDoMtx_stack_c::ZXYrotM(shape_angle.x, shape_angle.y, shape_angle.z);
}
mpModel->setBaseTRMtx(mDoMtx_stack_c::get());
}
void daBomb_c::init_mtx() {
set_mtx();
}
void daBomb_c::se_cannon_fly_set() {
mDoAud_seStart(JA_SE_LK_SHIP_CANNON_FLY, &current.pos);
field_0x77F = 1;
}
void daBomb_c::se_cannon_fly_stop() {
if(field_0x77F) {
mDoAud_seStopActor(&current.pos, -1);
field_0x77F = 0;
}
}
void daBomb_c::eff_water_splash() {
cXyz pos(current.pos.x, field_0x554.y, current.pos.z);
fopKyM_createWpillar(&pos, 0.5f, 0.75f, 0);
cBgS_PolyInfo* temp[2] = {
field_0x562 ? NULL : &mAcch.m_wtr,
&mAcch.m_gnd,
};
u32 mtrlSndId = 0x13;
for (int i = 0; i < ARRAY_SIZE(temp); i++) {
if (temp[i] == NULL)
continue;
int bg_index = temp[i]->GetBgIndex();
if (bg_index >= 0 && bg_index < 0x100) {
mtrlSndId = dComIfG_Bgsp()->GetMtrlSndId(*temp[i]);
break;
}
}
fopAcM_seStart(this, JA_SE_OBJ_FALL_WATER_S, mtrlSndId);
}
static bool daBomb_IsDelete(daBomb_c*) {
return true;
}
bool daBomb_c::bombDelete() {
if(mSmoke.mpEmitter) {
mSmoke.mpEmitter->mpEmitterCallBack = 0;
mSmoke.mpEmitter->becomeInvalidEmitter();
}
mSmoke.mpEmitter = 0;
if(mSparks.mpEmitter) {
mSparks.mpEmitter->mpEmitterCallBack = 0;
mSparks.mpEmitter->becomeInvalidEmitter();
}
mSparks.mpEmitter = 0;
if(field_0x6F0) {
if(daPy_getPlayerLinkActorClass()->mActivePlayerBombs != 0) {
daPy_getPlayerLinkActorClass()->mActivePlayerBombs -= 1;
}
}
se_cannon_fly_stop();
if(mType == 1) {
dComIfG_resDelete(&mPhs, m_attrType[mType].resName);
}
dKy_actor_addcol_set(0, 0, 0, 0.0f);
dKy_efplight_cut(&mPntLight);
dKyw_pntwind_cut(&mPntWind);
return true;
}
static BOOL daBomb_Delete(daBomb_c* i_this) {
i_this->bombDelete();
return true;
}
BOOL daBomb_c::createHeap() {
BOOL ret;
if(mType == 1) {
J3DModelData* modelData = static_cast<J3DModelData*>(dComIfG_getObjectRes(m_attrType[mType].resName, VBAKH_BDL_VBAKM));
JUT_ASSERT(0x9A5, modelData != 0);
mpModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000022);
J3DAnmTransform* bck0_data = static_cast<J3DAnmTransform*>(dComIfG_getObjectRes(m_attrType[mType].resName, VBAKH_BCK_VBAMX));
JUT_ASSERT(0x9AE, bck0_data != 0);
int temp = mBck0.init(modelData, bck0_data, true, 0, 1.0f, 0, -1, false);
J3DAnmTransform* bck1_data = static_cast<J3DAnmTransform*>(dComIfG_getObjectRes(m_attrType[mType].resName, VBAKH_BCK_VBAKM));
JUT_ASSERT(0x9B4, bck1_data != 0);
int temp2 = mBck1.init(modelData, bck1_data, true, 0, 1.0f, 0, -1, false);
J3DAnmTevRegKey* brk0_data = static_cast<J3DAnmTevRegKey*>(dComIfG_getObjectRes(m_attrType[mType].resName, VBAKH_BRK_VBAMX));
JUT_ASSERT(0x9BB, brk0_data != 0);
int temp3 = mBrk0.init(modelData, brk0_data, true, 0, 1.0f, 0, -1, false, 0);
J3DAnmTevRegKey* brk1_data = static_cast<J3DAnmTevRegKey*>(dComIfG_getObjectRes(m_attrType[mType].resName, VBAKH_BRK_VBAKM));
JUT_ASSERT(0x9C1, brk1_data != 0);
int temp4 = mBrk1.init(modelData, brk1_data, true, 0, 1.0f, 0, -1, false, 0);
return mpModel && temp && temp2 && temp3 && temp4;
}
else {
J3DModelData* modelData = static_cast<J3DModelData*>(dComIfG_getObjectRes(m_attrType[mType].resName, LINK_BDL_BOMB));
JUT_ASSERT(0x9CE, modelData != 0);
mpModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000002);
if(!mpModel) {
return false;
}
else {
J3DAnmTransform* bck0_data = (J3DAnmTransform*)dComIfG_getObjectRes(m_attrType[mType].resName, LINK_BCK_BOMB);
int temp = mBck0.init(modelData, bck0_data, false, 2, 1.0f, 0, -1, false);
return temp ? TRUE : FALSE;
}
}
}
static BOOL daBomb_createHeap(fopAc_ac_c* i_this) {
return static_cast<daBomb_c*>(i_this)->createHeap();
}
int daBomb_c::create() {
int state = prm_get_state();
if(state == 5 || state == 6) {
mType = 1;
}
else if(state == 4) {
mType = 2;
}
else {
mType = 0;
}
fopAcM_SetupActor(this, daBomb_c);
int status;
if(mType == 1) {
status = dComIfG_resLoad(&mPhs, m_attrType[mType].resName);
}
else {
status = cPhs_COMPLEATE_e;
}
if(status == cPhs_COMPLEATE_e) {
if(fopAcM_entrySolidHeap(this, daBomb_createHeap, attrType().heapSize)) {
create_init();
}
else {
status = cPhs_ERROR_e;
}
}
return status;
}
/* 800DCC0C-800DCEBC .text __ct__8daBomb_cFv */
daBomb_c::daBomb_c() {}
static int daBomb_Create(fopAc_ac_c* i_this) {
return static_cast<daBomb_c*>(i_this)->create();
}
// TODO: not sure why this appears in data
daBomb_c::procFunc dummy_5390 = &daBomb_c::procSink;
static dCcD_SrcSph l_sph_src = {
// dCcD_SrcGObjInf
{
/* Flags */ 0,
/* SrcObjAt Type */ AT_TYPE_BOMB,
/* SrcObjAt Atp */ 0x04,
/* SrcObjAt SPrm */ AT_SPRM_GRP,
/* SrcObjTg Type */ ~(AT_TYPE_WATER | AT_TYPE_UNK20000 | AT_TYPE_UNK400000 | AT_TYPE_LIGHT),
/* SrcObjTg SPrm */ TG_SPRM_SET | TG_SPRM_IS_OTHER,
/* SrcObjCo SPrm */ CO_SPRM_SET | CO_SPRM_IS_UNK8 | CO_SPRM_VSGRP,
/* SrcGObjAt Se */ 0,
/* SrcGObjAt HitMark */ 0,
/* SrcGObjAt Spl */ 1,
/* SrcGObjAt Mtrl */ 0,
/* SrcGObjAt SPrm */ 0,
/* SrcGObjTg Se */ 0,
/* SrcGObjTg HitMark */ 0,
/* SrcGObjTg Spl */ 0,
/* SrcGObjTg Mtrl */ 0,
/* SrcGObjTg SPrm */ G_TG_SPRM_NO_CON_HIT,
/* SrcGObjCo SPrm */ 0,
},
// cM3dGSphS
{
/* Center */ 0.0f, 0.0f, 0.0f,
/* Radius */ 30.0f,
},
};
void daBomb_c::create_init() {
mCir.SetWall(30.0f, 30.0f);
mAcch.Set(&current.pos, &next.pos, this, 1, &mCir, &speed, &current.angle, &shape_angle);
mAcch.ClrWaterNone();
mAcch.ClrRoofNone();
mAcch.m_roof_crr_height = 50.0f;
mAcch.OnLineCheck();
field_0x554.setall(-1.0e9f);
field_0x560 = 0;
mbWaterIn = 0;
field_0x562 = 0;
fopAcM_SetMtx(this, mpModel->getBaseTRMtx());
mStts.Init(200, 0xFF, this);
mSph.Set(l_sph_src);
mSph.SetStts(&mStts);
if(chk_state(STATE_8)) {
mSph.GetObjAt().SetAtp(2);
}
mGravity = -2.9f;
mMaxFallSpeed = -100.0f;
mRestTime = 0x96;
mInitialState = prm_get_state();
if(!chk_state(STATE_4)) {
mAttentionInfo.mFlags |= fopAc_Attn_ACTION_CARRY_e;
}
field_0x77C = 0;
field_0x77D = 0;
field_0x77E = 0;
field_0x6F4 = 0;
field_0x77F = 0;
field_0x780 = 0;
field_0x781 = 0;
field_0x782 = 0;
field_0x784 = 0;
mWindVec.set(cXyz::Zero);
mMassCounter = g_Counter.mCounter0 - 1;
if(chk_attrState(this, ATTR_STATE_2)) {
mScale.setall(0.0f);
}
if(chk_attrState(this, ATTR_STATE_4)) {
setFuseEffect();
}
if(chk_attrState(this, ATTR_STATE_8)) {
bgCrrPos();
}
if(chk_state(STATE_3)) {
field_0x6F0 = 1;
field_0x7C8 = 2;
}
else {
field_0x7C8 = 0;
}
if(chk_attrState(this, ATTR_STATE_1)) {
procExplode_init();
}
else {
procWait_init();
}
mCull.mBox.mMin.x = -36.0f;
mCull.mBox.mMin.y = 0.0f;
mCull.mBox.mMin.z = -36.0f;
mCull.mBox.mMax.x = 36.0f;
mCull.mBox.mMax.y = 66.0f;
mCull.mBox.mMax.z = 36.0f;
fopAcM_setCullSizeFar(this, 10.0f);
init_mtx();
}
actor_method_class l_daBomb_Method = {
(process_method_func)daBomb_Create,
(process_method_func)daBomb_Delete,
(process_method_func)daBomb_Execute,
(process_method_func)daBomb_IsDelete,
(process_method_func)daBomb_Draw,
};
actor_process_profile_definition g_profile_BOMB = {
fpcLy_CURRENT_e,
7,
fpcPi_CURRENT_e,
PROC_BOMB,
&g_fpcLf_Method.mBase,
sizeof(daBomb_c),
0,
0,
&g_fopAc_Method.base,
0x0115,
&l_daBomb_Method,
fopAcStts_CULL_e | fopAcStts_UNK40000_e,
fopAc_ACTOR_e,
fopAc_CULLBOX_CUSTOM_e,
};