Skip to content
This repository has been archived by the owner on Oct 4, 2024. It is now read-only.

Commit

Permalink
port Box_CalculateTarget
Browse files Browse the repository at this point in the history
  • Loading branch information
rr- committed Apr 15, 2024
1 parent b8076d0 commit e0d550c
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 10 deletions.
16 changes: 8 additions & 8 deletions docs/progress.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/progress.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1748,7 +1748,7 @@ typedef enum GAME_OBJECT_ID {
0040E8A0 000000A4 + int32_t __cdecl Box_EscapeBox(const struct ITEM_INFO *item, const struct ITEM_INFO *enemy, int16_t box_num);
0040E950 000000A7 + int32_t __cdecl Box_ValidBox(const struct ITEM_INFO *item, int16_t zone_num, int16_t box_num);
0040EA00 0000043F - void __cdecl CreatureMood(struct ITEM_INFO *item, struct AI_INFO *info, int32_t violent);
0040EE70 00000459 - enum TARGET_TYPE __cdecl Box_CalculateTarget(struct XYZ_32 *target, struct ITEM_INFO *item, struct LOT_INFO *lot);
0040EE70 00000459 + enum TARGET_TYPE __cdecl Box_CalculateTarget(struct XYZ_32 *target, struct ITEM_INFO *item, struct LOT_INFO *lot);
0040F2D0 000000F8 - int32_t __cdecl Creature_CheckBaddieOverlap(int16_t item_num);
0040F3D0 0000008B - int32_t __cdecl Box_BadFloor(int32_t x, int32_t y, int32_t z, int32_t box_height, int32_t next_height, int16_t room_num, struct LOT_INFO *lot);
0040F460 000000B8 - void __cdecl Creature_Die(int16_t item_num, int32_t explode);
Expand Down
179 changes: 179 additions & 0 deletions src/game/box.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@
#define BOX_NUM_BITS (~BOX_END_BIT) // = 0x7FFF
#define BOX_STALK_DIST 3 // tiles
#define BOX_ESCAPE_DIST 5 // tiles
#define BOX_MAX_EXPANSION 5

#define BOX_BIFF (WALL_L / 2) // = 0x200 = 512
#define BOX_CLIP_LEFT 1
#define BOX_CLIP_RIGHT 2
#define BOX_CLIP_TOP 4
#define BOX_CLIP_BOTTOM 8
#define BOX_CLIP_ALL \
(BOX_CLIP_LEFT | BOX_CLIP_RIGHT | BOX_CLIP_TOP | BOX_CLIP_BOTTOM) // = 15
#define BOX_CLIP_SECONDARY 16

int32_t __cdecl Box_SearchLOT(
struct LOT_INFO *const lot, const int32_t expansion)
Expand Down Expand Up @@ -212,3 +222,172 @@ int32_t __cdecl Box_ValidBox(
&& item->pos.x > (box->top << WALL_SHIFT)
&& item->pos.x < (box->bottom << WALL_SHIFT));
}

