Skip to content

Commit

Permalink
tr2: port Grenade_Control
Browse files Browse the repository at this point in the history
  • Loading branch information
rr- committed Oct 26, 2024
1 parent ee6beac commit a30da40
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 10 deletions.
16 changes: 8 additions & 8 deletions docs/tr2/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/tr2/progress.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3439,7 +3439,7 @@ typedef enum {
0x0042BF60 0x0187 + void __cdecl Gun_Rifle_FireHarpoon(void);
0x0042C0F0 0x0344 + void __cdecl HarpoonBolt_Control(int16_t item_num);
0x0042C440 0x00F0 + void __cdecl Gun_Rifle_FireGrenade(void);
0x0042C530 0x03FD - void __cdecl Rocket_Control(int16_t item_num);
0x0042C530 0x03FD + void __cdecl Grenade_Control(int16_t item_num);
0x0042C930 0x0166 + void __cdecl Gun_Rifle_Draw(LARA_GUN_TYPE weapon_type);
0x0042CAA0 0x0104 + void __cdecl Gun_Rifle_Undraw(LARA_GUN_TYPE weapon_type);
0x0042CBB0 0x037E + void __cdecl Gun_Rifle_Animate(LARA_GUN_TYPE weapon_type);
Expand Down
139 changes: 139 additions & 0 deletions src/tr2/game/objects/general/grenade.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#include "game/objects/general/grenade.h"

#include "game/creature.h"
#include "game/effects.h"
#include "game/gun/gun_misc.h"
#include "game/items.h"
#include "game/math.h"
#include "game/room.h"
#include "game/sound.h"
#include "global/funcs.h"
#include "global/vars.h"

#define M_BLAST_RADIUS (WALL_L / 2) // = 512
#define M_SPEED 200
#define M_FALL_SPEED (M_SPEED - 10) // = 190

static void M_Explode(int16_t grenade_item_num, XYZ_32 pos);

static void M_Explode(int16_t grenade_item_num, const XYZ_32 pos)
{
const ITEM *const grenade_item = Item_Get(grenade_item_num);
const int16_t fx_num = Effect_Create(grenade_item->room_num);
if (fx_num != NO_ITEM) {
FX *const fx = &g_Effects[fx_num];
fx->pos = pos;
fx->speed = 0;
fx->frame_num = 0;
fx->counter = 0;
fx->object_id = O_EXPLOSION;
}
Sound_Effect(SFX_EXPLOSION1, NULL, SPM_NORMAL);
Item_Kill(grenade_item_num);
}

void __cdecl Grenade_Control(int16_t item_num)
{
ITEM *const item = Item_Get(item_num);

const XYZ_32 old_pos = item->pos;

item->speed--;
if (item->speed < M_FALL_SPEED) {
item->fall_speed++;
}
item->pos.y +=
item->fall_speed - ((item->speed * Math_Sin(item->rot.x)) >> W2V_SHIFT);

const int16_t speed = (item->speed * Math_Cos(item->rot.x)) >> W2V_SHIFT;
item->pos.z += (speed * Math_Cos(item->rot.y)) >> W2V_SHIFT;
item->pos.x += (speed * Math_Sin(item->rot.y)) >> W2V_SHIFT;

int16_t room_num = item->room_num;
const SECTOR *const sector =
Room_GetSector(item->pos.x, item->pos.y, item->pos.z, &room_num);
item->floor = Room_GetHeight(sector, item->pos.x, item->pos.y, item->pos.z);
if (item->room_num != room_num) {
Item_NewRoom(item_num, room_num);
}

bool explode = false;
int32_t radius = 0;
if (item->pos.y >= item->floor
|| item->pos.y
<= Room_GetCeiling(sector, item->pos.x, item->pos.y, item->pos.z)) {
radius = M_BLAST_RADIUS;
explode = true;
}

for (int16_t target_item_num = Room_Get(item->room_num)->item_num;
target_item_num != NO_ITEM;
target_item_num = Item_Get(target_item_num)->next_item) {
ITEM *const target_item = Item_Get(target_item_num);
const OBJECT *const target_obj =
Object_GetObject(target_item->object_id);
if (target_item == g_LaraItem) {
continue;
}
if (!target_item->collidable) {
continue;
}

if (target_item->object_id != O_WINDOW_1
&& (!target_obj->intelligent || target_item->status == IS_INVISIBLE
|| target_obj->collision == NULL)) {
continue;
}

const FRAME_INFO *const frame = Item_GetBestFrame(target_item);
const BOUNDS_16 *const bounds = &frame->bounds;

const int32_t cdy = item->pos.y - target_item->pos.y;
if (cdy + radius < bounds->min_y || cdy - radius > bounds->max_y) {
continue;
}

const int32_t cy = Math_Cos(target_item->rot.y);
const int32_t sy = Math_Sin(target_item->rot.y);
const int32_t cdx = item->pos.x - target_item->pos.x;
const int32_t cdz = item->pos.z - target_item->pos.z;
const int32_t odx = old_pos.x - target_item->pos.x;
const int32_t odz = old_pos.z - target_item->pos.z;

const int32_t rx = (cy * cdx - sy * cdz) >> W2V_SHIFT;
const int32_t sx = (cy * odx - sy * odz) >> W2V_SHIFT;
if ((rx + radius < bounds->min_x && sx + radius < bounds->min_x)
|| (rx - radius > bounds->max_x && sx - radius > bounds->max_x)) {
continue;
}

const int32_t rz = (sy * cdx + cy * cdz) >> W2V_SHIFT;
const int32_t sz = (sy * odx + cy * odz) >> W2V_SHIFT;
if ((rz + radius < bounds->min_z && sz + radius < bounds->min_z)
|| (rz - radius > bounds->max_z && sz - radius > bounds->max_z)) {
continue;
}

if (target_item->object_id == O_WINDOW_1) {
SmashWindow(target_item_num);
} else {
// XXX: missing check if obj is intelligent?
Gun_HitTarget(target_item, NULL, 30);

explode = true;
g_SaveGame.statistics.hits++;

if (target_item->hit_points <= 0) {
g_SaveGame.statistics.kills++;
if (target_item->object_id != O_DRAGON_FRONT
&& target_item->object_id != O_GIANT_YETI) {
Creature_Die(target_item_num, true);
}
}
}
}

if (explode) {
M_Explode(item_num, old_pos);
}
}
5 changes: 5 additions & 0 deletions src/tr2/game/objects/general/grenade.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include "global/types.h"

void __cdecl Grenade_Control(const int16_t item_num);
1 change: 0 additions & 1 deletion src/tr2/global/funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@
#define InitialiseHair ((void __cdecl (*)(void))0x00420EA0)
#define HairControl ((void __cdecl (*)(int32_t in_cutscene))0x00420F20)
#define DrawHair ((void __cdecl (*)(void))0x00421920)
#define Rocket_Control ((void __cdecl (*)(int16_t item_num))0x0042C530)
#define Flare_DoLight ((int32_t __cdecl (*)(XYZ_32 *pos, int32_t flare_age))0x0042F7A0)
#define Flare_DoInHand ((void __cdecl (*)(int32_t flare_age))0x0042F840)
#define Flare_DrawInAir ((void __cdecl (*)(ITEM *item))0x0042F920)
Expand Down
2 changes: 2 additions & 0 deletions src/tr2/inject_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#include "game/objects/general/drawbridge.h"
#include "game/objects/general/final_level_counter.h"
#include "game/objects/general/gong_bonger.h"
#include "game/objects/general/grenade.h"
#include "game/objects/general/harpoon_bolt.h"
#include "game/objects/general/keyhole.h"
#include "game/objects/general/lift.h"
Expand Down Expand Up @@ -1024,6 +1025,7 @@ static void M_Objects(const bool enable)
INJECT(enable, 0x004183E0, Bartoli_Initialise);
INJECT(enable, 0x00418500, Bartoli_Control);
INJECT(enable, 0x0042C0F0, HarpoonBolt_Control);
INJECT(enable, 0x0042C530, Grenade_Control);
INJECT(enable, 0x004336F0, BodyPart_Control);
INJECT(enable, 0x004338F0, MovableBlock_Initialise);
INJECT(enable, 0x00433920, MovableBlock_Control);
Expand Down
1 change: 1 addition & 0 deletions src/tr2/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ dll_sources = [
'game/objects/general/drawbridge.c',
'game/objects/general/final_level_counter.c',
'game/objects/general/gong_bonger.c',
'game/objects/general/grenade.c',
'game/objects/general/harpoon_bolt.c',
'game/objects/general/keyhole.c',
'game/objects/general/lift.c',
Expand Down

0 comments on commit a30da40

Please sign in to comment.