creature: move Creature_CheckBaddieOverlap to trx

This commit is contained in:
Marcin Kurczewski 2025-04-08 23:22:33 +02:00
parent d4da3f874e
commit 2d37378223
21 changed files with 141 additions and 107 deletions

View file

@ -3,7 +3,7 @@
#include "game/lara/common.h" #include "game/lara/common.h"
#include "game/los.h" #include "game/los.h"
#include "game/objects/vars.h" #include "game/objects/vars.h"
#include "game/pathing/lot.h" #include "game/pathing.h"
#include "game/random.h" #include "game/random.h"
#include "game/rooms.h" #include "game/rooms.h"
#include "log.h" #include "log.h"
@ -14,6 +14,7 @@
#define M_ATTACK_RANGE SQUARE(WALL_L * 3) // = 0x900000 = 9437184 #define M_ATTACK_RANGE SQUARE(WALL_L * 3) // = 0x900000 = 9437184
#define M_ESCAPE_CHANCE 2048 #define M_ESCAPE_CHANCE 2048
#define M_RECOVER_CHANCE 256 #define M_RECOVER_CHANCE 256
#define M_TARGET_TOLERANCE 0x400000
#define M_MAX_TILT (3 * DEG_1) // = 546 #define M_MAX_TILT (3 * DEG_1) // = 546
#define M_MAX_HEAD_CHANGE (5 * DEG_1) // = 910 #define M_MAX_HEAD_CHANGE (5 * DEG_1) // = 910
#if TR_VERSION == 1 #if TR_VERSION == 1
@ -23,6 +24,8 @@
#endif #endif
#define M_MAX_X_ROT (20 * DEG_1) // = 3640 #define M_MAX_X_ROT (20 * DEG_1) // = 3640
static bool m_AlliesHostile = false;
static ITEM *M_ChooseEnemy(const ITEM *item); static ITEM *M_ChooseEnemy(const ITEM *item);
static bool M_SwitchToWater( static bool M_SwitchToWater(
int16_t item_num, const int32_t *wh, const HYBRID_INFO *info); int16_t item_num, const int32_t *wh, const HYBRID_INFO *info);
@ -32,10 +35,76 @@ static bool M_TestSwitchOrKill(int16_t item_num, GAME_OBJECT_ID target_id);
#if TR_VERSION == 1 #if TR_VERSION == 1
extern void Carrier_TestItemDrops(int16_t item_num); extern void Carrier_TestItemDrops(int16_t item_num);
#elif TR_VERSION == 2
extern void Creature_GetBaddieTarget(int16_t item_num, bool goody);
#endif #endif
static void M_GetBaddieTarget(const int16_t item_num, const bool goody)
{
ITEM *const lara_item = Lara_GetItem();
ITEM *const item = Item_Get(item_num);
CREATURE *const creature = item->data;
ITEM *best_item = nullptr;
int32_t best_distance = INT32_MAX;
for (int32_t i = 0; i < LOT_SLOT_COUNT; i++) {
const int16_t target_item_num = LOT_GetBaddieSlot(i)->item_num;
if (target_item_num == NO_ITEM || target_item_num == item_num) {
continue;
}
ITEM *const target = Item_Get(target_item_num);
const GAME_OBJECT_ID obj_id = target->object_id;
#if TR_VERSION == 2
if (goody && obj_id != O_BANDIT_1 && obj_id != O_BANDIT_2) {
continue;
} else if (!goody && obj_id != O_MONK_1 && obj_id != O_MONK_2) {
continue;
}
#endif
const int32_t dx = (target->pos.x - item->pos.x) >> 6;
const int32_t dy = (target->pos.y - item->pos.y) >> 6;
const int32_t dz = (target->pos.z - item->pos.z) >> 6;
const int32_t distance = SQUARE(dx) + SQUARE(dy) + SQUARE(dz);
if (distance < best_distance) {
best_item = target;
best_distance = distance;
}
}
if (best_item == nullptr) {
if (!goody || Creature_AreAlliesHostile()) {
creature->enemy = lara_item;
} else {
creature->enemy = nullptr;
}
return;
}
if (!goody || Creature_AreAlliesHostile()) {
const int32_t dx = (lara_item->pos.x - item->pos.x) >> 6;
const int32_t dy = (lara_item->pos.y - item->pos.y) >> 6;
const int32_t dz = (lara_item->pos.z - item->pos.z) >> 6;
const int32_t distance = SQUARE(dx) + SQUARE(dy) + SQUARE(dz);
if (distance < best_distance) {
best_item = lara_item;
best_distance = distance;
}
}
const ITEM *const target = creature->enemy;
if (target == nullptr || target->status != IS_ACTIVE) {
creature->enemy = best_item;
} else {
const int32_t dx = (target->pos.x - item->pos.x) >> 6;
const int32_t dy = (target->pos.y - item->pos.y) >> 6;
const int32_t dz = (target->pos.z - item->pos.z) >> 6;
const int32_t distance = SQUARE(dz) + SQUARE(dy) + SQUARE(dx);
if (distance < best_distance + M_TARGET_TOLERANCE) {
creature->enemy = best_item;
}
}
}
static ITEM *M_ChooseEnemy(const ITEM *const item) static ITEM *M_ChooseEnemy(const ITEM *const item)
{ {
CREATURE *const creature = item->data; CREATURE *const creature = item->data;
@ -43,12 +112,12 @@ static ITEM *M_ChooseEnemy(const ITEM *const item)
#if TR_VERSION == 2 #if TR_VERSION == 2
case O_BANDIT_1: case O_BANDIT_1:
case O_BANDIT_2: case O_BANDIT_2:
Creature_GetBaddieTarget(creature->item_num, false); M_GetBaddieTarget(creature->item_num, false);
break; break;
case O_MONK_1: case O_MONK_1:
case O_MONK_2: case O_MONK_2:
Creature_GetBaddieTarget(creature->item_num, true); M_GetBaddieTarget(creature->item_num, true);
break; break;
#endif #endif
@ -1015,6 +1084,16 @@ int32_t Creature_Vault(
return vault; return vault;
} }
bool Creature_AreAlliesHostile(void)
{
return m_AlliesHostile;
}
void Creature_SetAlliesHostile(bool enable)
{
m_AlliesHostile = enable;
}
int16_t Creature_Effect( int16_t Creature_Effect(
const ITEM *const item, const BITE *const bite, const ITEM *const item, const BITE *const bite,
int16_t (*const spawn)( int16_t (*const spawn)(

View file

@ -1,6 +1,7 @@
#include "game/objects/creatures/bear.h" #include "game/objects/creatures/bear.h"
#include "config.h" #include "config.h"
#include "game/const.h"
#include "game/creature.h" #include "game/creature.h"
#include "game/lara/common.h" #include "game/lara/common.h"
#include "game/random.h" #include "game/random.h"

View file

@ -1,5 +1,6 @@
#include "game/objects/creatures/wolf.h" #include "game/objects/creatures/wolf.h"
#include "game/const.h"
#include "game/creature.h" #include "game/creature.h"
#include "game/lara/common.h" #include "game/lara/common.h"
#include "game/random.h" #include "game/random.h"

View file

@ -29,6 +29,8 @@ void Creature_Die(int16_t item_num, bool explode);
int32_t Creature_Vault( int32_t Creature_Vault(
int16_t item_num, int16_t angle, int32_t vault, int32_t shift); int16_t item_num, int16_t angle, int32_t vault, int32_t shift);
bool Creature_AreAlliesHostile(void);
void Creature_SetAlliesHostile(bool enable);
extern bool Creature_IsHostile(const ITEM *item); extern bool Creature_IsHostile(const ITEM *item);
int16_t Creature_Effect( int16_t Creature_Effect(

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "../items.h" #include "../items.h"
#include "../pathing.h" #include "../pathing/types.h"
#include "./enum.h" #include "./enum.h"
typedef struct { typedef struct {

View file

@ -6,8 +6,10 @@
#define BOX_ZONE(num) (((num) / STEP_L) - 1) #define BOX_ZONE(num) (((num) / STEP_L) - 1)
#if TR_VERSION == 1 #if TR_VERSION == 1
#define MAX_ZONES 2 #define MAX_ZONES 2
#define LOT_SLOT_COUNT 32
#else #else
#define MAX_ZONES 4 #define MAX_ZONES 4
#define LOT_SLOT_COUNT 5
#endif #endif
#define BOX_BLOCKED 0x4000 #define BOX_BLOCKED 0x4000

View file

@ -1,4 +1,7 @@
#pragma once #pragma once
#include "../creature/types.h"
extern bool LOT_EnableBaddieAI(int16_t item_num, bool always); extern bool LOT_EnableBaddieAI(int16_t item_num, bool always);
extern void LOT_DisableBaddieAI(int16_t item_num); extern void LOT_DisableBaddieAI(int16_t item_num);
extern CREATURE *LOT_GetBaddieSlot(int32_t i);

View file

@ -49,8 +49,8 @@
#define SHOTGUN_RARM_XMIN (-65 * DEG_1) #define SHOTGUN_RARM_XMIN (-65 * DEG_1)
#define SHOTGUN_RARM_XMAX (+65 * DEG_1) #define SHOTGUN_RARM_XMAX (+65 * DEG_1)
static ITEM *m_TargetList[NUM_SLOTS]; static ITEM *m_TargetList[LOT_SLOT_COUNT];
static ITEM *m_LastTargetList[NUM_SLOTS]; static ITEM *m_LastTargetList[LOT_SLOT_COUNT];
WEAPON_INFO g_Weapons[NUM_WEAPONS] = { WEAPON_INFO g_Weapons[NUM_WEAPONS] = {
// null // null
@ -269,7 +269,7 @@ void Gun_GetNewTarget(WEAPON_INFO *winfo)
} }
if (num_targets > 0) { if (num_targets > 0) {
for (int slot = 0; slot < NUM_SLOTS; slot++) { for (int slot = 0; slot < LOT_SLOT_COUNT; slot++) {
if (!m_TargetList[slot]) { if (!m_TargetList[slot]) {
g_Lara.target = nullptr; g_Lara.target = nullptr;
} }
@ -288,7 +288,7 @@ void Gun_GetNewTarget(WEAPON_INFO *winfo)
} }
if (g_Lara.target != m_LastTargetList[0]) { if (g_Lara.target != m_LastTargetList[0]) {
for (int slot = NUM_SLOTS - 1; slot > 0; slot--) { for (int slot = LOT_SLOT_COUNT - 1; slot > 0; slot--) {
m_LastTargetList[slot] = m_LastTargetList[slot - 1]; m_LastTargetList[slot] = m_LastTargetList[slot - 1];
} }
m_LastTargetList[0] = g_Lara.target; m_LastTargetList[0] = g_Lara.target;
@ -302,12 +302,12 @@ void Gun_ChangeTarget(WEAPON_INFO *winfo)
g_Lara.target = nullptr; g_Lara.target = nullptr;
bool found_new_target = false; bool found_new_target = false;
for (int new_target = 0; new_target < NUM_SLOTS; new_target++) { for (int new_target = 0; new_target < LOT_SLOT_COUNT; new_target++) {
if (!m_TargetList[new_target]) { if (!m_TargetList[new_target]) {
break; break;
} }
for (int last_target = 0; last_target < NUM_SLOTS; last_target++) { for (int last_target = 0; last_target < LOT_SLOT_COUNT; last_target++) {
if (!m_LastTargetList[last_target]) { if (!m_LastTargetList[last_target]) {
found_new_target = true; found_new_target = true;
break; break;
@ -325,7 +325,8 @@ void Gun_ChangeTarget(WEAPON_INFO *winfo)
} }
if (g_Lara.target != m_LastTargetList[0]) { if (g_Lara.target != m_LastTargetList[0]) {
for (int last_target = NUM_SLOTS - 1; last_target > 0; last_target--) { for (int last_target = LOT_SLOT_COUNT - 1; last_target > 0;
last_target--) {
m_LastTargetList[last_target] = m_LastTargetList[last_target - 1]; m_LastTargetList[last_target] = m_LastTargetList[last_target - 1];
} }
m_LastTargetList[0] = g_Lara.target; m_LastTargetList[0] = g_Lara.target;

View file

@ -16,8 +16,8 @@ static CREATURE *m_BaddieSlots = nullptr;
void LOT_InitialiseArray(void) void LOT_InitialiseArray(void)
{ {
m_BaddieSlots = m_BaddieSlots =
GameBuf_Alloc(NUM_SLOTS * sizeof(CREATURE), GBUF_CREATURE_DATA); GameBuf_Alloc(LOT_SLOT_COUNT * sizeof(CREATURE), GBUF_CREATURE_DATA);
for (int i = 0; i < NUM_SLOTS; i++) { for (int i = 0; i < LOT_SLOT_COUNT; i++) {
CREATURE *creature = &m_BaddieSlots[i]; CREATURE *creature = &m_BaddieSlots[i];
creature->item_num = NO_ITEM; creature->item_num = NO_ITEM;
creature->lot.node = creature->lot.node =
@ -26,6 +26,11 @@ void LOT_InitialiseArray(void)
m_SlotsUsed = 0; m_SlotsUsed = 0;
} }
CREATURE *LOT_GetBaddieSlot(const int32_t i)
{
return &m_BaddieSlots[i];
}
void LOT_DisableBaddieAI(int16_t item_num) void LOT_DisableBaddieAI(int16_t item_num)
{ {
ITEM *const item = Item_Get(item_num); ITEM *const item = Item_Get(item_num);
@ -43,8 +48,8 @@ bool LOT_EnableBaddieAI(const int16_t item_num, const bool always)
return true; return true;
} }
if (m_SlotsUsed < NUM_SLOTS) { if (m_SlotsUsed < LOT_SLOT_COUNT) {
for (int32_t slot = 0; slot < NUM_SLOTS; slot++) { for (int32_t slot = 0; slot < LOT_SLOT_COUNT; slot++) {
CREATURE *creature = &m_BaddieSlots[slot]; CREATURE *creature = &m_BaddieSlots[slot];
if (creature->item_num == NO_ITEM) { if (creature->item_num == NO_ITEM) {
LOT_InitialiseSlot(item_num, slot); LOT_InitialiseSlot(item_num, slot);
@ -64,7 +69,7 @@ bool LOT_EnableBaddieAI(const int16_t item_num, const bool always)
} }
int32_t worst_slot = -1; int32_t worst_slot = -1;
for (int32_t slot = 0; slot < NUM_SLOTS; slot++) { for (int32_t slot = 0; slot < LOT_SLOT_COUNT; slot++) {
CREATURE *creature = &m_BaddieSlots[slot]; CREATURE *creature = &m_BaddieSlots[slot];
const ITEM *const item = Item_Get(creature->item_num); const ITEM *const item = Item_Get(creature->item_num);
int32_t x = (item->pos.x - g_Camera.pos.x) >> 8; int32_t x = (item->pos.x - g_Camera.pos.x) >> 8;

View file

@ -6,7 +6,7 @@
#define PHD_ONE 0x10000 #define PHD_ONE 0x10000
#define MAX_REQLINES 18 #define MAX_REQLINES 18
#define NUM_SLOTS 32 #define LOT_SLOT_COUNT 32
#define MAX_SECRETS 16 #define MAX_SECRETS 16
#define LARA_MAX_HITPOINTS 1000 #define LARA_MAX_HITPOINTS 1000
#define LARA_MAX_AIR 1800 #define LARA_MAX_AIR 1800

View file

@ -166,7 +166,7 @@ void InitialiseGameFlags(void)
Output_SetSunsetTimer(0); Output_SetSunsetTimer(0);
g_LevelComplete = false; g_LevelComplete = false;
g_DetonateAllMines = false; g_DetonateAllMines = false;
g_IsMonkAngry = false; Creature_SetAlliesHostile(false);
} }
void GetCarriedItems(void) void GetCarriedItems(void)

View file

@ -21,79 +21,13 @@
#include <libtrx/game/math.h> #include <libtrx/game/math.h>
#include <libtrx/utils.h> #include <libtrx/utils.h>
#define M_TARGET_TOLERANCE 0x400000
#define M_SHOOT_TARGETING_SPEED 300 #define M_SHOOT_TARGETING_SPEED 300
#define M_SHOOT_HIT_CHANCE 0x2000 #define M_SHOOT_HIT_CHANCE 0x2000
void Creature_GetBaddieTarget(const int16_t item_num, const bool goody)
{
ITEM *const item = Item_Get(item_num);
CREATURE *const creature = item->data;
ITEM *best_item = nullptr;
int32_t best_distance = INT32_MAX;
for (int32_t i = 0; i < NUM_SLOTS; i++) {
const int16_t target_item_num = g_BaddieSlots[i].item_num;
if (target_item_num == NO_ITEM || target_item_num == item_num) {
continue;
}
ITEM *const target = Item_Get(target_item_num);
const GAME_OBJECT_ID obj_id = target->object_id;
if (goody && obj_id != O_BANDIT_1 && obj_id != O_BANDIT_2) {
continue;
} else if (!goody && obj_id != O_MONK_1 && obj_id != O_MONK_2) {
continue;
}
const int32_t dx = (target->pos.x - item->pos.x) >> 6;
const int32_t dy = (target->pos.y - item->pos.y) >> 6;
const int32_t dz = (target->pos.z - item->pos.z) >> 6;
const int32_t distance = SQUARE(dx) + SQUARE(dy) + SQUARE(dz);
if (distance < best_distance) {
best_item = target;
best_distance = distance;
}
}
if (best_item == nullptr) {
if (!goody || g_IsMonkAngry) {
creature->enemy = g_LaraItem;
} else {
creature->enemy = nullptr;
}
return;
}
if (!goody || g_IsMonkAngry) {
const int32_t dx = (g_LaraItem->pos.x - item->pos.x) >> 6;
const int32_t dy = (g_LaraItem->pos.y - item->pos.y) >> 6;
const int32_t dz = (g_LaraItem->pos.z - item->pos.z) >> 6;
const int32_t distance = SQUARE(dx) + SQUARE(dy) + SQUARE(dz);
if (distance < best_distance) {
best_item = g_LaraItem;
best_distance = distance;
}
}
const ITEM *const target = creature->enemy;
if (target == nullptr || target->status != IS_ACTIVE) {
creature->enemy = best_item;
} else {
const int32_t dx = (target->pos.x - item->pos.x) >> 6;
const int32_t dy = (target->pos.y - item->pos.y) >> 6;
const int32_t dz = (target->pos.z - item->pos.z) >> 6;
const int32_t distance = SQUARE(dz) + SQUARE(dy) + SQUARE(dx);
if (distance < best_distance + M_TARGET_TOLERANCE) {
creature->enemy = best_item;
}
}
}
bool Creature_IsHostile(const ITEM *const item) bool Creature_IsHostile(const ITEM *const item)
{ {
return Object_IsType(item->object_id, g_EnemyObjects) return Object_IsType(item->object_id, g_EnemyObjects)
|| (g_IsMonkAngry || (Creature_AreAlliesHostile()
&& (item->object_id == O_MONK_1 || item->object_id == O_MONK_2)); && (item->object_id == O_MONK_1 || item->object_id == O_MONK_2));
} }

View file

@ -4,7 +4,6 @@
#include <libtrx/game/creature.h> #include <libtrx/game/creature.h>
void Creature_GetBaddieTarget(int16_t item_num, bool goody);
bool Creature_IsAlly(const ITEM *item); bool Creature_IsAlly(const ITEM *item);
int32_t Creature_ShootAtLara( int32_t Creature_ShootAtLara(
ITEM *item, const AI_INFO *info, const BITE *gun, int16_t extra_rotation, ITEM *item, const AI_INFO *info, const BITE *gun, int16_t extra_rotation,

View file

@ -116,7 +116,7 @@ void Gun_GetNewTarget(const WEAPON_INFO *const winfo)
ITEM *best_target = nullptr; ITEM *best_target = nullptr;
const int16_t max_dist = winfo->target_dist; const int16_t max_dist = winfo->target_dist;
for (int32_t i = 0; i < NUM_SLOTS; i++) { for (int32_t i = 0; i < LOT_SLOT_COUNT; i++) {
const int16_t item_num = g_BaddieSlots[i].item_num; const int16_t item_num = g_BaddieSlots[i].item_num;
if (item_num == NO_ITEM || item_num == g_Lara.item_num) { if (item_num == NO_ITEM || item_num == g_Lara.item_num) {
continue; continue;
@ -327,13 +327,13 @@ void Gun_HitTarget(
item->rot.y, item->room_num); item->rot.y, item->room_num);
} }
if (!g_IsMonkAngry if (!Creature_AreAlliesHostile()
&& (item->object_id == O_MONK_1 || item->object_id == O_MONK_2)) { && (item->object_id == O_MONK_1 || item->object_id == O_MONK_2)) {
CREATURE *const creature = item->data; CREATURE *const creature = item->data;
creature->flags += damage; creature->flags += damage;
if ((creature->flags & 0xFFF) > MONK_FRIENDLY_FIRE_THRESHOLD if ((creature->flags & 0xFFF) > MONK_FRIENDLY_FIRE_THRESHOLD
|| creature->mood == MOOD_BORED) { || creature->mood == MOOD_BORED) {
g_IsMonkAngry = true; Creature_SetAlliesHostile(true);
} }
} }
} }

View file

@ -10,12 +10,13 @@
#include <libtrx/utils.h> #include <libtrx/utils.h>
static int32_t m_SlotsUsed = 0; static int32_t m_SlotsUsed = 0;
void LOT_InitialiseArray(void) void LOT_InitialiseArray(void)
{ {
g_BaddieSlots = g_BaddieSlots =
GameBuf_Alloc(NUM_SLOTS * sizeof(CREATURE), GBUF_CREATURE_DATA); GameBuf_Alloc(LOT_SLOT_COUNT * sizeof(CREATURE), GBUF_CREATURE_DATA);
for (int32_t i = 0; i < NUM_SLOTS; i++) { for (int32_t i = 0; i < LOT_SLOT_COUNT; i++) {
CREATURE *const creature = &g_BaddieSlots[i]; CREATURE *const creature = &g_BaddieSlots[i];
creature->item_num = NO_ITEM; creature->item_num = NO_ITEM;
creature->lot.node = creature->lot.node =
@ -25,6 +26,11 @@ void LOT_InitialiseArray(void)
m_SlotsUsed = 0; m_SlotsUsed = 0;
} }
CREATURE *LOT_GetBaddieSlot(const int32_t i)
{
return &g_BaddieSlots[i];
}
void LOT_DisableBaddieAI(const int16_t item_num) void LOT_DisableBaddieAI(const int16_t item_num)
{ {
CREATURE *creature; CREATURE *creature;
@ -54,8 +60,8 @@ bool LOT_EnableBaddieAI(const int16_t item_num, const bool always)
return true; return true;
} }
if (m_SlotsUsed < NUM_SLOTS) { if (m_SlotsUsed < LOT_SLOT_COUNT) {
for (int32_t slot = 0; slot < NUM_SLOTS; slot++) { for (int32_t slot = 0; slot < LOT_SLOT_COUNT; slot++) {
if (g_BaddieSlots[slot].item_num == NO_ITEM) { if (g_BaddieSlots[slot].item_num == NO_ITEM) {
LOT_InitialiseSlot(item_num, slot); LOT_InitialiseSlot(item_num, slot);
return true; return true;
@ -74,7 +80,7 @@ bool LOT_EnableBaddieAI(const int16_t item_num, const bool always)
} }
int32_t worst_slot = -1; int32_t worst_slot = -1;
for (int32_t slot = 0; slot < NUM_SLOTS; slot++) { for (int32_t slot = 0; slot < LOT_SLOT_COUNT; slot++) {
const int32_t item_num = g_BaddieSlots[slot].item_num; const int32_t item_num = g_BaddieSlots[slot].item_num;
const ITEM *const item = Item_Get(item_num); const ITEM *const item = Item_Get(item_num);
const int32_t dx = (item->pos.x - g_Camera.pos.pos.x) >> 8; const int32_t dx = (item->pos.x - g_Camera.pos.pos.x) >> 8;

View file

@ -113,7 +113,8 @@ static void M_Control(const int16_t item_num)
switch (item->current_anim_state) { switch (item->current_anim_state) {
case MONK_STATE_WAIT_1: case MONK_STATE_WAIT_1:
creature->flags &= 0xFFF; creature->flags &= 0xFFF;
if (!g_IsMonkAngry && info.ahead != 0 && g_Lara.target == item) { if (!Creature_AreAlliesHostile() && info.ahead != 0
&& g_Lara.target == item) {
} else if (creature->mood == MOOD_BORED) { } else if (creature->mood == MOOD_BORED) {
item->goal_anim_state = MONK_STATE_WALK; item->goal_anim_state = MONK_STATE_WALK;
} else if (creature->mood == MOOD_ESCAPE) { } else if (creature->mood == MOOD_ESCAPE) {
@ -137,7 +138,8 @@ static void M_Control(const int16_t item_num)
case MONK_STATE_WAIT_2: case MONK_STATE_WAIT_2:
creature->flags &= 0xFFF; creature->flags &= 0xFFF;
if (!g_IsMonkAngry && info.ahead != 0 && g_Lara.target == item) { if (!Creature_AreAlliesHostile() && info.ahead != 0
&& g_Lara.target == item) {
} else if (creature->mood == MOOD_BORED) { } else if (creature->mood == MOOD_BORED) {
item->goal_anim_state = MONK_STATE_WALK; item->goal_anim_state = MONK_STATE_WALK;
} else if (creature->mood == MOOD_ESCAPE) { } else if (creature->mood == MOOD_ESCAPE) {
@ -161,7 +163,7 @@ static void M_Control(const int16_t item_num)
case MONK_STATE_WALK: case MONK_STATE_WALK:
creature->maximum_turn = MONK_WALK_TURN; creature->maximum_turn = MONK_WALK_TURN;
if (creature->mood == MOOD_BORED) { if (creature->mood == MOOD_BORED) {
if (!g_IsMonkAngry && info.ahead != 0 if (!Creature_AreAlliesHostile() && info.ahead != 0
&& g_Lara.target == item) { && g_Lara.target == item) {
if (Random_GetControl() < 0x4000) { if (Random_GetControl() < 0x4000) {
item->goal_anim_state = MONK_STATE_WAIT_1; item->goal_anim_state = MONK_STATE_WAIT_1;
@ -185,7 +187,7 @@ static void M_Control(const int16_t item_num)
case MONK_STATE_RUN: case MONK_STATE_RUN:
creature->flags &= 0xFFF; creature->flags &= 0xFFF;
creature->maximum_turn = MONK_RUN_TURN; creature->maximum_turn = MONK_RUN_TURN;
if (g_IsMonkAngry) { if (Creature_AreAlliesHostile()) {
creature->maximum_turn = MONK_RUN_TURN_FAST; creature->maximum_turn = MONK_RUN_TURN_FAST;
} }
tilt = angle / 4; tilt = angle / 4;

View file

@ -276,7 +276,8 @@ static JSON_OBJECT *M_DumpMisc(void)
JSON_OBJECT *const misc_obj = JSON_ObjectNew(); JSON_OBJECT *const misc_obj = JSON_ObjectNew();
JSON_ObjectAppendString(misc_obj, "game_version", g_TRXVersion); JSON_ObjectAppendString(misc_obj, "game_version", g_TRXVersion);
JSON_ObjectAppendInt(misc_obj, "bonus_flag", Game_GetBonusFlag()); JSON_ObjectAppendInt(misc_obj, "bonus_flag", Game_GetBonusFlag());
JSON_ObjectAppendBool(misc_obj, "are_monks_angry", g_IsMonkAngry); JSON_ObjectAppendBool(
misc_obj, "are_monks_angry", Creature_AreAlliesHostile());
return misc_obj; return misc_obj;
} }
@ -289,7 +290,8 @@ static bool M_LoadMisc(JSON_OBJECT *const misc_obj)
const int32_t bonus_flag = JSON_ObjectGetInt(misc_obj, "bonus_flag", 0); const int32_t bonus_flag = JSON_ObjectGetInt(misc_obj, "bonus_flag", 0);
Game_SetBonusFlag(bonus_flag); Game_SetBonusFlag(bonus_flag);
g_IsMonkAngry = JSON_ObjectGetBool(misc_obj, "are_monks_angry", 0); const bool hostile = JSON_ObjectGetBool(misc_obj, "are_monks_angry", false);
Creature_SetAlliesHostile(hostile);
return true; return true;
} }

View file

@ -776,7 +776,7 @@ static void M_SaveToFile(MYFILE *const fp, SAVEGAME_INFO *const info)
M_WriteS32(Room_GetFlipEffect()); M_WriteS32(Room_GetFlipEffect());
M_WriteS32(Room_GetFlipTimer()); M_WriteS32(Room_GetFlipTimer());
M_WriteS32(g_IsMonkAngry); M_WriteS32(Creature_AreAlliesHostile());
M_WriteFlares(); M_WriteFlares();
@ -860,7 +860,7 @@ static bool M_LoadFromFile(MYFILE *const fp)
Room_SetFlipEffect(M_ReadS32()); Room_SetFlipEffect(M_ReadS32());
Room_SetFlipTimer(M_ReadS32()); Room_SetFlipTimer(M_ReadS32());
g_IsMonkAngry = M_ReadS32(); Creature_SetAlliesHostile(M_ReadS32() != 0);
M_ReadFlares(); M_ReadFlares();

View file

@ -150,7 +150,6 @@
#define FOG_START (12 * WALL_L) // = 12288 #define FOG_START (12 * WALL_L) // = 12288
#define FOG_END (20 * WALL_L) // = 20480 #define FOG_END (20 * WALL_L) // = 20480
#define NUM_SLOTS 5
#define PITCH_SHIFT 4 #define PITCH_SHIFT 4
#define IDS_DX5_REQUIRED 1 #define IDS_DX5_REQUIRED 1

View file

@ -50,7 +50,6 @@ int32_t g_PhdWinRight;
int32_t g_SurfaceCount; int32_t g_SurfaceCount;
SORT_ITEM *g_Sort3DPtr = nullptr; SORT_ITEM *g_Sort3DPtr = nullptr;
bool g_IsDemoLoaded; bool g_IsDemoLoaded;
bool g_IsMonkAngry;
uint16_t g_SoundOptionLine; uint16_t g_SoundOptionLine;
int32_t g_HealthBarTimer; int32_t g_HealthBarTimer;
int32_t g_LevelComplete; int32_t g_LevelComplete;

View file

@ -51,7 +51,6 @@ extern int32_t g_PhdWinRight;
extern int32_t g_SurfaceCount; extern int32_t g_SurfaceCount;
extern SORT_ITEM *g_Sort3DPtr; extern SORT_ITEM *g_Sort3DPtr;
extern bool g_IsDemoLoaded; extern bool g_IsDemoLoaded;
extern bool g_IsMonkAngry;
extern uint16_t g_SoundOptionLine; extern uint16_t g_SoundOptionLine;
extern int32_t g_HealthBarTimer; extern int32_t g_HealthBarTimer;
extern int32_t g_LevelComplete; extern int32_t g_LevelComplete;