enum TARGET_TYPE __cdecl Box_CalculateTarget(
struct XYZ_32 *const target, const struct ITEM_INFO *const item,
struct LOT_INFO *const lot)
{
Box_UpdateLOT(lot, BOX_MAX_EXPANSION);

*target = item->pos;

int32_t box_num = item->box_num;
if (box_num == NO_BOX) {
return TARGET_NONE;
}

int32_t bottom = 0;
int32_t top = 0;
int32_t right = 0;
int32_t left = 0;

struct BOX_INFO *box = NULL;
int32_t box_left = 0;
int32_t box_right = 0;
int32_t box_top = 0;
int32_t box_bottom = 0;

int32_t prime_free = BOX_CLIP_ALL;
do {
box = &g_Boxes[box_num];
int32_t height = box->height;
if (lot->fly != 0) {
height -= WALL_L;
}
if (target->y > height - WALL_L) {
target->y = height - WALL_L;
}

box_left = box->left << WALL_SHIFT;
box_right = (box->right << WALL_SHIFT) - 1;
box_top = box->top << WALL_SHIFT;
box_bottom = (box->bottom << WALL_SHIFT) - 1;

if (item->pos.z >= box_left && item->pos.z <= box_right
&& item->pos.x >= box_top && item->pos.x <= box_bottom) {
left = box_left;
right = box_right;
top = box_top;
bottom = box_bottom;
} else {
if (item->pos.z < box_left) {
if ((prime_free & BOX_CLIP_LEFT) != 0 && item->pos.x >= box_top
&& item->pos.x <= box_bottom) {
CLAMPL(target->z, box_left + BOX_BIFF);
if ((prime_free & BOX_CLIP_SECONDARY) != 0) {
return TARGET_SECONDARY;
}
CLAMPL(top, box_top);
CLAMPG(bottom, box_bottom);
prime_free = BOX_CLIP_LEFT;
} else if (prime_free != BOX_CLIP_LEFT) {
target->z = right - BOX_BIFF;
if (prime_free != BOX_CLIP_ALL) {
return TARGET_SECONDARY;
}
prime_free |= BOX_CLIP_SECONDARY;
}
} else if (item->pos.z > box_right) {
if ((prime_free & BOX_CLIP_RIGHT) != 0 && item->pos.x >= box_top
&& item->pos.x <= box_bottom) {
CLAMPG(target->z, box_right - BOX_BIFF);
if ((prime_free & BOX_CLIP_SECONDARY) != 0) {
return TARGET_SECONDARY;
}
CLAMPL(top, box_top);
CLAMPG(bottom, box_bottom);
prime_free = BOX_CLIP_RIGHT;
} else if (prime_free != BOX_CLIP_RIGHT) {
target->z = left + BOX_BIFF;
if (prime_free != BOX_CLIP_ALL) {
return TARGET_SECONDARY;
}
prime_free |= BOX_CLIP_SECONDARY;
}
}

if (item->pos.x < box_top) {
if ((prime_free & BOX_CLIP_TOP) != 0
&& (item->pos.z >= box_left) && item->pos.z <= box_right) {
CLAMPL(target->x, box_top + BOX_BIFF);
if ((prime_free & BOX_CLIP_SECONDARY) != 0) {
return TARGET_SECONDARY;
}
CLAMPL(left, box_left);
CLAMPG(right, box_right);
prime_free = BOX_CLIP_TOP;
} else if (prime_free != BOX_CLIP_TOP) {
target->x = bottom - BOX_BIFF;
if (prime_free != BOX_CLIP_ALL) {
return TARGET_SECONDARY;
}
prime_free |= BOX_CLIP_SECONDARY;
}
} else if (item->pos.x > box_bottom) {
if ((prime_free & BOX_CLIP_BOTTOM) != 0
&& item->pos.z >= box_left && item->pos.z <= box_right) {
CLAMPG(target->x, box_bottom - BOX_BIFF);
if ((prime_free & BOX_CLIP_SECONDARY) != 0) {
return TARGET_SECONDARY;
}
CLAMPL(left, box_left);
CLAMPG(right, box_right);
prime_free = BOX_CLIP_BOTTOM;
} else if (prime_free != BOX_CLIP_BOTTOM) {
target->x = top + BOX_BIFF;
if (prime_free != BOX_CLIP_ALL) {
return TARGET_SECONDARY;
}
prime_free |= BOX_CLIP_SECONDARY;
}
}
}

if (box_num == lot->target_box) {
if ((prime_free & (BOX_CLIP_LEFT | BOX_CLIP_RIGHT)) != 0) {
target->z = lot->target.z;
} else if ((prime_free & BOX_CLIP_SECONDARY) == 0) {
CLAMP(target->z, box_left + BOX_BIFF, box_right - BOX_BIFF);
}

if ((prime_free & (BOX_CLIP_TOP | BOX_CLIP_BOTTOM)) != 0) {
target->x = lot->target.x;
} else if ((prime_free & BOX_CLIP_SECONDARY) == 0) {
CLAMP(target->x, box_top + BOX_BIFF, box_bottom - BOX_BIFF);
}

target->y = lot->target.y;
return TARGET_PRIMARY;
}

box_num = lot->node[box_num].exit_box;
if (box_num != NO_BOX
&& (g_Boxes[box_num].overlap_index & lot->block_mask) != 0) {
break;
}
} while (box_num != NO_BOX);

if ((prime_free & (BOX_CLIP_LEFT | BOX_CLIP_RIGHT)) != 0) {
target->z =
(((box_right - box_left - WALL_L) * Random_GetControl()) >> 15)
+ box_left + WALL_L / 2;
} else if ((prime_free & BOX_CLIP_SECONDARY) == 0) {
CLAMP(target->z, box_left + BOX_BIFF, box_right - BOX_BIFF);
}

if ((prime_free & (BOX_CLIP_TOP | BOX_CLIP_BOTTOM)) != 0) {
target->x =
(((box_bottom - box_top - WALL_L) * Random_GetControl()) >> 15)
+ box_top + WALL_L / 2;
} else if ((prime_free & BOX_CLIP_SECONDARY) == 0) {
CLAMP(target->x, box_top + BOX_BIFF, box_bottom - BOX_BIFF);
}

if (lot->fly != 0) {
target->y = box->height - STEP_L * 3 / 2;
} else {
target->y = box->height;
}

return TARGET_NONE;
}
2 changes: 2 additions & 0 deletions src/game/box.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ int32_t __cdecl Box_EscapeBox(
int16_t box_num);
int32_t __cdecl Box_ValidBox(
const struct ITEM_INFO *item, int16_t zone_num, int16_t box_num);
enum TARGET_TYPE __cdecl Box_CalculateTarget(
struct XYZ_32 *target, const struct ITEM_INFO *item, struct LOT_INFO *lot);
1 change: 0 additions & 1 deletion src/global/funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#define Boat_Control ((void __cdecl (*)(int16_t item_num))0x0040DAC0)
#define Gondola_Control ((void __cdecl (*)(int16_t item_num))0x0040E0F0)
#define CreatureMood ((void __cdecl (*)(struct ITEM_INFO *item, struct AI_INFO *info, int32_t violent))0x0040EA00)
#define Box_CalculateTarget ((enum TARGET_TYPE __cdecl (*)(struct XYZ_32 *target, struct ITEM_INFO *item, struct LOT_INFO *lot))0x0040EE70)
#define Creature_CheckBaddieOverlap ((int32_t __cdecl (*)(int16_t item_num))0x0040F2D0)
#define Box_BadFloor ((int32_t __cdecl (*)(int32_t x, int32_t y, int32_t z, int32_t box_height, int32_t next_height, int16_t room_num, struct LOT_INFO *lot))0x0040F3D0)
#define Creature_Die ((void __cdecl (*)(int16_t item_num, int32_t explode))0x0040F460)
Expand Down
1 change: 1 addition & 0 deletions src/inject_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@ static void Inject_Box(void)
INJECT(1, 0x0040E7A0, Box_StalkBox);
INJECT(1, 0x0040E8A0, Box_EscapeBox);
INJECT(1, 0x0040E950, Box_ValidBox);
INJECT(1, 0x0040EE70, Box_CalculateTarget);
}

static void Inject_Objects(void)
Expand Down

0 comments on commit e0d550c

Please sign in to comment.