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

Commit

Permalink
console/cmd: import /kill
Browse files Browse the repository at this point in the history
  • Loading branch information
rr- committed Sep 20, 2024
1 parent e376589 commit 41cd1a0
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/libtrx/game/console/cmd/kill.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include "../common.h"

extern CONSOLE_COMMAND g_Console_Cmd_Kill;
5 changes: 5 additions & 0 deletions include/libtrx/game/creature.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include "items.h"

bool Creature_IsEnemy(const ITEM_INFO *item);
6 changes: 6 additions & 0 deletions include/libtrx/game/game_string.def
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ GS_DEFINE(OSD_HEAL_ALREADY_FULL_HP, "Lara's already at full health")
GS_DEFINE(OSD_HEAL_SUCCESS, "Healed Lara back to full health")
GS_DEFINE(OSD_GIVE_ITEM, "Added %s to Lara's inventory")
GS_DEFINE(OSD_INVALID_ITEM, "Unknown item: %s")
GS_DEFINE(OSD_KILL_ALL, "Poof! %d enemies gone!")
GS_DEFINE(OSD_KILL_ALL_FAIL, "Uh-oh, there are no enemies left to kill...")
GS_DEFINE(OSD_KILL, "Bye-bye!")
GS_DEFINE(OSD_KILL_FAIL, "No enemy nearby...")
GS_DEFINE(OSD_INVALID_OBJECT, "Invalid object")
GS_DEFINE(OSD_OBJECT_NOT_FOUND, "Object not found")
5 changes: 5 additions & 0 deletions include/libtrx/game/items.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <stdbool.h>
#include <stdint.h>

#define NO_ITEM (-1)

#pragma pack(push, 1)

#if TR_VERSION == 1
Expand Down Expand Up @@ -93,4 +95,7 @@ typedef struct {

#pragma pack(pop)

ITEM_INFO *Item_Get(int16_t num);
int32_t Item_GetTotalCount(void);
int32_t Item_GetDistance(const ITEM_INFO *item, const XYZ_32 *target);
void Item_TakeDamage(ITEM_INFO *item, int16_t damage, bool hit_status);
4 changes: 4 additions & 0 deletions include/libtrx/game/lara/cheat.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#pragma once

#include <stdbool.h>
#include <stdint.h>

bool Lara_Cheat_GiveAllKeys(void);
bool Lara_Cheat_GiveAllGuns(void);
bool Lara_Cheat_GiveAllItems(void);
bool Lara_Cheat_KillEnemy(int16_t item_num);
1 change: 1 addition & 0 deletions include/libtrx/game/lara/misc.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma once

int16_t Lara_GetNearestEnemy(void);
void Lara_Extinguish(void);
2 changes: 2 additions & 0 deletions include/libtrx/game/objects/vars.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

#include "ids.h"

extern const GAME_OBJECT_ID g_EnemyObjects[];
extern const GAME_OBJECT_ID g_AllyObjects[];
extern const GAME_OBJECT_ID g_PickupObjects[];
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ sources = [
'src/game/console/cmd/config.c',
'src/game/console/cmd/give_item.c',
'src/game/console/cmd/heal.c',
'src/game/console/cmd/kill.c',
'src/game/console/cmd/pos.c',
'src/game/console/cmd/set_health.c',
'src/game/items.c',
Expand Down
125 changes: 125 additions & 0 deletions src/game/console/cmd/kill.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#include "game/console/cmd/kill.h"

#include "game/const.h"
#include "game/creature.h"
#include "game/game_string.h"
#include "game/items.h"
#include "game/lara/cheat.h"
#include "game/lara/common.h"
#include "game/lara/misc.h"
#include "game/objects/common.h"
#include "game/objects/ids.h"
#include "game/objects/names.h"
#include "game/objects/vars.h"
#include "memory.h"
#include "strings.h"

static bool M_CanTargetObjectCreature(GAME_OBJECT_ID object_id);
static COMMAND_RESULT M_Entrypoint(const char *args);

static bool M_CanTargetObjectCreature(const GAME_OBJECT_ID object_id)
{
return Object_IsObjectType(object_id, g_EnemyObjects)
|| Object_IsObjectType(object_id, g_AllyObjects);
}

static COMMAND_RESULT M_Entrypoint(const char *const args)
{
// kill all the enemies in the level
if (String_Equivalent(args, "all")) {
int32_t num_killed = 0;
for (int16_t item_num = 0; item_num < Item_GetTotalCount();
item_num++) {
const ITEM_INFO *const item = Item_Get(item_num);
if (!Creature_IsEnemy(item)) {
continue;
}
if (Lara_Cheat_KillEnemy(item_num)) {
num_killed++;
}
}

if (num_killed == 0) {
Console_Log(GS(OSD_KILL_ALL_FAIL));
return CR_FAILURE;
}

Console_Log(GS(OSD_KILL_ALL), num_killed);
return CR_SUCCESS;
}

// kill all the enemies around Lara within one tile, or a single nearest
// enemy
if (String_Equivalent(args, "")) {
bool found = false;
while (true) {
const int16_t best_item_num = Lara_GetNearestEnemy();
if (best_item_num == NO_ITEM) {
break;
}

const ITEM_INFO *const lara_item = Lara_GetItem();
const ITEM_INFO *const item = Item_Get(best_item_num);
const int32_t distance = Item_GetDistance(item, &lara_item->pos);
found |= Lara_Cheat_KillEnemy(best_item_num);
if (distance >= WALL_L) {
break;
}
}

if (!found) {
Console_Log(GS(OSD_KILL_FAIL));
return CR_FAILURE;
}

Console_Log(GS(OSD_KILL));
return CR_SUCCESS;
}

// kill a single enemy type
{
bool matches_found = false;
int32_t num_killed = 0;
int32_t match_count = 0;
GAME_OBJECT_ID *matching_objs =
Object_IdsFromName(args, &match_count, M_CanTargetObjectCreature);

for (int16_t item_num = 0; item_num < Item_GetTotalCount();
item_num++) {
const ITEM_INFO *const item = Item_Get(item_num);

bool is_matched = false;
for (int32_t i = 0; i < match_count; i++) {
if (matching_objs[i] == item->object_id) {
is_matched = true;
break;
}
}
if (!is_matched) {
continue;
}
matches_found = true;

if (Lara_Cheat_KillEnemy(item_num)) {
num_killed++;
}
}
Memory_FreePointer(&matching_objs);

if (!matches_found) {
Console_Log(GS(OSD_INVALID_OBJECT), args);
return CR_FAILURE;
}
if (num_killed == 0) {
Console_Log(GS(OSD_OBJECT_NOT_FOUND), args);
return CR_FAILURE;
}
Console_Log(GS(OSD_KILL_ALL), num_killed);
return CR_SUCCESS;
}
}

CONSOLE_COMMAND g_Console_Cmd_Kill = {
.prefix = "kill",
.proc = M_Entrypoint,
};

0 comments on commit 41cd1a0

Please # to comment.