public virtual void OnDamage(Networking.GameDataHandler handler) { bool isPlayer = handler.GetBool(2); byte targetId = handler.GetByte(3); Entities.Player p = null; try { handler.Room.Players.TryGetValue(targetId, out p); } catch { p = null; } if (p != null) { string weaponCode = handler.GetString(22).ToUpper(); if (weaponCode.Length == 4) { if (isPlayer) { Objects.Items.ItemData itemData = null; try { itemData = Managers.ItemManager.Instance.Items.Values.Where(n => n.Code == weaponCode).First(); } catch { itemData = null; } if (itemData != null && itemData.IsWeapon) { Objects.Items.Weapon weapon = (Objects.Items.Weapon)itemData; if (weapon != null) { Objects.Inventory.Item item = handler.Player.User.Inventory.Equipment.Get(handler.Player.Class, weaponCode); if (item != null) { if (handler.Player.IsAlive && handler.Player.Health > 0) { if (p.IsAlive && p.Health > 0) { uint boneId = handler.GetuInt(11); if (boneId > 0) { byte realBoneId = 0; bool head = false; short remainingHealth = 0; bool useRadius = handler.GetBool(10); ushort previousHealth = p.Health; short damageTaken = 0; if (!useRadius) { switch ((boneId - handler.Player.User.SessionID)) { case 1237: { realBoneId = 0; // Head head = true; break; } case 1239: { realBoneId = 1; // Chest break; } case 1241: { realBoneId = 2; break; } default: { Log.Instance.WriteLine("Unknown Bone :: " + (boneId - handler.Player.User.SessionID) + " :: " + boneId); //handler.Player.User.Disconnect(); break; } } damageTaken = (short)((float)weapon.Power * ((float)weapon.PowerPersonal[realBoneId] / 100)); } else { damageTaken = (short)((1000 / 100) * boneId); } if (handler.Room.Mode != Enums.Mode.Free_For_All && handler.Player.Team == p.Team) { damageTaken = 0; } remainingHealth = (short)((short)p.Health - damageTaken); if (remainingHealth < 0) { damageTaken = (short)p.Health; } if (remainingHealth <= 0) { handler.type = Enums.GameSubs.PlayerDeath; p.AddDeaths(); handler.Player.AddKill(head); OnDeath(handler.Player, p); } else { p.Health -= (ushort)damageTaken; } handler.Set(12, p.Health); handler.Set(13, previousHealth); handler.respond = true; //System.Log.Instance.WriteLine("DAMAGE :: " + handler.Player.User.Displayname + " -> " + p.User.Displayname + ": " + damageTaken); } else { handler.Player.User.Disconnect(); } } } } else { handler.Player.User.Disconnect(); } } else { handler.Player.User.Disconnect(); } } else { handler.Player.User.Disconnect(); } } else { handler.Player.User.Disconnect(); } } } }
public virtual void OnObjectDamage(Networking.GameDataHandler handler) { bool _isPlayer = handler.GetBool(2); byte _objectDamagedId = handler.GetByte(3); bool _isSubWeapon = handler.GetBool(9); bool _isRadiusWeapon = handler.GetBool(10); uint _radius = handler.GetuInt(11); //vehicles don´t seem to have a hitbox string _weaponCode = handler.GetString(22).ToUpper(); short _damageTaken = 0; Entities.Player Attacker = handler.Player; Entities.Vehicle VehicleDamaged = null; Objects.Items.Weapon Weapon = null; try { VehicleDamaged = Room.Vehicles[_objectDamagedId]; } catch { VehicleDamaged = null; Log.Instance.WriteError("Unknown damaged object with ID: " + _objectDamagedId.ToString()); } if (VehicleDamaged != null && CanInFlictDamageTo(Attacker, VehicleDamaged)) { if (_isPlayer) { try { Weapon = (Objects.Items.Weapon)Managers.ItemManager.Instance.Items.Values.Where(n => n.Code == _weaponCode).First(); } catch { Weapon = null; } if (Weapon != null) { short _weaponMultiplier = 100; switch (VehicleDamaged.VehicleClass) { case VehicleType.Surface: _weaponMultiplier = Weapon.PowerSurface[0]; break; case VehicleType.Air: _weaponMultiplier = Weapon.PowerAir[0]; break; case VehicleType.Ship: _weaponMultiplier = Weapon.PowerShip[0]; break; default: _weaponMultiplier = Weapon.PowerPersonal[0]; break; } _damageTaken = DamageCalculator(Weapon.Power, _weaponMultiplier, _radius); } } else //Vehicle attaking other vehicle { if (Attacker.VehicleId != -1) { Entities.Vehicle AttackerVehicle = Room.Vehicles[Attacker.VehicleId]; if (_weaponCode == AttackerVehicle.Code) //dont trust the client { Objects.VehicleSeat Seat = AttackerVehicle.Seats[AttackerVehicle.GetSeatOf(Attacker)]; Objects.VehicleWeapon VehWeapon = null; if (_isSubWeapon) //he is shooting with the subCT { Seat.Weapons.TryGetValue(VehicleWeaponType.Sub, out VehWeapon); } else { Seat.Weapons.TryGetValue(VehicleWeaponType.Main, out VehWeapon); } if (VehWeapon != null) { _damageTaken = DamageCalculator((short)VehWeapon.Damage, VehWeapon.HitBox[(byte)VehicleDamaged.VehicleClass], _radius); } } } else //maybe it´s an artillery attack { if (!isValidArtilleryAttack(Attacker)) { Attacker.User.Disconnect(); } Objects.VehicleWeapon Artillery = Managers.VehicleManager.Instance.GetWeaponBy(_weaponCode); if (Artillery != null) { _damageTaken = DamageCalculator((short)Artillery.Damage, Artillery.HitBox[(byte)VehicleDamaged.VehicleClass], _radius); } else { Log.Instance.WriteError("Couldn´t find artillery weapon " + _weaponCode + " in the Manager"); } } } DamageVehicle(handler, Attacker, VehicleDamaged, _damageTaken); } }
public virtual void OnDamage(Networking.GameDataHandler handler) { bool _isPlayer = handler.GetBool(2); byte _targetId = handler.GetByte(3); bool _isRadiusWeapon = handler.GetBool(10); uint _boneId = handler.GetuInt(11); string _weaponCode = handler.GetString(22).ToUpper(); //Radius is used when _isradiusWeapon is true. Values range from 0 to 100 uint _radius = _boneId; Entities.Player Victim = null; Entities.Player Attacker = handler.Player; try { handler.Room.Players.TryGetValue(_targetId, out Victim); } catch { Victim = null; } if (Victim != null) { if (_isPlayer) { Objects.Items.ItemData ItemData = null; try { ItemData = Managers.ItemManager.Instance.Items.Values.Where(n => n.Code == _weaponCode).First(); } catch { ItemData = null; } if (ItemData != null && ItemData.IsWeapon) { Objects.Items.Weapon Weapon = (Objects.Items.Weapon)ItemData; Objects.Inventory.Item PlayerItem = Attacker.User.Inventory.Equipment.Get(handler.Player.Class, _weaponCode); if (PlayerItem != null) //player have the wep { if (CanInFlictDamageTo(Attacker, Victim)) { uint _realBoneId = _boneId - handler.Player.User.SessionID; bool _isHeadShot = false; short _damageTaken = 0; double _hitboxMultiplier = 1.0; Enums.Hitbox Location; try { Location = (Hitbox)_realBoneId; } catch { Location = Hitbox.TorsoLimbs; } if (Location == Hitbox.HeadNeck && !Weapon.Code.Contains("DA") && !Weapon.Code.Contains("DJ") && !Weapon.Code.Contains("DK")) { _isHeadShot = true; } #region Explanation to the DJ03 case //RPG-7 vanilla behaviour requires some tweaks... our reverse-engineered damage calc. is not consistent //with vanilla in-game experience suggesting some more shit is going on //server side //SO... most DJ-DK weapons have reduced personal hitMult. in the DB... consistent with gamefiles and damage calc. //but RPG-7 #endregion if (!_isRadiusWeapon) { if (Weapon.Code == "DJ03") { _damageTaken = 1000; } else { _hitboxMultiplier = GetHitBoxMultiplier(Location); _damageTaken = DamageCalculator(Weapon.Power, Weapon.PowerPersonal[0], _hitboxMultiplier, 100); } } else { _damageTaken = DamageCalculator(Weapon.Power, Weapon.PowerPersonal[0], 1.0, _radius); } DamagePlayer(handler, Attacker, Victim, _damageTaken, _isHeadShot); } } // else // Attacker.User.Disconnect(); ---> Commented out because of client bug with knifes } } else //a vehicle attacked our poor player :( { OnVehicleAttackToPlayer(handler, Attacker, Victim); } } }
private void OnVehicleAttackToPlayer(Networking.GameDataHandler handler, Entities.Player Attacker, Entities.Player Victim) { Entities.Vehicle AttackerVehicle = null; string _vehicleId = handler.GetString(22).ToUpper(); try { AttackerVehicle = handler.Room.Vehicles[Attacker.VehicleId]; } catch { AttackerVehicle = null; } if (AttackerVehicle != null) { if (CanInFlictDamageTo(Attacker, Victim) && IsOperative(AttackerVehicle)) { if (_vehicleId == AttackerVehicle.Code) { Objects.VehicleSeat Seat = AttackerVehicle.Seats[Attacker.VehicleSeatId]; if (Seat.Weapons.Count > 0) { byte _weaponSlot = handler.GetByte(9); //0 = main CT, 1 = subCT Objects.VehicleWeapon Weapon = null; Seat.Weapons.TryGetValue((VehicleWeaponType)_weaponSlot, out Weapon); if (Weapon != null) { //Most vehicles uses Radius even for machineguns... yeah odd short _damageTaken = 0; double _hitboxMultiplier = 1.0; bool _useRadius = handler.GetBool(10); uint _boneId = handler.GetuInt(11); uint _radius = _boneId; uint _realBoneId = _boneId - handler.Player.User.SessionID; //just to make sure... if (!_useRadius) { Enums.Hitbox Location; try { Location = (Hitbox)_realBoneId; } catch { Location = Hitbox.TorsoLimbs; } _hitboxMultiplier = GetHitBoxMultiplier(Location); _radius = 100; } _damageTaken = DamageCalculator((short)Weapon.Damage, Weapon.HitBox[(byte)VehWeapDamType.Personal], _radius); DamagePlayer(handler, Attacker, Victim, _damageTaken, false); } } } } } else //Artillery Attack? { Objects.VehicleWeapon Artillery = null; Artillery = Managers.VehicleManager.Instance.GetWeaponBy(handler.GetString(22).ToUpper()); if (Artillery != null && isValidArtilleryAttack(Attacker)) { uint _radius = handler.GetuInt(11); short _damageTaken = DamageCalculator((short)Artillery.Damage, Artillery.HitBox[(byte)VehWeapDamType.Personal], _radius); DamagePlayer(handler, Attacker, Victim, _damageTaken, false); } else { Attacker.User.Disconnect(); } } }