Skip to content

Commit

Permalink
Stimpak/Healing powder scales with First Aid skill
Browse files Browse the repository at this point in the history
- New pbs_first_aid script for heal scaling (dude only)
- Stimpak: removed small HP reduction to avoid confusion, narrowed heal amt spread
- Super Stimpak: nerfed from 5x avg Stimpak to 4x (75->60)
- Show current heal amount in item descriptions
- Add toggle to installer
  • Loading branch information
phobos2077 committed May 18, 2024
1 parent 488507a commit a985f8e
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 23 deletions.
5 changes: 2 additions & 3 deletions docs/ecco_readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@
Talking Heads Addon & Talking Heads Actually Talk (THAT):
- Full built-in support, no patches needed (if you previously used compatibility patches, DELETE them)

Inventory Filter (2.0.2 from github):
Inventory Filter (2.0.3+ from github):
- SmartBarter option seems to cause issues with barter, avoid!

FO2Tweaks:
Expand All @@ -194,7 +194,7 @@ Companion Expansion:

-=== CREDITS ===-

Mod was developed by phobos2077 between 2010 and 2023 (with years-long gaps).
Mod was developed by phobos2077 between 2010 and 2024 (with years-long gaps).

Additional dialogs, designs, flow fixes: Lujo.
Russian translators: Pyran, Drobovik, phobos2077, Frederika, PolarTulip.
Expand All @@ -213,7 +213,6 @@ Many thanks to following people, who made this mod possible:
- vad for F12se - an invaluable mod testing/debugging tool
- PercivalCrump for another save editor with unique features
- Ziro for solid balance advice
- pelicano for his Party Orders addon
- Haenlomal, Glovz and Burn for their damage formulas that inspired me to make my own
- people at NMA and Nuclear-City forums for useful comments
- Black Isle Studios (R.I.P.) for my favorite game of all time!
Expand Down
9 changes: 1 addition & 8 deletions docs/todo.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ for 0.9.*:

for "future":
- add warning message if wrong sfall version is used (save version to ini, if it changed and still wrong, show message again)
- Stimpak & Healing powder heal amt to depend upon First Aid skill
- add tie-ins to barter "demand" feature, have some trader explain it in dialog (and maybe also boost your barter skill)
- add info about bonus move points to stat description


Considering:
- buff Sharpened Spear & Sledge (check progression)
- add Cattle Prod Modoc, VC, Gecko, Broken Hills (check balance)
- add Cattle Prod to Modoc, VC, Gecko, Broken Hills (check balance)
- add crafting components like rocks and junk to human enemy bodies on death with small probability
- Hunting Rifle -> Scoped for Slags rewards
- Marcus Scoped Rifle to something better as reward
Expand All @@ -20,13 +17,9 @@ Considering:


