Implement & link m_collision_bg

This commit is contained in:
Cuyler36
2025-01-25 22:24:46 -05:00
parent cb8d8bc5fc
commit 81bbadf75d
25 changed files with 6203 additions and 138 deletions
+1 -1
View File
@@ -1383,7 +1383,7 @@ config.libs = [
Object(Matching, "game/m_choice.c"),
Object(Matching, "game/m_clip.c"),
Object(Matching, "game/m_cockroach.c"),
Object(NonMatching, "game/m_collision_bg.c"),
Object(Matching, "game/m_collision_bg.c"),
Object(Matching, "game/m_collision_obj.c"),
Object(Matching, "game/m_common_data.c"),
Object(Matching, "game/m_controller.c"),
+1
View File
@@ -7,6 +7,7 @@ extern "C" {
#include "types.h"
#define SQRT_OF_2_DIV_2 0.70710678118654752440f
#define SQRT_OF_2_F 1.41421356237309504880f
#define SQRT_OF_3_F 1.73205080756887729353f
+1 -1
View File
@@ -1077,7 +1077,7 @@ typedef struct actor_shape_info_s {
/* 0x1C */ f32 shadow_alpha_change_rate;
/* 0x20 */ int unk_20;
/* 0x24 */ xyz_t* shadow_position;
/* 0x28 */ int unk_28;
/* 0x28 */ int move_bg_idx;
/* 0x2C */ u8 draw_shadow; /* TRUE = shadow is drawn, FALSE = shadow is not drawn */
/* 0x2D */ u8 unk_2D;
/* 0x2E */ u8
+131 -34
View File
@@ -10,6 +10,22 @@ extern "C" {
#define mCoBG_HEIGHT_MAX 31
#define mCoBG_ATR_NO_PLACE (0 << 3)
#define mCoBG_ATR_PLACE (1 << 3)
#define mCoBG_ATR_NO_NPC (0 << 4)
#define mCoBG_ATR_NPC (1 << 4)
enum {
mCoBG_PLANT0 = 0, /* Stay a sapling */
mCoBG_PLANT1 = 1, /* Grow until the first stage of growth */
mCoBG_PLANT2 = 2, /* Grow until the second stage of growth */
mCoBG_PLANT3 = 3, /* Grow until the third stage of growth */
mCoBG_PLANT4 = 4, /* Fully grow */
mCoBG_KILL_PLANT = 7 /* No growth, all plants die on this unit */
};
enum field_layer {
mCoBG_LAYER0,
mCoBG_LAYER1,
@@ -103,13 +119,12 @@ enum background_attribute {
};
enum {
mCoBG_PLANT0 = 0, /* Stay a sapling */
mCoBG_PLANT1 = 1, /* Grow until the first stage of growth */
mCoBG_PLANT2 = 2, /* Grow until the second stage of growth */
mCoBG_PLANT3 = 3, /* Grow until the third stage of growth */
mCoBG_PLANT4 = 4, /* Fully grow */
mCoBG_DIM_XY,
mCoBG_DIM_XZ,
mCoBG_DIM_YZ,
mCoBG_DIM_ALL,
mCoBG_KILL_PLANT = 7 /* No growth, all plants die on this unit */
mCoBG_DIM_NUM
};
enum {
@@ -141,14 +156,16 @@ enum {
mCoBG_BLOCK_BGCHECK_MODE_NUM
};
extern int mCoBG_block_bgcheck_mode;
/* sizeof(mCoBG_CollisionData_c) == 4*/
typedef struct collision_bg_data_s {
/* 1------- -------- -------- -------- */ u32 shape : 1; /* collision shape */
/* 1------- -------- -------- -------- */ u32 slate_flag : 1; /* collision shape */
/* -11111-- -------- -------- -------- */ u32 center : 5;
/* ------11 111----- -------- -------- */ u32 top_left : 5;
/* -------- ---11111 -------- -------- */ u32 bot_left : 5;
/* -------- -------- 11111--- -------- */ u32 top_right : 5;
/* -------- -------- -----111 11------ */ u32 bot_right : 5;
/* -------- -------- 11111--- -------- */ u32 bot_right : 5;
/* -------- -------- -----111 11------ */ u32 top_right : 5;
/* -------- -------- -------- --111111 */ u32 unit_attribute : 6; /* background_attribute type */
} mCoBG_CollisionData_c;
@@ -165,11 +182,10 @@ typedef struct collision_unit_info_s {
f32 rightDown_offset;
f32 rightUp_offset;
f32 base_height;
f32 pos_x;
f32 pos_z;
f32 unit_pos[2];
int ut_x;
int ut_z;
int shape;
u32 slate_flag;
u8 attribute;
mActor_name_t item;
} mCoBG_UnitInfo_c;
@@ -187,7 +203,7 @@ typedef struct collision_bg_check_result_s {
//
u32 hit_wall : 5; // 2 bits in prev byte
u32 hit_wall_count : 3;
u32 unk_flag0 : 1;
u32 jump_flag : 1;
//
u32 unit_attribute : 6; // 1 bit in prev byte
u32 is_on_move_bg_obj : 1;
@@ -214,6 +230,26 @@ enum {
mCoBG_WALL_TYPE_NUM
};
enum {
mCoBG_WALL_UP,
mCoBG_WALL_LEFT,
mCoBG_WALL_DOWN,
mCoBG_WALL_RIGHT,
mCoBG_WALL_SLATE_UP,
mCoBG_WALL_SLATE_DOWN,
mCoBG_WALL_NUM
};
enum {
mCoBG_NORM_DIRECT_UP,
mCoBG_NORM_DIRECT_LEFT,
mCoBG_NORM_DIRECT_DOWN,
mCoBG_NORM_DIRECT_RIGHT,
mCoBG_NORM_DIRECT_NUM
};
typedef struct collision_bg_check_s {
mCoBG_Collision_u collision_units[5];
mCoBG_CheckResult_c result;
@@ -229,11 +265,19 @@ typedef struct bg_side_contact_s {
s16 angle;
} mCoBG_side_contact_c;
typedef struct bg_on_contact_s {
s16 name;
} mCoBG_on_contact_c;
typedef struct bg_on_contact_inf_s {
mCoBG_on_contact_c contact[5];
int count;
} mCoBG_on_contact_info_c;
typedef struct bg_contact_s {
mCoBG_side_contact_c side_contact[5];
int side_count;
s16 on_contact_names[5];
int on_count;
mCoBG_on_contact_info_c on_contact;
} mCoBG_bg_contact_c;
typedef struct bg_size_s {
@@ -256,6 +300,12 @@ typedef struct bg_register_s {
f32* scale_percent;
} mCoBG_bg_regist_c;
#define mCoBG_MOVE_REGIST_MAX 64
typedef struct bg_mgr_s {
mCoBG_bg_regist_c* regist_p[mCoBG_MOVE_REGIST_MAX];
int count;
} mCoBG_mBgMgr_c;
typedef struct collision_offset_table_s {
u8 unit_attribute;
s8 centerRight_offset;
@@ -266,31 +316,72 @@ typedef struct collision_offset_table_s {
s8 shape;
} mCoBG_OffsetTable_c;
typedef struct wall_height_s {
f32 top;
f32 bot;
} mCoBG_WallHeight_c;
#define mCoBG_WALL_COL_NUM 2
typedef struct collision_actor_info_s {
mActor_name_t name_id;
u8 _02;
u8 on_ground;
s16 name;
u8 check_type;
u8 old_on_ground;
u8 _04;
u8 in_water;
u8 _06[2]; // alignment?
u8 old_in_water;
// u8 _06[2]; // alignment?
mCoBG_CheckResult_c* check_res_p;
xz_t speed_xz0;
xz_t speed_xz1;
f32 speed_xz0[2];
f32 speed_xz1[2];
xyz_t center_pos;
xyz_t old_center_pos;
xyz_t rev_pos;
u8 _40[4];
f32 _44;
f32 _48;
f32 _4C;
u8 _50[0x20];
f32 range;
f32 ground_dist;
f32 old_ground_y;
f32 ground_y;
mCoBG_WallHeight_c wall_height;
mCoBG_WallInfo_c wall_info[mCoBG_WALL_COL_NUM];
s16 ut_count;
u32 _64;
int _68;
int _6C;
} mCoBG_ActorInf_c;
enum {
mCoBG_UNIT_RADIAN,
mCoBG_UNIT_DEGREE,
mCoBG_UNIT_SHORT,
mCoBG_UNIT_NUM
};
enum {
mCoBG_CHECK_TYPE_NORMAL,
mCoBG_CHECK_TYPE_PLAYER,
mCoBG_CHECK_TYPE_NUM
};
enum {
mCoBG_REVERSE_TYPE_REVERSE,
mCoBG_REVERSE_TYPE_NO_REVERSE,
mCoBG_REVERSE_TYPE_NUM
};
#define mCoBG_LINE_CHECK_WALL (1 << 0)
#define mCoBG_LINE_CHECK_GROUND (1 << 1)
#define mCoBG_LINE_CHECK_WATER (1 << 2)
#define mCoBG_LINE_CHECK_UNDERWATER (1 << 3)
typedef int (*mCoBG_COLUMN_CHECK_ITEM_TYPE_PROC)(mActor_name_t item);
extern u32 mCoBG_Wpos2BgAttribute_Original(xyz_t wpos);
extern u32 mCoBG_Wpos2Attribute(xyz_t wpos, s8* is_diggable);
extern u32 mCoBG_Wpos2Attribute(xyz_t wpos, s8* cant_dig);
extern int mCoBG_CheckWaterAttribute(u32 attribute);
extern f32 mCoBG_GetBgY_AngleS_FromWpos(s_xyz* angle_to_ground, xyz_t wpos, f32 offset_y);
extern f32 mCoBG_GetShadowBgY_AngleS_FromWpos(f32, s_xyz*, xyz_t);
extern f32 mCoBG_GetShadowBgY_AngleS_FromWpos(s_xyz*, xyz_t, f32);
extern int mCoBG_CheckWaterAttribute_OutOfSea(u32 attribute);
extern int mCoBG_CheckHole_OrgAttr(u32 attribute);
extern f32 mCoBG_GetBgY_OnlyCenter_FromWpos(xyz_t wpos, f32 dist);
@@ -302,11 +393,11 @@ extern int mCoBG_Height2GetLayer(f32 height);
extern void mCoBG_SetPlussOffset(xyz_t wpos, s16 offset, s16 new_attrib);
extern int mCoBG_GetLayer(const xyz_t* wpos);
extern int mCoBG_BnumUnum2HoleNumber(int block_x, int block_z, int ut_x, int ut_z);
extern u32 mCoBG_UtNum2BgAttr(int ut_x, int ut_z);
extern int mCoBG_UtNum2BgAttr(int ut_x, int ut_z);
extern f32 mCoBG_UtNum2UtCenterY(int ut_x, int ut_z);
extern int mCoBG_CheckCliffAttr(u32 attribute);
extern void mCoBG_SetPluss5PointOffset_file(xyz_t pos, mCoBG_OffsetTable_c offsetptr, const char* file, int line);
#define mCoBG_SetPluss5PointOffset(pos, offsetptr) mCoBG_SetPluss5PointOffset_file(pos, offsetptr, __FILE__, __LINE__);
extern void mCoBG_SetPluss5PointOffset_file(xyz_t pos, mCoBG_OffsetTable_c ofs_data, char* file, int line);
#define mCoBG_SetPluss5PointOffset(pos, ofs_data) mCoBG_SetPluss5PointOffset_file(pos, offsetptr, __FILE__, __LINE__);
extern int mCoBG_Change2PoorAttr(mCoBG_Collision_u* col);
extern int mCoBG_CheckHole(xyz_t wpos);
extern int mCoBG_CheckSkySwing(xyz_t wpos);
@@ -320,7 +411,7 @@ extern int mCoBG_ExistHeightGap_KeepAndNow_Detail(xyz_t wpos);
extern int mCoBG_GetHoleNumber(xyz_t wpos);
extern int mCoBG_Attr2CheckPlaceNpc(u32 attribute);
extern int mCoBG_ExistHeightGap_KeepAndNow(xyz_t wpos);
extern void mCoBG_GetNorm_By3Point(xyz_t* norm, xyz_t* p0, xyz_t* p1, xyz_t* p2);
extern void mCoBG_GetNorm_By3Point(xyz_t* normal, f32* v0, f32* v1, f32* v2);
extern int mCoBG_SearchWaterLimitDistN(xyz_t* water_pos, xyz_t wpos, s16 angle, float max_dist, int divisor);
extern f32 mCoBG_GetBalloonGroundY(const xyz_t* pos);
extern void mCoBG_MakeBoatCollision(ACTOR* actor, xyz_t* pos, s16* angle_y);
@@ -335,7 +426,7 @@ extern int mCoBG_CheckSandHole_ClData(mCoBG_Collision_u* col);
extern int mCoBG_GetHoleNumber_ClData(mCoBG_Collision_u* col);
extern void mCoBG_GetBgNorm_FromWpos(xyz_t* norm, xyz_t wpos);
extern int mCoBG_GetWaterFlow(xyz_t* water_flow, u32 attr);
extern void mCoBG_SetAttribute(xyz_t pos, u32 attr);
extern void mCoBG_SetAttribute(xyz_t pos, s16 attr);
extern int mCoBG_GetPointInfoFrontLine(f32* line, f32* check_pos, f32* norm);
extern int mCoBG_GetCrossCircleAndLine2Dvector(f32* cross0_xz, f32* cross1_xz, f32* point_xz, f32* vec_xz,
f32* center_xz, f32 radius);
@@ -363,6 +454,12 @@ extern void mCoBG_VirtualBGCheck(xyz_t* rev_pos_p, mCoBG_Check_c* bg_check, cons
extern f32 mCoBG_Wpos2GroundCheckOnly(const xyz_t* pos_p, f32 ground_dist);
extern int mCoBG_Wpos2CheckNpc(xyz_t wpos);
extern void mCoBG_WallCheckOnly(xyz_t* rev_pos_p, ACTOR* actor, f32 range, f32 ground_dist, s16 rev_type, s16 check_type);
extern int mCoBG_GetCrossJudge_2Vector(f32* vec0_p0, f32* vec0_p1, f32* vec1_p0, f32* vec1_p1);
extern void mCoBG_GetCross2Line(f32* cross, f32* line0_p0, f32* line0_p1, f32* line1_p0, f32* line1_p1);
extern int mCoBG_GetPointInfoFrontLine(f32* start, f32* point, f32* normal);
extern int mCoBG_JudgePointInCircle(f32* point, f32* center, f32 radius);
extern f32 mCoBG_WaveCos(void);
extern mCoBG_bg_regist_c* mCoBG_Idx2RegistPointer(int move_bg_idx);
typedef int (*mCoBG_LINECHECK_PROC)(mActor_name_t);
+1
View File
@@ -34,6 +34,7 @@ extern "C" {
#define FGBLOCKXZ_2_FGIDX(x, z) ((z) * FG_BLOCK_X_NUM + (x))
#define BLOCKXZ_2_BLOCKIDX(x, z) ((z) * BLOCK_X_NUM + (x))
#define UNITXZ_2_UNIT(x, z) ((z) * UT_X_NUM + (x))
#define mFM_VISIBLE_BLOCK_NUM 4 /* number of visible blocks (nearest to the Player) */
#define mFM_SOUND_SOURCE_NUM 6
+9
View File
@@ -549,6 +549,9 @@ extern int mNT_check_unknown(mActor_name_t item_no);
#define ITEM_IS_PAINT(item) ((item) >= ITM_RED_PAINT && (item) <= ITM_BROWN_PAINT)
#define ITEM_IS_TOOL(item) ((item) >= ITM_TOOL_START && (item) < ITM_TOOL_END)
#define ITEM_IS_DUMMY_MAILBOX(item) ((item) >= DUMMY_MAILBOX0 && (item) <= DUMMY_MAILBOX3)
#define ITEM_IS_SIGN(item) ((item) == DUMMY_RESERVE || ITEM_IS_SIGNBOARD(item))
#define BG_CATEGORY 0
#define ENV_CATEGORY 8
@@ -3047,6 +3050,10 @@ extern int mNT_check_unknown(mActor_name_t item_no);
#define NPC_END (NPC_START + 236)
#define DUMMY_START 0xF000
#define DUMMY_MAILBOX0 (DUMMY_START + 1) // 0xF001
#define DUMMY_MAILBOX1 (DUMMY_START + 2) // 0xF002
#define DUMMY_MAILBOX2 (DUMMY_START + 3) // 0xF003
#define DUMMY_MAILBOX3 (DUMMY_START + 4) // 0xF004
#define DUMMY_NPC_HOUSE_START (DUMMY_START + 5) // 0xF005
#define DUMMY_NPC_HOUSE_000 (DUMMY_START + 5) // F005
#define DUMMY_NPC_HOUSE_001 (DUMMY_START + 6) // F006
@@ -3390,6 +3397,8 @@ extern int mNT_check_unknown(mActor_name_t item_no);
#define RSV_SHOP_SOLD_UMBRELLA 0xFE16
#define RSV_SHOP_SOLD_PAINT 0xFE17
#define RSV_SHOP_SOLD_SIGNBOARD 0xFE18
#define RSV_HOLE 0xFE19
#define RSV_TREE 0xFE1A
#define RSV_DOOR 0xFE1B
#define RSV_FE1C 0xFE1C
#define RSV_FE1F 0xFE1F
+1 -1
View File
@@ -31,7 +31,7 @@ extern void Matrix_softcv3_load(s_xyz* src, f32 x, f32 y, f32 z);
extern Mtx* _MtxF_to_Mtx(MtxF* src, Mtx* dest);
extern Mtx* _Matrix_to_Mtx(Mtx* dest);
extern Mtx* _Matrix_to_Mtx_new(GRAPH* graph);
extern void Matrix_Position(xyz_t* old_pos, xyz_t* new_pos);
extern void Matrix_Position(xyz_t* input_position, xyz_t* output_position);
extern void Matrix_Position_Zero(xyz_t* screen_pos);
extern void Matrix_Position_VecX(f32 x, xyz_t* screen_pos);
extern void Matrix_Position_VecZ(f32 z, xyz_t* screen_pos);
+1 -1
View File
@@ -676,7 +676,7 @@ static int aMR_GroundFlat(xyz_t* pos) {
mCoBG_Collision_u* col = mFI_GetUnitCol(*pos);
if (col->data.center == col->data.top_left && col->data.center == col->data.bot_left &&
col->data.center == col->data.top_right && col->data.center == col->data.bot_right) {
col->data.center == col->data.bot_right && col->data.center == col->data.top_right) {
return TRUE;
}
+1 -1
View File
@@ -55,7 +55,7 @@ static void eFootPrint_ct(eEC_Effect_c* effect, GAME* game, void* ct_arg) {
int sum_angle_x = 0;
int sum_angle_z = 0;
effect->position.y = 2.0f + mCoBG_GetShadowBgY_AngleS_FromWpos(0.0f, NULL, effect->position);
effect->position.y = 2.0f + mCoBG_GetShadowBgY_AngleS_FromWpos(NULL, effect->position, 0.0f);
effect->effect_specific[2] = data->angle;
/* Get the total ground angle (x & z) in a triangle around the effect position */
+1 -1
View File
@@ -100,7 +100,7 @@ extern void Shape_Info_init(ACTOR* actor, f32 ofs_y, mActor_shadow_proc shadow_p
actor->shape_info.shadow_position = &actor->world.position; // ???
#endif
actor->shape_info.unk_28 = -1;
actor->shape_info.move_bg_idx = -1;
actor->shape_info.unk_2D = 0;
}
+2 -2
View File
@@ -148,7 +148,7 @@ void mActorShadow_GetShadowTopPos_GetSlideS(Shadow_Info* shadow) {
wpos.y = shadow->position.y + base.y;
wpos.z = shadow->position.z + base.z;
res = 0;
bg_y = mCoBG_GetShadowBgY_AngleS_FromWpos(0.0f, NULL, wpos);
bg_y = mCoBG_GetShadowBgY_AngleS_FromWpos(NULL, wpos, 0.0f);
if ((shadow->position.y - bg_y) > 20.0f) {
shadow->unk34 = 28;
return;
@@ -292,7 +292,7 @@ int mActorShadow_GetShadowKind(void) {
}
f32 mAc_GetShadowGroundY_NoneForce(const Shadow_Info* shadow) {
f32 res = mCoBG_GetShadowBgY_AngleS_FromWpos(0.0f, NULL, shadow->position);
f32 res = mCoBG_GetShadowBgY_AngleS_FromWpos(NULL, shadow->position, 0.0f);
return res;
}
+2 -2
View File
@@ -2268,7 +2268,7 @@ static void mAGrw_GetDepositAbleFlatNum(u8* candidate_num, u8* flat_num, mActor_
/* Check if the unit collision data is a flat square */
if ((col->data.center == col->data.top_left) && (col->data.center == col->data.bot_left) &&
(col->data.center == col->data.top_right) && (col->data.center == col->data.bot_right) &&
(col->data.center == col->data.bot_right) && (col->data.center == col->data.top_right) &&
(mCoBG_CheckSandHole_ClData(col) != TRUE)) {
flat_num[0]++;
}
@@ -2298,7 +2298,7 @@ static void mAGrw_SetShineGroundBlock(mAGrw_SSPosInfo_c* pos_info, mActor_name_t
(mCoBG_CheckHole_OrgAttr(col->data.unit_attribute))) {
/* Check if the unit collision data is a flat square */
if ((col->data.center == col->data.top_left) && (col->data.center == col->data.bot_left) &&
(col->data.center == col->data.top_right) && (col->data.center == col->data.bot_right) &&
(col->data.center == col->data.bot_right) && (col->data.center == col->data.top_right) &&
(mCoBG_CheckSandHole_ClData(col) != TRUE)) {
if (selected_ut == 0) {
pos_info->ut_x = ut_x;
+1645 -84
View File
File diff suppressed because it is too large Load Diff
+88
View File
@@ -0,0 +1,88 @@
int mCoBG_block_bgcheck_mode = mCoBG_BLOCK_BGCHECK_MODE_NORMAL;
extern void mCoBG_InitBlockBgCheckMode(void) {
mCoBG_block_bgcheck_mode = mCoBG_BLOCK_BGCHECK_MODE_NORMAL;
}
extern int mCoBG_ChangeBlockBgCheckMode(int mode) {
mCoBG_block_bgcheck_mode = mode & 1;
return mCoBG_block_bgcheck_mode;
}
extern int mCoBG_GetBlockBgCheckMode(void) {
return mCoBG_block_bgcheck_mode & 1;
}
extern xyz_t mCoBG_UniqueWallCheck(ACTOR* actorx, f32 range, f32 y_ofs) {
int bx;
int bz;
xyz_t ret = { 0.0f, 0.0f, 0.0f };
mCoBG_InitRevpos(&l_ActorInf.rev_pos);
mCoBG_GetCurrentCenterPosition(&l_ActorInf.center_pos, actorx);
mCoBG_GetOldCenterPosition(&l_ActorInf.old_center_pos, actorx);
mCoBG_GetSpeedByWpos(l_ActorInf.speed_xz0, actorx);
if (mFI_Wpos2BlockNum(&bx, &bz, l_ActorInf.old_center_pos)) {
xyz_t block_base = { 0.0f, 0.0f, 0.0f };
mCoBG_SetXyz_t(&l_ActorInf.rev_pos, 0.0f, 0.0f, 0.0f);
mFI_BkNum2WposXZ(&block_base.x, &block_base.z, bx, bz);
if (mCoBG_GetBlockBgCheckMode() == mCoBG_BLOCK_BGCHECK_MODE_INTRO_DEMO &&
(mFI_BkNum2BlockKind(bx, bz) & mRF_BLOCKKIND_PLAYER) != 0
) {
block_base.x += mFI_UT_WORLDSIZE_X_F;
block_base.z += mFI_UT_WORLDSIZE_Z_F;
return mCoBG_ScopeWallCheck(actorx, &block_base, mFI_BK_WORLDSIZE_X - 2 * mFI_UT_WORLDSIZE_X, mFI_BK_WORLDSIZE_Z - 2 * mFI_UT_WORLDSIZE_Z, range, y_ofs);
} else {
return mCoBG_ScopeWallCheck(actorx, &block_base, mFI_BK_WORLDSIZE_X, mFI_BK_WORLDSIZE_Z, range, y_ofs);
}
}
return ret;
}
extern xyz_t mCoBG_ScopeWallCheck(ACTOR* actorx, const xyz_t* base_pos, f32 x, f32 z, f32 range, f32 y_ofs) {
f32 start[2];
f32 end[2];
s16 rev_type;
xyz_t rev = { 0.0f, 0.0f, 0.0f };
mCoBG_InitRevpos(&l_ActorInf.rev_pos);
mCoBG_GetCurrentCenterPosition(&l_ActorInf.center_pos, actorx);
mCoBG_GetOldCenterPosition(&l_ActorInf.old_center_pos, actorx);
mCoBG_GetSpeedByWpos(l_ActorInf.speed_xz0, actorx);
if (l_ActorInf.speed_xz0[0] != 0.0f || l_ActorInf.speed_xz0[1] != 0.0f) {
start[0] = (base_pos->x);
start[1] = (base_pos->z);
end[0] = start[0] + x;
end[1] = start[1] + z;
start[0] += range;
start[1] += range;
end[0] -= range;
end[1] -= range;
mCoBG_SetXyz_t(&l_ActorInf.rev_pos, 0.0f, 0.0f, 0.0f);
if (l_ActorInf.center_pos.x < start[0]) {
l_ActorInf.rev_pos.x = start[0] - l_ActorInf.center_pos.x;
} else if (l_ActorInf.center_pos.x > end[0]) {
l_ActorInf.rev_pos.x = end[0] - l_ActorInf.center_pos.x;
}
if (l_ActorInf.center_pos.z < start[1]) {
l_ActorInf.rev_pos.z = start[1] - l_ActorInf.center_pos.z;
} else if (l_ActorInf.center_pos.z > end[1]) {
l_ActorInf.rev_pos.z = end[1] - l_ActorInf.center_pos.z;
}
mCoBG_GroundCheck(&l_ActorInf.rev_pos, &l_ActorInf, actorx, y_ofs, &actorx->bg_collision_check.result, NULL, FALSE);
mCoBG_CarryOutReverse(actorx, l_ActorInf.rev_pos, mCoBG_REVERSE_TYPE_REVERSE);
return l_ActorInf.rev_pos;
}
return rev;
}
+578
View File
@@ -0,0 +1,578 @@
typedef struct {
xyz_t pos;
int in_use;
f32 start_radius;
f32 end_radius;
f32 now_radius;
s16 start_timer;
s16 now_timer;
} mCoBG_regist_circle_info_c;
static int mCoBG_regist_decal_circle_count = 0;
static mCoBG_regist_circle_info_c mCoBG_regist_circle_info[3];
static mCoBG_column_c mCoBG_decal_circle[3];
static f32 mCoBG_CalcAdjust(s16 now_a, s16 start_a, s16 end_a, f32 start_val, f32 end_val) {
if (start_a == end_a) {
return start_val;
}
if (now_a <= start_a) {
return start_val;
}
if (now_a >= end_a) {
return end_val;
}
{
f32 d_a = now_a - start_a;
f32 n_a = end_a - start_a;
f32 n_val = end_val - start_val;
return start_val + d_a * (n_val / n_a);
}
}
static void mCoBG_CalcTimerDecalCircleOne(mCoBG_regist_circle_info_c* regist, mCoBG_column_c* col_circle) {
if (regist->in_use == TRUE) {
if (regist->start_timer != -100) {
regist->now_radius = mCoBG_CalcAdjust(regist->start_timer - regist->now_timer, 0, regist->start_timer, regist->start_radius, regist->end_radius);
col_circle->pos = regist->pos;
col_circle->height = regist->pos.y;
col_circle->radius = regist->now_radius;
col_circle->atr_wall = TRUE;
col_circle->ux = (int)(col_circle->pos.x / mFI_UT_WORLDSIZE_X_F);
col_circle->uz = (int)(col_circle->pos.z / mFI_UT_WORLDSIZE_Z_F);
regist->now_timer--;
if (regist->now_timer < 0) {
regist->in_use = FALSE;
mCoBG_regist_decal_circle_count--;
}
}
}
}
extern void mCoBG_CalcTimerDecalCircle(void) {
int i;
mCoBG_regist_circle_info_c* regist = mCoBG_regist_circle_info;
mCoBG_column_c* col_circle = mCoBG_decal_circle;
if (mCoBG_regist_decal_circle_count > 0) {
for (i = 0; i < 3; i++) {
mCoBG_CalcTimerDecalCircleOne(regist, col_circle);
regist++;
col_circle++;
}
}
}
extern int mCoBG_RegistDecalCircle(const xyz_t* pos, f32 start_radius, f32 end_radius, s16 timer) {
int i;
mCoBG_regist_circle_info_c* regist = mCoBG_regist_circle_info;
mCoBG_column_c* col_circle = mCoBG_decal_circle;
if (mCoBG_regist_decal_circle_count < 3) {
for (i = 0; i < 3; i++) {
if (regist->in_use == FALSE) {
// @BUG - this will clobber data below mCoBG_regist_circle_info???
// because we don't break/return after finding a free
// circle and we clear the WHOLE array, we can clear into
// mCoBG_decal_circle's data.
#ifndef BUGFIXES
bzero(regist, sizeof(mCoBG_regist_circle_info));
#else
bzero(regist, sizeof(mCoBG_regist_circle_info_c));
#endif
bzero(col_circle, sizeof(mCoBG_column_c));
regist->in_use = TRUE;
regist->pos = *pos;
regist->start_radius = start_radius;
regist->end_radius = end_radius;
regist->now_radius = start_radius;
regist->start_timer = timer;
regist->now_timer = timer;
mCoBG_CalcTimerDecalCircleOne(regist, col_circle);
mCoBG_regist_decal_circle_count++;
// @BUG - shouldn't this exit immediately?
// As it stands, all free 'decal circle' collision columns
// will be utilized.
#ifdef BUGFIXES
return i;
#endif
}
regist++;
col_circle++;
}
}
return -1;
}
extern void mCoBG_InitDecalCircle(void) {
// @BUG - they incorrectly clear 3x the memory necessary.
// I'm guessing that they did 3 * sizeof(array) rather than
// 3 * sizeof(struct).
#ifndef BUGFIXES
bzero(mCoBG_regist_circle_info, 3 * sizeof(mCoBG_regist_circle_info));
#else
bzero(mCoBG_regist_circle_info, sizeof(mCoBG_regist_circle_info_c));
#endif
bzero(mCoBG_decal_circle, sizeof(mCoBG_decal_circle));
mCoBG_regist_decal_circle_count = 0;
}
// @unused, @fabricated
extern void mCoBG_CrossOffDecalCircle(int idx) {
if (idx >= 0 && idx < 3) {
bzero(&mCoBG_regist_circle_info[idx], sizeof(mCoBG_regist_circle_info_c));
bzero(&mCoBG_decal_circle[idx], sizeof(mCoBG_decal_circle));
mCoBG_regist_decal_circle_count--;
}
}
static int mCoBG_MakeOneColumnCollisionData(mCoBG_column_c* col, mCoBG_UnitInfo_c* ut_info, int old_on_ground, mCoBG_COLUMN_CHECK_ITEM_TYPE_PROC check_proc, int ux, int uz) {
if ((check_proc != NULL && (*check_proc)(ut_info->item) == FALSE) || check_proc == NULL) {
if (ut_info->ut_x == ux && ut_info->ut_z == uz) {
return FALSE;
}
if (old_on_ground == TRUE && (ITEM_IS_HOLE(ut_info->item) || ut_info->item == HOLE_SHINE || ut_info->item == RSV_HOLE)) {
col->pos.x = mFI_UT_WORLDSIZE_HALF_X_F + mFI_UT_WORLDSIZE_X_F * ut_info->ut_x;
col->pos.z = mFI_UT_WORLDSIZE_HALF_Z_F + mFI_UT_WORLDSIZE_Z_F * ut_info->ut_z;
col->pos.y = 0.0f;
col->ux = ut_info->ut_x;
col->uz = ut_info->ut_z;
col->pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(col->pos, 0.0f);
col->height = col->pos.y;
col->radius = 19.0f;
col->atr_wall = TRUE;
return TRUE;
}
if (IS_ITEM_SMALL_TREE(ut_info->item)) {
col->pos.x = mFI_UT_WORLDSIZE_HALF_X_F + mFI_UT_WORLDSIZE_X_F * ut_info->ut_x;
col->pos.z = mFI_UT_WORLDSIZE_HALF_Z_F + mFI_UT_WORLDSIZE_Z_F * ut_info->ut_z;
col->pos.y = 0.0f;
col->pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(col->pos, 0.0f);
col->height = col->pos.y + 30.0f;
col->ux = ut_info->ut_x;
col->uz = ut_info->ut_z;
col->radius = 19.0f;
col->atr_wall = FALSE;
return TRUE;
}
if (IS_ITEM_MED_TREE(ut_info->item)) {
col->pos.x = mFI_UT_WORLDSIZE_HALF_X_F + mFI_UT_WORLDSIZE_X_F * ut_info->ut_x;
col->pos.z = mFI_UT_WORLDSIZE_HALF_Z_F + mFI_UT_WORLDSIZE_Z_F * ut_info->ut_z;
col->pos.y = 0.0f;
col->pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(col->pos, 0.0f);
col->height = col->pos.y + 40.0f;
col->ux = ut_info->ut_x;
col->uz = ut_info->ut_z;
col->radius = 19.0f;
col->atr_wall = FALSE;
return TRUE;
}
if (IS_ITEM_LARGE_TREE(ut_info->item)) {
col->pos.x = mFI_UT_WORLDSIZE_HALF_X_F + mFI_UT_WORLDSIZE_X_F * ut_info->ut_x;
col->pos.z = mFI_UT_WORLDSIZE_HALF_Z_F + mFI_UT_WORLDSIZE_Z_F * ut_info->ut_z;
col->pos.y = 0.0f;
col->pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(col->pos, 0.0f);
col->height = col->pos.y + 60.0f;
col->ux = ut_info->ut_x;
col->uz = ut_info->ut_z;
col->radius = 19.0f;
col->atr_wall = FALSE;
return TRUE;
}
if (IS_ITEM_FULL_TREE(ut_info->item) || ut_info->item == RSV_TREE) {
col->pos.x = mFI_UT_WORLDSIZE_HALF_X_F + mFI_UT_WORLDSIZE_X_F * ut_info->ut_x;
col->pos.z = mFI_UT_WORLDSIZE_HALF_Z_F + mFI_UT_WORLDSIZE_Z_F * ut_info->ut_z;
col->pos.y = 0.0f;
col->pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(col->pos, 0.0f);
col->height = col->pos.y + 80.0f;
col->ux = ut_info->ut_x;
col->uz = ut_info->ut_z;
col->radius = 19.0f;
col->atr_wall = FALSE;
return TRUE;
}
if (IS_ITEM_TREE_STUMP(ut_info->item)) {
col->pos.x = mFI_UT_WORLDSIZE_HALF_X_F + mFI_UT_WORLDSIZE_X_F * ut_info->ut_x;
col->pos.z = mFI_UT_WORLDSIZE_HALF_Z_F + mFI_UT_WORLDSIZE_Z_F * ut_info->ut_z;
col->pos.y = 0.0f;
col->pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(col->pos, 0.0f);
col->ux = ut_info->ut_x;
col->uz = ut_info->ut_z;
if (ut_info->item == TREE_STUMP001 || ut_info->item == TREE_PALM_STUMP001 || ut_info->item == CEDAR_TREE_STUMP001 || ut_info->item == GOLD_TREE_STUMP001) {
col->radius = 10.0f;
col->height = col->pos.y + 30.0f;
} else {
col->radius = 18.0f;
col->height = col->pos.y + 30.0f;
}
col->atr_wall = FALSE;
return TRUE;
}
if (IS_ITEM_ROCK(ut_info->item)) {
col->pos.x = mFI_UT_WORLDSIZE_HALF_X_F + mFI_UT_WORLDSIZE_X_F * ut_info->ut_x;
col->pos.z = mFI_UT_WORLDSIZE_HALF_Z_F + mFI_UT_WORLDSIZE_Z_F * ut_info->ut_z;
col->pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(col->pos, 0.0f);
col->ux = ut_info->ut_x;
col->uz = ut_info->ut_z;
col->radius = 19.0f;
col->height = col->pos.y + 31.5f;
col->atr_wall = FALSE;
return TRUE;
}
if (ut_info->item == DUMMY_MAILBOX0 || ut_info->item == DUMMY_MAILBOX1 || ut_info->item == DUMMY_MAILBOX2 || ut_info->item == DUMMY_MAILBOX3) {
col->pos.x = mFI_UT_WORLDSIZE_HALF_X_F + mFI_UT_WORLDSIZE_X_F * ut_info->ut_x;
col->pos.z = mFI_UT_WORLDSIZE_HALF_Z_F + mFI_UT_WORLDSIZE_Z_F * ut_info->ut_z;
col->pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(col->pos, 0.0f);
col->ux = ut_info->ut_x;
col->uz = ut_info->ut_z;
col->radius = 15.0f;
col->height = col->pos.y + 50.0f;
col->atr_wall = FALSE;
return TRUE;
}
if (ITEM_IS_SIGN(ut_info->item)) {
col->pos.x = mFI_UT_WORLDSIZE_HALF_X_F + mFI_UT_WORLDSIZE_X_F * ut_info->ut_x;
col->pos.z = mFI_UT_WORLDSIZE_HALF_Z_F + mFI_UT_WORLDSIZE_Z_F * ut_info->ut_z;
col->pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(col->pos, 0.0f);
col->radius = 19.0f;
col->height = col->pos.y + 45.0f;
col->ux = ut_info->ut_x;
col->uz = ut_info->ut_z;
col->atr_wall = FALSE;
return TRUE;
}
if (ut_info->item == RSV_SIGNBOARD) {
col->pos.x = mFI_UT_WORLDSIZE_HALF_X_F + mFI_UT_WORLDSIZE_X_F * ut_info->ut_x;
col->pos.z = mFI_UT_WORLDSIZE_HALF_Z_F + mFI_UT_WORLDSIZE_Z_F * ut_info->ut_z;
col->pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(col->pos, 0.0f);
col->radius = 10.0f;
col->height = col->pos.y + 45.0f;
col->ux = ut_info->ut_x;
col->uz = ut_info->ut_z;
col->atr_wall = FALSE;
return TRUE;
}
if (ut_info->item == DUMMY_KOINOBORI || ut_info->item == DUMMY_FLAG) {
col->pos.x = mFI_UT_WORLDSIZE_HALF_X_F + mFI_UT_WORLDSIZE_X_F * ut_info->ut_x;
col->pos.z = mFI_UT_WORLDSIZE_HALF_Z_F + mFI_UT_WORLDSIZE_Z_F * ut_info->ut_z;
col->pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(col->pos, 0.0f);
col->radius = 19.0f;
col->height = col->pos.y + 160.0f;
col->ux = ut_info->ut_x;
col->uz = ut_info->ut_z;
col->atr_wall = FALSE;
return TRUE;
}
}
return FALSE;
}
static void mCoBG_MakeColumnCollisionData(mCoBG_column_c* col, int* col_count_p, mCoBG_UnitInfo_c* ut_info, int count, int old_on_ground, mCoBG_COLUMN_CHECK_ITEM_TYPE_PROC check_item_proc, int ux, int uz) {
int count_sq = SQ(count);
int i;
*col_count_p = 0;
for (i = 0; i < count_sq; i++) {
if (*col_count_p < 16) {
mCoBG_MakeOneColumnCollisionData(col, ut_info, old_on_ground, check_item_proc, ux, uz);
col++;
(*col_count_p)++;
}
ut_info++;
}
}
static void mCoBG_ColumnCheck_NormalWall(xyz_t* rev, mCoBG_ActorInf_c* actor_info, const xyz_t* pos, const xyz_t* old_pos, mCoBG_column_c* col, s16 attr_wall) {
f32 ground_dist = actor_info->ground_dist;
f32 now_y = ground_dist + pos->y;
if (mCoBG_JudgePointInCircle_Xyz(old_pos, &col->pos, col->radius) == FALSE && (col->height >= (now_y + 3.0f))) {
f32 dx = pos->x - col->pos.x;
f32 dz = pos->z - col->pos.z;
f32 dist = sqrtf(SQ(dx) + SQ(dz));
f32 check_dist = actor_info->range + col->radius;
if (dist < check_dist) {
xyz_t rev_vec;
f32 rev_dist = check_dist - dist;
xyz_t rev_unit_vec;
mCoBG_WallHeight_c height;
s16 angle = atans_table(dz, dx);
f32 div;
rev_vec.x = pos->x - col->pos.x;
rev_vec.y = 0.0f;
rev_vec.z = pos->z - col->pos.z;
if (F32_IS_ZERO(dist)) {
div = 1.0f;
} else {
div = 1.0f / dist;
}
rev_unit_vec.x = rev_vec.x * div;
rev_unit_vec.y = 0.0f;
rev_unit_vec.z = rev_vec.z * div;
rev->x = rev_unit_vec.x * rev_dist;
rev->y = rev_unit_vec.y * rev_dist;
rev->z = rev_unit_vec.z * rev_dist;
height.top = col->height;
height.bot = col->pos.y;
mCoBG_RegistCollisionWallInfo(actor_info, actor_info->wall_info, &height, angle, FALSE);
} else {
f32 diff = dist - check_dist;
if (diff > 0.0f && diff < 2.7f) {
mCoBG_WallHeight_c height;
s16 angle = atans_table(dz, dx);
height.top = col->height;
height.bot = col->pos.y;
mCoBG_RegistCollisionWallInfo(actor_info, actor_info->wall_info, &height, angle, FALSE);
}
}
}
}
static void mCoBG_ColumnCheckOldOnGround_AttrWall(xyz_t* rev, mCoBG_ActorInf_c* actor_info, const xyz_t* pos, const xyz_t* old_pos, mCoBG_column_c* col) {
if (mCoBG_JudgePointInCircle_Xyz(old_pos, &col->pos, col->radius) == FALSE) {
f32 dx = pos->x - col->pos.x;
f32 dz = pos->z - col->pos.z;
f32 dist = sqrtf(SQ(dx) + SQ(dz));
f32 check_dist = actor_info->range + col->radius;
if (dist < check_dist) {
xyz_t rev_vec;
f32 rev_dist = check_dist - dist;
xyz_t rev_unit_vec;
s16 angle = atans_table(dz, dx);
f32 div;
rev_vec.x = pos->x - col->pos.x;
rev_vec.y = 0.0f;
rev_vec.z = pos->z - col->pos.z;
if (F32_IS_ZERO(dist)) {
div = 1.0f;
} else {
div = 1.0f / dist;
}
rev_unit_vec.x = rev_vec.x * div;
rev_unit_vec.y = 0.0f;
rev_unit_vec.z = rev_vec.z * div;
rev->x = rev_unit_vec.x * rev_dist;
rev->y = rev_unit_vec.y * rev_dist;
rev->z = rev_unit_vec.z * rev_dist;
mCoBG_RegistCollisionWallInfo(actor_info, actor_info->wall_info, NULL, angle, TRUE);
} else {
f32 diff = dist - check_dist;
if (diff > 0.0f && diff < 2.7f) {
s16 angle = atans_table(dz, dx);
mCoBG_RegistCollisionWallInfo(actor_info, actor_info->wall_info, NULL, angle, TRUE);
}
}
}
}
static void mCoBG_ColumnCheckNotOldOnGround_AttrWall(xyz_t* rev, mCoBG_ActorInf_c* actor_info, const xyz_t* pos, const xyz_t* old_pos, mCoBG_column_c* col) {
// nothing
}
typedef void (*mCoBG_ATR_COLUMN_SUB_PROC)(xyz_t* rev, mCoBG_ActorInf_c* actor_info, const xyz_t* pos, const xyz_t* old_pos, mCoBG_column_c* col);
static void mCoBG_ColumnCheck_AttrWall(xyz_t* rev, mCoBG_ActorInf_c* actor_info, const xyz_t* pos, const xyz_t* old_pos, mCoBG_column_c* col, s16 attr_wall) {
if (attr_wall != FALSE) {
static mCoBG_ATR_COLUMN_SUB_PROC atr_column_sub_proc_table[] = { &mCoBG_ColumnCheckNotOldOnGround_AttrWall, &mCoBG_ColumnCheckOldOnGround_AttrWall };
(*atr_column_sub_proc_table[actor_info->old_on_ground])(rev, actor_info, pos, old_pos, col);
}
}
typedef void (*mCoBG_WALL_CHECK_PROC)(xyz_t* rev, mCoBG_ActorInf_c* actor_info, const xyz_t* pos, const xyz_t* old_pos, mCoBG_column_c* col, s16 attr_wall);
static void mCoBG_ColumnWallCheck(xyz_t* rev, mCoBG_ActorInf_c* actor_info, const xyz_t* pos, mCoBG_column_c* col, int col_count, s16 attr_wall) {
static mCoBG_WALL_CHECK_PROC column_wall_check_func[] = { &mCoBG_ColumnCheck_NormalWall, &mCoBG_ColumnCheck_AttrWall };
static xyz_t reverse0 = { 0.0f, 0.0f, 0.0f };
*rev = reverse0;
if (col_count != 0) {
int i;
for (i = 0; i < col_count; i++) {
xyz_t reverse = { 0.0f, 0.0f, 0.0f };
xyz_t tmp_pos;
tmp_pos.x = pos->x + rev->x;
tmp_pos.y = pos->y + rev->y;
tmp_pos.z = pos->z + rev->z;
(*column_wall_check_func[col->atr_wall])(&reverse, actor_info, &tmp_pos, &actor_info->old_center_pos, col, attr_wall);
rev->x += reverse.x;
rev->z += reverse.z;
rev->y = 0.0f;
col++;
}
}
}
static f32 mCoBG_GetBGHeight_Column(const xyz_t* pos, mCoBG_UnitInfo_c* ut_info) {
mCoBG_column_c col;
if (mCoBG_MakeOneColumnCollisionData(&col, ut_info, FALSE, NULL, -1, -1) && mCoBG_JudgePointInCircle_Xyz(pos, &col.pos, col.radius)) {
return col.height;
}
return 0.0f;
}
static int mCoBG_LineWallCheck_Column(xyz_t* rev, mCoBG_column_c* col, int col_count, const xyz_t* start_pos, const xyz_t* end_pos) {
int i;
xyz_t vec_end_start;
xyz_t tmp_end;
static xyz_t reverse0 = { 0.0f, 0.0f, 0.0f };
xyz_t reverse = reverse0;
for (i = 0; i < col_count; i++) {
f32 vec_end_start_len_xz;
tmp_end.x = end_pos->x + reverse.x;
tmp_end.y = end_pos->y + reverse.y;
tmp_end.z = end_pos->z + reverse.z;
reverse = reverse0;
vec_end_start.x = start_pos->x - tmp_end.x;
vec_end_start.y = start_pos->y - tmp_end.y;
vec_end_start.z = start_pos->z - tmp_end.z;
vec_end_start_len_xz = sqrtf(SQ(vec_end_start.x) + SQ(vec_end_start.z));
if (!F32_IS_ZERO(vec_end_start_len_xz)) {
xyz_t cross0;
xyz_t cross1;
if (mCoBG_JudgePointInCircle_Xyz(start_pos, &col->pos, col->radius) == FALSE &&
mCoBG_GetCrossCircleAndLine2DvectorPlaneXZ_Xyz(&cross0, &cross1, start_pos, &vec_end_start, &col->pos, col->radius)) {
f32 rev_dist_xz;
xyz_t reverse_vec;
xyz_t delta_cross0_xz;
xyz_t delta_cross1_xz;
f32 dist_sq_cross0_xz;
f32 dist_sq_cross1_xz;
delta_cross0_xz.x = cross0.x - start_pos->x;
delta_cross0_xz.z = cross0.z - start_pos->z;
delta_cross1_xz.x = cross1.x - start_pos->x;
delta_cross1_xz.z = cross1.z - start_pos->z;
dist_sq_cross0_xz = SQ(delta_cross0_xz.x) + SQ(delta_cross0_xz.z);
dist_sq_cross1_xz = SQ(delta_cross1_xz.x) + SQ(delta_cross1_xz.z);
if (dist_sq_cross0_xz < dist_sq_cross1_xz) {
if (((cross0.x >= start_pos->x && cross0.x <= tmp_end.x) || (cross0.x >= tmp_end.x && cross0.x <= start_pos->x)) &&
((cross0.z >= start_pos->z && cross0.z <= tmp_end.z) || (cross0.z >= tmp_end.z && cross0.z <= start_pos->z))
) {
f32 mult;
rev_dist_xz = vec_end_start_len_xz - sqrtf(dist_sq_cross0_xz);
mult = rev_dist_xz / vec_end_start_len_xz;
reverse_vec.x = vec_end_start.x * mult;
reverse_vec.y = vec_end_start.y * mult;
reverse_vec.z = vec_end_start.z * mult;
if ((end_pos->y + reverse_vec.y) <= col->height) {
*rev = reverse_vec;
return TRUE;
}
}
} else {
if (((cross1.x >= start_pos->x && cross1.x <= tmp_end.x) || (cross1.x >= tmp_end.x && cross1.x <= start_pos->x)) &&
((cross1.z >= start_pos->z && cross1.z <= tmp_end.z) || (cross1.z >= tmp_end.z && cross1.z <= start_pos->z))
) {
f32 mult;
rev_dist_xz = vec_end_start_len_xz - sqrtf(dist_sq_cross1_xz);
mult = rev_dist_xz / vec_end_start_len_xz;
reverse_vec.x = vec_end_start.x * mult;
reverse_vec.y = vec_end_start.y * mult;
reverse_vec.z = vec_end_start.z * mult;
if ((end_pos->y + reverse_vec.y) <= col->height) {
*rev = reverse_vec;
return TRUE;
}
}
}
}
col++;
}
}
return FALSE;
}
static int mCoBG_LineGroundCheck_Column(xyz_t* rev, mCoBG_column_c* col, int col_count, const xyz_t* start_pos, const xyz_t* end_pos) {
int i;
static xyz_t reverse0; // @BUG - isn't this supposed to be initialized with data?
xyz_t reverse;
xyz_t tmp_end;
xyz_t vec_end_start;
reverse = reverse0;
for (i = 0; i < col_count; i++) {
if (start_pos->y > col->height && end_pos->y < col->height) {
f32 vec_y;
tmp_end.x = end_pos->x + reverse.x;
tmp_end.y = end_pos->y + reverse.y;
tmp_end.z = end_pos->z + reverse.z;
reverse = reverse0;
vec_end_start.x = start_pos->x - tmp_end.x;
vec_end_start.y = start_pos->y - tmp_end.y;
vec_end_start.z = start_pos->z - tmp_end.z;
vec_y = col->height - tmp_end.y;
if (!F32_IS_ZERO(vec_end_start.y)) {
f32 mult = vec_y / vec_end_start.y;
reverse.x = vec_end_start.x * mult;
reverse.y = vec_end_start.y * mult;
reverse.z = vec_end_start.z * mult;
*rev = reverse;
return TRUE;
}
return FALSE;
}
col++;
}
return FALSE;
}
File diff suppressed because it is too large Load Diff
+593
View File
@@ -0,0 +1,593 @@
static void mCoBG_GetSpeedXZ(f32* speed, xyz_t* start, xyz_t* end) {
speed[0] = end->x - start->x;
speed[1] = end->z - start->z;
}
static void mCoBG_TransCenter(int* x, int* z, f32* speed, int ut_count) {
int count = ut_count >> 1;
if (!F32_IS_ZERO(speed[0])) {
if (speed[0] > 0.0f) {
(*x) += count;
} else {
(*x) -= count;
}
}
if (!F32_IS_ZERO(speed[1])) {
if (speed[1] > 0.0f) {
(*z) += count;
} else {
(*z) -= count;
}
}
}
static int mCoBG_UvecInf2PolygonVtx(xyz_t* v0, xyz_t* v1, xyz_t* v2, int idx, mCoBG_unit_vec_info_c* unit_vec) {
switch (idx & 1) {
case 0:
if (unit_vec->wall_bounds.start_top != unit_vec->wall_bounds.start_btm) {
v0->x = unit_vec->start[0];
v0->y = unit_vec->wall_bounds.start_top;
v0->z = unit_vec->start[1];
v1->x = unit_vec->start[0];
v1->y = unit_vec->wall_bounds.start_btm;
v1->z = unit_vec->start[1];
v2->x = unit_vec->end[0];
v2->y = unit_vec->wall_bounds.end_top;
v2->z = unit_vec->end[1];
return TRUE;
}
break;
case 1:
default:
if (unit_vec->wall_bounds.end_top != unit_vec->wall_bounds.end_btm) {
v0->x = unit_vec->end[0];
v0->y = unit_vec->wall_bounds.end_top;
v0->z = unit_vec->end[1];
v1->x = unit_vec->start[0];
v1->y = unit_vec->wall_bounds.start_btm;
v1->z = unit_vec->start[1];
v2->x = unit_vec->end[0];
v2->y = unit_vec->wall_bounds.end_btm;
v2->z = unit_vec->end[1];
return TRUE;
}
break;
}
return FALSE;
}
static int mCoBG_GetRevWallPlaneAndVector(xyz_t* rev, mCoBG_unit_vec_info_c* unit_vec, xyz_t start_pos, xyz_t end_pos, f32* start, f32* end) {
xyz_t rev0 = { 0.0f, 0.0f, 0.0f };
*rev = rev0;
if (mCoBG_SearchWallFront(start, unit_vec) == TRUE && mCoBG_SearchWallFront(end, unit_vec) == FALSE) {
xyz_t v0;
xyz_t v1;
xyz_t v2;
xyz_t cross;
int i;
for (i = 0; i < 2; i++) {
if (mCoBG_UvecInf2PolygonVtx(&v0, &v1, &v2, i, unit_vec)) {
if (mCoBG_GetCrossTriangleAndLine3D(&cross, v0, v1, v2, start_pos, end_pos)) {
rev->x = cross.x - end_pos.x;
rev->y = cross.y - end_pos.y;
rev->z = cross.z - end_pos.z;
return TRUE;
}
}
}
}
return FALSE;
}
static int mCoBG_LineWallCheck(xyz_t* rev, xyz_t start_pos, xyz_t end_pos) {
int i;
int count = l_VecInf.unit_count;
mCoBG_unit_vec_info_c* unit_vec = l_VecInf.unit;
f32 start[2];
f32 end[2];
start[0] = start_pos.x;
start[1] = start_pos.z;
end[0] = end_pos.x;
end[1] = end_pos.z;
for (i = 0; i < count; i++) {
xyz_t tmp_rev = { 0.0f, 0.0f, 0.0f };
if (mCoBG_GetRevWallPlaneAndVector(&tmp_rev, unit_vec, start_pos, end_pos, start, end)) {
rev->x = tmp_rev.x;
rev->y = tmp_rev.y;
rev->z = tmp_rev.z;
return TRUE;
}
unit_vec++;
}
return FALSE;
}
static void mCoBG_GetAreaPolygon(xyz_t* v0, xyz_t* v1, xyz_t* v2, mCoBG_UnitInfo_c* ut_info, int area) {
mCoBG_Collision_u* col = ut_info->collision;
f32 x = ut_info->ut_x * mFI_UT_WORLDSIZE_X_F;
f32 z = ut_info->ut_z * mFI_UT_WORLDSIZE_Z_F;
f32 center_y = col->data.center * 10.0f + ut_info->base_height;
if (ut_info->slate_flag == FALSE) {
switch (area) {
case mCoBG_AREA_N:
v0->x = x;
v0->y = ut_info->leftUp_offset;
v0->z = z;
v1->x = x + mFI_UT_WORLDSIZE_HALF_X_F;
v1->y = center_y;
v1->z = z + mFI_UT_WORLDSIZE_HALF_Z_F;
v2->x = x + mFI_UT_WORLDSIZE_X_F;
v2->y = ut_info->rightUp_offset;
v2->z = z;
break;
case mCoBG_AREA_W:
v0->x = x;
v0->y = ut_info->leftUp_offset;
v0->z = z;
v1->x = x;
v1->y = ut_info->leftDown_offset;
v1->z = z + mFI_UT_WORLDSIZE_Z_F;
v2->x = x + mFI_UT_WORLDSIZE_HALF_X_F;
v2->y = center_y;
v2->z = z + mFI_UT_WORLDSIZE_HALF_Z_F;
break;
case mCoBG_AREA_S:
v0->x = x + mFI_UT_WORLDSIZE_HALF_X_F;
v0->y = center_y;
v0->z = z + mFI_UT_WORLDSIZE_HALF_Z_F;
v1->x = x;
v1->y = ut_info->leftDown_offset;
v2->z = z + mFI_UT_WORLDSIZE_Z_F;
v2->x = x + mFI_UT_WORLDSIZE_X_F;
v2->y = ut_info->rightDown_offset;
v1->z = z + mFI_UT_WORLDSIZE_Z_F;
break;
default:
// case mCoBG_AREA_E:
v0->x = x + mFI_UT_WORLDSIZE_HALF_X_F;
v0->y = center_y;
v0->z = z + mFI_UT_WORLDSIZE_HALF_Z_F;
v1->x = x + mFI_UT_WORLDSIZE_X_F;
v1->y = ut_info->rightDown_offset;
v1->z = z + mFI_UT_WORLDSIZE_Z_F;
v2->x = x + mFI_UT_WORLDSIZE_X_F;
v2->y = ut_info->rightUp_offset;
v2->z = z;
break;
}
} else {
switch (area) {
case mCoBG_AREA_N:
v0->x = x;
v0->y = ut_info->leftUp_offset;
v0->z = z;
v1->x = x + mFI_UT_WORLDSIZE_HALF_X_F;
v1->y = center_y;
v1->z = z + mFI_UT_WORLDSIZE_HALF_Z_F;
v2->x = x + mFI_UT_WORLDSIZE_X_F;
v2->y = ut_info->rightUp_offset;
v2->z = z;
if (ut_info->leftUp_offset < ut_info->rightUp_offset) {
v0->y = v1->y;
v2->y = v1->y;
} else if (ut_info->leftUp_offset > ut_info->rightUp_offset) {
v0->y = v2->y;
v1->y = v2->y;
}
break;
case mCoBG_AREA_W:
v0->x = x;
v0->y = ut_info->leftUp_offset;
v0->z = z;
v1->x = x;
v1->y = ut_info->leftDown_offset;
v1->z = z + mFI_UT_WORLDSIZE_Z_F;
v2->x = x + mFI_UT_WORLDSIZE_HALF_X_F;
v2->y = center_y;
v2->z = z + mFI_UT_WORLDSIZE_HALF_Z_F;
if (ut_info->leftUp_offset > ut_info->leftDown_offset) {
v0->y = v1->y;
// @BUG - this should be v2->y = v1->y
#ifndef BUGFXIES
v0->y = v1->y;
#else
v2->y = v1->y;
#endif
} else if (ut_info->leftUp_offset < ut_info->leftDown_offset) {
v1->y = v0->y;
v2->y = v0->y;
}
break;
case mCoBG_AREA_S:
v0->x = x + mFI_UT_WORLDSIZE_HALF_X_F;
v0->y = center_y;
v0->z = z + mFI_UT_WORLDSIZE_HALF_Z_F;
v1->x = x;
v1->y = ut_info->leftDown_offset;
v2->z = z + mFI_UT_WORLDSIZE_Z_F;
v2->x = x + mFI_UT_WORLDSIZE_X_F;
v2->y = ut_info->rightDown_offset;
v1->z = z + mFI_UT_WORLDSIZE_Z_F;
if (ut_info->leftDown_offset < ut_info->rightDown_offset) {
v0->y = v1->y;
v2->y = v1->y;
} else if (ut_info->leftDown_offset > ut_info->rightDown_offset) {
v0->y = v2->y;
v1->y = v2->y;
}
break;
// case mCoBG_AREA_E:
default:
v0->x = x + mFI_UT_WORLDSIZE_HALF_X_F;
v0->y = center_y;
v0->z = z + mFI_UT_WORLDSIZE_HALF_Z_F;
v1->x = x + mFI_UT_WORLDSIZE_X_F;
v1->y = ut_info->rightDown_offset;
v1->z = z + mFI_UT_WORLDSIZE_Z_F;
v2->x = x + mFI_UT_WORLDSIZE_X_F;
v2->y = ut_info->rightUp_offset;
v2->z = z;
if (ut_info->rightUp_offset < ut_info->rightDown_offset) {
v0->y = v2->y;
v1->y = v2->y;
} else if (ut_info->rightUp_offset > ut_info->rightDown_offset) {
v0->y = v1->y;
v2->y = v1->y;
}
break;
}
}
}
static void mCoBG_GetFlatGroundPolygon(xyz_t* v0, xyz_t* v1, xyz_t* v2, f32 bg_y, f32 x, f32 z, int type) {
static xyz_t offset_from_base[][3] = {
{ { 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 40.0f}, {40.0f, 0.0f, 0.0f} },
{ {40.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 40.0f}, {40.0f, 0.0f, 40.0f} },
};
xyz_t* ofs = offset_from_base[type & 1];
v0->x = x + ofs[0].x;
v0->y = bg_y;
v0->z = z + ofs[0].z;
v1->x = x + ofs[1].x;
v1->y = bg_y;
v1->z = z + ofs[1].z;
v2->x = x + ofs[2].x;
v2->y = bg_y;
v2->z = z + ofs[2].z;
}
static int mCoBG_GetRevGroundAndLine(xyz_t* rev, mCoBG_UnitInfo_c* ut_info, xyz_t start_pos, xyz_t end_pos) {
xyz_t v0;
xyz_t v1;
xyz_t v2;
xyz_t cross = { 0.0f, 0.0f, 0.0f };
int area;
f32 a;
f32 b;
f32 c;
f32 d;
f32 dist_start;
f32 dist_end;
if (
// clang-format off
ut_info->collision->data.center == ut_info->collision->data.top_left &&
ut_info->collision->data.center == ut_info->collision->data.bot_left &&
ut_info->collision->data.center == ut_info->collision->data.bot_right &&
ut_info->collision->data.center == ut_info->collision->data.top_right
// clang-format on
) {
f32 bg_y;
f32 x;
f32 z;
int i;
if (start_pos.y >= end_pos.y) {
bg_y = ut_info->leftUp_offset;
x = ut_info->ut_x * mFI_UT_WORLDSIZE_X_F;
z = ut_info->ut_z * mFI_UT_WORLDSIZE_Z_F;
for (i = 0; i < 2; i++) {
mCoBG_GetFlatGroundPolygon(&v0, &v1, &v2, bg_y, x, z, i);
Math3DPlane(&v0, &v1, &v2, &a, &b, &c, &d);
dist_start = Math3DSignedLengthPlaneAndPos(a, b, c, d, &start_pos);
dist_end = Math3DSignedLengthPlaneAndPos(a, b, c, d, &end_pos);
if (dist_start >= 0.0f && dist_end <= 0.0f) {
if (mCoBG_GetCrossTriangleAndLine3D(&cross, v0, v1, v2, start_pos, end_pos)) {
rev->x = cross.x - end_pos.x;
rev->y = cross.y - end_pos.y;
rev->z = cross.z - end_pos.z;
return TRUE;
}
}
}
}
} else {
for (area = mCoBG_AREA_N; area < mCoBG_AREA_NUM; area++) {
mCoBG_GetAreaPolygon(&v0, &v1, &v2, ut_info, area);
Math3DPlane(&v0, &v1, &v2, &a, &b, &c, &d);
dist_start = Math3DSignedLengthPlaneAndPos(a, b, c, d, &start_pos);
dist_end = Math3DSignedLengthPlaneAndPos(a, b, c, d, &end_pos);
if (dist_start >= 0.0f && dist_end <= 0.0f) {
if (mCoBG_GetCrossTriangleAndLine3D(&cross, v0, v1, v2, start_pos, end_pos)) {
rev->x = cross.x - end_pos.x;
rev->y = cross.y - end_pos.y;
rev->z = cross.z - end_pos.z;
return TRUE;
}
}
}
}
return FALSE;
}
static int mCoBG_LineGroundCheck_Move(xyz_t* rev, xyz_t* start_pos, xyz_t* end_pos) {
mCoBG_bg_regist_c* regist_p;
mCoBG_mBgMgr_c* bg_mgr = &l_mBgMgr;
mCoBG_bg_regist_c** regist_pp = bg_mgr->regist_p;
xyz_t ofs;
xyz_t p0;
xyz_t p1;
xyz_t p2;
xyz_t p3;
xyz_t v0;
xyz_t v1;
xyz_t v2;
xyz_t v3;
xyz_t cross;
f32 a;
f32 b;
f32 c;
f32 d;
f32 dist_start;
f32 dist_end;
f32 start[2];
f32 end[2];
f32 point[2];
int i;
mCoBG_bg_size_c* size_p;
f32 rate;
xyz_t* pos_p;
s16 angle;
start[0] = start_pos->x;
start[1] = start_pos->z;
end[0] = end_pos->x;
end[1] = end_pos->z;
if (bg_mgr->count != 0) {
for (i = 0; i < mCoBG_MOVE_REGIST_MAX; i++) {
regist_p = *regist_pp; // might be regist_pp[i]
if (regist_p != NULL) {
static xyz_t xyz0 = { 0.0f, 0.0f, 0.0f };
size_p = regist_p->bg_size;
ofs = regist_p->base_ofs != NULL ? *regist_p->base_ofs : xyz0;
angle = regist_p->angle_y != NULL ? *regist_p->angle_y : 0;
rate = regist_p->scale_percent != NULL ? *regist_p->scale_percent : 1.0f;
pos_p = regist_p->wpos;
point[0] = pos_p->x;
point[1] = pos_p->z;
if (mCoBG_JudgeMoveBgGroundCheck(point, start, regist_p->active_dist) || mCoBG_JudgeMoveBgGroundCheck(point, end, regist_p->active_dist)) {
Matrix_translate(pos_p->x, pos_p->y, pos_p->z, 0);
Matrix_RotateY(angle, 1);
Matrix_translate(ofs.x, ofs.y, ofs.z, 1);
p0 = xyz0;
p1 = xyz0;
p2 = xyz0;
p3 = xyz0;
p0.x -= size_p->left_size * rate;
p0.z -= size_p->up_size * rate;
p0.y += regist_p->height;
Matrix_Position(&p0, &v0);
p1.x -= size_p->left_size * rate;
p1.z += size_p->down_size * rate;
p1.y += regist_p->height;
Matrix_Position(&p1, &v1);
p2.x += size_p->right_size * rate;
p2.z += size_p->down_size * rate;
p2.y += regist_p->height;
Matrix_Position(&p2, &v2);
p3.x += size_p->right_size * rate;
p3.z -= size_p->up_size * rate;
p3.y += regist_p->height;
Matrix_Position(&p3, &v3);
Math3DPlane(&v0, &v1, &v2, &a, &b, &c, &d);
dist_start = Math3DSignedLengthPlaneAndPos(a, b, c, d, start_pos);
dist_end = Math3DSignedLengthPlaneAndPos(a, b, c, d, end_pos);
if (dist_start >= 0.0f && dist_end <= 0.0f) {
if (mCoBG_GetCrossTriangleAndLine3D(&cross, v0, v1, v2, *start_pos, *end_pos)) {
rev->x = cross.x - end_pos->x;
rev->y = cross.y - end_pos->y;
rev->z = cross.z - end_pos->z;
return TRUE;
}
}
Math3DPlane(&v0, &v2, &v3, &a, &b, &c, &d);
dist_start = Math3DSignedLengthPlaneAndPos(a, b, c, d, start_pos);
dist_end = Math3DSignedLengthPlaneAndPos(a, b, c, d, end_pos);
if (dist_start >= 0.0f && dist_end <= 0.0f) {
if (mCoBG_GetCrossTriangleAndLine3D(&cross, v0, v2, v3, *start_pos, *end_pos)) {
rev->x = cross.x - end_pos->x;
rev->y = cross.y - end_pos->y;
rev->z = cross.z - end_pos->z;
return TRUE;
}
}
}
regist_pp++;
}
}
}
return FALSE;
}
static int mCoBG_LineGroundCheck(xyz_t* rev, xyz_t start_pos, xyz_t end_pos) {
mCoBG_UnitInfo_c* ut_info = l_crtutInf;
int i;
xyz_t ground_rev = { 0.0f, 0.0f, 0.0f };
xyz_t move_rev = { 0.0f, 0.0f, 0.0f };
for (i = 0; i < 9; i++) {
if (mCoBG_GetRevGroundAndLine(&ground_rev, ut_info, start_pos, end_pos)) {
*rev = ground_rev;
return TRUE;
}
ut_info++;
}
if (mCoBG_LineGroundCheck_Move(&move_rev, &start_pos, &end_pos)) {
*rev = move_rev;
return TRUE;
}
return FALSE;
}
static void mCoBG_MakeLineCheckCollisionData(xyz_t start_pos, xyz_t end_pos) {
int ux;
int uz;
f32 speed[2];
mCoBG_GetSpeedXZ(speed, &start_pos, &end_pos);
mFI_Wpos2UtNum(&ux, &uz, start_pos);
mCoBG_TransCenter(&ux, &uz, speed, 3);
mCoBG_MakeSizeUnitInfo(l_crtutInf, ux, uz, 3);
mCoBG_MakeUnitVector(&l_VecInf, l_crtutInf, 3, mCoBG_CHECK_TYPE_NORMAL, TRUE, FALSE, FALSE);
}
static int mCoBG_JudgeStartLineCheck(xyz_t* rev, xyz_t start_pos, xyz_t end_pos) {
if (rev != NULL) {
mCoBG_InitRevpos(rev);
}
if (F32_IS_ZERO(start_pos.x - end_pos.x) && F32_IS_ZERO(start_pos.y - end_pos.y) && F32_IS_ZERO(start_pos.z - end_pos.z)) {
return FALSE;
}
return TRUE;
}
static void mCoBG_SetWallGroundReverse(xyz_t* rev, const xyz_t* wall_rev, const xyz_t* ground_rev, const xyz_t* wall_col_rev, const xyz_t* ground_col_rev) {
if (rev != NULL) {
rev->x = wall_rev->x + ground_rev->x + wall_col_rev->x + ground_col_rev->x;
rev->y = wall_rev->y + ground_rev->y + wall_col_rev->y + ground_col_rev->y;
rev->z = wall_rev->z + ground_rev->z + wall_col_rev->z + ground_col_rev->z;
}
}
extern int mCoBG_LineCheck_RemoveFg(xyz_t* rev, xyz_t start_pos, xyz_t end_pos, mCoBG_COLUMN_CHECK_ITEM_TYPE_PROC check_proc, int line_check_type) {
int ret = 0;
bzero(l_crtutInf, sizeof(l_crtutInf));
bzero(&l_VecInf, sizeof(l_VecInf));
if (mCoBG_JudgeStartLineCheck(rev, start_pos, end_pos)) {
xyz_t wall_rev = { 0.0f, 0.0f, 0.0f };
xyz_t ground_rev = { 0.0f, 0.0f, 0.0f };
xyz_t wall_col_rev = { 0.0f, 0.0f, 0.0f };
xyz_t ground_col_rev = { 0.0f, 0.0f, 0.0f };
mCoBG_MakeLineCheckCollisionData(start_pos, end_pos);
mCoBG_MakeMoveBgVector(&l_VecInf, &l_mBgMgr, &end_pos, mCoBG_CHECK_TYPE_PLAYER);
mCoBG_MakeColumnCollisionData(l_VecInf.column, &l_VecInf.col_count, l_crtutInf, 3, FALSE, check_proc, -1, -1);
if ((line_check_type & mCoBG_LINE_CHECK_WALL) != 0) {
if (mCoBG_LineWallCheck(&wall_rev, start_pos, end_pos)) {
ret |= mCoBG_LINE_CHECK_WALL;
}
mCoBG_PlusEqualPos(&end_pos, &wall_rev);
if (mCoBG_LineWallCheck_Column(&wall_col_rev, l_VecInf.column, l_VecInf.col_count, &start_pos, &end_pos)) {
ret |= mCoBG_LINE_CHECK_WALL;
}
mCoBG_PlusEqualPos(&end_pos, &wall_col_rev);
}
if ((line_check_type & mCoBG_LINE_CHECK_GROUND) != 0) {
if (mCoBG_LineGroundCheck(&ground_rev, start_pos, end_pos)) {
ret |= mCoBG_LINE_CHECK_GROUND;
}
mCoBG_PlusEqualPos(&end_pos, &ground_rev);
if (mCoBG_LineGroundCheck_Column(&ground_col_rev, l_VecInf.column, l_VecInf.col_count, &start_pos, &end_pos)) {
ret |= mCoBG_LINE_CHECK_GROUND;
}
mCoBG_PlusEqualPos(&end_pos, &ground_col_rev);
}
if ((line_check_type & mCoBG_LINE_CHECK_WATER) != 0) {
if ((end_pos.y <= 21.0f && start_pos.y >= 19.0f) || (start_pos.y <= 21.0f && end_pos.y >= 19.0f)) {
ret |= mCoBG_LINE_CHECK_WATER;
} else {
if (mCoBG_CheckWaterAttribute(mCoBG_Wpos2Attribute(end_pos, NULL))) {
f32 water_y = mCoBG_GetWaterHeight_File(end_pos, __FILE__, 880);
if (end_pos.y <= water_y + 1.0f) {
ret |= mCoBG_LINE_CHECK_UNDERWATER;
}
}
}
}
mCoBG_SetWallGroundReverse(rev, &wall_rev, &ground_rev, &wall_col_rev, &ground_col_rev);
}
return ret;
}
+500
View File
@@ -0,0 +1,500 @@
extern void mCoBG_RotateY(f32* pos, f32 rad) {
f32 p[2];
f32 cos;
f32 sin;
cos = cosf_table(rad);
sin = sinf_table(rad);
p[0] = pos[0];
p[1] = pos[1];
pos[0] = p[0] * cos + p[1] * sin;
pos[1] = -p[0] * sin + p[1] * cos;
}
extern f32 mCoBG_GetVectorProductin2D(f32* vec0_xz, f32* vec1_xz) {
return vec0_xz[0] * vec1_xz[1] - vec0_xz[1] * vec1_xz[0];
}
static void mCoBG_JudgeCrossTriangleAndLine2D_XY(f32* m0, f32* m1, const xyz_t* v0, const xyz_t* v1, const xyz_t* v2) {
*m0 = (v0->x * v1->y - v0->y * v1->x) * (v0->x * v2->y - v0->y * v2->x);
*m1 = (v2->x * v0->y - v2->y * v0->x) * (v2->x * v1->y - v2->y * v1->x);
}
static void mCoBG_JudgeCrossTriangleAndLine2D_XZ(f32* m0, f32* m1, const xyz_t* v0, const xyz_t* v1, const xyz_t* v2) {
*m0 = (v0->x * v1->z - v0->z * v1->x) * (v0->x * v2->z - v0->z * v2->x);
*m1 = (v2->x * v0->z - v2->z * v0->x) * (v2->x * v1->z - v2->z * v1->x);
}
static void mCoBG_JudgeCrossTriangleAndLine2D_YZ(f32* m0, f32* m1, const xyz_t* v0, const xyz_t* v1, const xyz_t* v2) {
*m0 = (v0->y * v1->z - v0->z * v1->y) * (v0->y * v2->z - v0->z * v2->y);
*m1 = (v2->y * v0->z - v2->z * v0->y) * (v2->y * v1->z - v2->z * v1->y);
}
typedef void (*mCoBG_PRO_DIMENSION_PROC)(f32* m0, f32* m1, const xyz_t* v0, const xyz_t* v1, const xyz_t* v2);
static mCoBG_PRO_DIMENSION_PROC mCoBG_pro_dimension_proc[] = {
&mCoBG_JudgeCrossTriangleAndLine2D_XY,
&mCoBG_JudgeCrossTriangleAndLine2D_XZ,
&mCoBG_JudgeCrossTriangleAndLine2D_YZ,
NULL,
};
extern int mCoBG_JudgeCrossTriangleAndLine2D(xyz_t v0, xyz_t v1, xyz_t v2, xyz_t p, int dim) {
xyz_t vec0;
xyz_t vec1;
xyz_t vec2;
vec0.x = v0.x - p.x;
vec0.y = v0.y - p.y;
vec0.z = v0.z - p.z;
vec1.x = v1.x - p.x;
vec1.y = v1.y - p.y;
vec1.z = v1.z - p.z;
vec2.x = v2.x - p.x;
vec2.y = v2.y - p.y;
vec2.z = v2.z - p.z;
// Doesn't this mean the mCoBG_DIM_ALL path can never be hit?
if (CLAMP(dim, 0, dim) > mCoBG_DIM_YZ) {
dim = mCoBG_DIM_YZ;
} else {
dim = CLAMP(dim, 0, dim);
}
if (dim == mCoBG_DIM_ALL) {
f32 m0;
f32 m1;
(*mCoBG_pro_dimension_proc[mCoBG_DIM_XZ])(&m0, &m1, &vec0, &vec1, &vec2);
if (m0 <= 0.0f && m1 <= 0.0f) {
(*mCoBG_pro_dimension_proc[mCoBG_DIM_XY])(&m0, &m1, &vec0, &vec1, &vec2);
if (m0 <= 0.0f && m1 <= 0.0f) {
(*mCoBG_pro_dimension_proc[mCoBG_DIM_YZ])(&m0, &m1, &vec0, &vec1, &vec2);
if (m0 <= 0.0f && m1 <= 0.0f) {
return TRUE;
}
}
}
} else {
f32 m0 = 0.0f;
f32 m1 = 0.0f;
(*mCoBG_pro_dimension_proc[dim])(&m0, &m1, &vec0, &vec1, &vec2);
if (m0 <= 0.0f && m1 <= 0.0f) {
return TRUE;
}
}
return FALSE;
}
extern int mCoBG_GetDimension2Idx(f32 p0, f32 p1, f32 p2) {
if (F32_IS_ZERO(p0) && F32_IS_ZERO(p2)) {
return mCoBG_DIM_XZ;
}
if (F32_IS_ZERO(p0) && F32_IS_ZERO(p1)) {
return mCoBG_DIM_XY;
}
if (F32_IS_ZERO(p1) && F32_IS_ZERO(p2)) {
return mCoBG_DIM_YZ;
}
return mCoBG_DIM_ALL;
}
extern int mCoBG_GetCrossTriangleAndLine3D(xyz_t* cross, xyz_t v0, xyz_t v1, xyz_t v2, xyz_t line0, xyz_t line1) {
f32 x;
f32 y;
f32 z;
f32 nox;
f32 noy;
f32 noz;
f32 dist;
f32 ldist;
f32 t;
f32 scale;
cross->x = 0.0f;
cross->y = 0.0f;
cross->z = 0.0f;
Math3DPlane(&v0, &v1, &v2, &nox, &noy, &noz, &dist);
t = (nox * line0.x + noy * line0.y + noz * line0.z) + dist;
x = line0.x - line1.x;
y = line0.y - line1.y;
z = line0.z - line1.z;
ldist = nox * x + noy * y + noz * z;
if (!F32_IS_ZERO(ldist)) {
int dim;
scale = -(t / ldist);
cross->x = line0.x + x * scale;
cross->y = line0.y + y * scale;
cross->z = line0.z + z * scale;
dim = mCoBG_GetDimension2Idx(nox, noy, noz);
return mCoBG_JudgeCrossTriangleAndLine2D(v0, v1, v2, *cross, dim);
}
return FALSE;
}
extern f32 mCoBG_GetVectorScalar2D(f32* v0, f32* v1) {
return v0[0] * v1[0] + v0[1] * v1[1];
}
extern int mCoBG_GetCrossJudge_2Vector(f32* vec0_p0, f32* vec0_p1, f32* vec1_p0, f32* vec1_p1) {
f32 v0[2];
f32 v1[2];
f32 v2[2];
f32 product0;
f32 product1;
v0[0] = vec1_p1[0] - vec0_p0[0];
v0[1] = vec1_p1[1] - vec0_p0[1];
v1[0] = vec0_p1[0] - vec0_p0[0];
v1[1] = vec0_p1[1] - vec0_p0[1];
v2[0] = vec1_p0[0] - vec0_p0[0];
v2[1] = vec1_p0[1] - vec0_p0[1];
product0 = mCoBG_GetVectorProductin2D(v1, v0) * mCoBG_GetVectorProductin2D(v1, v2);
v0[0] = vec0_p1[0] - vec1_p0[0];
v0[1] = vec0_p1[1] - vec1_p0[1];
v1[0] = vec1_p1[0] - vec1_p0[0];
v1[1] = vec1_p1[1] - vec1_p0[1];
v2[0] = vec0_p0[0] - vec1_p0[0];
v2[1] = vec0_p0[1] - vec1_p0[1];
product1 = mCoBG_GetVectorProductin2D(v1, v0) * mCoBG_GetVectorProductin2D(v1, v2);
if (product0 < 0.0f && product1 < 0.0f) {
return TRUE;
}
return FALSE;
}
extern void mCoBG_GetCross2Line(f32* cross,
f32* line0_p0,
f32* line0_p1,
f32* line1_p0,
f32* line1_p1)
{
f32 t;
f32 vec[2];
vec[0] = line0_p1[0] - line0_p0[0];
vec[1] = line0_p1[1] - line0_p0[1];
t =
(
( ( line1_p0[0] - line0_p0[0] ) * ( line1_p1[1] - line1_p0[1] ) ) +
( ( line1_p1[0] - line1_p0[0] ) * ( line0_p0[1] - line1_p0[1] ) )
)
/
(
( (line1_p1[1] - line1_p0[1]) * ( line0_p1[0] - line0_p0[0] ) ) -
( (line0_p1[1] - line0_p0[1]) * ( line1_p1[0] - line1_p0[0] ) )
);
cross[0] = line0_p0[0] + t * vec[0];
cross[1] = line0_p0[1] + t * vec[1];
}
extern f32 mCoBG_Get2VectorAngleF(f32* v0, f32* v1, u8 unit) {
if (v0[0] != 0.0f || v0[1] != 0.0f || v1[0] != 0.0f || v1[1] != 0.0f) {
switch (unit) {
case mCoBG_UNIT_RADIAN:
return atanf_table(mCoBG_GetVectorScalar2D(v0, v1), mCoBG_GetVectorProductin2D(v0, v1));
case mCoBG_UNIT_DEGREE:
return RAD2DEG(atanf_table(mCoBG_GetVectorScalar2D(v0, v1), mCoBG_GetVectorProductin2D(v0, v1)));
default:
return 1.0f;
}
}
return 1.0f;
}
// @unused, @fabricated
extern s16 mCoBG_Get2VectorAngleS(f32* v0, f32* v1) {
if (v0[0] != 0.0f || v0[1] != 0.0f || v1[0] != 0.0f || v1[1] != 0.0f) {
return atans_table(mCoBG_GetVectorScalar2D(v0, v1), mCoBG_GetVectorProductin2D(v0, v1));
}
return 1;
}
extern int mCoBG_GetCrossLineAndPerpendicular(f32* cross, f32* p0, f32* p1, f32* target) {
f32 vec[2];
f32 len;
f32 t;
vec[0] = p1[0] - p0[0];
vec[1] = p1[1] - p0[1];
len = SQ(vec[0]) + SQ(vec[1]);
if (len != 0.0f) {
t = (-vec[0] * (p0[0] - target[0]) + -vec[1] * (p0[1] - target[1])) / len;
cross[0] = p0[0] + t * vec[0];
cross[1] = p0[1] + t * vec[1];
return TRUE;
}
cross[0] = 0.0f;
cross[1] = 0.0f;
return FALSE;
}
extern int mCoBG_GetPointInfoFrontLine(f32* start, f32* point, f32* normal) {
f32 a = normal[0];
f32 b = normal[1];
f32 a2 = a * point[0];
f32 b2 = b * point[1];
f32 c = -(a * start[0] + b * start[1]);
if ((a2 + b2) + c >= 0.0f) {
return TRUE;
}
return FALSE;
}
/* @unused, @fabricated */
extern int mCoBG_GetDistPointAndLine2D(f32* dist, f32* line0, f32* line1, f32* point) {
f32 cross[2];
f32 dist_xy[2];
if (mCoBG_GetCrossLineAndPerpendicular(cross, line0, line1, point)) {
dist_xy[0] = point[0] - cross[0];
dist_xy[1] = point[1] - cross[1];
dist[0] = ABS(sqrtf(SQ(dist_xy[0]) + SQ(dist_xy[1])));
return TRUE;
}
dist[0] = 0.0f;
dist[1] = 0.0f;
return FALSE;
}
extern int mCoBG_GetDistPointAndLine2D_Norm(f32* dist, f32* line0, f32* line1, f32* normal, f32* point) {
f32 a = normal[0];
f32 b = normal[1];
f32 a2 = a * point[0];
f32 b2 = b * point[1];
f32 c = -(a * line0[0] + b * line0[1]);
f32 d = (a2 + b2) + c;
dist[0] = ABS(d);
return TRUE;
}
extern int mCoBG_GetCrossCircleAndLine2Dvector(f32* cross0, f32* cross1, f32* point, f32* vec, f32* center, f32 radius) {
// a = x^2 + y^2
f32 A = SQ(vec[0]) + SQ(vec[1]);
// b = 2 * ((vec.x * point.x) - (vec.x * center.x)) + ((vec.y * point.y) - (vec.y * center.y))
f32 B = 2.0f * (vec[0] * point[0] - vec[0] * center[0] + vec[1] * point[1] - vec[1] * center[1]);
// c = (point.x - center.x)^2 + (point.y - center.y)^2 - radius^2
f32 C = SQ(point[0] - center[0]) + SQ(point[1] - center[1]) - SQ(radius);
f32 R = SQ(B) - 4.0f*A*C; // b^2 - 4*a*c
f32 t0;
f32 t1;
if (R >= 0.0f) {
// sqrt(b^2 - 4*a*c)
f32 root = ABS(sqrtf(R));
if (A != 0.0f) {
// (-b +- sqrt(b^2 - 4*a*c)) / 2a
t0 = (-B + root) / (2.0f * A);
t1 = (-B - root) / (2.0f * A);
cross0[0] = point[0] + t0 * vec[0];
cross0[1] = point[1] + t0 * vec[1];
cross1[0] = point[0] + t1 * vec[0];
cross1[1] = point[1] + t1 * vec[1];
return TRUE;
}
}
return FALSE;
}
static int mCoBG_GetCrossCircleAndLine2DvectorPlaneXZ_Xyz(xyz_t* cross1, xyz_t* cross2, const xyz_t* point, const xyz_t* vec, const xyz_t* center, f32 radius) {
static xyz_t cross0 = { 0.0f, 0.0f, 0.0f };
f32 cross1_xz[2];
f32 cross2_xz[2];
f32 point_xz[2];
f32 vec_xz[2];
f32 center_xz[2];
*cross1 = cross0;
*cross2 = cross0;
point_xz[0] = point->x;
point_xz[1] = point->z;
vec_xz[0] = vec->x;
vec_xz[1] = vec->z;
center_xz[0] = center->x;
center_xz[1] = center->z;
if (mCoBG_GetCrossCircleAndLine2Dvector(cross1_xz, cross2_xz, point_xz, vec_xz, center_xz, radius)) {
cross1->x = cross1_xz[0];
cross1->z = cross1_xz[1];
cross2->x = cross2_xz[0];
cross2->z = cross2_xz[1];
return TRUE;
}
return FALSE;
}
// @unused, @fabricated
extern int mCoBG_GetCrossCircleAndLine2D(f32* cross0, f32* cross1, f32* p0, f32* p1, f32* center, f32 radius) {
f32 vec[2];
vec[0] = p1[0] - p0[0];
vec[1] = p1[1] - p0[1];
return mCoBG_GetCrossCircleAndLine2Dvector(cross0, cross1, p0, vec, center, radius);
}
// @unused, @fabricated
extern void mCoBG_GetReverseVector2D(f32* vec) {
vec[0] *= -1.0f;
vec[1] *= -1.0f;
}
// @unused, @fabricated
extern void mCoBG_GetUnitVector2D(f32* vec) {
f32 len = sqrtf(SQ(vec[0]) + SQ(vec[1]));
if (!F32_IS_ZERO(len)) {
vec[0] /= len;
vec[1] /= len;
}
}
extern int mCoBG_JudgePointInCircle_Xyz(const xyz_t* p, const xyz_t* center, f32 radius) {
f32 dx = p->x - center->x;
f32 dz = p->z - center->z;
if (SQ(dx) + SQ(dz) <= SQ(radius)) {
return TRUE;
}
return FALSE;
}
extern int mCoBG_JudgePointInCircle(f32* p, f32* center, f32 radius) {
f32 dx = p[0] - center[0];
f32 dz = p[1] - center[1];
if (SQ(dx) + SQ(dz) <= SQ(radius)) {
return TRUE;
}
return FALSE;
}
// @unused, @fabricated
extern f32 mCoBG_GetAbsBiggerF(f32 a, f32 b) {
if (ABS(a) > ABS(b)) {
return a;
} else {
return b;
}
}
static void mCoBG_GetDeffVec(f32* v0, f32* v1, f32* v2, f32* vec0, f32* vec1) {
vec0[0] = v0[0] - v1[0];
vec1[0] = v1[0] - v2[0];
vec0[1] = v0[1] - v1[1];
vec1[1] = v1[1] - v2[1];
vec0[2] = v0[2] - v1[2];
vec1[2] = v1[2] - v2[2];
}
extern void mCoBG_GetNorm_By2Vector(f32* v0, f32* v1, xyz_t* normal) {
if (normal != NULL) {
normal->x = v0[1] * v1[2] - v0[2] * v1[1];
normal->y = v0[2] * v1[0] - v0[0] * v1[2];
normal->z = v0[0] * v1[1] - v0[1] * v1[0];
}
}
extern void mCoBG_GetNorm_By3Point(xyz_t* normal, f32* v0, f32* v1, f32* v2) {
static f32 vec1[3];
static f32 vec2[3];
if (normal != NULL) {
mCoBG_GetDeffVec(v0, v1, v2, vec1, vec2);
mCoBG_GetNorm_By2Vector(vec1, vec2, normal);
}
}
static u32 mCoBG_SelectBiggerUnint(u32 a, u32 b) {
if (a > b) {
return a;
} else {
return b;
}
}
static u32 mCoBG_SelectSmallerUnint(u32 a, u32 b) {
if (a < b) {
return a;
} else {
return b;
}
}
static u32 mCoBG_GetMaxOffset(u32 p0, u32 p1, u32 p2, u32 p3, u32 p4) {
return mCoBG_SelectBiggerUnint(
mCoBG_SelectBiggerUnint(mCoBG_SelectBiggerUnint(p0, p1), mCoBG_SelectBiggerUnint(p2, p3)),
p4
);
}
static u32 mCoBG_GetMinOffset(u32 p0, u32 p1, u32 p2, u32 p3, u32 p4) {
return mCoBG_SelectSmallerUnint(
mCoBG_SelectSmallerUnint(mCoBG_SelectSmallerUnint(p0, p1), mCoBG_SelectSmallerUnint(p2, p3)),
p4
);
}
extern int mCoBG_RangeCheckLinePoint(f32* start, f32* end, f32* point) {
f32 normal01[2];
normal01[0] = end[0] - start[0];
normal01[1] = end[1] - start[1];
if (mCoBG_GetPointInfoFrontLine(start, point, normal01)) {
f32 normal10[2];
normal10[0] = start[0] - end[0];
normal10[1] = start[1] - end[1];
if (mCoBG_GetPointInfoFrontLine(end, point, normal10)) {
return TRUE;
}
}
return FALSE;
}
static void mCoBG_SetLinePos(f32* line, f32 x, f32 z) {
line[0] = x;
line[1] = z;
}
static void mCoBG_PlusLinePos(f32* line, f32 x, f32 z) {
line[0] += x;
line[1] += z;
}
static void mCoBG_PlusEqualPos(xyz_t* p0, xyz_t* p1) {
p0->x += p1->x;
p0->y += p1->y;
p0->z += p1->z;
}
+480
View File
@@ -0,0 +1,480 @@
static mCoBG_bg_size_c mCoBG_mBgDataA = { 20.0f, 20.0f, 20.0f, 20.0f };
static mCoBG_bg_size_c mCoBG_mBgDataB_0 = { 60.0f, 20.0f, 20.0f, 20.0f };
static mCoBG_bg_size_c mCoBG_mBgDataB_180 = { 20.0f, 60.0f, 20.0f, 20.0f };
static mCoBG_bg_size_c mCoBG_mBgDataB_270 = { 20.0f, 20.0f, 20.0f, 60.0f };
static mCoBG_bg_size_c mCoBG_mBgDataB_90 = { 20.0f, 20.0f, 60.0f, 20.0f };
static mCoBG_bg_size_c mCoBG_mBgDataC = { 40.0f, 40.0f, 40.0f, 40.0f };
static mCoBG_bg_size_c* mCoBG_mBg_data[] = {
&mCoBG_mBgDataA, &mCoBG_mBgDataB_0, &mCoBG_mBgDataB_180, &mCoBG_mBgDataB_270, &mCoBG_mBgDataB_90, &mCoBG_mBgDataC,
};
extern int mCoBG_JudgeMoveBgGroundCheck(f32* point, f32* goal, f32 dist) {
f32 delta[2];
delta[0] = ABS(point[0] - goal[0]);
delta[1] = ABS(point[1] - goal[1]);
if (delta[0] < dist && delta[1] < dist) {
return TRUE;
}
return FALSE;
}
extern int mCoBG_GetMoveBgHeight(f32* move_bg_height, xyz_t* pos_p) {
mCoBG_mBgMgr_c* bg_mgr = &l_mBgMgr;
mCoBG_bg_regist_c* regist_p;
xyz_t* wpos;
mCoBG_bg_regist_c** regist_pp = bg_mgr->regist_p;
f32 pos[2];
int i;
f32 left;
f32 right;
f32 up;
f32 down;
int move_bg_idx = -1;
xyz_t* base_ofs;
mCoBG_bg_size_c* size_p;
f32 base[2];
f32 angleY_rad;
f32 rate;
*move_bg_height = -500.0f;
pos[0] = pos_p->x;
pos[1] = pos_p->z;
if (bg_mgr->count != 0) {
for (i = 0; i < mCoBG_MOVE_REGIST_MAX; i++) {
regist_p = *regist_pp;
if (regist_p != NULL) {
wpos = regist_p->wpos;
size_p = regist_p->bg_size;
base_ofs = regist_p->base_ofs;
base[0] = wpos->x;
base[1] = wpos->z;
if (mCoBG_JudgeMoveBgGroundCheck(base, pos, regist_p->active_dist)) {
f32 leftUp_pos[2];
f32 leftDown_pos[2];
f32 rightDown_pos[2];
angleY_rad = SHORT2RAD_ANGLE2(*regist_p->angle_y);
rate = regist_p->scale_percent != NULL ? *regist_p->scale_percent : 1.0f;
left = size_p->left_size * rate;
right = size_p->right_size * rate;
up = size_p->up_size * rate;
down = size_p->down_size * rate;
mCoBG_SetLinePos(leftUp_pos, -left, -up);
mCoBG_SetLinePos(leftDown_pos, -left, down);
mCoBG_SetLinePos(rightDown_pos, right, down);
if (base_ofs != NULL) {
mCoBG_PlusLinePos(leftUp_pos, base_ofs->x, base_ofs->z);
mCoBG_PlusLinePos(leftDown_pos, base_ofs->x, base_ofs->z);
mCoBG_PlusLinePos(rightDown_pos, base_ofs->x, base_ofs->z);
}
if (angleY_rad != 0.0f) {
mCoBG_RotateY(leftUp_pos, angleY_rad);
mCoBG_RotateY(leftDown_pos, angleY_rad);
mCoBG_RotateY(rightDown_pos, angleY_rad);
}
mCoBG_PlusLinePos(leftUp_pos, wpos->x, wpos->z);
mCoBG_PlusLinePos(leftDown_pos, wpos->x, wpos->z);
mCoBG_PlusLinePos(rightDown_pos, wpos->x, wpos->z);
if (mCoBG_RangeCheckLinePoint(leftUp_pos, leftDown_pos, pos) &&
mCoBG_RangeCheckLinePoint(leftDown_pos, rightDown_pos, pos)) {
*move_bg_height = wpos->y + regist_p->height;
move_bg_idx = i;
}
}
}
regist_pp++;
}
}
return move_bg_idx;
}
// @unused, @fabricated
extern void mCoBG_InitMoveBgContact(mCoBG_bg_contact_c* contact) {
bzero(contact, sizeof(mCoBG_bg_contact_c));
bzero(&l_VecInf, sizeof(mCoBG_vec_info_c));
bzero(&l_ActorInf, sizeof(mCoBG_ActorInf_c));
bzero(&l_mBgMgr, sizeof(mCoBG_mBgMgr_c));
}
extern int mCoBG_RegistMoveBg(mCoBG_bg_regist_c* regist, xyz_t* wpos, xyz_t* old_wpos, s16* angleY, f32 height,
mCoBG_bg_size_c* size, f32* scale_percent, mCoBG_bg_contact_c* contact, xyz_t* base_ofs,
int type, u32 attribute, f32 check_dist) {
mCoBG_mBgMgr_c* bg_mgr = &l_mBgMgr;
mCoBG_bg_regist_c** regist_pp = bg_mgr->regist_p;
int i;
if (bg_mgr->count < mCoBG_MOVE_REGIST_MAX) {
for (i = 0; i < mCoBG_MOVE_REGIST_MAX; i++) {
if (regist_pp[i] == NULL) {
regist_pp[i] = regist;
if (type == mCoBG_FTR_TYPE_NUM) {
regist_pp[i]->bg_size = size;
} else {
regist_pp[i]->bg_size = mCoBG_mBg_data[type];
}
regist_pp[i]->height = height;
regist_pp[i]->base_ofs = base_ofs;
regist_pp[i]->contact = contact;
regist_pp[i]->wpos = wpos;
regist_pp[i]->last_wpos = old_wpos;
regist_pp[i]->angle_y = angleY;
regist_pp[i]->attribute = attribute;
regist_pp[i]->active_dist = check_dist;
regist_pp[i]->scale_percent = scale_percent;
if (regist_pp[i]->contact != NULL) {
bzero(regist_pp[i]->contact, sizeof(mCoBG_bg_contact_c));
}
bg_mgr->count++;
return i;
}
}
}
return -1;
}
extern mCoBG_bg_regist_c* mCoBG_Idx2RegistPointer(int move_bg_idx) {
mCoBG_mBgMgr_c* bg_mgr = &l_mBgMgr;
mCoBG_bg_regist_c** regist_pp = bg_mgr->regist_p;
if (bg_mgr->count != 0 && move_bg_idx >= 0 && move_bg_idx < mCoBG_MOVE_REGIST_MAX) {
return regist_pp[move_bg_idx];
}
return NULL;
}
extern void mCoBG_CrossOffMoveBg(int move_bg_idx) {
mCoBG_mBgMgr_c* bg_mgr = &l_mBgMgr;
mCoBG_bg_regist_c** regist_pp = bg_mgr->regist_p;
if (move_bg_idx > -1 && move_bg_idx < mCoBG_MOVE_REGIST_MAX && bg_mgr->count != 0 &&
move_bg_idx < mCoBG_MOVE_REGIST_MAX) {
if (regist_pp[move_bg_idx] != NULL) {
bzero(regist_pp[move_bg_idx], sizeof(mCoBG_bg_regist_c));
regist_pp[move_bg_idx] = NULL;
bg_mgr->count--;
}
}
}
extern void mCoBG_InitMoveBgData(void) {
mCoBG_mBgMgr_c* bg_mgr = &l_mBgMgr;
mCoBG_bg_regist_c** regist_pp = bg_mgr->regist_p;
int i;
bg_mgr->count = 0;
for (i = 0; i < mCoBG_MOVE_REGIST_MAX; i++) {
regist_pp[i] = NULL;
}
}
static void mCoBG_SetBaseOffset(f32* start, f32* end, xyz_t* base_ofs) {
if (base_ofs != NULL) {
mCoBG_PlusLinePos(start, base_ofs->x, base_ofs->z);
mCoBG_PlusLinePos(end, base_ofs->x, base_ofs->z);
}
}
static void mCoBG_MakeCommonData(mCoBG_unit_vec_info_c* unit_vec, mCoBG_bg_regist_c* regist) {
unit_vec->regist_p = regist;
unit_vec->atr_wall = FALSE;
}
static f32 norm_up[2] = { 0.0f, -1.0f };
static f32 norm_lt[2] = { -1.0f, 0.0f };
static f32 norm_dn[2] = { 0.0f, 1.0f };
static f32 norm_rt[2] = { 1.0f, 0.0f };
static f32* norm_table[4] = { norm_up, norm_lt, norm_dn, norm_rt };
static void mCoBG_GetNorm(f32* norm, int direct) {
f32* np = norm_table[direct & 3];
norm[0] = np[0];
norm[1] = np[1];
}
static void mCoBG_SetMoveBgHeightInf(mCoBG_WallBounds_c* bounds, xyz_t* pos, f32 height) {
bounds->start_top = pos->y + height;
bounds->start_btm = pos->y;
bounds->end_top = bounds->start_top;
bounds->end_btm = pos->y;
}
static void mCoBG_SetMoveBgContactSide(mCoBG_bg_regist_c* regist, ACTOR* actorx, s16 angle) {
mCoBG_bg_contact_c* contact = regist->contact;
if (contact != NULL) {
mCoBG_side_contact_c* side_contact = contact->side_contact;
int* count = &contact->side_count;
if (*count < 5) {
side_contact[*count].name = actorx->id;
side_contact[*count].angle = angle;
(*count)++;
}
}
}
static void mCoBG_SetMoveBgContactOn(mCoBG_bg_regist_c* regist, ACTOR* actorx) {
mCoBG_bg_contact_c* contact = regist->contact;
if (contact != NULL) {
mCoBG_on_contact_info_c* info = &contact->on_contact;
mCoBG_on_contact_c* on_contact = info->contact;
int* count = &info->count;
if (*count < 5) {
on_contact[*count].name = actorx->id;
(*count)++;
}
}
}
static void mCoBG_MoveBgGroundCheck(xyz_t* rev, mCoBG_ActorInf_c* actor_info, ACTOR* actorx,
mCoBG_CheckResult_c* result, s_xyz* angle) {
f32 height = -500.0f;
f32 dist = actor_info->ground_dist;
xyz_t pos;
int on_move_bg_idx;
pos.x = actorx->world.position.x + rev->x;
pos.y = 0.0f;
pos.z = actorx->world.position.z + rev->z;
if (actorx->id != mAc_PROFILE_GYOEI) {
on_move_bg_idx = mCoBG_GetMoveBgHeight(&height, &pos);
if (on_move_bg_idx != -1 && (actorx->world.position.y + dist + rev->y) <= height) {
mCoBG_bg_regist_c* on_regist = mCoBG_Idx2RegistPointer(on_move_bg_idx);
if (on_regist != NULL) {
s_xyz angle0 = { 0, 0, 0 };
rev->y = (height - dist) - actorx->world.position.y;
*angle = angle0;
result->on_ground = TRUE;
result->is_on_move_bg_obj = TRUE;
result->unit_attribute = on_regist->attribute;
actorx->shape_info.move_bg_idx = on_move_bg_idx;
actorx->position_speed.y = 0.0f;
mCoBG_SetMoveBgContactOn(on_regist, actorx);
}
}
}
}
static void mCoBG_RotateMoveBgCollisionData(mCoBG_unit_vec_info_c* unit_vec, f32 rad) {
f32* normal = unit_vec->normal;
f32* start = unit_vec->start;
f32* end = unit_vec->end;
if (ABS(RAD2DEG(rad)) >= 0.05f) {
mCoBG_RotateY(normal, rad);
mCoBG_RotateY(start, rad);
mCoBG_RotateY(end, rad);
}
}
static void mCoBG_SizeData2CollisionData(mCoBG_bg_regist_c* regist, mCoBG_vec_info_c* vec_info, u8 check_type,
int move_bg_idx) {
int* unit_count_p;
mCoBG_unit_vec_info_c* unit_vec;
xyz_t pos;
f32* start;
f32* end;
f32* normal;
mCoBG_WallBounds_c* bounds;
mCoBG_unit_vec_info_c* ut_vec_p;
s16 angleY;
f32 angleY_rad;
f32 height;
xyz_t* base_ofs;
mCoBG_bg_size_c* size;
mCoBG_tab_c tab_data;
f32 rate;
unit_count_p = &vec_info->unit_count;
unit_vec = vec_info->unit;
pos = *regist->wpos;
angleY = *regist->angle_y;
angleY_rad = SHORT2RAD_ANGLE2(angleY);
height = regist->height;
base_ofs = regist->base_ofs;
size = regist->bg_size;
tab_data = mCoBG_tab_data[check_type];
rate = 1.0f;
if (regist->scale_percent != NULL) {
rate = *regist->scale_percent;
}
if (*unit_count_p < mCoBG_UNIT_VEC_INFO_MAX) {
ut_vec_p = &unit_vec[*unit_count_p];
start = ut_vec_p->start;
end = ut_vec_p->end;
normal = ut_vec_p->normal;
bounds = &ut_vec_p->wall_bounds;
mCoBG_SetLinePos(start, -(size->left_size * rate) - tab_data.t0, -(size->up_size * rate));
mCoBG_SetLinePos(end, (size->right_size * rate) + tab_data.t0, -(size->up_size * rate));
mCoBG_SetBaseOffset(start, end, base_ofs);
mCoBG_SetMoveBgHeightInf(bounds, &pos, height);
mCoBG_GetNorm(normal, mCoBG_NORM_DIRECT_UP);
ut_vec_p->wall_name = mCoBG_WALL_UP;
ut_vec_p->normal_angle = DEG2SHORT_ANGLE2(180.0f);
mCoBG_MakeCommonData(ut_vec_p, regist);
mCoBG_RotateMoveBgCollisionData(ut_vec_p, angleY_rad);
ut_vec_p->normal_angle += angleY;
mCoBG_PlusLinePos(start, pos.x, pos.z);
mCoBG_PlusLinePos(end, pos.x, pos.z);
(*unit_count_p)++;
}
if (*unit_count_p < mCoBG_UNIT_VEC_INFO_MAX) {
ut_vec_p = &unit_vec[*unit_count_p];
start = ut_vec_p->start;
end = ut_vec_p->end;
normal = ut_vec_p->normal;
bounds = &ut_vec_p->wall_bounds;
mCoBG_SetLinePos(start, -(size->left_size * rate), (size->down_size * rate) + tab_data.t0);
mCoBG_SetLinePos(end, -(size->left_size * rate), -(size->up_size * rate) - tab_data.t0);
mCoBG_SetBaseOffset(start, end, base_ofs);
mCoBG_SetMoveBgHeightInf(bounds, &pos, height);
mCoBG_GetNorm(normal, mCoBG_NORM_DIRECT_LEFT);
ut_vec_p->wall_name = mCoBG_WALL_LEFT;
ut_vec_p->normal_angle = DEG2SHORT_ANGLE2(-90.0f);
mCoBG_MakeCommonData(ut_vec_p, regist);
mCoBG_RotateMoveBgCollisionData(ut_vec_p, angleY_rad);
ut_vec_p->normal_angle += angleY;
mCoBG_PlusLinePos(start, pos.x, pos.z);
mCoBG_PlusLinePos(end, pos.x, pos.z);
(*unit_count_p)++;
}
if (*unit_count_p < mCoBG_UNIT_VEC_INFO_MAX) {
ut_vec_p = &unit_vec[*unit_count_p];
start = ut_vec_p->start;
end = ut_vec_p->end;
normal = ut_vec_p->normal;
bounds = &ut_vec_p->wall_bounds;
mCoBG_SetLinePos(start, (size->right_size * rate) + tab_data.t0, (size->down_size * rate));
mCoBG_SetLinePos(end, -(size->left_size * rate) - tab_data.t0, (size->down_size * rate));
mCoBG_SetBaseOffset(start, end, base_ofs);
mCoBG_SetMoveBgHeightInf(bounds, &pos, height);
mCoBG_GetNorm(normal, mCoBG_NORM_DIRECT_DOWN);
ut_vec_p->wall_name = mCoBG_WALL_DOWN;
ut_vec_p->normal_angle = DEG2SHORT_ANGLE2(0.0f);
mCoBG_MakeCommonData(ut_vec_p, regist);
mCoBG_RotateMoveBgCollisionData(ut_vec_p, angleY_rad);
ut_vec_p->normal_angle += angleY;
mCoBG_PlusLinePos(start, pos.x, pos.z);
mCoBG_PlusLinePos(end, pos.x, pos.z);
(*unit_count_p)++;
}
if (*unit_count_p < mCoBG_UNIT_VEC_INFO_MAX) {
ut_vec_p = &unit_vec[*unit_count_p];
start = ut_vec_p->start;
end = ut_vec_p->end;
normal = ut_vec_p->normal;
bounds = &ut_vec_p->wall_bounds;
mCoBG_SetLinePos(start, (size->right_size * rate), -(size->up_size * rate) - tab_data.t0);
mCoBG_SetLinePos(end, (size->right_size * rate), (size->down_size * rate) + tab_data.t0);
mCoBG_SetBaseOffset(start, end, base_ofs);
mCoBG_SetMoveBgHeightInf(bounds, &pos, height);
mCoBG_GetNorm(normal, mCoBG_NORM_DIRECT_RIGHT);
ut_vec_p->wall_name = mCoBG_WALL_RIGHT;
ut_vec_p->normal_angle = DEG2SHORT_ANGLE2(90.0f);
mCoBG_MakeCommonData(ut_vec_p, regist);
mCoBG_RotateMoveBgCollisionData(ut_vec_p, angleY_rad);
ut_vec_p->normal_angle += angleY;
mCoBG_PlusLinePos(start, pos.x, pos.z);
mCoBG_PlusLinePos(end, pos.x, pos.z);
(*unit_count_p)++;
}
}
static void mCoBG_MakeMoveBgVector(mCoBG_vec_info_c* vec_info, mCoBG_mBgMgr_c* bg_mgr, const xyz_t* pos,
u8 check_type) {
int bg_count = bg_mgr->count;
int i;
int count = 0;
mCoBG_bg_regist_c** regist_pp = bg_mgr->regist_p;
if (bg_count != 0) {
for (i = 0; i < mCoBG_MOVE_REGIST_MAX; i++) {
if (regist_pp[i] != NULL) {
xyz_t* regist_pos = regist_pp[i]->wpos;
if (Math3DLength2D(pos->x, pos->z, regist_pos->x, regist_pos->z) < regist_pp[i]->active_dist) {
mCoBG_SizeData2CollisionData(regist_pp[i], vec_info, check_type, i);
count++;
if (count >= bg_count) {
break;
}
}
}
}
}
}
typedef struct {
ACTOR* actor;
int move_bg_idx;
mCoBG_bg_regist_c regist;
} mCoBG_boat_collision_c;
static mCoBG_boat_collision_c l_mCoBG_boat_move_bg_data[2];
static mCoBG_bg_size_c l_mCoBG_boat_size = { 20.0f, 20.0f, 40.0f, 40.0f };
extern void mCoBG_InitBoatCollision(void) {
int i;
for (i = 0; i < 2; i++) {
bzero(&l_mCoBG_boat_move_bg_data[i], sizeof(mCoBG_boat_collision_c));
l_mCoBG_boat_move_bg_data[i].move_bg_idx = -1;
}
bzero(&l_mBgMgr, sizeof(l_mBgMgr));
}
extern void mCoBG_MakeBoatCollision(ACTOR* actor, xyz_t* pos, s16* angle_y) {
int i;
for (i = 0; i < 2; i++) {
if (l_mCoBG_boat_move_bg_data[i].move_bg_idx == -1) {
l_mCoBG_boat_move_bg_data[i].move_bg_idx =
mCoBG_RegistMoveBg(&l_mCoBG_boat_move_bg_data[i].regist, pos, pos, angle_y, 30.0f, &l_mCoBG_boat_size,
NULL, NULL, NULL, mCoBG_FTR_TYPE_NUM, mCoBG_ATTRIBUTE_SAND, 120.0f);
l_mCoBG_boat_move_bg_data[i].actor = actor;
break;
}
}
}
extern void mCoBG_DeleteBoatCollision(ACTOR* actor) {
int i;
for (i = 0; i < 2; i++) {
if (actor == l_mCoBG_boat_move_bg_data[i].actor) {
mCoBG_CrossOffMoveBg(l_mCoBG_boat_move_bg_data[i].move_bg_idx);
l_mCoBG_boat_move_bg_data[i].move_bg_idx = -1;
break;
}
}
}
+183
View File
@@ -0,0 +1,183 @@
static u32 mCoBG_OffsetInRule(int ofs) {
if (ofs > 31) {
return 31;
}
return CLAMP(ofs, 0, ofs);
}
static void mCoBG_SetBestBgY(mCoBG_Collision_u* col, s16* change_ofs) {
u32 max = mCoBG_GetMaxOffset(col->data.center, col->data.top_left, col->data.bot_left, col->data.bot_right, col->data.top_right);
u32 min = mCoBG_GetMinOffset(col->data.center, col->data.top_left, col->data.bot_left, col->data.bot_right, col->data.top_right);
}
static void mCoBG_TidyChangeOffset(s16* change_ofs, mCoBG_Collision_u* col) {
if (
// clang-format off
col->data.center + *change_ofs > 31 ||
col->data.top_left + *change_ofs > 31 ||
col->data.bot_left + *change_ofs > 31 ||
col->data.bot_right + *change_ofs > 31 ||
col->data.top_right + *change_ofs > 31 ||
col->data.center + *change_ofs < 0 ||
col->data.top_left + *change_ofs < 0 ||
col->data.bot_left + *change_ofs < 0 ||
col->data.bot_right + *change_ofs < 0 ||
col->data.top_right + *change_ofs < 0
// clang-format on
) {
mCoBG_SetBestBgY(col, change_ofs);
}
}
// @unused, @fabricated
extern void mCoBG_Ut2SetPlussOffset(int ux, int uz, s16 change_ofs, s16 attr) {
xyz_t pos = { 0.0f, 0.0f, 0.0f };
if (mFI_UtNum2CenterWpos(&pos, ux, uz)) {
mCoBG_SetPlussOffset(pos, change_ofs, attr);
}
}
extern void mCoBG_SetPlussOffset(xyz_t wpos, s16 change_ofs, s16 attr) {
int ux;
int uz;
if (mFI_Wpos2UtNum(&ux, &uz, wpos)) {
mCoBG_Collision_u* col = mFI_UtNum2UtCol(ux, uz);
u8 keep_h = mFI_UtNum2UtKeepH(ux, uz);
if (keep_h == col->data.center) {
mCoBG_TidyChangeOffset(&change_ofs, col);
} else {
u32 gap = keep_h - col->data.center;
col->data.center = (u8)keep_h;
col->data.top_left += gap;
col->data.bot_left += gap;
col->data.bot_right += gap;
col->data.top_right += gap;
mCoBG_TidyChangeOffset(&change_ofs, col);
}
col->data.center += change_ofs;
col->data.bot_left += change_ofs;
col->data.top_left += change_ofs;
col->data.top_right += change_ofs;
col->data.bot_right += change_ofs;
if (attr != mCoBG_ATTRIBUTE_NONE) {
col->data.unit_attribute = (s16)attr;
}
}
}
extern void mCoBG_SetAttribute(xyz_t pos, s16 attr) {
mCoBG_Collision_u* col;
int ux;
int uz;
if (mFI_Wpos2UtNum(&ux, &uz, pos)) {
col = mFI_UtNum2UtCol(ux, uz);
if (attr != mCoBG_ATTRIBUTE_NONE) {
col->data.unit_attribute = (s16)attr;
}
}
}
extern void mCoBG_Ut2SetPluss5PointOffset_file(int ux, int uz, mCoBG_OffsetTable_c ofs_data, char* file, int line) {
xyz_t pos = { 0.0f, 0.0f, 0.0f };
if (mFI_UtNum2CenterWpos(&pos, ux, uz)) {
mCoBG_SetPluss5PointOffset_file(pos, ofs_data, file, line);
}
}
extern void mCoBG_SetPluss5PointOffset_file(xyz_t pos, mCoBG_OffsetTable_c ofs_data, char* file, int line) {
int ux;
int uz;
if (mFI_Wpos2UtNum(&ux, &uz, pos)) {
u8 keep_h = mFI_UtNum2UtKeepH(ux, uz);
mCoBG_Collision_u* col = mFI_UtNum2UtCol(ux, uz);
if (
// clang-format off
col->data.center == col->data.top_left &&
col->data.center == col->data.bot_left &&
col->data.center == col->data.bot_right &&
col->data.center == col->data.top_right
// clang-format on
) {
col->data.center = mCoBG_OffsetInRule(keep_h + ofs_data.centerRight_offset);
col->data.top_left = mCoBG_OffsetInRule(keep_h + ofs_data.leftUp_offset);
col->data.bot_left = mCoBG_OffsetInRule(keep_h + ofs_data.leftDown_offset);
col->data.bot_right = mCoBG_OffsetInRule(keep_h + ofs_data.rightDown_offset);
col->data.top_right = mCoBG_OffsetInRule(keep_h + ofs_data.rightUp_offset);
col->data.slate_flag = (s8)ofs_data.shape;
if (ofs_data.unit_attribute != mCoBG_ATTRIBUTE_NONE) {
col->data.unit_attribute = ofs_data.unit_attribute;
}
} else if (
// clang-format off
ofs_data.centerRight_offset == 0 &&
ofs_data.leftUp_offset == 0 &&
ofs_data.leftDown_offset == 0 &&
ofs_data.rightDown_offset == 0 &&
ofs_data.rightUp_offset == 0
// clang-format on
) {
if (col->data.slate_flag) {
col->data.center = keep_h;
col->data.top_left = keep_h;
col->data.bot_left = keep_h;
col->data.bot_right = keep_h;
col->data.top_right = keep_h;
col->data.slate_flag = FALSE;
} else {
col->data.center = keep_h;
col->data.top_left = keep_h;
col->data.bot_left = keep_h;
col->data.bot_right = keep_h;
col->data.top_right = keep_h;
}
if (ofs_data.unit_attribute != mCoBG_ATTRIBUTE_NONE) {
col->data.unit_attribute = ofs_data.unit_attribute;
}
}
}
}
typedef struct {
u8 src;
u8 dst;
} mCoBG_change_poor_c;
extern int mCoBG_Change2PoorAttr(mCoBG_Collision_u* col) {
static mCoBG_change_poor_c change_data[] = {
{ mCoBG_ATTRIBUTE_GRASS0, mCoBG_ATTRIBUTE_GRASS2 },
{ mCoBG_ATTRIBUTE_GRASS1, mCoBG_ATTRIBUTE_GRASS2 },
{ mCoBG_ATTRIBUTE_SOIL0, mCoBG_ATTRIBUTE_SOIL2 },
{ mCoBG_ATTRIBUTE_SOIL1, mCoBG_ATTRIBUTE_SOIL2 },
};
u8 attr = col->data.unit_attribute;
int i;
for (i = 0; i < ARRAY_COUNT(change_data); i++) {
if (attr == change_data[i].src) {
col->data.unit_attribute = change_data[i].dst;
return TRUE;
}
}
return FALSE;
}
extern void mCoBG_Ut2SetDefaultOffset(int ux, int uz) {
static mCoBG_OffsetTable_c offset_data = { mCoBG_ATTRIBUTE_NONE, 0, 0, 0, 0, 0, FALSE };
mCoBG_Ut2SetPluss5PointOffset_file(ux, uz, offset_data, __FILE__, 515);
}
+662
View File
@@ -0,0 +1,662 @@
static void mCoBG_UnitNoName2StartEnd(f32* start, f32* end, f32 ux, f32 uz, u8 wall_name, u8 check_type) {
mCoBG_tab_c tab = mCoBG_tab_data[check_type];
switch (wall_name) {
case mCoBG_WALL_UP:
start[0] = ux * mFI_UT_WORLDSIZE_X_F - tab.t0;
start[1] = uz * mFI_UT_WORLDSIZE_Z_F;
end[0] = start[0] + mFI_UT_WORLDSIZE_X_F + tab.t1;
end[1] = start[1];
break;
case mCoBG_WALL_LEFT:
start[0] = ux * mFI_UT_WORLDSIZE_X_F;
start[1] = uz * mFI_UT_WORLDSIZE_Z_F - tab.t0;
end[0] = start[0];
end[1] = start[1] + mFI_UT_WORLDSIZE_Z_F + tab.t1;
break;
case mCoBG_WALL_DOWN:
end[0] = ux * mFI_UT_WORLDSIZE_X_F - tab.t0;
end[1] = (uz + 1) * mFI_UT_WORLDSIZE_Z_F;
start[0] = end[0] + mFI_UT_WORLDSIZE_X_F + tab.t1;
start[1] = end[1];
break;
case mCoBG_WALL_RIGHT:
start[0] = (ux + 1) * mFI_UT_WORLDSIZE_X_F;
start[1] = uz * mFI_UT_WORLDSIZE_Z_F - tab.t0;
end[0] = start[0];
end[1] = start[1] + mFI_UT_WORLDSIZE_Z_F + tab.t1;
break;
case mCoBG_WALL_SLATE_UP:
start[0] = ux * mFI_UT_WORLDSIZE_X_F - tab.t0;
end[0] = start[0] + tab.t1 + mFI_UT_WORLDSIZE_X_F;
start[1] = (uz + 1) * mFI_UT_WORLDSIZE_Z_F + tab.t0;
end[1] = start[1] - mFI_UT_WORLDSIZE_Z_F - tab.t1;
break;
case mCoBG_WALL_SLATE_DOWN:
start[0] = ux * mFI_UT_WORLDSIZE_X_F - tab.t0;
end[0] = start[0] + tab.t1 + mFI_UT_WORLDSIZE_X_F;
start[1] = uz * mFI_UT_WORLDSIZE_Z_F - tab.t0;
end[1] = start[1] + mFI_UT_WORLDSIZE_Z_F + tab.t1;
break;
}
}
static u8 l_make33_coldata[9] = {
0x00, 0x02, 0x02, 0x01, 0x03, 0x03, 0x01, 0x03,
0x03,
};
static u8 l_make55_coldata[25] = {
0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x03, 0x03,
0x03, 0x03, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01,
0x03, 0x03, 0x03, 0x03, 0x01, 0x03, 0x03, 0x03,
0x03,
};
static u8 l_make77_coldata[49] = {
0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x01, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x01, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03,
};
static u8 mCoBG_SearchSlateDetail(mCoBG_CollisionData_c* col) {
if (col->bot_right != col->top_left) {
return mCoBG_WALL_SLATE_UP;
} else if (col->top_right != col->bot_left) {
return mCoBG_WALL_SLATE_DOWN;
} else {
return mCoBG_WALL_SLATE_UP;
}
}
static u8 mCoBG_SearchWallFlag(mCoBG_unit_vec_info_c* unit_vec, mCoBG_UnitInfo_c* ut_info0, mCoBG_UnitInfo_c* ut_info1, u8 wall_name) {
switch (wall_name) {
case mCoBG_WALL_UP:
if (ut_info0->leftUp_offset != ut_info1->leftDown_offset || ut_info0->rightUp_offset != ut_info1->rightDown_offset) {
if (ut_info1->leftDown_offset > ut_info0->leftUp_offset || ut_info1->rightDown_offset > ut_info0->rightUp_offset) {
mCoBG_SetXZ(unit_vec->normal, 0.0f, 1.0f);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(0.0f);
return TRUE;
} else {
mCoBG_SetXZ(unit_vec->normal, 0.0f, -1.0f);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(180.0f);
return TRUE;
}
}
break;
case mCoBG_WALL_LEFT:
if (ut_info0->leftUp_offset != ut_info1->rightUp_offset || ut_info0->leftDown_offset != ut_info1->rightDown_offset) {
if (ut_info1->rightUp_offset > ut_info0->leftUp_offset || ut_info1->rightDown_offset > ut_info0->leftDown_offset) {
mCoBG_SetXZ(unit_vec->normal, 1.0f, 0.0f);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(90.0f);
return TRUE;
} else {
mCoBG_SetXZ(unit_vec->normal, -1.0f, 0.0f);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(-90.0f);
return TRUE;
}
}
break;
case mCoBG_WALL_DOWN:
if (ut_info0->leftDown_offset != ut_info1->leftUp_offset || ut_info0->rightDown_offset != ut_info1->rightUp_offset) {
if (ut_info1->leftUp_offset > ut_info0->leftDown_offset || ut_info1->rightUp_offset > ut_info0->rightDown_offset) {
mCoBG_SetXZ(unit_vec->normal, 0.0f, -1.0f);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(180.0f);
return TRUE;
} else {
mCoBG_SetXZ(unit_vec->normal, 0.0f, 1.0f);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(0.0f);
return TRUE;
}
}
break;
case mCoBG_WALL_RIGHT:
if (ut_info0->rightUp_offset != ut_info1->leftUp_offset || ut_info0->rightDown_offset != ut_info1->leftDown_offset) {
if (ut_info1->leftUp_offset > ut_info0->leftDown_offset || ut_info1->rightUp_offset > ut_info0->rightDown_offset) {
mCoBG_SetXZ(unit_vec->normal, -1.0f, 0.0f);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(-90.0f);
return TRUE;
} else {
mCoBG_SetXZ(unit_vec->normal, 1.0f, 0.0f);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(90.0f);
return TRUE;
}
}
break;
}
return FALSE;
}
static void mCoBG_SetTopBtm(mCoBG_WallBounds_c* bounds, f32 start_top, f32 end_top, f32 start_btm, f32 end_btm) {
bounds->start_top = start_top;
bounds->end_top = end_top;
bounds->start_btm = start_btm;
bounds->end_btm = end_btm;
}
static void mCoBG_GetUnitVecInf_SlatingWall(mCoBG_unit_vec_info_c* unit_vec, mCoBG_UnitInfo_c* unit_info, u8 name, u8 check_type) {
f32 ux = unit_info->ut_x;
f32 uz = unit_info->ut_z;
f32* start = unit_vec->start;
f32* end = unit_vec->end;
f32* normal = unit_vec->normal;
mCoBG_WallBounds_c* bounds = &unit_vec->wall_bounds;
unit_vec->wall_name = name;
switch (name) {
case mCoBG_WALL_SLATE_UP:
mCoBG_UnitNoName2StartEnd(start, end, ux, uz, mCoBG_WALL_SLATE_UP, check_type);
if (unit_info->leftUp_offset > unit_info->rightDown_offset) {
mCoBG_SetXZ(normal, SQRT_OF_2_DIV_2, SQRT_OF_2_DIV_2);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(45.0f);
mCoBG_SetTopBtm(bounds, unit_info->leftUp_offset, unit_info->leftUp_offset, unit_info->rightDown_offset, unit_info->rightDown_offset);
} else {
mCoBG_SetXZ(normal, -SQRT_OF_2_DIV_2, -SQRT_OF_2_DIV_2);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(-135.0f);
mCoBG_SetTopBtm(bounds, unit_info->rightDown_offset, unit_info->rightDown_offset, unit_info->leftUp_offset, unit_info->leftUp_offset);
}
break;
case mCoBG_WALL_SLATE_DOWN:
mCoBG_UnitNoName2StartEnd(start, end, ux, uz, mCoBG_WALL_SLATE_DOWN, check_type);
if (unit_info->leftDown_offset > unit_info->rightUp_offset) {
mCoBG_SetXZ(normal, SQRT_OF_2_DIV_2, -SQRT_OF_2_DIV_2);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(135.0f);
mCoBG_SetTopBtm(bounds, unit_info->leftDown_offset, unit_info->leftDown_offset, unit_info->rightUp_offset, unit_info->rightUp_offset);
} else {
mCoBG_SetXZ(normal, -SQRT_OF_2_DIV_2, SQRT_OF_2_DIV_2);
unit_vec->normal_angle = DEG2SHORT_ANGLE2(-45.0f);
mCoBG_SetTopBtm(bounds, unit_info->rightUp_offset, unit_info->rightUp_offset, unit_info->leftDown_offset, unit_info->leftDown_offset);
}
break;
}
}
static void mCoBG_JudgeTopAndSet(f32* top, f32* bot, f32 y0, f32 y1) {
if (y0 >= y1) {
*top = y0;
*bot = y1;
} else {
*top = y1;
*bot = y0;
}
}
static void mCoBG_UtInf2NormalWallVector(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* unit_info0, mCoBG_UnitInfo_c* unit_info1, s16 wall_name, u8 check_type) {
f32 ux = unit_info0->ut_x;
f32 uz = unit_info0->ut_z;
int count = vec_info->unit_count;
mCoBG_unit_vec_info_c* unit_vec = &vec_info->unit[count];
mCoBG_WallBounds_c* bounds = &unit_vec->wall_bounds;
f32* start = unit_vec->start;
f32* end = unit_vec->end;
unit_vec->regist_p = NULL;
unit_vec->atr_wall = FALSE;
switch (wall_name) {
case mCoBG_WALL_UP:
if (mCoBG_SearchWallFlag(unit_vec, unit_info0, unit_info1, mCoBG_WALL_UP)) {
// @BUG - isn't this missing?
// unit_vec->wall_name = mCoBG_WALL_UP;
mCoBG_UnitNoName2StartEnd(start, end, ux, uz, mCoBG_WALL_UP, check_type);
mCoBG_JudgeTopAndSet(&bounds->start_top, &bounds->start_btm, unit_info0->leftUp_offset, unit_info1->leftDown_offset);
mCoBG_JudgeTopAndSet(&bounds->end_top, &bounds->end_btm, unit_info0->rightUp_offset, unit_info1->rightDown_offset);
unit_vec->regist_p = NULL;
unit_vec->atr_wall = FALSE;
vec_info->unit_count++;
}
break;
case mCoBG_WALL_LEFT:
if (mCoBG_SearchWallFlag(unit_vec, unit_info0, unit_info1, mCoBG_WALL_LEFT)) {
unit_vec->wall_name = mCoBG_WALL_LEFT;
mCoBG_UnitNoName2StartEnd(start, end, ux, uz, mCoBG_WALL_LEFT, check_type);
mCoBG_JudgeTopAndSet(&bounds->start_top, &bounds->start_btm, unit_info0->leftUp_offset, unit_info1->rightUp_offset);
mCoBG_JudgeTopAndSet(&bounds->end_top, &bounds->end_btm, unit_info0->leftDown_offset, unit_info1->rightDown_offset);
unit_vec->regist_p = NULL;
unit_vec->atr_wall = FALSE;
vec_info->unit_count++;
}
break;
case mCoBG_WALL_DOWN:
if (mCoBG_SearchWallFlag(unit_vec, unit_info0, unit_info1, mCoBG_WALL_DOWN)) {
unit_vec->wall_name = mCoBG_WALL_DOWN;
mCoBG_UnitNoName2StartEnd(start, end, ux, uz, mCoBG_WALL_DOWN, check_type);
mCoBG_JudgeTopAndSet(&bounds->start_top, &bounds->start_btm, unit_info0->leftDown_offset, unit_info1->leftUp_offset);
mCoBG_JudgeTopAndSet(&bounds->end_top, &bounds->end_btm, unit_info0->rightDown_offset, unit_info1->rightUp_offset);
unit_vec->regist_p = NULL;
unit_vec->atr_wall = FALSE;
vec_info->unit_count++;
}
break;
case mCoBG_WALL_RIGHT:
if (mCoBG_SearchWallFlag(unit_vec, unit_info0, unit_info1, mCoBG_WALL_RIGHT)) {
unit_vec->wall_name = mCoBG_WALL_RIGHT;
mCoBG_UnitNoName2StartEnd(start, end, ux, uz, mCoBG_WALL_RIGHT, check_type);
mCoBG_JudgeTopAndSet(&bounds->start_top, &bounds->start_btm, unit_info0->rightUp_offset, unit_info1->leftUp_offset);
mCoBG_JudgeTopAndSet(&bounds->end_top, &bounds->end_btm, unit_info0->rightDown_offset, unit_info1->leftDown_offset);
unit_vec->regist_p = NULL;
unit_vec->atr_wall = FALSE;
vec_info->unit_count++;
}
break;
}
}
static void mCoBG_UtInf2NormalSlateWallVector(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info0, mCoBG_UnitInfo_c* ut_info1, s16 wall_name, u8 check_type) {
mCoBG_UnitInfo_c tmp_ut_info;
if (ut_info0->slate_flag == FALSE && ut_info1->slate_flag == TRUE) {
u8 slateDir = mCoBG_SearchSlateDetail(&ut_info1->collision->data);
tmp_ut_info = *ut_info1;
switch (wall_name) {
case mCoBG_WALL_UP:
if (slateDir == mCoBG_WALL_SLATE_UP) {
tmp_ut_info.leftDown_offset = tmp_ut_info.rightDown_offset;
} else {
tmp_ut_info.rightDown_offset = tmp_ut_info.leftDown_offset;
}
break;
case mCoBG_WALL_LEFT:
if (slateDir == mCoBG_WALL_SLATE_UP) {
tmp_ut_info.rightUp_offset = tmp_ut_info.rightDown_offset;
} else {
tmp_ut_info.rightDown_offset = tmp_ut_info.rightUp_offset;
}
break;
case mCoBG_WALL_DOWN:
if (slateDir == mCoBG_WALL_SLATE_UP) {
tmp_ut_info.rightUp_offset = tmp_ut_info.leftUp_offset;
} else {
tmp_ut_info.leftUp_offset = tmp_ut_info.rightUp_offset;
}
break;
case mCoBG_WALL_RIGHT:
if (slateDir == mCoBG_WALL_SLATE_UP) {
tmp_ut_info.leftDown_offset = tmp_ut_info.leftUp_offset;
} else {
tmp_ut_info.leftUp_offset = tmp_ut_info.leftDown_offset;
}
break;
}
mCoBG_UtInf2NormalWallVector(vec_info, ut_info0, &tmp_ut_info, wall_name, check_type);
} else if (ut_info0->slate_flag == TRUE && ut_info1->slate_flag == FALSE) {
u8 slateDir = mCoBG_SearchSlateDetail(&ut_info0->collision->data);
tmp_ut_info = *ut_info0;
switch (wall_name) {
case mCoBG_WALL_UP:
if (slateDir == mCoBG_WALL_SLATE_UP) {
tmp_ut_info.rightUp_offset = tmp_ut_info.leftUp_offset;
} else {
tmp_ut_info.leftUp_offset = tmp_ut_info.rightUp_offset;
}
break;
case mCoBG_WALL_LEFT:
if (slateDir == mCoBG_WALL_SLATE_UP) {
tmp_ut_info.leftDown_offset = tmp_ut_info.leftUp_offset;
} else {
tmp_ut_info.leftUp_offset = tmp_ut_info.leftDown_offset;
}
break;
case mCoBG_WALL_DOWN:
if (slateDir == mCoBG_WALL_SLATE_UP) {
tmp_ut_info.leftDown_offset = tmp_ut_info.rightDown_offset;
} else {
tmp_ut_info.rightDown_offset = tmp_ut_info.leftDown_offset;
}
break;
case mCoBG_WALL_RIGHT:
if (slateDir == mCoBG_WALL_SLATE_UP) {
tmp_ut_info.rightDown_offset = tmp_ut_info.rightUp_offset;
} else {
tmp_ut_info.rightUp_offset = tmp_ut_info.rightDown_offset;
}
break;
}
mCoBG_UtInf2NormalWallVector(vec_info, &tmp_ut_info, ut_info1, wall_name, check_type);
}
}
typedef void (*mCoBG_MAKE_NORMAL_WALL_PROC)(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info0, mCoBG_UnitInfo_c* ut_info1, s16 wall_name, u8 check_type);
static void mCoBG_RegistNormalWallVector_AttributeOn(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info0, mCoBG_UnitInfo_c* ut_info1, s16 wall_name, u8 check_type, s16 old_in_water) {
static mCoBG_MAKE_NORMAL_WALL_PROC make_normal_wall_proc[] = { &mCoBG_UtInf2NormalWallVector, &mCoBG_UtInf2NormalSlateWallVector };
if (vec_info->unit_count < mCoBG_UNIT_VEC_INFO_MAX) {
int proc = ut_info0->slate_flag | ut_info1->slate_flag;
(*make_normal_wall_proc[proc & 1])(vec_info, ut_info0, ut_info1, wall_name, check_type);
}
}
static void mCoBG_UnitInf2NormalVector(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info0, mCoBG_UnitInfo_c* ut_info1, s16 wall_name, u8 check_type) {
static mCoBG_MAKE_NORMAL_WALL_PROC make_normal_wall_proc[] = { &mCoBG_UtInf2NormalWallVector, &mCoBG_UtInf2NormalSlateWallVector };
int proc = ut_info0->slate_flag | ut_info1->slate_flag;
(*make_normal_wall_proc[proc & 1])(vec_info, ut_info0, ut_info1, wall_name, check_type);
}
static void mCoBG_RegistNormalWallVector_AttributeOff(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info0, mCoBG_UnitInfo_c* ut_info1, s16 wall_name, u8 check_type, s16 old_in_water) {
if (vec_info->unit_count < mCoBG_UNIT_VEC_INFO_MAX) {
if (old_in_water) {
if (ut_info0->attribute == mCoBG_ATTRIBUTE_WOOD && ut_info1->attribute >= mCoBG_ATTRIBUTE_27 && ut_info1->attribute <= mCoBG_ATTRIBUTE_35) {
mCoBG_UnitInfo_c tmp_ut_info = *ut_info1;
f32 min_h = MIN(MIN(tmp_ut_info.leftDown_offset, tmp_ut_info.leftUp_offset), MIN(tmp_ut_info.rightDown_offset, tmp_ut_info.rightUp_offset));
tmp_ut_info.slate_flag = FALSE;
tmp_ut_info.leftDown_offset = min_h;
tmp_ut_info.leftUp_offset = min_h;
tmp_ut_info.rightDown_offset = min_h;
tmp_ut_info.rightUp_offset = min_h;
mCoBG_UnitInf2NormalVector(vec_info, ut_info0, &tmp_ut_info, wall_name, check_type);
} else if (ut_info1->attribute == mCoBG_ATTRIBUTE_WOOD && ut_info0->attribute >= mCoBG_ATTRIBUTE_27 && ut_info0->attribute <= mCoBG_ATTRIBUTE_35) {
mCoBG_UnitInfo_c tmp_ut_info = *ut_info0;
f32 min_h = MIN(MIN(tmp_ut_info.leftDown_offset, tmp_ut_info.leftUp_offset), MIN(tmp_ut_info.rightDown_offset, tmp_ut_info.rightUp_offset));
tmp_ut_info.slate_flag = FALSE;
tmp_ut_info.leftDown_offset = min_h;
tmp_ut_info.leftUp_offset = min_h;
tmp_ut_info.rightDown_offset = min_h;
tmp_ut_info.rightUp_offset = min_h;
mCoBG_UnitInf2NormalVector(vec_info, &tmp_ut_info, ut_info1, wall_name, check_type);
} else if (!(ut_info0->attribute >= mCoBG_ATTRIBUTE_27 && ut_info0->attribute <= mCoBG_ATTRIBUTE_35) && !(ut_info1->attribute >= mCoBG_ATTRIBUTE_27 && ut_info1->attribute <= mCoBG_ATTRIBUTE_35)) {
mCoBG_UnitInf2NormalVector(vec_info, ut_info0, ut_info1, wall_name, check_type);
}
} else {
mCoBG_UnitInf2NormalVector(vec_info, ut_info0, ut_info1, wall_name, check_type);
}
}
}
static void mCoBG_RegistSlatingWallVector_AttributeOn_NoSlate(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type, s16 old_in_water) {
// nothing
}
static void mCoBG_RegistSlatingWallVector_AttributeOn_Slate(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type, s16 old_in_water) {
if (vec_info->unit_count < mCoBG_UNIT_VEC_INFO_MAX) {
mCoBG_unit_vec_info_c* unit_vec = vec_info->unit;
int* unit_count_p = &vec_info->unit_count;
unit_vec[*unit_count_p].wall_name = mCoBG_SearchSlateDetail(&ut_info->collision->data);
mCoBG_GetUnitVecInf_SlatingWall(&unit_vec[*unit_count_p], ut_info, unit_vec[*unit_count_p].wall_name, check_type);
unit_vec[0].regist_p = NULL; // @BUG: ??? shouldn't this be unit_vec->regist_p = NULL;
(*unit_count_p)++;
}
}
typedef void (*mCoBG_ATTRON_MAKE_SLATE_WALL_PROC)(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type, s16 old_in_water);
static void mCoBG_RegistSlatingWallVector_AttributeOn(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type, s16 old_in_water) {
static mCoBG_ATTRON_MAKE_SLATE_WALL_PROC attron_make_slate_wall_proc_table[] = { &mCoBG_RegistSlatingWallVector_AttributeOn_NoSlate, &mCoBG_RegistSlatingWallVector_AttributeOn_Slate };
(*attron_make_slate_wall_proc_table[ut_info->slate_flag & 1])(vec_info, ut_info, check_type, old_in_water);
}
static void mCoBG_RegistSlatingWallVector_AttributeOff_Slate_NoOldInWater(mCoBG_unit_vec_info_c* unit_vec, mCoBG_UnitInfo_c* ut_info, int* unit_count_p, u8 check_type) {
unit_vec->wall_name = mCoBG_SearchSlateDetail(&ut_info->collision->data);
mCoBG_GetUnitVecInf_SlatingWall(unit_vec, ut_info, unit_vec->wall_name, check_type);
unit_vec->regist_p = NULL;
(*unit_count_p)++;
}
static void mCoBG_RegistSlatingWallVector_AttributeOff_Slate_OldInWater(mCoBG_unit_vec_info_c* unit_vec, mCoBG_UnitInfo_c* ut_info, int* unit_count_p, u8 check_type) {
if (ut_info->attribute >= mCoBG_ATTRIBUTE_27 && ut_info->attribute <= mCoBG_ATTRIBUTE_35) {
return;
}
unit_vec->wall_name = mCoBG_SearchSlateDetail(&ut_info->collision->data);
mCoBG_GetUnitVecInf_SlatingWall(unit_vec, ut_info, unit_vec->wall_name, check_type);
unit_vec->regist_p = NULL;
(*unit_count_p)++;
}
typedef void (*mCoBG_MAKE_SLATE_WALL_PROC2)(mCoBG_unit_vec_info_c* unit_vec, mCoBG_UnitInfo_c* ut_info, int* unit_count_p, u8 check_type);
static void mCoBG_RegistSlatingWallVector_AttributeOff_Slate(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type, s16 old_in_water) {
static mCoBG_MAKE_SLATE_WALL_PROC2 make_slate_wall_proc_table2[] = { &mCoBG_RegistSlatingWallVector_AttributeOff_Slate_NoOldInWater, &mCoBG_RegistSlatingWallVector_AttributeOff_Slate_OldInWater };
mCoBG_unit_vec_info_c* all_unit_vec = vec_info->unit;
int* unit_count_p = &vec_info->unit_count;
mCoBG_unit_vec_info_c* unit_vec = &all_unit_vec[*unit_count_p];
if (*unit_count_p < mCoBG_UNIT_VEC_INFO_MAX) {
(*make_slate_wall_proc_table2[old_in_water & 1])(unit_vec, ut_info, unit_count_p, check_type);
}
}
static void mCoBG_RegistSlatingWallVector_AttributeOff_NoSlate(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type, s16 old_in_water) {
// nothing
}
static void mCoBG_RegistSlatingWallVector_AttributeOff(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type, s16 old_in_water) {
static mCoBG_ATTRON_MAKE_SLATE_WALL_PROC make_slate_wall_proc_table[] = { &mCoBG_RegistSlatingWallVector_AttributeOff_NoSlate, &mCoBG_RegistSlatingWallVector_AttributeOff_Slate };
(*make_slate_wall_proc_table[ut_info->slate_flag & 1])(vec_info, ut_info, check_type, old_in_water);
}
static u8* mCoBG_GetUnitInfSearchData(int count) {
switch (count) {
case 3:
return l_make33_coldata;
case 5:
return l_make55_coldata;
case 7:
return l_make77_coldata;
default:
return l_make33_coldata;
}
}
static void mCoBG_MakeForbidVectorData(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type) {
u8 attribute = ut_info->attribute;
int* unit_count_p = &vec_info->unit_count;
mCoBG_unit_vec_info_c* unit_vec = &vec_info->unit[*unit_count_p];
f32 ux = ut_info->ut_x;
f32 uz = ut_info->ut_z;
int forbid_idx_idx = attribute - mCoBG_ATTRIBUTE_27;
int i;
for (i = 0; i < 2; i++) {
s16* data = mCoBG_forbid_vector_idx[forbid_idx_idx];
s16 idx = data[i];
if (idx != -1) {
mCoBG_forbid_vec_data_c* forbid_data = &mCoBG_make_vector_table[idx];
unit_vec->normal[0] = forbid_data->norm[0];
unit_vec->normal[1] = forbid_data->norm[1];
unit_vec->normal_angle = forbid_data->norm_angle;
unit_vec->wall_name = forbid_data->wall_name;
mCoBG_UnitNoName2StartEnd(unit_vec->start, unit_vec->end, ux, uz, unit_vec->wall_name, check_type);
unit_vec->atr_wall = TRUE;
unit_vec->regist_p = NULL;
unit_vec++;
(*unit_count_p)++;
}
}
}
static void mCoBG_MakeForbidAttrVector_DUMMY(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type) {
// nothing
}
static void mCoBG_MakeForbidAttrVector(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type) {
u32 attribute = ut_info->attribute;
if (attribute >= mCoBG_ATTRIBUTE_27 && attribute <= mCoBG_ATTRIBUTE_62) {
mCoBG_MakeForbidVectorData(vec_info, ut_info, check_type);
}
}
typedef void (*mCoBG_REGIST_NORMAL_WALL_PROC)(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info0, mCoBG_UnitInfo_c* ut_info1, s16 wall_name, u8 check_type, s16 old_in_water);
typedef void (*mCoBG_REGIST_SLATE_WALL_PROC)(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type, s16 old_in_water);
typedef void (*mCoBG_MAKE_FORBID_ATTR_VECTOR_PROC)(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, u8 check_type);
static void mCoBG_MakeUnitVector(mCoBG_vec_info_c* vec_info, mCoBG_UnitInfo_c* ut_info, s16 ut_count, u8 check_type, s16 attr_wall, s16 old_on_ground, s16 old_in_water) {
static mCoBG_REGIST_NORMAL_WALL_PROC make_normal_wall[] = { &mCoBG_RegistNormalWallVector_AttributeOff, &mCoBG_RegistNormalWallVector_AttributeOn };
static mCoBG_REGIST_SLATE_WALL_PROC make_slate_wall[] = { &mCoBG_RegistSlatingWallVector_AttributeOff, &mCoBG_RegistSlatingWallVector_AttributeOn };
int unit;
int ut_count2 = SQ(ut_count);
u8* make_info_p;
int forbid_proc = (old_on_ground & attr_wall) & 1;
mCoBG_UnitInfo_c* ut_info_p = ut_info;
int bx;
int bz;
vec_info->unit_count = 0;
make_info_p = mCoBG_GetUnitInfSearchData(ut_count);
if (mFI_Wpos2BlockNum(&bx, &bz, l_ActorInf.center_pos)) {
u32 kind = mFI_BkNum2BlockKind(bx, bz);
if ((kind & mRF_BLOCKKIND_DOCK) != 0 || (kind & mRF_BLOCKKIND_ISLAND) != 0) {
old_in_water = FALSE;
}
}
for (unit = 0; unit < ut_count2; unit++) {
static mCoBG_MAKE_FORBID_ATTR_VECTOR_PROC make_forbid_atr_vector_proc[] = { &mCoBG_MakeForbidAttrVector_DUMMY, &mCoBG_MakeForbidAttrVector };
(*make_slate_wall[attr_wall])(vec_info, ut_info_p, check_type, old_in_water);
if (make_info_p[0] & 1) {
(*make_normal_wall[attr_wall])(vec_info, ut_info_p, &ut_info[unit - ut_count], mCoBG_WALL_UP, check_type, old_in_water);
}
if (make_info_p[0] & 2) {
(*make_normal_wall[attr_wall])(vec_info, ut_info_p, &ut_info[unit - 1], mCoBG_WALL_LEFT, check_type, old_in_water);
}
if (make_info_p[0] & 4) {
(*make_normal_wall[attr_wall])(vec_info, ut_info_p, &ut_info[unit + ut_count], mCoBG_WALL_DOWN, check_type, old_in_water);
}
if (make_info_p[0] & 8) {
(*make_normal_wall[attr_wall])(vec_info, ut_info_p, &ut_info[unit + 1], mCoBG_WALL_RIGHT, check_type, old_in_water);
}
(*make_forbid_atr_vector_proc[forbid_proc])(vec_info, ut_info_p, check_type);
make_info_p++;
ut_info_p++;
}
}
typedef struct {
int dx;
int dz;
s16 normal_angle0;
f32 normal0[2];
u8 wall_name0;
s16 normal_angle1;
f32 normal1[2];
u8 wall_name1;
} mCoBG_defence_wall_info_c;
static int mCoBG_CircleDefenceWallIdx(int dx, int dz, s16* normal0_p, f32* normal0, u8* wall_name0_p, s16* normal1_p, f32* normal1, u8* wall_name1_p) {
int i;
// clang-format off
static mCoBG_defence_wall_info_c defence_wall_info[] = {
{ 1, 0, DEG2SHORT_ANGLE2(0.0f), { 0.0f, 1.0f}, mCoBG_WALL_UP, DEG2SHORT_ANGLE2(180.0f), { 0.0f, -1.0f}, mCoBG_WALL_UP},
{-1, 0, DEG2SHORT_ANGLE2(0.0f), { 0.0f, 1.0f}, mCoBG_WALL_UP, DEG2SHORT_ANGLE2(180.0f), { 0.0f, -1.0f}, mCoBG_WALL_UP},
{ 0, 1, DEG2SHORT_ANGLE2(90.0f), { 1.0f, 0.0f}, mCoBG_WALL_RIGHT, DEG2SHORT_ANGLE2(-90.0f), { -1.0f, 0.0f}, mCoBG_WALL_RIGHT},
{ 0, -1, DEG2SHORT_ANGLE2(90.0f), { 1.0f, 0.0f}, mCoBG_WALL_RIGHT, DEG2SHORT_ANGLE2(-90.0f), { -1.0f, 0.0f}, mCoBG_WALL_RIGHT},
{ 1, 1, DEG2SHORT_ANGLE2(135.0f), { SQRT_OF_2_DIV_2, -SQRT_OF_2_DIV_2}, mCoBG_WALL_SLATE_DOWN, DEG2SHORT_ANGLE2(-45.0f), {-SQRT_OF_2_DIV_2, SQRT_OF_2_DIV_2}, mCoBG_WALL_SLATE_DOWN},
{-1, -1, DEG2SHORT_ANGLE2(135.0f), { SQRT_OF_2_DIV_2, -SQRT_OF_2_DIV_2}, mCoBG_WALL_SLATE_DOWN, DEG2SHORT_ANGLE2(-45.0f), {-SQRT_OF_2_DIV_2, SQRT_OF_2_DIV_2}, mCoBG_WALL_SLATE_DOWN},
{ 1, -1, DEG2SHORT_ANGLE2(-135.0f), {-SQRT_OF_2_DIV_2, -SQRT_OF_2_DIV_2}, mCoBG_WALL_SLATE_UP, DEG2SHORT_ANGLE2(45.0f), { SQRT_OF_2_DIV_2, SQRT_OF_2_DIV_2}, mCoBG_WALL_SLATE_UP},
{-1, 1, DEG2SHORT_ANGLE2(-135.0f), {-SQRT_OF_2_DIV_2, -SQRT_OF_2_DIV_2}, mCoBG_WALL_SLATE_UP, DEG2SHORT_ANGLE2(45.0f), { SQRT_OF_2_DIV_2, SQRT_OF_2_DIV_2}, mCoBG_WALL_SLATE_UP},
};
// clang-format on
mCoBG_defence_wall_info_c* defence_p = defence_wall_info;
for (i = 0; i < ARRAY_COUNT(defence_wall_info); i++) {
if (dx == defence_p->dx && dz == defence_p->dz) {
*normal0_p = defence_p->normal_angle0;
normal0[0] = defence_p->normal0[0];
normal0[1] = defence_p->normal0[1];
*wall_name0_p = defence_p->wall_name0;
*normal1_p = defence_p->normal_angle1;
normal1[0] = defence_p->normal1[0];
normal1[1] = defence_p->normal1[1];
*wall_name1_p = defence_p->wall_name1;
return i;
}
defence_p++;
}
return -1;
}
static void mCoBG_MakeCircleDefenceWall(mCoBG_ActorInf_c* actor_info, s16 attr_wall) {
if (attr_wall && actor_info->old_on_ground) {
mCoBG_column_c* col0;
mCoBG_column_c* col1;
int col_count = l_VecInf.col_count;
mCoBG_unit_vec_info_c* all_unit_vec = l_VecInf.unit;
int* unit_count_p = &l_VecInf.unit_count;
mCoBG_unit_vec_info_c* unit_vec;
int i0;
int i1;
int dx;
int dz;
s16 normal_angle0;
s16 normal_angle1;
f32 normal0[2];
f32 normal1[2];
u8 wall_name0;
u8 wall_name1;
col0 = l_VecInf.column;
for (i0 = 0; i0 < col_count; i0++) {
col1 = l_VecInf.column;
for (i1 = 0; i1 < col_count; i1++) {
if (i0 != i1 && mCoBG_CircleDefenceWallIdx(col0->ux - col1->ux, col0->uz - col1->uz, &normal_angle0, normal0, &wall_name0, &normal_angle1, normal1, &wall_name1) != -1) {
if (*unit_count_p < mCoBG_UNIT_VEC_INFO_MAX) {
unit_vec = &all_unit_vec[*unit_count_p];
unit_vec->start[0] = col0->pos.x;
unit_vec->start[1] = col0->pos.z;
unit_vec->end[0] = col1->pos.x;
unit_vec->end[1] = col1->pos.z;
unit_vec->normal[0] = normal0[0];
unit_vec->normal[1] = normal0[1];
unit_vec->normal_angle = normal_angle0;
unit_vec->regist_p = NULL;
unit_vec->atr_wall = TRUE;
unit_vec->wall_name = wall_name0;
(*unit_count_p)++;
}
if (*unit_count_p < mCoBG_UNIT_VEC_INFO_MAX) {
unit_vec = &all_unit_vec[*unit_count_p];
unit_vec->start[0] = col0->pos.x;
unit_vec->start[1] = col0->pos.z;
unit_vec->end[0] = col1->pos.x;
unit_vec->end[1] = col1->pos.z;
unit_vec->normal[0] = normal1[0];
unit_vec->normal[1] = normal1[1];
unit_vec->normal_angle = normal_angle1;
unit_vec->regist_p = NULL;
unit_vec->atr_wall = TRUE;
unit_vec->wall_name = wall_name1;
(*unit_count_p)++;
}
}
col1++;
}
col0++;
}
}
}
+184
View File
@@ -0,0 +1,184 @@
extern f32 mCoBG_GetBgY_AngleS_FromWpos2(s_xyz* ground_angle, xyz_t pos, f32 ground_dist) {
mCoBG_UnitInfo_c ut_info;
s_xyz normal_ground_angle;
f32 normal_y;
f32 column_y;
static s_xyz ground_angle0 = { 0, 0, 0 };
f32 t0;
f32 t1;
f32 ret;
if (ground_angle != NULL) {
*ground_angle = ground_angle0;
}
mCoBG_Wpos2UnitInfo(&ut_info, pos);
normal_y = mCoBG_GetBGHeight_Normal(&normal_ground_angle, &ut_info);
column_y = mCoBG_GetBGHeight_Column(&pos, &ut_info);
if (ground_angle != NULL && normal_y >= column_y && normal_y >= -100.0f) {
*ground_angle = normal_ground_angle;
return normal_y - ground_dist;
}
t0 = MAX(normal_y, -100.0f);
t1 = MAX(normal_y, column_y);
if (t1 > t0) {
ret = MAX(normal_y, column_y);
} else {
ret = MAX(normal_y, -100.0f);
}
return ret - ground_dist;
}
extern f32 mCoBG_GetWaterHeight_File(xyz_t pos, char* file, int line) {
u32 attr;
int ux;
int uz;
mCoBG_Collision_u* col;
xyz_t mod_pos = pos;
mFI_Wpos2UtNum(&ux, &uz, pos);
col = mFI_UtNum2UtCol(ux, uz);
attr = col->data.unit_attribute;
if (attr == mCoBG_ATTRIBUTE_SEA || attr == mCoBG_ATTRIBUTE_37 || attr == mCoBG_ATTRIBUTE_38) {
return 20.0f;
}
if (attr >= mCoBG_ATTRIBUTE_WATER && attr <= mCoBG_ATTRIBUTE_RIVER_NE) {
return 20.0f + mCoBG_GetBgY_AngleS_FromWpos2(NULL, pos, 0.0f);
}
if (attr >= mCoBG_ATTRIBUTE_27 && attr <= mCoBG_ATTRIBUTE_35) {
int idx = attr - mCoBG_ATTRIBUTE_27;
int search = mCoBG_bridge_search_water[idx];
u32 new_attr;
int i;
for (i = 0; i < mSc_DIRECT_NUM; i++) {
if ((search & (1 << i)) != 0) {
int ux;
int uz;
mCoBG_PlussDirectOffset(&mod_pos, pos, i);
mFI_Wpos2UtNum(&ux, &uz, mod_pos);
new_attr = mFI_UtNum2UtCol(ux, uz)->data.unit_attribute;
if (new_attr >= mCoBG_ATTRIBUTE_WATER && new_attr <= mCoBG_ATTRIBUTE_RIVER_NE) {
return 20.0f + mCoBG_GetBgY_AngleS_FromWpos2(NULL, mod_pos, 0.0f);
}
}
}
} else if (attr >= mCoBG_ATTRIBUTE_39 && attr <= mCoBG_ATTRIBUTE_42) {
u32 attr2 = mCoBG_Wpos2Attribute(pos, NULL);
if (attr2 >= mCoBG_ATTRIBUTE_WATER && attr2 <= mCoBG_ATTRIBUTE_RIVER_NE) {
int i;
u32 new_attr;
xyz_t new_pos;
int idx = attr - mCoBG_ATTRIBUTE_39;
int search = mCoBG_grass3_search_water[idx];
for (i = 0; i < mSc_DIRECT_NUM; i++) {
if ((search & (1 << i)) != 0) {
int ux;
int uz;
mCoBG_PlussDirectOffset(&new_pos, pos, i);
mFI_Wpos2UtNum(&ux, &uz, new_pos);
new_attr = mFI_UtNum2UtCol(ux, uz)->data.unit_attribute;
if (new_attr >= mCoBG_ATTRIBUTE_WATER && new_attr <= mCoBG_ATTRIBUTE_RIVER_NE) {
return 20.0f + mCoBG_GetBgY_AngleS_FromWpos2(NULL, new_pos, 0.0f);
}
}
}
}
}
return -100.0f;
}
extern int mCoBG_CheckWaterAttribute(u32 attr) {
if (attr == mCoBG_ATTRIBUTE_SEA) {
return TRUE;
}
if (attr >= mCoBG_ATTRIBUTE_WATER && attr <= mCoBG_ATTRIBUTE_RIVER_NE) {
return TRUE;
}
return FALSE;
}
extern int mCoBG_CheckWaterAttribute_OutOfSea(u32 attr) {
if (attr >= mCoBG_ATTRIBUTE_WATER && attr <= mCoBG_ATTRIBUTE_RIVER_NE) {
return TRUE;
}
return FALSE;
}
static f32 mCoBG_wave_cos = 0.0f;
extern void mCoBG_WaveCos2BgCheck(f32 value) {
mCoBG_wave_cos = value;
}
extern f32 mCoBG_WaveCos(void) {
return mCoBG_wave_cos;
}
extern int mCoBG_GetWaterFlow(xyz_t* flow, u32 attr) {
static xyz_t flow_data[] = {
{0.0f, 0.0f, 0.0f},
{0.0f, -5.0f, 0.0f},
{0.0f, 0.0f, -0.5f},
{-0.35355338f, 0.0f, -0.35355338f},
{-0.5f, 0.0f, 0.0f},
{-0.35355338f, 0.0f, 0.35355338f},
{0.0f, 0.0f, 0.5f},
{0.35355338f, 0.0f, 0.35355338f},
{0.5f, 0.0f, 0.0f},
{0.35355338f, 0.0f, -0.35355338f},
};
if (attr == mCoBG_ATTRIBUTE_SEA) {
static const xyz_t sea_flow = { 0.0f, 0.0f, -1.0f };
*flow = sea_flow;
return TRUE;
}
if (mCoBG_CheckWaterAttribute(attr)) {
int idx = attr - mCoBG_ATTRIBUTE_WATER;
*flow = flow_data[idx];
return TRUE;
}
*flow = flow_data[0];
return FALSE;
}
extern int mCoBG_CheckWaveAttr(u32 attr) {
if (attr == mCoBG_ATTRIBUTE_WAVE || attr == mCoBG_ATTRIBUTE_36 || attr == mCoBG_ATTRIBUTE_25 || attr == mCoBG_ATTRIBUTE_26) {
return TRUE;
}
return FALSE;
}
// @unused, @fabricated
extern int mCoBG_CheckSand2Sea(xyz_t* pos) {
u32 attr = mCoBG_Wpos2BgAttribute_Original(*pos);
if (attr == mCoBG_ATTRIBUTE_SEA || mCoBG_CheckWaveAttr(attr)) {
return TRUE;
}
return FALSE;
}
+2 -2
View File
@@ -4650,7 +4650,7 @@ extern int mNpc_GetMakeUtNuminBlock_hard_area(int* ut_x, int* ut_z, int bx, int
/* Check that the height of each point on the unit is equal*/
if ((int)center == col_p->data.top_left && center == col_p->data.bot_left &&
center == col_p->data.top_right && (int)center == col_p->data.bot_right) {
center == col_p->data.bot_right && (int)center == col_p->data.top_right) {
now_ut_x = 8 - j;
now_ut_z = 8 - i;
@@ -4839,7 +4839,7 @@ extern int mNpc_GetMakeUtNuminBlock_hide_hard_area(int* ut_x, int* ut_z, int bx,
/* Check that the height of each point on the unit is equal*/
if ((int)center == col_p->data.top_left && center == col_p->data.bot_left &&
center == col_p->data.top_right && (int)center == col_p->data.bot_right &&
center == col_p->data.bot_right && (int)center == col_p->data.top_right &&
((hide_ut_bit[i] >> j) & 1) == 1) {
now_ut_x = 8 - j;
+3 -3
View File
@@ -160,7 +160,7 @@ static int Player_actor_check_bg_for_next_goto(ACTOR* actor, mActor_name_t door)
if (door >= DOOR_START && door < EXIT_DOOR) {
col = mFI_GetUnitCol(actor->world.position);
if (col->data.center != col->data.top_left || col->data.center != col->data.bot_left ||
col->data.center != col->data.top_right || col->data.center != col->data.bot_right) {
col->data.center != col->data.bot_right || col->data.center != col->data.top_right) {
return TRUE;
}
return FALSE;
@@ -190,9 +190,9 @@ static void Player_actor_check_nextgoto(ACTOR* actor, GAME* game) {
mFI_GetUnitCol(actor->world.position)->data.center !=
mFI_GetUnitCol(actor->world.position)->data.bot_left ||
mFI_GetUnitCol(actor->world.position)->data.center !=
mFI_GetUnitCol(actor->world.position)->data.top_right ||
mFI_GetUnitCol(actor->world.position)->data.bot_right ||
mFI_GetUnitCol(actor->world.position)->data.center !=
mFI_GetUnitCol(actor->world.position)->data.bot_right) &&
mFI_GetUnitCol(actor->world.position)->data.top_right) &&
mFI_GET_TYPE(mFI_GetFieldId()) == mFI_FIELD_PLAYER0_ROOM) {
aMR_SaveWaltzTempo2();
mBGMPsComp_make_ps_wipe(0x10E);
+17 -5
View File
@@ -609,14 +609,26 @@ Mtx* _Matrix_to_Mtx_new(GRAPH* graph) {
return _Matrix_to_Mtx(GRAPH_ALLOC(graph, sizeof(Mtx)));
}
void Matrix_Position(xyz_t* old_pos, xyz_t* new_pos) {
MtxF* curm = Matrix_now;
void Matrix_Position(xyz_t* input_position, xyz_t* output_position) {
MtxF* current_matrix = Matrix_now;
new_pos->x = (curm->xx * old_pos->x) + (curm->xy * old_pos->y) + (curm->xz * old_pos->z) + curm->xw;
new_pos->y = (curm->yx * old_pos->x) + (curm->yy * old_pos->y) + (curm->yz * old_pos->z) + curm->yw;
new_pos->z = (curm->zx * old_pos->x) + (curm->zy * old_pos->y) + (curm->zz * old_pos->z) + curm->zw;
output_position->x = (current_matrix->xx * input_position->x) +
(current_matrix->xy * input_position->y) +
(current_matrix->xz * input_position->z) +
current_matrix->xw;
output_position->y = (current_matrix->yx * input_position->x) +
(current_matrix->yy * input_position->y) +
(current_matrix->yz * input_position->z) +
current_matrix->yw;
output_position->z = (current_matrix->zx * input_position->x) +
(current_matrix->zy * input_position->y) +
(current_matrix->zz * input_position->z) +
current_matrix->zw;
}
void Matrix_Position_Zero(xyz_t* v) {
MtxF* curm = Matrix_now;