mirror of https://github.com/zeldaret/tp.git
337 lines
9.8 KiB
C
337 lines
9.8 KiB
C
#ifndef D_A_FORMATION_MNG_H
|
|
#define D_A_FORMATION_MNG_H
|
|
|
|
#include "d/d_com_inf_game.h"
|
|
#include "d/d_path.h"
|
|
#include "d/actor/d_a_player.h"
|
|
#include "d/d_kankyo.h"
|
|
#include "SSystem/SComponent/c_math.h"
|
|
|
|
struct daFmtMng_Path_c {
|
|
bool checkPathEnd(cXyz, f32);
|
|
bool checkPoint(cXyz, f32);
|
|
|
|
bool isPathClose() { return dPath_ChkClose(mPath); }
|
|
s8 getArg0() { return mPath->m_points[field_0x4].mArg0; }
|
|
s8 getArg1() { return mPath->m_points[field_0x4].mArg1; }
|
|
|
|
void chgDir() {
|
|
int dir;
|
|
if (field_0xc > 0) {
|
|
dir = -1;
|
|
} else {
|
|
dir = 1;
|
|
}
|
|
field_0xc = dir;
|
|
}
|
|
|
|
void setPath(int param_1, int param_2, cXyz* param_3) {
|
|
mPath = dPath_GetRoomPath(param_1, param_2);
|
|
field_0x4 = 0;
|
|
field_0xc = 1;
|
|
field_0x8 = param_3->abs(dPath_GetPnt(mPath, field_0x4)->m_position);
|
|
}
|
|
|
|
void getStartPoint(Vec* param_1, SVec* param_2) {
|
|
*param_1 = dPath_GetPnt(mPath, 0)->m_position;
|
|
Vec local_2c = dPath_GetPnt(mPath, 1)->m_position;
|
|
cXyz cStack_38(param_1->x, param_1->y + 200.0f, param_1->z);
|
|
if (fopAcM_gc_c::gndCheck(&cStack_38)) {
|
|
param_1->y = fopAcM_gc_c::getGroundY();
|
|
}
|
|
param_2->x = 0;
|
|
param_2->y = cLib_targetAngleY(param_1, &local_2c);
|
|
param_2->z = 0;
|
|
}
|
|
|
|
void getTargetPoint(Vec* param_1) {
|
|
*param_1 = dPath_GetPnt(mPath, field_0x4)->m_position;
|
|
}
|
|
|
|
int decIndex(int param_1) {
|
|
param_1--;
|
|
if (param_1 < 0) {
|
|
if (isPathClose()) {
|
|
param_1 = mPath->m_num - 1;
|
|
} else {
|
|
param_1 = 0;
|
|
}
|
|
}
|
|
return param_1;
|
|
}
|
|
|
|
int incIndex(int param_1) {
|
|
param_1++;
|
|
if (param_1 >= mPath->m_num) {
|
|
if (isPathClose()) {
|
|
param_1 = 0;
|
|
} else {
|
|
param_1--;
|
|
}
|
|
}
|
|
return param_1;
|
|
}
|
|
|
|
void setNextPoint() {
|
|
if (field_0xc > 0) {
|
|
field_0x4 = incIndex(field_0x4);
|
|
} else {
|
|
field_0x4 = decIndex(field_0x4);
|
|
}
|
|
field_0x8 = G_CM3D_F_INF;
|
|
}
|
|
|
|
void setNextPoint(cXyz *param_1) {
|
|
setNextPoint();
|
|
field_0x8 = param_1->abs(dPath_GetPnt(mPath, field_0x4)->m_position);
|
|
}
|
|
|
|
/* 0x0 */ dPath* mPath;
|
|
/* 0x4 */ int field_0x4;
|
|
/* 0x8 */ f32 field_0x8;
|
|
/* 0xC */ s8 field_0xc;
|
|
};
|
|
|
|
struct FmtPos_c : public daFmtMng_Path_c {
|
|
/* 0x10 */ cXyz field_0x10;
|
|
/* 0x1C */ s16 field_0x1c;
|
|
/* 0x1E */ s16 field_0x1e;
|
|
};
|
|
|
|
struct FmtMember_c {
|
|
/* 0x00 */ u32 mNpcId;
|
|
/* 0x04 */ cXyz field_0x04;
|
|
/* 0x10 */ cXyz field_0x10;
|
|
/* 0x1C */ s16 field_0x1c;
|
|
/* 0x1E */ u16 field_0x1e;
|
|
};
|
|
|
|
enum FmtMngAction {
|
|
MODE_0_e,
|
|
MODE_1_e,
|
|
MODE_2_e,
|
|
MODE_3_e,
|
|
MODE_4_e,
|
|
MODE_MAX_e,
|
|
};
|
|
|
|
struct FmtMngAttributes {
|
|
/* 0x00 */ int field_0x00;
|
|
/* 0x04 */ f32 field_0x04;
|
|
/* 0x08 */ f32 field_0x08;
|
|
/* 0x0C */ f32 field_0x0c;
|
|
/* 0x10 */ f32 field_0x10;
|
|
/* 0x14 */ s16 field_0x14;
|
|
/* 0x16 */ s16 field_0x16;
|
|
};
|
|
|
|
struct daFmtMng_c : public fopAc_ac_c {
|
|
void initWait();
|
|
void initMemberPos();
|
|
void executeWait();
|
|
void initWalk();
|
|
void executeWalk();
|
|
void setMovePath(FmtPos_c*, int);
|
|
void initReverse();
|
|
void executeReverse();
|
|
void initMotion();
|
|
void executeMotion();
|
|
void initFight();
|
|
void executeFight();
|
|
int create();
|
|
void create_init();
|
|
|
|
~daFmtMng_c() {
|
|
FmtMember_c* member = mMember;
|
|
for (int i = 0; i < mFormationLine * mFormationRow; i++, member++) {
|
|
fopAcM_delete(member->mNpcId);
|
|
}
|
|
delete [] mPos;
|
|
delete [] mMember;
|
|
}
|
|
|
|
int getTimeHour() {
|
|
if (dKy_darkworld_check()) {
|
|
return dKy_getDarktime_hour();
|
|
}
|
|
return dKy_getdaytime_hour();
|
|
}
|
|
|
|
int getTimeMinute() {
|
|
if (dKy_darkworld_check()) {
|
|
return dKy_getDarktime_minute();
|
|
}
|
|
return dKy_getdaytime_minute();
|
|
}
|
|
|
|
int getTime() {
|
|
return getTimeHour() * 60 + getTimeMinute();
|
|
}
|
|
|
|
u8 getPathID() { return shape_angle.x; }
|
|
u8 getFormationLine() { return fopAcM_GetParam(this) & 0xff; }
|
|
u8 getFormationRow() { return (fopAcM_GetParam(this) >> 8) & 0xff; }
|
|
int getStartTime() { return (fopAcM_GetParam(this) >> 16) & 0xff; }
|
|
int getEndTime() { return (fopAcM_GetParam(this) >> 24) & 0xff; }
|
|
|
|
void callExecute() {
|
|
JUT_ASSERT(680, mAction != NULL);
|
|
(this->*(mAction[1]))();
|
|
}
|
|
|
|
bool checkEmergency() {
|
|
if (dKy_darkworld_check() || !daPy_py_c::checkNowWolf()) {
|
|
return false;
|
|
}
|
|
FmtMember_c* member = mMember;
|
|
fopAc_ac_c* npcFgd = NULL;
|
|
for (int i = 0; i < mFormationRow * mFormationLine; i++, member++) {
|
|
fopAcM_SearchByID(member->mNpcId, &npcFgd);
|
|
if (npcFgd != NULL) {
|
|
cXyz* iVar6 = fopAcM_GetPosition_p(daPy_getPlayerActorClass());
|
|
f32 dVar10 = iVar6->y;
|
|
cXyz* this_01 = fopAcM_GetPosition_p(npcFgd);
|
|
if (this_01->y - dVar10 < 200.0f) {
|
|
f32 maxDist = pow(500.0, 2.0);
|
|
if (fopAcM_searchPlayerDistanceXZ2(npcFgd) < maxDist) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void callInit() {
|
|
JUT_ASSERT(667, mAction != NULL)
|
|
(this->*(*mAction))();
|
|
}
|
|
|
|
void setAction(int i_action) {
|
|
JUT_ASSERT(633, i_action < MODE_MAX_e);
|
|
mPrevAction = mCurrentAction;
|
|
mCurrentAction = i_action;
|
|
mAction = &((ActionFunc*)ActionTable)[mCurrentAction * 2];
|
|
callInit();
|
|
}
|
|
|
|
int execute() {
|
|
callExecute();
|
|
if (mCurrentAction != MODE_4_e && checkEmergency()) {
|
|
setAction(MODE_4_e);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
bool isAllMemberCulling() {
|
|
FmtMember_c* member = mMember;
|
|
bool memberCulling;
|
|
fopAc_ac_c* npcFgd = NULL;
|
|
for (int i = 0; i < mFormationRow * mFormationLine; i++, member++) {
|
|
memberCulling = false;
|
|
if (member->mNpcId != -1) {
|
|
fopAcM_SearchByID(member->mNpcId, &npcFgd);
|
|
if (npcFgd != NULL) {
|
|
memberCulling = fopAcM_CheckCondition(npcFgd, 4);
|
|
}
|
|
if (!memberCulling) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void setMoveSpeed() {
|
|
speedF += attr().field_0x08;
|
|
if (speedF > attr().field_0x04) {
|
|
speedF = attr().field_0x04;
|
|
}
|
|
}
|
|
|
|
void setMoveAngle(FmtPos_c* member) {
|
|
if (speedF <= 0.0f) {
|
|
return;
|
|
}
|
|
cXyz acStack_28;
|
|
member->getTargetPoint(&acStack_28);
|
|
cLib_addCalcAngleS2(&member->field_0x1c,
|
|
cLib_targetAngleY(&member->field_0x10, &acStack_28),
|
|
attr().field_0x14, attr().field_0x16);
|
|
}
|
|
|
|
void setMovePos(cXyz* param_1, s16* param_2) {
|
|
param_1->x += speedF * cM_ssin(*param_2);
|
|
param_1->z += speedF * cM_scos(*param_2);
|
|
}
|
|
|
|
void correctFormation() {
|
|
FmtPos_c* pos = mPos + 1;
|
|
for (int i = 1; i < mFormationRow; i++, pos++) {
|
|
if (cLib_distanceAngleS(pos[-1].field_0x1c, pos[0].field_0x1c) <= attr().field_0x00) {
|
|
pos[0].field_0x10.set(0.0f, 0.0f, -attr().field_0x10);
|
|
mDoMtx_stack_c::transS(pos[-1].field_0x10);
|
|
mDoMtx_stack_c::YrotM(pos[-1].field_0x1c);
|
|
mDoMtx_stack_c::multVec(&pos[0].field_0x10, &pos[0].field_0x10);
|
|
}
|
|
}
|
|
}
|
|
|
|
void setMemberPos() {
|
|
int j;
|
|
FmtPos_c* pos;
|
|
fopAc_ac_c* npcFgd;
|
|
FmtMember_c* member;
|
|
int i;
|
|
pos = mPos;
|
|
member = mMember;
|
|
for (i = 0; i < mFormationRow; i++, pos++) {
|
|
f32 dVar13 = (mFormationLine - 1) * attr().field_0x0c * 0.5f;
|
|
mDoMtx_stack_c::transS(pos->field_0x10);
|
|
mDoMtx_stack_c::YrotM(pos->field_0x1c);
|
|
for (j = 0; j < mFormationLine; j++, member++) {
|
|
member->field_0x10.set(member->field_0x04);
|
|
member->field_0x04.set(dVar13, 0.0f, 0.0f);
|
|
mDoMtx_stack_c::multVec(&member->field_0x04, &member->field_0x04);
|
|
dVar13 -= attr().field_0x0c;
|
|
npcFgd = NULL;
|
|
fopAcM_SearchByID(member->mNpcId, &npcFgd);
|
|
if (npcFgd != NULL) {
|
|
cXyz* npcPos = fopAcM_GetPosition_p(npcFgd);
|
|
csXyz* npcAngle = fopAcM_GetShapeAngle_p(npcFgd);
|
|
npcPos->x = member->field_0x04.x;
|
|
npcPos->z = member->field_0x04.z;
|
|
cLib_addCalcAngleS2(&npcAngle->y,
|
|
cLib_targetAngleY(&member->field_0x10, &member->field_0x04),
|
|
attr().field_0x14, attr().field_0x16);
|
|
fopAcM_SetSpeedF(npcFgd, member->field_0x10.abs(member->field_0x04));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static FmtMngAttributes const& attr() { return M_attr; }
|
|
static FmtMngAttributes const M_attr;
|
|
|
|
typedef void (daFmtMng_c::*ActionFunc)();
|
|
static daFmtMng_c::ActionFunc ActionTable[10];
|
|
|
|
/* 0x568 */ FmtPos_c* mPos;
|
|
/* 0x56C */ FmtMember_c* mMember;
|
|
/* 0x570 */ dPath* mRoomPath;
|
|
/* 0x574 */ ActionFunc* mAction;
|
|
/* 0x578 */ int mCurrentAction;
|
|
/* 0x57C */ int mPrevAction;
|
|
/* 0x580 */ int field_0x580;
|
|
/* 0x584 */ int mFormationLine;
|
|
/* 0x588 */ int mFormationRow;
|
|
/* 0x58C */ int mStartTime;
|
|
/* 0x590 */ int mEndTime;
|
|
/* 0x594 */ int mDayOfWeek;
|
|
/* 0x598 */ int field_0x598;
|
|
/* 0x59C */ int field_0x59c;
|
|
/* 0x5A0 */ int field_0x5a0;
|
|
};
|
|
|
|
#endif /* D_A_FORMATION_MNG_H */
|