mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added the display of actual damage for unarmed attacks in inven
This commit is contained in:
+40
-24
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "FalloutEngine.h"
|
#include "FalloutEngine.h"
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
|
#include "Unarmed.h"
|
||||||
|
|
||||||
#include "ReplacementFuncs.h"
|
#include "ReplacementFuncs.h"
|
||||||
|
|
||||||
@@ -422,24 +423,37 @@ static void __declspec(naked) DisplayBonusHtHDmg1_hook() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool bonusHtHDamageFix = false;
|
||||||
|
static bool displayBonusDamage = false;
|
||||||
|
|
||||||
|
static long __fastcall GetHtHDamage(TGameObj* source, long &meleeDmg, long handOffset) {
|
||||||
|
long min, max;
|
||||||
|
|
||||||
|
AttackType hit = Unarmed_GetStoredHitMode((handOffset == 0) ? HANDSLOT_Left : HANDSLOT_Right);
|
||||||
|
long bonus = Unarmed_GetDamage(hit, min, max);
|
||||||
|
meleeDmg += max + bonus;
|
||||||
|
|
||||||
|
long perkBonus = sfgame_perk_level(source, PERK_bonus_hth_damage) << 1;
|
||||||
|
if (!displayBonusDamage) meleeDmg -= perkBonus;
|
||||||
|
if (bonusHtHDamageFix && displayBonusDamage) min += perkBonus;
|
||||||
|
|
||||||
|
return min + bonus;
|
||||||
|
}
|
||||||
|
|
||||||
static void __declspec(naked) DisplayBonusHtHDmg2_hack() {
|
static void __declspec(naked) DisplayBonusHtHDmg2_hack() {
|
||||||
static const DWORD DisplayBonusHtHDmg2Exit = 0x47254E;
|
static const DWORD DisplayBonusHtHDmg2Exit = 0x47254F;
|
||||||
__asm {
|
__asm {
|
||||||
mov ecx, eax;
|
mov ecx, eax;
|
||||||
call stat_level_;
|
call stat_level_; // get STAT_melee_dmg
|
||||||
add eax, 2;
|
push eax; // max dmg (meleeDmg)
|
||||||
push eax; // max dmg
|
mov edx, esp; // meleeDmg ref
|
||||||
mov edx, PERK_bonus_hth_damage;
|
push edi; // handOffset
|
||||||
mov eax, ecx;
|
call GetHtHDamage;
|
||||||
call perk_level_;
|
push eax; // min dmg
|
||||||
shl eax, 1; // Multiply by 2
|
|
||||||
inc eax; // min dmg (1 + bonus)
|
|
||||||
jmp DisplayBonusHtHDmg2Exit;
|
jmp DisplayBonusHtHDmg2Exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool bonusHtHDamageFix = false;
|
|
||||||
|
|
||||||
long DamageMod_GetHtHMinDamageBonus(TGameObj* source) {
|
long DamageMod_GetHtHMinDamageBonus(TGameObj* source) {
|
||||||
return (bonusHtHDamageFix)
|
return (bonusHtHDamageFix)
|
||||||
? sfgame_perk_level(source, PERK_bonus_hth_damage) << 1 // Rank_of_Bonus_HtH_Damage_perk *= 2
|
? sfgame_perk_level(source, PERK_bonus_hth_damage) << 1 // Rank_of_Bonus_HtH_Damage_perk *= 2
|
||||||
@@ -459,13 +473,13 @@ void DamageMod_Init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int BonusHtHDmgFix = GetConfigInt("Misc", "BonusHtHDamageFix", 1);
|
bonusHtHDamageFix = GetConfigInt("Misc", "BonusHtHDamageFix", 1) != 0;
|
||||||
int DisplayBonusDmg = GetConfigInt("Misc", "DisplayBonusDamage", 0);
|
displayBonusDamage = GetConfigInt("Misc", "DisplayBonusDamage", 0) != 0;
|
||||||
|
|
||||||
if (BonusHtHDmgFix) {
|
if (bonusHtHDamageFix) {
|
||||||
bonusHtHDamageFix = true;
|
|
||||||
dlog("Applying Bonus HtH Damage Perk fix.", DL_INIT);
|
dlog("Applying Bonus HtH Damage Perk fix.", DL_INIT);
|
||||||
if (DisplayBonusDmg == 0) { // Subtract damage from perk bonus (vanilla displaying)
|
// Subtract damage from perk bonus (vanilla displaying)
|
||||||
|
if (!displayBonusDamage) {
|
||||||
const DWORD meleeDmgDispPrtAddr[] = {
|
const DWORD meleeDmgDispPrtAddr[] = {
|
||||||
0x435C0C, // DisplayFix (ListDrvdStats_)
|
0x435C0C, // DisplayFix (ListDrvdStats_)
|
||||||
0x439921 // PrintFix (Save_as_ASCII_)
|
0x439921 // PrintFix (Save_as_ASCII_)
|
||||||
@@ -482,17 +496,19 @@ void DamageMod_Init() {
|
|||||||
dlogr(" Done", DL_INIT);
|
dlogr(" Done", DL_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DisplayBonusDmg) {
|
if (displayBonusDamage) {
|
||||||
dlog("Applying Display Bonus Damage patch.", DL_INIT);
|
dlog("Applying Display Bonus Damage patch.", DL_INIT);
|
||||||
HookCall(0x4722DD, DisplayBonusRangedDmg_hook); // display_stats_
|
HookCall(0x4722DD, DisplayBonusRangedDmg_hook); // display_stats_
|
||||||
if (BonusHtHDmgFix) {
|
if (bonusHtHDamageFix) {
|
||||||
HookCall(0x472309, DisplayBonusHtHDmg1_hook); // display_stats_
|
HookCall(0x472309, DisplayBonusHtHDmg1_hook); // MeleeWeap (display_stats_)
|
||||||
MakeJump(0x472546, DisplayBonusHtHDmg2_hack); // display_stats_
|
|
||||||
SafeWrite32(0x472558, 0x509EDC); // fmt: '%s %d-%d'
|
|
||||||
SafeWrite8(0x472552, 0x98 + 4);
|
|
||||||
SafeWrite8(0x47255F, 0x0C + 4);
|
|
||||||
SafeWrite8(0x472568, 0x10 + 4);
|
|
||||||
}
|
}
|
||||||
dlogr(" Done", DL_INIT);
|
dlogr(" Done", DL_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Display actual damage values for unarmed attacks (display_stats_ hacks)
|
||||||
|
MakeJump(0x472546, DisplayBonusHtHDmg2_hack);
|
||||||
|
SafeWrite32(0x472558, 0x509EDC); // fmt: '%s %d-%d'
|
||||||
|
SafeWrite8(0x472552, 0x98 + 4);
|
||||||
|
SafeWrite8(0x47255F, 0x0C + 4);
|
||||||
|
SafeWrite8(0x472568, 0x10 + 4);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -739,6 +739,17 @@ enum HandSlot : unsigned long
|
|||||||
HANDSLOT_Right = 1
|
HANDSLOT_Right = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum HandSlotMode : long
|
||||||
|
{
|
||||||
|
HANDMODE_Unset = 0,
|
||||||
|
HANDMODE_Primary = 1,
|
||||||
|
HANDMODE_Primary_Aimed = 2,
|
||||||
|
HANDMODE_Secondary = 3,
|
||||||
|
HANDMODE_Secondary_Aimed = 4,
|
||||||
|
HANDMODE_Reload = 5,
|
||||||
|
HANDMODE_UnkMode = 6
|
||||||
|
};
|
||||||
|
|
||||||
enum RollResult
|
enum RollResult
|
||||||
{
|
{
|
||||||
ROLL_CRITICAL_FAILURE = 0x0,
|
ROLL_CRITICAL_FAILURE = 0x0,
|
||||||
|
|||||||
+19
-7
@@ -617,6 +617,18 @@ __declspec(noinline) TGameObj* __stdcall GetItemPtrSlot(TGameObj* critter, Inven
|
|||||||
return itemPtr;
|
return itemPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AttackType GetHandSlotPrimaryAttack(HandSlot slot) {
|
||||||
|
return (AttackType)ptr_itemButtonItems[slot].primaryAttack;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttackType GetHandSlotSecondaryAttack(HandSlot slot) {
|
||||||
|
return (AttackType)ptr_itemButtonItems[slot].secondaryAttack;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandSlotMode GetHandSlotMode(HandSlot slot) {
|
||||||
|
return (HandSlotMode)ptr_itemButtonItems[slot].mode;
|
||||||
|
}
|
||||||
|
|
||||||
long& GetActiveItemMode() {
|
long& GetActiveItemMode() {
|
||||||
return ptr_itemButtonItems[*ptr_itemCurrentItem].mode;
|
return ptr_itemButtonItems[*ptr_itemCurrentItem].mode;
|
||||||
}
|
}
|
||||||
@@ -627,13 +639,13 @@ TGameObj* GetActiveItem() {
|
|||||||
|
|
||||||
AttackType GetSlotHitMode(HandSlot hand) { // 0 - left, 1 - right
|
AttackType GetSlotHitMode(HandSlot hand) { // 0 - left, 1 - right
|
||||||
switch (ptr_itemButtonItems[hand].mode) {
|
switch (ptr_itemButtonItems[hand].mode) {
|
||||||
case 1:
|
case HANDMODE_Primary:
|
||||||
case 2: // called shot
|
case HANDMODE_Primary_Aimed: // called shot
|
||||||
return (AttackType)ptr_itemButtonItems[hand].primaryAttack;
|
return GetHandSlotPrimaryAttack(hand);
|
||||||
case 3:
|
case HANDMODE_Secondary:
|
||||||
case 4: // called shot
|
case HANDMODE_Secondary_Aimed: // called shot
|
||||||
return (AttackType)ptr_itemButtonItems[hand].secondaryAttack;
|
return GetHandSlotSecondaryAttack(hand);
|
||||||
case 5: // reload mode
|
case HANDMODE_Reload:
|
||||||
return (AttackType)(ATKTYPE_LWEAPON_RELOAD + hand);
|
return (AttackType)(ATKTYPE_LWEAPON_RELOAD + hand);
|
||||||
}
|
}
|
||||||
return ATKTYPE_PUNCH;
|
return ATKTYPE_PUNCH;
|
||||||
|
|||||||
@@ -587,6 +587,10 @@ long GetItemType(TGameObj* item);
|
|||||||
|
|
||||||
__declspec(noinline) TGameObj* __stdcall GetItemPtrSlot(TGameObj* critter, InvenType slot);
|
__declspec(noinline) TGameObj* __stdcall GetItemPtrSlot(TGameObj* critter, InvenType slot);
|
||||||
|
|
||||||
|
AttackType GetHandSlotPrimaryAttack(HandSlot slot);
|
||||||
|
AttackType GetHandSlotSecondaryAttack(HandSlot slot);
|
||||||
|
HandSlotMode GetHandSlotMode(HandSlot slot);
|
||||||
|
|
||||||
long& GetActiveItemMode();
|
long& GetActiveItemMode();
|
||||||
|
|
||||||
TGameObj* GetActiveItem();
|
TGameObj* GetActiveItem();
|
||||||
|
|||||||
@@ -203,8 +203,11 @@ WRAP_WATCOM_FUNC2(long, scr_ptr, long, scriptId, TScript**, scriptPtr) // Return
|
|||||||
WRAP_WATCOM_FUNC1(long, scr_remove, long, scriptID)
|
WRAP_WATCOM_FUNC1(long, scr_remove, long, scriptID)
|
||||||
WRAP_WATCOM_FUNC1(void, set_focus_func, void*, func)
|
WRAP_WATCOM_FUNC1(void, set_focus_func, void*, func)
|
||||||
WRAP_WATCOM_FUNC1(long, skill_is_tagged, long, skill)
|
WRAP_WATCOM_FUNC1(long, skill_is_tagged, long, skill)
|
||||||
|
WRAP_WATCOM_FUNC2(long, skill_level, TGameObj*, critter, long, statID)
|
||||||
WRAP_WATCOM_FUNC2(long, stat_get_base, TGameObj*, critter, long, statID)
|
WRAP_WATCOM_FUNC2(long, stat_get_base, TGameObj*, critter, long, statID)
|
||||||
WRAP_WATCOM_FUNC2(long, stat_get_base_direct, TGameObj*, critter, long, statID)
|
WRAP_WATCOM_FUNC2(long, stat_get_base_direct, TGameObj*, critter, long, statID)
|
||||||
|
WRAP_WATCOM_FUNC2(long, stat_get_bonus, TGameObj*, critter, long, statID)
|
||||||
|
WRAP_WATCOM_FUNC3(long, stat_set_bonus, TGameObj*, critter, long, statID, long, amount)
|
||||||
WRAP_WATCOM_FUNC2(void, skill_get_tags, long*, tags, long, num)
|
WRAP_WATCOM_FUNC2(void, skill_get_tags, long*, tags, long, num)
|
||||||
WRAP_WATCOM_FUNC2(void, skill_set_tags, long*, tags, long, num)
|
WRAP_WATCOM_FUNC2(void, skill_set_tags, long*, tags, long, num)
|
||||||
WRAP_WATCOM_FUNC2(long, stat_level, TGameObj*, critter, long, statId)
|
WRAP_WATCOM_FUNC2(long, stat_level, TGameObj*, critter, long, statId)
|
||||||
|
|||||||
+4
-1
@@ -669,9 +669,12 @@ void Inventory_Init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the max text width of the total weight display on the inventory screen
|
// Adjust the maximum text width of the total weight display on the inventory screen
|
||||||
SafeWrite32(0x472632, widthWeight);
|
SafeWrite32(0x472632, widthWeight);
|
||||||
|
|
||||||
|
// Adjust the maximum text width of the unarmed attack display on the inventory screen
|
||||||
|
SafeWrite8(0x472576, 150);
|
||||||
|
|
||||||
if (GetConfigInt("Misc", "SuperStimExploitFix", 0)) {
|
if (GetConfigInt("Misc", "SuperStimExploitFix", 0)) {
|
||||||
Translate_Get("sfall", "SuperStimExploitMsg", "You cannot use this item on someone who is not injured!", superStimMsg);
|
Translate_Get("sfall", "SuperStimExploitMsg", "You cannot use this item on someone who is not injured!", superStimMsg);
|
||||||
MakeCall(0x49C3D9, protinst_use_item_on_hack);
|
MakeCall(0x49C3D9, protinst_use_item_on_hack);
|
||||||
|
|||||||
+83
-30
@@ -23,6 +23,12 @@
|
|||||||
|
|
||||||
#include "DamageMod.h"
|
#include "DamageMod.h"
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
AttackType primaryHit;
|
||||||
|
AttackType secondaryHit;
|
||||||
|
long mode;
|
||||||
|
} slotHitData[2];
|
||||||
|
|
||||||
class Hits {
|
class Hits {
|
||||||
public:
|
public:
|
||||||
static const long count = 20;
|
static const long count = 20;
|
||||||
@@ -40,7 +46,6 @@ private:
|
|||||||
bool isPenetrate; // compute_damage_
|
bool isPenetrate; // compute_damage_
|
||||||
bool isSecondary;
|
bool isSecondary;
|
||||||
|
|
||||||
// HitsData() : reqLevel(0), reqSkill(0), reqStat(), minDamage(1), maxDamage(2), bonusDamage(0), bonusCrit(0), costAP(3), isPenetrate(false), isSecondary(false) {}
|
|
||||||
HitsData() {
|
HitsData() {
|
||||||
reqLevel = 0;
|
reqLevel = 0;
|
||||||
reqSkill = 0;
|
reqSkill = 0;
|
||||||
@@ -231,7 +236,7 @@ Hits unarmed;
|
|||||||
static bool UnarmedReqStats(AttackType hit) {
|
static bool UnarmedReqStats(AttackType hit) {
|
||||||
if (unarmed.SkillLevel() >= unarmed.Hit(hit).reqSkill && (long)*ptr_Level_pc >= unarmed.Hit(hit).reqLevel) {
|
if (unarmed.SkillLevel() >= unarmed.Hit(hit).reqSkill && (long)*ptr_Level_pc >= unarmed.Hit(hit).reqLevel) {
|
||||||
for (size_t stat = 0; stat < STAT_base_count; stat++) {
|
for (size_t stat = 0; stat < STAT_base_count; stat++) {
|
||||||
if (unarmed.Hit(hit).reqStat[stat] == 0) continue;
|
if (unarmed.Hit(hit).reqStat[stat] <= 0) continue;
|
||||||
if (unarmed.Hit(hit).reqStat[stat] > unarmed.DudeStat(stat)) {
|
if (unarmed.Hit(hit).reqStat[stat] > unarmed.DudeStat(stat)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -241,29 +246,20 @@ static bool UnarmedReqStats(AttackType hit) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Punching(bool isPrimary) {
|
static AttackType GetPunchingHit(bool isPrimary) {
|
||||||
for (size_t i = 0; i < 6; i++) {
|
for (size_t i = 0; i < 6; i++) {
|
||||||
AttackType hit = unarmed.GetSortHit(i);
|
AttackType hit = unarmed.GetSortHit(i);
|
||||||
if (unarmed.Hit(hit).isSecondary == isPrimary) continue;
|
if (unarmed.Hit(hit).isSecondary != isPrimary && UnarmedReqStats(hit)) return hit;
|
||||||
|
|
||||||
if (UnarmedReqStats(hit)) {
|
|
||||||
if (unarmed.Hit(hit).isSecondary) {
|
|
||||||
ptr_itemButtonItems[HANDSLOT_Left].secondaryAttack = hit;
|
|
||||||
} else {
|
|
||||||
ptr_itemButtonItems[HANDSLOT_Left].primaryAttack = hit;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return ATKTYPE_PUNCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Punch hits
|
// Punch hits
|
||||||
static void __fastcall check_unarmed_left_slot(long skillLevel) {
|
static void __fastcall check_unarmed_left_slot(long skillLevel) {
|
||||||
unarmed.GetDudeStats(skillLevel);
|
unarmed.GetDudeStats(skillLevel);
|
||||||
|
|
||||||
if (!Punching(true)) ptr_itemButtonItems[HANDSLOT_Left].primaryAttack = ATKTYPE_PUNCH;
|
ptr_itemButtonItems[HANDSLOT_Left].primaryAttack = GetPunchingHit(true);
|
||||||
if (!Punching(false)) ptr_itemButtonItems[HANDSLOT_Left].secondaryAttack = ATKTYPE_PUNCH;
|
ptr_itemButtonItems[HANDSLOT_Left].secondaryAttack = GetPunchingHit(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) intface_update_items_hack_punch() {
|
static void __declspec(naked) intface_update_items_hack_punch() {
|
||||||
@@ -273,27 +269,18 @@ static void __declspec(naked) intface_update_items_hack_punch() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Kicking(bool isPrimary) {
|
static AttackType GetKickingHit(bool isPrimary) {
|
||||||
for (size_t i = 6; i < 12; i++) {
|
for (size_t i = 6; i < 12; i++) {
|
||||||
AttackType hit = unarmed.GetSortHit(i);
|
AttackType hit = unarmed.GetSortHit(i);
|
||||||
if (unarmed.Hit(hit).isSecondary == isPrimary) continue;
|
if (unarmed.Hit(hit).isSecondary != isPrimary && UnarmedReqStats(hit)) return hit;
|
||||||
|
|
||||||
if (UnarmedReqStats(hit)) {
|
|
||||||
if (unarmed.Hit(hit).isSecondary) {
|
|
||||||
ptr_itemButtonItems[HANDSLOT_Right].secondaryAttack = hit;
|
|
||||||
} else {
|
|
||||||
ptr_itemButtonItems[HANDSLOT_Right].primaryAttack = hit;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return ATKTYPE_KICK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kick hits
|
// Kick hits
|
||||||
static void check_unarmed_right_slot() {
|
static void check_unarmed_right_slot() {
|
||||||
if (!Kicking(true)) ptr_itemButtonItems[HANDSLOT_Right].primaryAttack = ATKTYPE_KICK;
|
ptr_itemButtonItems[HANDSLOT_Right].primaryAttack = GetKickingHit(true);
|
||||||
if (!Kicking(false)) ptr_itemButtonItems[HANDSLOT_Right].secondaryAttack = ATKTYPE_KICK;
|
ptr_itemButtonItems[HANDSLOT_Right].secondaryAttack = GetKickingHit(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) intface_update_items_hack_kick() {
|
static void __declspec(naked) intface_update_items_hack_kick() {
|
||||||
@@ -350,6 +337,69 @@ long Unarmed_GetHitAPCost(AttackType hit) {
|
|||||||
return unarmed.Hit(hit).apCost;
|
return unarmed.Hit(hit).apCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long Unarmed_GetDamage(AttackType hit, long &minOut, long &maxOut) {
|
||||||
|
minOut = unarmed.Hit(hit).minDamage;
|
||||||
|
maxOut = unarmed.Hit(hit).maxDamage;
|
||||||
|
return unarmed.Hit(hit).bonusDamage;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static AttackType GetPunchingHit() {
|
||||||
|
unarmed.GetDudeStats(fo_skill_level(*ptr_obj_dude, SKILL_UNARMED_COMBAT));
|
||||||
|
return GetPunchingHit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static AttackType GetKickingHit() {
|
||||||
|
//unarmed.GetDudeStats(fo_skill_level(*ptr_obj_dude, SKILL_UNARMED_COMBAT));
|
||||||
|
return GetKickingHit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SlotsStoreCurrentHitMode() {
|
||||||
|
slotHitData[HANDSLOT_Left].primaryHit = GetHandSlotPrimaryAttack(HANDSLOT_Left);
|
||||||
|
slotHitData[HANDSLOT_Left].secondaryHit = GetHandSlotSecondaryAttack(HANDSLOT_Left);
|
||||||
|
slotHitData[HANDSLOT_Left].mode = GetHandSlotMode(HANDSLOT_Left);
|
||||||
|
|
||||||
|
slotHitData[HANDSLOT_Right].primaryHit = GetHandSlotPrimaryAttack(HANDSLOT_Right);
|
||||||
|
slotHitData[HANDSLOT_Right].secondaryHit = GetHandSlotSecondaryAttack(HANDSLOT_Right);
|
||||||
|
slotHitData[HANDSLOT_Right].mode = GetHandSlotMode(HANDSLOT_Right);
|
||||||
|
}
|
||||||
|
|
||||||
|
AttackType Unarmed_GetStoredHitMode(HandSlot slot) {
|
||||||
|
AttackType hit;
|
||||||
|
|
||||||
|
switch (slotHitData[slot].mode) {
|
||||||
|
case HANDMODE_Primary:
|
||||||
|
case HANDMODE_Primary_Aimed: // called shot
|
||||||
|
hit = slotHitData[slot].primaryHit;
|
||||||
|
break;
|
||||||
|
case HANDMODE_Secondary:
|
||||||
|
case HANDMODE_Secondary_Aimed: // called shot
|
||||||
|
hit = slotHitData[slot].secondaryHit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hit < ATKTYPE_STRONGPUNCH && hit != ATKTYPE_PUNCH && hit != ATKTYPE_KICK) {
|
||||||
|
hit = (slot == HANDSLOT_Left) ? GetPunchingHit() : GetKickingHit(); // get Primary
|
||||||
|
|
||||||
|
if (slot == HANDSLOT_Left) {
|
||||||
|
slotHitData[HANDSLOT_Left].primaryHit = hit;
|
||||||
|
slotHitData[HANDSLOT_Left].mode = HANDMODE_Primary;
|
||||||
|
} else {
|
||||||
|
slotHitData[HANDSLOT_Right].primaryHit = hit;
|
||||||
|
slotHitData[HANDSLOT_Right].mode = HANDMODE_Primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __declspec(naked) handle_inventory_hook() {
|
||||||
|
__asm {
|
||||||
|
call SlotsStoreCurrentHitMode;
|
||||||
|
jmp display_stats_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void __declspec(naked) statPCAddExperienceCheckPMs_hook() {
|
static void __declspec(naked) statPCAddExperienceCheckPMs_hook() {
|
||||||
@@ -437,6 +487,9 @@ void Unarmed_Init() {
|
|||||||
MakeCall(0x4248B6, check_unarmed_penetrate, 5);
|
MakeCall(0x4248B6, check_unarmed_penetrate, 5);
|
||||||
SafeWrite16(0x4248C1, 0x01F8); // cmp eax, 1
|
SafeWrite16(0x4248C1, 0x01F8); // cmp eax, 1
|
||||||
SafeWrite8(0x4248C8, CODETYPE_JumpShort);
|
SafeWrite8(0x4248C8, CODETYPE_JumpShort);
|
||||||
|
|
||||||
|
// Store the current values of unarmed attack modes when opening the player's inventory
|
||||||
|
HookCall(0x46E8D4, handle_inventory_hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void Unarmed_Exit() {
|
//void Unarmed_Exit() {
|
||||||
|
|||||||
@@ -22,3 +22,6 @@ void Unarmed_Init();
|
|||||||
//void Unarmed_Exit();
|
//void Unarmed_Exit();
|
||||||
|
|
||||||
long Unarmed_GetHitAPCost(AttackType hit);
|
long Unarmed_GetHitAPCost(AttackType hit);
|
||||||
|
long Unarmed_GetDamage(AttackType hit, long &minOut, long &maxOut);
|
||||||
|
|
||||||
|
AttackType Unarmed_GetStoredHitMode(HandSlot slot);
|
||||||
|
|||||||
+1
-1
@@ -124,7 +124,7 @@
|
|||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>None</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<CallingConvention>Cdecl</CallingConvention>
|
<CallingConvention>Cdecl</CallingConvention>
|
||||||
<ForcedIncludeFiles>stdafx.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
|
<ForcedIncludeFiles>stdafx.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
|||||||
Reference in New Issue
Block a user