mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Renamed elements in PerkInfo/TraitInfo structs
Implemented StatFormula struct from 4.x for Stats.cpp. Implemented DudeState struct from 4.x for PartyControl.cpp.
This commit is contained in:
+14
-2
@@ -175,7 +175,7 @@ char* ptr_pc_name = reinterpret_cast<char*>(_pc_name);
|
||||
DWORD* ptr_pc_proto = reinterpret_cast<DWORD*>(_pc_proto);
|
||||
BYTE* ptr_PeanutButter = reinterpret_cast<BYTE*>(_PeanutButter);
|
||||
DWORD* ptr_perk_data = reinterpret_cast<DWORD*>(_perk_data);
|
||||
int** ptr_perkLevelDataList = reinterpret_cast<int**>(_perkLevelDataList);
|
||||
long** ptr_perkLevelDataList = reinterpret_cast<long**>(_perkLevelDataList); // dynamic array, limited to PERK_Count
|
||||
const DWORD* ptr_pip_win = reinterpret_cast<DWORD*>(_pip_win);
|
||||
DWORD* ptr_pipboy_message_file = reinterpret_cast<DWORD*>(_pipboy_message_file);
|
||||
DWORD* ptr_pipmesg = reinterpret_cast<DWORD*>(_pipmesg);
|
||||
@@ -185,7 +185,7 @@ MSGList* ptr_proto_main_msg_file = reinterpret_cast<MSGList*>(_proto_main
|
||||
MSGList* ptr_proto_msg_files = reinterpret_cast<MSGList*>(_proto_msg_files); // array of 6 elements
|
||||
DWORD* ptr_ptable = reinterpret_cast<DWORD*>(_ptable);
|
||||
DWORD* ptr_pud = reinterpret_cast<DWORD*>(_pud);
|
||||
DWORD* ptr_queue = reinterpret_cast<DWORD*>(_queue);
|
||||
Queue** ptr_queue = reinterpret_cast<Queue**>(_queue);
|
||||
DWORD* ptr_quick_done = reinterpret_cast<DWORD*>(_quick_done);
|
||||
DWORD* ptr_read_callback = reinterpret_cast<DWORD*>(_read_callback);
|
||||
RectList** ptr_rectList = reinterpret_cast<RectList**>(_rectList);
|
||||
@@ -1299,6 +1299,18 @@ const char* MsgSearch(const MSGList* fileAddr, long messageId) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Queue* QueueFindUtil(TGameObj* object, long type) {
|
||||
if (*ptr_queue) {
|
||||
Queue* queue = *ptr_queue;
|
||||
while (queue->object != object && queue->type != type) {
|
||||
queue = queue->next;
|
||||
if (!queue) break;
|
||||
}
|
||||
return queue;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char* GetProtoPtr(long pid) {
|
||||
char* proto;
|
||||
long result;
|
||||
|
||||
@@ -478,7 +478,7 @@ extern char* ptr_pc_name;
|
||||
extern DWORD* ptr_pc_proto;
|
||||
extern BYTE* ptr_PeanutButter;
|
||||
extern DWORD* ptr_perk_data;
|
||||
extern int** ptr_perkLevelDataList; // limited to PERK_Count
|
||||
extern long** ptr_perkLevelDataList; // dynamic array, limited to PERK_Count
|
||||
extern const DWORD* ptr_pip_win;
|
||||
extern DWORD* ptr_pipboy_message_file;
|
||||
extern DWORD* ptr_pipmesg;
|
||||
@@ -488,7 +488,7 @@ extern MSGList* ptr_proto_main_msg_file;
|
||||
extern MSGList* ptr_proto_msg_files; // array of 6 elements
|
||||
extern DWORD* ptr_ptable;
|
||||
extern DWORD* ptr_pud;
|
||||
extern DWORD* ptr_queue;
|
||||
extern Queue** ptr_queue;
|
||||
extern DWORD* ptr_quick_done;
|
||||
extern DWORD* ptr_read_callback;
|
||||
extern RectList** ptr_rectList;
|
||||
@@ -1283,6 +1283,8 @@ const char* GetMessageStr(const MSGList* fileAddr, long messageId);
|
||||
// similar to GetMessageStr, but returns nullptr when no message is found
|
||||
const char* MsgSearch(const MSGList* fileAddr, long messageId);
|
||||
|
||||
Queue* QueueFindUtil(TGameObj* object, long type);
|
||||
|
||||
// returns pointer to prototype by PID, or nullptr on failure
|
||||
char* GetProtoPtr(long pid);
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ WRAP_WATCOM_FFUNC4(long, MouseClickIn, mouse_click_in_, long, x, long, y, long,
|
||||
WRAP_WATCOM_FFUNC4(long, MouseIn, mouse_in_, long, x, long, y, long, x_offs, long, y_offs)
|
||||
WRAP_WATCOM_FFUNC3(TGameObj*, ObjBlockingAt, obj_blocking_at_, TGameObj*, object, long, tile, long, elevation)
|
||||
WRAP_WATCOM_FFUNC3(long, ObjNewSidInst, obj_new_sid_inst_, TGameObj*, object, long, sType, long, scriptIndex)
|
||||
WRAP_WATCOM_FFUNC3(long, ObjectUnderMouse, object_under_mouse_, long, crSwitch, long, inclDude, long, elevation)
|
||||
WRAP_WATCOM_FFUNC3(TGameObj*, ObjectUnderMouse, object_under_mouse_, long, crSwitch, long, inclDude, long, elevation)
|
||||
WRAP_WATCOM_FFUNC4(long, QueueAdd, queue_add_, long, time, TGameObj*, object, void*, data, long, qType)
|
||||
WRAP_WATCOM_FFUNC4(void, RegisterObjectCall, register_object_call_, long*, target, long*, source, void*, func, long, delay)
|
||||
WRAP_WATCOM_FFUNC3(long, ScrGetLocalVar, scr_get_local_var_, long, sid, long, varId, long*, value)
|
||||
WRAP_WATCOM_FFUNC3(long, ScrSetLocalVar, scr_set_local_var_, long, sid, long, varId, long, value)
|
||||
@@ -96,6 +97,7 @@ WRAP_WATCOM_FUNC0(void, DisplayStats, display_stats_)
|
||||
WRAP_WATCOM_FUNC1(long, CritterIsDead, critter_is_dead_, TGameObj*, critter)
|
||||
// Execute script proc by internal proc number (from script's proc table, basically a sequential number of a procedure as defined in code, starting from 1)
|
||||
WRAP_WATCOM_FUNC2(void, ExecuteProcedure, executeProcedure_, TProgram*, sptr, long, procNum)
|
||||
WRAP_WATCOM_FUNC1(long, FolderPrintLine, folder_print_line_, const char*, text)
|
||||
WRAP_WATCOM_FUNC1(const char*, FindCurrentProc, findCurrentProc_, TProgram*, program) // Returns the name of current procedure by program pointer
|
||||
WRAP_WATCOM_FUNC1(long, FMtextWidth, FMtext_width_, const char*, text)
|
||||
WRAP_WATCOM_FUNC0(long, GetInputBtn, get_input_)
|
||||
@@ -124,8 +126,8 @@ WRAP_WATCOM_FUNC1(TGameObj*, InvenRightHand, inven_right_hand_, TGameObj*, critt
|
||||
WRAP_WATCOM_FUNC2(TGameObj*, InvenPidIsCarriedPtr, inven_pid_is_carried_ptr_, TGameObj*, invenObj, long, pid)
|
||||
WRAP_WATCOM_FUNC2(long, InvenUnwield, inven_unwield_, TGameObj*, critter, long, slot)
|
||||
WRAP_WATCOM_FUNC1(TGameObj*, InvenWorn, inven_worn_, TGameObj*, critter) // Critter worn item (armor)
|
||||
WRAP_WATCOM_FUNC1(long, IsPartyMember, isPartyMember_, TGameObj*, obj)
|
||||
WRAP_WATCOM_FUNC2(long, IsWithinPerception, is_within_perception_, TGameObj*, source, TGameObj*, target)
|
||||
WRAP_WATCOM_FUNC1(long, IsPartyMember, isPartyMember_, TGameObj*, obj)
|
||||
WRAP_WATCOM_FUNC1(long, ItemCCurrSize, item_c_curr_size_, TGameObj*, critter)
|
||||
WRAP_WATCOM_FUNC1(long, ItemCapsTotal, item_caps_total_, TGameObj*, object)
|
||||
WRAP_WATCOM_FUNC1(long, ItemGetType, item_get_type_, TGameObj*, item)
|
||||
@@ -174,8 +176,9 @@ WRAP_WATCOM_FUNC2(long, PerkLevel, perk_level_, TGameObj*, critter, long, perkId
|
||||
WRAP_WATCOM_FUNC6(long, PickDeath, pick_death_, TGameObj*, attacker, TGameObj*, target, TGameObj*, weapon, long, amount, long, anim, long, hitFromBack)
|
||||
WRAP_WATCOM_FUNC0(void, ProcessBk, process_bk_)
|
||||
WRAP_WATCOM_FUNC0(void, ProtoDudeUpdateGender, proto_dude_update_gender_)
|
||||
WRAP_WATCOM_FUNC2(long*, QueueFindFirst, queue_find_first_, TGameObj*, object, long, qType)
|
||||
WRAP_WATCOM_FUNC2(long*, QueueFindNext, queue_find_next_, TGameObj*, object, long, qType)
|
||||
WRAP_WATCOM_FUNC2(void*, QueueFindFirst, queue_find_first_, TGameObj*, object, long, qType)
|
||||
WRAP_WATCOM_FUNC2(void*, QueueFindNext, queue_find_next_, TGameObj*, object, long, qType)
|
||||
WRAP_WATCOM_FUNC2(void, QueueRemoveThis, queue_remove_this_, TGameObj*, object, long, qType)
|
||||
WRAP_WATCOM_FUNC3(long, RegisterObjectAnimateAndHide, register_object_animate_and_hide_, TGameObj*, object, long, anim, long, delay)
|
||||
WRAP_WATCOM_FUNC3(long, RegisterObjectChangeFid, register_object_change_fid_, TGameObj*, object, long, artFid, long, delay)
|
||||
WRAP_WATCOM_FUNC3(long, RegisterObjectLight, register_object_light_, TGameObj*, object, long, lightRadius, long, delay)
|
||||
|
||||
+24
-24
@@ -216,30 +216,30 @@ struct ItemButtonItem {
|
||||
long fid;
|
||||
};
|
||||
|
||||
// When gained, the perk increases Stat by StatMag, which may be negative. All other perk effects come from being
|
||||
// When gained, the perk increases Stat by StatMod, which may be negative. All other perk effects come from being
|
||||
// specifically checked for by scripts or the engine. If a primary stat requirement is negative, that stat must be
|
||||
// below the value specified (e.g., -7 indicates a stat must be less than 7). Type is only non-zero when there
|
||||
// below the value specified (e.g., -7 indicates a stat must be less than 7). Operator is only non-zero when there
|
||||
// are two skill requirements. If set to 1, only one of those requirements must be met; if set to 2, both must be met.
|
||||
struct PerkInfo {
|
||||
const char* Name;
|
||||
const char* Desc;
|
||||
long Image;
|
||||
long Ranks;
|
||||
long Level;
|
||||
long Stat;
|
||||
long StatMag;
|
||||
long Skill1;
|
||||
long Skill1Mag;
|
||||
long Type;
|
||||
long Skill2;
|
||||
long Skill2Mag;
|
||||
long Str;
|
||||
long Per;
|
||||
long End;
|
||||
long Chr;
|
||||
long Int;
|
||||
long Agl;
|
||||
long Lck;
|
||||
const char* name;
|
||||
const char* description;
|
||||
long image;
|
||||
long ranks;
|
||||
long levelMin;
|
||||
long stat;
|
||||
long statMod;
|
||||
long skill1;
|
||||
long skill1Min;
|
||||
long skillOperator;
|
||||
long skill2;
|
||||
long skill2Min;
|
||||
long strengthMin;
|
||||
long perceptionMin;
|
||||
long enduranceMin;
|
||||
long charismaMin;
|
||||
long intelligenceMin;
|
||||
long agilityMin;
|
||||
long luckMin;
|
||||
};
|
||||
|
||||
struct DbFile {
|
||||
@@ -443,9 +443,9 @@ struct SkillInfo {
|
||||
};
|
||||
|
||||
struct TraitInfo {
|
||||
const char* Name;
|
||||
const char* Desc;
|
||||
long Image;
|
||||
const char* name;
|
||||
const char* description;
|
||||
long image;
|
||||
};
|
||||
|
||||
//fallout2 path node structure
|
||||
|
||||
+87
-80
@@ -36,24 +36,28 @@ static bool skipCounterAnim = false;
|
||||
static std::vector<WORD> Chars;
|
||||
static int delayedExperience;
|
||||
|
||||
static TGameObj* real_dude = nullptr;
|
||||
static long real_traits[2];
|
||||
static char real_pc_name[32];
|
||||
static DWORD real_last_level;
|
||||
static DWORD real_Level;
|
||||
static DWORD real_Experience;
|
||||
static char real_free_perk;
|
||||
static DWORD real_unspent_skill_points;
|
||||
//static DWORD real_map_elevation;
|
||||
static DWORD real_sneak_working;
|
||||
//static DWORD real_sneak_queue_time;
|
||||
static DWORD real_hand;
|
||||
static ItemButtonItem real_itemButtonItems[2];
|
||||
static DWORD real_perkLevelDataList[PERK_count];
|
||||
//static DWORD real_drug_gvar[6];
|
||||
//static DWORD real_jet_gvar;
|
||||
static long real_tag_skill[4];
|
||||
//static DWORD real_bbox_sneak;
|
||||
static struct DudeState {
|
||||
TGameObj* obj_dude;
|
||||
DWORD art_vault_guy_num;
|
||||
long traits[2];
|
||||
char pc_name[32];
|
||||
DWORD last_level;
|
||||
DWORD Level;
|
||||
DWORD Experience;
|
||||
char free_perk;
|
||||
DWORD unspent_skill_points;
|
||||
//DWORD map_elevation;
|
||||
DWORD sneak_working;
|
||||
//DWORD sneak_queue_time;
|
||||
DWORD itemCurrentItem;
|
||||
ItemButtonItem itemButtonItems[2];
|
||||
long perkLevelDataList[PERK_count];
|
||||
//long addictGvar[8];
|
||||
long tag_skill[4];
|
||||
//DWORD bbox_sneak;
|
||||
|
||||
DudeState() : obj_dude(nullptr) {}
|
||||
} realDude;
|
||||
|
||||
static const DWORD* list_com = ptr_list_com;
|
||||
|
||||
@@ -69,10 +73,10 @@ static bool __stdcall IsInPidList(TGameObj* obj) {
|
||||
|
||||
static void __stdcall SetInventoryCheck(bool skip) {
|
||||
if (skip) {
|
||||
SafeWrite16(0x46E7CD, 0x9090); //Inventory check
|
||||
SafeWrite16(0x46E7CD, 0x9090); // Inventory check
|
||||
SafeWrite32(0x46E7CF, 0x90909090);
|
||||
} else {
|
||||
SafeWrite16(0x46E7CD, 0x850F); //Inventory check
|
||||
SafeWrite16(0x46E7CD, 0x850F); // Inventory check
|
||||
SafeWrite32(0x46E7CF, 0x4B1);
|
||||
}
|
||||
}
|
||||
@@ -86,19 +90,20 @@ static void __stdcall StatPcAddExperience(int amount) {
|
||||
|
||||
// saves the state of PC before moving control to NPC
|
||||
static void SaveRealDudeState() {
|
||||
real_dude = *ptr_obj_dude;
|
||||
real_hand = *ptr_itemCurrentItem;
|
||||
memcpy(real_itemButtonItems, ptr_itemButtonItems, sizeof(ItemButtonItem) * 2);
|
||||
memcpy(real_traits, ptr_pc_traits, sizeof(long) * 2);
|
||||
memcpy(real_perkLevelDataList, *ptr_perkLevelDataList, sizeof(DWORD) * PERK_count);
|
||||
strcpy_s(real_pc_name, 32, ptr_pc_name);
|
||||
real_Level = *ptr_Level_;
|
||||
real_last_level = *ptr_last_level;
|
||||
real_Experience = *ptr_Experience_;
|
||||
real_free_perk = *ptr_free_perk;
|
||||
real_unspent_skill_points = ptr_curr_pc_stat[0];
|
||||
real_sneak_working = *ptr_sneak_working;
|
||||
SkillGetTags(real_tag_skill, 4);
|
||||
realDude.obj_dude = *ptr_obj_dude;
|
||||
realDude.art_vault_guy_num = *ptr_art_vault_guy_num;
|
||||
realDude.itemCurrentItem = *ptr_itemCurrentItem;
|
||||
memcpy(realDude.itemButtonItems, ptr_itemButtonItems, sizeof(ItemButtonItem) * 2);
|
||||
memcpy(realDude.traits, ptr_pc_traits, sizeof(long) * 2);
|
||||
memcpy(realDude.perkLevelDataList, *ptr_perkLevelDataList, sizeof(DWORD) * PERK_count);
|
||||
strcpy_s(realDude.pc_name, 32, ptr_pc_name);
|
||||
realDude.Level = *ptr_Level_;
|
||||
realDude.last_level = *ptr_last_level;
|
||||
realDude.Experience = *ptr_Experience_;
|
||||
realDude.free_perk = *ptr_free_perk;
|
||||
realDude.unspent_skill_points = ptr_curr_pc_stat[0];
|
||||
realDude.sneak_working = *ptr_sneak_working;
|
||||
SkillGetTags(realDude.tag_skill, 4);
|
||||
|
||||
if (skipCounterAnim) {
|
||||
const DWORD counterAnimAddr[] = {0x422BDE, 0x4229EC};
|
||||
@@ -127,8 +132,8 @@ static void TakeControlOfNPC(TGameObj* npc) {
|
||||
|
||||
// change level
|
||||
int level = IsPartyMember(npc)
|
||||
? PartyMemberGetCurrentLevel(npc)
|
||||
: 0;
|
||||
? PartyMemberGetCurrentLevel(npc)
|
||||
: 0;
|
||||
|
||||
*ptr_Level_ = level;
|
||||
*ptr_last_level = level;
|
||||
@@ -144,17 +149,17 @@ static void TakeControlOfNPC(TGameObj* npc) {
|
||||
|
||||
// deduce active hand by weapon anim code
|
||||
char critterAnim = (npc->artFid & 0xF000) >> 12; // current weapon as seen in hands
|
||||
if (AnimCodeByWeapon(InvenLeftHand(npc)) == critterAnim) { // definitely left hand..
|
||||
if (AnimCodeByWeapon(InvenLeftHand(npc)) == critterAnim) { // definitely left hand
|
||||
*ptr_itemCurrentItem = 0;
|
||||
} else {
|
||||
*ptr_itemCurrentItem = 1;
|
||||
}
|
||||
|
||||
*ptr_inven_pid = npc->protoId;
|
||||
|
||||
// switch main dude_obj pointers - this should be done last!
|
||||
*ptr_obj_dude = npc;
|
||||
*ptr_inven_dude = npc;
|
||||
*ptr_inven_pid = npc->protoId;
|
||||
*ptr_art_vault_guy_num = npc->artFid & 0xFFF;
|
||||
|
||||
isControllingNPC = true;
|
||||
delayedExperience = 0;
|
||||
@@ -165,26 +170,27 @@ static void TakeControlOfNPC(TGameObj* npc) {
|
||||
|
||||
// restores the real dude state
|
||||
static void RestoreRealDudeState(bool redraw = true) {
|
||||
assert(real_dude != nullptr);
|
||||
assert(realDude.obj_dude != nullptr);
|
||||
|
||||
*ptr_map_elevation = real_dude->elevation;
|
||||
*ptr_map_elevation = realDude.obj_dude->elevation;
|
||||
|
||||
*ptr_obj_dude = real_dude;
|
||||
*ptr_inven_dude = real_dude;
|
||||
*ptr_inven_pid = real_dude->protoId;
|
||||
*ptr_obj_dude = realDude.obj_dude;
|
||||
*ptr_inven_dude = realDude.obj_dude;
|
||||
*ptr_inven_pid = realDude.obj_dude->protoId;
|
||||
*ptr_art_vault_guy_num = realDude.art_vault_guy_num;
|
||||
|
||||
*ptr_itemCurrentItem = real_hand;
|
||||
memcpy(ptr_itemButtonItems, real_itemButtonItems, sizeof(ItemButtonItem) * 2);
|
||||
memcpy(ptr_pc_traits, real_traits, sizeof(long) * 2);
|
||||
memcpy(*ptr_perkLevelDataList, real_perkLevelDataList, sizeof(DWORD) * PERK_count);
|
||||
strcpy_s(ptr_pc_name, 32, real_pc_name);
|
||||
*ptr_Level_ = real_Level;
|
||||
*ptr_last_level = real_last_level;
|
||||
*ptr_Experience_ = real_Experience;
|
||||
*ptr_free_perk = real_free_perk;
|
||||
ptr_curr_pc_stat[0] = real_unspent_skill_points;
|
||||
*ptr_sneak_working = real_sneak_working;
|
||||
SkillSetTags(real_tag_skill, 4);
|
||||
*ptr_itemCurrentItem = realDude.itemCurrentItem;
|
||||
memcpy(ptr_itemButtonItems, realDude.itemButtonItems, sizeof(ItemButtonItem) * 2);
|
||||
memcpy(ptr_pc_traits, realDude.traits, sizeof(long) * 2);
|
||||
memcpy(*ptr_perkLevelDataList, realDude.perkLevelDataList, sizeof(DWORD) * PERK_count);
|
||||
strcpy_s(ptr_pc_name, 32, realDude.pc_name);
|
||||
*ptr_Level_ = realDude.Level;
|
||||
*ptr_last_level = realDude.last_level;
|
||||
*ptr_Experience_ = realDude.Experience;
|
||||
*ptr_free_perk = realDude.free_perk;
|
||||
ptr_curr_pc_stat[0] = realDude.unspent_skill_points;
|
||||
*ptr_sneak_working = realDude.sneak_working;
|
||||
SkillSetTags(realDude.tag_skill, 4);
|
||||
|
||||
if (delayedExperience > 0) {
|
||||
StatPcAddExperience(delayedExperience);
|
||||
@@ -199,7 +205,6 @@ static void RestoreRealDudeState(bool redraw = true) {
|
||||
|
||||
SetInventoryCheck(false);
|
||||
isControllingNPC = false;
|
||||
real_dude = nullptr;
|
||||
|
||||
if (isDebug) DebugPrintf("\n[SFALL] Restore control to dude.\n");
|
||||
}
|
||||
@@ -269,39 +274,39 @@ int __fastcall PartyControl_SwitchHandHook(TGameObj* item) {
|
||||
}
|
||||
|
||||
static long __fastcall GetRealDudePerk(TGameObj* source, long perk) {
|
||||
if (isControllingNPC && source == real_dude) {
|
||||
return real_perkLevelDataList[perk];
|
||||
if (isControllingNPC && source == realDude.obj_dude) {
|
||||
return realDude.perkLevelDataList[perk];
|
||||
}
|
||||
return PerkLevel(source, perk);
|
||||
}
|
||||
|
||||
static long __fastcall GetRealDudeTrait(TGameObj* source, long trait) {
|
||||
if (isControllingNPC && source == real_dude) {
|
||||
return (trait == real_traits[0] || trait == real_traits[1]) ? 1 : 0;
|
||||
if (isControllingNPC && source == realDude.obj_dude) {
|
||||
return (trait == realDude.traits[0] || trait == realDude.traits[1]) ? 1 : 0;
|
||||
}
|
||||
return TraitLevel(trait);
|
||||
}
|
||||
|
||||
static void __declspec(naked) CombatWrapper_v2() {
|
||||
__asm {
|
||||
sub esp, 4;
|
||||
sub esp, 4;
|
||||
pushad;
|
||||
push eax;
|
||||
call CombatWrapperInner;
|
||||
mov [esp+32], eax;
|
||||
mov [esp + 32], eax;
|
||||
popad;
|
||||
add esp, 4;
|
||||
cmp [esp-4], 0;
|
||||
je gonormal;
|
||||
cmp [esp-4], -1;
|
||||
je combatend;
|
||||
xor eax, eax;
|
||||
add esp, 4;
|
||||
cmp [esp - 4], 0;
|
||||
je gonormal;
|
||||
cmp [esp - 4], -1;
|
||||
je combatend;
|
||||
xor eax, eax;
|
||||
retn;
|
||||
combatend:
|
||||
mov eax, -1; // don't continue combat, as the game was loaded
|
||||
mov eax, -1; // don't continue combat, as the game was loaded
|
||||
retn;
|
||||
gonormal:
|
||||
jmp combat_turn_;
|
||||
jmp combat_turn_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,13 +315,13 @@ static void __declspec(naked) CombatHack_add_noncoms_() {
|
||||
static const DWORD CombatHack_add_noncoms_back = 0x422359;
|
||||
__asm {
|
||||
call CombatWrapper_v2;
|
||||
cmp eax, -1;
|
||||
jne gonormal;
|
||||
mov eax, list_com;
|
||||
mov [eax], 0;
|
||||
mov ecx, [esp];
|
||||
cmp eax, -1;
|
||||
jne gonormal;
|
||||
mov eax, list_com;
|
||||
mov [eax], 0;
|
||||
mov ecx, [esp];
|
||||
gonormal:
|
||||
jmp CombatHack_add_noncoms_back;
|
||||
jmp CombatHack_add_noncoms_back;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,15 +384,16 @@ static void __declspec(naked) proto_name_hook() {
|
||||
jne pcName;
|
||||
jmp critter_name_;
|
||||
pcName:
|
||||
lea eax, real_pc_name;
|
||||
lea eax, realDude.pc_name;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void PartyControlReset() {
|
||||
if (real_dude != nullptr && isControllingNPC) {
|
||||
if (realDude.obj_dude != nullptr && isControllingNPC) {
|
||||
RestoreRealDudeState(false);
|
||||
}
|
||||
realDude.obj_dude = nullptr;
|
||||
}
|
||||
|
||||
bool IsNpcControlled() {
|
||||
@@ -395,12 +401,13 @@ bool IsNpcControlled() {
|
||||
}
|
||||
|
||||
TGameObj* RealDudeObject() {
|
||||
return real_dude != nullptr
|
||||
? real_dude
|
||||
return realDude.obj_dude != nullptr
|
||||
? realDude.obj_dude
|
||||
: *ptr_obj_dude;
|
||||
}
|
||||
|
||||
static char levelMsg[12], armorClassMsg[12], addictMsg[16];
|
||||
|
||||
static void __fastcall PartyMemberPrintStat(BYTE* surface, DWORD toWidth) {
|
||||
const char* fmt = "%s %d";
|
||||
char lvlMsg[16], acMsg[16];
|
||||
|
||||
+38
-45
@@ -44,9 +44,8 @@ static DWORD addPerkMode = 2;
|
||||
static bool perksReInit = false;
|
||||
static int perksEnable = 0;
|
||||
|
||||
//static const PerkInfo BlankPerk={ &Name[PERK_count*64], &Desc[PERK_count*1024], 0x48, 1, 1, -1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
static PerkInfo Perks[PERK_count];
|
||||
static TraitInfo Traits[TRAIT_count];
|
||||
static PerkInfo perks[PERK_count];
|
||||
static TraitInfo traits[TRAIT_count];
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct FakePerk {
|
||||
@@ -330,13 +329,7 @@ static void __declspec(naked) GetFakeSPerkLevel() {
|
||||
|
||||
static DWORD __stdcall HandleFakeTraits(int isSelect) {
|
||||
for (DWORD i = 0; i < fakeTraits.size(); i++) {
|
||||
DWORD a = (DWORD)fakeTraits[i].Name;
|
||||
__asm {
|
||||
mov eax, a;
|
||||
call folder_print_line_;
|
||||
mov a, eax;
|
||||
}
|
||||
if (a && !isSelect) {
|
||||
if (FolderPrintLine(fakeTraits[i].Name) && !isSelect) {
|
||||
isSelect = 1;
|
||||
*ptr_folder_card_fid = fakeTraits[i].Image;
|
||||
*ptr_folder_card_title = (DWORD)fakeTraits[i].Name;
|
||||
@@ -626,7 +619,7 @@ lower:
|
||||
static bool perkHeaveHoModFix = false;
|
||||
void __stdcall ApplyHeaveHoFix() { // not really a fix
|
||||
MakeJump(0x478AC4, HeaveHoHook);
|
||||
Perks[PERK_heave_ho].Str = 0;
|
||||
perks[PERK_heave_ho].strengthMin = 0;
|
||||
perkHeaveHoModFix = true;
|
||||
}
|
||||
|
||||
@@ -682,59 +675,59 @@ static void PerkSetup() {
|
||||
if (!perksReInit) {
|
||||
// _perk_data
|
||||
const DWORD perkDataAddr[] = {0x496669, 0x496837, 0x496BAD, 0x496C41, 0x496D25};
|
||||
SafeWriteBatch<DWORD>((DWORD)Perks, perkDataAddr);
|
||||
SafeWriteBatch<DWORD>((DWORD)perks, perkDataAddr);
|
||||
const DWORD perkDataDescAddr[] = {0x496696, 0x496BD1};
|
||||
SafeWriteBatch<DWORD>((DWORD)&Perks[0].Desc, perkDataDescAddr);
|
||||
SafeWrite32(0x496BF5, (DWORD)&Perks[0].Image);
|
||||
SafeWrite32(0x496AD4, (DWORD)&Perks[0].Ranks);
|
||||
SafeWriteBatch<DWORD>((DWORD)&perks[0].description, perkDataDescAddr);
|
||||
SafeWrite32(0x496BF5, (DWORD)&perks[0].image);
|
||||
SafeWrite32(0x496AD4, (DWORD)&perks[0].ranks);
|
||||
}
|
||||
memcpy(Perks, (void*)_perk_data, sizeof(PerkInfo) * PERK_count); // copy vanilla data
|
||||
memcpy(perks, (void*)_perk_data, sizeof(PerkInfo) * PERK_count); // copy vanilla data
|
||||
|
||||
if (perksEnable) {
|
||||
char num[4];
|
||||
for (int i = 0; i < PERK_count; i++) {
|
||||
_itoa(i, num, 10);
|
||||
if (iniGetString(num, "Name", "", &Name[i * maxNameLen], maxNameLen - 1, perksFile)) {
|
||||
Perks[i].Name = &Name[i * maxNameLen];
|
||||
perks[i].name = &Name[i * maxNameLen];
|
||||
}
|
||||
if (iniGetString(num, "Desc", "", &Desc[i * descLen], descLen - 1, perksFile)) {
|
||||
Perks[i].Desc = &Desc[i * descLen];
|
||||
perks[i].description = &Desc[i * descLen];
|
||||
}
|
||||
int value;
|
||||
value = iniGetInt(num, "Image", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Image = value;
|
||||
if (value != -99999) perks[i].image = value;
|
||||
value = iniGetInt(num, "Ranks", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Ranks = value;
|
||||
if (value != -99999) perks[i].ranks = value;
|
||||
value = iniGetInt(num, "Level", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Level = value;
|
||||
if (value != -99999) perks[i].levelMin = value;
|
||||
value = iniGetInt(num, "Stat", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Stat = value;
|
||||
if (value != -99999) perks[i].stat = value;
|
||||
value = iniGetInt(num, "StatMag", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].StatMag = value;
|
||||
if (value != -99999) perks[i].statMod = value;
|
||||
value = iniGetInt(num, "Skill1", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Skill1 = value;
|
||||
if (value != -99999) perks[i].skill1 = value;
|
||||
value = iniGetInt(num, "Skill1Mag", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Skill1Mag = value;
|
||||
if (value != -99999) perks[i].skill1Min = value;
|
||||
value = iniGetInt(num, "Type", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Type = value;
|
||||
if (value != -99999) perks[i].skillOperator = value;
|
||||
value = iniGetInt(num, "Skill2", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Skill2 = value;
|
||||
if (value != -99999) perks[i].skill2 = value;
|
||||
value = iniGetInt(num, "Skill2Mag", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Skill2Mag = value;
|
||||
if (value != -99999) perks[i].skill2Min = value;
|
||||
value = iniGetInt(num, "STR", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Str = value;
|
||||
if (value != -99999) perks[i].strengthMin = value;
|
||||
value = iniGetInt(num, "PER", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Per = value;
|
||||
if (value != -99999) perks[i].perceptionMin = value;
|
||||
value = iniGetInt(num, "END", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].End = value;
|
||||
if (value != -99999) perks[i].enduranceMin = value;
|
||||
value = iniGetInt(num, "CHR", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Chr = value;
|
||||
if (value != -99999) perks[i].charismaMin = value;
|
||||
value = iniGetInt(num, "INT", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Int = value;
|
||||
if (value != -99999) perks[i].intelligenceMin = value;
|
||||
value = iniGetInt(num, "AGL", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Agl = value;
|
||||
if (value != -99999) perks[i].agilityMin = value;
|
||||
value = iniGetInt(num, "LCK", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Lck = value;
|
||||
if (value != -99999) perks[i].luckMin = value;
|
||||
}
|
||||
}
|
||||
perksReInit = false;
|
||||
@@ -883,28 +876,28 @@ static void TraitSetup() {
|
||||
MakeJump(0x4B3C7C, TraitAdjustStatHack); // trait_adjust_stat_
|
||||
MakeJump(0x4B40FC, TraitAdjustSkillHack); // trait_adjust_skill_
|
||||
|
||||
memcpy(Traits, (void*)_trait_data, sizeof(TraitInfo) * TRAIT_count);
|
||||
memcpy(traits, (void*)_trait_data, sizeof(TraitInfo) * TRAIT_count);
|
||||
|
||||
// _trait_data
|
||||
const DWORD traitDataAddr[] = {0x4B3A81, 0x4B3B80};
|
||||
SafeWriteBatch<DWORD>((DWORD)Traits, traitDataAddr);
|
||||
SafeWriteBatch<DWORD>((DWORD)traits, traitDataAddr);
|
||||
const DWORD traitDataDescAddr[] = {0x4B3AAE, 0x4B3BA0};
|
||||
SafeWriteBatch<DWORD>((DWORD)&Traits[0].Desc, traitDataDescAddr);
|
||||
SafeWrite32(0x4B3BC0, (DWORD)&Traits[0].Image);
|
||||
SafeWriteBatch<DWORD>((DWORD)&traits[0].description, traitDataDescAddr);
|
||||
SafeWrite32(0x4B3BC0, (DWORD)&traits[0].image);
|
||||
|
||||
char buf[512], num[5] = {'t'};
|
||||
char* num2 = &num[1];
|
||||
for (int i = 0; i < TRAIT_count; i++) {
|
||||
_itoa_s(i, num2, 4, 10);
|
||||
if (iniGetString(num, "Name", "", &tName[i * maxNameLen], maxNameLen - 1, perksFile)) {
|
||||
Traits[i].Name = &tName[i * maxNameLen];
|
||||
traits[i].name = &tName[i * maxNameLen];
|
||||
}
|
||||
if (iniGetString(num, "Desc", "", &tDesc[i * descLen], descLen - 1, perksFile)) {
|
||||
Traits[i].Desc = &tDesc[i * descLen];
|
||||
traits[i].description = &tDesc[i * descLen];
|
||||
}
|
||||
int value;
|
||||
value = iniGetInt(num, "Image", -99999, perksFile);
|
||||
if (value != -99999) Traits[i].Image = value;
|
||||
if (value != -99999) traits[i].image = value;
|
||||
|
||||
if (iniGetString(num, "StatMod", "", buf, 512, perksFile) > 0) {
|
||||
char *stat, *mod;
|
||||
@@ -1068,21 +1061,21 @@ static void FastShotTraitFix() {
|
||||
|
||||
void __fastcall SetPerkValue(int id, int param, int value) {
|
||||
if (id < 0 || id >= PERK_count) return;
|
||||
*(DWORD*)((DWORD)(&Perks[id]) + param) = value;
|
||||
*(DWORD*)((DWORD)(&perks[id]) + param) = value;
|
||||
perksReInit = true;
|
||||
}
|
||||
|
||||
void __stdcall SetPerkName(int id, const char* value) {
|
||||
if (id < 0 || id >= PERK_count) return;
|
||||
strncpy_s(&Name[id * maxNameLen], maxNameLen, value, _TRUNCATE);
|
||||
Perks[id].Name = &Name[maxNameLen * id];
|
||||
perks[id].name = &Name[maxNameLen * id];
|
||||
perksReInit = true;
|
||||
}
|
||||
|
||||
void __stdcall SetPerkDesc(int id, const char* value) {
|
||||
if (id < 0 || id >= PERK_count) return;
|
||||
strncpy_s(&Desc[id * descLen], descLen, value, _TRUNCATE);
|
||||
Perks[id].Desc = &Desc[descLen * id];
|
||||
perks[id].description = &Desc[descLen * id];
|
||||
perksReInit = true;
|
||||
}
|
||||
|
||||
|
||||
+54
-50
@@ -32,10 +32,10 @@ void __fastcall sf_critter_adjust_poison(TGameObj* critter, long amount) {
|
||||
if (critter->critter.poison < 0) critter->critter.poison = 0; // level can't be negative
|
||||
}
|
||||
|
||||
static DWORD StatMaximumsPC[STAT_max_stat];
|
||||
static DWORD StatMinimumsPC[STAT_max_stat];
|
||||
static DWORD StatMaximumsNPC[STAT_max_stat];
|
||||
static DWORD StatMinimumsNPC[STAT_max_stat];
|
||||
static DWORD statMaximumsPC[STAT_max_stat];
|
||||
static DWORD statMinimumsPC[STAT_max_stat];
|
||||
static DWORD statMaximumsNPC[STAT_max_stat];
|
||||
static DWORD statMinimumsNPC[STAT_max_stat];
|
||||
|
||||
static DWORD xpTable[99];
|
||||
|
||||
@@ -43,9 +43,12 @@ float ExperienceMod = 1.0f; // set_xp_mod func
|
||||
DWORD StandardApAcBonus = 4;
|
||||
DWORD ExtraApAcBonus = 4;
|
||||
|
||||
static int StatFormulas[33 * 2] = {0};
|
||||
static int StatShifts[33 * 7] = {0};
|
||||
static double StatMulti[33 * 7] = {0};
|
||||
static struct StatFormula {
|
||||
long base;
|
||||
long min;
|
||||
long shift[STAT_lu + 1];
|
||||
double multi[STAT_lu + 1];
|
||||
} statFormulas[STAT_max_derived + 1] = {0};
|
||||
|
||||
static TGameObj* cCritter;
|
||||
|
||||
@@ -62,14 +65,14 @@ static void __declspec(naked) stat_level_hack() {
|
||||
static int __fastcall check_stat_level(int value, DWORD stat) {
|
||||
int valLimit;
|
||||
if (cCritter == *ptr_obj_dude) {
|
||||
valLimit = StatMinimumsPC[stat];
|
||||
valLimit = statMinimumsPC[stat];
|
||||
if (value < valLimit) return valLimit;
|
||||
valLimit = StatMaximumsPC[stat];
|
||||
valLimit = statMaximumsPC[stat];
|
||||
if (value > valLimit) return valLimit;
|
||||
} else {
|
||||
valLimit = StatMinimumsNPC[stat];
|
||||
valLimit = statMinimumsNPC[stat];
|
||||
if (value < valLimit) return valLimit;
|
||||
valLimit = StatMaximumsNPC[stat];
|
||||
valLimit = statMaximumsNPC[stat];
|
||||
if (value > valLimit) return valLimit;
|
||||
}
|
||||
return value;
|
||||
@@ -90,15 +93,15 @@ static void __declspec(naked) stat_set_base_hack_check() {
|
||||
__asm {
|
||||
cmp esi, dword ptr ds:[_obj_dude];
|
||||
jz pc;
|
||||
cmp ebx, StatMinimumsNPC[eax];
|
||||
cmp ebx, statMinimumsNPC[eax];
|
||||
jl failMin;
|
||||
cmp ebx, StatMaximumsNPC[eax];
|
||||
cmp ebx, statMaximumsNPC[eax];
|
||||
jg failMax;
|
||||
jmp StatSetBaseHack_Ret;
|
||||
pc:
|
||||
cmp ebx, StatMinimumsPC[eax];
|
||||
cmp ebx, statMinimumsPC[eax];
|
||||
jl failMin;
|
||||
cmp ebx, StatMaximumsPC[eax];
|
||||
cmp ebx, statMaximumsPC[eax];
|
||||
jg failMax;
|
||||
jmp StatSetBaseHack_Ret;
|
||||
failMin:
|
||||
@@ -157,7 +160,7 @@ static void __declspec(naked) __stdcall ProtoPtr(DWORD pid, int** proto) {
|
||||
|
||||
static void __stdcall StatRecalcDerived(TGameObj* critter) {
|
||||
int baseStats[7];
|
||||
for (int i = STAT_st; i <= STAT_lu; i++) baseStats[i] = StatLevel(critter, i);
|
||||
for (int stat = STAT_st; stat <= STAT_lu; stat++) baseStats[stat] = StatLevel(critter, stat);
|
||||
|
||||
int* proto;
|
||||
ProtoPtr(critter->protoId, &proto);
|
||||
@@ -166,11 +169,12 @@ static void __stdcall StatRecalcDerived(TGameObj* critter) {
|
||||
if (i >= STAT_dmg_thresh && i <= STAT_dmg_resist_explosion) continue;
|
||||
|
||||
double sum = 0;
|
||||
for (int j = STAT_st; j <= STAT_lu; j++) {
|
||||
sum += (baseStats[j] + StatShifts[i * 7 + j]) * StatMulti[i * 7 + j];
|
||||
for (int stat = STAT_st; stat <= STAT_lu; stat++) {
|
||||
sum += (baseStats[stat] + statFormulas[i].shift[stat]) * statFormulas[i].multi[stat];
|
||||
}
|
||||
proto[i + 9] = StatFormulas[i * 2] + (int)floor(sum);
|
||||
if (proto[i + 9] < StatFormulas[i * 2 + 1]) proto[i + 9] = StatFormulas[i * 2 + 1];
|
||||
long calcStat = statFormulas[i].base + (int)floor(sum);
|
||||
if (calcStat < statFormulas[i].min) calcStat = statFormulas[i].min;
|
||||
proto[9 + i] = calcStat; // offset from base_stat_srength
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,8 +231,8 @@ static void __declspec(naked) critter_adjust_poison_hack() {
|
||||
|
||||
static void StatsReset() {
|
||||
for (size_t i = 0; i < STAT_max_stat; i++) {
|
||||
StatMaximumsPC[i] = StatMaximumsNPC[i] = *(DWORD*)(_stat_data + 16 + i * 24);
|
||||
StatMinimumsPC[i] = StatMinimumsNPC[i] = *(DWORD*)(_stat_data + 12 + i * 24);
|
||||
statMaximumsPC[i] = statMaximumsNPC[i] = *(DWORD*)(_stat_data + 16 + i * 24);
|
||||
statMinimumsPC[i] = statMinimumsNPC[i] = *(DWORD*)(_stat_data + 12 + i * 24);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,32 +287,32 @@ void StatsInit() {
|
||||
MakeJump(0x4AF6FC, stat_recalc_derived_hack); // overrides function
|
||||
|
||||
// STAT_st + STAT_en * 2 + 15
|
||||
StatFormulas[7 * 2] = 15; // max hp
|
||||
StatMulti[7 * 7 + STAT_st] = 1;
|
||||
StatMulti[7 * 7 + STAT_en] = 2;
|
||||
statFormulas[STAT_max_hit_points].base = 15; // max hp
|
||||
statFormulas[STAT_max_hit_points].multi[STAT_st] = 1;
|
||||
statFormulas[STAT_max_hit_points].multi[STAT_en] = 2;
|
||||
// STAT_ag / 2 + 5
|
||||
StatFormulas[8 * 2] = 5; // max ap
|
||||
StatMulti[8 * 7 + STAT_ag] = 0.5;
|
||||
statFormulas[STAT_max_move_points].base = 5; // max ap
|
||||
statFormulas[STAT_max_move_points].multi[STAT_ag] = 0.5;
|
||||
|
||||
StatMulti[9 * 7 + STAT_ag] = 1; // ac
|
||||
statFormulas[STAT_ac].multi[STAT_ag] = 1; // ac
|
||||
// STAT_st - 5
|
||||
StatFormulas[11 * 2 + 1] = 1; // melee damage
|
||||
StatShifts[11 * 7 + STAT_st] = -5;
|
||||
StatMulti[11 * 7 + STAT_st] = 1;
|
||||
statFormulas[STAT_melee_dmg].min = 1; // melee damage
|
||||
statFormulas[STAT_melee_dmg].shift[STAT_st] = -5;
|
||||
statFormulas[STAT_melee_dmg].multi[STAT_st] = 1;
|
||||
// STAT_st * 25 + 25
|
||||
StatFormulas[12 * 2] = 25; // carry weight
|
||||
StatMulti[12 * 7 + STAT_st] = 25;
|
||||
statFormulas[STAT_carry_amt].base = 25; // carry weight
|
||||
statFormulas[STAT_carry_amt].multi[STAT_st] = 25;
|
||||
// STAT_pe * 2
|
||||
StatMulti[13 * 7 + STAT_pe] = 2; // sequence
|
||||
statFormulas[STAT_sequence].multi[STAT_pe] = 2; // sequence
|
||||
// STAT_en / 3
|
||||
StatFormulas[14 * 2 + 1] = 1; // heal rate
|
||||
StatMulti[14 * 7 + STAT_en] = 1.0 / 3.0;
|
||||
statFormulas[STAT_heal_rate].min = 1; // heal rate
|
||||
statFormulas[STAT_heal_rate].multi[STAT_en] = 1.0 / 3.0;
|
||||
|
||||
StatMulti[15 * 7 + STAT_lu] = 1; // critical chance
|
||||
statFormulas[STAT_crit_chance].multi[STAT_lu] = 1; // critical chance
|
||||
// STAT_en * 2
|
||||
StatMulti[31 * 7 + STAT_en] = 2; // rad resist
|
||||
statFormulas[STAT_rad_resist].multi[STAT_en] = 2; // rad resist
|
||||
// STAT_en * 5
|
||||
StatMulti[32 * 7 + STAT_en] = 5; // poison resist
|
||||
statFormulas[STAT_poison_resist].multi[STAT_en] = 5; // poison resist
|
||||
|
||||
char key[6], buf2[256], buf3[256];
|
||||
const char* statFile = statsFile.insert(0, ".\\").c_str();
|
||||
@@ -318,15 +322,15 @@ void StatsInit() {
|
||||
if (i >= STAT_dmg_thresh && i <= STAT_dmg_resist_explosion) continue;
|
||||
|
||||
_itoa(i, key, 10);
|
||||
StatFormulas[i * 2] = iniGetInt(key, "base", StatFormulas[i * 2], statFile);
|
||||
StatFormulas[i * 2 + 1] = iniGetInt(key, "min", StatFormulas[i * 2 + 1], statFile);
|
||||
statFormulas[i].base = iniGetInt(key, "base", statFormulas[i].base, statFile);
|
||||
statFormulas[i].min = iniGetInt(key, "min", statFormulas[i].min, statFile);
|
||||
for (int j = 0; j < STAT_max_hit_points; j++) {
|
||||
sprintf(buf2, "shift%d", j);
|
||||
StatShifts[i * 7 + j] = iniGetInt(key, buf2, StatShifts[i * 7 + j], statFile);
|
||||
statFormulas[i].shift[j] = iniGetInt(key, buf2, statFormulas[i].shift[j], statFile);
|
||||
sprintf(buf2, "multi%d", j);
|
||||
_gcvt(StatMulti[i * 7 + j], 16, buf3);
|
||||
_gcvt(statFormulas[i].multi[j], 16, buf3);
|
||||
iniGetString(key, buf2, buf3, buf2, 256, statFile);
|
||||
StatMulti[i * 7 + j] = atof(buf2);
|
||||
statFormulas[i].multi[j] = atof(buf2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,38 +338,38 @@ void StatsInit() {
|
||||
|
||||
long __stdcall GetStatMax(int stat, int isNPC) {
|
||||
if (stat >= 0 && stat < STAT_max_stat) {
|
||||
return (isNPC) ? StatMaximumsNPC[stat] : StatMaximumsPC[stat];
|
||||
return (isNPC) ? statMaximumsNPC[stat] : statMaximumsPC[stat];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long __stdcall GetStatMin(int stat, int isNPC) {
|
||||
if (stat >= 0 && stat < STAT_max_stat) {
|
||||
return (isNPC) ? StatMinimumsNPC[stat] : StatMinimumsPC[stat];
|
||||
return (isNPC) ? statMinimumsNPC[stat] : statMinimumsPC[stat];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __stdcall SetPCStatMax(int stat, int value) {
|
||||
if (stat >= 0 && stat < STAT_max_stat) {
|
||||
StatMaximumsPC[stat] = value;
|
||||
statMaximumsPC[stat] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void __stdcall SetPCStatMin(int stat, int value) {
|
||||
if (stat >= 0 && stat < STAT_max_stat) {
|
||||
StatMinimumsPC[stat] = value;
|
||||
statMinimumsPC[stat] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void __stdcall SetNPCStatMax(int stat, int value) {
|
||||
if (stat >= 0 && stat < STAT_max_stat) {
|
||||
StatMaximumsNPC[stat] = value;
|
||||
statMaximumsNPC[stat] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void __stdcall SetNPCStatMin(int stat, int value) {
|
||||
if (stat >= 0 && stat < STAT_max_stat) {
|
||||
StatMinimumsNPC[stat] = value;
|
||||
statMinimumsNPC[stat] = value;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ static void TimerReset() {
|
||||
addedYears += 13;
|
||||
|
||||
// fix queue time
|
||||
Queue* queue = (Queue*)(*ptr_queue);
|
||||
Queue* queue = *ptr_queue;
|
||||
while (queue) {
|
||||
if (queue->time > time) {
|
||||
queue->time -= time;
|
||||
|
||||
Reference in New Issue
Block a user