mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
HOOK_MOVECOST (#496)
This commit is contained in:
@@ -106,8 +106,8 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
|
||||
| UseObj | `HOOK_USEOBJ` | ✅ | CE notes an sfall-matching inconsistency around return code `2` behavior between interface contexts. |
|
||||
| RemoveInvenObj | `HOOK_REMOVEINVENOBJ` | 🚫 | - |
|
||||
| BarterPrice | `HOOK_BARTERPRICE` | ✅ | - |
|
||||
| MoveCost | `HOOK_MOVECOST` | 🚫 | - |
|
||||
| ItemDamage | `HOOK_ITEMDAMAGE` | ✅ | - |
|
||||
| MoveCost | `HOOK_MOVECOST` | ✅ | - |
|
||||
| AmmoCost | `HOOK_AMMOCOST` | ✅ | Requires `check_weapon_ammo_cost=1` if you want pre-attack ammo validation to respect per-shot/per-round overrides. |
|
||||
| KeyPress | `HOOK_KEYPRESS` | ✅ | Third hook arg is currently `0`; CE doesn't use VK codes. |
|
||||
| MouseClick | `HOOK_MOUSECLICK` | ✅ | - |
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "sfall.h"
|
||||
#include "dik.h"
|
||||
|
||||
variable movecost_mode := 0;
|
||||
|
||||
procedure movecost_mode_name(variable mode) begin
|
||||
variable name := "unknown";
|
||||
|
||||
if (mode == 0) then name := "engine";
|
||||
else if (mode == 1) then name := "plus_per_hex";
|
||||
else if (mode == 2) then name := "double";
|
||||
|
||||
return name;
|
||||
end
|
||||
|
||||
procedure cycle_movecost_mode begin
|
||||
if (movecost_mode == 0) then movecost_mode := 1;
|
||||
else if (movecost_mode == 1) then movecost_mode := 2;
|
||||
else movecost_mode := 0;
|
||||
|
||||
display_msg(string_format1("movecost mode=%s", movecost_mode_name(movecost_mode)));
|
||||
end
|
||||
|
||||
procedure movecost_handler begin
|
||||
variable
|
||||
args := get_sfall_args,
|
||||
critter := args[0],
|
||||
distance := args[1],
|
||||
defaultCost := args[2],
|
||||
modeName := movecost_mode_name(movecost_mode),
|
||||
newCost := defaultCost;
|
||||
|
||||
if (critter != dude_obj) then return;
|
||||
|
||||
display_msg(string_format3("movecost dist=%d default=%d mode=%s",
|
||||
distance,
|
||||
defaultCost,
|
||||
modeName));
|
||||
|
||||
if (movecost_mode == 1) then begin
|
||||
newCost := defaultCost + distance;
|
||||
end else if (movecost_mode == 2) then begin
|
||||
newCost := defaultCost * 2;
|
||||
end else begin
|
||||
return;
|
||||
end
|
||||
|
||||
set_sfall_return(newCost);
|
||||
end
|
||||
|
||||
procedure keypress_handler begin
|
||||
variable
|
||||
pressed := get_sfall_arg_at(0),
|
||||
key := get_sfall_arg_at(1);
|
||||
|
||||
if (not pressed) then return;
|
||||
if (key != DIK_M) then return;
|
||||
|
||||
call cycle_movecost_mode;
|
||||
end
|
||||
|
||||
procedure start begin
|
||||
if (not game_loaded) then return;
|
||||
|
||||
display_msg("movecost manual test ready: enter combat, hover a tile, then move");
|
||||
display_msg("press M to cycle hook override: engine -> plus_per_hex -> double");
|
||||
|
||||
register_hook_proc(HOOK_KEYPRESS, keypress_handler);
|
||||
register_hook_proc(HOOK_MOVECOST, movecost_handler);
|
||||
end
|
||||
+6
-3
@@ -1359,13 +1359,16 @@ int critterGetMovementPointCostAdjustedForCrippledLegs(Object* critter, int dist
|
||||
}
|
||||
|
||||
int flags = critter->data.critter.combat.results;
|
||||
int actionPoints = 0;
|
||||
if ((flags & DAM_CRIP_LEG_LEFT) != 0 && (flags & DAM_CRIP_LEG_RIGHT) != 0) {
|
||||
return 8 * distance;
|
||||
actionPoints = 8 * distance;
|
||||
} else if ((flags & DAM_CRIP_LEG_ANY) != 0) {
|
||||
return 4 * distance;
|
||||
actionPoints = 4 * distance;
|
||||
} else {
|
||||
return distance;
|
||||
actionPoints = distance;
|
||||
}
|
||||
|
||||
return scriptHooks_MoveCost(critter, distance, actionPoints);
|
||||
}
|
||||
|
||||
// 0x42E66C critterIsOverloaded
|
||||
|
||||
@@ -570,6 +570,35 @@ int scriptHooks_CalcApCost(Object* critter, int hitMode, bool aiming, int action
|
||||
return hook.getReturnValueAt(0).asInt();
|
||||
}
|
||||
|
||||
/*
|
||||
Runs when calculating the AP cost of movement.
|
||||
|
||||
The engine calls this both for full-path AP previews and for per-hex AP
|
||||
deduction during movement animation. In practice, arg1 may therefore be the
|
||||
full path length or 1, depending on the caller. Non-linear overrides can make
|
||||
the UI preview diverge from the AP actually spent.
|
||||
|
||||
Critter arg0 - The critter doing the moving
|
||||
int arg1 - The number of hexes being moved
|
||||
int arg2 - The original AP cost
|
||||
|
||||
int ret0 - The new AP cost
|
||||
*/
|
||||
int scriptHooks_MoveCost(Object* critter, int distance, int actionPoints)
|
||||
{
|
||||
if (scriptHooks[HOOK_MOVECOST].empty()) {
|
||||
return actionPoints;
|
||||
}
|
||||
|
||||
ScriptHookCall hook(HOOK_MOVECOST, 1, { critter, distance, actionPoints });
|
||||
hook.call();
|
||||
|
||||
if (hook.numReturnValues() <= 0) {
|
||||
return actionPoints;
|
||||
}
|
||||
return hook.getReturnValueAt(0).asInt();
|
||||
}
|
||||
|
||||
/*
|
||||
Runs before moving items between inventory slots in dude interface. You can override the action.
|
||||
|
||||
|
||||
@@ -302,6 +302,7 @@ bool scriptHooks_CombatTurnEnd(Object* critter, int turnResult, bool reloadedDur
|
||||
void scriptHooks_CombatTurnCombatEnd(Object* critter);
|
||||
PerceptionResult scriptHooks_WithinPerception(Object* watcher, Object* target, PerceptionType type, PerceptionResult result);
|
||||
int scriptHooks_CalcApCost(Object* critter, int hitMode, bool aiming, int actionPoints, Object* weapon);
|
||||
int scriptHooks_MoveCost(Object* critter, int distance, int actionPoints);
|
||||
int scriptHooks_ToHit(Object* attacker, Object* defender, int tile, int hitMode, int hitLocation, int hitChance, int hitChanceUncapped, bool useDistance);
|
||||
int scriptHooks_AfterHitRoll(Object* attacker, Object** defenderPtr, int* hitLocationPtr, int hitChance, int roll);
|
||||
void scriptHooks_DeathAnim(Object* attacker, Object* defender, Object* weapon, int damage, int* anim);
|
||||
|
||||
Reference in New Issue
Block a user