mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-09-02 09:51:37 -04:00
Improve logic for objectives failed HUD message
* Roll up all the objective failed commands into a new "any objective failed" one * Remove wasteful looping logic from ailist * Use existing statuses array instead of recalculating every objective on every frame
This commit is contained in:
+8
-27
@@ -3628,31 +3628,20 @@ u8 func0000_idle_0009[] = {
|
||||
u8 func0016_show_objective_failed_msg[] = {
|
||||
// Wait until an objective has failed
|
||||
beginloop(0x0c)
|
||||
if_timer_gt(0, /*goto*/ 0x13)
|
||||
if_objective_failed(0, /*goto*/ 0x16)
|
||||
if_objective_failed(1, /*goto*/ 0x16)
|
||||
if_objective_failed(2, /*goto*/ 0x16)
|
||||
if_objective_failed(3, /*goto*/ 0x16)
|
||||
if_objective_failed(4, /*goto*/ 0x16)
|
||||
if_any_objective_failed(/*goto*/ 0x16)
|
||||
endloop(0x0c)
|
||||
|
||||
// Wait 30 seconds. It iterates to the top loop here, which instantly jumps
|
||||
// down to 0x13 because the timer is > 0. Seems a bit unnecessary...
|
||||
// Wait 30 seconds
|
||||
label(0x16)
|
||||
restart_timer
|
||||
yield
|
||||
|
||||
label(0x13)
|
||||
if_timer_gt(1800, /*goto*/ 0x13)
|
||||
goto_first(0x0c)
|
||||
beginloop(0x0d)
|
||||
if_timer_gt(1800, /*goto*/ 0x13)
|
||||
endloop(0x0d)
|
||||
|
||||
// Check objective is still failed
|
||||
label(0x13)
|
||||
if_objective_failed(0, /*goto*/ 0x13)
|
||||
if_objective_failed(1, /*goto*/ 0x13)
|
||||
if_objective_failed(2, /*goto*/ 0x13)
|
||||
if_objective_failed(3, /*goto*/ 0x13)
|
||||
if_objective_failed(4, /*goto*/ 0x13)
|
||||
if_any_objective_failed(/*goto*/ 0x13)
|
||||
set_ailist(CHR_SELF, GAILIST_IDLE)
|
||||
|
||||
// Show message first time
|
||||
@@ -3668,11 +3657,7 @@ u8 func0016_show_objective_failed_msg[] = {
|
||||
|
||||
// Check objective is still failed
|
||||
label(0x16)
|
||||
if_objective_failed(0, /*goto*/ 0x13)
|
||||
if_objective_failed(1, /*goto*/ 0x13)
|
||||
if_objective_failed(2, /*goto*/ 0x13)
|
||||
if_objective_failed(3, /*goto*/ 0x13)
|
||||
if_objective_failed(4, /*goto*/ 0x13)
|
||||
if_any_objective_failed(/*goto*/ 0x13)
|
||||
set_ailist(CHR_SELF, GAILIST_IDLE)
|
||||
|
||||
// Show message second time
|
||||
@@ -3687,11 +3672,7 @@ u8 func0016_show_objective_failed_msg[] = {
|
||||
|
||||
// Check objective is still failed
|
||||
label(0x06)
|
||||
if_objective_failed(0, /*goto*/ 0x13)
|
||||
if_objective_failed(1, /*goto*/ 0x13)
|
||||
if_objective_failed(2, /*goto*/ 0x13)
|
||||
if_objective_failed(3, /*goto*/ 0x13)
|
||||
if_objective_failed(4, /*goto*/ 0x13)
|
||||
if_any_objective_failed(/*goto*/ 0x13)
|
||||
set_ailist(CHR_SELF, GAILIST_IDLE)
|
||||
|
||||
// Show message third time
|
||||
|
||||
@@ -2790,11 +2790,7 @@ u8 func1014_msg_cantleaveany[] = {
|
||||
|
||||
u8 func1015_msg_jumpshipwaiting[] = {
|
||||
beginloop(0x1f)
|
||||
if_objective_failed(0, /*goto*/ 0x00)
|
||||
if_objective_failed(1, /*goto*/ 0x00)
|
||||
if_objective_failed(2, /*goto*/ 0x00)
|
||||
if_objective_failed(3, /*goto*/ 0x00)
|
||||
if_objective_failed(4, /*goto*/ 0x00)
|
||||
if_any_objective_failed(/*goto*/ 0x00)
|
||||
if_chr_in_room(CHR_BOND, 0x00, 0x0002, /*goto*/ 0x20)
|
||||
endloop(0x1f)
|
||||
|
||||
|
||||
@@ -1980,17 +1980,33 @@ bool aiIfNeverBeenOnScreen(void)
|
||||
bool aiIfObjectiveComplete(s32 index)
|
||||
{
|
||||
return index < objectiveGetCount()
|
||||
&& objectiveCheck(index) == OBJECTIVE_COMPLETE
|
||||
&& g_ObjectiveStatuses[index] == OBJECTIVE_COMPLETE
|
||||
&& objectiveGetDifficultyBits(index) & (1 << lvGetDifficulty());
|
||||
}
|
||||
|
||||
bool aiIfObjectiveFailed(s32 index)
|
||||
{
|
||||
return index < objectiveGetCount()
|
||||
&& objectiveCheck(index) == OBJECTIVE_FAILED
|
||||
&& g_ObjectiveStatuses[index] == OBJECTIVE_FAILED
|
||||
&& objectiveGetDifficultyBits(index) & (1 << lvGetDifficulty());
|
||||
}
|
||||
|
||||
bool aiIfAnyObjectiveFailed(void)
|
||||
{
|
||||
s32 numobjectives = objectiveGetCount();
|
||||
s32 mask = 1 << lvGetDifficulty();
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < numobjectives; i++) {
|
||||
if (g_ObjectiveStatuses[i] == OBJECTIVE_FAILED
|
||||
&& objectiveGetDifficultyBits(i) & mask) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool aiIfObjectDistanceToPadLessThan(s32 tagnum, s32 padnum, f32 distance)
|
||||
{
|
||||
f32 xdiff;
|
||||
|
||||
@@ -941,6 +941,10 @@
|
||||
objective, \
|
||||
label,
|
||||
|
||||
#define if_any_objective_failed(label) \
|
||||
mkshort(0x0064), \
|
||||
label,
|
||||
|
||||
/**
|
||||
* This is only ever called in a sequence of 4, with u1 values 8, 2, 4, 8 in
|
||||
* that order. Believed to be a pad within specific distance of target chr,
|
||||
|
||||
@@ -562,6 +562,10 @@ class App():
|
||||
self.emit('jal', ['aiIfChrAmmoQuantityLessThan'])
|
||||
self.emit_bnez_label(params[3])
|
||||
|
||||
def ai_if_any_objective_failed(self, params):
|
||||
self.emit('jal', ['aiIfAnyObjectiveFailed'])
|
||||
self.emit_bnez_label(params[0])
|
||||
|
||||
def ai_if_calculated_safety2_lt(self, params):
|
||||
self.emit('li', ['$a0', params[0]])
|
||||
self.emit('jal', ['aiIfSafety2LessThan'])
|
||||
|
||||
@@ -84,6 +84,7 @@ def get_commands():
|
||||
commands[0x0061] = {'macro': 'if_gun_unclaimed', 'len': 5}
|
||||
commands[0x0062] = {'macro': 'if_object_in_good_condition', 'len': 4}
|
||||
commands[0x0063] = {'macro': 'if_chr_activated_object', 'len': 5}
|
||||
commands[0x0064] = {'macro': 'if_any_objective_failed', 'len': 3}
|
||||
commands[0x0066] = {'macro': 'destroy_object', 'len': 3}
|
||||
commands[0x0068] = {'macro': 'drop_concealed_items', 'len': 3}
|
||||
commands[0x0069] = {'macro': 'chr_drop_weapon', 'len': 3}
|
||||
|
||||
Reference in New Issue
Block a user