IDEAS:
- script for automatically adjusting/randomizing NPC equipment in random encounters
- crafting robes?
- crafting more advanced items require Workbench (scenery object) in close proximity (check FRM from FOnline)
- add another Sword-like weapon to take advantage of new Wakizashi animation in RPU (Make-shift sword? Between Wakizashi and Combat Knife, but heavy)
- Bonus Move perk should give 3-4 points per level instead of 2 + simulate select NPCs to have this perk
- bonus move points based on EN instead of AG
- remove bonus move points based on AG, but make perk more accessible? (and give it to some NPC's?)
- remove early link to EPA (it has too OP enemies and loot)? - on the other hand, the area has lots of difficult random encounters!
- Reduce ammo/drug loot in containers similar to critter loot and FNV Famine mod (less reduction for closed containers, etc.)
- one more "unarmed" weapon above Spiked Knuckles (knuckles with knife?)
Expand Down
11 changes: 6 additions & 5 deletions extra/installer.iss
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ en.InstallCustom=Custom install
en.InstallNull=Uncheck all

en.CMain=EcCo Gameplay Overhaul mod
en.CCombatFreeMove=Bonus move points for high AG characters
;en.CCombatFreeMove=Bonus move points for high AG characters
en.CCarryUnspentAP=Carry up to 2 unspent AP to next round
en.RemoveBonusRoF=Remove Bonus Rate of Fire perk
en.StimpakRadiation=Stimpaks slightly irradiate on use
en.StimpakSkillScaling=Stimpaks & Healing Powders heal amount scales with First Aid skill

en.WFalloutNotFound=Fallout not detected in selected directory (fallout2.exe), mod won't work. Install anyway?
en.WRPNotFound=Restoration Project not detected in selected directory! This mod is only compatible with RPU 2.6 or above. Are you sure you want to continue?
Expand All @@ -79,10 +80,11 @@ ru.InstallCustom=Выборочная установка
ru.InstallNull=Ничего не выбирать
ru.CMain=EcCo - переработка геймплея
ru.CCombatFreeMove=Бонусные ОД всем персонажам с высокой Ловкостью
;ru.CCombatFreeMove=Бонусные ОД всем персонажам с высокой Ловкостью
ru.CCarryUnspentAP=Перенос части непотраченных ОД на следующих ход
ru.RemoveBonusRoF=Удалить перк "Бонус скорострельности"
ru.StimpakRadiation=Стимпаки слегка облучают при применении
ru.StimpakSkillScaling=Эффективность стимпаков и лечебных порошков зависит от навыка первой помощи
ru.WFalloutNotFound=По указанному пути не найдена установленная игра (fallout2.exe), мод не будет работать! Все равно установить?
ru.WRPNotFound=Restoration Project не обнаружен в указанной папке! Данный мод совместим только с RPU 2.6. Все равно продолжить?
Expand All @@ -96,9 +98,9 @@ Name: "custom"; Description: "{cm:InstallCustom}"; Flags: iscustom
[Components]
Name: "main"; Description: "{cm:CMain}"; Types: full custom; Flags: fixed
Name: "combat_free_move"; Description: "{cm:CCombatFreeMove}"; Types: full
Name: "carry_unspent_ap"; Description: "{cm:CCarryUnspentAP}"; Types: full
Name: "remove_bonus_rof"; Description: "{cm:RemoveBonusRoF}"; Types: full
Name: "stimpak_skill_scaling"; Description: "{cm:StimpakSkillScaling}"; Types: full
Name: "stimpak_radiation"; Description: "{cm:StimpakRadiation}"; Types: full
[InstallDelete]
Expand Down Expand Up @@ -141,10 +143,9 @@ Filename: "{app}\ddraw.ini"; Section: "Misc"; Key: "MovieTimer_artimer4"; String
;Filename: "{app}\ddraw.ini"; Section: "Misc"; Key: "CheckWeaponAmmoCost"; String: "1"; Components: combat
Filename: "{app}\mods\ecco\combat.ini"; Section: "COMBAT_FREE_MOVE"; Key: "mult_dude"; String: "0"; Components: not combat_free_move
Filename: "{app}\mods\ecco\combat.ini"; Section: "COMBAT_FREE_MOVE"; Key: "mult_npc"; String: "0"; Components: not combat_free_move
Filename: "{app}\mods\ecco\combat.ini"; Section: "APCOST"; Key: "carry_unspent_ap"; String: "0"; Components: not carry_unspent_ap
Filename: "{app}\mods\ecco\misc.ini"; Section: "ITEM_TWEAKS"; Key: "stimpak_radiation_disable"; String: "1"; Components: not stimpak_radiation
Filename: "{app}\mods\ecco\misc.ini"; Section: "FIRST_AID"; Key: "ini_healing_skill_max"; String: "0"; Components: not stimpak_skill_scaling
Filename: "{app}\sfall\perks.ini"; Section: "5"; Key: "Level"; String: "15"; Components: not remove_bonus_rof
Expand Down
8 changes: 4 additions & 4 deletions proto_src/items/drug/00000040.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ drugData:
- STAT_CURRENT_HIT_POINTS
- STAT_CURRENT_RADIATION_LEVEL
amount:
- 10
- 20
- 12
- 18
- 0
duration1: 1
amount1:
Expand All @@ -32,8 +32,8 @@ drugData:
- 0
duration2: 5
amount2:
- -4
- -1
- 0
- 0
- 5
addictionChance: 0
withdrawalEffect: -1
Expand Down
6 changes: 3 additions & 3 deletions proto_src/items/drug/00000144.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ drugData:
- NONE
- STAT_CURRENT_RADIATION_LEVEL
amount:
- 75
- 60
- 0
- 0
duration1: 1
amount1:
- -5
- -3
- 0
- 0
duration2: 5
amount2:
- -10
- -6
- 0
- 25
addictionChance: 0
Expand Down
Binary file modified root/data/proto/items/00000040.pro
Binary file not shown.
Binary file modified root/data/proto/items/00000144.pro
Binary file not shown.
5 changes: 5 additions & 0 deletions root/data/text/english/game/pbs_combat.msg
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@
{210}{}{%s damaged her %s beyond repair.}
{211}{}{%s lost her %s in the heat of battle.}
{212}{}{%s shattered her %s to pieces while defending.}


# first aid
{300}{}{ Restores %d-%d HP.}
{301}{}{ Restores %d HP.}
5 changes: 5 additions & 0 deletions root/data/text/russian/game/pbs_combat.msg
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@
{210}{}{%s ��������� ���� %s �� ��������������.}
{211}{}{%s �������� %s � ���� ��������.}
{212}{}{%s, ���������, ������� ���� %s �� �����.}


# first aid
{300}{}{ ��������������� %d-%d ��.}
{301}{}{ ��������������� %d ��.}
15 changes: 15 additions & 0 deletions root/mods/ecco/misc.ini
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ exp_mult=10
stimpak_radiation_disable=0


[FIRST_AID]
; Changes the HP gain amount when using healing drugs depending on skill level (player only)
; List of drug pids to apply skill scaling: Healing Powder, Stimpak, Super Stimpak
healing_drug_pids=273,40,144

; First Aid base = 2 * (PE + IN). The minimum base is 4 (1 PE, 1 IN), average is 20 (5 PE, 5 IN).
; With these settings: average heal amt is equal to vanilla at 36% First Aid and twice at 150%.
; Healing powder (8-18): at 4% (5.6-12.6), at 20% (6.9-15.5), at 150% (16.0-36)
; Stimpak (12-18): at 4% (8.4-12.6), at 20% (10.3-15.5), at 150% (24.0-36)
; Super Stimpak (60): at 4% (42), at 20% (51.6), at 150% (120)
healing_mult_min=0.66
healing_mult_max=2.0
healing_skill_max=150


[TOWN_REP]
0=47 ; ARROYO
2=48 ; KLAMATH
Expand Down
161 changes: 161 additions & 0 deletions scripts_src/_pbs_main/gl_pbs_first_aid.ssl
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
First aid tweaks:
- Healing items immediate heal amount will be scaled with First Aid skill (player only).
*/
#define SCRIPT_REALNAME "pbs_first_aid"

#include "../sfall/sfall.h"
#include "../sfall/lib.arrays.h"
#include "../sfall/lib.math.h"
//#include "../sfall/lib.obj.h"
#include "../sfall/define_lite.h"
#include "../sfall/define_extra.h"

#include "../_pbs_headers/math_ext.h"
#include "../_pbs_headers/ecco_ids.h"
#include "../_pbs_headers/ecco_ini.h"
#include "../_pbs_headers/ecco_log.h"
#include "../_pbs_headers/ecco_msg.h"

#define INI_FILE INI_MISC
#define INI_SECTION "FIRST_AID"

#define HI_STAT_MIN_HP (1)
#define HI_STAT_MAX_HP (2)

variable begin
ini_healing_drug_pids;
ini_healing_mult_min;
ini_healing_mult_max;
ini_healing_skill_max;
default_stats;
end

#define is_scalable_healing_item(itemPid) (proto_data(itemPid, it_type) == item_type_drug and is_in_array(itemPid, ini_healing_drug_pids))

procedure remember_default_stats begin
variable pid, stats;
default_stats := create_array_map;
foreach (pid in ini_healing_drug_pids) begin
default_stats[pid] := array_fixed({
HI_STAT_MIN_HP: get_proto_data(pid, PROTO_DR_AMOUNT_1_A),
HI_STAT_MAX_HP: get_proto_data(pid, PROTO_DR_AMOUNT_1_B)
});
end
end

procedure calculate_healing_min_max(variable itemPid, variable user, variable forDisplay := false) begin
variable
defaultMinHp := default_stats[itemPid][HI_STAT_MIN_HP],
defaultMaxHp := default_stats[itemPid][HI_STAT_MAX_HP],
skill := has_skill(user, SKILL_FIRST_AID),
skillFactor := math_min(1.0 * skill / ini_healing_skill_max, 1.0),
mult := ini_healing_mult_min + (ini_healing_mult_max - ini_healing_mult_min) * skillFactor,
minHp := defaultMinHp * mult,
maxHp := (defaultMaxHp * mult) if (defaultMaxHp > 0) else 0;

if (forDisplay) then begin
minHp := floor(minHp);
maxHp := ceil(maxHp);
end else begin
minHp := math_round_chance(minHp);
maxHp := math_max(math_round_chance(maxHp), minHp) if (maxHp > 0) else 0;
end
return [minHp, maxHp];
end

/*
Runs when:

a critter uses an object on another critter. (Or themselves)
a critter uses an object from inventory screen AND this object does not have "Use" action flag set and it's not active flare or explosive.
player or AI uses any drug
This is fired before the object is used, and the relevant use_obj_on script procedures are run. You can disable default item behavior.

NOTE: You can't remove and/or destroy this object during the hookscript (game will crash otherwise). To remove it, return 1.

Critter arg0 - The target
Critter arg1 - The user
int arg2 - The object used

int ret0 - overrides hard-coded handler and selects what should happen with the item (0 - place it back, 1 - remove it, -1 - use engine handler)
*/
procedure useobjon_hook begin
variable
target := get_sfall_arg,
user := get_sfall_arg,
item := get_sfall_arg,
itemPid := obj_pid(item);

//display_msg(string_format("%s tries to use %s (%d)", obj_name(user), obj_name(item), proto_data(itemPid, it_type)));
if (is_scalable_healing_item(itemPid)) then begin
if (user == dude_obj) then begin
variable
healingAmt := calculate_healing_min_max(itemPid, user);

set_proto_data(itemPid, PROTO_DR_AMOUNT_1_A, healingAmt[0]);
set_proto_data(itemPid, PROTO_DR_AMOUNT_1_B, healingAmt[1]);
debug_log(string_format("Changed %s min: %d, max: %d", obj_name(item), healingAmt[0], healingAmt[1]));
end else begin // for NPC's always use defaults
set_proto_data(itemPid, PROTO_DR_AMOUNT_1_A, default_stats[itemPid][HI_STAT_MIN_HP]);
set_proto_data(itemPid, PROTO_DR_AMOUNT_1_B, default_stats[itemPid][HI_STAT_MAX_HP]);
end
end
end

/*
procedure is_healing_item(variable item) begin

variable itemPid := obj_pid(item), hpStatIsA, hpStatIsB, hpAmt;
if (obj_type(item) != OBJ_TYPE_ITEM or proto_data(itemPid, it_type) != item_type_drug) then return false;

hpStatIsA := (get_proto_data(itemPid, PROTO_DR_STAT_A) == STAT_current_hp);
hpStatIsB := (get_proto_data(itemPid, PROTO_DR_STAT_B) == STAT_current_hp);
if (not hpStatIsA and not hpStatIsB) then return false;

hpAmt := get_proto_data(itemPid, PROTO_DR_AMOUNT_1_A) if hpStatIsA else get_proto_data(itemPid, PROTO_DR_AMOUNT_1_B);
return hpAmt > 0;
end
*/

/*
Runs when using the examine action icon to display the description of an object. You can override the description text. An example usage would be to add an additional description to the item based on player's stats/skills.

Does not run if the script of the object overrides the description.

NOTE: Returning a pointer to the new text received from the get_string_pointer function is still valid, but the method is DEPRECATED and is left for backward compatibility only.

Obj arg0 - the object

String ret0 - the new description text to use
*/
procedure descriptionobj_hook begin
variable
obj := get_sfall_arg,
objPid := obj_pid(obj),
healAmt, str;

if ((obj_type(obj) != OBJ_TYPE_ITEM) or (not is_scalable_healing_item(objPid))) then return;

healAmt := calculate_healing_min_max(objPid, dude_obj, true);
str := string_format(mstr_ecco_combat(300), healAmt[0], healAmt[1])
if (healAmt[1] > 0)
else string_format(mstr_ecco_combat(301), healAmt[0]);
set_sfall_return(message_str_game(GAME_MSG_PRO_ITEM, get_proto_data(objPid, PROTO_TEXTID) + 1) + str);
end

procedure start begin
if (game_loaded) then begin
int_list_from_ini_file(healing_drug_pids, INI_FILE, INI_SECTION);
float_from_ini_file_clamped(healing_mult_min, INI_FILE, INI_SECTION, 0.0, 10.0);
float_from_ini_file_clamped(healing_mult_max, INI_FILE, INI_SECTION, ini_healing_mult_min, 10.0);
int_from_ini_file_clamped(healing_skill_max, INI_FILE, INI_SECTION, 0, 300);

call remember_default_stats;

if (ini_healing_skill_max > 0 and ini_healing_mult_max > 0.01) then begin
register_hook_proc(HOOK_USEOBJON, useobjon_hook);
register_hook_proc(HOOK_DESCRIPTIONOBJ, descriptionobj_hook);
end
end
end

0 comments on commit a985f8e

Please sign in to comment.