Code refactoring in Arrays.cpp.

Added a new example mod gl_ammomod to modderspack.
This commit is contained in:
NovaRain
2019-05-05 08:47:08 +08:00
parent 42cf5ded97
commit 0f98591b77
15 changed files with 558 additions and 69 deletions
+1 -1
View File
@@ -733,7 +733,7 @@ SkipSizeCheck=0
;Does not require sfall debugging mode
;ExtraCRC=0x00000000,0x00000000
;Set to 1 to stop Fallout from deleting non readonly protos at startup
;Set to 1 to stop Fallout from deleting non read-only protos at startup
;Has pretty nasty side effects when saving/reloading, so don't use for regular gameplay
DontDeleteProtos=0
@@ -0,0 +1,201 @@
;Glovz's Damage Fix
; PID_EXPLOSIVE_ROCKET
[1]
pid=14
ac_adjust=-10
dr_adjust=0
dam_mult=1
dam_div=1
; PID_10MM_JHP
[2]
pid=29
ac_adjust=0
dr_adjust=0
dam_mult=2
dam_div=1
; PID_10MM_AP
[3]
pid=30
ac_adjust=-5
dr_adjust=0
dam_mult=1
dam_div=2
; PID_44_MAGNUM_JHP
[4]
pid=31
ac_adjust=0
dr_adjust=-10
dam_mult=2
dam_div=1
; PID_FLAMETHROWER_FUEL
[5]
pid=32
ac_adjust=-20
dr_adjust=0
dam_mult=1
dam_div=1
; PID_14MM_AP
[6]
pid=33
ac_adjust=-5
dr_adjust=-30
dam_mult=1
dam_div=2
; PID_223_FMJ
[7]
pid=34
ac_adjust=-15
dr_adjust=-15
dam_mult=2
dam_div=2
; PID_5MM_JHP
[8]
pid=35
ac_adjust=0
dr_adjust=-15
dam_mult=2
dam_div=1
; PID_5MM_AP
[9]
pid=36
ac_adjust=-5
dr_adjust=-15
dam_mult=1
dam_div=2
; PID_ROCKET_AP
[10]
pid=37
ac_adjust=-10
dr_adjust=0
dam_mult=1
dam_div=2
; PID_SMALL_ENERGY_CELL
[11]
pid=38
ac_adjust=-20
dr_adjust=0
dam_mult=2
dam_div=1
; PID_MICRO_FUSION_CELL
[12]
pid=39
ac_adjust=-20
dr_adjust=0
dam_mult=2
dam_div=1
; PID_SHOTGUN_SHELLS
[13]
pid=95
ac_adjust=-15
dr_adjust=0
dam_mult=3
dam_div=1
; PID_44_FMJ_MAGNUM
[14]
pid=111
ac_adjust=-5
dr_adjust=-10
dam_mult=2
dam_div=2
; PID_9MM_BALL
[15]
pid=121
ac_adjust=0
dr_adjust=0
dam_mult=1
dam_div=1
; PID_BBS
[16]
pid=163
ac_adjust=0
dr_adjust=0
dam_mult=1
dam_div=1
; PID_ROBO_ROCKET_AMMO
[17]
pid=274
ac_adjust=-10
dr_adjust=-10
dam_mult=1
dam_div=1
; PID_45_CALIBER_AMMO
[18]
pid=357
ac_adjust=0
dr_adjust=-5
dam_mult=2
dam_div=1
; PID_2MM_EC_AMMO
[19]
pid=358
ac_adjust=-25
dr_adjust=-20
dam_mult=1
dam_div=3
; PID_4_7MM_CASELESS
[20]
pid=359
ac_adjust=-5
dr_adjust=-25
dam_mult=1
dam_div=2
; PID_9MM_AMMO
[21]
pid=360
ac_adjust=0
dr_adjust=0
dam_mult=2
dam_div=1
; PID_HN_NEEDLER_CARTRIDGE
[22]
pid=361
ac_adjust=-20
dr_adjust=-5
dam_mult=1
dam_div=1
; PID_HN_AP_NEEDLER_CARTRIDGE
[23]
pid=362
ac_adjust=-20
dr_adjust=-5
dam_mult=1
dam_div=2
; PID_7_62MM_AMMO
[24]
pid=363
ac_adjust=-10
dr_adjust=-20
dam_mult=2
dam_div=2
; PID_FLAMETHROWER_FUEL_MK_II
[25]
pid=382
ac_adjust=-20
dr_adjust=-15
dam_mult=1
dam_div=1
+201
View File
@@ -0,0 +1,201 @@
;YAAM
; PID_EXPLOSIVE_ROCKET
[1]
pid=14
ac_adjust=0
dr_adjust=0
dam_mult=3
dam_div=2
; PID_10MM_JHP
[2]
pid=29
ac_adjust=0
dr_adjust=0
dam_mult=3
dam_div=2
; PID_10MM_AP
[3]
pid=30
ac_adjust=0
dr_adjust=4
dam_mult=1
dam_div=1
; PID_44_MAGNUM_JHP
[4]
pid=31
ac_adjust=0
dr_adjust=0
dam_mult=3
dam_div=2
; PID_FLAMETHROWER_FUEL
[5]
pid=32
ac_adjust=-20
dr_adjust=0
dam_mult=3
dam_div=4
; PID_14MM_AP
[6]
pid=33
ac_adjust=0
dr_adjust=8
dam_mult=1
dam_div=1
; PID_223_FMJ
[7]
pid=34
ac_adjust=-20
dr_adjust=5
dam_mult=1
dam_div=1
; PID_5MM_JHP
[8]
pid=35
ac_adjust=0
dr_adjust=0
dam_mult=3
dam_div=2
; PID_5MM_AP
[9]
pid=36
ac_adjust=0
dr_adjust=4
dam_mult=1
dam_div=1
; PID_ROCKET_AP
[10]
pid=37
ac_adjust=0
dr_adjust=20
dam_mult=1
dam_div=1
; PID_SMALL_ENERGY_CELL
[11]
pid=38
ac_adjust=0
dr_adjust=0
dam_mult=1
dam_div=1
; PID_MICRO_FUSION_CELL
[12]
pid=39
ac_adjust=0
dr_adjust=0
dam_mult=1
dam_div=1
; PID_SHOTGUN_SHELLS
[13]
pid=95
ac_adjust=-10
dr_adjust=0
dam_mult=1
dam_div=1
; PID_44_FMJ_MAGNUM
[14]
pid=111
ac_adjust=0
dr_adjust=5
dam_mult=1
dam_div=1
; PID_9MM_BALL
[15]
pid=121
ac_adjust=0
dr_adjust=2
dam_mult=3
dam_div=2
; PID_BBS
[16]
pid=163
ac_adjust=0
dr_adjust=0
dam_mult=1
dam_div=1
; PID_ROBO_ROCKET_AMMO
[17]
pid=274
ac_adjust=0
dr_adjust=10
dam_mult=1
dam_div=1
; PID_45_CALIBER_AMMO
[18]
pid=357
ac_adjust=0
dr_adjust=0
dam_mult=1
dam_div=1
; PID_2MM_EC_AMMO
[19]
pid=358
ac_adjust=-30
dr_adjust=9
dam_mult=3
dam_div=2
; PID_4_7MM_CASELESS
[20]
pid=359
ac_adjust=-5
dr_adjust=7
dam_mult=3
dam_div=2
; PID_9MM_AMMO
[21]
pid=360
ac_adjust=0
dr_adjust=2
dam_mult=1
dam_div=1
; PID_HN_NEEDLER_CARTRIDGE
[22]
pid=361
ac_adjust=-10
dr_adjust=2
dam_mult=1
dam_div=1
; PID_HN_AP_NEEDLER_CARTRIDGE
[23]
pid=362
ac_adjust=-10
dr_adjust=5
dam_mult=2
dam_div=1
; PID_7_62MM_AMMO
[24]
pid=363
ac_adjust=-5
dr_adjust=2
dam_mult=1
dam_div=1
; PID_FLAMETHROWER_FUEL_MK_II
[25]
pid=382
ac_adjust=-20
dr_adjust=0
dam_mult=1
dam_div=1
Binary file not shown.
@@ -0,0 +1,63 @@
/*
Ammo INI Loader mod for Fallout 2 by NovaRain
---------------------------------------------
- modifies ammo protos with data from an INI file:
* AmmoGlovz.ini if DamageFormula=1 or 2 in ddraw.ini
* AmmoYAAM.ini if DamageFormula=5 in ddraw.ini
* AmmoMod.ini if not using any bulit-in damage formula
Requires sfall 3.5 or higher
*/
#include "..\headers\define_extra.h"
procedure set_ammo_mod;
procedure start;
procedure map_enter_p_proc;
variable ammoIni;
variable enabled;
procedure set_ammo_mod begin
variable pid, dmg_mod, i := 1;
while (i > 0) do begin
pid := get_ini_setting(ammoIni + "|" + i + "|pid");
if (pid < 1) then break;
set_proto_data(pid, PROTO_AM_AC_MOD, get_ini_setting(ammoIni + "|" + i + "|ac_adjust"));
set_proto_data(pid, PROTO_AM_DR_MOD, get_ini_setting(ammoIni + "|" + i + "|dr_adjust"));
// dam_mult and dam_div must be positive integers
dmg_mod := get_ini_setting(ammoIni + "|" + i + "|dam_mult");
if (dmg_mod < 1) then dmg_mod := 1;
set_proto_data(pid, PROTO_AM_DMG_MULT, dmg_mod);
dmg_mod := get_ini_setting(ammoIni + "|" + i + "|dam_div");
if (dmg_mod < 1) then dmg_mod := 1;
set_proto_data(pid, PROTO_AM_DMG_DIV, dmg_mod);
i++;
end
//debug_msg("AmmoMod: " + ammoIni + " - set " + (i - 1) + " ammo protos.");
end
procedure start begin
if game_loaded then begin
ammoIni := get_ini_setting("ddraw.ini|Misc|DamageFormula");
switch (ammoIni) begin
case 1: ammoIni := "AmmoGlovz.ini";
case 2: ammoIni := "AmmoGlovz.ini";
case 5: ammoIni := "AmmoYAAM.ini";
default: ammoIni := "AmmoMod.ini";
end
enabled := get_ini_setting(ammoIni + "|1|pid");
if (enabled > 0) then call set_ammo_mod;
end
end
procedure map_enter_p_proc begin
if (enabled > 0) then call set_ammo_mod;
end
+12
View File
@@ -0,0 +1,12 @@
Ammo INI Loader mod for Fallout 2 by NovaRain
---------------------------------------------
- modifies ammo protos with data from an INI file:
* AmmoGlovz.ini if DamageFormula=1 or 2 in ddraw.ini
* AmmoYAAM.ini if DamageFormula=5 in ddraw.ini
* AmmoMod.ini if not using any bulit-in damage formula
Requires sfall 3.5 or higher.
To use, copy gl_ammomod.int to your scripts folder, and copy the INI files to the same directory as sfall.
+2 -2
View File
@@ -18,6 +18,8 @@
// because the compiler builds the better/optimized code when calling the engine functions
WRAP_WATCOM_FFUNC4(long, _word_wrap, const char*, text, int, maxWidth, DWORD*, buf, BYTE*, count)
WRAP_WATCOM_FFUNC7(long, createWindow, const char*, winName, long, x, long, y, long, width, long, height, long, bgColorIndex, long, flags)
WRAP_WATCOM_FFUNC3(void, display_inventory, long, inventoryOffset, long, visibleOffset, long, mode)
WRAP_WATCOM_FFUNC4(void, display_target_inventory, long, inventoryOffset, long, visibleOffset, DWORD*, targetInventory, long, mode)
WRAP_WATCOM_FFUNC3(FrmSubframeData*, frame_ptr, FrmFrameData*, frm, long, frame, long, direction)
WRAP_WATCOM_FFUNC7(void, make_straight_path_func, fo::GameObject*, objFrom, DWORD, tileFrom, DWORD, tileTo, void*, rotationPtr, DWORD*, result, long, flags, void*, func)
WRAP_WATCOM_FFUNC3(long, object_under_mouse, long, crSwitch, long, inclDude, long, elevation)
@@ -42,8 +44,6 @@ WRAP_WATCOM_FUNC3(long, db_freadIntCount, DbFile*, file, DWORD*, dest, long, cou
WRAP_WATCOM_FUNC2(long, db_fwriteByte, DbFile*, file, long, value)
WRAP_WATCOM_FUNC2(long, db_fwriteInt, DbFile*, file, long, value)
WRAP_WATCOM_FUNC0(void, display_stats)
WRAP_WATCOM_FUNC3(void, display_inventory, long, inventoryOffset, long, visibleOffset, long, mode)
WRAP_WATCOM_FUNC4(void, display_target_inventory, long, inventoryOffset, long, visibleOffset, DWORD*, targetInventory, long, mode)
// perform combat turn for a given critter
WRAP_WATCOM_FUNC2(long, combat_turn, GameObject*, critter, long, isDudeTurn)
WRAP_WATCOM_FUNC1(long, critter_is_dead, GameObject*, critter)
+5 -5
View File
@@ -172,16 +172,16 @@ VAR_(sound_music_path1, char*)
VAR_(sound_music_path2, char*)
VAR_(square, DWORD)
VAR_(squares, DWORD*)
VAR_(stack, DWORD)
VAR_(stack_offset, DWORD)
VARA(stack, DWORD, 10)
VARA(stack_offset, DWORD, 10)
VARA(stat_data, StatInfo, STAT_real_max_stat) // dynamic array
VAR_(stat_flag, DWORD)
VAR_(Tag_, DWORD)
VAR_(tag_skill, DWORD)
VAR_(target_curr_stack, DWORD)
VAR_(target_pud, DWORD)
VAR_(target_stack, DWORD)
VAR_(target_stack_offset, DWORD)
VAR_(target_pud, DWORD*)
VARA(target_stack, DWORD, 10)
VARA(target_stack_offset, DWORD, 10)
VAR_(target_str, DWORD)
VAR_(target_xpos, DWORD)
VAR_(target_ypos, DWORD)
+1 -1
View File
@@ -365,13 +365,13 @@ void LoadOrder::init() {
MakeCall(0x47F5A5, GameMap2Slot_hack); // save game
MakeCall(0x47FB80, SlotMap2Game_hack); // load game
MakeCall(0x47FBBF, SlotMap2Game_hack_attr, 1);
dlogr(" Done", DL_INIT);
LoadGameHook::OnAfterGameInit() += RemoveSavFiles;
LoadGameHook::OnGameReset() += []() {
savPrototypes.clear();
RemoveSavFiles();
};
dlogr(" Done", DL_INIT);
}
}
+2 -6
View File
@@ -17,7 +17,7 @@
*/
#include <cassert>
#include <set>
//#include <unordered_set>
#include <string>
#include <unordered_map>
#include <map>
@@ -582,11 +582,7 @@ static void RunScript(GlobalScript* script) {
- reset reg_anim_* combatstate checks
*/
static void ResetStateAfterFrame() {
if (!tempArrays.empty()) {
for (std::set<DWORD>::iterator it = tempArrays.begin(); it != tempArrays.end(); ++it)
FreeArray(*it);
tempArrays.clear();
}
DeleteAllTempArrays();
RegAnimCombatCheck(1);
}
+11 -2
View File
@@ -1,4 +1,4 @@
#include <set>
#include <unordered_set>
#include <algorithm>
#include "..\ScriptExtender.h"
@@ -22,7 +22,7 @@ ArraysMap arrays;
// auto-incremented ID
DWORD nextArrayID = 1;
// temp arrays: set of arrayId
std::set<DWORD> tempArrays;
std::unordered_set<DWORD> tempArrays;
// saved arrays: arrayKey => arrayId
ArrayKeysMap savedArrays;
// special array ID for array expressions
@@ -407,6 +407,15 @@ void _stdcall FreeArray(DWORD id) {
}
}
void DeleteAllTempArrays() {
if (!tempArrays.empty()) {
for (std::unordered_set<DWORD>::iterator it = tempArrays.begin(); it != tempArrays.end(); ++it) {
FreeArray(*it);
}
tempArrays.clear();
}
}
ScriptValue _stdcall GetArrayKey(DWORD id, int index) {
if (arrays.find(id) == arrays.end() || index < -1 || index > arrays[id].size()) {
return ScriptValue(0);
+3 -4
View File
@@ -2,7 +2,6 @@
#include <functional>
#include <unordered_map>
#include <set>
#include <Windows.h>
#include "ScriptValue.h"
@@ -149,9 +148,6 @@ extern DWORD nextArrayID;
extern DWORD arraysBehavior;
// temp arrays: set of arrayId
extern std::set<DWORD> tempArrays;
// saved arrays: arrayKey => arrayId
extern ArrayKeysMap savedArrays;
@@ -172,6 +168,9 @@ DWORD _stdcall TempArray(DWORD len, DWORD flags);
// destroys array
void _stdcall FreeArray(DWORD id);
// destroy all temp arrays
void DeleteAllTempArrays();
/*
op_get_array_key can be used to iterate over all keys in associative array
*/
+51 -41
View File
@@ -31,9 +31,7 @@ namespace script
void sf_create_array(OpcodeContext& ctx) {
auto arrayId = CreateArray(ctx.arg(0).asInt(), ctx.arg(1).asInt());
ctx.setReturn(
ScriptValue(DataType::INT, arrayId)
);
ctx.setReturn(arrayId, DataType::INT);
}
void sf_set_array(OpcodeContext& ctx) {
@@ -84,9 +82,7 @@ void sf_resize_array(OpcodeContext& ctx) {
void sf_temp_array(OpcodeContext& ctx) {
auto arrayId = TempArray(ctx.arg(0).asInt(), ctx.arg(1).asInt());
ctx.setReturn(
ScriptValue(DataType::INT, arrayId)
);
ctx.setReturn(arrayId, DataType::INT);
}
void sf_fix_array(OpcodeContext& ctx) {
@@ -122,23 +118,34 @@ void sf_stack_array(OpcodeContext& ctx) {
}
// object LISTS
struct sList {
fo::GameObject** obj;
DWORD len;
DWORD pos;
sList(const std::vector<fo::GameObject*>* vec) {
sList(const std::vector<fo::GameObject*>* vec) : pos(0) {
len = vec->size();
obj = new fo::GameObject*[len];
for (size_t i = 0; i < len; i++) {
obj[i] = (*vec)[i];
}
pos = 0;
}
};
static DWORD listID = 0xCCCCCC;
struct ListId {
sList* list;
DWORD id;
ListId(sList* lst) : list(lst) {
id = ++listID;
}
};
static std::vector<ListId> mList;
static void FillListVector(DWORD type, std::vector<fo::GameObject*>& vec) {
vec.reserve(100);
if (type == 6) {
fo::ScriptInstance* scriptPtr;
fo::GameObject* self_obj;
@@ -155,22 +162,20 @@ static void FillListVector(DWORD type, std::vector<fo::GameObject*>& vec) {
scriptPtr = fo::func::scr_find_next_at();
}
}
} else if (type == 4) {
/*} else if (type == 4) {
// TODO: verify code correctness
/*for(int elv=0;elv<2;elv++) {
for(int elv=0;elv<2;elv++) {
DWORD* esquares = &fo::var::squares[elv];
for(int tile=0;tile<10000;tile++) {
esquares[tile]=0x8f000002;
}
}*/
} else {
} else if (type != 4) {
for (int elv = 0; elv < 3; elv++) {
for (int tile = 0; tile < 40000; tile++) {
fo::GameObject* obj = fo::func::obj_find_first_at_tile(elv, tile);
while (obj) {
DWORD otype = (obj->protoId & 0xff000000) >> 24;
DWORD otype = obj->Type();
if (type == 9 || (type == 0 && otype == 1) || (type == 1 && otype == 0) || (type >= 2 && type <= 5 && type == otype)) {
vec.push_back(obj);
}
@@ -181,59 +186,64 @@ static void FillListVector(DWORD type, std::vector<fo::GameObject*>& vec) {
}
}
static void* _stdcall ListBegin(DWORD type) {
static DWORD ListBegin(DWORD type) {
std::vector<fo::GameObject*> vec = std::vector<fo::GameObject*>();
FillListVector(type, vec);
sList* list = new sList(&vec);
return list;
mList.emplace_back(list);
return listID;
}
static DWORD _stdcall ListAsArray(DWORD type) {
static DWORD ListAsArray(DWORD type) {
std::vector<fo::GameObject*> vec = std::vector<fo::GameObject*>();
FillListVector(type, vec);
DWORD id = TempArray(vec.size(), 4);
for (DWORD i = 0; i < vec.size(); i++) {
size_t sz = vec.size();
DWORD id = TempArray(sz, 0);
for (size_t i = 0; i < sz; i++) {
arrays[id].val[i].set((long)vec[i]);
}
return id;
}
static fo::GameObject* _stdcall ListNext(sList* list) {
if (list->pos == list->len) return 0;
static fo::GameObject* ListNext(sList* list) {
if (!list || list->pos == list->len) return 0;
else return list->obj[list->pos++];
}
static void _stdcall ListEnd(sList* list) {
delete[] list->obj;
delete list;
static void ListEnd(DWORD id) {
for (std::vector<ListId>::const_iterator it = mList.cbegin(), it_end = mList.cend(); it != it_end; ++it) {
if (it->id == id) {
delete[] it->list->obj;
delete it->list;
mList.erase(it);
break;
}
}
}
void sf_list_begin(OpcodeContext& ctx) {
auto list = ListBegin(ctx.arg(0).asInt());
ctx.setReturn(
ScriptValue(DataType::INT, reinterpret_cast<DWORD>(list))
);
ctx.setReturn(ListBegin(ctx.arg(0).rawValue()), DataType::INT);
}
void sf_list_as_array(OpcodeContext& ctx) {
auto arrayId = ListAsArray(ctx.arg(0).asInt());
ctx.setReturn(
ScriptValue(DataType::INT, arrayId)
);
auto arrayId = ListAsArray(ctx.arg(0).rawValue());
ctx.setReturn(arrayId, DataType::INT);
}
void sf_list_next(OpcodeContext& ctx) {
// TODO: make it safer
auto list = reinterpret_cast<sList*>(ctx.arg(0).rawValue());
ctx.setReturn(
ListNext(list)
);
auto id = ctx.arg(0).rawValue();
sList* list = nullptr;
for (std::vector<ListId>::const_iterator it = mList.cbegin(), it_end = mList.cend(); it != it_end; ++it) {
if (it->id == id) {
list = it->list;
break;
}
}
ctx.setReturn(ListNext(list));
}
void sf_list_end(OpcodeContext& ctx) {
// TODO: make it safer
auto list = reinterpret_cast<sList*>(ctx.arg(0).rawValue());
ListEnd(list);
ListEnd(ctx.arg(0).rawValue());
}
}
@@ -352,7 +352,7 @@ void sf_set_iface_tag_text(OpcodeContext& ctx) {
}
void sf_inventory_redraw(OpcodeContext& ctx) {
int mode = -1;
int mode;
DWORD loopFlag = GetLoopFlags();
if (loopFlag & INVENTORY) {
mode = 0;
@@ -367,13 +367,11 @@ void sf_inventory_redraw(OpcodeContext& ctx) {
}
if (!ctx.arg(0).asBool()) {
int* stack_offset = (int*)FO_VAR_stack_offset;
stack_offset[fo::var::curr_stack * 4] = 0;
fo::var::stack_offset[fo::var::curr_stack] = 0;
fo::func::display_inventory(0, -1, mode);
} else if (mode >= 2) {
int* target_stack_offset = (int*)FO_VAR_target_stack_offset;
target_stack_offset[fo::var::target_curr_stack * 4] = 0;
fo::func::display_target_inventory(0, -1, (DWORD*)fo::var::target_pud, mode);
fo::var::target_stack_offset[fo::var::target_curr_stack] = 0;
fo::func::display_target_inventory(0, -1, fo::var::target_pud, mode);
fo::func::win_draw(fo::var::i_wid);
}
}
+1 -1
View File
@@ -478,7 +478,7 @@ void PathfinderFixInit() {
void StartingStatePatches() {
int date = GetConfigInt("Misc", "StartYear", -1);
if (date > 0) {
if (date >= 0) {
dlog("Applying starting year patch.", DL_INIT);
SafeWrite32(0x4A336C, date);
dlogr(" Done", DL_INIT);