mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ff3bd9964 | ||
|
|
f3caac0bda | ||
|
|
fec5df8981 | ||
|
|
4715e0b349 | ||
|
|
8ce4361365 | ||
|
|
2447593e9c |
@@ -144,13 +144,13 @@ In time this stuff will receive in-game interface, right now you have to do it m
|
||||
* Expanded 4-row barter screen
|
||||
* Expanded AP bar
|
||||
* Party members can loot and barter in place of PC
|
||||
* Increased pathfinding nodes 5x for more accurate pathfinding
|
||||
* Increased pathfinding nodes 5x for more accurate pathfinding, and use accurate path length for walk vs run
|
||||
* Ctrl-click to quickly move items when bartering, looting, or stealing
|
||||
* _a_ to select "all" when selecting item quantity
|
||||
* _a_ to `Take All` when looting
|
||||
* When bartering, caps default to the right amount to balance the trade (if possible)
|
||||
* _a_ to select "all" when selecting item quantity, and for `Take All` when looting
|
||||
* When bartering, caps default to the right amount to balance the trade
|
||||
* Music continues playing between maps
|
||||
* Auto open doors
|
||||
* Integrated "HELP" menu
|
||||
* 44.1 kHz stereo sound/music supported, in .ogg and .wav format as well as legacy .acm
|
||||
* Last used save slot is remembered
|
||||
* Item/Corpse/Container/Critter highlighting (configure using [mods/sfall-mods.ini](https://github.com/sfall-team/sfall/blob/master/artifacts/config_files/sfall-mods.ini))
|
||||
|
||||
@@ -75,10 +75,10 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
|
||||
| Global scripts / Global script functions | set_global_script_repeat<br>set_global_script_type<br>available_global_script_types | âś… except available_global_script_types | - |
|
||||
| Combat | attack_is_aimed<br>block_combat<br>force_aimed_shots<br>disable_aimed_shots<br>get_attack_type<br>get/set_bodypart_hit_modifier<br>combat_data<br>get/set/reset_critical_table<br>get_last_target<br>get_last_attacker<br>set_critter_burst_disable<br>get/set_critter_current_ap<br>set_spray_settings<br>get/set_combat_free_move | âś… except block_combat, force_aimed_shots, disable_aimed_shots, get_last_target, get_last_attacker, set_spray_settings | - |
|
||||
| Car | set_car_current_town<br>car_gas_amount<br>set_car_intface_art | implemented: all except set_car_intface_art | - |
|
||||
| Interface / Windows and images | art_frame_data<br>interface_art_draw<br>interface_print<br>draw_image<br>draw_image_scaled<br>get_window_under_mouse<br>create_win<br>get_window_attribute<br>message_box<br>set_window_flag<br>win_fill_color<br>interface_overlay<br>dialog_message<br>get_text_width<br>hide_window<br>show_window<br>create_message_window | implemented: only message_box, get_text_width, show_window, create_message_window | - |
|
||||
| Interface / Windows and images | art_frame_data<br>interface_art_draw<br>interface_print<br>draw_image<br>draw_image_scaled<br>get_window_under_mouse<br>create_win<br>get_window_attribute<br>message_box<br>set_window_flag<br>win_fill_color<br>interface_overlay<br>dialog_message<br>get_text_width<br>hide_window<br>show_window<br>create_message_window | implemented: get_window_under_mouse, create_win, get_window_attribute, message_box, set_window_flag, dialog_message, get_text_width, hide_window, show_window, create_message_window | - |
|
||||
| Interface / Outline | outlined_object<br>get_outline<br>set_outline | âś… | - |
|
||||
| Interface / Main interface | intface_is_hidden<br>intface_redraw<br>intface_hide<br>intface_show<br>set_quest_failure_value | implemented: only intface_redraw | `intface_redraw` only supports the zero-argument form; the optional-argument path is explicitly unimplemented. |
|
||||
| Interface / Inventory | display_stats<br>inventory_redraw<br>critter_inven_obj2<br>get_current_inven_size<br>item_weight | implemented: critter_inven_obj2, item_weight | - |
|
||||
| Interface / Inventory | display_stats<br>inventory_redraw<br>critter_inven_obj2<br>get_current_inven_size<br>item_weight | âś… except get_current_inven_size | - |
|
||||
| Interface / Cursor | get/set_cursor_mode | âś… | - |
|
||||
| Locks | lock_is_jammed<br>unjam_lock<br>set_unjam_locks_time | not implemented | - |
|
||||
| INI settings | get_ini_setting<br>get_ini_string<br>get_ini_section<br>get_ini_sections<br>get_ini_config<br>get_ini_config_db<br>set_ini_setting | âś… | `modified_ini` is intentionally omitted as deprecated. |
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1 @@
|
||||
{0}{}{HELP}
|
||||
@@ -0,0 +1 @@
|
||||
{0}{}{AIDE}
|
||||
@@ -0,0 +1 @@
|
||||
{0}{}{HILFE}
|
||||
@@ -0,0 +1 @@
|
||||
{0}{}{AIUTO}
|
||||
@@ -0,0 +1 @@
|
||||
{0}{}{POMOC}
|
||||
@@ -0,0 +1 @@
|
||||
{0}{}{AJUDA}
|
||||
@@ -0,0 +1 @@
|
||||
{0}{}{ПОМОЩЬ}
|
||||
@@ -0,0 +1 @@
|
||||
{0}{}{AYUDA}
|
||||
+10
-1
@@ -39,7 +39,16 @@ IFACE_BAR_SIDES_ORI=0
|
||||
;if IFACE_BAR_WIDTH=800 - Interface bar will use 800pix wide asset from f2_res.dat. Note
|
||||
|
||||
IFACE_BAR_WIDTH=640
|
||||
|
||||
|
||||
; Controls ammo display in the HP/AC cluster.
|
||||
; 0 = stock 1-pixel ammo bar only.
|
||||
; 1 = numeric current/max ammo counter only.
|
||||
; 2 = HRP 2-pixel ammo bar only.
|
||||
; 3 = hidden, no stock bar and no numeric counter.
|
||||
; 4 = stock 1-pixel ammo bar plus numeric counter.
|
||||
; 5 = HRP 2-pixel ammo bar plus numeric counter.
|
||||
IFACE_AMMO_COUNTER=0
|
||||
|
||||
;##################################################################################################################
|
||||
[STATIC_SCREENS]
|
||||
|
||||
|
||||
@@ -130,6 +130,8 @@ inventory_columns=2
|
||||
;Set to 1 to scale only the main menu background image to fit the screen while maintaining aspect ratio.
|
||||
;Set to 2 to also scale the main menu button panel, red buttons, and button labels with the menu art.
|
||||
main_menu_scale_mode=1
|
||||
;Set to 1 to show a Help option in the in-game options menu which opens the F1 help screen.
|
||||
in_game_menu_help=1
|
||||
|
||||
|
||||
[qol]
|
||||
|
||||
@@ -46,6 +46,8 @@ static void _decode_map_data(int elevation);
|
||||
static int automapCreate();
|
||||
static int _copy_file_data(File* stream1, File* stream2, int length);
|
||||
|
||||
static int gAutomapWindow = -1;
|
||||
|
||||
typedef enum AutomapFrm {
|
||||
AUTOMAP_FRM_BACKGROUND,
|
||||
AUTOMAP_FRM_BUTTON_UP,
|
||||
@@ -326,6 +328,7 @@ void automapShow(bool isInGame, bool isUsingScanner)
|
||||
int automapWindowY = (screenGetHeight() - AUTOMAP_WINDOW_HEIGHT) / 2;
|
||||
// adding WINDOW_TRANSPARENT and WINDOW_DRAGGABLE_BY_BACKGROUND for testing temporarily
|
||||
int window = windowCreate(automapWindowX, automapWindowY, AUTOMAP_WINDOW_WIDTH, AUTOMAP_WINDOW_HEIGHT, color, WINDOW_MODAL | WINDOW_MOVE_ON_TOP | WINDOW_TRANSPARENT | WINDOW_DRAGGABLE_BY_BACKGROUND);
|
||||
gAutomapWindow = window;
|
||||
|
||||
int scannerBtn = buttonCreate(window,
|
||||
111,
|
||||
@@ -493,10 +496,16 @@ void automapShow(bool isInGame, bool isUsingScanner)
|
||||
}
|
||||
|
||||
windowDestroy(window);
|
||||
gAutomapWindow = -1;
|
||||
fontSetCurrent(oldFont);
|
||||
touch_set_touchscreen_mode(false);
|
||||
}
|
||||
|
||||
int automapGetWindow()
|
||||
{
|
||||
return windowGetWindow(gAutomapWindow) != nullptr ? gAutomapWindow : -1;
|
||||
}
|
||||
|
||||
// Renders automap in Map window.
|
||||
//
|
||||
// 0x41BD1C draw_top_down_map
|
||||
|
||||
@@ -55,6 +55,7 @@ void automapShow(bool isInGame, bool isUsingScanner);
|
||||
int automapRenderInPipboyWindow(int win, int map, int elevation);
|
||||
int automapSaveCurrent();
|
||||
int automapGetHeader(AutomapHeader** automapHeaderPtr);
|
||||
int automapGetWindow();
|
||||
|
||||
void automapSetDisplayMap(int map, bool available);
|
||||
|
||||
|
||||
+36
-10
@@ -663,7 +663,7 @@ static int gCharacterEditorPrimaryStatMinusBtns[7];
|
||||
static unsigned char* gCharacterEditorWindowBuffer;
|
||||
|
||||
// 0x57060C edit_win
|
||||
static int gCharacterEditorWindow;
|
||||
static int gCharacterEditorWindow = -1;
|
||||
|
||||
// + stats buttons
|
||||
//
|
||||
@@ -1436,24 +1436,27 @@ static int characterEditorWindowInit()
|
||||
str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 111);
|
||||
strcpy(kills, str);
|
||||
|
||||
int tabLabelY = 5;
|
||||
int inactiveTabLabelY = tabLabelY + 1;
|
||||
|
||||
// perks selected
|
||||
len = fontGetStringWidth(perks);
|
||||
fontDrawText(
|
||||
gCharacterEditorFrmCopy[46] + 5 * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 61 - len / 2,
|
||||
gCharacterEditorFrmCopy[46] + tabLabelY * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 61 - len / 2,
|
||||
perks,
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
_colorTable[18979]);
|
||||
|
||||
len = fontGetStringWidth(karma);
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED] + 5 * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 159 - len / 2,
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED] + inactiveTabLabelY * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 159 - len / 2,
|
||||
karma,
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
_colorTable[14723]);
|
||||
|
||||
len = fontGetStringWidth(kills);
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED] + 5 * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 257 - len / 2,
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED] + inactiveTabLabelY * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 257 - len / 2,
|
||||
kills,
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
@@ -1461,21 +1464,21 @@ static int characterEditorWindowInit()
|
||||
|
||||
// karma selected
|
||||
len = fontGetStringWidth(perks);
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + 5 * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 61 - len / 2,
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + inactiveTabLabelY * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 61 - len / 2,
|
||||
perks,
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
_colorTable[14723]);
|
||||
|
||||
len = fontGetStringWidth(karma);
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + 5 * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 159 - len / 2,
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + tabLabelY * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 159 - len / 2,
|
||||
karma,
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
_colorTable[18979]);
|
||||
|
||||
len = fontGetStringWidth(kills);
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + 5 * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 257 - len / 2,
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KARMA_FOLDER_SELECTED] + inactiveTabLabelY * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 257 - len / 2,
|
||||
kills,
|
||||
_editorFrmImages[46].getWidth(),
|
||||
_editorFrmImages[46].getWidth(),
|
||||
@@ -1483,21 +1486,21 @@ static int characterEditorWindowInit()
|
||||
|
||||
// kills selected
|
||||
len = fontGetStringWidth(perks);
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + 5 * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 61 - len / 2,
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + inactiveTabLabelY * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 61 - len / 2,
|
||||
perks,
|
||||
_editorFrmImages[46].getWidth(),
|
||||
_editorFrmImages[46].getWidth(),
|
||||
_colorTable[14723]);
|
||||
|
||||
len = fontGetStringWidth(karma);
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + 5 * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 159 - len / 2,
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + inactiveTabLabelY * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 159 - len / 2,
|
||||
karma,
|
||||
_editorFrmImages[46].getWidth(),
|
||||
_editorFrmImages[46].getWidth(),
|
||||
_colorTable[14723]);
|
||||
|
||||
len = fontGetStringWidth(kills);
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + 5 * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 257 - len / 2,
|
||||
fontDrawText(gCharacterEditorFrmCopy[EDITOR_GRAPHIC_KILLS_FOLDER_SELECTED] + tabLabelY * _editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth() + 257 - len / 2,
|
||||
kills,
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
_editorFrmImages[EDITOR_GRAPHIC_PERKS_FOLDER_SELECTED].getWidth(),
|
||||
@@ -5680,6 +5683,29 @@ void characterEditorReset()
|
||||
gCharacterEditorLastLevel = 1;
|
||||
}
|
||||
|
||||
int characterEditorGetWindow()
|
||||
{
|
||||
return windowGetWindow(gCharacterEditorWindow) != nullptr ? gCharacterEditorWindow : -1;
|
||||
}
|
||||
|
||||
void characterEditorDisplayStats()
|
||||
{
|
||||
if (windowGetWindow(gCharacterEditorWindow) == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
critterUpdateDerivedStats(gDude);
|
||||
critterAdjustHitPoints(gDude, 0);
|
||||
|
||||
characterEditorDrawSkills(0);
|
||||
characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0);
|
||||
characterEditorDrawPcStats();
|
||||
characterEditorDrawDerivedStats();
|
||||
characterEditorDrawFolders();
|
||||
characterEditorDrawCard();
|
||||
windowRefresh(gCharacterEditorWindow);
|
||||
}
|
||||
|
||||
// level up if needed
|
||||
//
|
||||
// 0x43C228 UpdateLevel
|
||||
|
||||
@@ -14,6 +14,8 @@ char* _strmfe(char* dest, const char* name, const char* ext);
|
||||
int characterEditorSave(File* stream);
|
||||
int characterEditorLoad(File* stream);
|
||||
void characterEditorReset();
|
||||
int characterEditorGetWindow();
|
||||
void characterEditorDisplayStats();
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
||||
+53
-64
@@ -3537,7 +3537,7 @@ void attackInit(Attack* attack, Object* attacker, Object* defender, int hitMode,
|
||||
attack->defenderFlags = 0;
|
||||
attack->defenderKnockback = 0;
|
||||
attack->extrasLength = 0;
|
||||
attack->oops = defender;
|
||||
attack->intendedTarget = defender;
|
||||
}
|
||||
|
||||
// 0x422F3C
|
||||
@@ -4336,7 +4336,7 @@ static int attackComputeCriticalFailure(Attack* attack)
|
||||
int rounds = attackType == ATTACK_TYPE_RANGED ? attack->ammoQuantity : 1;
|
||||
attackComputeDamage(attack, rounds, 2);
|
||||
} else {
|
||||
attack->defender = attack->oops;
|
||||
attack->defender = attack->intendedTarget;
|
||||
}
|
||||
|
||||
if (attack->defender != nullptr) {
|
||||
@@ -4758,31 +4758,28 @@ void _apply_damage(Attack* attack, bool animated)
|
||||
{
|
||||
Object* attacker = attack->attacker;
|
||||
bool attackerIsCritter = attacker != nullptr && FID_TYPE(attacker->fid) == OBJ_TYPE_CRITTER;
|
||||
bool v5 = attack->defender != attack->oops;
|
||||
bool hitUnintendedTarget = attack->defender != attack->intendedTarget;
|
||||
|
||||
if (attackerIsCritter && (attacker->data.critter.combat.results & DAM_DEAD) == 0) {
|
||||
_set_new_results(attacker, attack->attackerFlags);
|
||||
// TODO: Not sure about "attack->defender == attack->oops".
|
||||
_damage_object(attacker, attack->attackerDamage, animated, attack->defender == attack->oops, attacker);
|
||||
_damage_object(attacker, attack->attackerDamage, animated, hitUnintendedTarget, attacker);
|
||||
}
|
||||
|
||||
Object* v7 = attack->oops;
|
||||
if (v7 != nullptr && v7 != attack->defender) {
|
||||
_combatai_notify_onlookers(v7);
|
||||
// bystanders might flee
|
||||
if (attack->intendedTarget != nullptr && hitUnintendedTarget) {
|
||||
_combatai_notify_onlookers(attack->intendedTarget);
|
||||
}
|
||||
|
||||
Object* defender = attack->defender;
|
||||
bool defenderIsCritter = defender != nullptr && FID_TYPE(defender->fid) == OBJ_TYPE_CRITTER;
|
||||
|
||||
if (!defenderIsCritter && !v5) {
|
||||
bool v9 = objectIsPartyMember(attack->defender) && objectIsPartyMember(attack->attacker) ? false : true;
|
||||
if (v9) {
|
||||
if (defender != nullptr) {
|
||||
if (defender->sid != -1) {
|
||||
scriptSetFixedParam(defender->sid, attack->attackerDamage);
|
||||
scriptSetObjects(defender->sid, attack->attacker, attack->weapon);
|
||||
scriptExecProc(defender->sid, SCRIPT_PROC_DAMAGE);
|
||||
}
|
||||
if (!defenderIsCritter && !hitUnintendedTarget) {
|
||||
bool shouldRunDamageProc = !objectIsPartyMember(attack->defender) || !objectIsPartyMember(attack->attacker);
|
||||
if (shouldRunDamageProc) {
|
||||
if (defender != nullptr && defender->sid != -1) {
|
||||
scriptSetFixedParam(defender->sid, attack->attackerDamage);
|
||||
scriptSetObjects(defender->sid, attack->attacker, attack->weapon);
|
||||
scriptExecProc(defender->sid, SCRIPT_PROC_DAMAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4790,24 +4787,17 @@ void _apply_damage(Attack* attack, bool animated)
|
||||
if (defenderIsCritter && (defender->data.critter.combat.results & DAM_DEAD) == 0) {
|
||||
_set_new_results(defender, attack->defenderFlags);
|
||||
|
||||
if (defenderIsCritter) {
|
||||
if (defenderIsCritter) {
|
||||
if ((defender->data.critter.combat.results & (DAM_DEAD | DAM_KNOCKED_OUT)) != 0) {
|
||||
if (!v5 || defender != gDude) {
|
||||
critterSetWhoHitMe(defender, attack->attacker);
|
||||
}
|
||||
} else if (defender == attack->oops || defender->data.critter.combat.team != attack->attacker->data.critter.combat.team) {
|
||||
_combatai_check_retaliation(defender, attack->attacker);
|
||||
}
|
||||
if ((defender->data.critter.combat.results & (DAM_DEAD | DAM_KNOCKED_OUT)) != 0) {
|
||||
if (!hitUnintendedTarget || defender != gDude) {
|
||||
critterSetWhoHitMe(defender, attack->attacker);
|
||||
}
|
||||
} else if (attackerIsCritter && (defender == attack->intendedTarget || defender->data.critter.combat.team != attack->attacker->data.critter.combat.team)) {
|
||||
_combatai_check_retaliation(defender, attack->attacker);
|
||||
}
|
||||
|
||||
scriptSetObjects(defender->sid, attack->attacker, attack->weapon);
|
||||
_damage_object(defender, attack->defenderDamage, animated, attack->defender != attack->oops, attacker);
|
||||
|
||||
if (defenderIsCritter) {
|
||||
_combatai_notify_onlookers(defender);
|
||||
}
|
||||
_damage_object(defender, attack->defenderDamage, animated, hitUnintendedTarget, attacker);
|
||||
_combatai_notify_onlookers(defender);
|
||||
|
||||
if (attack->defenderDamage >= 0 && (attack->attackerFlags & DAM_HIT) != 0) {
|
||||
scriptSetObjects(attack->attacker->sid, nullptr, attack->defender);
|
||||
@@ -4824,14 +4814,13 @@ void _apply_damage(Attack* attack, bool animated)
|
||||
if (defenderIsCritter) {
|
||||
if ((obj->data.critter.combat.results & (DAM_DEAD | DAM_KNOCKED_OUT)) != 0) {
|
||||
critterSetWhoHitMe(obj, attack->attacker);
|
||||
} else if (obj->data.critter.combat.team != attack->attacker->data.critter.combat.team) {
|
||||
} else if (attackerIsCritter && obj->data.critter.combat.team != attack->attacker->data.critter.combat.team) {
|
||||
_combatai_check_retaliation(obj, attack->attacker);
|
||||
}
|
||||
}
|
||||
|
||||
scriptSetObjects(obj->sid, attack->attacker, attack->weapon);
|
||||
// TODO: Not sure about defender == oops.
|
||||
_damage_object(obj, attack->extrasDamage[index], animated, attack->defender == attack->oops, attack->attacker);
|
||||
_damage_object(obj, attack->extrasDamage[index], animated, hitUnintendedTarget, attack->attacker);
|
||||
_combatai_notify_onlookers(obj);
|
||||
|
||||
if (attack->extrasDamage[index] >= 0) {
|
||||
@@ -4900,18 +4889,18 @@ static void _set_new_results(Object* critter, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
// 0x425020
|
||||
static void _damage_object(Object* a1, int damage, bool animated, int a4, Object* a5)
|
||||
// 0x425020 damage_object
|
||||
static void _damage_object(Object* target, int damage, bool animated, int hitUnintendedTarget, Object* damageSource)
|
||||
{
|
||||
if (a1 == nullptr) {
|
||||
if (target == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (FID_TYPE(a1->fid) != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(target->fid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (critterFlagCheck(a1->pid, CRITTER_INVULNERABLE)) {
|
||||
if (critterFlagCheck(target->pid, CRITTER_INVULNERABLE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4919,50 +4908,50 @@ static void _damage_object(Object* a1, int damage, bool animated, int a4, Object
|
||||
return;
|
||||
}
|
||||
|
||||
critterAdjustHitPoints(a1, -damage);
|
||||
critterAdjustHitPoints(target, -damage);
|
||||
|
||||
if (a1 == gDude) {
|
||||
if (target == gDude) {
|
||||
interfaceRenderHitPoints(animated);
|
||||
}
|
||||
|
||||
a1->data.critter.combat.damageLastTurn += damage;
|
||||
target->data.critter.combat.damageLastTurn += damage;
|
||||
|
||||
if (!a4) {
|
||||
if (!hitUnintendedTarget) {
|
||||
// TODO: Not sure about this one.
|
||||
if (!objectIsPartyMember(a1) || !objectIsPartyMember(a5)) {
|
||||
scriptSetFixedParam(a1->sid, damage);
|
||||
scriptExecProc(a1->sid, SCRIPT_PROC_DAMAGE);
|
||||
if (!objectIsPartyMember(target) || !objectIsPartyMember(damageSource)) {
|
||||
scriptSetFixedParam(target->sid, damage);
|
||||
scriptExecProc(target->sid, SCRIPT_PROC_DAMAGE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((a1->data.critter.combat.results & DAM_DEAD) != 0) {
|
||||
scriptSetObjects(a1->sid, a1->data.critter.combat.whoHitMe, nullptr);
|
||||
scriptExecProc(a1->sid, SCRIPT_PROC_DESTROY);
|
||||
itemDestroyAllHidden(a1);
|
||||
if ((target->data.critter.combat.results & DAM_DEAD) != 0) {
|
||||
scriptSetObjects(target->sid, target->data.critter.combat.whoHitMe, nullptr);
|
||||
scriptExecProc(target->sid, SCRIPT_PROC_DESTROY);
|
||||
itemDestroyAllHidden(target);
|
||||
|
||||
if (a1 != gDude) {
|
||||
Object* whoHitMe = a1->data.critter.combat.whoHitMe;
|
||||
if (target != gDude) {
|
||||
Object* whoHitMe = target->data.critter.combat.whoHitMe;
|
||||
if (whoHitMe == gDude || (whoHitMe != nullptr && whoHitMe->data.critter.combat.team == gDude->data.critter.combat.team)) {
|
||||
bool scriptOverrides = false;
|
||||
Script* scr;
|
||||
if (scriptGetScript(a1->sid, &scr) != -1) {
|
||||
if (scriptGetScript(target->sid, &scr) != -1) {
|
||||
scriptOverrides = scr->scriptOverrides;
|
||||
}
|
||||
|
||||
if (!scriptOverrides) {
|
||||
_combat_exps += critterGetExp(a1);
|
||||
killsIncByType(critterGetKillType(a1));
|
||||
_combat_exps += critterGetExp(target);
|
||||
killsIncByType(critterGetKillType(target));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (a1->sid != -1) {
|
||||
scriptRemove(a1->sid);
|
||||
a1->sid = -1;
|
||||
if (target->sid != -1) {
|
||||
scriptRemove(target->sid);
|
||||
target->sid = -1;
|
||||
}
|
||||
|
||||
partyMemberRemove(a1);
|
||||
scriptHooks_OnDeath(a1);
|
||||
partyMemberRemove(target);
|
||||
scriptHooks_OnDeath(target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5034,11 +5023,11 @@ void _combat_display(Attack* attack)
|
||||
|
||||
char text[280];
|
||||
if (attack->defender != nullptr
|
||||
&& attack->oops != nullptr
|
||||
&& attack->defender != attack->oops
|
||||
&& attack->intendedTarget != nullptr
|
||||
&& attack->defender != attack->intendedTarget
|
||||
&& (attack->attackerFlags & DAM_HIT) != 0) {
|
||||
if (FID_TYPE(attack->defender->fid) == OBJ_TYPE_CRITTER) {
|
||||
if (attack->oops == gDude) {
|
||||
if (attack->intendedTarget == gDude) {
|
||||
// 608 (male) - Oops! %s was hit instead of you!
|
||||
// 708 (female) - Oops! %s was hit instead of you!
|
||||
messageListItem.num = baseMessageId + 8;
|
||||
@@ -5048,7 +5037,7 @@ void _combat_display(Attack* attack)
|
||||
} else {
|
||||
// 509 (male) - Oops! %s were hit instead of %s!
|
||||
// 559 (female) - Oops! %s were hit instead of %s!
|
||||
const char* name = objectGetName(attack->oops);
|
||||
const char* name = objectGetName(attack->intendedTarget);
|
||||
messageListItem.num = baseMessageId + 9;
|
||||
if (messageListGetItem(&gCombatMessageList, &messageListItem)) {
|
||||
snprintf(text, sizeof(text), messageListItem.text, mainCritterName, name);
|
||||
|
||||
+2
-2
@@ -103,7 +103,7 @@ typedef struct Attack {
|
||||
Object* attacker;
|
||||
int hitMode;
|
||||
Object* weapon;
|
||||
int attackHitLocation;
|
||||
int attackHitLocation; // UNUSED?
|
||||
int attackerDamage;
|
||||
int attackerFlags;
|
||||
int ammoQuantity;
|
||||
@@ -114,7 +114,7 @@ typedef struct Attack {
|
||||
int defenderDamage;
|
||||
int defenderFlags;
|
||||
int defenderKnockback;
|
||||
Object* oops;
|
||||
Object* intendedTarget; // mainTarget
|
||||
int extrasLength;
|
||||
Object* extras[EXPLOSION_TARGET_COUNT];
|
||||
int extrasHitLocation[EXPLOSION_TARGET_COUNT];
|
||||
|
||||
+14
-4
@@ -89,7 +89,6 @@ namespace fallout {
|
||||
static int gameTakeScreenshot(int width, int height, unsigned char* buffer, unsigned char* palette);
|
||||
static void gameFreeGlobalVars();
|
||||
static bool tryLoadBaseCEModAtPath(const char* path, bool* found, bool* openFailed);
|
||||
static void showHelp();
|
||||
static int gameDbInit();
|
||||
static void showSplash();
|
||||
|
||||
@@ -1186,12 +1185,21 @@ static void gameFreeGlobalVars()
|
||||
}
|
||||
|
||||
// 0x443F74
|
||||
static void showHelp()
|
||||
void showHelp()
|
||||
{
|
||||
ScopedGameMode gm(GameMode::kHelp);
|
||||
|
||||
bool isoWasEnabled = isoDisable();
|
||||
gameMouseObjectsHide();
|
||||
bool gameMouseWasVisible;
|
||||
if (isoWasEnabled) {
|
||||
gameMouseWasVisible = gameMouseObjectsIsVisible();
|
||||
} else {
|
||||
gameMouseWasVisible = false;
|
||||
}
|
||||
|
||||
if (gameMouseWasVisible) {
|
||||
gameMouseObjectsHide();
|
||||
}
|
||||
|
||||
gameMouseSetCursor(MOUSE_CURSOR_NONE);
|
||||
|
||||
@@ -1257,7 +1265,9 @@ static void showHelp()
|
||||
colorCycleEnable();
|
||||
}
|
||||
|
||||
gameMouseObjectsShow();
|
||||
if (gameMouseWasVisible) {
|
||||
gameMouseObjectsShow();
|
||||
}
|
||||
|
||||
if (isoWasEnabled) {
|
||||
isoEnable();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user