diff --git a/Client/game_sa/CWeaponStatManagerSA.cpp b/Client/game_sa/CWeaponStatManagerSA.cpp index d7f420be5cd..b7768bc6c18 100644 --- a/Client/game_sa/CWeaponStatManagerSA.cpp +++ b/Client/game_sa/CWeaponStatManagerSA.cpp @@ -14,6 +14,7 @@ sWeaponInfo CWeaponStatManagerSA::OriginalPoorWeaponData[WEAPONTYPE_MAX + 1]; sWeaponInfo CWeaponStatManagerSA::OriginalNormalWeaponData[WEAPONTYPE_MAX + 1]; sWeaponInfo CWeaponStatManagerSA::OriginalHitmanWeaponData[WEAPONTYPE_MAX + 1]; +sWeaponInfo CWeaponStatManagerSA::OriginalSpecialWeaponData[WEAPONTYPE_MAX + 1]; CWeaponStatManagerSA::CWeaponStatManagerSA() { @@ -35,7 +36,7 @@ void CWeaponStatManagerSA::InitLists() LoadDefaultInternal(pWeaponStat, weaponType); } - for (int skill = 0; skill < 3; skill++) + for (int skill = 0; skill < WEAPONSKILL_MAX_NUMBER; skill++) { for (int i = 0; i < NUM_WeaponInfosOtherSkill; i++) { @@ -124,21 +125,17 @@ CWeaponStat* CWeaponStatManagerSA::GetWeaponStatsFromSkillLevel(eWeaponType type CWeaponStat* pPoor = GetWeaponStats(type, WEAPONSKILL_POOR); CWeaponStat* pStd = GetWeaponStats(type, WEAPONSKILL_STD); CWeaponStat* pPro = GetWeaponStats(type, WEAPONSKILL_PRO); - if (pStd) - { - if (pPoor && pPro) - { - if (fSkillLevel >= pPro->GetRequiredStatLevel()) - return pPro; - else if (fSkillLevel >= pStd->GetRequiredStatLevel()) - return pStd; - else - return pPoor; - } - else - return pStd; - } - return nullptr; + CWeaponStat* pSpec = GetWeaponStats(type, WEAPONSKILL_SPECIAL); + if (pSpec && fSkillLevel >= pSpec->GetRequiredStatLevel()) + return pSpec; + else if (pPro && fSkillLevel >= pPro->GetRequiredStatLevel()) + return pPro; + else if (pStd && fSkillLevel >= pStd->GetRequiredStatLevel()) + return pStd; + else if (pPoor && fSkillLevel >= pPoor->GetRequiredStatLevel()) + return pPoor; + else + return pStd; } CWeaponStat* CWeaponStatManagerSA::GetOriginalWeaponStats(eWeaponType type, eWeaponSkill skill) @@ -1510,6 +1507,71 @@ void CWeaponStatManagerSA::Init() OriginalHitmanWeaponData[32].aim_offset = 4; OriginalHitmanWeaponData[32].default_combo = 4; OriginalHitmanWeaponData[32].combos_available = 1; + + // 22 - Colt 45 Stat: 3 + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].weapon_range = 35.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].target_range = 30.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].accuracy = 1.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].damage = 25; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].life_span = 0.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].firing_speed = 0.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].spread = 0.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].maximum_clip_ammo = 17; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].move_speed = 1.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].flags = 28721; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim_group = 14; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].fire_type = (eFireType)1; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].model = 346; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].model2 = -1; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].weapon_slot = (eWeaponSlot)2; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].fire_offset = CVector(0.25f, 0.050000000745058f, 0.090000003576279f); + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].skill_level = (eWeaponSkill)3; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].required_skill_level = 5000; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim_loop_start = 0.20000001788139f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim_loop_stop = 0.49399998784065f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim_loop_bullet_fire = 0.20000001788139f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim2_loop_start = 0.20000001788139f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim2_loop_stop = 0.49399998784065f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim2_loop_bullet_fire = 0.20000001788139f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim_breakout_time = 3.3000001907349f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].radius = 0.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].aim_offset = 2; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].default_combo = 4; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].combos_available = 1; + + for (int i = WEAPONTYPE_PISTOL + 1; i <= WEAPONTYPE_EXTINGUISHER; ++i) + { + OriginalSpecialWeaponData[i].weapon_range = OriginalHitmanWeaponData[i].weapon_range; + OriginalSpecialWeaponData[i].target_range = OriginalHitmanWeaponData[i].target_range; + OriginalSpecialWeaponData[i].accuracy = OriginalHitmanWeaponData[i].accuracy; + OriginalSpecialWeaponData[i].damage = OriginalHitmanWeaponData[i].damage; + OriginalSpecialWeaponData[i].life_span = OriginalHitmanWeaponData[i].life_span; + OriginalSpecialWeaponData[i].firing_speed = OriginalHitmanWeaponData[i].firing_speed; + OriginalSpecialWeaponData[i].spread = OriginalHitmanWeaponData[i].spread; + OriginalSpecialWeaponData[i].maximum_clip_ammo = OriginalHitmanWeaponData[i].maximum_clip_ammo; + OriginalSpecialWeaponData[i].move_speed = OriginalHitmanWeaponData[i].move_speed; + OriginalSpecialWeaponData[i].flags = OriginalHitmanWeaponData[i].flags; + OriginalSpecialWeaponData[i].anim_group = OriginalHitmanWeaponData[i].anim_group; + OriginalSpecialWeaponData[i].fire_type = OriginalHitmanWeaponData[i].fire_type; + OriginalSpecialWeaponData[i].model = OriginalHitmanWeaponData[i].model; + OriginalSpecialWeaponData[i].model2 = OriginalHitmanWeaponData[i].model2; + OriginalSpecialWeaponData[i].weapon_slot = OriginalHitmanWeaponData[i].weapon_slot; + OriginalSpecialWeaponData[i].fire_offset = OriginalHitmanWeaponData[i].fire_offset; + OriginalSpecialWeaponData[i].skill_level = (eWeaponSkill)3; + OriginalSpecialWeaponData[i].required_skill_level = 5000; + OriginalSpecialWeaponData[i].anim_loop_start = OriginalHitmanWeaponData[i].anim_loop_start; + OriginalSpecialWeaponData[i].anim_loop_stop = OriginalHitmanWeaponData[i].anim_loop_stop; + OriginalSpecialWeaponData[i].anim_loop_bullet_fire = OriginalHitmanWeaponData[i].anim_loop_bullet_fire; + OriginalSpecialWeaponData[i].anim2_loop_start = OriginalHitmanWeaponData[i].anim2_loop_start; + OriginalSpecialWeaponData[i].anim2_loop_stop = OriginalHitmanWeaponData[i].anim2_loop_stop; + OriginalSpecialWeaponData[i].anim2_loop_bullet_fire = OriginalHitmanWeaponData[i].anim2_loop_bullet_fire; + OriginalSpecialWeaponData[i].anim_breakout_time = OriginalHitmanWeaponData[i].anim_breakout_time; + OriginalSpecialWeaponData[i].radius = OriginalHitmanWeaponData[i].radius; + OriginalSpecialWeaponData[i].aim_offset = OriginalHitmanWeaponData[i].aim_offset; + OriginalSpecialWeaponData[i].default_combo = OriginalHitmanWeaponData[i].default_combo; + OriginalSpecialWeaponData[i].combos_available = OriginalHitmanWeaponData[i].combos_available; + } + // End of Skill Level Weapons } @@ -1555,6 +1617,39 @@ bool CWeaponStatManagerSA::LoadDefault(CWeaponStat* pDest, eWeaponType weaponTyp pDest->SetCombosAvailable(OriginalPoorWeaponData[iVal].combos_available); break; } + case WEAPONSKILL_STD: + { + pDest->SetWeaponRange(OriginalNormalWeaponData[iVal].weapon_range); + pDest->SetTargetRange(OriginalNormalWeaponData[iVal].target_range); + pDest->SetAccuracy(OriginalNormalWeaponData[iVal].accuracy); + pDest->SetDamagePerHit(OriginalNormalWeaponData[iVal].damage); + pDest->SetLifeSpan(OriginalNormalWeaponData[iVal].life_span); + pDest->SetFiringSpeed(OriginalNormalWeaponData[iVal].firing_speed); + pDest->SetSpread(OriginalNormalWeaponData[iVal].spread); + pDest->SetMaximumClipAmmo(OriginalNormalWeaponData[iVal].maximum_clip_ammo); + pDest->SetMoveSpeed(OriginalNormalWeaponData[iVal].move_speed); + pDest->SetFlags(OriginalNormalWeaponData[iVal].flags); + pDest->SetAnimGroup(OriginalNormalWeaponData[iVal].anim_group); + pDest->SetFireType(OriginalNormalWeaponData[iVal].fire_type); + pDest->SetModel(OriginalNormalWeaponData[iVal].model); + pDest->SetModel2(OriginalNormalWeaponData[iVal].model2); + pDest->SetSlot(OriginalNormalWeaponData[iVal].weapon_slot); + pDest->SetFireOffset(&OriginalNormalWeaponData[iVal].fire_offset); + pDest->SetSkill(OriginalNormalWeaponData[iVal].skill_level); + pDest->SetRequiredStatLevel(OriginalNormalWeaponData[iVal].required_skill_level); + pDest->SetWeaponAnimLoopStart(OriginalNormalWeaponData[iVal].anim_loop_start); + pDest->SetWeaponAnimLoopStop(OriginalNormalWeaponData[iVal].anim_loop_stop); + pDest->SetWeaponAnimLoopFireTime(OriginalNormalWeaponData[iVal].anim_loop_bullet_fire); + pDest->SetWeaponAnim2LoopStart(OriginalNormalWeaponData[iVal].anim2_loop_start); + pDest->SetWeaponAnim2LoopStop(OriginalNormalWeaponData[iVal].anim2_loop_stop); + pDest->SetWeaponAnim2LoopFireTime(OriginalNormalWeaponData[iVal].anim2_loop_bullet_fire); + pDest->SetWeaponAnimBreakoutTime(OriginalNormalWeaponData[iVal].anim_breakout_time); + pDest->SetWeaponRadius(OriginalNormalWeaponData[iVal].radius); + pDest->SetAimOffsetIndex(OriginalNormalWeaponData[iVal].aim_offset); + pDest->SetDefaultCombo(OriginalNormalWeaponData[iVal].default_combo); + pDest->SetCombosAvailable(OriginalNormalWeaponData[iVal].combos_available); + break; + } case WEAPONSKILL_PRO: { pDest->SetWeaponRange(OriginalHitmanWeaponData[iVal].weapon_range); @@ -1588,37 +1683,37 @@ bool CWeaponStatManagerSA::LoadDefault(CWeaponStat* pDest, eWeaponType weaponTyp pDest->SetCombosAvailable(OriginalHitmanWeaponData[iVal].combos_available); break; } - case WEAPONSKILL_STD: + case WEAPONSKILL_SPECIAL: { - pDest->SetWeaponRange(OriginalNormalWeaponData[iVal].weapon_range); - pDest->SetTargetRange(OriginalNormalWeaponData[iVal].target_range); - pDest->SetAccuracy(OriginalNormalWeaponData[iVal].accuracy); - pDest->SetDamagePerHit(OriginalNormalWeaponData[iVal].damage); - pDest->SetLifeSpan(OriginalNormalWeaponData[iVal].life_span); - pDest->SetFiringSpeed(OriginalNormalWeaponData[iVal].firing_speed); - pDest->SetSpread(OriginalNormalWeaponData[iVal].spread); - pDest->SetMaximumClipAmmo(OriginalNormalWeaponData[iVal].maximum_clip_ammo); - pDest->SetMoveSpeed(OriginalNormalWeaponData[iVal].move_speed); - pDest->SetFlags(OriginalNormalWeaponData[iVal].flags); - pDest->SetAnimGroup(OriginalNormalWeaponData[iVal].anim_group); - pDest->SetFireType(OriginalNormalWeaponData[iVal].fire_type); - pDest->SetModel(OriginalNormalWeaponData[iVal].model); - pDest->SetModel2(OriginalNormalWeaponData[iVal].model2); - pDest->SetSlot(OriginalNormalWeaponData[iVal].weapon_slot); - pDest->SetFireOffset(&OriginalNormalWeaponData[iVal].fire_offset); - pDest->SetSkill(OriginalNormalWeaponData[iVal].skill_level); - pDest->SetRequiredStatLevel(OriginalNormalWeaponData[iVal].required_skill_level); - pDest->SetWeaponAnimLoopStart(OriginalNormalWeaponData[iVal].anim_loop_start); - pDest->SetWeaponAnimLoopStop(OriginalNormalWeaponData[iVal].anim_loop_stop); - pDest->SetWeaponAnimLoopFireTime(OriginalNormalWeaponData[iVal].anim_loop_bullet_fire); - pDest->SetWeaponAnim2LoopStart(OriginalNormalWeaponData[iVal].anim2_loop_start); - pDest->SetWeaponAnim2LoopStop(OriginalNormalWeaponData[iVal].anim2_loop_stop); - pDest->SetWeaponAnim2LoopFireTime(OriginalNormalWeaponData[iVal].anim2_loop_bullet_fire); - pDest->SetWeaponAnimBreakoutTime(OriginalNormalWeaponData[iVal].anim_breakout_time); - pDest->SetWeaponRadius(OriginalNormalWeaponData[iVal].radius); - pDest->SetAimOffsetIndex(OriginalNormalWeaponData[iVal].aim_offset); - pDest->SetDefaultCombo(OriginalNormalWeaponData[iVal].default_combo); - pDest->SetCombosAvailable(OriginalNormalWeaponData[iVal].combos_available); + pDest->SetWeaponRange(OriginalSpecialWeaponData[iVal].weapon_range); + pDest->SetTargetRange(OriginalSpecialWeaponData[iVal].target_range); + pDest->SetAccuracy(OriginalSpecialWeaponData[iVal].accuracy); + pDest->SetDamagePerHit(OriginalSpecialWeaponData[iVal].damage); + pDest->SetLifeSpan(OriginalSpecialWeaponData[iVal].life_span); + pDest->SetFiringSpeed(OriginalSpecialWeaponData[iVal].firing_speed); + pDest->SetSpread(OriginalSpecialWeaponData[iVal].spread); + pDest->SetMaximumClipAmmo(OriginalSpecialWeaponData[iVal].maximum_clip_ammo); + pDest->SetMoveSpeed(OriginalSpecialWeaponData[iVal].move_speed); + pDest->SetFlags(OriginalSpecialWeaponData[iVal].flags); + pDest->SetAnimGroup(OriginalSpecialWeaponData[iVal].anim_group); + pDest->SetFireType(OriginalSpecialWeaponData[iVal].fire_type); + pDest->SetModel(OriginalSpecialWeaponData[iVal].model); + pDest->SetModel2(OriginalSpecialWeaponData[iVal].model2); + pDest->SetSlot(OriginalSpecialWeaponData[iVal].weapon_slot); + pDest->SetFireOffset(&OriginalSpecialWeaponData[iVal].fire_offset); + pDest->SetSkill(OriginalSpecialWeaponData[iVal].skill_level); + pDest->SetRequiredStatLevel(OriginalSpecialWeaponData[iVal].required_skill_level); + pDest->SetWeaponAnimLoopStart(OriginalSpecialWeaponData[iVal].anim_loop_start); + pDest->SetWeaponAnimLoopStop(OriginalSpecialWeaponData[iVal].anim_loop_stop); + pDest->SetWeaponAnimLoopFireTime(OriginalSpecialWeaponData[iVal].anim_loop_bullet_fire); + pDest->SetWeaponAnim2LoopStart(OriginalSpecialWeaponData[iVal].anim2_loop_start); + pDest->SetWeaponAnim2LoopStop(OriginalSpecialWeaponData[iVal].anim2_loop_stop); + pDest->SetWeaponAnim2LoopFireTime(OriginalSpecialWeaponData[iVal].anim2_loop_bullet_fire); + pDest->SetWeaponAnimBreakoutTime(OriginalSpecialWeaponData[iVal].anim_breakout_time); + pDest->SetWeaponRadius(OriginalSpecialWeaponData[iVal].radius); + pDest->SetAimOffsetIndex(OriginalSpecialWeaponData[iVal].aim_offset); + pDest->SetDefaultCombo(OriginalSpecialWeaponData[iVal].default_combo); + pDest->SetCombosAvailable(OriginalSpecialWeaponData[iVal].combos_available); break; } } @@ -1669,6 +1764,39 @@ bool CWeaponStatManagerSA::LoadDefaultInternal(CWeaponStatSA* pDest, eWeaponType pDest->SetCombosAvailable(OriginalPoorWeaponData[iVal].combos_available); break; } + case WEAPONSKILL_STD: + { + pDest->SetWeaponRange(OriginalNormalWeaponData[iVal].weapon_range); + pDest->SetTargetRange(OriginalNormalWeaponData[iVal].target_range); + pDest->SetAccuracy(OriginalNormalWeaponData[iVal].accuracy); + pDest->SetDamagePerHit(OriginalNormalWeaponData[iVal].damage); + pDest->SetLifeSpan(OriginalNormalWeaponData[iVal].life_span); + pDest->SetFiringSpeed(OriginalNormalWeaponData[iVal].firing_speed); + pDest->SetSpread(OriginalNormalWeaponData[iVal].spread); + pDest->SetMaximumClipAmmo(OriginalNormalWeaponData[iVal].maximum_clip_ammo); + pDest->SetMoveSpeed(OriginalNormalWeaponData[iVal].move_speed); + pDest->SetFlags(OriginalNormalWeaponData[iVal].flags); + pDest->SetAnimGroup(OriginalNormalWeaponData[iVal].anim_group); + pDest->SetFireType(OriginalNormalWeaponData[iVal].fire_type); + pDest->SetModel(OriginalNormalWeaponData[iVal].model); + pDest->SetModel2(OriginalNormalWeaponData[iVal].model2); + pDest->SetSlot(OriginalNormalWeaponData[iVal].weapon_slot); + pDest->SetFireOffset(&OriginalNormalWeaponData[iVal].fire_offset); + pDest->SetSkill(OriginalNormalWeaponData[iVal].skill_level); + pDest->SetRequiredStatLevel(OriginalNormalWeaponData[iVal].required_skill_level); + pDest->SetWeaponAnimLoopStart(OriginalNormalWeaponData[iVal].anim_loop_start); + pDest->SetWeaponAnimLoopStop(OriginalNormalWeaponData[iVal].anim_loop_stop); + pDest->SetWeaponAnimLoopFireTime(OriginalNormalWeaponData[iVal].anim_loop_bullet_fire); + pDest->SetWeaponAnim2LoopStart(OriginalNormalWeaponData[iVal].anim2_loop_start); + pDest->SetWeaponAnim2LoopStop(OriginalNormalWeaponData[iVal].anim2_loop_stop); + pDest->SetWeaponAnim2LoopFireTime(OriginalNormalWeaponData[iVal].anim2_loop_bullet_fire); + pDest->SetWeaponAnimBreakoutTime(OriginalNormalWeaponData[iVal].anim_breakout_time); + pDest->SetWeaponRadius(OriginalNormalWeaponData[iVal].radius); + pDest->SetAimOffsetIndex(OriginalNormalWeaponData[iVal].aim_offset); + pDest->SetDefaultCombo(OriginalNormalWeaponData[iVal].default_combo); + pDest->SetCombosAvailable(OriginalNormalWeaponData[iVal].combos_available); + break; + } case WEAPONSKILL_PRO: { pDest->SetWeaponRange(OriginalHitmanWeaponData[iVal].weapon_range); @@ -1702,37 +1830,37 @@ bool CWeaponStatManagerSA::LoadDefaultInternal(CWeaponStatSA* pDest, eWeaponType pDest->SetCombosAvailable(OriginalHitmanWeaponData[iVal].combos_available); break; } - case WEAPONSKILL_STD: + case WEAPONSKILL_SPECIAL: { - pDest->SetWeaponRange(OriginalNormalWeaponData[iVal].weapon_range); - pDest->SetTargetRange(OriginalNormalWeaponData[iVal].target_range); - pDest->SetAccuracy(OriginalNormalWeaponData[iVal].accuracy); - pDest->SetDamagePerHit(OriginalNormalWeaponData[iVal].damage); - pDest->SetLifeSpan(OriginalNormalWeaponData[iVal].life_span); - pDest->SetFiringSpeed(OriginalNormalWeaponData[iVal].firing_speed); - pDest->SetSpread(OriginalNormalWeaponData[iVal].spread); - pDest->SetMaximumClipAmmo(OriginalNormalWeaponData[iVal].maximum_clip_ammo); - pDest->SetMoveSpeed(OriginalNormalWeaponData[iVal].move_speed); - pDest->SetFlags(OriginalNormalWeaponData[iVal].flags); - pDest->SetAnimGroup(OriginalNormalWeaponData[iVal].anim_group); - pDest->SetFireType(OriginalNormalWeaponData[iVal].fire_type); - pDest->SetModel(OriginalNormalWeaponData[iVal].model); - pDest->SetModel2(OriginalNormalWeaponData[iVal].model2); - pDest->SetSlot(OriginalNormalWeaponData[iVal].weapon_slot); - pDest->SetFireOffset(&OriginalNormalWeaponData[iVal].fire_offset); - pDest->SetSkill(OriginalNormalWeaponData[iVal].skill_level); - pDest->SetRequiredStatLevel(OriginalNormalWeaponData[iVal].required_skill_level); - pDest->SetWeaponAnimLoopStart(OriginalNormalWeaponData[iVal].anim_loop_start); - pDest->SetWeaponAnimLoopStop(OriginalNormalWeaponData[iVal].anim_loop_stop); - pDest->SetWeaponAnimLoopFireTime(OriginalNormalWeaponData[iVal].anim_loop_bullet_fire); - pDest->SetWeaponAnim2LoopStart(OriginalNormalWeaponData[iVal].anim2_loop_start); - pDest->SetWeaponAnim2LoopStop(OriginalNormalWeaponData[iVal].anim2_loop_stop); - pDest->SetWeaponAnim2LoopFireTime(OriginalNormalWeaponData[iVal].anim2_loop_bullet_fire); - pDest->SetWeaponAnimBreakoutTime(OriginalNormalWeaponData[iVal].anim_breakout_time); - pDest->SetWeaponRadius(OriginalNormalWeaponData[iVal].radius); - pDest->SetAimOffsetIndex(OriginalNormalWeaponData[iVal].aim_offset); - pDest->SetDefaultCombo(OriginalNormalWeaponData[iVal].default_combo); - pDest->SetCombosAvailable(OriginalNormalWeaponData[iVal].combos_available); + pDest->SetWeaponRange(OriginalSpecialWeaponData[iVal].weapon_range); + pDest->SetTargetRange(OriginalSpecialWeaponData[iVal].target_range); + pDest->SetAccuracy(OriginalSpecialWeaponData[iVal].accuracy); + pDest->SetDamagePerHit(OriginalSpecialWeaponData[iVal].damage); + pDest->SetLifeSpan(OriginalSpecialWeaponData[iVal].life_span); + pDest->SetFiringSpeed(OriginalSpecialWeaponData[iVal].firing_speed); + pDest->SetSpread(OriginalSpecialWeaponData[iVal].spread); + pDest->SetMaximumClipAmmo(OriginalSpecialWeaponData[iVal].maximum_clip_ammo); + pDest->SetMoveSpeed(OriginalSpecialWeaponData[iVal].move_speed); + pDest->SetFlags(OriginalSpecialWeaponData[iVal].flags); + pDest->SetAnimGroup(OriginalSpecialWeaponData[iVal].anim_group); + pDest->SetFireType(OriginalSpecialWeaponData[iVal].fire_type); + pDest->SetModel(OriginalSpecialWeaponData[iVal].model); + pDest->SetModel2(OriginalSpecialWeaponData[iVal].model2); + pDest->SetSlot(OriginalSpecialWeaponData[iVal].weapon_slot); + pDest->SetFireOffset(&OriginalSpecialWeaponData[iVal].fire_offset); + pDest->SetSkill(OriginalSpecialWeaponData[iVal].skill_level); + pDest->SetRequiredStatLevel(OriginalSpecialWeaponData[iVal].required_skill_level); + pDest->SetWeaponAnimLoopStart(OriginalSpecialWeaponData[iVal].anim_loop_start); + pDest->SetWeaponAnimLoopStop(OriginalSpecialWeaponData[iVal].anim_loop_stop); + pDest->SetWeaponAnimLoopFireTime(OriginalSpecialWeaponData[iVal].anim_loop_bullet_fire); + pDest->SetWeaponAnim2LoopStart(OriginalSpecialWeaponData[iVal].anim2_loop_start); + pDest->SetWeaponAnim2LoopStop(OriginalSpecialWeaponData[iVal].anim2_loop_stop); + pDest->SetWeaponAnim2LoopFireTime(OriginalSpecialWeaponData[iVal].anim2_loop_bullet_fire); + pDest->SetWeaponAnimBreakoutTime(OriginalSpecialWeaponData[iVal].anim_breakout_time); + pDest->SetWeaponRadius(OriginalSpecialWeaponData[iVal].radius); + pDest->SetAimOffsetIndex(OriginalSpecialWeaponData[iVal].aim_offset); + pDest->SetDefaultCombo(OriginalSpecialWeaponData[iVal].default_combo); + pDest->SetCombosAvailable(OriginalSpecialWeaponData[iVal].combos_available); break; } } @@ -1746,19 +1874,15 @@ eWeaponSkill CWeaponStatManagerSA::GetWeaponSkillFromSkillLevel(eWeaponType type CWeaponStat* pPoor = GetWeaponStats(type, WEAPONSKILL_POOR); CWeaponStat* pStd = GetWeaponStats(type, WEAPONSKILL_STD); CWeaponStat* pPro = GetWeaponStats(type, WEAPONSKILL_PRO); - if (pStd) - { - if (pPoor && pPro) - { - if (fSkillLevel >= pPro->GetRequiredStatLevel()) - return WEAPONSKILL_PRO; - else if (fSkillLevel >= pStd->GetRequiredStatLevel()) - return WEAPONSKILL_STD; - else - return WEAPONSKILL_POOR; - } - else - return WEAPONSKILL_STD; - } - return WEAPONSKILL_STD; + CWeaponStat* pSpec = GetWeaponStats(type, WEAPONSKILL_SPECIAL); + if (pSpec && fSkillLevel >= pSpec->GetRequiredStatLevel()) + return WEAPONSKILL_SPECIAL; + else if (pPro && fSkillLevel >= pPro->GetRequiredStatLevel()) + return WEAPONSKILL_PRO; + else if (pStd && fSkillLevel >= pStd->GetRequiredStatLevel()) + return WEAPONSKILL_STD; + else if (pPoor && fSkillLevel >= pPoor->GetRequiredStatLevel()) + return WEAPONSKILL_POOR; + else + return WEAPONSKILL_STD; } diff --git a/Client/game_sa/CWeaponStatManagerSA.h b/Client/game_sa/CWeaponStatManagerSA.h index c1b6344f706..2452244a280 100644 --- a/Client/game_sa/CWeaponStatManagerSA.h +++ b/Client/game_sa/CWeaponStatManagerSA.h @@ -100,4 +100,5 @@ class CWeaponStatManagerSA : public CWeaponStatManager static sWeaponInfo OriginalPoorWeaponData[WEAPONTYPE_MAX + 1]; static sWeaponInfo OriginalNormalWeaponData[WEAPONTYPE_MAX + 1]; static sWeaponInfo OriginalHitmanWeaponData[WEAPONTYPE_MAX + 1]; + static sWeaponInfo OriginalSpecialWeaponData[WEAPONTYPE_MAX + 1]; }; diff --git a/Client/mods/deathmatch/logic/CPacketHandler.cpp b/Client/mods/deathmatch/logic/CPacketHandler.cpp index c6fea64065e..f026e128897 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -2603,6 +2603,8 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) pWeaponInfo->SetWeaponAnim2LoopFireTime(weaponProperty.data.anim2_loop_bullet_fire); pWeaponInfo->SetAnimBreakoutTime(weaponProperty.data.anim_breakout_time); + + pWeaponInfo->SetAnimGroup(weaponProperty.data.anim_group); } bool bEnabled; @@ -2617,7 +2619,7 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) bitStream.ReadBit(bReadWeaponInfo); if (bReadWeaponInfo) { - for (int j = 0; j <= 2; j++) + for (int j = 0; j <= 3; j++) { bitStream.Read(&weaponProperty); CWeaponStat* pWeaponInfo = g_pGame->GetWeaponStatManager()->GetWeaponStats((eWeaponType)weaponProperty.data.weaponType, (eWeaponSkill)j); @@ -2638,6 +2640,23 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) pWeaponInfo->SetWeaponAnim2LoopFireTime(weaponProperty.data.anim2_loop_bullet_fire); pWeaponInfo->SetAnimBreakoutTime(weaponProperty.data.anim_breakout_time); + + pWeaponInfo->SetAnimGroup(weaponProperty.data.anim_group); + pWeaponInfo->SetAnimGroup(weaponProperty.data.anim_group); + pWeaponInfo->SetFireType((eFireType)weaponProperty.data.fire_type); + pWeaponInfo->SetModel(weaponProperty.data.model); + pWeaponInfo->SetModel2( weaponProperty.data.model2); + pWeaponInfo->SetSlot((eWeaponSlot)weaponProperty.data.weapon_slot); + pWeaponInfo->SetFireOffset(&weaponProperty.data.fire_offset); + pWeaponInfo->SetSkill((eWeaponSkill)weaponProperty.data.skill_level); + pWeaponInfo->SetRequiredStatLevel(weaponProperty.data.required_skill_level); + pWeaponInfo->SetFiringSpeed(weaponProperty.data.firing_speed); + pWeaponInfo->SetRadius(weaponProperty.data.radius); + pWeaponInfo->SetLifeSpan(weaponProperty.data.life_span); + pWeaponInfo->SetSpread(weaponProperty.data.spread); + pWeaponInfo->SetAimOffsetIndex(weaponProperty.data.aim_offset); + pWeaponInfo->SetDefaultCombo(weaponProperty.data.default_combo); + pWeaponInfo->SetCombosAvailable(weaponProperty.data.combos_available); } } diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index 7ae83f8bfbb..2c62d812593 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -314,6 +314,7 @@ IMPLEMENT_ENUM_BEGIN(eWeaponSkill) ADD_ENUM(WEAPONSKILL_POOR, "poor") ADD_ENUM(WEAPONSKILL_STD, "std") ADD_ENUM(WEAPONSKILL_PRO, "pro") +ADD_ENUM(WEAPONSKILL_SPECIAL, "special") IMPLEMENT_ENUM_END("weapon-skill") IMPLEMENT_ENUM_BEGIN(ERenderFormat) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp index 450214d624f..e5e383d574b 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp @@ -2119,8 +2119,22 @@ int CLuaPedDefs::SetPedStat(lua_State* luaVM) if (!argStream.HasErrors()) { // Check the stat and value - if (usStat > NUM_PLAYER_STATS - 1 || fValue < 0.0f || fValue > 1000.0f) - argStream.SetCustomError("Stat must be 0 to 342 and value must be 0 to 1000."); + if (usStat > NUM_PLAYER_STATS - 1) + { + argStream.SetCustomError("Stat must be 0 to 342 and value must be 0 to 5000."); + } + else if (fValue < 0.0f) + { + argStream.SetCustomError("Value must be greater than 0."); + } + else if ((usStat >= WEAPONTYPE_PISTOL_SKILL && usStat <= WEAPONTYPE_SNIPERRIFLE_SKILL) && fValue > 5000.0f) + { + argStream.SetCustomError("Value must be at most 5000 (for weapon stats)."); + } + else if ((usStat < WEAPONTYPE_PISTOL_SKILL || usStat > WEAPONTYPE_SNIPERRIFLE_SKILL) && fValue > 1000.0f) + { + argStream.SetCustomError("Value must be at most 1000 (for non-weapon stats)."); + } else if (CStaticFunctionDefinitions::SetPedStat(*pEntity, usStat, fValue)) { lua_pushboolean(luaVM, true); diff --git a/Client/multiplayer_sa/CMultiplayerSA.cpp b/Client/multiplayer_sa/CMultiplayerSA.cpp index bf1ea9c5bb1..560e8ac0fce 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA.cpp @@ -6124,40 +6124,54 @@ eWeaponType weaponSkillWeapon; BYTE weaponSkill; bool CPed_GetWeaponSkill() { + if (weaponSkillWeapon < WEAPONTYPE_PISTOL || weaponSkillWeapon > WEAPONTYPE_TEC9) + { + return false; + } + SClientEntity* pPedClientEntity = pGameInterface->GetPools()->GetPed((DWORD*)weaponSkillPed); CPed* pPed = pPedClientEntity ? pPedClientEntity->pEntity : nullptr; - if (pPed) + if (!pPed) + { + return false; + } + + CPlayerPed* playerPed = dynamic_cast(pPed); + if (!playerPed) + { + return false; + } + + unsigned short skillStatIdx = pGameInterface->GetStats()->GetSkillStatIndex(weaponSkillWeapon); + float stat; + CPed* pLocalPlayerPed = pGameInterface->GetPools()->GetPedFromRef((DWORD)1); + if (pPed == pLocalPlayerPed) { - CPed* pLocalPlayerPed = pGameInterface->GetPools()->GetPedFromRef((DWORD)1); - if (pPed != pLocalPlayerPed) + stat = pGameInterface->GetStats()->GetStatValue(skillStatIdx); + } + else + { + CRemoteDataStorageSA* data = CRemoteDataSA::GetRemoteDataStorage(playerPed); + if (!data) { - if (weaponSkillWeapon >= WEAPONTYPE_PISTOL && weaponSkillWeapon <= WEAPONTYPE_TEC9) - { - CPlayerPed* playerPed = dynamic_cast(pPed); - if (playerPed) - { - CRemoteDataStorageSA* data = CRemoteDataSA::GetRemoteDataStorage(playerPed); - if (data) - { - float stat = data->m_stats.StatTypesFloat[pGameInterface->GetStats()->GetSkillStatIndex(weaponSkillWeapon)]; - - CWeaponInfo* pPoor = pGameInterface->GetWeaponInfo(weaponSkillWeapon, WEAPONSKILL_POOR); - CWeaponInfo* pStd = pGameInterface->GetWeaponInfo(weaponSkillWeapon, WEAPONSKILL_STD); - CWeaponInfo* pPro = pGameInterface->GetWeaponInfo(weaponSkillWeapon, WEAPONSKILL_PRO); - - if (stat >= pPro->GetRequiredStatLevel()) - weaponSkill = WEAPONSKILL_PRO; - else if (stat >= pStd->GetRequiredStatLevel()) - weaponSkill = WEAPONSKILL_STD; - else - weaponSkill = WEAPONSKILL_POOR; - return true; - } - } - } + return false; } - } - return false; + stat = data->m_stats.StatTypesFloat[skillStatIdx]; + } + + CWeaponInfo* pPoor = pGameInterface->GetWeaponInfo(weaponSkillWeapon, WEAPONSKILL_POOR); + CWeaponInfo* pStd = pGameInterface->GetWeaponInfo(weaponSkillWeapon, WEAPONSKILL_STD); + CWeaponInfo* pPro = pGameInterface->GetWeaponInfo(weaponSkillWeapon, WEAPONSKILL_PRO); + CWeaponInfo* pSpec = pGameInterface->GetWeaponInfo(weaponSkillWeapon, WEAPONSKILL_SPECIAL); + if (stat >= pSpec->GetRequiredStatLevel()) + weaponSkill = WEAPONSKILL_SPECIAL; + else if (stat >= pPro->GetRequiredStatLevel()) + weaponSkill = WEAPONSKILL_PRO; + else if (stat >= pStd->GetRequiredStatLevel()) + weaponSkill = WEAPONSKILL_STD; + else + weaponSkill = WEAPONSKILL_POOR; + return true; } static void __declspec(naked) HOOK_CPed_GetWeaponSkill() diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index d0ed1f7ebc5..f902c8baec2 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -2498,6 +2498,11 @@ bool CStaticFunctionDefinitions::SetWeaponProperty(eWeaponProperty eProperty, eW pWeaponInfo->ToggleFlagBits(sData); break; } + case WEAPON_ANIM_GROUP: + { + pWeaponInfo->SetAnimGroup(sData); + break; + } default: return false; } @@ -3949,47 +3954,61 @@ bool CStaticFunctionDefinitions::SetPedStat(CElement* pElement, unsigned short u assert(pElement); // Check the stat - if (usStat < NUM_PLAYER_STATS && fValue >= 0.0f && fValue <= 1000.0f) + if (usStat > NUM_PLAYER_STATS - 1) + { + return false; + } + if (fValue < 0.0f) + { + return false; + } + if ((usStat >= 69 /* WEAPONTYPE_PISTOL_SKILL */ && usStat <= 79 /* WEAPONTYPE_SNIPERRIFLE_SKILL */) && fValue > 5000.0f) + { + return false; + } + if ((usStat < 69 /* WEAPONTYPE_PISTOL_SKILL */ || usStat > 79 /* WEAPONTYPE_SNIPERRIFLE_SKILL */) && fValue > 1000.0f) { - RUN_CHILDREN(SetPedStat(*iter, usStat, fValue)) + return false; + } - if (IS_PLAYER(pElement)) - { - CPlayer* pPlayer = static_cast(pElement); + RUN_CHILDREN(SetPedStat(*iter, usStat, fValue)) - // Dont let them set visual stats if they dont have the CJ model - if ((usStat != 21 /* FAT */ && usStat != 23 /* BODY_MUSCLE */) || pPlayer->GetModel() == 0) - { - // Save the stat - pPlayer->SetPlayerStat(usStat, fValue); + if (IS_PLAYER(pElement)) + { + CPlayer* pPlayer = static_cast(pElement); - // Notify everyone - CPlayerStatsPacket Packet; - Packet.SetSourceElement(pPlayer); - Packet.Add(usStat, fValue); - m_pPlayerManager->BroadcastOnlyJoined(Packet); + // Dont let them set visual stats if they dont have the CJ model + if ((usStat != 21 /* FAT */ && usStat != 23 /* BODY_MUSCLE */) || pPlayer->GetModel() == 0) + { + // Save the stat + pPlayer->SetPlayerStat(usStat, fValue); - return true; - } + // Notify everyone + CPlayerStatsPacket Packet; + Packet.SetSourceElement(pPlayer); + Packet.Add(usStat, fValue); + m_pPlayerManager->BroadcastOnlyJoined(Packet); + + return true; } - else if (IS_PED(pElement)) - { - CPed* pPed = static_cast(pElement); + } + else if (IS_PED(pElement)) + { + CPed* pPed = static_cast(pElement); - // Dont let them set visual stats if they dont have the CJ model - if ((usStat != 21 /* FAT */ && usStat != 23 /* BODY_MUSCLE */) || pPed->GetModel() == 0) - { - // Save the stat - pPed->SetPlayerStat(usStat, fValue); + // Dont let them set visual stats if they dont have the CJ model + if ((usStat != 21 /* FAT */ && usStat != 23 /* BODY_MUSCLE */) || pPed->GetModel() == 0) + { + // Save the stat + pPed->SetPlayerStat(usStat, fValue); - // Notify everyone - CPlayerStatsPacket Packet; - Packet.SetSourceElement(pPed); - Packet.Add(usStat, fValue); - m_pPlayerManager->BroadcastOnlyJoined(Packet); + // Notify everyone + CPlayerStatsPacket Packet; + Packet.SetSourceElement(pPed); + Packet.Add(usStat, fValue); + m_pPlayerManager->BroadcastOnlyJoined(Packet); - return true; - } + return true; } } diff --git a/Server/mods/deathmatch/logic/CWeaponStatManager.cpp b/Server/mods/deathmatch/logic/CWeaponStatManager.cpp index 0aa0aef874b..bf69a8d14ee 100644 --- a/Server/mods/deathmatch/logic/CWeaponStatManager.cpp +++ b/Server/mods/deathmatch/logic/CWeaponStatManager.cpp @@ -15,6 +15,7 @@ SFixedArray CWeaponStatManager::OriginalPoorWeaponData; SFixedArray CWeaponStatManager::OriginalNormalWeaponData; SFixedArray CWeaponStatManager::OriginalHitmanWeaponData; +SFixedArray CWeaponStatManager::OriginalSpecialWeaponData; CWeaponStatManager::CWeaponStatManager() { Init(); @@ -36,7 +37,7 @@ CWeaponStatManager::CWeaponStatManager() LoadDefault(pWeaponStat, weaponType); } - for (int skill = 0; skill < 3; skill++) + for (int skill = 0; skill < WEAPONSKILL_MAX_NUMBER; skill++) { for (int i = 0; i < NUM_WeaponInfosOtherSkill; i++) { @@ -89,21 +90,17 @@ CWeaponStat* CWeaponStatManager::GetWeaponStatsFromSkillLevel(eWeaponType type, CWeaponStat* pPoor = GetWeaponStats(type, WEAPONSKILL_POOR); CWeaponStat* pStd = GetWeaponStats(type, WEAPONSKILL_STD); CWeaponStat* pPro = GetWeaponStats(type, WEAPONSKILL_PRO); - if (pStd) - { - if (pPoor && pPro) - { - if (fSkillLevel >= pPro->GetRequiredStatLevel()) - return pPro; - else if (fSkillLevel >= pStd->GetRequiredStatLevel()) - return pStd; - else - return pPoor; - } - else - return pStd; - } - return NULL; + CWeaponStat* pSpec = GetWeaponStats(type, WEAPONSKILL_SPECIAL); + if (pSpec && fSkillLevel >= pSpec->GetRequiredStatLevel()) + return pSpec; + else if (pPro && fSkillLevel >= pPro->GetRequiredStatLevel()) + return pPro; + else if (pStd && fSkillLevel >= pStd->GetRequiredStatLevel()) + return pStd; + else if (pPoor && fSkillLevel >= pPoor->GetRequiredStatLevel()) + return pPoor; + else + return pStd; } CWeaponStat* CWeaponStatManager::GetOriginalWeaponStats(eWeaponType type, eWeaponSkill skill) @@ -1475,6 +1472,71 @@ void CWeaponStatManager::Init() OriginalHitmanWeaponData[32].aim_offset = 4; OriginalHitmanWeaponData[32].default_combo = 4; OriginalHitmanWeaponData[32].combos_available = 1; + + // 22 - Colt 45 Stat: 3 + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].weapon_range = 35.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].target_range = 30.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].accuracy = 1.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].damage = 25; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].life_span = 0.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].firing_speed = 0.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].spread = 0.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].maximum_clip_ammo = 17; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].move_speed = 1.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].flags = 28721; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim_group = 14; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].fire_type = (eFireType)1; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].model = 346; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].model2 = -1; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].weapon_slot = (eWeaponSlot)2; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].fire_offset = CVector(0.25f, 0.050000000745058f, 0.090000003576279f); + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].skill_level = (eWeaponSkill)3; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].required_skill_level = 5000; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim_loop_start = 0.20000001788139f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim_loop_stop = 0.49399998784065f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim_loop_bullet_fire = 0.20000001788139f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim2_loop_start = 0.20000001788139f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim2_loop_stop = 0.49399998784065f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim2_loop_bullet_fire = 0.20000001788139f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].anim_breakout_time = 3.3000001907349f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].radius = 0.0f; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].aim_offset = 2; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].default_combo = 4; + OriginalSpecialWeaponData[WEAPONTYPE_PISTOL].combos_available = 1; + + for (int i = WEAPONTYPE_PISTOL + 1; i <= WEAPONTYPE_EXTINGUISHER; ++i) + { + OriginalSpecialWeaponData[i].weapon_range = OriginalHitmanWeaponData[i].weapon_range; + OriginalSpecialWeaponData[i].target_range = OriginalHitmanWeaponData[i].target_range; + OriginalSpecialWeaponData[i].accuracy = OriginalHitmanWeaponData[i].accuracy; + OriginalSpecialWeaponData[i].damage = OriginalHitmanWeaponData[i].damage; + OriginalSpecialWeaponData[i].life_span = OriginalHitmanWeaponData[i].life_span; + OriginalSpecialWeaponData[i].firing_speed = OriginalHitmanWeaponData[i].firing_speed; + OriginalSpecialWeaponData[i].spread = OriginalHitmanWeaponData[i].spread; + OriginalSpecialWeaponData[i].maximum_clip_ammo = OriginalHitmanWeaponData[i].maximum_clip_ammo; + OriginalSpecialWeaponData[i].move_speed = OriginalHitmanWeaponData[i].move_speed; + OriginalSpecialWeaponData[i].flags = OriginalHitmanWeaponData[i].flags; + OriginalSpecialWeaponData[i].anim_group = OriginalHitmanWeaponData[i].anim_group; + OriginalSpecialWeaponData[i].fire_type = OriginalHitmanWeaponData[i].fire_type; + OriginalSpecialWeaponData[i].model = OriginalHitmanWeaponData[i].model; + OriginalSpecialWeaponData[i].model2 = OriginalHitmanWeaponData[i].model2; + OriginalSpecialWeaponData[i].weapon_slot = OriginalHitmanWeaponData[i].weapon_slot; + OriginalSpecialWeaponData[i].fire_offset = OriginalHitmanWeaponData[i].fire_offset; + OriginalSpecialWeaponData[i].skill_level = (eWeaponSkill)3; + OriginalSpecialWeaponData[i].required_skill_level = 5000; + OriginalSpecialWeaponData[i].anim_loop_start = OriginalHitmanWeaponData[i].anim_loop_start; + OriginalSpecialWeaponData[i].anim_loop_stop = OriginalHitmanWeaponData[i].anim_loop_stop; + OriginalSpecialWeaponData[i].anim_loop_bullet_fire = OriginalHitmanWeaponData[i].anim_loop_bullet_fire; + OriginalSpecialWeaponData[i].anim2_loop_start = OriginalHitmanWeaponData[i].anim2_loop_start; + OriginalSpecialWeaponData[i].anim2_loop_stop = OriginalHitmanWeaponData[i].anim2_loop_stop; + OriginalSpecialWeaponData[i].anim2_loop_bullet_fire = OriginalHitmanWeaponData[i].anim2_loop_bullet_fire; + OriginalSpecialWeaponData[i].anim_breakout_time = OriginalHitmanWeaponData[i].anim_breakout_time; + OriginalSpecialWeaponData[i].radius = OriginalHitmanWeaponData[i].radius; + OriginalSpecialWeaponData[i].aim_offset = OriginalHitmanWeaponData[i].aim_offset; + OriginalSpecialWeaponData[i].default_combo = OriginalHitmanWeaponData[i].default_combo; + OriginalSpecialWeaponData[i].combos_available = OriginalHitmanWeaponData[i].combos_available; + } + // End of Skill Level Weapons } @@ -1521,6 +1583,40 @@ bool CWeaponStatManager::LoadDefault(CWeaponStat* pDest, eWeaponType weaponType, pDest->SetCombosAvailable(OriginalPoorWeaponData[iVal].combos_available); break; } + case WEAPONSKILL_STD: + { + pDest->SetWeaponSkillLevel(weaponSkill); + pDest->SetWeaponRange(OriginalNormalWeaponData[iVal].weapon_range); + pDest->SetTargetRange(OriginalNormalWeaponData[iVal].target_range); + pDest->SetAccuracy(OriginalNormalWeaponData[iVal].accuracy); + pDest->SetDamagePerHit(OriginalNormalWeaponData[iVal].damage); + pDest->SetLifeSpan(OriginalNormalWeaponData[iVal].life_span); + pDest->SetFiringSpeed(OriginalNormalWeaponData[iVal].firing_speed); + pDest->SetSpread(OriginalNormalWeaponData[iVal].spread); + pDest->SetMaximumClipAmmo(OriginalNormalWeaponData[iVal].maximum_clip_ammo); + pDest->SetMoveSpeed(OriginalNormalWeaponData[iVal].move_speed); + pDest->SetFlags(OriginalNormalWeaponData[iVal].flags); + pDest->SetAnimGroup(OriginalNormalWeaponData[iVal].anim_group); + pDest->SetFireType(OriginalNormalWeaponData[iVal].fire_type); + pDest->SetModel(OriginalNormalWeaponData[iVal].model); + pDest->SetModel2(OriginalNormalWeaponData[iVal].model2); + pDest->SetSlot(OriginalNormalWeaponData[iVal].weapon_slot); + pDest->SetFireOffset(&OriginalNormalWeaponData[iVal].fire_offset); + pDest->SetSkill(OriginalNormalWeaponData[iVal].skill_level); + pDest->SetRequiredStatLevel(OriginalNormalWeaponData[iVal].required_skill_level); + pDest->SetWeaponAnimLoopStart(OriginalNormalWeaponData[iVal].anim_loop_start); + pDest->SetWeaponAnimLoopStop(OriginalNormalWeaponData[iVal].anim_loop_stop); + pDest->SetWeaponAnimLoopFireTime(OriginalNormalWeaponData[iVal].anim_loop_bullet_fire); + pDest->SetWeaponAnim2LoopStart(OriginalNormalWeaponData[iVal].anim2_loop_start); + pDest->SetWeaponAnim2LoopStop(OriginalNormalWeaponData[iVal].anim2_loop_stop); + pDest->SetWeaponAnim2LoopFireTime(OriginalNormalWeaponData[iVal].anim2_loop_bullet_fire); + pDest->SetWeaponAnimBreakoutTime(OriginalNormalWeaponData[iVal].anim_breakout_time); + pDest->SetWeaponRadius(OriginalNormalWeaponData[iVal].radius); + pDest->SetAimOffsetIndex(OriginalNormalWeaponData[iVal].aim_offset); + pDest->SetDefaultCombo(OriginalNormalWeaponData[iVal].default_combo); + pDest->SetCombosAvailable(OriginalNormalWeaponData[iVal].combos_available); + break; + } case WEAPONSKILL_PRO: { pDest->SetWeaponSkillLevel(weaponSkill); @@ -1555,38 +1651,38 @@ bool CWeaponStatManager::LoadDefault(CWeaponStat* pDest, eWeaponType weaponType, pDest->SetCombosAvailable(OriginalHitmanWeaponData[iVal].combos_available); break; } - case WEAPONSKILL_STD: + case WEAPONSKILL_SPECIAL: { pDest->SetWeaponSkillLevel(weaponSkill); - pDest->SetWeaponRange(OriginalNormalWeaponData[iVal].weapon_range); - pDest->SetTargetRange(OriginalNormalWeaponData[iVal].target_range); - pDest->SetAccuracy(OriginalNormalWeaponData[iVal].accuracy); - pDest->SetDamagePerHit(OriginalNormalWeaponData[iVal].damage); - pDest->SetLifeSpan(OriginalNormalWeaponData[iVal].life_span); - pDest->SetFiringSpeed(OriginalNormalWeaponData[iVal].firing_speed); - pDest->SetSpread(OriginalNormalWeaponData[iVal].spread); - pDest->SetMaximumClipAmmo(OriginalNormalWeaponData[iVal].maximum_clip_ammo); - pDest->SetMoveSpeed(OriginalNormalWeaponData[iVal].move_speed); - pDest->SetFlags(OriginalNormalWeaponData[iVal].flags); - pDest->SetAnimGroup(OriginalNormalWeaponData[iVal].anim_group); - pDest->SetFireType(OriginalNormalWeaponData[iVal].fire_type); - pDest->SetModel(OriginalNormalWeaponData[iVal].model); - pDest->SetModel2(OriginalNormalWeaponData[iVal].model2); - pDest->SetSlot(OriginalNormalWeaponData[iVal].weapon_slot); - pDest->SetFireOffset(&OriginalNormalWeaponData[iVal].fire_offset); - pDest->SetSkill(OriginalNormalWeaponData[iVal].skill_level); - pDest->SetRequiredStatLevel(OriginalNormalWeaponData[iVal].required_skill_level); - pDest->SetWeaponAnimLoopStart(OriginalNormalWeaponData[iVal].anim_loop_start); - pDest->SetWeaponAnimLoopStop(OriginalNormalWeaponData[iVal].anim_loop_stop); - pDest->SetWeaponAnimLoopFireTime(OriginalNormalWeaponData[iVal].anim_loop_bullet_fire); - pDest->SetWeaponAnim2LoopStart(OriginalNormalWeaponData[iVal].anim2_loop_start); - pDest->SetWeaponAnim2LoopStop(OriginalNormalWeaponData[iVal].anim2_loop_stop); - pDest->SetWeaponAnim2LoopFireTime(OriginalNormalWeaponData[iVal].anim2_loop_bullet_fire); - pDest->SetWeaponAnimBreakoutTime(OriginalNormalWeaponData[iVal].anim_breakout_time); - pDest->SetWeaponRadius(OriginalNormalWeaponData[iVal].radius); - pDest->SetAimOffsetIndex(OriginalNormalWeaponData[iVal].aim_offset); - pDest->SetDefaultCombo(OriginalNormalWeaponData[iVal].default_combo); - pDest->SetCombosAvailable(OriginalNormalWeaponData[iVal].combos_available); + pDest->SetWeaponRange(OriginalSpecialWeaponData[iVal].weapon_range); + pDest->SetTargetRange(OriginalSpecialWeaponData[iVal].target_range); + pDest->SetAccuracy(OriginalSpecialWeaponData[iVal].accuracy); + pDest->SetDamagePerHit(OriginalSpecialWeaponData[iVal].damage); + pDest->SetLifeSpan(OriginalSpecialWeaponData[iVal].life_span); + pDest->SetFiringSpeed(OriginalSpecialWeaponData[iVal].firing_speed); + pDest->SetSpread(OriginalSpecialWeaponData[iVal].spread); + pDest->SetMaximumClipAmmo(OriginalSpecialWeaponData[iVal].maximum_clip_ammo); + pDest->SetMoveSpeed(OriginalSpecialWeaponData[iVal].move_speed); + pDest->SetFlags(OriginalSpecialWeaponData[iVal].flags); + pDest->SetAnimGroup(OriginalSpecialWeaponData[iVal].anim_group); + pDest->SetFireType(OriginalSpecialWeaponData[iVal].fire_type); + pDest->SetModel(OriginalSpecialWeaponData[iVal].model); + pDest->SetModel2(OriginalSpecialWeaponData[iVal].model2); + pDest->SetSlot(OriginalSpecialWeaponData[iVal].weapon_slot); + pDest->SetFireOffset(&OriginalSpecialWeaponData[iVal].fire_offset); + pDest->SetSkill(OriginalSpecialWeaponData[iVal].skill_level); + pDest->SetRequiredStatLevel(OriginalSpecialWeaponData[iVal].required_skill_level); + pDest->SetWeaponAnimLoopStart(OriginalSpecialWeaponData[iVal].anim_loop_start); + pDest->SetWeaponAnimLoopStop(OriginalSpecialWeaponData[iVal].anim_loop_stop); + pDest->SetWeaponAnimLoopFireTime(OriginalSpecialWeaponData[iVal].anim_loop_bullet_fire); + pDest->SetWeaponAnim2LoopStart(OriginalSpecialWeaponData[iVal].anim2_loop_start); + pDest->SetWeaponAnim2LoopStop(OriginalSpecialWeaponData[iVal].anim2_loop_stop); + pDest->SetWeaponAnim2LoopFireTime(OriginalSpecialWeaponData[iVal].anim2_loop_bullet_fire); + pDest->SetWeaponAnimBreakoutTime(OriginalSpecialWeaponData[iVal].anim_breakout_time); + pDest->SetWeaponRadius(OriginalSpecialWeaponData[iVal].radius); + pDest->SetAimOffsetIndex(OriginalSpecialWeaponData[iVal].aim_offset); + pDest->SetDefaultCombo(OriginalSpecialWeaponData[iVal].default_combo); + pDest->SetCombosAvailable(OriginalSpecialWeaponData[iVal].combos_available); break; } default: diff --git a/Server/mods/deathmatch/logic/CWeaponStatManager.h b/Server/mods/deathmatch/logic/CWeaponStatManager.h index 61ef6db791b..602f3958265 100644 --- a/Server/mods/deathmatch/logic/CWeaponStatManager.h +++ b/Server/mods/deathmatch/logic/CWeaponStatManager.h @@ -99,4 +99,5 @@ class CWeaponStatManager static SFixedArray OriginalPoorWeaponData; static SFixedArray OriginalNormalWeaponData; static SFixedArray OriginalHitmanWeaponData; + static SFixedArray OriginalSpecialWeaponData; }; diff --git a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index ffe4133f790..951c0d94e30 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -229,6 +229,7 @@ IMPLEMENT_ENUM_BEGIN(eWeaponSkill) ADD_ENUM(WEAPONSKILL_POOR, "poor") ADD_ENUM(WEAPONSKILL_STD, "std") ADD_ENUM(WEAPONSKILL_PRO, "pro") +ADD_ENUM(WEAPONSKILL_SPECIAL, "special") IMPLEMENT_ENUM_END("weapon-skill") IMPLEMENT_ENUM_BEGIN(eWeaponState) diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Weapon.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Weapon.cpp index de986285805..691391bc170 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Weapon.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Weapon.cpp @@ -693,6 +693,7 @@ int CLuaFunctionDefs::SetWeaponProperty(lua_State* luaVM) case WEAPON_DAMAGE: case WEAPON_MAX_CLIP_AMMO: case WEAPON_FLAGS: + case WEAPON_ANIM_GROUP: { int sWeaponInfo = 0; argStream.ReadNumber(sWeaponInfo); diff --git a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp index aceac1b129f..32e29af87e7 100644 --- a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp @@ -297,6 +297,23 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const WeaponProperty.data.anim2_loop_bullet_fire = pWeaponStat->GetWeaponAnim2LoopFireTime(); WeaponProperty.data.anim_breakout_time = pWeaponStat->GetWeaponAnimBreakoutTime(); + + WeaponProperty.data.anim_group = pWeaponStat->GetAnimGroup(); + WeaponProperty.data.fire_type = pWeaponStat->GetFireType(); + WeaponProperty.data.model = pWeaponStat->GetModel(); + WeaponProperty.data.model2 = pWeaponStat->GetModel2(); + WeaponProperty.data.weapon_slot = pWeaponStat->GetSlot(); + WeaponProperty.data.fire_offset = *pWeaponStat->GetFireOffset(); + WeaponProperty.data.skill_level = pWeaponStat->GetSkill(); + WeaponProperty.data.required_skill_level = pWeaponStat->GetRequiredStatLevel(); + WeaponProperty.data.firing_speed = pWeaponStat->GetFiringSpeed(); + WeaponProperty.data.radius = pWeaponStat->GetRadius(); + WeaponProperty.data.life_span = pWeaponStat->GetLifeSpan(); + WeaponProperty.data.spread = pWeaponStat->GetSpread(); + WeaponProperty.data.aim_offset = pWeaponStat->GetAimOffsetIndex(); + WeaponProperty.data.default_combo = pWeaponStat->GetDefaultCombo(); + WeaponProperty.data.combos_available = pWeaponStat->GetCombosAvailable(); + BitStream.Write(&WeaponProperty); BitStream.WriteBit(g_pGame->GetJetpackWeaponEnabled((eWeaponType)i)); @@ -306,7 +323,7 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const { sWeaponPropertySync WeaponProperty; BitStream.WriteBit(true); - for (int j = 0; j <= 2; j++) + for (int j = 0; j <= 3; j++) { CWeaponStat* pWeaponStat = g_pGame->GetWeaponStatManager()->GetWeaponStats((eWeaponType)i, (eWeaponSkill)j); WeaponProperty.data.weaponType = (int)pWeaponStat->GetWeaponType(); @@ -327,6 +344,23 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const WeaponProperty.data.anim2_loop_bullet_fire = pWeaponStat->GetWeaponAnim2LoopFireTime(); WeaponProperty.data.anim_breakout_time = pWeaponStat->GetWeaponAnimBreakoutTime(); + + WeaponProperty.data.anim_group = pWeaponStat->GetAnimGroup(); + WeaponProperty.data.fire_type = pWeaponStat->GetFireType(); + WeaponProperty.data.model = pWeaponStat->GetModel(); + WeaponProperty.data.model2 = pWeaponStat->GetModel2(); + WeaponProperty.data.weapon_slot = pWeaponStat->GetSlot(); + WeaponProperty.data.fire_offset = *pWeaponStat->GetFireOffset(); + WeaponProperty.data.skill_level = pWeaponStat->GetSkill(); + WeaponProperty.data.required_skill_level = pWeaponStat->GetRequiredStatLevel(); + WeaponProperty.data.firing_speed = pWeaponStat->GetFiringSpeed(); + WeaponProperty.data.radius = pWeaponStat->GetRadius(); + WeaponProperty.data.life_span = pWeaponStat->GetLifeSpan(); + WeaponProperty.data.spread = pWeaponStat->GetSpread(); + WeaponProperty.data.aim_offset = pWeaponStat->GetAimOffsetIndex(); + WeaponProperty.data.default_combo = pWeaponStat->GetDefaultCombo(); + WeaponProperty.data.combos_available = pWeaponStat->GetCombosAvailable(); + BitStream.Write(&WeaponProperty); } diff --git a/Shared/sdk/net/SyncStructures.h b/Shared/sdk/net/SyncStructures.h index 8c3276be531..ddbd0cf3b16 100644 --- a/Shared/sdk/net/SyncStructures.h +++ b/Shared/sdk/net/SyncStructures.h @@ -2372,7 +2372,23 @@ struct sWeaponPropertySync : public ISyncStructure bitStream.Read(data.nAmmo) && bitStream.Read(data.nDamage) && bitStream.Read(data.fAccuracy) && bitStream.Read(data.fMoveSpeed) && bitStream.Read(data.anim_loop_start) && bitStream.Read(data.anim_loop_stop) && bitStream.Read(data.anim_loop_bullet_fire) && bitStream.Read(data.anim2_loop_start) && bitStream.Read(data.anim2_loop_stop) && bitStream.Read(data.anim2_loop_bullet_fire) && - bitStream.Read(data.anim_breakout_time)) + bitStream.Read(data.anim_breakout_time) && + + bitStream.Read(data.anim_group) && + bitStream.Read(data.fire_type) && + bitStream.Read(data.model) && + bitStream.Read(data.model2) && + bitStream.Read(data.weapon_slot) && + bitStream.Read(data.fire_offset.fX) && bitStream.Read(data.fire_offset.fY) && bitStream.Read(data.fire_offset.fZ) && + bitStream.Read(data.skill_level) && + bitStream.Read(data.required_skill_level) && + bitStream.Read(data.firing_speed) && + bitStream.Read(data.radius) && + bitStream.Read(data.life_span) && + bitStream.Read(data.spread) && + bitStream.Read(data.aim_offset) && + bitStream.Read(data.default_combo) && + bitStream.Read(data.combos_available)) return true; return false; @@ -2396,6 +2412,22 @@ struct sWeaponPropertySync : public ISyncStructure bitStream.Write(data.anim2_loop_stop); bitStream.Write(data.anim2_loop_bullet_fire); bitStream.Write(data.anim_breakout_time); + + bitStream.Write(data.anim_group); + bitStream.Write(data.fire_type); + bitStream.Write(data.model); + bitStream.Write(data.model2); + bitStream.Write(data.weapon_slot); + bitStream.Write(data.fire_offset.fX); bitStream.Write(data.fire_offset.fY); bitStream.Write(data.fire_offset.fZ); + bitStream.Write(data.skill_level); + bitStream.Write(data.required_skill_level); + bitStream.Write(data.firing_speed); + bitStream.Write(data.radius); + bitStream.Write(data.life_span); + bitStream.Write(data.spread); + bitStream.Write(data.aim_offset); + bitStream.Write(data.default_combo); + bitStream.Write(data.combos_available); } struct @@ -2420,7 +2452,24 @@ struct sWeaponPropertySync : public ISyncStructure FLOAT anim2_loop_stop; // end of animation2 loop FLOAT anim2_loop_bullet_fire; // time in animation2 when weapon should be fired - FLOAT anim_breakout_time; // time after which player can break out of attack and run off + FLOAT anim_breakout_time; // time after which player can break out of attack and run off + + DWORD anim_group; + + DWORD fire_type; + int model; + int model2; + DWORD weapon_slot; + CVector fire_offset; + BYTE skill_level; + int required_skill_level; + float firing_speed; + float radius; + float life_span; + float spread; + short aim_offset; + BYTE default_combo; + BYTE combos_available; } data; };