using System.Reflection.Metadata.Ecma335; namespace Supercell.Laser.Logic.Battle.Objects { using System; using Supercell.Laser.Logic.Message.Home; using System.Collections.Generic; using System.Data.Common; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.SymbolStore; using System.Globalization; using System.Net.Http.Headers; using System.Numerics; using System.Reflection.Metadata; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Security.Cryptography; using System.Xml.Linq; using DeenGames.Utils; using DeenGames.Utils.AStarPathFinder; using Supercell.Laser.Logic.Message.Account.Auth; using Supercell.Laser.Logic.Battle.Component; using Supercell.Laser.Logic.Battle.Level; using Supercell.Laser.Logic.Battle.Structures; using Supercell.Laser.Logic.Data; using Supercell.Laser.Logic.Home.Items; using Supercell.Laser.Logic.Util; using Supercell.Laser.Titan.DataStream; using Supercell.Laser.Titan.Debug; using Supercell.Laser.Titan.Math; using static System.Net.Mime.MediaTypeNames; using Supercell.Laser.Logic.Message.Account; using Supercell.Laser.Logic.Command.Home; using System.Runtime.Serialization; using System.ComponentModel; using System.Reflection; // using System.Diagnostics; public class DamageNumber { public int Delay; public int Value; public int Dealer; public DamageNumber(int value, int dealerIndex, int delay) { Dealer = dealerIndex; Value = value; Delay = delay; } } public class Character : GameObject { public const int MAX_HOLD_TICKS = 15; public const int INTRO_TICKS = 100; public const int DAMAGE_NUMBERS_DELAY_TICKS = 2; public const int DEPLOY_TICKS_FIRST_SPAWN = 4; public const int DEPLOY_TICKS = 19; public int ForcedAngleTicks; public CardData StarPowerData => GetPlayer() == null ? null : GetPlayer().StarPowerData; public int m_hitpoints; public int m_maxHitpoints; public int OrginalMaxHP; public int MapHeight => GameObjectManager.GetBattle().GetTileMap().LogicHeight; public int MapWidth => GameObjectManager.GetBattle().GetTileMap().LogicWidth; public int int344; public int dword348; public int State; public int MoveAngle; public int AttackAngle; public bool UltiSkill; public bool IsControlled; public int Shaking; public bool IsInvincible; public bool m_usingUltiCurrently; public bool ShouldExecuteColetteChargeOnReturn; public LogicVector2 WayPoint2 = new LogicVector2(); public LogicVector2 WayPoint; public LogicVector2 WayPointStart; public LogicVector2 PosDelta; public LogicVector2 MovementVector = new LogicVector2(); public int MoveStart; public int MoveEnd; public int PathLength; private int HealthRegenBlockedTick; public int m_lastSelfHealTick; public int BulletIndex; public int PrevY; public int PrevX; public bool YellowEye = false; public int VisibilityState = 0; public int InvisibleTicks = 0; public bool IsInvisible = false; public int SeeInvisibilityDistance = 0; public bool BreakInvisibilityOnAttack = false; public int SpawnTick; public AreaEffectData ChargeAreaEffectData; public bool KnockBacked; public bool Knockback1; public bool Knockback2; public bool Knockback3; public bool m_BoostSet; public int ExtraRegenAmount; public int ExtraRegenTicks; public int ExtraRegenerIndex; public int HealthRegenedTick; public int HealthRegenedTickSP; public int ReloadBuffTicks; public AreaEffect AreaEffect; public int ChargeUpType; public int ChargeUp; public int ChargeUpMax; public bool MeleeAttackPushBacks; public int MeleeAttackPushBack; public int ConsumableShield; public int ConsumableShieldMax; public int ConsumableShieldTick; public int ConsumableShieldDuration; private int BlinkX; private int BlinkY; private GameObject DraggingObject; private int DraggingOffsetX; private int DraggingOffsetY; public bool StarPowerIC; public int AutoAttackDamangeBoost; public int DeployedTick; public int StarPowerProjectileTimer; public int ParentGID; public int HitEffectAngle; public int HitEffectProjectile; public int HitEffectSkin; public int StaticSpeedBuff; public int AoeRegenerate; public bool IsCrippled; public int CripplePercent; public int CrippleEndTick; public bool ChargeBreaksEnvironment; public int CastingTime; public bool TransformAnimation; public int SteerAngle; public int SteerStartTicks; public int AutoUltiChargeTimer; public int CcImmunityTicks; public int ChargedShotCount; public int ChargedShotMisses; public int RunningChargingUlti; public bool IsWeaklyStunned; public int JesterSkillCount; public int ItemPickedUpTick; public int UltiButtonPressedTimes; public bool DisplayUltiTmp; public int ViusalChargeType; public int VisionOverrideX; public int VisionOverrideY; public int VisionOverrideTicks; public int AshLastRageTick; public bool Attacking; public Character AutoAttackTarget; public int AutoAttackSpeedMs; public int AFKTicks; public int SkillHoldTicks; public int RapidFireTick; public List m_buffs; public List DamageNumbers; public List ChargeHitGIDs; public List FangHitGIDs; public Accessory Accessory => GetPlayer() == null ? null : GetPlayer().Accessory; public bool IsTeleporting; public BattlePlayer PreviousPlayer; public bool Ultiing; public List m_skills; public List Immunitys; private int m_itemCount; public int BattleRoyaleBuffs = 0; public AreaEffect RealmEffect; public CharacterData SummonedCharacter; public ItemData SpawnedItem; public int NumSpawns; public int NumSpawnsItem; public int MaxSpawns; public int MaxSpawnsItem; public int SpawnDamage; public int SpawnedItemDamage; public int SpawnedItemNormalDMG; public int SpawnHealth; public int m_heroLevel; public int LeftHand; public int AttackOffsetX; public int AttackOffsetY; public int AttackOffset2X; public int AttackOffset2Y; public LogicVector2 AttackVector; public LogicVector2 AttackTarget; public int ProjectileShieldAngle; public int ProjectileShieldScale; public int ProjectileShieldCoolDown; public int RapidFireX; public int RapidFireY; public int RapidFireDamage; public int RapidFireNormalDMG; public int RapidFireAttackPattern; public int RapidFireRange; public int RapidFireSpread; public ProjectileData RapidFireProjectile; public ProjectileData SkinProjectileData; public int RapidFireBulletsPerShoot; public int RapidFireMsBetweenAttacks; public int RapidFireShootTimes; public int RapidFireRepeatX; public int RapidFireRepeatY; public bool IsRapidFireHeld; public int RapidFireRepeatTick; public int ShootIndex; public int slowingModifier; public int AcceleratingModifier; public int DamageModifier; public int RealmTimer; public int m_isBot; public int m_ticksSinceBotEnemyCheck = 100; public int m_lastAIAttackTick; public int m_lastUltiTick; public int m_lastBotPosX; public int m_lastBotPosY; public int m_lastBotMoveTick; public int m_botStuckTicks; public int m_botDetourX; public int m_botDetourY; public int m_botDetourUntil; public bool m_botHadPathThisTick; public int m_botState; public int m_botStateUntil; public int m_botWanderX; public int m_botWanderY; public int m_botWanderUntil; public int m_botStrafeDir; public int m_botLastHp; public int m_botReactionDelay; public int m_botTeamingWith = -1; public int m_botTeamingUntil; private Character m_closestEnemy; private LogicVector2 m_closestEnemyPosition; public int m_activeChargeType; public int ChargeHits; public int FangUltiCount; public bool IsCharging; public int ChargeSpeed; public int ChargePushback; public int ChargeAnimation; public int ChargeDamage; public int ChargeNormalDMG; public int ChargePercentDamage; private int m_stunTicks; private int m_destructafterticks; public int m_damageMultiplier; private int m_lastTileDamageTick; private int ShieldTicks; private int ShieldPercent; private int m_attackingTicks; public int LastAttckTick; public List Poisons; public int PartialStunPromille; public int TicksSincePartialStun; public LogicVector2 m_chargestart; public AreaEffect CharacterAreaEffect; public AreaEffect tms; public int TransformationState; public bool IsRage; public int PassiveCounter; public int PassiveCounter2; public Gear Gear1; public Gear Gear2; public CharacterData CharacterData; public bool TaraGadget; public int PiperTick; public bool SamState; public bool ImmunToPushbackOutOfWalls; public bool IsReviverUlti; public int AttackAcceleratingFactor; public bool StopAI; public bool IsOvercharged; public bool BigState; public bool CanHeal; public bool IsHealer; public double FrozenPercentage; public bool Slippery; public int SlipperyTicks; public int FrozenDecayTick; public int SpeedX; public int SpeedY; public int LastFrozenTick; public bool IsMovementControlDisabled; public bool Silence; public int SilenceTick; public int PortalTicks; public bool RedCharacter; public bool IsWillowControl; public Character ControlledCharacter; public bool SplitterLegsActive; public bool Tagged; public int LastTagTick; public bool IsFirstTag; public bool Attached; public Character AttachedCharacter; public bool IsDragging; public Character CarringCharacter; private List _spawnedEffects = new(); private int _lastX = -1; private int _lastY = -1; public bool SamuraiAttackSlashAttack; public string NextAttackModifier { get; set; } public Accessory ActiveNextAttackGadget { get; set; } public int CarryablePersonImunTicks = 0; public int LastPickupPlayerIndex; public int LastPickupPlayerIndexTOCHNO; public int CarryablePickTicks; public Character(CharacterData characterData) : base(characterData) { CharacterData = characterData; DamageNumbers = new List(); m_skills = new List(); m_buffs = new List(); PosDelta = new LogicVector2(); WayPoint = new LogicVector2(); WayPointStart = new LogicVector2(); AttackTarget = new LogicVector2(); AttackVector = new LogicVector2(); MoveStart = 0; MoveEnd = 0; m_maxHitpoints = CharacterData.Hitpoints; AutoAttackSpeedMs = CharacterData.AutoAttackSpeedMs; m_hitpoints = m_maxHitpoints; OrginalMaxHP = m_maxHitpoints; BlinkX = -1; Poisons = new List(); Immunitys = new List(); IsControlled = false; RealmTimer = 0; State = 4; UltiSkill = false; m_destructafterticks = 5; SteerAngle = -1; SkillHoldTicks = -1; VisionOverrideX = -1; AFKTicks = 0; if (WeaponSkillData != null) { m_skills.Add(new Skill(WeaponSkillData.GetGlobalId(), false, this)); if (m_isBot == 2) m_skills[0].Infinity = true; } if (UltimateSkillData != null) { m_skills.Add(new Skill(UltimateSkillData.GetGlobalId(), true, this)); } if (CharacterData.Name == "Mummy") TransformationState = 0; CanHeal = true; m_activeChargeType = -1; PassiveCounter = 1; PassiveCounter2 = 4; SamState = true; } async Task TriggerPushbackImmun() { ImmunToPushbackOutOfWalls = true; await Task.Delay(5000); ImmunToPushbackOutOfWalls = false; } public bool IsBlackListSkinPro(string projectile) { return new List{ "FleaProjectile3", "CocoonerUltiProjectile", "PuppeteerProjectile", "PuppeteerUltiProjectile", "ReviverUltiProjectile", "Roller003Projectile", "Poco003Projectile", "Poco003UltiProjectile", "Poco004Projectile", "Poco004UltiProjectile", "Poco005Projectile", "Poco005UltiProjectile", "Poco006UltiProjectile", "Poco007Projectile", "Poco007UltiProjectile", }.Contains(projectile); } public int GetMaxHoldTicks() { int v2 = GetCardValueForPassive("faster_focus", 1); if (v2 >= 1) return 13 - 13 * v2 / 100; return 13; } public int GetMaxChargedShots() { if (WeaponSkillData?.ChargedShotCount >= 1) return WeaponSkillData.ChargedShotCount; if (CharacterData.UniqueProperty == 10) return CharacterData.UniquePropertyValue1; return -1; } public void SetKing() { BigState = true; GiveSpeedSlowerBuff(-100, 9999); CanHeal = false; m_hitpoints = 100000; m_maxHitpoints = 100000; } public void PushOutOfWalls() { if(this.CharacterData.IsCarryable()) return; if (!IsSteerMovementActive() && DraggingObject == null && !Knockback3 && !Knockback1 && !Knockback2 && (!IsCharging || !GamePlayUtil.IsJumpCharge(m_activeChargeType))) { if (ImmunToPushbackOutOfWalls) return; TileMap tileMap = GetBattle().GetTileMap(); if (!tileMap.IsPassable(1, GetX() / 300, GetY() / 300, 0, 0, CharacterData.CanWalkOverWater)) { TriggerStun(1, true); GamePlayUtil.GetClosestPassableSpot(1, GetX(), GetY(), 10, tileMap, PosDelta, CharacterData.CanWalkOverWater); TriggerPushback( GetX() - PosDelta.X + GetX(), GetY() - PosDelta.Y + GetY(), LogicMath.Max(GamePlayUtil.GetDistanceBetween(GetX(), GetY(), PosDelta.X, PosDelta.Y), 300) / 6, true, 0, true, false, false, true, false, true, false, 0); } } } public void TriggerImmunToPushOutOfWalls(int ticks) { TriggerPushbackImmun(); } private bool CheckTileCollision(int startX, int startY, int endX, int endY, ref LogicVector2 normal) { TileMap tileMap = GetBattle().GetTileMap(); int startTileX = startX / 300; int startTileY = startY / 300; int endTileX = endX / 300; int endTileY = endY / 300; int dx = Math.Abs(endTileX - startTileX); int dy = Math.Abs(endTileY - startTileY); int sx = startTileX < endTileX ? 1 : -1; int sy = startTileY < endTileY ? 1 : -1; int err = dx - dy; int currentX = startTileX; int currentY = startTileY; while (true) { Tile tile = tileMap.GetTile(currentX, currentY, true); if (tile != null && tile.Data.BlocksMovement && !tile.IsDestructed()) { normal = CalculateTileNormal(currentX, currentY, startTileX, startTileY); return true; } if (currentX == endTileX && currentY == endTileY) break; int e2 = 2 * err; if (e2 > -dy) { err -= dy; currentX += sx; } if (e2 < dx) { err += dx; currentY += sy; } } return false; } private LogicVector2 CalculateTileNormal(int tileX, int tileY, int fromTileX, int fromTileY) { int tileCenterX = tileX * 300 + 150; int tileCenterY = tileY * 300 + 150; int toStartX = fromTileX * 300 + 150 - tileCenterX; int toStartY = fromTileY * 300 + 150 - tileCenterY; LogicVector2 normal = new(0, 0); if (Math.Abs(toStartX) > Math.Abs(toStartY)) { normal.X = Math.Sign(toStartX); } else { normal.Y = Math.Sign(toStartY); } int length = (int)Math.Sqrt(normal.X * normal.X + normal.Y * normal.Y); if (length > 0) { normal.X = (normal.X * 1024) / length; normal.Y = (normal.Y * 1024) / length; } return normal; } public void SetVisionOverride(int X, int Y, int ticks) { VisionOverrideX = X; VisionOverrideY = Y; VisionOverrideTicks = ticks; StopMovement(); } public void AddCcImmunity(int ticks) { for (int i = 0; i < m_buffs.Count; i++) { Buff buff = m_buffs[i]; if (buff.Type == 3) { m_buffs.Remove(buff); i--; } } Knockback3 = false; KnockBacked = false; CcImmunityTicks = ticks; StopMovement(); } public static Character SummonMinion( CharacterData CharacterData, int X, int Y, int a4, int NumSpawn, int MaxSpawn, int ExtraDamage, int ExtraHealth, BattleMode a9, int a10, int a11, int a12, bool OverridePrevious, bool a14, int a15, bool StarPowerIC, int a17) { int v18; // r4 int v20; // r10 int v21; // r6 int v22; // r8 int v23; // r9 int v24; // r0 bool v25; // zf int v26; // r9 MAPDST bool v27; // cc int v29; // r10 Character v30; // r6 int v31; // r0 int v33; // r8 int v34; // r9 int v35; // r0 int HP; // r8 int v37; // r9 int v38; // r0 int v39; // r2 Character v40; // r6 int v41; // r0 MAPDST int v42; // r10 int v43; // r7 int v48; // r4 int v49; // r6 int v50; // r4 TileMap v51; // r0 int v52; // r5 int v53; // r0 int v54; // r6 int v55; // r4 int v56; // r6 char v58; // r4 int v59; // r9 int v60; // r6 int v61; // r0 int v62; // r8 int v63; // r0 int v64; // r2 bool v66; // cf int v67; // r9 int i; // r4 int v69; // r0 int v71; // r0 bool v72; // zf int v74; // r4 int v75; // r0 int v76; // r0 int v77; // r2 int v78; // r1 int v79; // r0 int v80; // r4 int v81; // r8 int v83; // r0 int v85; // r0 bool v86; // zf Character v90; // [sp+34h] [bp-3Ch] int v95; // [sp+48h] [bp-28h] int v97; // [sp+50h] [bp-20h] int v98; // [sp+50h] [bp-20h] int v99; // [sp+50h] [bp-20h] int v100; // [sp+50h] [bp-20h] v26 = NumSpawn; if (a9.GetGameObjectManager().GetGameObjects().Length < 1) { v97 = 0; } else { v20 = 0; v97 = 0; foreach (Character character in a9.GetGameObjectManager().GetCharacters()) { if (character.GetIndex() == a11 * 16 + a10 && character.CharacterData == CharacterData) v97++; } } if (OverridePrevious) { if (v97 >= MaxSpawn) { foreach (Character character in a9.GetGameObjectManager().GetCharacters()) { if (character.GetIndex() == a11 * 16 + a10 && character.CharacterData == CharacterData) { character.CauseDamage(null, character.m_hitpoints, 0, false, null, false, true); --v97; } } while (v97 >= MaxSpawn) ; v26 = NumSpawn; } } else if (MaxSpawn - v97 < NumSpawn) { v26 = MaxSpawn - v97; } if (v26 < 1) return null; v40 = null; v41 = 0; do { if (NumSpawn == 5) { v48 = v41 * 72 - 18; a4 = 600; v49 = LogicMath.GetRotatedX(a4, 0, v48); v50 = LogicMath.GetRotatedY(a4, 0, v48); v51 = a9.GetTileMap(); v52 = LogicMath.Clamp(v49 + X, 101, v51.LogicWidth - 101); v54 = LogicMath.Clamp(v50 + Y, 101, v51.LogicHeight - 101); v74 = v54; v67 = v52; } else { v74 = Y; v67 = X; } LogicVector2 tmp = new LogicVector2(); GamePlayUtil.GetClosestPassableSpot(0, v67, v74, 10, a9.GetTileMap(), tmp, CharacterData.CanWalkOverWater); v40 = GameObjectFactory.CreateGameObjectByData(CharacterData); v75 = CharacterData.FlyingHeight; v100 = v74; v40.SetPosition(tmp.X, tmp.Y, v75); v40.SetIndex(a11 * 16 + a10); v76 = CharacterData.AutoAttackDamage; v77 = v40.AutoAttackDamangeBoost; v78 = v40.m_maxHitpoints + ExtraHealth; v40.m_hitpoints = v78; if (v76 > 0) v77 += ExtraDamage; v40.m_maxHitpoints = v78; v40.AutoAttackDamangeBoost = v77; v40.DeployedTick = a9.GetTicksGone(); v40.ParentGID = a12; a9.GetGameObjectManager().AddGameObject(v40); v40.AddAreaEffect(ExtraDamage, a17, null, 0, false); v40.StarPowerIC = StarPowerIC; ++v41; } while (v41 != v26); return v40; } public void SetUpgrades(int a2) { SetHeroLevel(a2); CalculateChargeUp(); } public void SetStarPowerBoosts() { if (StarPowerData != null && !m_BoostSet) { m_BoostSet = true; if (GetCardValueForPassive("aoe_regenerate", 1) != -1) { AoeRegenerate = (int)(((double)GetCardValueForPassive("aoe_regenerate", 1) / 1000) * (double)m_maxHitpoints); } if (GetCardValueForPassive("speed", 1) != -1) { StaticSpeedBuff += GetCardValueForPassive("speed", 1); } if (GetCardValueForPassive("gain_health", 1) != -1) { m_maxHitpoints += (int)(((double)GetCardValueForPassive("gain_health", 1) / 1000) * (double)m_maxHitpoints); m_hitpoints = m_maxHitpoints; m_BoostSet = false; } if (GetCardValueForPassive("extra_bullet", 1) != -1) { m_skills[0].MaxCharge += 1000 * GetCardValueForPassive("extra_bullet", 1); m_skills[0].Charge = m_skills[0].MaxCharge; } StarPowerIC = true; } } public Character TriggerTransforming(CharacterData a2) { Character c = GetBattle().SpawnHero(a2, m_heroLevel, GetIndex(), 0, false); c.SetPosition(GetX(), GetY(), 0); if (CharacterData.UniqueProperty == 7) c.m_hitpoints = m_hitpoints; c.m_itemCount = m_itemCount; c.BattleRoyaleBuffs = BattleRoyaleBuffs; c.m_skills[0].Charge = m_skills[0].Charge; c.BlockHealthRegen(); GetPlayer().OwnObjectId = c.GetGlobalID(); GameObjectManager.RemoveGameObject(this); TransformAnimation = true; return c; } async Task CauseTimedDamage(Character target, int Time, int Damage, Character old, BattlePlayer player, int hp) { while (target.m_hitpoints > 0) { await Task.Delay(2000); target.CauseDamage(this, 800, 0, false, null, false, true); target.BlockHealthRegen(); } if (target.m_hitpoints <= 0) { GameObjectManager.RemoveGameObject(target); Character c = GetBattle().SpawnHero(old.CharacterData, old.GetHeroLevel(), old.GetIndex(), 0, false); c.SetPosition(GetX(), GetY(), 0); if (player != null) player.OwnObjectId = c.ObjectGlobalId; c.m_hitpoints = hp; } } public Character TimedTransform(CharacterData a2, int Duration, int x, int y, int index, Character oldModel, BattlePlayer oldPlayer, int hitPoints, Character Owner) { CharacterData old = CharacterData; Character c = GetBattle().SpawnHero(a2, 11, 0, 0, false); c.SetPosition(x, y, 0); if (oldPlayer != null) oldPlayer.OwnObjectId = c.GetGlobalID(); c.CauseTimedDamage(c, 0, 0, oldModel, oldPlayer, hitPoints); return c; } public void UltiButtonPressedTwice() { if (IsCharging && m_activeChargeType == 1) { UltiButtonPressedTimes = 0; StopMovement(); InterruptAllSkills(true); } } public void CalculateChargeUp() { int result; if (m_skills.Count >= 2) { if (m_skills[0].SkillData.ChargeSpeed > 0 && m_skills[0].SkillData.ChargeType == 0) { ChargeUpType = 1; ChargeUpMax = m_skills[0].SkillData.ChargeSpeed; return; } if (m_skills[1].SkillData.ChargeType == 15) { ChargeUpType = 7; ChargeUpMax = m_skills[1].SkillData.ActiveTime; ChargeUp = 0; } } if (GetCardValueForPassive("medikit", 1) >= 0) { ChargeUpType = 2; ChargeUpMax = GetCardValueForPassive("medikit", 2); return; } if (GetCardValueForPassive("grow_from_damage", 1) >= 0) { ChargeUpType = 3; ChargeUpMax = GetCardValueForPassive("grow_from_damage", 0); return; } if (GetCardValueForPassive("armor", 1) >= 0) { ChargeUpType = 4; ChargeUpMax = GetCardValueForPassive("armor", 1); ChargeUp = ChargeUpMax; return; } if (GetCardValueForPassive("increased_explosion", 1) >= 0) { ChargeUpType = 6; ChargeUpMax = GetCardValueForPassive("increased_explosion", 1); return; } if (GetCardValueForPassive("attack_pierce", 1) >= 0) { ChargeUpType = 6; ChargeUpMax = GetCardValueForPassive("attack_pierce", 1) * 50; return; } if (GetCardValueForPassive("explosion_damage_increase", 1) >= 0) { ChargeUpType = 6; ChargeUpMax = GetCardValueForPassive("explosion_damage_increase", 1); return; } if (GetCardValueForPassive("reduce_damage_periodically", 1) >= 0) { ChargeUpType = 2; ChargeUpMax = GetCardValueForPassive("reduce_damage_periodically", 1) * 50; return; } if (GetCardValueForPassive("spawn_pet_on_hit", 1) >= 0) { ChargeUpType = 6; ChargeUpMax = GetCardValueForPassive("spawn_pet_on_hit", 1) * 50; return; } switch (CharacterData.UniqueProperty) { case 1: ChargeUpMax = 1000; ChargeUpType = 8; break; case 3: ChargeUpType = 1; ChargeUpMax = CharacterData.UniquePropertyValue1 * 50; result = GetCardValueForPassive("faster_long_dash", 1); if (result >= 1) ChargeUpMax -= 50 * result; break; case 10: ChargeUpType = 9; ChargeUpMax = CharacterData.UniquePropertyValue1; break; case 12: ChargeUpType = 10; ChargeUpMax = CharacterData.UniquePropertyValue1; break; case 17: ChargeUpType = 6; ChargeUpMax = CharacterData.UniquePropertyValue1; break; } if (GetPlayer() != null && GetPlayer().Accessory != null && GetPlayer().Accessory.AccessoryData.ShowCountdown) { ChargeUpType = 7; ChargeUpMax = GetPlayer().Accessory.AccessoryData.ActiveTicks * 50; } } public void AddExtraHealthRegen( int a2, int a3, int a4) { ApplyBuff(10, a3, a2, 0, a4); } public void SetStartRotation(int angle) { MoveAngle = angle; AttackAngle = angle; } public void ApplyPoison(int SourceIndex, int Damage, int NormalDMG, bool IsUlti, Character Source, int Type)//5 Electronic 6 Eve 8 IceAmber { if (Poisons.Count >= 1) { foreach (Poison poison in Poisons) { if (poison.SourceIndex == SourceIndex && !poison.AllowStacking()) { poison.RefreshPosion(Damage, NormalDMG, IsUlti, Type); return; } } } Poison poison1 = new Poison(Damage, NormalDMG, IsUlti, Source, SourceIndex, Type); Poisons.Add(poison1); } public void TriggerShake() { Shaking = 6; } public bool IsChargeUpReady() { return ChargeUp >= ChargeUpMax; } public void AddShield(int time, int percentage) { ShieldPercent = percentage; ShieldTicks = time; } public void SetBot(int isbot) { m_isBot = isbot; } public SkillData WeaponSkillData => DataTables.Get(DataType.Skill).GetData(CharacterData.WeaponSkill); public SkillData UltimateSkillData => DataTables.Get(DataType.Skill).GetData(CharacterData.UltimateSkill); public void ApplyItem(Item logicItem) { BattlePlayer player = GameObjectManager.GetBattle().GetPlayer(GetGlobalID()); switch (logicItem.ItemData.Name) { case "SoulCollectorSoul": int heal = logicItem.Damage; if (GetCardValueForPassive("item_healing_increased", 1) >= 1) heal *= 2; Heal(logicItem.GetIndex(), heal, true, logicItem.ItemData); break; case "BattleRoyaleBuff": if (GameObjectManager.GetBattle().GetGameModeVariation() == 9) { foreach (Character character in GetBattle().GetCharactersByTeam(GetPlayer().TeamIndex)) { character.BattleRoyaleBuffs++; character.m_maxHitpoints += 400; character.m_hitpoints += 400; character.m_damageMultiplier++; } } else { BattleRoyaleBuffs++; m_maxHitpoints += 400; m_hitpoints += 400; m_damageMultiplier++; } break; case "Money": if (player != null) { player.AddScore(1); } break; case "Point": player = GameObjectManager.GetBattle().GetPlayer(GetGlobalID()); if (player != null) { m_itemCount++; player.AddScore(1); } break; case "RuffsBuff": player = GameObjectManager.GetBattle().GetPlayer(GetGlobalID()); if (HasBuff(13)) return; if (player != null) { ApplyBuff(13, 1230, 1, 10); } m_hitpoints += 700; m_maxHitpoints += 700; m_damageMultiplier++; break; case "WeaponThrowerWeapon": player = GameObjectManager.GetBattle().GetPlayer(GetGlobalID()); if (player != null && CharacterData.Name == "WeaponThrower") { player.AddUltiCharge(4000); } SamState = true; break; } switch (logicItem.ItemData.ParentItemForSkin) { case "WeaponThrowerWeapon": player = GameObjectManager.GetBattle().GetPlayer(GetGlobalID()); if (player != null && CharacterData.Name == "WeaponThrower") { player.AddUltiCharge(4000); } SamState = true; break; } } public static int TransformPushBackStrengthToLength(int a1) { return 6 * LogicMath.Abs(a1); } public static int TransformPushBackLengthToStrength(int a1) { return a1 / 6; } public void GiveReloadBuff(int a2) { ReloadBuffTicks = a2; } public void SetDraggingObject(GameObject a2, int a3, int a4) { if (HasCcImmunity() || IsInvincible || IsCharging) return; DraggingObject = a2; DraggingOffsetX = a3; DraggingOffsetY = a4; MoveStart = TicksGone - 1; MoveEnd = TicksGone - 1; InterruptAllSkills(false); } private void TickSkills() { CastingTime = LogicMath.Max(0, CastingTime - 50); for (int i = 0; i < m_skills.Count; i++) { m_skills[i].Tick(this); } } private void TickAutoUltiCharge() { if (State != 4) { int v1 = CharacterData.ChargeUltiAutomatically / 4; if (v1 >= 1) { AutoUltiChargeTimer--; if (AutoUltiChargeTimer <= 0) { if (GetPlayer() != null) { if (Accessory != null && Accessory.Type == "auto_super_load_boost" && Accessory.IsActive) { v1 += v1 * Accessory.AccessoryData.CustomValue1 / 100; } ChargeUlti(v1, false, true, GetPlayer(), this); } AutoUltiChargeTimer = 5; } } } } private const int PickupRadiusSqr = 90000; private const int DefenseRadius = 400; private const int DefenseRadiusSqr = DefenseRadius * DefenseRadius; private const int BaseFlightDuration = 140; private const int MinFlightDuration = 40; private const int BounceDurationDecrement = 10; private const float MaxHeight = 3000f; private const int CenterX = 3150; private const int CenterY = 4950; private const int TargetMinX = 1200; private const int TargetMaxX = 4800; private const int Team0TargetMinY = 1200; private const int Team0TargetMaxY = 3500; private const int Team1TargetMinY = 5500; private const int Team1TargetMaxY = 7800; public int LandingTick; public int BallState; public AreaEffect CurrentZone; public int ServingTeam = -1; public string CurrentZoneName = ""; public int TargetX { get; set; } public int TargetY { get; set; } public AreaEffect CurrentDistanceIndicator; public int MoveStartX; public int MoveStartY; public int MoveStartZ; public bool IsScored; private int m_lastLaunchTick = 0; private bool m_indicatorSpawned = false; private AreaEffect m_distanceIndicator; private int m_indicatorSpawnTick = 0; private void TickVolleyBall() { if (this.IsScored) return; var battle = GameObjectManager.GetBattle(); var manager = battle?.GetGameObjectManager(); int currentTick = TicksGone; if (BallState == 0) { if (!m_indicatorSpawned) { var indicatorData = DataTables.GetAreaEffectByName("VolleyBallDistanceIndicator"); if (indicatorData != null) { m_distanceIndicator = new AreaEffect(indicatorData); m_distanceIndicator.SetPosition(GetX(), GetY(), 0); m_distanceIndicator.SetIndex(this.GetIndex()); m_distanceIndicator.SetSource(this, 1); manager.AddGameObject(m_distanceIndicator); m_distanceIndicator.Trigger(); m_indicatorSpawned = true; m_indicatorSpawnTick = currentTick; } } if (currentTick < m_lastLaunchTick + 40) return; foreach (Character c in manager.GetCharacters()) { if (!c.IsAlive() || c.GetPlayer() == null || c.GetGlobalID() == this.GetGlobalID()) continue; int dx = GetX() - c.GetX(); int dy = GetY() - c.GetY(); if ((long)dx * dx + (long)dy * dy <= PickupRadiusSqr) { if (m_distanceIndicator != null) { manager.RemoveGameObject(m_distanceIndicator); m_distanceIndicator = null; } this.BounceCount = 0; this.MoveStartX = GetX(); this.MoveStartY = GetY(); this.MoveStartZ = GetZ(); this.m_lastLaunchTick = currentTick; LaunchBallToOpponent(c.GetPlayer().TeamIndex, battle, manager); return; } } } else if (BallState == 1) { if (m_distanceIndicator != null) { GameObjectManager.GetBattle().GetGameObjectManager().RemoveGameObject(m_distanceIndicator); m_distanceIndicator = null; } UpdateFlightPosition(currentTick); if (currentTick >= LandingTick) { CheckLanding(battle, manager); } } } private void UpdateFlightPosition(int currentTick) { int totalDuration = LandingTick - MoveStart; if (totalDuration <= 0) return; float t = (float)(currentTick - MoveStart) / totalDuration; if (t > 1.0f) t = 1.0f; int curX = MoveStartX + (int)((TargetX - MoveStartX) * t); int curY = MoveStartY + (int)((TargetY - MoveStartY) * t); int curZ = (int)(4f * MaxHeight * t * (1.0f - t)); SetPosition(curX, curY, curZ); if (currentTick % 2 == 0) { var manager = GameObjectManager.GetBattle().GetGameObjectManager(); int defendingTeam = (ServingTeam == 0) ? 1 : 0; bool isAnyDefendingPlayerInside = false; foreach (Character c in manager.GetCharacters()) { if (!c.IsAlive() || !c.CharacterData.IsHero() || c.GetPlayer()?.TeamIndex != defendingTeam) continue; int dx = TargetX - c.GetX(); int dy = TargetY - c.GetY(); if ((long)dx * dx + (long)dy * dy <= DefenseRadiusSqr) { isAnyDefendingPlayerInside = true; break; } } string targetName = isAnyDefendingPlayerInside ? "VolleyBallTargetOccupied" : "VolleyBallTarget"; if (this.CurrentZoneName != targetName) { if (this.CurrentZone != null) manager.RemoveGameObject(this.CurrentZone); SpawnArea(targetName, manager); } } } private void LaunchBallToOpponent(int attackerTeam, BattleMode battle, GameObjectManager manager) { this.BallState = 1; this.ServingTeam = attackerTeam; this.MoveStart = TicksGone; int duration = BaseFlightDuration - (BounceCount * BounceDurationDecrement); if (duration < MinFlightDuration) duration = MinFlightDuration; this.LandingTick = TicksGone + duration; this.CurrentZoneName = ""; TileMap tileMap = battle.GetTileMap(); int targetMinY = (attackerTeam == 0) ? Team0TargetMinY : Team1TargetMinY; int targetMaxY = (attackerTeam == 0) ? Team0TargetMaxY : Team1TargetMaxY; Random rnd = new Random(); this.TargetX = rnd.Next(TargetMinX, TargetMaxX); this.TargetY = rnd.Next(targetMinY, targetMaxY); LogicVector2 passableSpot = new LogicVector2(); GamePlayUtil.GetClosestPassableSpot(1, TargetX, TargetY, 15, tileMap, passableSpot, true); if (passableSpot.X > 0) { TargetX = passableSpot.X; TargetY = passableSpot.Y; } var hitData = DataTables.GetAreaEffectByName("VolleyBallHit"); if (hitData != null) { AreaEffect hitEff = new AreaEffect(hitData); hitEff.SetPosition(GetX(), GetY(), 0); hitEff.SetIndex(this.GetIndex()); hitEff.SetSource(this, 1); manager.AddGameObject(hitEff); hitEff.Trigger(); } if (this.CurrentZone != null) { manager.RemoveGameObject(this.CurrentZone); this.CurrentZone = null; } SpawnArea("VolleyBallTarget", manager); } private bool IsTileBlocking(int x, int y, TileMap map) { int tileX = x / 300; int tileY = y / 300; for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { int tx = tileX + dx; int ty = tileY + dy; if (tx < 0 || tx >= map.Width || ty < 0 || ty >= map.Height) continue; Tile t = map.GetTile(tx, ty, true); if (t == null || t.Data == null) continue; if (t.IsDestructed()) continue; bool blocksMovement = t.Data.BlocksMovement; bool blocksProjectiles = t.Data.BlocksProjectiles; if (blocksMovement || blocksProjectiles) return true; } } return false; } private void SpawnArea(string name, GameObjectManager manager) { var aeData = DataTables.GetAreaEffectByName(name); if (aeData != null) { AreaEffect newZone = new AreaEffect(aeData); newZone.SetPosition(TargetX, TargetY, 0); newZone.SetIndex(this.GetIndex()); newZone.SetSource(this, 1); this.CurrentZone = newZone; this.CurrentZoneName = name; manager.AddGameObject(newZone); newZone.Trigger(); if (BallState == 1) { var indicatorData = DataTables.GetAreaEffectByName("VolleyBallDistanceIndicator"); if (indicatorData != null) { if (this.CurrentDistanceIndicator != null) manager.RemoveGameObject(this.CurrentDistanceIndicator); AreaEffect indicator = new AreaEffect(indicatorData); indicator.SetPosition(TargetX, TargetY, 0); indicator.SetIndex(this.GetIndex()); indicator.SetSource(this, 1); this.CurrentDistanceIndicator = indicator; manager.AddGameObject(indicator); indicator.Trigger(); } } } } private void CheckLanding(BattleMode battle, GameObjectManager manager) { if (battle.GoalPauseEndTick > 0 && battle.GetTicksGone() < battle.GoalPauseEndTick) return; int defendingTeam = (ServingTeam == 0) ? 1 : 0; int scoringTeam = ServingTeam; Character defender = null; foreach (Character c in manager.GetCharacters()) { if (!c.IsAlive() || !c.CharacterData.IsHero() || c.GetPlayer() == null) continue; if (c.GetPlayer().TeamIndex != defendingTeam) continue; int dx = TargetX - c.GetX(); int dy = TargetY - c.GetY(); if ((long)dx * dx + (long)dy * dy <= DefenseRadiusSqr) { defender = c; break; } } if (this.CurrentDistanceIndicator != null) { manager.RemoveGameObject(this.CurrentDistanceIndicator); this.CurrentDistanceIndicator = null; } if (defender != null) { if (this.CurrentZone != null) { manager.RemoveGameObject(this.CurrentZone); this.CurrentZone = null; } this.BounceCount++; this.MoveStartX = GetX(); this.MoveStartY = GetY(); this.MoveStartZ = GetZ(); LaunchBallToOpponent(defendingTeam, battle, manager); } else { int currentTick = battle.GetTicksGone(); int pauseEndTick = currentTick + 100; // пауза ~5 секунд // battle.GoalPauseEndTick = pauseEndTick; // manager.GoalScoredTeamIndex = scoringTeam; bool goalAssigned = false; battle.AddWinInLaserBall(scoringTeam); battle.SetGoalLaserBall(scoringTeam); manager.RemoveGameObject(this); m_indicatorSpawned = false; } } private void SpawnHitEffect(GameObjectManager manager) { const string hitEffectName = "VolleyBallHit"; var hitData = DataTables.GetAreaEffectByName(hitEffectName); if (hitData != null) { AreaEffect hitEff = new AreaEffect(hitData); hitEff.SetPosition(this.GetX(), this.GetY(), 0); hitEff.SetIndex(this.GetIndex()); hitEff.SetSource(this, 1); manager.AddGameObject(hitEff); hitEff.Trigger(); } } private void ResetBallToCenter() { if (this.CurrentDistanceIndicator != null) { GameObjectManager.GetBattle().GetGameObjectManager().RemoveGameObject(CurrentDistanceIndicator); this.CurrentDistanceIndicator = null; } BallState = 0; SetPosition(CenterX, CenterY, 0); if (CurrentZone != null) { GameObjectManager.RemoveGameObject(CurrentZone); CurrentZone = null; } } public override void Tick() { // if (StopAI) InterruptAllSkills(false); if (IsAlive()) { if (!StopAI) TickTimers(); TickStarPowers(); ExecuteBlink(); PushOutOfWalls(); TickSkills(); if (IsRapidFireHeld) { Skill weaponSkill = GetWeaponSkill(); if (weaponSkill != null && weaponSkill.SkillData.ButtonExportName == "rapid_fire_button") { if (!weaponSkill.IsActive && weaponSkill.CoolDown <= 0) ActivateSkill(0, RapidFireRepeatX, RapidFireRepeatY); if (TicksGone - RapidFireRepeatTick > 2) IsRapidFireHeld = false; } else IsRapidFireHeld = false; } TickInvisibility(); if (CharacterData.IsHero()) TickHeals(); if (!StopAI) HandleMoveAndAttack(); TickEffects(); TickFrozen(); TickAutoUltiCharge(); TickTile(); if ((m_activeChargeType == 8 || m_activeChargeType == 99 || m_activeChargeType == 105) && IsChargeActive()) ImmunToPushbackOutOfWalls = true; else ImmunToPushbackOutOfWalls = false; if (TicksGone > INTRO_TICKS && !StopAI) TickAI(); AFKTicks++; if (AreaEffect != null) { AreaEffect.SetPosition(GetX(), GetY(), 0); } } if (m_hitpoints <= 0) GameObjectManager.RemoveGameObject(this); if (CharacterData.IsCarryable()) { switch (CharacterData.Name) { case "LaserBall": TickLaserBallMove(); break; } } if(CharacterData.Name == "VolleyBall") TickVolleyBall(); if (AFKTicks > 380 && GameObjectManager.GetBattle().GetGameModeVariation() != 13) { try { if (this == null) return; var player = GameObjectManager.GetBattle().GetPlayer(GetGlobalID()); if (player == null) return; if (player.IsBot() > 1) return; if (!CharacterData.IsHero()) return; AFKTicks = 0; if (player.GameListener != null) { var loginFailed = new DisconnectedMessage(); loginFailed.Reason = 2; player.GameListener.SendTCPMessage(loginFailed); } GameObjectManager.GetBattle().RemovePlayer(player); SetBot(2); } catch (Exception ex) { } } } public void TickLaserBallMove() { if (GetBattle().GoalTicks > 0) return; if (GetY() < 1150) { if (GetBattle().Carryable != null && GetBattle().Carryable.LastPickupPlayerIndex == 1) { StopKicking(); TriggerBlink(GetX(), 1300, null, null, 0, 0); if (GetBattle().Carryable.CarringCharacter != null) GetBattle().Carryable.CarringCharacter.CarryablePersonImunTicks = 20; GetBattle().Carryable.CarringCharacter = null; return; } CarringCharacter = null; StopKicking(); GetBattle().AddWinInLaserBall(LastPickupPlayerIndexTOCHNO); GetBattle().ResetCarryable(); GetBattle().SetGoalLaserBall(0); } if (GetY() > 8850) { if (GetBattle().Carryable != null && GetBattle().Carryable.LastPickupPlayerIndex == 0) { StopKicking(); TriggerBlink(GetX(), 8700, null, null, 0, 0); if (GetBattle().Carryable.CarringCharacter != null) GetBattle().Carryable.CarringCharacter.CarryablePersonImunTicks = 20; GetBattle().Carryable.CarringCharacter = null; return; } CarringCharacter = null; StopKicking(); GetBattle().AddWinInLaserBall(LastPickupPlayerIndexTOCHNO); GetBattle().ResetCarryable(); GetBattle().SetGoalLaserBall(1); } if (CarringCharacter != null && !CarringCharacter.IsAlive()) CarringCharacter = null; if (!IsKicked) { this.Z = 0; return; } int newZ = 1; if (TotalKickDistance > 0) { float progress = (float)DistanceTraveled / TotalKickDistance; if (progress <= 0.1f) { float normalizedProgress = progress / 0.1f; float smoothProgress = normalizedProgress < 0.5f ? 2.0f * normalizedProgress * normalizedProgress : 1.0f - 2.0f * (1.0f - normalizedProgress) * (1.0f - normalizedProgress); newZ = (int)(smoothProgress * 250); } else if (progress <= 0.4f) { float normalizedProgress = (progress - 0.1f) / 0.3f; float smoothProgress = normalizedProgress < 0.5f ? 2.0f * normalizedProgress * normalizedProgress : 1.0f - 2.0f * (1.0f - normalizedProgress) * (1.0f - normalizedProgress); newZ = (int)(250 - smoothProgress * (250 - 1)); } else newZ = 1; } this.Z = newZ; if (TotalKickDistance > 0) { float progress = (float)DistanceTraveled / TotalKickDistance; if (progress >= 0.25f) { float normalizedProgress = (progress - 0.25f) / 0.95f; float minSpeedMultiplier = 0.25f; CurrentKickSpeed = (int)(MaxKickSpeed * (1.0f - normalizedProgress * (1.0f - minSpeedMultiplier))); } else CurrentKickSpeed = MaxKickSpeed; } int deltaX = (KickDirection.X * CurrentKickSpeed) / 1024 / 20; int deltaY = (KickDirection.Y * CurrentKickSpeed) / 1024 / 20; if (Math.Abs(deltaX) < 1 && Math.Abs(deltaY) < 1) { StopKicking(); return; } int newX = GetX() + deltaX; int newY = GetY() + deltaY; bool hasCollision = false; LogicVector2 collisionNormal = new LogicVector2(0, 0); LogicVector2 borderCollision = new LogicVector2(newX, newY); bool hasBorderCollision = GamePlayUtil.GetClosestLevelBorderCollision(GetX(), GetY(), newX, newY, GetBattle().GetTileMap(), 1, borderCollision); if (hasBorderCollision) { hasCollision = true; collisionNormal = CalculateBorderNormal(GetX(), GetY(), borderCollision.X, borderCollision.Y); newX = borderCollision.X; newY = borderCollision.Y; } else { hasCollision = CheckTileCollision(GetX(), GetY(), newX, newY, ref collisionNormal); } if (hasCollision) { Bounce(collisionNormal); newX = GetX() + (collisionNormal.X * 50) / 1024; newY = GetY() + (collisionNormal.Y * 50) / 1024; } TileMap tileMap = GetBattle().GetTileMap(); int borderLeft = 0; int borderRight = tileMap.LogicWidth; int borderTop = 0; int borderBottom = tileMap.LogicHeight; newX = Math.Max(borderLeft, Math.Min(borderRight, newX)); newY = Math.Max(borderTop, Math.Min(borderBottom, newY)); SetPosition(newX, newY, GetZ()); int currentX = GetX(); int currentY = GetY(); if (currentX < borderLeft || currentX > borderRight || currentY < borderTop || currentY > borderBottom) { GetBattle().ResetRoundLaserBall(true); return; } int distanceThisTick = (int)Math.Sqrt(deltaX * deltaX + deltaY * deltaY); DistanceTraveled += distanceThisTick; if (DistanceTraveled >= TotalKickDistance) { StopKicking(); return; } } public bool IsKicked { get; set; } = false; public int KickStartX { get; set; } public int KickStartY { get; set; } public int TotalKickDistance = 2400; public int DistanceTraveled { get; set; } = 0; public int CurrentKickSpeed { get; set; } public int MaxKickSpeed { get; set; } public LogicVector2 KickDirection { get; set; } public int BounceCount { get; set; } = 0; public const int MaxBounces = 9999999; public void Kick(int angle, int speed, int totalDistance) { if (IsKicked) return; IsKicked = true; MaxKickSpeed = speed; CurrentKickSpeed = speed; KickDirection = new LogicVector2(LogicMath.Cos(angle), LogicMath.Sin(angle)); KickStartX = GetX(); KickStartY = GetY(); DistanceTraveled = 0; BounceCount = 0; TotalKickDistance = totalDistance; if (KickDirection.X == 0 && KickDirection.Y == 0) { StopKicking(); return; } } public void StopKicking() { IsKicked = false; CurrentKickSpeed = 0; DistanceTraveled = 0; } public void Bounce(LogicVector2 normal) { if (BounceCount >= MaxBounces) { StopKicking(); return; } BounceCount++; CurrentKickSpeed = (int)(CurrentKickSpeed * 0.7f); int remainingDistance = TotalKickDistance - DistanceTraveled; TotalKickDistance = DistanceTraveled + (int)(remainingDistance * 0.8f); int dotProduct = (KickDirection.X * normal.X + KickDirection.Y * normal.Y) / 1024; int reflectX = KickDirection.X - 2 * dotProduct * normal.X / 1024; int reflectY = KickDirection.Y - 2 * dotProduct * normal.Y / 1024; int length = (int)Math.Sqrt(reflectX * reflectX + reflectY * reflectY); if (length > 0) { KickDirection.X = (reflectX * 1024) / length; KickDirection.Y = (reflectY * 1024) / length; } MaxKickSpeed = CurrentKickSpeed; } private LogicVector2 CalculateBorderNormal(int startX, int startY, int collisionX, int collisionY) { LogicVector2 normal = new(0, 0); TileMap tileMap = GetBattle().GetTileMap(); int borderLeft = 0; int borderRight = tileMap.LogicWidth; int borderTop = 0; int borderBottom = tileMap.LogicHeight; if (collisionX <= borderLeft + 10) { normal.X = 1; } else if (collisionX >= borderRight - 10) { normal.X = -1; } if (collisionY <= borderTop + 10) { normal.Y = 1; } else if (collisionY >= borderBottom - 10) { normal.Y = -1; } if (normal.X == 0 && normal.Y == 0) { int dx = collisionX - startX; int dy = collisionY - startY; if (Math.Abs(dx) > Math.Abs(dy)) { normal.X = Math.Sign(dx) * -1; } else { normal.Y = Math.Sign(dy) * -1; } } int length = (int)Math.Sqrt(normal.X * normal.X + normal.Y * normal.Y); if (length > 0) { normal.X = (normal.X * 1024) / length; normal.Y = (normal.Y * 1024) / length; } return normal; } public void SetSilence(int ticks) { Silence = true; SilenceTick = TicksGone + ticks; } public void AddFrozen(float count) { if (FrozenPercentage >= 100) return; if (m_stunTicks <= TicksGone) FrozenPercentage += count; LastFrozenTick = TicksGone; FrozenDecayTick = TicksGone; } public void TickFrozen() { if (FrozenPercentage >= 100) { TriggerStun(20, true); if (GetBattle().GetTicksGone() == LastFrozenTick + 20) FrozenPercentage = 0; //if (m_stunTicks == 0) FrozenPercentage = 0; } if (SlipperyTicks > 0) { SlipperyTicks--; } Slippery = SlipperyTicks > 0; if (LastFrozenTick + 29 < TicksGone && FrozenPercentage > 0) { if (TicksGone - FrozenDecayTick >= 6) { FrozenPercentage--; FrozenDecayTick = TicksGone; } } } public void ResetAFKTicks() { AFKTicks = 0; } public void SetImmunity(int TargetIndex, int Ticks, LogicData TargetData) { Immunity immunity = new Immunity(TargetIndex, TargetData, Ticks); Immunitys.Add(immunity); } public bool HasBuff(int Type) { foreach (Buff buff in m_buffs) { if (buff.Type == Type) return true; } return false; } public Buff GetBuff(int Type) { foreach (Buff buff in m_buffs) { if (buff.Type == Type) return buff; } return null; } public int GetBuffedSpeed() { int v1 = 0; foreach (Buff buff in m_buffs) { if (buff.Type <= 6 && ((1 << buff.Type) & 88) != 0) // 3 4 6 v1 += buff.Modifier; } return v1; } public int GetUnbuffedSpeed() { int v1 = 0; v1 += StaticSpeedBuff; if (CharacterData.HasPowerLevels && GetPowerLevel() > 0) v1 += 170; if (CharacterData.UniqueProperty == 1) v1 += 60 * GetPowerLevel(); if (GetBattle().HasEventModifier(14)) v1 += 350; if (GetPlayer()?.OverCharging ?? false) { if (CharacterData.OverchargeSpeedPercent > 0) v1 += CharacterData.OverchargeSpeedPercent * CharacterData.Speed / 100; else v1 += 20 * CharacterData.Speed / 100; } return v1; } public void TickEffects() { List ToRemove2 = new List(); foreach (Immunity immunity in Immunitys) { if (immunity.Tick(50)) ToRemove2.Add(immunity); } foreach (Immunity immunity in ToRemove2) { Immunitys.Remove(immunity); } List ToRemove1 = new List(); foreach (Poison poison in Poisons) { if (poison.Tick(this)) ToRemove1.Add(poison); } foreach (Poison poison1 in ToRemove1) { Poisons.Remove(poison1); } List ToRemove = new List(); foreach (Buff buff in m_buffs) { if (buff.Tick(this)) ToRemove.Add(buff); } foreach (Buff buff in ToRemove) { m_buffs.Remove(buff); } } public void TickTimers() { if (GetPlayer() != null && GetBattle().GetGameModeVariation() == 13) { GetPlayer()._damageHistory.RemoveAll(d => d.Tick + 20 < TicksGone); } if (AttachedCharacter != null) SetPosition(AttachedCharacter.GetX(), AttachedCharacter.GetY(), 0); if (Silence && SilenceTick < TicksGone) Silence = false; if (CharacterData.UniqueProperty == 1 && TicksGone - AshLastRageTick >= 21) ChargeUp = LogicMath.Max(0, ChargeUp - 3); if (RealmTimer >= 1) RealmTimer--; if (RealmTimer == 0) IsInRealm = false; if (RapidFireTick != TicksGone) m_attackingTicks = 63; if (LastTagTick <= TicksGone) Tagged = false; IsCrippled = TicksGone < CrippleEndTick; if (!IsCrippled) CripplePercent = 0; if (VisionOverrideTicks >= 1) VisionOverrideTicks--; if (ShieldTicks >= 1) ShieldTicks--; if (CcImmunityTicks >= 1) CcImmunityTicks--; if (Shaking >= 1) Shaking--; if (ReloadBuffTicks >= 1) ReloadBuffTicks--; if (SkillHoldTicks >= 0) SkillHoldTicks++; if (TicksGone <= SpawnTick + 60) IsInvincible = true; if (CarryablePickTicks > 0) CarryablePickTicks--; if (CarryablePersonImunTicks > 0) CarryablePersonImunTicks--; if (GetBattle().Carryable != null && GetBattle().Carryable.CarringCharacter == this) SetFadeCounter(10); else IsInvincible = false; if (ChargeUpMax > 0 && CharacterData.Name == "Ghost") { ImmunToPushbackOutOfWalls = true; ChargeUp--; } if (ChargeUpType == 2 || ChargeUpType == 6 || ChargeUpType == 1 && (m_skills[0].HasFullCharge() || CharacterData.Name == "CannonGirlSmall")) { if (State != 4) ChargeUp = LogicMath.Min(ChargeUp + 50, ChargeUpMax); } else if (ChargeUpType == 10) { if (State == 1 || State == 3) ChargeUp = 0; else if (State != 4) ChargeUp = LogicMath.Min(ChargeUp + 50, ChargeUpMax); } if (ConsumableShield >= 1 && TicksGone > ConsumableShieldTick && ((TicksGone - ConsumableShieldTick) % (ConsumableShieldDuration / 20) == 0)) ConsumableShield = LogicMath.Max(0, ConsumableShield - ConsumableShieldMax / 20); if (ChargeUpType == 7 && State != 4) { if (GetUltimateSkill().SkillData.ChargeType == 15) { ChargeUp = GetUltimateSkill().TicksActive; return; } BattlePlayer result = GetPlayer(); if (result != null) { Accessory v20 = result.Accessory; if (v20 != null) { if (v20.AccessoryData.ShowCountdown) { if (v20.IsActive) { ChargeUp = ChargeUpMax - 50 * v20.TicksActive; return; } } } ChargeUp = 0; } } } public void SetCharacterTagged(int a1, int a2, Character a3) { Tagged = true; if (a3.GetCardValueForPassive("tag_lasts_longer", 1) >= 1) { LastTagTick = a2 + (4 + a3.GetCardValueForPassive("tag_lasts_longer", 1)) * 20; return; } LastTagTick = a2 + 4 * 20; } public void GiveSpeedSlowerBuff(int a2, int a3) { ApplyBuff(3, a3, a2, 0); } public void GiveElectrocution(int Damage, int NormalDMG, int EffectType, int Bounces) { for (int i = 0; i < m_buffs.Count; i++) { if (m_buffs[i].Type == 14) { m_buffs.RemoveAt(i); i--; } } Buff b = ApplyBuff(14, 20, Damage, 0); b.EffectType = EffectType; b.NormalDMG = NormalDMG; b.BelleWeaponBounces = Bounces; } public void GiveSpeedFasterBuff( int a2, int a3, bool a4) { if (a4) { if (m_buffs.Count < 1) { int344 = 10; dword348 = 0; } else { foreach (Buff buff in m_buffs) { if (buff.Type == 4) { ApplyBuff(4, a3, a2, 0); return; } } int344 = 10; dword348 = 0; } } ApplyBuff(4, a3, a2, 0); } public void GiveDamageBuff( int a2, int a3) { ApplyBuff(1, a3, a2, 1); int344 = 10; dword348 = 2; } public void GiveDamageBuff2( int a2, int a3) { if (m_buffs.Count < 1) { int344 = 10; dword348 = 2; } else { foreach (Buff buff in m_buffs) { if (buff.Type == 5) { ApplyBuff(5, a3, a2, 1); return; } } int344 = 10; dword348 = 2; } ApplyBuff(5, a3, a2, 1); } public async void EyeActive() { if (YellowEye) return; YellowEye = true; await Task.Delay(8000); YellowEye = false; } public void TickGears() { if (Gear1 != null) Gear1.Tick(this); if (Gear2 != null) Gear2.Tick(this); } public void TriggerBlink(int x, int y, AreaEffectData areaEffectData1, AreaEffectData areaEffectData2, int Damage, int NormalDMG) { IsTeleporting = true; if (areaEffectData1 != null) { AreaEffect areaEffect = new AreaEffect(areaEffectData1); areaEffect.SetPosition(x, y, 0); areaEffect.SetIndex(GetIndex()); areaEffect.Damage = Damage; areaEffect.NormalDMG = NormalDMG; GameObjectManager.AddGameObject(areaEffect); areaEffect.Trigger(); } if (areaEffectData2 != null) { AreaEffect areaEffect2 = new AreaEffect(areaEffectData2); areaEffect2.SetPosition(GetX(), GetY(), 0); areaEffect2.SetIndex(GetIndex()); GameObjectManager.AddGameObject(areaEffect2); areaEffect2.Trigger(); } MoveStart = TicksGone - 1; MoveEnd = TicksGone - 1; BlinkX = x; BlinkY = y; } public override void ResetEventsOnTick() { IsTeleporting = false; HitEffectProjectile = 0; HitEffectSkin = 0; List Tobe = new List(); if (DamageNumbers.Count >= 1) { foreach (DamageNumber damageNumber in DamageNumbers) { if (damageNumber.Delay <= 0) { Tobe.Add(damageNumber); } else { damageNumber.Delay--; } } } if (Tobe.Count >= 1) { foreach (DamageNumber damageNumber in Tobe) { DamageNumbers.Remove(damageNumber); } } } public Buff ApplyBuff( int Type, int Dura, int Modi, int SizeInc, int Index = -1) { if (m_buffs.Count < 1) { m_buffs.Add(new Buff(Type, Dura, Modi, SizeInc)); return m_buffs.Last(); } else { foreach (Buff buff in m_buffs) { if (buff.Type == Type && !buff.CanStack()) { bool v14 = buff.Duration < Dura; if (buff.Duration >= Dura) v14 = buff.Modifier < Modi; if (v14) { buff.Modifier = Modi; buff.SizeIncrease = SizeInc; buff.Duration = Dura; } return buff; } } } m_buffs.Add(new Buff(Type, Dura, Modi, SizeInc) { SourceIndex = Index }); return m_buffs.Last(); } private void ExecuteBlink() { if (BlinkX != -1) { MoveStart = TicksGone - 1; MoveEnd = TicksGone - 1; SetPosition(BlinkX, BlinkY, CharacterData.FlyingHeight); IsTeleporting = true; BlinkX = -1; } } private void TickStarPowers() { if (GetPlayer() == null) return; if (GetCardValueForPassive("shield_while_ulti", 1) >= 1) { if (GetControlledProjectile() != null) AddShield(2, GetCardValueForPassive("shield_while_ulti", 1)); return; } if (GetCardValueForPassive("bush_shield", 1) >= 1) { if (IsInBush()) AddShield(GetCardValueForPassive("bush_shield", 0), GetCardValueForPassive("bush_shield", 1)); return; } // if (GetCardValueForPassive("low_health_shield", 1) >= 1) // { // if (GetHitpointPercentage() <= GetCardValueForPassive("low_health_shield", 0)) AddShield(99999, GetCardValueForPassive("low_health_shield", 1)); // return; // } if (GetCardValueForPassive("speed_full_ammo", 1) >= 1) { if (ChargeUp >= ChargeUpMax || MeleeAttackPushBacks) GiveSpeedFasterBuff(GetCardValueForPassive("speed_full_ammo", 1), 10, true); return; } if (GetCardValueForPassive("speed_low_health", 0) >= 1) { if (GetHitpointPercentage() <= GetCardValueForPassive("speed_low_health", 0)) GiveSpeedFasterBuff(GetCardValueForPassive("speed_low_health", 1), 10, true); return; } if (GetCardValueForPassive("berserker", 1) >= 1) { if (GetHitpointPercentage() <= GetCardValueForPassive("berserker", 1)) GiveReloadBuff(10); return; } if (GetCardValueForPassive("low_health_shield", 1) >= 1) { if (GetHitpointPercentage() <= GetCardValueForPassive("low_health_shield", 1)) AddShield(4, GetCardValueForPassive("low_health_shield", 0)); return; } if (GetCardValueForPassive("shield_homerun", 1) >= 1) { if (ChargeUp >= ChargeUpMax || MeleeAttackPushBacks) AddShield(4, GetCardValueForPassive("shield_homerun", 1)); return; } if (GetCardValueForPassive("shield_while_charged_shots", 1) >= 1) { if (ChargedShotCount >= 1) AddShield(4, GetCardValueForPassive("shield_while_charged_shots", 1)); return; } if (GetCardValueForPassive("shield_while_charged_up", 1) >= 1) { if (ChargeUp >= ChargeUpMax) AddShield(4, GetCardValueForPassive("shield_while_charged_up", 1)); } if (GetCardValueForPassive("charged_bullet_speed", 1) >= 1) { if (ChargeUp >= ChargeUpMax) AttackAcceleratingFactor = GetCardValueForPassive("charged_bullet_speed", 1) * 2; else AttackAcceleratingFactor = 0; } if (GetCardValueForPassive("speed_ulti", 1) >= 1) { if (HasUlti()) GiveSpeedFasterBuff(GetCardValueForPassive("speed_ulti", 1), 10, true); return; } if (GetCardValueForPassive("medikit", 1) >= 1) { if (GetHitpointPercentage() <= GetCardValueForPassive("medikit", 1) && ChargeUp >= ChargeUpMax) { int v890 = (int)(((double)GetCardValueForPassive("medikit", 0) / 100) * (double)m_maxHitpoints); Heal(GetIndex(), v890, true, CharacterData); ChargeUp = 0; } return; } BattlePlayer v51 = GetPlayer(); if (v51 != null) { int v52 = v51.GetCardValueForPassive("plugged_in", 1); if (v52 >= 1 && !CharacterData.IsHero()) { StarPowerProjectileTimer--; if (StarPowerProjectileTimer <= 0) { Character v55 = (Character)GameObjectManager.GetGameObjectByID(ParentGID); int v56 = v51.GetCardValueForPassive("plugged_in", 2); if (v55 != null && v55.IsAlive()) { int v57 = 300 * v51.GetCardValueForPassive("plugged_in", 0); if (GamePlayUtil.GetDistanceSquaredBetween(GetX(), GetY(), v55.GetX(), v55.GetY()) < v57 * v57) { Projectile v66 = Projectile.ShootProjectile( -1, -1, this, this, DataTables.GetProjectileByName("ArcadeStarPowerProjectile"), v55.GetX(), v55.GetY(), 0, 0, 0, false, 0, GetBattle(), 0, 3); v66.HomingTarget = v55; v66.SetIndex(GetIndex()); v66.SpeedBuffModifier = v52; v66.SpeedBuffLength = 2 * v56; } } StarPowerProjectileTimer = v56; } } v52 = v51.GetCardValueForPassive("ulti_item_repeated_area", 1); if (v52 >= 1) { StarPowerProjectileTimer--; if (StarPowerProjectileTimer <= 0) { Item v55 = null; foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 3) continue; if (gameObject.GetIndex() != GetIndex()) continue; v55 = (Item)gameObject; break; } if (v55 != null) { AreaEffect areaEffect = GameObjectFactory.CreateGameObjectByData(DataTables.GetAreaEffectByName("WeaponThrowerElectroArea")); areaEffect.SetPosition(v55.GetX(), v55.GetY(), 0); areaEffect.SetIndex(GetIndex()); areaEffect.SetSource(this, 3); areaEffect.Damage = GetCardValueForPassive("ulti_item_repeated_area", 1); areaEffect.NormalDMG = 0; GameObjectManager.AddGameObject(areaEffect); areaEffect.Trigger(); StarPowerProjectileTimer = GetCardValueForPassive("ulti_item_repeated_area", 0); } } } v52 = v51.GetCardValueForPassive("pet_lifesteal", 1); // 1 shaman spg if (v52 >= 1) { } v52 = v51.GetCardValueForPassive("pet_attack_speed", 1); // 2 shaman spg if (v52 >= 1) { Character v55 = (Character)GameObjectManager.GetGameObjectByID(ParentGID); if (v55 != null) { } } } } private void TickTile() { TileMap tileMap = GameObjectManager.GetBattle().GetTileMap(); Tile tile = tileMap.GetTile(GetX(), GetY()); if (tile == null) { return; } if ((tile.Data.HidesHero && !tile.IsDestructed()) || IsInvisible) { DecrementFadeCounter(); } else { IncrementFadeCounter(); } int x = TileMap.LogicToTile(GetX()); int y = TileMap.LogicToTile(GetY()); if (TicksGone - m_lastTileDamageTick > 20) { if (GameObjectManager.GetBattle().IsTileOnPoisonArea(x, y)) { m_lastTileDamageTick = TicksGone; CauseDamage(null, 1000, 0, false, null); } } } public bool IsInBush() { TileMap tileMap = GameObjectManager.GetBattle().GetTileMap(); Tile tile = tileMap.GetTile(GetX(), GetY()); if (tile.Data.HidesHero && !tile.IsDestructed()) { return true; } return false; } public bool IsInWater() { TileMap tileMap = GameObjectManager.GetBattle().GetTileMap(); Tile tile = tileMap.GetTile(GetX(), GetY()); if (tile.Code == 'W' && !tile.IsDestructed()) { return true; } return false; } public void ShowDamageNumber(int a2, int a3, Character a4) { bool v7 = false; int v11; if (a4 != null) { SkillData v8 = a4.GetWeaponSkill() == null ? null : a4.GetWeaponSkill().SkillData; if (v8 != null) v7 = v8.NumBulletsInOneAttack > 1; } if (DamageNumbers.Count < 1) { if (v7) { v11 = DAMAGE_NUMBERS_DELAY_TICKS; } else { v11 = 0; } DamageNumber damageNumber = new DamageNumber(a3, a2, v11); DamageNumbers.Add(damageNumber); } else { foreach (DamageNumber DamageNumber in DamageNumbers) { if (DamageNumber.Dealer == a2) { DamageNumber.Value += a3; if (v7) { v11 = DAMAGE_NUMBERS_DELAY_TICKS; } else { v11 = 0; } DamageNumber.Delay = v11; return; } } if (v7) { v11 = DAMAGE_NUMBERS_DELAY_TICKS; } else { v11 = 0; } DamageNumber damageNumber = new DamageNumber(a3, a2, v11); DamageNumbers.Add(damageNumber); } } public void StopMovement() { MoveStart = TicksGone - 1; MoveEnd = TicksGone - 1; } private Character ShamanPetTarget; private void TickAI() { if (m_isBot != 0) { TickBot(); return; } if (CharacterData.IsHero()) return; } public void SetInvisible(int ticks = 3) { if (InvisibleTicks <= 0) IsInvisible = true; InvisibleTicks = ticks; } private void TickBot() { if (IsControlled) return; m_ticksSinceBotEnemyCheck++; m_botHadPathThisTick = false; if (TicksGone - m_lastBotMoveTick >= 10) { int dx = LogicMath.Abs(GetX() - m_lastBotPosX); int dy = LogicMath.Abs(GetY() - m_lastBotPosY); m_botStuckTicks = (dx < 50 && dy < 50) ? m_botStuckTicks + 1 : 0; m_lastBotPosX = GetX(); m_lastBotPosY = GetY(); m_lastBotMoveTick = TicksGone; } if (m_ticksSinceBotEnemyCheck > 20 || m_closestEnemy == null) { m_ticksSinceBotEnemyCheck = 0; Character found = null; int foundDist = 99999999; foreach (Character c in GameObjectManager.GetCharacters().ToList()) { if (!c.CharacterData.IsHero()) continue; if (!c.IsAlive() || c.m_hitpoints <= 0) continue; if (c.CharacterData.IsCarryable()) continue; if (c.GetIndex() / 16 == GetIndex() / 16) continue; if (c.IsInvisible) continue; int d = Position.GetDistance(c.GetPosition()); if (d < foundDist) { foundDist = d; found = c; } } if (found != null) { m_closestEnemy = found; m_closestEnemyPosition = found.GetPosition(); } } if (m_closestEnemy != null && m_closestEnemy.m_hitpoints > 0) m_closestEnemyPosition = m_closestEnemy.GetPosition(); else m_closestEnemy = null; bool tookDamage = m_hitpoints < m_botLastHp; m_botLastHp = m_hitpoints; TileMap tileMap = GameObjectManager.GetBattle().GetTileMap(); var pathFinder = GetBattle().GetPathFinder(); int moveTargetX = -1; int moveTargetY = -1; int mode = GetBattle().GetGameModeVariation(); int myTeam = GetIndex() / 16; int myScore = GetPlayer()?.GetScore() ?? 0; int separationOffsetX = 0; int separationOffsetY = 0; int botIndexInTeam = GetIndex() % 16; if (botIndexInTeam > 0) { int sepAngle = (botIndexInTeam * 90) % 360; int sepDist = 600 + botIndexInTeam * 200; separationOffsetX = LogicMath.Sin(sepAngle) * sepDist >> 10; separationOffsetY = LogicMath.Cos(sepAngle) * sepDist >> 10; } if (mode == 0 || mode == 25) { int myTeamGems = GetBattle().GetTeamScore(myTeam); int eneTeamGems = GetBattle().GetTeamScore(myTeam == 0 ? 1 : 0); if (myTeamGems >= 10 && GetPlayer() != null) { LogicVector2 spawn = GetPlayer().GetSpawnPoint(); moveTargetX = LogicMath.Clamp(spawn.X + separationOffsetX, 300, MapWidth - 300); moveTargetY = LogicMath.Clamp(spawn.Y + separationOffsetY, 300, MapHeight - 300); } else if (eneTeamGems >= 7 && m_closestEnemy != null) { moveTargetX = m_closestEnemyPosition.X; moveTargetY = m_closestEnemyPosition.Y; } else { Item closestGem = null; int gemDist = 99999999; foreach (Item item in GameObjectManager.GetItems()) { if (item.ItemData.Name != "Point") continue; int d = Position.GetDistance(item.GetPosition()); if (d < gemDist) { gemDist = d; closestGem = item; } } if (closestGem != null) { moveTargetX = closestGem.GetX() + separationOffsetX / 2; moveTargetY = closestGem.GetY() + separationOffsetY / 2; } else if (m_closestEnemy != null) { moveTargetX = m_closestEnemyPosition.X; moveTargetY = m_closestEnemyPosition.Y; } } } else if (mode == 5 || mode == 23) { Character ball = GetBattle().Carryable; if (ball != null) { bool ballIsCarried = ball.CarringCharacter != null && ball.CarringCharacter.IsAlive(); bool myTeamHasBall = ballIsCarried && ball.CarringCharacter.GetIndex() / 16 == myTeam; bool enemyHasBall = ballIsCarried && ball.CarringCharacter.GetIndex() / 16 != myTeam; if (myTeamHasBall) { List mySpawns = myTeam == 0 ? tileMap.SpawnPointsTeam1 : tileMap.SpawnPointsTeam2; List enemySpawns = myTeam == 0 ? tileMap.SpawnPointsTeam2 : tileMap.SpawnPointsTeam1; int mySpawnX = mySpawns.Count > 0 ? mySpawns[0].X : tileMap.LogicWidth / 2; int mySpawnY = mySpawns.Count > 0 ? mySpawns[0].Y : tileMap.LogicHeight / 2; int enemySpawnX = enemySpawns.Count > 0 ? enemySpawns[0].X : tileMap.LogicWidth / 2; int enemySpawnY = enemySpawns.Count > 0 ? enemySpawns[0].Y : tileMap.LogicHeight / 2; int goalY = mySpawnY > enemySpawnY ? 600 : tileMap.LogicHeight - 600; LogicVector2 goal = new LogicVector2(tileMap.LogicWidth / 2, goalY); bool iAmClosestToGoal = true; int myDistToGoal = Position.GetDistance(goal); foreach (Character ally in GetBattle().GetCharactersByTeam(myTeam)) { if (ally == this || !ally.IsAlive() || !ally.CharacterData.IsHero()) continue; if (ally.Position.GetDistance(goal) < myDistToGoal) iAmClosestToGoal = false; } if (iAmClosestToGoal) { moveTargetX = goal.X; moveTargetY = goal.Y; } else { moveTargetX = LogicMath.Clamp(ball.GetX() + separationOffsetX, 300, MapWidth - 300); moveTargetY = LogicMath.Clamp(ball.GetY() + separationOffsetY, 300, MapHeight - 300); } } else if (enemyHasBall) { moveTargetX = ball.CarringCharacter.GetX() + separationOffsetX / 3; moveTargetY = ball.CarringCharacter.GetY() + separationOffsetY / 3; } else { moveTargetX = LogicMath.Clamp(ball.GetX() + separationOffsetX / 3, 600, MapWidth - 600); moveTargetY = LogicMath.Clamp(ball.GetY() + separationOffsetY / 3, 600, MapHeight - 600); } } else { moveTargetX = tileMap.LogicWidth / 2 + separationOffsetX; moveTargetY = tileMap.LogicHeight / 2 + separationOffsetY; } } else if (mode == 3) { if (m_closestEnemy != null) { moveTargetX = m_closestEnemyPosition.X + separationOffsetX / 3; moveTargetY = m_closestEnemyPosition.Y + separationOffsetY / 3; } } else if (mode == 9 || mode == 6) { int hpPercent = m_maxHitpoints > 0 ? m_hitpoints * 100 / m_maxHitpoints : 100; Item closestItem = null; int itemDist = 99999999; foreach (Item item in GameObjectManager.GetItems()) { int d = Position.GetDistance(item.GetPosition()); if (d < itemDist) { itemDist = d; closestItem = item; } } Character teamingAlly = null; if (m_botTeamingUntil > TicksGone && m_botTeamingWith != -1) { foreach (Character c in GameObjectManager.GetCharacters().ToList()) { if (!c.CharacterData.IsHero() || !c.IsAlive()) continue; if (c == this) continue; if (c.m_isBot != 1) continue; if (c.m_botTeamingWith == GetIndex()) { teamingAlly = c; break; } } } if (m_botTeamingUntil <= TicksGone && m_botTeamingWith == -1) { Character nearbyBot = null; int nearbyDist = 99999999; foreach (Character c in GameObjectManager.GetCharacters().ToList()) { if (!c.CharacterData.IsHero() || !c.IsAlive()) continue; if (c == this) continue; if (c.m_isBot != 1) continue; if (c.m_botTeamingWith != -1) continue; int d = Position.GetDistance(c.GetPosition()); if (d < 2000 && d < nearbyDist) { nearbyDist = d; nearbyBot = c; } } int totalBotCount = GameObjectManager.GetCharacters().ToList() .Count(c => c.CharacterData.IsHero() && c.IsAlive() && c.m_isBot == 1); if (nearbyBot != null && totalBotCount > 3 && GetBattle().GetRandomInt(4) == 0 && nearbyBot.m_botTeamingWith == -1) { m_botTeamingWith = nearbyBot.GetIndex(); m_botTeamingUntil = TicksGone + GetBattle().GetRandomInt(40, 100); nearbyBot.m_botTeamingWith = GetIndex(); nearbyBot.m_botTeamingUntil = m_botTeamingUntil; } } if (m_botTeamingWith != -1 && m_botTeamingUntil <= TicksGone) { m_botTeamingWith = -1; m_botTeamingUntil = 0; } if (teamingAlly != null) { if (m_closestEnemy != null) { moveTargetX = m_closestEnemyPosition.X; moveTargetY = m_closestEnemyPosition.Y; } else { moveTargetX = LogicMath.Clamp(teamingAlly.GetX() + separationOffsetX, 300, MapWidth - 300); moveTargetY = LogicMath.Clamp(teamingAlly.GetY() + separationOffsetY, 300, MapHeight - 300); } } else if (hpPercent < 40 && closestItem != null) { moveTargetX = closestItem.GetX(); moveTargetY = closestItem.GetY(); } else if (m_closestEnemy != null) { moveTargetX = m_closestEnemyPosition.X + separationOffsetX / 3; moveTargetY = m_closestEnemyPosition.Y + separationOffsetY / 3; } else if (closestItem != null) { moveTargetX = closestItem.GetX(); moveTargetY = closestItem.GetY(); } } else if (mode == 17) { moveTargetX = LogicMath.Clamp(tileMap.LogicWidth / 2 + separationOffsetX, 300, MapWidth - 300); moveTargetY = LogicMath.Clamp(tileMap.LogicHeight / 2 + separationOffsetY, 300, MapHeight - 300); } else { if (m_closestEnemy != null) { moveTargetX = m_closestEnemyPosition.X + separationOffsetX / 3; moveTargetY = m_closestEnemyPosition.Y + separationOffsetY / 3; } else { bool wanderReached = LogicMath.Abs(GetX() - m_botWanderX) < 400 && LogicMath.Abs(GetY() - m_botWanderY) < 400; if (TicksGone >= m_botWanderUntil || wanderReached) { m_botWanderX = GetBattle().GetRandomInt(300, MapWidth - 300); m_botWanderY = GetBattle().GetRandomInt(300, MapHeight - 300); m_botWanderUntil = TicksGone + GetBattle().GetRandomInt(60, 150); } moveTargetX = m_botWanderX; moveTargetY = m_botWanderY; } } if (m_closestEnemy != null) { int distToEnemy = Position.GetDistance(m_closestEnemyPosition); int attackRange = m_skills[0] != null ? m_skills[0].SkillData.CastingRange * 50 : 3000; int retreatRange = attackRange * 5 / 10; int hpPercent = m_maxHitpoints > 0 ? m_hitpoints * 100 / m_maxHitpoints : 100; if (TicksGone >= m_botStateUntil) { if (tookDamage && hpPercent < 50) { if (m_botState != 2) m_botReactionDelay = GetBattle().GetRandomInt(5, 15); m_botState = 2; m_botStateUntil = TicksGone + GetBattle().GetRandomInt(40, 80); } else if (tookDamage && hpPercent < 75 && GetBattle().GetRandomInt(2) == 0) { if (m_botState != 3) { m_botStrafeDir = GetBattle().GetRandomInt(2) == 0 ? 1 : -1; m_botReactionDelay = GetBattle().GetRandomInt(5, 15); } m_botState = 3; m_botStateUntil = TicksGone + GetBattle().GetRandomInt(25, 50); } else if (distToEnemy < retreatRange && GetBattle().GetRandomInt(3) == 0) { if (m_botState != 3) { m_botStrafeDir = GetBattle().GetRandomInt(2) == 0 ? 1 : -1; m_botReactionDelay = GetBattle().GetRandomInt(5, 15); } m_botState = 3; m_botStateUntil = TicksGone + GetBattle().GetRandomInt(20, 40); } else { if (m_botState != 1) m_botReactionDelay = GetBattle().GetRandomInt(8, 18); m_botState = 1; m_botStateUntil = TicksGone + GetBattle().GetRandomInt(30, 60); } } if (m_botReactionDelay > 0) { m_botReactionDelay--; goto tryAttack; } if (m_botState == 2) { int retreatAngle = LogicMath.GetAngle(GetX() - m_closestEnemyPosition.X, GetY() - m_closestEnemyPosition.Y); retreatAngle += GetBattle().GetRandomInt(-20, 20); int dist = 700; moveTargetX = LogicMath.Clamp(GetX() + (LogicMath.Sin(retreatAngle) * dist >> 10), 300, MapWidth - 300); moveTargetY = LogicMath.Clamp(GetY() + (LogicMath.Cos(retreatAngle) * dist >> 10), 300, MapHeight - 300); } else if (m_botState == 3) { int strafeAngle = LogicMath.GetAngle(m_closestEnemyPosition.X - GetX(), m_closestEnemyPosition.Y - GetY()); strafeAngle += 90 * m_botStrafeDir; int dist = GetBattle().GetRandomInt(400, 700); moveTargetX = LogicMath.Clamp(GetX() + (LogicMath.Sin(strafeAngle) * dist >> 10), 300, MapWidth - 300); moveTargetY = LogicMath.Clamp(GetY() + (LogicMath.Cos(strafeAngle) * dist >> 10), 300, MapHeight - 300); } tryAttack: if (TicksGone - m_lastAIAttackTick > 30 && m_skills[0] != null) { Skill weapon = GetWeaponSkill(); if (weapon != null && weapon.HasEnoughCharge() && distToEnemy < attackRange * 70 / 100) { m_lastAIAttackTick = TicksGone; ActivateSkill(0, m_closestEnemyPosition.X, m_closestEnemyPosition.Y); BattlePlayer bot = GameObjectManager.GetBattle().GetPlayerWithObject(GetGlobalID()); if (bot != null && bot.GetUltiCharge() >= 4000 && GetBattle().GetRandomInt(3) == 0) ActivateSkill(1, m_closestEnemyPosition.X, m_closestEnemyPosition.Y); } } } if (moveTargetX == -1) { bool wanderReached = LogicMath.Abs(GetX() - m_botWanderX) < 400 && LogicMath.Abs(GetY() - m_botWanderY) < 400; if (TicksGone >= m_botWanderUntil || wanderReached) { m_botWanderX = GetBattle().GetRandomInt(300, MapWidth - 300); m_botWanderY = GetBattle().GetRandomInt(300, MapHeight - 300); m_botWanderUntil = TicksGone + GetBattle().GetRandomInt(60, 150); } moveTargetX = m_botWanderX; moveTargetY = m_botWanderY; } moveTargetX = LogicMath.Clamp(moveTargetX, 300, MapWidth - 300); moveTargetY = LogicMath.Clamp(moveTargetY, 300, MapHeight - 300); var path = pathFinder.FindPath(new LogicVector2(GetX(), GetY()), new LogicVector2(moveTargetX, moveTargetY)); if (path == null || path.Count <= 1) return; m_botHadPathThisTick = true; int pathIndex = Math.Min(2, path.Count - 1); MoveTo(0, path[pathIndex].X, path[pathIndex].Y, 0, 0, 0, 0); if (m_botStuckTicks >= 3 && m_closestEnemy != null) { m_botStuckTicks = 0; if (TicksGone < m_botDetourUntil) return; int detourAngle = LogicMath.NormalizeAngle360( LogicMath.GetAngle(m_closestEnemyPosition.X - GetX(), m_closestEnemyPosition.Y - GetY()) ); detourAngle += GetBattle().GetRandomInt(2) == 1 ? 90 : -90; int detourDist = GetBattle().GetRandomInt(400, 800); int dtx = LogicMath.Clamp(GetX() + (LogicMath.Sin(detourAngle) * detourDist >> 10), 1, MapWidth - 2); int dty = LogicMath.Clamp(GetY() + (LogicMath.Cos(detourAngle) * detourDist >> 10), 1, MapHeight - 2); var detourPath = pathFinder.FindPath(new LogicVector2(GetX(), GetY()), new LogicVector2(dtx, dty)); if (detourPath != null && detourPath.Count > 1) { int di = Math.Min(2, detourPath.Count - 1); m_botDetourX = detourPath[di].X; m_botDetourY = detourPath[di].Y; m_botDetourUntil = TicksGone + 20; MoveTo(0, m_botDetourX, m_botDetourY, 0, 0, 0, 0); } } } public void TickAreaEffectForCharge() { if (WayPoint.X == WayPointStart.X) return; if (WayPoint.Y == WayPointStart.Y) return; AreaEffectData area = DataTables.Get(DataType.AreaEffect).GetData("RollerFire"); AreaEffect areaEffect = new AreaEffect(area); areaEffect.SetPosition(GetX(), GetY(), 0); areaEffect.SetIndex(GetIndex()); areaEffect.SetSource(this, 2); areaEffect.Damage = area.Damage; areaEffect.NormalDMG = area.Damage; } public void TriggerCharge(int x, int y, int speed, int Type, int Damage, int Pushback, bool returning, AreaEffectData areaEffectdata = null) { int X = GetX(); int Y = GetY(); LogicVector2 t = new LogicVector2(x, y); bool hitBorder = GamePlayUtil.GetClosestLevelBorderCollision(X, Y, x, y, GetBattle().GetTileMap(), 1, t); if (Type == 7 && hitBorder) { int origDirX = x - X; int origDirY = y - Y; bool hitVerticalWall = LogicMath.Abs(origDirX) > LogicMath.Abs(origDirY); if (hitVerticalWall) origDirX = -origDirX; else origDirY = -origDirY; WayPoint2 = new LogicVector2( LogicMath.Clamp(t.X + origDirX * 2, 101, GetBattle().GetTileMap().LogicWidth - 102), LogicMath.Clamp(t.Y + origDirY * 2, 101, GetBattle().GetTileMap().LogicHeight - 102)); ShouldExecuteColetteChargeOnReturn = true; } if (t.X > x) t.X += 50; if (t.X < x) t.X -= 50; if (t.Y > y) t.Y += 50; if (t.Y < y) t.Y -= 50; x = t.X; y = t.Y; if (ChargeUpType == 1) ChargeUp = 0; if (GetCardValueForPassive("heal_on_charge", 1) >= 1) Heal(GetIndex(), GetCardValueForPassive("heal_on_charge", 1), true, null); Accessory accessory = GetPlayer()?.Accessory; // if (accessory != null && accessory.IsActive && accessory.AccessoryData.Type == "ulti_change" && accessory.AccessoryData.SubType == 2) // { // ChargeBreaksEnvironment = true; // accessory.EndAccessoryActivation(); // } // else ChargeBreaksEnvironment = false; FangUltiCount = 0; //TeamIndex = a1->TeamIndex; //if (TeamIndex >= 0) //{ // v20 = (1431655765LL* a4) >> 32; // v21 = ZNK21LogicGameObjectServer24getLogicBattleModeServerEv(); // a1 = ZN11LogicPlayer20increaseTeamingScoreEi(*(*(v21 + 72) + 4 * TeamIndex), ((v20 - a4) >> 1) + ((v20 - a4) >> 31)); //} //v22 = a15 == 0; //if (!a15) // a1 = a1->dword394; //if (!a15) // v22 = a1 == (&dword_0 + 1); //if (v22) // a1->dword38C = 0; if (Type != 10 || returning) { if (GetCardValueForPassive("shield_charge", 1) >= 1) { AddShield(GetCardValueForPassive("shield_charge", 2), GetCardValueForPassive("shield_charge", 1)); } //a1->UltiSkill = a15; m_stunTicks = 0; //a1->Rotate = 0; ChargeHits = 0; if (Type == 10) WayPoint2 = GetPosition(); } ChargeHitGIDs = new List(); FangHitGIDs = new List(); //if (a9 != 7) // JUMPOUT(0x324764); //v26 = GetX(); //v157[0] = v26; //v27 = GetY(); //v28 = x - v26; //v156 = v27; //v29 = y - v27; //v30 = LogicMath.Sqrt(v29 * v29 + v28 * v28); //v31 = v30; //v32 = 100 * a14; //v129 = 100 * a14; //if (v30) //{ // v28 = a1_divide_a2(v28 * v32, v30); // v29 = a1_divide_a2(v29 * v32, v31); //} //v155 = v26 + v28; //v154 = v27 + v29; //v153 = 0; //v152[1] = 0; //v151 = 0; //p[1] = 0; //v152[0] = 0; //p[0] = 0; //sub_6F83B4(v152, v157); //sub_6F83B4(p, &v156); //v33 = a1; //v34 = ZNK21LogicGameObjectServer24getLogicBattleModeServerEv(); //v35 = sub_5F01A8(v34); //v36 = v156; //v37 = v157[0]; //v124 = v35; //v131 = 0; //v126 = 0; //while (1) { if (Type == 4 || Type == 7 || Type == 8 || Type == 10 || (Type == 12 && !ChargeBreaksEnvironment)) { int v46; int v47; LogicVector2 v148 = new LogicVector2(-1, -1); bool v38 = GamePlayUtil.GetClosestAnyCollision( X, Y, x, y, GameObjectManager.GetBattle().GetTileMap(), v148, 0, 0, 0, 0); bool v127 = v38; if (v148.X == -1) { v47 = y; v46 = x; } else { int v39 = v148.X - X; int v40 = Y; int v41 = v148.Y - Y; int v42 = LogicMath.Sqrt(v39 * v39 + v41 * v41); if (v42 > 0) { int v43 = v42; int v44 = 20; if (v43 <= 20) v44 = LogicMath.Max(1, v43 - 5); int v45 = v43 - v44; v39 = (v43 - v44) * v39 / v43; v41 = v45 * v41 / v43; } v46 = v39 + X; v47 = v41 + v40; y = v41 + v40; x = v46; } //int v48 = LogicMath.Sqrt((v46 - X) * (v46 - X) + (v47 - Y) * (v47 - Y)); if (Type == 7 && v38) { int moveDirX = x - X; int moveDirY = y - Y; int len = LogicMath.Sqrt(moveDirX * moveDirX + moveDirY * moveDirY); if (len > 0) { bool hitVerticalWall = LogicMath.Abs(moveDirX) > LogicMath.Abs(moveDirY); if (hitVerticalWall) moveDirX = -moveDirX; else moveDirY = -moveDirY; int bounceTargetX = x + moveDirX * 2; int bounceTargetY = y + moveDirY * 2; bounceTargetX = LogicMath.Clamp(bounceTargetX, 101, GameObjectManager.GetBattle().GetTileMap().LogicWidth - 102); bounceTargetY = LogicMath.Clamp(bounceTargetY, 101, GameObjectManager.GetBattle().GetTileMap().LogicHeight - 102); WayPoint2 = new LogicVector2(bounceTargetX, bounceTargetY); ShouldExecuteColetteChargeOnReturn = true; } } x = LogicMath.Clamp(x, 101, GameObjectManager.GetBattle().GetTileMap().LogicWidth - 102); y = LogicMath.Clamp(y, 101, GameObjectManager.GetBattle().GetTileMap().LogicHeight - 102); } if (Type == 2 || Type == 6 || Type == 9 || Type == 11 || Type == 16) { LogicVector2 v = new(); GamePlayUtil.GetClosestPassableSpot(1, x, y, 10, GetBattle().GetTileMap(), v, true); x = v.X; y = v.Y; } // sub_6F83B4(v152, &v155); // sub_6F83B4(p, &v154); // v55 = v129; // v56 = v48 + v131; // v131 += v48; // if (!v38 || (v57 = 1, v56 >= v129 - 50)) // { // v58 = ZN12LogicTileMap21logicToPathFinderTileEi(v155); // v59 = ZN12LogicTileMap21logicToPathFinderTileEi(v154); // v60 = sub_432FEC(v33); // if (ZNK12LogicTileMap20isPassablePathFinderEiiibb(v124, v60, v58, v59, 0, 0)) // goto LABEL_36; // v57 = 0; // v55 = v129 + 300; // ++v126; // } // v61 = v155; // v62 = v155 - v37; // v125 = v154; // v63 = v154 - v36; // v64 = LogicMath.Sqrt(v62 * v62 + v63 * v63); // if (v57) // { // v65 = v127 == 4; // if (v127 != 4) // v65 = v127 == 1; // if (v65) // v63 = -v63; // else // v62 = -v62; // } // v129 = v55; // if (v64) // { // v62 = a1_divide_a2(v62 * (v55 - v131), v64); // v63 = a1_divide_a2(v63 * (v55 - v131), v64); // } // v155 += v62; // v154 += v63; // v37 = v61; // v36 = v125; // v33 = a1; // if (v126 >= 10) // { // LABEL_36: // if (v33->WayPoints >= 1) // { // do // sub_2234E4(v33); // while (v33->WayPoints > 0); // } // v66 = ZNK21LogicGameObjectServer4getXEv(v33); // v33->field_54 = ZN12LogicTileMap21logicToPathFinderTileEi(v66); // v67 = ZNK21LogicGameObjectServer4getYEv(v33); // v33->field_58 = ZN12LogicTileMap21logicToPathFinderTileEi(v67); // v33->field_5C = ZN12LogicTileMap21logicToPathFinderTileEi(*(v152[0] + 4 * v153 - 4)); // v33->field_60 = ZN12LogicTileMap21logicToPathFinderTileEi(*(p[0] + v151 - 1)); // v68 = v153; // v132 = v153 - 1; // if (v153 >= 1) // { // v69 = 4 * v153 - 4; // v70 = 0; // p_YwayPoints = &a1->YwayPoints; // p_XwayPoints = &a1->XwayPoints; // do // { // v73 = (v152[0] + v69); // if (v70) // { // sub_6F83B4(p_XwayPoints, v73); // v74 = (p[0] + v69); // v75 = p_YwayPoints; // } // else // { // v76 = *v73; // v77 = v68; // v78 = *(p[0] + v132); // ZN12LogicVector2C2Ev(v146); // v79 = sub_432FEC(a1); // v80 = v78; // v68 = v77; // v81 = v76; // p_YwayPoints = &a1->YwayPoints; // sub_48C8C4(v79, v81, v80, 5, v124, v146, 0); // sub_6F83B4(p_XwayPoints, v146); // v75 = &a1->YwayPoints; // v74 = &v147; // } // sub_6F83B4(v75, v74); // --v70; // v69 -= 4; // } // while (v68 + v70 > 0); // } //v82 = ZNK21LogicGameObjectServer24getLogicBattleModeServerEv(); // v83 = ZN21LogicBattleModeServer13getPathFinderEv(v82); // ZN20LogicCharacterServer12ensurePathOkEP15LogicPathFinder(a1, v83); if (x == GetX()) y -= 100; PathfindTo(0, x, y, 0, 0, 0, 0, 0, 0); int v84 = GetPathLength(); PathLength = v84; int pathlength = PathLength; if (v84 > 0) { MoveStart = TicksGone; if (Type == 2 || Type == 6 || Type == 9 || Type == 11 || Type == 16) { int range = m_skills[1].SkillData.CastingRange; if (range == 0) range = 22; //speed = speed * PathLength / range / 100; //speed = speed * 7 / 10; if (Type == 9) speed = (int)(speed * 0.3); //if (Type == 11) speed = (int)(speed * 0.7); if (Type == 16) speed = (int)(speed * 0.8); //if (Type == 2) speed = (int)(speed * 0.95); //if (Type == 6) speed = (int)(speed * 0.9); speed = LogicMath.Max(speed, 1); if (Type == 2 || Type == 6 || Type == 11) pathlength = 2300; } MoveEnd = LogicMath.Max(1, 20 * pathlength / speed) + TicksGone; //if(Type==2||Type==6) MoveEnd = LogicMath.Max(1, 20 * m_skills[1].SkillData.CastingRange*100 / speed) + TicksGone; } //a1->field_158 = 0; IsCharging = true; /* if (CharacterData.UniqueProperty == 4) { AddShield(CharacterData.UniquePropertyValue1, CharacterData.UniquePropertyValue2); }*/ //v8 = *(v4 + 12); //v9 = *(v4 + 8); if (GetCardValueForPassive("super_reload", 1) >= 0) ReloadBuffTicks = GetCardValueForPassive("super_reload", 1); //*&v1->gap1BE[2] = 0; //v1->field_14C = 0; ChargeSpeed = speed; //v1->FangUltiCount = 0; ChargeDamage = Damage; //v1->field_180 = v9; //v1->field_184 = 0; ChargePushback = Pushback; m_activeChargeType = Type; ShouldExecuteColetteChargeOnReturn = returning; //*v1->gap190 = v7; if (Type == 6) { //v18 = *(v4 + 40); //v19 = ZNK21LogicGameObjectServer4getXEv(v34); //v20 = ZNK21LogicGameObjectServer4getYEv(v34); //v21 = *(v34 + 40); //v22 = *(v34 + 44); //v23 = ZNK21LogicGameObjectServer24getLogicBattleModeServerEv(); //v32 = v18; //v1 = v34; //sub_5EEF4C(*(v4 + 32), v19, v20, *(v4 + 36), v32, v33, v9, v21, v22, v34, v23, 2); } else if (Type == 2 || Type == 11) { AreaEffect areaEffect = new AreaEffect(areaEffectdata); areaEffect.SetPosition(GetX(), GetY(), 0); areaEffect.SetIndex(GetIndex()); areaEffect.SetSource(this, 2); areaEffect.Damage = Damage; areaEffect.NormalDMG = ChargeNormalDMG; //v14 = GetCardValueForPassive(v1, 21, 1); //if (v14 >= 0) // v11[25] = v14; int v15 = GetCardValueForPassive("prey_on_the_weak", 1); if (v15 >= 0) { areaEffect.SetPreyOnTheWeak(v15, GetCardValueForPassive("prey_on_the_weak", 0)); } GameObjectManager.AddGameObject(areaEffect); areaEffect.Trigger(); ChargeAreaEffectData = areaEffectdata; } //dword2A0 = v1->dword2A0; //if (dword2A0) //{ // v25 = ZNK21LogicGameObjectServer4getXEv(v1); // v26 = ZNK21LogicGameObjectServer24getLogicBattleModeServerEv(); // v27 = ZN21LogicBattleModeServer12getRandomIntEii(v26, -100, 100); // v28 = ZNK21LogicGameObjectServer4getYEv(v1); // v29 = ZNK21LogicGameObjectServer24getLogicBattleModeServerEv(); // v30 = ZN21LogicBattleModeServer12getRandomIntEii(v29, -100, 100); // dword2A0 = sub_1F4FCC(v1, v27 + v25, v30 + v28); //} ////} } //v145 = GetX(); //v89 = GetY(); //v90 = x - v145; //v91 = v145; //v92 = y - v89; //v144 = v89; //v93 = LogicMath.Sqrt(v92 * v92 + v90 * v90); //if (v93) //{ // v94 = v93; // v90 = a1_divide_a2(v90 * 100 * a14, v93); // v92 = a1_divide_a2(v92 * 100 * a14, v94); //} //v143 = 0; //v142[1] = 0; //v141 = 0; //v140[1] = 0; //v142[0] = 0; //v140[0] = 0; //sub_6F83B4(v142, &v145); //sub_6F83B4(v140, &v144); //v95 = ZNK21LogicGameObjectServer24getLogicBattleModeServerEv(); //v96 = sub_5F01A8(v95); //ZN12LogicVector2C2Ev(&v138); //v139 = -1; //v138 = -1; //v133 = v96; //v97 = v91 + v90; //v98 = v89 + v92; //if (ZN17LogicGamePlayUtil22getClosestAnyCollisionEiiiiPK12LogicTileMapP12LogicVector2bbbb( // v145, // v144, // v97, // v89 + v92, // v96, // &v138, // 0, // 0, // 0, // 0)) //{ // v99 = v138 - v145; // v100 = v139 - v144; // v101 = LogicMath.Sqrt(v99 * v99 + v100 * v100); // if (v101) // { // v102 = v101; // v103 = LogicMath.Max(1, v101 - 150); // v99 = a1_divide_a2(v103 * v99, v102); // v100 = a1_divide_a2(v103 * v100, v102); // } // v98 = v144 + v100; // v97 = v145 + v99; //} //v137 = LogicMath.Clamp(v97, 1, v133[26] - 2); //sub_6F83B4(v142, &v137); //v136 = LogicMath.Clamp(v98, 1, v133[27] - 2); //sub_6F83B4(v140, &v136); //sub_6F83B4(v142, &v145); //sub_6F83B4(v140, &v144); //if (a1->WayPoints >= 1) //{ // do // sub_2234E4(a1); // while (a1->WayPoints > 0); //} //v104 = GetX(); //a1->field_54 = ZN12LogicTileMap21logicToPathFinderTileEi(v104); //v105 = GetY(); //a1->field_58 = ZN12LogicTileMap21logicToPathFinderTileEi(v105); //a1->field_5C = ZN12LogicTileMap21logicToPathFinderTileEi(*(v142[0] + 4 * v143 - 4)); //a1->field_60 = ZN12LogicTileMap21logicToPathFinderTileEi(*(v140[0] + 4 * v141 - 4)); //v106 = v143; //v130 = v143 - 1; //if (v143 >= 1) //{ // v107 = 4 * v143 - 4; // v108 = 0; // v109 = &a1->YwayPoints; // v110 = &a1->XwayPoints; // do // { // v111 = (v142[0] + v107); // if (v108) // { // sub_6F83B4(v110, v111); // v112 = (v140[0] + v107); // v113 = v109; // } // else // { // v114 = v106; // v115 = *v111; // v116 = *(v140[0] + 4 * v130); // ZN12LogicVector2C2Ev(v134); // v117 = sub_432FEC(a1); // v118 = v115; // v106 = v114; // v109 = &a1->YwayPoints; // sub_48C8C4(v117, v118, v116, 5, v133, v134, 0); // sub_6F83B4(v110, v134); // v113 = &a1->YwayPoints; // v112 = &v135; // } // sub_6F83B4(v113, v112); // --v108; // v107 -= 4; // } // while (v106 + v108 > 0); //} //v119 = ZNK21LogicGameObjectServer24getLogicBattleModeServerEv(); //v120 = ZN21LogicBattleModeServer13getPathFinderEv(v119); //ZN20LogicCharacterServer12ensurePathOkEP15LogicPathFinder(a1, v120); //v121 = ZNK20LogicCharacterServer13getPathLengthEv(a1); //*&a1->MoveLength = v121; //if (v121 <= 0) // JUMPOUT(0x324724); //v122 = ZNK21LogicGameObjectServer24getLogicBattleModeServerEv(); //ZNK21LogicBattleModeServer12getTicksGoneEv(v122); //return sub_3246FC(*&a1->MoveLength); } public int GetActiveSkillShield() { foreach (Skill skill in m_skills) { if (skill.SkillData.BehaviorType == "Shield" && skill.TicksActive > 0) return skill.SkillData.MsBetweenAttacks; } return 0; } public Projectile GetClosestProjectileFlyingAgainstYou() { Projectile closestEnemy = null; int distance = 99999999; foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 1) continue; // not a character, ignore. Projectile enemy = (Projectile)gameObject; if (enemy == null) continue; // invalid object if (enemy.GetIndex() / 16 == GetIndex() / 16 || enemy.State == 4) continue; // teammate, ignore. int distanceToEnemy = Position.GetDistance(enemy.GetPosition()); if (distanceToEnemy < distance) { closestEnemy = enemy; distance = distanceToEnemy; } } return closestEnemy; } public Character GetClosestEnemy(int RangeSubTiles, int Type, bool IgnoreVisibility, bool IgnoreVisibility2, List IgnoreTargets, bool RequireLOS, bool TargetTeammates, bool TargetFullHP) { Character closestEnemy = null; int distance = RangeSubTiles * 100; foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 0) continue; // not a character, ignore. Character enemy = (Character)gameObject; if (enemy == null) continue; // invalid object if (enemy.m_hitpoints <= 0) continue; if (enemy.CharacterData.IsCarryable()) continue; if (enemy.GetIndex() / 16 == GetIndex() / 16 || enemy.IsImmuneAndBulletsGoThrough(IsInRealm) || enemy.IsInvincible) continue; // teammate, ignore. if (!enemy.IsAlive()) continue; if (enemy.GetFadeCounter() < 1 && !IgnoreVisibility) continue; int distanceToEnemy = Position.GetDistance(enemy.GetPosition()); if (distanceToEnemy < distance) { closestEnemy = enemy; distance = distanceToEnemy; } } return closestEnemy; } public Character GetClosestEnemy() { Character closestEnemy = null; int distance = 99999999; foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 0) continue; // not a character, ignore. Character enemy = (Character)gameObject; if (enemy == null) continue; // invalid object if (enemy.m_hitpoints <= 0) continue; if (enemy.CharacterData.IsCarryable()) continue; if (enemy.GetIndex() / 16 == GetIndex() / 16 || enemy.IsImmuneAndBulletsGoThrough(IsInRealm) || enemy.IsInvincible) continue; // teammate, ignore. int distanceToEnemy = Position.GetDistance(enemy.GetPosition()); if (distanceToEnemy < distance) { closestEnemy = enemy; distance = distanceToEnemy; } } return closestEnemy; } public Character GetClosestVisibleEnemy() { Character closestEnemy = null; int distance = 99999999; foreach (GameObject gameObject in GameObjectManager.GetVisibleGameObjects(GetIndex(), GetGlobalID())) { if (gameObject.GetObjectType() != 0) continue; // not a character, ignore. Character enemy = (Character)gameObject; if (enemy == null) continue; // invalid object if (enemy.m_hitpoints <= 0) continue; if (enemy.CharacterData.IsCarryable()) continue; if (enemy.GetIndex() / 16 == GetIndex() / 16 || enemy.IsInvisible) continue; // teammate, ignore. int distanceToEnemy = Position.GetDistance(enemy.GetPosition()); if (distanceToEnemy < distance) { closestEnemy = enemy; distance = distanceToEnemy; } } return closestEnemy; } public Character GetEnemy() { Character closestEnemy = null; int distance = 99999999; foreach (GameObject gameObject in GameObjectManager.GetVisibleGameObjects(GetIndex(), GetGlobalID())) { if (gameObject.GetObjectType() != 0) continue; // not a character, ignore. Character enemy = (Character)gameObject; if (enemy == null) continue; // invalid object if (enemy.m_hitpoints <= 0) continue; if (enemy.CharacterData.IsCarryable()) continue; if (enemy.GetIndex() / 16 == GetIndex() / 16) continue; // teammate, ignore. int distanceToEnemy = Position.GetDistance(enemy.GetPosition()); if (distanceToEnemy < distance) { closestEnemy = enemy; distance = distanceToEnemy; } } return closestEnemy; } public Character GetTeammateForHeal() { Character closestEnemy = null; int distance = 99999999; foreach (GameObject gameObject in GameObjectManager.GetVisibleGameObjects(GetIndex(), GetGlobalID())) { if (gameObject.GetObjectType() != 0) continue; // not a character, ignore. Character enemy = (Character)gameObject; if (enemy == null) continue; // invalid object if (enemy.m_hitpoints <= 0) continue; if (enemy.m_hitpoints >= enemy.m_maxHitpoints) continue; if (!enemy.CharacterData.IsHero()) continue; if (enemy.CharacterData.IsCarryable()) continue; if (enemy.GetIndex() / 16 != GetIndex() / 16) continue; // not teammate, ignore. int distanceToEnemy = Position.GetDistance(enemy.GetPosition()); if (distanceToEnemy < distance) { closestEnemy = enemy; distance = distanceToEnemy; } } return closestEnemy; } private int GetRegeneratePerSecond() { if (CharacterData.IsHero()) { return 13 * m_maxHitpoints / 100; } return 0; } public int GetCardValueForPassive(string a2, int a3) { if (StarPowerData != null) { if (StarPowerData.Type == a2) { if (a3 == 2) return StarPowerData.Value3; return a3 > 0 ? StarPowerData.Value : StarPowerData.Value2; } else return -1; } else return -1; } private void TickHeals() { if (!CanHeal) return; if (!CharacterData.IsHero()) return; if (IsInvincible) { HealthRegenBlockedTick = TicksGone; } if (ExtraRegenTicks >= 1) { ExtraRegenTicks--; if ((ExtraRegenTicks + 1) % 20 == 0) Heal(ExtraRegenerIndex, ExtraRegenAmount, true, null); } foreach (Buff buff in m_buffs) { if (buff.Type == 10 && buff.Duration % 20 == 0) Heal(buff.SourceIndex, buff.Modifier, true, null); } int v6 = TicksGone; int v8 = GetCardValueForPassive("repair_self", 1); int result; if (v8 < 0) result = 60; else { result = 60 - v8; if (result <= 21) result = 21; } if (TicksGone >= HealthRegenedTick + 20) { int v7 = GetRegeneratePerSecond(); if ((v7 < 0 || v6 >= HealthRegenBlockedTick + result) && v7 > 0 && v6 >= DEPLOY_TICKS_FIRST_SPAWN) { if (m_hitpoints < m_maxHitpoints) v7 += v7 * GetGearBoost(1) / 100; if (v7 < 1) { } else { Heal(GetIndex(), v7, false, CharacterData); HealthRegenedTick = TicksGone; } } } if (TicksGone >= HealthRegenedTickSP + 20) { bool v10 = false; int v15 = GetCardValueForPassive("heal_forest", 1); if (v15 >= 0) { if (IsInBush()) { Heal(GetIndex(), (int)(((double)v15 / 1000) * (double)m_maxHitpoints), true, CharacterData); v10 = true; } } if (GetActiveSkill("Invisibility") != null && IsInvisible) { int v42 = (int)(((double)GetCardValueForPassive("heal_invisible", 1) / 1000) * (double)m_maxHitpoints); if (v42 >= 0) { Heal(GetIndex(), v42, true, CharacterData); v10 = true; } } if (AoeRegenerate >= 1) { foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 0) continue; Character v31 = (Character)gameObject; if (v31.IsAlive() && v31.GetIndex() / 16 == GetIndex()) { if (v31 != this && v31.CharacterData.IsHero() && v31.m_hitpoints < v31.m_maxHitpoints) { AreaEffectData v49 = DataTables.GetAreaEffectByName("AutoHeal"); int v48 = v31.GetX(); int v36 = GetX(); int v47 = v31.GetY(); int v46 = GetY(); int v37 = AreaEffect.GetRangeAgainst(v49, v31) - 100; if (LogicMath.Abs(v48 - v36) <= v37 && LogicMath.Abs(v47 - v46) <= v37 && (v48 - v36) * (v48 - v36) + (v47 - v46) * (v47 - v46) <= (v37 * v37)) { AreaEffect v38 = GameObjectFactory.CreateGameObjectByData(v49); v38.SetPosition(GetX(), GetY(), 0); v38.SetIndex(GetIndex()); v38.SetSource(this, 3); v38.Damage = -AoeRegenerate; v38.NormalDMG = 0; GameObjectManager.AddGameObject(v38); v38.Trigger(); HealthRegenedTick = TicksGone; v10 = true; break; } } } } } if (GetCardValueForPassive("heal_continuous", 1) >= 1) { if (TicksGone >= HealthRegenedTickSP + GetCardValueForPassive("heal_continuous", 0)) { Heal(GetIndex(), (m_maxHitpoints - m_hitpoints) * GetCardValueForPassive("heal_continuous", 1) / 100, false, CharacterData); v10 = true; } } if (v10) HealthRegenedTickSP = TicksGone; } } public bool IsObject() { return !CharacterData.HasAutoAttack() && CharacterData.Speed == 0; } public void TriggerStun(int a2, bool a3) { if(this.CharacterData.IsCarryable()) return; if (a2 >= 1) { if ((!IsInvincible && !HasCcImmunity()) || a3) { m_stunTicks = a2; InterruptAllSkills(false); if (GetCardValueForPassive("ulti_defense", 1) >= 0) { ShieldTicks = 0; } if ((!IsCharging && !KnockBacked) || a3) { StopMovement(); } if (GetControlledProjectile() != null) { GetControlledProjectile().TargetReached(5); } } IsWeaklyStunned = false; } } public bool Heal(int DealerIndex, int healing, bool shouldShow, LogicData projectileData) { if (m_hitpoints >= 1) { if (Immunitys.Count >= 1) { foreach (Immunity immunity in Immunitys) { if (immunity.TargetIndex == DealerIndex && immunity.TargetData == projectileData) return false; } } int HP = m_hitpoints; int v23 = LogicMath.Min(m_maxHitpoints, HP + healing); m_hitpoints = v23; if (shouldShow && m_hitpoints > HP) DamageNumbers.Add(new DamageNumber(-healing, DealerIndex, 0)); return true; } return false; } public void ChargeUlti(int a2, bool a3, bool a4, BattlePlayer a5, Character a6) { if (!a4) a2 += (a2 * a5.GetGearBoost(6) + 50) / 100; ((Character)GameObjectManager.GetGameObjectByID(a5.OwnObjectId))?.GetGearBoost(6); a5.ChargeUlti(a2, a3, a4); } public bool CauseDamage(Character damageDealer, int damage, int NormalDMG, bool SkillType, LogicData source, bool shouldShow = true, bool IgnoreInvincible = false, int X = -1, int Y = -1, bool isTransform = false) { if (CharacterData.IsCarryable() && damageDealer != null) return false; if (StopAI && CharacterData.IsHero()) return false; if (damage == 1) damage = 0; if (NormalDMG == 1) NormalDMG = 0; // if (CharacterData.Name == "StickyBomb") damage = 0; // if (CharacterData.Name == "StickyBomb") NormalDMG = 0; int index = damageDealer == null ? -1 : damageDealer.GetIndex(); bool result = false; if (IgnoreInvincible) goto LABEL_1; if (IsInvincible) { if (shouldShow) ShowDamageNumber(index, 0, damageDealer); return false; } if (HasBuff(15)) damage += damage * 35 / 100; if (Immunitys.Count >= 1) { foreach (Immunity immunity in Immunitys) { if (immunity.TargetData == source && immunity.TargetIndex == damageDealer?.GetIndex()) return false; } } if (m_hitpoints <= 0) { return result; } if (IsWeaklyStunned) { if (m_stunTicks > 0) m_stunTicks = 0; IsWeaklyStunned = false; } if (Accessory != null && (Accessory.Type == "return_damage" || Accessory.Type == "reload_shield") && Accessory.IsActive) { if (Accessory.Type == "return_damage") { if (damageDealer != null) { Projectile nani = Projectile.ShootProjectile(-1, -1, this, this, DataTables.GetProjectileByName(Accessory.AccessoryData.CustomObject), damageDealer.GetX(), damageDealer.GetY(), Accessory.AccessoryData.CustomValue1 * damage / 100, 0, 0, false, 0, GetBattle(), 0, 4); nani.HomingTarget = damageDealer; } } else if (Accessory.Type == "reload_shield") { GetWeaponSkill().AddCharge(this, 100 * Accessory.AccessoryData.CustomValue2); } damage -= damage * Accessory.AccessoryData.CustomValue1 / 100; Accessory.EndAccessoryActivation(); } if (Accessory != null && Accessory.Type == "take_damage" && Accessory.AccessoryData.SubType == 3 && Accessory.IsActive) { Accessory.RewindHP += damage; } int shield = 0; if (ShieldTicks > 0) { shield += ShieldPercent; } else shield = GetActiveSkillShield(); if (GetCardValueForPassive("reduce_all_damage", 1) >= 1) shield += GetCardValueForPassive("reduce_all_damage", 1); if (GetCardValueForPassive("running_reduces_damage", 1) >= 1 && X != -1) { int Angle = LogicMath.NormalizeAngle360(LogicMath.GetAngle(X - GetX(), Y - GetY()) - 180); if (Angle >= MoveAngle - GetCardValueForPassive("running_reduces_damage", 0) / 2 && Angle <= MoveAngle + GetCardValueForPassive("running_reduces_damage", 0) / 2) shield += GetCardValueForPassive("running_reduces_damage", 1); } if (GetPlayer()?.OverCharging ?? false) { if (CharacterData.OverchargeShieldPercent > 0) shield += CharacterData.OverchargeShieldPercent; else shield += 20; } if (shield >= 100) { ShowDamageNumber(index, 0, damageDealer); return false; } damage = LogicMath.Max(1, damage - shield * damage / 100); if (damage == 1) damage = 0; if (shouldShow && damage != 0) ShowDamageNumber(index, damage, damageDealer); if (GetCardValueForPassive("reduce_damage_periodically", 1) >= 1 && ChargeUp >= ChargeUpMax) { int v = LogicMath.Min(damage * GetCardValueForPassive("reduce_damage_periodically", 2) / 100, GetCardValueForPassive("reduce_damage_periodically", 0)); damage -= v; ChargeUp = 0; } if (ConsumableShield >= 1) { int v51 = LogicMath.Min(damage, ConsumableShield); damage -= v51; ConsumableShield -= v51; } if (Gear1 != null) { if (Gear1.ShieldAmount >= 1) { int dr = LogicMath.Min(damage, Gear1.ShieldAmount); damage -= dr; Gear1.ShieldAmount -= dr; GetGearBoost(4); } } if (Gear2 != null) { if (Gear2.ShieldAmount >= 1) { int dr = LogicMath.Min(damage, Gear2.ShieldAmount); damage -= dr; Gear2.ShieldAmount -= dr; GetGearBoost(4); } } if (source == null) { if (damageDealer != null) { if (damageDealer.CharacterData.IsHero()) { BattlePlayer v44 = damageDealer.GetPlayer(); if (v44 != null && v44.SkinData != null) { HitEffectSkin = v44.SkinData.GetInstanceId() + 1; } else HitEffectSkin = DataTables.Get(DataType.Skin).GetData(damageDealer.CharacterData.DefaultSkin).GetInstanceId() + 1; } } } else if (source.GetDataType() == 6) HitEffectProjectile = source.GetInstanceId() + 1; HandleHealFromDamage(damage, SkillType, damageDealer); int v55 = GetCardValueForPassive("reflect_damage_aoe", 1); if (v55 >= 1) { if (v55 * damage >= 100) TriggerAreaEffect(DataTables.GetAreaEffectByName("DrillerReflectArea"), GetX(), GetY(), v55 * damage / 100, 3); } LABEL_1: result = damage > 0; m_hitpoints -= damage; m_hitpoints = LogicMath.Max(m_hitpoints, 0); m_hitpoints = LogicMath.Min(m_hitpoints, m_maxHitpoints); if (damage > 0) { BlockHealthRegen(); SetForcedVisible(); } BattleMode battle = GameObjectManager.GetBattle(); if (CharacterData.Name == "KnightPet") // ������� �� ���� ������ � ���� ������������� { AreaEffect v1 = GameObjectFactory.CreateGameObjectByData(DataTables.GetAreaEffectByName("KnightPetExplosion")); v1.SetPosition(GetX(), GetY(), 0); v1.SetIndex(GetIndex()); v1.Damage = 300; // 1 lvl dmg v1.NormalDMG = 0; } if (CharacterData.IsHero() || CharacterData.IsTrainingDummy() || CharacterData.IsLootBox()) { if (damageDealer != null && damageDealer != this && !IsControlled) { BattlePlayer enemy = battle.GetPlayerWithObject(damageDealer.GetGlobalID()); if (enemy != null) { if (damage > 0 && !CharacterData.IsLootBox()) { ChargeUlti(NormalDMG, SkillType, false, enemy, damageDealer); if (damageDealer.CharacterData.UniqueProperty == 1) { damageDealer.AshLastRageTick = TicksGone; if (SkillType) damageDealer.ChargeUp += NormalDMG / 2; else damageDealer.ChargeUp += NormalDMG / 6 + NormalDMG / 6 * damageDealer.GetPowerLevel() / 4;//160 per mouse mouse damage:300 damageDealer.ChargeUp = LogicMath.Clamp(damageDealer.ChargeUp, 0, damageDealer.ChargeUpMax); } if (GetBattle().GetGameModeVariation() != 13) enemy.DamageDealed(damage); else enemy.DamageDealed(damage, TicksGone); } } } void CreateBattleRoyaleItem(ItemData data, int count = 1) { if (data == null) return; for (int i = 0; i < count; i++) { try { Item item = new Item(data); if (!GamePlayUtil.FindSafeDropPosition( GetBattle().GetTileMap(), GetX(), GetY(), 300, 400, out int targetX, out int targetY)) { continue; } int startX = targetX; int startY = targetY; int scatter = GetBattle().GetRandomInt(-400, 400); item.StartJumpEffect( startX, startY, 0, targetX + scatter, targetY + scatter, 0 ); GameObjectManager.AddGameObject(item); } catch (Exception ex) { } } } if (m_hitpoints <= 0) { if (GameObjectManager.GetBattle().GetGameModeVariation() == 6 || GameObjectManager.GetBattle().GetGameModeVariation() == 9) { ItemData data = DataTables.Get(18).GetData("BattleRoyaleBuff"); if (CharacterData.Name == "LootBox") { CreateBattleRoyaleItem(data); } else if (CharacterData.IsHero()) { int count = Math.Min(BattleRoyaleBuffs, 5); if (count <= 1) count = Math.Min(1, 5); CreateBattleRoyaleItem(data, count); } GameObjectManager.RemoveGameObject(this); } Projectile v113 = GetControlledProjectile(); if (v113 != null) v113.TargetReached(5); BattlePlayer player = battle.GetPlayerWithObject(GetGlobalID()); if (CharacterData.UniqueProperty == 2 && CharacterData.Name == "MechaDudeBig") { Character n = TriggerTransforming(DataTables.GetCharacterByName("MechaDude")); n.m_itemCount = m_itemCount; n.BattleRoyaleBuffs = BattleRoyaleBuffs; n.m_hitpoints = n.m_maxHitpoints; n.m_skills[0].Charge = 1000; player.OwnObjectId = n.GetGlobalID(); if (GetCardValueForPassive("mecha_explosion", 1) >= 1) { TriggerAreaEffect(DataTables.GetAreaEffectByName("MechaDudeDestroyExplosion"), GetX(), GetY(), 0, 3); } if (GetCardValueForPassive("downgrade_shield", 1) != -1) n.AddShield(GetCardValueForPassive("downgrade_shield", 0), GetCardValueForPassive("downgrade_shield", 12)); n.TriggerPushback(n.GetX(), n.GetY(), 50, true, 0, false, false, false, true, false, false, false, 0); n.Knockback3 = true; return result; } if (player != null) { if (damageDealer != null && damageDealer.GetPlayer() != null && GetBattle().GetGameModeVariation() == 25) damageDealer.GetPlayer().AddScore(1); GameObjectManager.RemoveGameObject(this); HitEffectSkin = 0; if (!isTransform) battle.PlayerDied(player); foreach (Item item in GameObjectManager.GetItems()) { if (item.Owner != null && item.Owner.GetIndex() == GetIndex() && item.Owner.CharacterData.Name == "WeaponThrower") { item.PickedUp = true; } } // if (player.Accessory != null) player.Accessory.Interrupt(false, this); } if (damageDealer != null) { if (damageDealer.GetCardValueForPassive("steal_souls2", 1) >= 0) { Projectile v125 = Projectile.ShootProjectile(-1, -1, this, this, DataTables.GetProjectileByName("HammerDudeStarPowerProjectile"), damageDealer.GetX(), damageDealer.GetY(), damageDealer.GetCardValueForPassive("steal_souls2", 1), 0, 0, false, 0, GetBattle(), 0, 3); v125.HomingTarget = damageDealer; v125.SetStealSouls2BuffingData(damageDealer.GetCardValueForPassive("steal_souls2", 1), 20 * damageDealer.GetCardValueForPassive("steal_souls2", 0)); v125.SetIndex(damageDealer.GetIndex()); } if (IsInRealm) { damageDealer.IsInRealm = false; IsInRealm = false; GameObjectManager.RemoveGameObject(RealmEffect); } BattlePlayer enemy = battle.GetPlayerWithObject(damageDealer.GetGlobalID()); if (GameObjectManager.GetBattle().GetGameModeVariation() == 3) { if (enemy != null) { damageDealer.AddItemsCollected(1); enemy.AddScore(m_itemCount + 2); } } if (enemy != null) { int bountyStars = GameObjectManager.GetBattle().GetGameModeVariation() == 3 ? m_itemCount + 1 : 0; enemy.KilledPlayer(GetIndex() % 16, bountyStars); if (HasBuff(15)) { if (GetBuff(15).BelleWeaponBounces >= 0) enemy.AddUltiCharge(2000); } } } if (GameObjectManager.GetBattle().GetGameModeVariation() == 0) { ItemData data = DataTables.Get(18).GetData("Point"); for (int i = 0; i < m_itemCount; i++) { int v165 = GetBattle().GetRandomInt(300, 600); int v167 = GetBattle().GetRandomInt(360); int v168 = LogicMath.GetRotatedX(v165, 0, v167); int v169 = LogicMath.GetRotatedY(v165, 0, v167); int v160 = LogicMath.Clamp(GetX() + v168, 1, MapWidth - 2); int v172 = LogicMath.Clamp(GetY() + v169, 1, MapHeight - 2); LogicVector2 logicVector2 = new(); GamePlayUtil.GetClosestPassableSpot(0, v160, v172, 10, GetBattle().GetTileMap(), logicVector2, true); v160 = logicVector2.X; v172 = logicVector2.Y; Item item = new Item(data); item.SetFromToPosition(GetX(), GetY(), GetZ(), v160, v172, 0); item.SetAngle(GameObjectManager.GetBattle().GetRandomInt(0, 360)); GameObjectManager.AddGameObject(item); } } } } if (m_hitpoints <= 0) { if (CharacterData.DeathAreaEffect != null) { TriggerAreaEffect(DataTables.GetAreaEffectByName(CharacterData.DeathAreaEffect), GetX(), GetY(), 0, 2); } if (AreaEffect != null) GameObjectManager.RemoveGameObject(AreaEffect); } return result; } public void AddItemsCollected(int a) { m_itemCount += a; if (GameObjectManager.GetBattle().GetGameModeVariation() == 3) { m_itemCount = LogicMath.Min(6, m_itemCount); } } public void ResetItemsCollected() { m_itemCount = 0; } public void HoldSkillStarted() { SkillHoldTicks = 0; } public void EndRapidFire() { Attacking = false; if (!UltiSkill && Accessory != null && Accessory.IsActive && Accessory.Type == "next_attack_change" && Accessory.AccessoryData.ActiveTicks == 100000) { Accessory.EndAccessoryActivation(); } /* if (CharacterData.UniqueProperty == 11 && UltiSkill) { string skill = null; SkillData skillData = m_skills[1].SkillData; switch (GetBattle().GetRandomInt(0, 4)) { case 0: skill = skillData.SecondarySkill; break; case 1: skill = skillData.SecondarySkill2; break; case 2: skill = skillData.SecondarySkill3; break; case 3: skill = skillData.SecondarySkill4; break; } m_skills[1] = new Skill(DataTables.Get(DataType.Skill).GetData(skill).GetGlobalId(), true, this); }*/ } public Skill GetWeaponSkill() { return m_skills.Count > 0 ? m_skills[0] : null; } public Skill GetUltimateSkill() { return m_skills.Count > 1 ? m_skills[1] : null; } public int GetPowerLevel() { if (CharacterData.UniqueProperty == 1) return LogicMath.Clamp(3 * ChargeUp / ChargeUpMax, 0, 2); if (GetPlayer() != null) return GetPlayer().PowerLevel; return 0; } public void InterruptAllSkills(bool IgnoreAccessory = true) { ChargeAnimation = 0; IsCharging = false; for (int i = 0; i < m_skills.Count; i++) { m_skills[i].Interrupt(this); } if (GetPlayer() == null || GetPlayer().Accessory == null) return; GetPlayer().Accessory.Interrupt(IgnoreAccessory, this); } public void AddAreaEffect(int a2, int a3, AreaEffectData a4, int a5, bool a6) { int v12; // w25 int v13; // w0 int v14; // x0 int v15; // x8 int v16; // w0 MAPDST int v17; // x22 int v19; // w8 int v20; // w20 int v21; // w0 BattlePlayer v22; // x0 SkinData v23; // x24 int v25; // x0 LABEL_2: if (a4 != null) { AreaEffect = new AreaEffect(a4); AreaEffect.SetPosition(GetX(), GetY(), 0); AreaEffect.SetIndex(GetIndex()); AreaEffect.SetSource(this, a5); AreaEffect.aoe_dot = a3; v16 = a4.Damage; if (v16 < 1) { v21 = 0; v20 = v16 - a2; } else { v20 = v16 + a2; v21 = a4.Damage; } AreaEffect.Damage = v20; AreaEffect.NormalDMG = v21; GameObjectManager.AddGameObject(AreaEffect); AreaEffect.Trigger(); return; } v22 = GetPlayer(); if (v22 != null) v23 = v22.SkinData; else v23 = null; if (GetCardValueForPassiveFromPlayer("larger_area_ulti", 1) >= 1) { if (v23 != null) { a4 = DataTables.GetAreaEffectByName(DataTables.Get(DataType.SkinConf).GetData(v23.Conf).AreaEffectStarPower); if (a4 != null) goto LABEL_2; } a4 = DataTables.GetAreaEffectByName("DamageBoost_larger"); if (a4 == null) return; goto LABEL_2; } else if (GetCardValueForPassiveFromPlayer("plugged_in", 1) >= 1) { if (v23 != null) { a4 = DataTables.GetAreaEffectByName(DataTables.Get(DataType.SkinConf).GetData(v23.Conf).AreaEffectStarPower2); if (a4 != null) goto LABEL_2; } a4 = DataTables.GetAreaEffectByName("DamageBoostPlugIn"); if (a4 == null) return; goto LABEL_2; } else if (GetCardValueForPassiveFromPlayer("super_charge_area", 1) >= 1) { a4 = DataTables.GetAreaEffectByName("RopeDudeSuperChargeAreaLarge"); if (a4 == null) return; goto LABEL_2; } else { if (v23 != null) { a4 = DataTables.GetAreaEffectByName(DataTables.Get(DataType.SkinConf).GetData(v23.Conf).AreaEffect); if (a4 != null) goto LABEL_2; } } a4 = DataTables.GetAreaEffectByName(CharacterData.AreaEffect); if (a4 != null) goto LABEL_2; } public void BlockHealthRegen() { HealthRegenBlockedTick = TicksGone; } async Task SpawnBombsWithDelayAsync() { BattlePlayer player = GameObjectManager.GetBattle().GetPlayerWithObject(this.GetGlobalID()); var skinData = DataTables.Get(DataType.Skin)?.GetDataByGlobalId(player.SkinId); if (skinData == null) return; var skinConfData = DataTables.Get(DataType.SkinConf)?.GetData(skinData.Conf); if (skinConfData == null) return; int startX = this.GetX(); int startY = this.GetY(); int startZ = this.GetZ(); TileMap tileMap = GetBattle().GetTileMap(); LogicVector2 collisionPoint = new LogicVector2(); void Direction(int fromX, int fromY, ref int x, ref int y, int offset) { float dx = x - fromX; float dy = y - fromY; float length = (float)Math.Sqrt(dx * dx + dy * dy); if (length == 0) return; dx /= length; dy /= length; x = (int)(x + dx * offset); y = (int)(y + dy * offset); } float OneBounceFunc(float x) { const float n1 = 7.5625f; const float d1 = 2.75f; if (x < 1 / d1) { return n1 * x * x; } else if (x < 2 / d1) { x -= 1.5f / d1; return n1 * x * x + 0.75f; } else if (x < 2.5f / d1) { x -= 2.25f / d1; return n1 * x * x + 0.9375f; } else { x -= 2.625f / d1; return n1 * x * x + 0.984375f; } } async Task MoveBombArc(Item bomb, int x, int y, int dura = 23, int a1 = 450) { int startX = bomb.GetX(); int startY = bomb.GetY(); int startZ = bomb.GetZ(); int fsz = startZ + 100; int fez = startZ; int steps = Math.Min(dura, 60); if (steps == 0) steps = 1; int delay = dura / steps; if (delay < 1 && dura > 0) delay = 1; for (int i = 1; i <= steps; i++) { float t = (float)i / steps; int curx = (int)(startX + (x - startX) * t); int cury = (int)(startY + (y - startY) * t); float height = a1 * (float)Math.Sin(t * Math.PI); cury -= (int)height; float zT = OneBounceFunc(t); int currz = (int)(fsz + (fez - fsz) * zT); bomb.SetPosition(curx, cury, currz); await Task.Delay(delay); } bomb.SetPosition(x, y, startZ); } async Task SpawnBomb(int targetX, int targetY) { Item bomb = GameObjectFactory.CreateGameObjectByData(DataTables.GetItemByName(skinConfData.SpawnedItem ?? "PiperdefBomb")); collisionPoint.X = targetX; collisionPoint.Y = targetY; bool hitBorder = GamePlayUtil.GetClosestLevelBorderCollision( startX, startY, targetX, targetY, tileMap, 0, collisionPoint); int spawnX = collisionPoint.X; int spawnY = collisionPoint.Y; if (hitBorder) { Direction(startX, startY, ref spawnX, ref spawnY, -50); } bomb.SetPosition(startX, startY, startZ); bomb.SetIndex(16 * player.TeamIndex); bomb.Owner = this; GameObjectManager.AddGameObject(bomb); _ = MoveBombArc(bomb, spawnX, spawnY); } await SpawnBomb(startX + 700, startY); await Task.Delay(85); await SpawnBomb(startX - 700, startY); await Task.Delay(85); await SpawnBomb(startX, startY + 700); await Task.Delay(100); await SpawnBomb(startX, startY - 700); } async Task SpawnTickItems() { BattlePlayer player = GameObjectManager.GetBattle().GetPlayerWithObject(this.GetGlobalID()); var skinData = DataTables.Get(DataType.Skin)?.GetDataByGlobalId(player.SkinId); if (skinData == null) return; var skinConfData = DataTables.Get(DataType.SkinConf)?.GetData(skinData.Conf); if (skinConfData == null) return; int startX = this.GetX(); int startY = this.GetY(); int startZ = this.GetZ(); TileMap tileMap = GetBattle().GetTileMap(); LogicVector2 collisionPoint = new LogicVector2(); void Direction(int fromX, int fromY, ref int x, ref int y, int offset) { float dx = x - fromX; float dy = y - fromY; float length = (float)Math.Sqrt(dx * dx + dy * dy); if (length == 0) return; dx /= length; dy /= length; x = (int)(x + dx * offset); y = (int)(y + dy * offset); } float OneBounceFunc(float x) { const float n1 = 7.5625f; const float d1 = 2.75f; if (x < 1 / d1) { return n1 * x * x; } else if (x < 2 / d1) { x -= 1.5f / d1; return n1 * x * x + 0.75f; } else if (x < 2.5f / d1) { x -= 2.25f / d1; return n1 * x * x + 0.9375f; } else { x -= 2.625f / d1; return n1 * x * x + 0.984375f; } } async Task MoveBombArc(Item bomb, int x, int y, int dura = 23, int a1 = 450) { int startX = bomb.GetX(); int startY = bomb.GetY(); int startZ = bomb.GetZ(); int fsz = startZ + 100; int fez = startZ; int steps = Math.Min(dura, 60); if (steps == 0) steps = 1; int delay = dura / steps; if (delay < 1 && dura > 0) delay = 1; for (int i = 1; i <= steps; i++) { float t = (float)i / steps; int curx = (int)(startX + (x - startX) * t); int cury = (int)(startY + (y - startY) * t); float height = a1 * (float)Math.Sin(t * Math.PI); cury -= (int)height; float zT = OneBounceFunc(t); int currz = (int)(fsz + (fez - fsz) * zT); bomb.SetPosition(curx, cury, currz); await Task.Delay(delay); } bomb.SetPosition(x, y, startZ); } async Task SpawnBomb(int targetX, int targetY) { Item bomb = GameObjectFactory.CreateGameObjectByData(DataTables.GetItemByName(skinConfData.SpawnedItem ?? "PiperdefBomb")); collisionPoint.X = targetX; collisionPoint.Y = targetY; bool hitBorder = GamePlayUtil.GetClosestLevelBorderCollision( startX, startY, targetX, targetY, tileMap, 0, collisionPoint); int spawnX = collisionPoint.X; int spawnY = collisionPoint.Y; if (hitBorder) { Direction(startX, startY, ref spawnX, ref spawnY, -50); } bomb.SetPosition(startX, startY, startZ); bomb.SetIndex(16 * player.TeamIndex); bomb.Owner = this; GameObjectManager.AddGameObject(bomb); _ = MoveBombArc(bomb, spawnX, spawnY); } await SpawnBomb(startX + 700, startY); await Task.Delay(85); await SpawnBomb(startX - 700, startY); await Task.Delay(85); await SpawnBomb(startX, startY + 700); await Task.Delay(100); await SpawnBomb(startX, startY - 700); } public void ToggleSam() { if (SamState) SamState = false; else SamState = true; } private void ToggleSamurai() { SamuraiAttackSlashAttack = !SamuraiAttackSlashAttack; } public void TriggerPortals(LogicVector2 a1Pos, LogicVector2 a2Pos) { } public void SetControl(Character Owner, int ticks) { IsControlled = true; Owner.ControlledCharacter = Owner; } public void ActivateSkill(int type, int x, int y) { if (Silence) return; if (GetZ() > 1) return; if (GetBattle().GetTicksGone() < 100) return; if (CharacterData.Name == "ClusterBomb") { if (type == 0) { Console.WriteLine("��������"); } } if (type == 1 && GetCardValueForPassive("speed_after_ulti", 1) >= 1) ApplyBuff(4, GetCardValueForPassive("speed_after_ulti", 1), GetCardValueForPassive("speed_after_ulti", 0), 10); if (IsPlayerControlRemoved() || (Accessory != null && Accessory.AccessoryData.InterruptsAction && Accessory.IsActive)) return; Skill skill = m_skills[type]; if (skill == null) return; if (skill.IsActive || skill.CoolDown > 0) return; TileMap tileMap = GameObjectManager.GetBattle().GetTileMap(); AttackAngle = LogicMath.GetAngle(x - GetX(), y - GetY()); if (GetBattle().Carryable != null && GetBattle().Carryable.CarringCharacter == this) { int speed = 2000; int distance = 2400; if (type == 0) { distance = 2400; speed = 2000; } if (type == 1) { distance = 3600; speed = 3400; } GetBattle().Carryable.SetPosition(GetX(), GetY(), 0); skill.ActivateLaserBall(this, type); GetBattle().Carryable.CarryablePickTicks = 10; GetBattle().Carryable.StopKicking(); GetBattle().Carryable.Kick(AttackAngle, speed, distance); GetBattle().Carryable.CarringCharacter = null; CarryablePersonImunTicks = 15; return; } skill.Activate(this, x, y, tileMap); if (skill.SkillData.ChargeType == 1) { DisplayUltiTmp = true; } if (skill.SkillData.ChargeType == 15) { SteerAngle = LogicMath.GetAngle(x - GetX(), y - GetY()); MoveAngle = SteerAngle; m_activeChargeType = 15; ChargeSpeed = skill.SkillData.ChargeSpeed; SteerStartTicks = TicksGone; } } public bool HasUlti() { int v2; // r0 BattlePlayer v3; // r0 int v5; // r0 if (!CharacterData.IsHero()) { return CharacterData.IsBoss(); } v3 = GetPlayer(); if (v3 != null) return v3.HasUlti(); return false; } public AreaEffect TriggerAreaEffect( AreaEffectData a2, int a3, int a4, int a5, int a6) { AreaEffect v9; // r5 int v10; // r6 v9 = new AreaEffect(a2); v9.SetPosition(a3, a4, 0); v9.SetIndex(GetIndex()); v9.SetSource(this, a6); v10 = 0; if (a6 == 1) v10 = v9.GetDamage(0); v9.Damage = v9.GetDamage(0) + a5; v9.NormalDMG = v10; GameObjectManager.AddGameObject(v9); v9.Trigger(); return v9; } void GetShootPositionModifiers( int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) { int v9; // r5 int v11; // r4 int v12; // r0 int v13; // r10 int v14; // r9 int v15; // r8 int v16; // r7 int v17; // r5 int v18; // r0 int v19; // r3 int result; // r0 int v21; // r2 int v22; // r2 int v23; // r3 v9 = a3 - a1; v11 = a4 - a2; v12 = LogicMath.Sqrt(v9 * v9 + v11 * v11); v13 = v9; v14 = v11; if (v12 != 0) { v13 = v9 * a6 / v12; v14 = v11 * a6 / v12; } v15 = a5; v16 = LogicMath.GetRotatedX(v9, v11, 90); v17 = LogicMath.GetRotatedY(v9, v11, 90); v18 = LogicMath.Sqrt(v16 * v16 + v17 * v17); if (v18 != 0) { v16 = v16 * a7 / v18; v15 = a5; v17 = v17 * a7 / v18; } v19 = v13 + a1; result = a9; v21 = v14 + a2; if (v15 != 0) { v22 = v21 - v17; v23 = v19 - v16; v17 = -v17; v16 = -v16; } else { v22 = v17 + v21; v23 = v16 + v19; } AttackOffsetX = v23; AttackOffsetY = v22; AttackOffset2X = v16; AttackOffset2Y = v17; } public void MeleeAttack(Character Target, int X, int Y, int Damage, int NormalDMG) {//Self Confident if (Target != null) { if (GamePlayUtil.GetDistanceBetween(GetX(), GetY(), Target.GetX(), Target.GetY()) <= CharacterData.AutoAttackRange * 100) { if (Target.CauseDamage(this, Damage, NormalDMG, UltiSkill, null)) { ; } } } } public void RapidFireMeleeAttack( int X, int Y, int Damage, int NormalDMG, int Spread) { int v9; // r0 int v10; // r5 int v11; // r4 int v15; // r5 int v17; // r4 int v18; // r8 int v19; // r4 int v20; // r4 int v21; // r10 int v22; // r0 int v23; // r4 float v24; // r0 float v25; // r0 int v26; // r1 int v27; // r8 int v28; // r10 int v29; // r4 int v30; // r7 int v31; // r0 int v32; // r3 int v33; // r8 int v34; // r7 int v35; // r0 bool v36; // r0 bool v37; // zf int v38; // r4 int v39; // r0 int v40; // r0 int v41; // r5 int v42; // r0 int v43; // r8 int v44; // r7 int v45; // r5 int result; // r0 int v47; // r10 int v48; // r0 int v51; // r9 int v52; // r6 int v53; // r5 int v55; // r5 int v56; // r0 float v57; // r0 int v58; // r1 int v59; // r0 int v60; // r0 int v61; // r4 int v62; // r0 int v64; // [sp+8h] [bp-70h] int v65; // [sp+34h] [bp-44h] int v66; // [sp+38h] [bp-40h] int v67; // [sp+3Ch] [bp-3Ch] int v68; // [sp+40h] [bp-38h] int v69; // [sp+44h] [bp-34h] int v71; // [sp+4Ch] [bp-2Ch] int v72; // [sp+50h] [bp-28h] int v73; // [sp+54h] [bp-24h] int v74; // [sp+54h] [bp-24h] v10 = X - GetX(); v11 = Y - GetY(); v71 = LogicMath.Sqrt(v10 * v10 + v11 * v11); v69 = LogicMath.GetAngle(v11, v10); foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 0) continue; Character v16 = (Character)gameObject; if (v16.IsAlive()) { if (v16.GetIndex() / 16 != GetIndex() / 16) { v17 = v16.GetX(); v18 = v17 - GetX(); v19 = v16.GetY(); v20 = v19 - GetY(); v21 = LogicMath.Sqrt(v18 * v18 + v20 * v20); if (v21 <= v16.CharacterData.CollisionRadius + v71) { v22 = LogicMath.GetAngle(v20, v18); v23 = LogicMath.GetAngleBetween(v69, v22); v24 = GamePlayUtil.WeaponSpreadToAngleRad(Spread); v25 = GamePlayUtil.RadToDeg(v24); v26 = 0; if (v21 > 300) v26 = 10; if (v21 <= 300 || v23 <= v26 + v25 / 2) { v27 = v16.CharacterData.CollisionRadius + 80; v28 = GetX(); v29 = GetY(); v30 = v16.GetX(); v31 = v16.GetY(); v32 = v30; if (GameObjectManager.GetBattle().GetTileMap().CalculateLOSWithCollision(v28, v29, v32, v31, v27 * 2)) { v33 = GetIndex(); v34 = GetX(); v35 = GetY(); v64 = v34; v36 = v16.CauseDamage(this, Damage, NormalDMG, UltiSkill, null); if (v36 && MeleeAttackPushBacks) { v16.TriggerPushback(GetX(), GetY(), MeleeAttackPushBack, false, 0, false, false, false, false, false, false, false, 0); } } } } } } } MeleeAttackPushBacks = false; } public void HandleHealFromDamage(int Damage, bool IsUlti, Character Target) { if (m_hitpoints < 1) return; if (Target == null) return; if (Target.CharacterData.IsHero()) { if (Target.GetCardValueForPassive("ulti_heals_self", 1) >= 1 && IsUlti) { int v893 = Target.GetCardValueForPassive("ulti_heals_self", 1); int v894 = (int)(((double)v893 / 100) * (double)m_maxHitpoints); if (GetIndex() / 16 != -1) Target.Heal(Target.GetIndex(), v894, true, Target.CharacterData); } } } public int GetCurrentAttackSpeedTicks() { if (HasActiveSkill("Attack")) { if (RapidFireMsBetweenAttacks >= 1) return RapidFireMsBetweenAttacks / 50; } if (CastingTime >= 1) { foreach (Skill skill in m_skills) { if (skill.SkillData.CastingTime >= 1) return skill.SkillData.CastingTime / 50; } } if (!CharacterData.IsBoss()) { if (GetWeaponSkill() != null) return GetWeaponSkill().SkillData.MsBetweenAttacks / 50; } return CharacterData.AutoAttackSpeedMs / 50; } public void Cripple(int a2, int ticks = 80) { IsCrippled = true; CripplePercent = a2; CrippleEndTick = TicksGone + ticks; } public void SetCharacterSummoningVariables( CharacterData SummonedCharacter, int NumSpawns, int MaxSpawns, int Damage, int Health) { this.SummonedCharacter = SummonedCharacter; this.NumSpawns = NumSpawns; this.MaxSpawns = MaxSpawns; SpawnDamage = Damage; SpawnHealth = Health; } public void SetItemSummoningVariables(ItemData a2, int NumSpawns, int MaxSpawns, int Damage, int NormalDMG) { SpawnedItem = a2; NumSpawnsItem = NumSpawns; MaxSpawnsItem = MaxSpawns; SpawnedItemDamage = Damage; SpawnedItemNormalDMG = NormalDMG; } public void Attack(Character AutoAttackTarget, int x, int y, int range, ProjectileData projectileData, int damage, int normalDMG, int spread, int bulletsPerShot, int a11 = 0) { int v15; // r0 int v17; // r5 int v18; // r0 int v20; // r0 bool v21; // cc int v22; // r0 bool v24; // zf int v25; // r0 int v26; // r5 int v27; // r0 int v28; // r0 int v29; // r5 int v30; // r0 bool v31; // zf int v32; // r0 int v33; // r0 int v34; // r0 int v35; // r1 int v36; // r0 int v38; // r0 int v40; // r5 int v41; // r0 int IsMinion; // r6 int v43; // r5 int v44; // r0 int v45; // r8 int v46; // r0 int v48; // r0 int v49; // r2 int v51; // r0 int v54; // r1 int v55; // r0 int v56; // r0 int v57; // r0 int v58; // r6 bool v59; // zf int v60; // r9 int v61; // r1 int v62; // r10 int v63; // r6 int SecondHand; // r9 int v65; // r7 int v66; // r0 int v67; // r0 int v70; // r10 int v71; // r6 int v72; // r6 int v73; // r8 int v74; // r9 int HP; // r8 int v76; // r6 int v77; // r0 int v78; // r0 int v79; // r5 int v80; // r1 int v81; // r0 int v82; // r5 int v83; // r5 int v84; // r5 int v85; // r0 int v86; // r7 int v87; // r8 int v88; // r8 int v89; // r1 int active; // r0 int v91; // r1 int v92; // r0 int v93; // r0 int v94; // r1 int v95; // r10 int v96; // r1 int v97; // r1 int v98; // r6 int v99; // r9 int v100; // r0 int v101; // r0 int v102; // r10 int v103; // r8 int v104; // r0 int v105; // r7 int v106; // r7 int v107; // r5 int v109; // r10 int v111; // kr00_4 int v112; // s16 int v113; // r6 int v114; // r9 int v115; // r9 int v116; // r0 int v117; // r6 int v118; // r7 int v119; // r9 int v120; // r0 int v121; // r1 int v122; // r8 int v123; // r6 int v124; // r0 int v125; // r0 int v126; // r6 bool v128; // zf int v129; // r9 int v130; // r7 int v131; // r6 int v132; // r8 bool v134; // zf bool v135; // zf int v136; // r0 int v137; // r0 int v138; // r0 int v139; // r0 int v140; // r5 int v141; // r6 int v142; // r2 int v143; // r0 int v144; // r1 int v145; // r0 int v146; // r5 int v147; // r6 int v148; // r0 int v149; // r5 int v150; // r6 int v151; // r0 bool v153; // zf bool v154; // zf int v155; // r6 int i; // r7 int v157; // r5 int v158; // r0 int v159; // r0 int v160; // r1 int v161; // r0 int v162; // r1 int v163; // r0 int v164; // r0 bool v165; // zf int v166; // r8 int v167; // r7 int v168; // r6 int v169; // r0 int v170; // r0 int v171; // r0 int v178; // r0 int v179; // r0 int v180; // r0 int v181; // r5 int v182; // r10 int j; // r5 int v184; // r0 int v185; // r0 int v186; // r5 int v188; // r0 int v189; // r1 int v190; // r2 int v191; // r3 int v193; // r0 int v194; // r0 int v196; // r0 int v197; // r9 int v198; // r7 int v199; // r5 int v201; // r5 int v202; // r7 int v203; // r9 int v204; // r6 int v205; // r9 int v206; // r7 int v207; // r5 int v208; // r2 int v209; // r0 int v210; // r0 int v211; // r5 int BuffsCount; // r1 int v216; // r5 int v217; // r6 int v218; // r5 int v219; // r7 int v220; // r0 int v221; // r3 int v222; // r0 int v223; // r0 int v224; // r0 int v225; // r0 int v226; // r8 int v227; // r10 int v228; // r6 bool v232; // r1 int v233; // r1 bool v234; // zf int v235; // r5 int v236; // r0 int v237; // r1 int v238; // r0 int v239; // r5 int v240; // r1 int v241; // r0 int v242; // r0 int v243; // r1 int v244; // r0 int v245; // r0 int v246; // r0 bool v247; // zf int v248; // r0 int v249; // r0 int v250; // r0 int v251; // r5 int TeamIndex; // r6 int v253; // r0 int v254; // r0 int v255; // r5 bool v260; // zf int v261; // r1 int v262; // r0 int v263; // r0 int v264; // r0 int v265; // r5 int v266; // r6 int v267; // r0 int v268; // [sp+0h] [bp-160h] int v269; // [sp+8h] [bp-158h] int v273; int v274; int v276; // [sp+40h] [bp-120h] int v277; // [sp+44h] [bp-11Ch] int v278; // [sp+4Ch] [bp-114h] int v279; // [sp+50h] [bp-110h] int v280; // [sp+54h] [bp-10Ch] int v281; // [sp+58h] [bp-108h] int v282; // [sp+5Ch] [bp-104h] int v284; // [sp+64h] [bp-FCh] int v285; // [sp+68h] [bp-F8h] int v286; // [sp+6Ch] [bp-F4h] int v287; // [sp+70h] [bp-F0h] int v288; // [sp+74h] [bp-ECh] int v289; // [sp+78h] [bp-E8h] int v290; // [sp+7Ch] [bp-E4h] int v291; // [sp+7Ch] [bp-E4h] int v292; // [sp+7Ch] [bp-E4h] int v293; // [sp+7Ch] [bp-E4h] int v294; // [sp+80h] [bp-E0h] int v295; // [sp+80h] [bp-E0h] int v296; // [sp+80h] [bp-E0h] int v297; // [sp+88h] [bp-D8h] int v298; // [sp+88h] [bp-D8h] int v299; // [sp+8Ch] [bp-D4h] int v300; // [sp+90h] [bp-D0h] int v301; // [sp+94h] [bp-CCh] int v302; // [sp+94h] [bp-CCh] int v303; // [sp+94h] [bp-CCh] int v304; // [sp+94h] [bp-CCh] int v305; // [sp+98h] [bp-C8h] int v307; // [sp+A0h] [bp-C0h] int v308; // [sp+A8h] [bp-B8h] int v309; // [sp+ACh] [bp-B4h] int v310; // [sp+B0h] [bp-B0h] int v315; // [sp+F4h] [bp-6Ch] List projectiles = new List(); ProjectileData skinprojectileData = projectileData; BattlePlayer player = GetPlayer(); if (player != null && !IsControlled) { if (!UltiSkill) { int skinid = player.SkinId; if (skinid > 0) { try { ProjectileData skinpro = DataTables.Get(DataType.Projectile).GetData(DataTables.Get(DataType.SkinConf).GetData(DataTables.Get(DataType.Skin).GetDataByGlobalId(skinid).Conf).MainAttackProjectile); if (skinpro != null) { if (projectileData != null && !IsBlackListSkinPro(projectileData.Name) && !IsBlackListSkinPro(skinpro.Name)) skinprojectileData = skinpro; } } catch {; } } } else { int skinid = player.SkinId; if (skinid > 0) { ProjectileData skinpro = DataTables.Get(DataType.Projectile).GetData(DataTables.Get(DataType.SkinConf).GetData(DataTables.Get(DataType.Skin).GetDataByGlobalId(skinid).Conf).UltiProjectile); if (skinpro != null) { if (projectileData != null && !IsBlackListSkinPro(projectileData.Name) && !IsBlackListSkinPro(skinpro.Name)) skinprojectileData = skinpro; } } } } if (skinprojectileData != null && player != null) { if (player.OverCharging && skinprojectileData.Name.EndsWith("UltiProjectile")) { if (CharacterData.Name == "Maisie") skinprojectileData = DataTables.Get(DataType.Projectile).GetData("MaisieOverchargedProjectile"); if (CharacterData.Name == "Rosa") skinprojectileData = DataTables.Get(DataType.Projectile).GetData("RosaOverchargedProjectile"); else skinprojectileData = DataTables.Get(DataType.Projectile).GetData(CharacterData.Name + "OverchargedUltiProjectile"); } } if (!SamState && CharacterData.Name == "WeaponThrower") { if (skinprojectileData.Name.StartsWith("Bronson") && skinprojectileData != null && !skinprojectileData.Name.EndsWith("UltiProjectile")) { if (skinprojectileData.Name.StartsWith("Bronson002")) skinprojectileData = DataTables.Get(DataType.Projectile).GetData("WeaponThrowerProjectile2"); else if (skinprojectileData.Name.StartsWith("Bronson003")) skinprojectileData = DataTables.Get(DataType.Projectile).GetData("WeaponThrowerProjectile2"); else if (skinprojectileData.Name.StartsWith("Bronson004")) skinprojectileData = DataTables.Get(DataType.Projectile).GetData("WeaponThrowerProjectile2"); else skinprojectileData = DataTables.Get(DataType.Projectile).GetData("WeaponThrowerProjectile2"); } else if (skinprojectileData.Name.StartsWith(CharacterData.Name) && skinprojectileData.Name != "WeaponThrowerUltiProjectile") { skinprojectileData = DataTables.Get(DataType.Projectile).GetData("WeaponThrowerProjectile2"); } } if (SamState && CharacterData.Name == "WeaponThrower" && skinprojectileData.Name.EndsWith("UltiProjectile")) { foreach (Item item in GameObjectManager.GetItems()) { player.ChargeUlti(4000, false, false); if (item.Owner == this) { item.PickedUp = true; int StartX = GetX(); // r9 int v4 = GetY(); // r0 Character v5 = this; // r8 int StartY = v4; // r10 Projectile v12; // r0 ProjectileData samUlti = DataTables.Get(DataType.Projectile).GetData("WeaponThrowerUltiProjectile2"); switch (skinprojectileData.Name) { case "Bronson002UltiProjectile": samUlti = DataTables.Get(DataType.Projectile).GetData("Bronson002UltiProjectile2"); break; case "Bronson003UltiProjectile": samUlti = DataTables.Get(DataType.Projectile).GetData("Bronson003UltiProjectile2"); break; case "Bronson004UltiProjectile": samUlti = DataTables.Get(DataType.Projectile).GetData("Bronson004UltiProjectile2"); break; } v12 = Projectile.ShootProjectile( -1, -1, v5, v5, samUlti, StartX, StartY, 0, 0, 0, false, skinprojectileData.Speed, GameObjectManager.GetBattle(), 0, 1); v12.HomingTarget = this; } } return; } int newDMG = damage; int SpeedMod = 0; Accessory accessory = player == null ? null : player.Accessory; if (!UltiSkill && accessory != null) { if (accessory.IsActive && accessory.Type == "next_attack_change" && accessory.AccessoryData.SubType == 2) { if (accessory.AccessoryData.CustomObject != null) { skinprojectileData = DataTables.GetProjectileByName(accessory.AccessoryData.CustomObject); } newDMG = newDMG * (100 + accessory.AccessoryData.CustomValue1) / 100; if (accessory.AccessoryData.ActiveTicks == 100000) accessory.EndAccessoryActivation(); } } v26 = TicksGone; v288 = 0; int v37 = LastAttckTick + GetCurrentAttackSpeedTicks(); m_attackingTicks = LogicMath.Clamp(v37 - v26, 0, 63); if (projectileData != null && RapidFireRange >= 1) { } if (v37 <= v26) { if (!UltiSkill && GetMaxChargedShots() >= 1 && CharacterData.UniqueProperty != 10) { if (ChargedShotCount < GetMaxChargedShots()) ChargedShotMisses = 0; else { newDMG = newDMG * WeaponSkillData.DamageModifier / 100; string name = GetPlayer()?.SkinConfData?.SecondaryProjectile; if (name != null) skinprojectileData = DataTables.GetProjectileByName(name); else skinprojectileData = DataTables.GetProjectileByName(WeaponSkillData.SecondaryProjectile); ChargedShotCount = 0; ChargedShotMisses++; } } bool se = false; if (GetCardValueForPassive("ambush", 1) >= 1 && !UltiSkill) { if (IsInBush()) { newDMG += (int)(((double)GetCardValueForPassive("ambush", 1) / 1000) * (double)WeaponSkillData.Damage); se = true; } } if (UltiSkill)//isultiskill { if (GetCardValueForPassive("gain_damage_super", 1) != -1) { newDMG += (int)(((double)GetCardValueForPassive("gain_damage_super", 1) / 1000) * (double)newDMG); } } else { if (GetCardValueForPassive("damage_main_attack", 1) != -1) { newDMG += (int)(((double)GetCardValueForPassive("damage_main_attack", 1) / 1000) * (double)newDMG); } } if (HasUlti()) { } newDMG -= CripplePercent * newDMG / 100; if (newDMG <= 1) newDMG = 1; bool DisablePercentageDamage = false; int StaticDMG = 0; if (accessory != null) { if (accessory.IsActive) { if (!UltiSkill && accessory.Type == "next_attack_change") { if (accessory.AccessoryData.SubType == 4) { StaticDMG = accessory.AccessoryData.CustomValue1; accessory.EndAccessoryActivation(); } } } } LastAttckTick = TicksGone; if (projectileData == null) { if (a11 == 3) RapidFireMeleeAttack(x, y, newDMG, normalDMG, spread); else MeleeAttack(AutoAttackTarget, 0, 0, newDMG, normalDMG); goto LABEL_229; } if (true) { v55 = LeftHand; v58 = CharacterData.TwoWeaponAttackEffectOffset; v246 = v55; GetShootPositionModifiers( GetX(), GetY(), x, y, v246, 50, v58, 0, 0); if (LeftHand == 0) LeftHand = 1; else LeftHand = 0; } v277 = spread; if (RapidFireAttackPattern <= 6 && ((1 << RapidFireAttackPattern) & 78) != 0 || RapidFireAttackPattern == 22) { v70 = x - GetX(); v71 = y - GetY(); v72 = LogicMath.Sqrt(v70 * v70 + v71 * v71); v73 = (v72 * spread) / 450; if (ShootIndex % 3 == 2) { v73 = (v72 * spread) / -450; v74 = -spread; } else { v74 = 0; if (ShootIndex % 3 == 1) { v73 = (v72 * spread) / -450; v74 = spread; } } v79 = x; v78 = y; v80 = RapidFireShootTimes; v298 = v78; if (v80 >= 5) { v81 = 1080 * ShootIndex / (v80 - 1); v74 = (LogicMath.Sin(v81) * spread) >> 10; } v302 = v79; switch (RapidFireAttackPattern) { case 6: v158 = ShootIndex; if (v158 != 0) { v159 = (v158 - ((v158 & 1) != 0 ? 0 : 1)) / 2 + 1; v160 = -1; if ((ShootIndex & 1) == 0) v160 = 1; v74 = v159 * v160 * spread / RapidFireShootTimes * 2; } else { v74 = 0; } break; case 3: v161 = (720 * ShootIndex) / (RapidFireShootTimes - 1); v74 = (LogicMath.Sin(v161) * spread) >> 10; break; case 2: v82 = ShootIndex; v74 = v82 * (2 * spread) / (RapidFireShootTimes - 1) - spread; break; case 22: int baseAngle = ShootIndex * 360 / (RapidFireShootTimes - 1); int zigzagSpread = spread; if ((ShootIndex % 2) == 0) { v74 = (LogicMath.Sin(baseAngle) * zigzagSpread) >> 10; } else { v74 = -(LogicMath.Sin(baseAngle) * zigzagSpread) >> 10; } break; } Projectile v177 = Projectile.ShootProjectile( AttackOffsetX, AttackOffsetY, this, this, skinprojectileData, AttackOffset2X + v302, AttackOffset2Y + v298, newDMG, RapidFireNormalDMG, v74, true, -v288, GameObjectManager.GetBattle(), ShootIndex, UltiSkill ? 2 : 1); v178 = (int)(((double)GetCardValueForPassive("heal_others_main_attack", 1) / 1000) * (double)m_maxHitpoints); if (v178 >= 0) v177.HealOthersAreaEffect = v178; v179 = GetCardValueForPassive("bounced_bullets_stronger", 1); if (v179 >= 0) v177.DamageAddFromBounce = v179; projectiles.Add(v177); if (Accessory != null && Accessory.IsActive && Accessory.Type == "next_attack_change") { switch (Accessory.AccessoryData.SubType) { case 9: v177.AttackSpecialParams_BounceHeal = Accessory.AccessoryData.CustomValue1; break; case 10: v177.AttackSpecialParams_StealBulletPercent = Accessory.AccessoryData.CustomValue1; v177.AttackSpecialParams_StealBulletPercentSelf = Accessory.AccessoryData.CustomValue2; v177.SpecialEffect = true; break; } } v177.RunEarlyTicks(); goto LABEL_218; } else if (RapidFireBulletsPerShoot >= 2) { v273 = RapidFireBulletsPerShoot - 1; v295 = 2 * spread / (RapidFireBulletsPerShoot - 1); v285 = projectileData.Speed / 7; v84 = RapidFireBulletsPerShoot; v291 = -spread; v85 = 3; if (RapidFireBulletsPerShoot == 5) v85 = 2; v274 = v85; v303 = 0; for (int b = 0; b != RapidFireBulletsPerShoot; b++) { v88 = 0; if (v84 >= 4) { v89 = (b + ShootIndex) % v274; if (v89 == 2) { v88 = v285; } else { v88 = 0; if (v89 == 1) v88 = v285 / 2; } } if (RapidFireAttackPattern == 5) { v286 = 0; v287 = 0; if ((b & 1) == 0) goto LABEL_117; int vx = x - GetX(); int vy = y - GetY(); int v110 = LogicMath.Sqrt(vx * vx + vy * vy); if (v110 >= 1) { int tmpp = projectileData.Speed; v111 = tmpp * (b & 1); v112 = v110 / tmpp; v88 = v111 / 4; v113 = (v112 * (tmpp - v111 / 4)) - v110; v286 = v113 * vx / v110 / 2; v287 = v113 * vy / v110 / 2; } } else { v286 = 0; v287 = 0; } if (RapidFireAttackPattern == 4) v88 = v285 * b; if (RapidFireAttackPattern == 13 || RapidFireAttackPattern == 10) { v286 = 0; v287 = 0; v88 = 0; } LABEL_117: v91 = newDMG; v282 = v91; v94 = v291; v95 = 0; if (projectileData.TravelType == 3) v94 = 0; v291 = v94; v96 = v295; if (projectileData.TravelType == 3) v96 = 0; v295 = v96; v97 = v285; if (projectileData.TravelType == 3) v97 = 0; v285 = v97; if (RapidFireAttackPattern != 7) { v106 = 0; v107 = v88; } else { v98 = x - GetX(); v99 = y - GetY(); v100 = LogicMath.Sqrt(v98 * v98 + v99 * v99); if (v100 < 1) { v106 = 0; v107 = v88; v95 = 0; } else { v101 = v100; v102 = LogicMath.GetRotatedX(v98, v99, 90); v103 = LogicMath.GetRotatedY(v98, v99, 90); if (RapidFireAttackPattern == 7) { v104 = 2 * projectileData.Radius; v105 = RapidFireBulletsPerShoot - 1; } else { v114 = LogicMath.Sin(spread / 2); v115 = LogicMath.Cos(spread / 2); v116 = (v101 << 10) / v115; v105 = RapidFireBulletsPerShoot - 1; v104 = 2 * ((v116 * v114) >> 10) / v273; } v117 = v104 * b; v118 = v104 * v105 / 2; v119 = v104 * b * v103 / v101; v120 = v118 * v103 / v101; v121 = v117 * v102; v122 = v102; v95 = v119 - v120; v296 = GetX(); v123 = v121 / v101; v106 = v123 - v118 * v122 / v101; v107 = 0; v124 = v286; if (RapidFireAttackPattern == 7) v124 = v106; v286 = v124; v125 = v287; if (RapidFireAttackPattern == 7) v125 = v95; v287 = v125; } } v281 = v106; if (!UltiSkill && accessory != null) { if (accessory.IsActive && accessory.Type == "next_attack_change" && accessory.AccessoryData.SubType == 1) { v295 = 2 * accessory.AccessoryData.CustomValue1 / v273 / 5; v291 = -accessory.AccessoryData.CustomValue1 / 5; v288 = accessory.AccessoryData.CustomValue3; if (accessory.AccessoryData.ActiveTicks == 100000) accessory.EndAccessoryActivation(); } } Projectile projectile = Projectile.ShootProjectile( AttackOffsetX + v281, AttackOffsetY + v95, this, this, skinprojectileData, v286 + x + AttackOffset2X, v287 + y + AttackOffset2Y, v282, RapidFireNormalDMG, v291 + v295 * b, true, v107 - v288, GameObjectManager.GetBattle(), b, UltiSkill ? 2 : 1); projectiles.Add(projectile); if (!UltiSkill && Accessory != null) { if (Accessory.Type == "next_attack_change" && Accessory.IsActive) { switch (Accessory.AccessoryData.SubType) { case 3: projectile.AttackSpecialParams_Stun = Accessory.AccessoryData.CustomValue1; break; case 11: projectile.AttackSpecialParams_WeaklyStun = Accessory.AccessoryData.CustomValue1; break; case 7: projectile.Damage += projectile.Damage * Accessory.AccessoryData.CustomValue2 / 100; projectile.AttackSpecialParams_Pushback = -Accessory.AccessoryData.CustomValue1; break; } } } if (projectileData.HealOwnPercent > 0) { v136 = GetCardValueForPassive("damage_super", 1); if (v136 >= 0) projectile.Healing = -v136; } else { v137 = GetCardValueForPassive("heal_main_attack", 1); if (v137 >= 0) { projectile.Healing = (int)((v137 / 100) * (double)m_maxHitpoints); ; projectile.SpecialEffect = true; } } v138 = GetCardValueForPassive("cripple", 1); if (v138 >= 0) projectile.CripplePercent = v138; if (UltiSkill) { v139 = GetCardValueForPassive("freeze", 1); if (v139 >= 0) { v142 = GetCardValueForPassive("freeze", 0); projectile.SetFreeze(v139, v142); } } else { v145 = GetCardValueForPassive("basic_freeze", 0); if (v145 >= 0) { v144 = GetCardValueForPassive("basic_freeze", 1); projectile.SetFreeze(v144, v145); } } v148 = GetCardValueForPassive("prey_on_the_weak", 1); if (v148 >= 0) { v151 = GetCardValueForPassive("prey_on_the_weak", 0); projectile.SetPreyOnTheWeak(v148, v151); } if (!projectile.ProjectileData.DamageOnlyWithOneProj) projectile.RunEarlyTicks(); } if (!UltiSkill && Accessory != null && Accessory.IsActive && Accessory.Type == "next_attack_change" && Accessory.AccessoryData.ActiveTicks != 100000) { Accessory.EndAccessoryActivation(); } if (projectiles.Count > 1 && projectileData.DamageOnlyWithOneProj) { foreach (Projectile projectile in projectiles) { foreach (Projectile projectile1 in projectiles) { if (projectile == projectile1) continue; projectile.LinkedProjectileGIDs.Add(projectile1.GetGlobalID()); } projectile.RunEarlyTicks(); } } goto LABEL_218; } else { if (!projectileData.Indirect) { v293 = v58; if (projectileData.IsFriendlyHomingMissile) { } else { Projectile projectile = Projectile.ShootProjectile( AttackOffsetX, AttackOffsetY, this, this, skinprojectileData, AttackOffset2X + x, AttackOffset2Y + y, newDMG + GetGearBoost(16) * 2, RapidFireNormalDMG, spread, false, -v288, GameObjectManager.GetBattle(), 0, UltiSkill ? 2 : 1); projectiles.Add(projectile); if (m_skills.Count > 0 && m_skills[0].SkillData.PercentDamage >= 1) { projectile.PercentDamage = m_skills[0].SkillData.PercentDamage; projectile.AttackSpecialParams_MinPercentDamage = 750 + GetGearBoost(16); projectile.AttackSpecialParams_DamageBuff = GetDamageBuffTemporary(); projectile.AttackSpecialParams_DamageDebuff = CripplePercent; int dis = 600; Character Guess = null; foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 0) continue; if (gameObject.GetIndex() / 16 == GetIndex() / 16) continue; if (gameObject.GetPosition().GetDistance(new LogicVector2(x, y)) > dis) continue; dis = gameObject.GetPosition().GetDistance(new LogicVector2(x, y)); Guess = (Character)gameObject; } if (Guess != null) { projectile.DisplayScale = LogicMath.Clamp(Guess.m_hitpoints / 10 - 100, 100, 1000); } else projectile.DisplayScale = 250; } if (StaticDMG >= 1) { projectile.AttackSpecialParams_StaticPercentDamage = StaticDMG; } if (GetCardValueForPassive("attack_pierce", 1) >= 0 && ChargeUp >= ChargeUpMax) { projectile.CanPierceCharacter = true; ChargeUp = 0; } if (Accessory != null && Accessory.IsActive && Accessory.Type == "next_attack_change") { switch (Accessory.AccessoryData.SubType) { case 5: SetDraggingObject(projectile, 0, 0); break; case 13: projectile.AttackSpecialParams_TrailArea = Accessory.AccessoryData.CustomObject; projectile.AttackSpecialParams_TrailAreaInterval = Accessory.AccessoryData.CustomValue1; break; } } if (SpawnedItem != null && skinprojectileData.ParentProjectileForSkin != "WeaponThrowerUltiProjectile" && SpawnedItem.Name != "SilencerHugger") { projectile.SetItemSummonProjectileData(SpawnedItem, NumSpawnsItem, MaxSpawnsItem, SpawnedItemDamage, SpawnedItemNormalDMG, this); } else if (SpawnedItem != null && skinprojectileData.ParentProjectileForSkin == "WeaponThrowerUltiProjectile") { ItemData item = DataTables.Get(DataType.Item).GetData("Bronson002Weapon"); switch (skinprojectileData.Name) { case "Bronson002UltiProjectile": item = DataTables.Get(DataType.Item).GetData("Bronson002Weapon"); break; case "Bronson003UltiProjectile": item = DataTables.Get(DataType.Item).GetData("Bronson003Weapon"); break; case "Bronson004UltiProjectile": item = DataTables.Get(DataType.Item).GetData("Bronson004Weapon"); break; } projectile.SetItemSummonProjectileData(item, NumSpawnsItem, MaxSpawnsItem, SpawnedItemDamage, SpawnedItemNormalDMG, this); } projectile.SpecialEffect = se; projectile.RunEarlyTicks(); goto LABEL_218; } } } v162 = AttackOffset2Y; AttackOffset2X += x; AttackOffset2Y = v162 + y; if (true) { if (RapidFireAttackPattern != 9) { v201 = AttackOffset2Y; v202 = newDMG; goto LABEL_265; } v167 = 0; v292 = ShootIndex % 5; } else { } v168 = GetX(); v169 = GetY(); v170 = GamePlayUtil.GetDistanceBetween(v168, v169, AttackOffset2X, AttackOffset2Y); if (false) ; else v171 = Projectile.GetSpreadMax(projectileData, spread, v170); int v229 = v171; v210 = v171; int v230, v231; switch (v292) { case 1: v230 = -v210; v231 = -v210; break; case 2: v231 = -v210; v230 = v210; break; case 3: v230 = -v210; goto LABEL_246; case 4: v230 = v210; LABEL_246: v231 = v210; break; default: v230 = 0; v231 = 0; break; } LogicRandom v316 = new LogicRandom(ShootIndex + 12345); v218 = v230 - v229 / 4 + (v316.Rand(1000) * (v229 / 4)) / 500; v219 = v231 - v229 / 4 + (v316.Rand(1000) * (v229 / 4)) / 500; v24 = true; v220 = 1; if (!v24) v220 = -1; v221 = AttackOffset2Y; AttackOffset2X += v218 * v220; AttackOffset2Y += v219 * v220; AttackOffset2X = LogicMath.Clamp(AttackOffset2X, 1, MapWidth - 2); v201 = LogicMath.Clamp(AttackOffset2Y, 1, MapHeight - 2); v202 = newDMG; AttackOffset2Y = v201; LABEL_265: v226 = AttackOffsetX; v227 = AttackOffsetY; v228 = AttackOffset2X; Projectile v2311 = Projectile.ShootProjectile( v226, v227, this, this, skinprojectileData, v228, v201, v202, RapidFireNormalDMG, 0, false, -v288, GameObjectManager.GetBattle(), ShootIndex, UltiSkill ? 2 : 1); projectiles.Add(v2311); v232 = false; if (v232) { } else { if (SummonedCharacter == null) { goto LABEL_272; } v2311.SetCharacterSummonProjectileData(SummonedCharacter, NumSpawns, MaxSpawns, SpawnDamage, SpawnHealth, StarPowerIC); } LABEL_272: if (GetCardValueForPassive("increased_explosion", 1) >= 0 && !UltiSkill && ChargeUp >= ChargeUpMax) { AreaEffectData areaEffectData = null; if (player?.SkinConfData != null) { areaEffectData = DataTables.GetAreaEffectByName(player.SkinConfData.AreaEffectStarPower); } if (areaEffectData == null) { areaEffectData = DataTables.GetAreaEffectByName("WallyExplosionBig"); } ChargeUp = 0; if (areaEffectData != null) projectiles[0].AttackSpecialParams_AreaEffectData = areaEffectData; } v243 = 0; if (GetCardValueForPassive("aoe_dot", 1) != -1) { v243 = (int)(((double)GetCardValueForPassive("aoe_dot", 1) / 1000) * (double)m_maxHitpoints); if (GetCardValueForPassive("aoe_dot", 2) != -1) { v243 = (int)((double)v243 * (double)0.23658) + 2; } if (v243 != -1) projectiles[0].aoe_dot = v243; } if (!UltiSkill) { v250 = GetCardValueForPassive("heal_self_main_attack", 1); if (v250 >= 0) { Heal(GetIndex(), 400, false, CharacterData); } } LABEL_218: ++ShootIndex; if (RapidFireAttackPattern == 14) { int m = GetCardValueForPassive("attack_sequence_extra_steps", 1); JesterSkillCount++; if (JesterSkillCount >= 3 + (m > 0 ? m : 0)) JesterSkillCount = 0; } LABEL_229: Attacking = false; BlockHealthRegen(); SetForcedVisible(); goto LABEL_132; } LABEL_132: if (projectiles.Count >= 1 && IsInRealm) { foreach (Projectile projectile in projectiles) { projectile.IsInRealm = true; } } AttackAngle = LogicMath.GetAngle(x - GetX(), y - GetY()); bool v108 = false; SkillData skill = GetCurrentCastingSkill(); if (skill != null) { v108 = !skill.CanMoveAtSameTime; } else { } if (v108) { if (CharacterData.Speed > 0) MoveAngle = AttackAngle; } } public override bool ShouldDestruct() { return m_hitpoints <= 0 && m_destructafterticks < 1; } public bool IsChargeActive() { return IsCharging; } public int GetHitpointPercentage() { return (int)(((float)this.m_hitpoints / (float)this.m_maxHitpoints) * 100f); } public bool HasActiveSkill() { if (m_skills.Count == 0) return false; if (m_skills.Count == 1) return m_skills[0].IsActive; else return m_skills[0].IsActive || m_skills[1].IsActive; } public bool HasActiveSkill(string type) { if (m_skills.Count < 1) return false; foreach (Skill s in m_skills) { if (s.SkillData.BehaviorType == type && s.TicksActive > 0) return true; } return false; } public SkillData GetActiveSkill(string type) { if (m_skills.Count < 1) return null; foreach (Skill s in m_skills) { if (s.SkillData.BehaviorType == type && s.TicksActive > 0) return s.SkillData; } return null; } public SkillData GetCurrentActiveOrCastingSkill() { if (m_skills.Count < 1) return null; foreach (Skill s in m_skills) { if (s.TicksActive > 0) return s.SkillData; } return null; } public Skill GetSkill(string type) { if (m_skills.Count < 1) return null; foreach (Skill s in m_skills) { if (s.SkillData.BehaviorType == type) return s; } return null; } public bool IsSteerMovementActive() { foreach (Skill skill in m_skills) { if (skill.TicksActive > 0 && skill.SkillData.ChargeType == 15) return true; } return false; } public bool IsImmuneAndBulletsGoThrough(bool IsInRealm = false) { if (Accessory != null && Accessory.Type == "dive" && Accessory.IsActive) return true; if (this.IsInRealm ^ IsInRealm) return true; int v2 = m_activeChargeType - 2; if ((!IsCharging || v2 >= 16 || ((0x4293 >> v2) & 1) == 0) && !IsSteerMovementActive()) { if (Knockback3) return true; return false; } return true; } public Projectile GetControlledProjectile() { foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() == 1 && gameObject.GetIndex() == GetIndex()) { if (((Projectile)gameObject).ProjectileData.TravelType == 5) return (Projectile)gameObject; } } return null; } public void TriggerWhirlwind(int Damage, int NormalDMG, int SpeedIncrease) { ChargeDamage = Damage; ChargeNormalDMG = NormalDMG; UltiSkill = true; ChargeHitGIDs = new List(); ApplyBuff(4, 2, SpeedIncrease, 0); if (GetCardValueForPassive("ulti_defense", 1) > 0) AddShield(GetCardValueForPassive("ulti_defense", 1), GetCardValueForPassive("ulti_defense", 0)); } public void TickWhirlwind() { SkillData skillData = GetActiveSkill("Ww"); if (skillData == null) return; ApplyBuff(4, 2, skillData.MsBetweenAttacks, 0); int v11 = ChargeDamage; v11 += ChargeDamage * GetDamageBuffTemporary() / 100; v11 -= ChargeDamage * CripplePercent / 100; for (int i = 0; i < ChargeHitGIDs.Count; i++) { Ignoring ignoring = ChargeHitGIDs[i]; ignoring.Ticks--; if (ignoring.Ticks <= 0) { ChargeHitGIDs.Remove(ignoring); i--; } } if (Knockback3) return; int v110 = 100 * skillData.CastingRange; foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 0) continue; Character character = (Character)gameObject; if (character.IsAlive() && character.GetIndex() / 16 != GetIndex() / 16 && !character.IsImmuneAndBulletsGoThrough(IsInRealm)) { int v32 = character.GetX(); int v34 = GetX(); int v35 = character.GetY(); int v36 = v32 - v34; int v37 = GetY(); int v38 = v35 - v37; if (LogicMath.Abs(v36) <= v110 && LogicMath.Abs(v38) <= v110) { int v39 = v36 * v36 + v38 * v38; if (v39 <= v110 * v110) { if (ChargeHitGIDs.Find(x => x.GID == character.GetGlobalID()) != null) continue; ChargeHitGIDs.Add(new Ignoring(character.GetGlobalID(), 5)); if (character.CauseDamage(this, v11, ChargeNormalDMG, UltiSkill, null, true)) { } } } } } GetBattle().GetTileMap().DestroyEnvironment(GetX(), GetY(), v110, true); if (GetCardValueForPassive("super_destroy_walls", 1) <= 0) return; int v77 = GetX() / 300; int v79 = GetY() / 300; TileMap v80 = GetBattle().GetTileMap(); int v81 = GetCardValueForPassive("super_destroy_walls", 1) - 100; int XMin = LogicMath.Clamp(v77 - 2, 0, v80.Width - 1); int YMin = LogicMath.Clamp(v79 - 2, 0, v80.Height - 1); int XMax = LogicMath.Clamp(v77 + 2, 0, v80.Width - 1); int YMax = LogicMath.Clamp(v79 + 2, 0, v80.Height - 1); for (int i = XMin; i <= XMax; i++) { for (int j = YMin; j <= YMax; j++) { if (((i * 300 + 150 - GetX()) * (i * 300 + 150 - GetX()) + (j * 300 + 150 - GetY()) * (j * 300 + 150 - GetY())) <= v81 * v81) { Tile tile = v80.GetTile(i, j, true); if (tile != null) tile.Destruct(); } } } } public void TickCharge() { int v110 = 0; int result = m_activeChargeType; if (result == 1 || result == 3 || result == 4 || (result == 5 && ChargeDamage >= 1) || result == 7 || result == 9 || result == 10 || result == 12 || result == 8 || result == 14 || result == 16) { int v8 = 400; if (CharacterData.IsBoss()) v8 = 800; bool v9 = m_activeChargeType == 9; if (m_activeChargeType != 9) v9 = m_activeChargeType == 3; v110 = v8; if (v9) v110 = 800; int v101 = ChargeDamage; v101 += ChargeDamage * GetDamageBuffTemporary() / 100; v101 -= ChargeDamage * CripplePercent / 100; if (m_activeChargeType == 7 || m_activeChargeType == 10 || CharacterData.IsTrain()) { for (int i = 0; i < ChargeHitGIDs.Count; i++) { Ignoring ignoring = ChargeHitGIDs[i]; ignoring.Ticks--; if (ignoring.Ticks <= 0) { ChargeHitGIDs.Remove(ignoring); i--; } } } foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 0) continue; Character character = (Character)gameObject; if (character.IsAlive() && character.GetIndex() / 16 != GetIndex() / 16 && !character.IsImmuneAndBulletsGoThrough(IsInRealm)) { int v32 = character.GetX(); int v34 = GetX(); int v35 = character.GetY(); int v36 = v32 - v34; int v37 = GetY(); int v38 = v35 - v37; if (LogicMath.Abs(v36) <= v110 && LogicMath.Abs(v38) <= v110) { int v39 = v36 * v36 + v38 * v38; if (v39 <= v110 * v110) { if (ChargeHitGIDs.Find(x => x.GID == character.GetGlobalID()) != null) continue; if (true) { int ChargeType = m_activeChargeType; if (ChargeType == 10) { ChargeHitGIDs.Add(new Ignoring(character.GetGlobalID(), 100)); int v61 = GamePlayUtil.CalculatePercentDamage(ChargePercentDamage, ChargeDamage, true, GetDamageBuffTemporary(), CripplePercent, ChargeDamage / 4, character); ChargeNormalDMG = 1000; v101 = v61; } else if (!CharacterData.IsTrain()) { ChargeHitGIDs.Add(new Ignoring(character.GetGlobalID(), 10)); } if (character.CauseDamage(this, v101, ChargeNormalDMG, UltiSkill, null, true)) { ++ChargeHits; if (GetCardValueForPassive("fire_dot_ulti", 1) >= 0) character.ApplyPoison(GetIndex() % 16, GetCardValueForPassive("fire_dot_ulti", 1), 0, true, this, 2); if (GetCardValueForPassive("push_charge", 1) >= 1 && ShouldExecuteColetteChargeOnReturn) { if (character.IsAlive()) { if (character.CharacterData.IsHero() || character.CharacterData.IsTrainingDummy()) { if (TicksGone + 2 < MoveEnd) { character.SetDraggingObject(this, character.GetX() - GetX(), character.GetY() - GetY()); } } } } int v70 = GetCardValueForPassive("shield_charge", 0);// 10 if (v70 >= 1) { AddShield(GetCardValueForPassive("shield_charge", 2), GetCardValueForPassive("shield_charge", 1) + ChargeHits * v70);// 100(5?) } if (GetCardValueForPassive("charge_ulti_on_kill", 1) >= 1) { if (!character.IsAlive()) GetPlayer().ChargeUlti(4000, false, true); } } character.TriggerPushback( GetX(), GetY(), ChargePushback, true, 0, false, false, false, false, false, false, false, 0); if (m_activeChargeType == 8) { IsCharging = false; StopMovement(); FangHitGIDs.Add(character.GetGlobalID()); if (FangUltiCount <= 2) { Character Target = null; int dis = GetUltimateSkill().SkillData.CastingRange * 50; foreach (GameObject gameObject1 in GameObjectManager.GetGameObjects()) { if (gameObject1.GetObjectType() != 0) continue; Character character1 = (Character)gameObject1; if (!character1.IsAlive()) continue; if (character1.GetIndex() / 16 == GetIndex() / 16) continue; if (character1.IsImmuneAndBulletsGoThrough(IsInRealm)) continue; if (GamePlayUtil.GetDistanceBetween(GetX(), GetY(), character1.GetX(), character1.GetY()) >= dis) continue; if (FangHitGIDs.Contains(character1.GetGlobalID())) continue; dis = GamePlayUtil.GetDistanceBetween(GetX(), GetY(), character1.GetX(), character1.GetY()); Target = character1; } if (Target != null) { List tmp = ChargeHitGIDs; List tmp2 = FangHitGIDs.ToList(); int t = FangUltiCount; TriggerCharge(Target.GetX(), Target.GetY(), ChargeSpeed, m_activeChargeType, ChargeDamage, ChargePushback, false); ChargeHitGIDs = tmp; FangHitGIDs = tmp2; FangUltiCount = t + 1; } } return; } } } } else { } } } } if (CharacterData.Name == "Roller" && IsChargeActive()) { AreaEffectData area = DataTables.Get(DataType.AreaEffect).GetData("RollerFire"); AreaEffect areaEffect = new AreaEffect(area); areaEffect.SetPosition(GetX(), GetY(), 0); areaEffect.SetIndex(GetIndex()); areaEffect.SetSource(this, 2); areaEffect.Damage = area.Damage; areaEffect.NormalDMG = area.Damage; GameObjectManager.AddGameObject(areaEffect); areaEffect.Trigger(); } if (m_activeChargeType == 101) { if (m_activeChargeType == 101) { int currentX = GetX(); int currentY = GetY(); bool canSpawn = true; if (_spawnedEffects.Count >= 5) { canSpawn = false; } else if (_lastX != -1 && _lastY != -1) { int distance = (int)Math.Sqrt((currentX - _lastX) * (currentX - _lastX) + (currentY - _lastY) * (currentY - _lastY)); if (distance < 550) { canSpawn = false; } } if (canSpawn) { AreaEffectData area = DataTables.Get(DataType.AreaEffect).GetData("PainterAreaExplosion"); if (area != null) { var areaEffect = new AreaEffect(area); areaEffect.SetPosition(currentX, currentY, 0); areaEffect.SetIndex(GetIndex()); areaEffect.SetSource(this, 2); areaEffect.Damage = 1500; areaEffect.NormalDMG = 1500; GameObjectManager.AddGameObject(areaEffect); areaEffect.Trigger(); _spawnedEffects.Add(areaEffect); _lastX = currentX; _lastY = currentY; } } } } if ((m_activeChargeType | 2) != 3 && !ChargeBreaksEnvironment) return; int v77 = GetX() / 300; int v79 = GetY() / 300; TileMap v80 = GetBattle().GetTileMap(); int v81 = v110; int XMin = LogicMath.Clamp(v77 - 2, 0, v80.Width - 1); int YMin = LogicMath.Clamp(v79 - 2, 0, v80.Height - 1); int XMax = LogicMath.Clamp(v77 + 2, 0, v80.Width - 1); int YMax = LogicMath.Clamp(v79 + 2, 0, v80.Height - 1); for (int i = XMin; i <= XMax; i++) { for (int j = YMin; j <= YMax; j++) { if (((i * 300 + 150 - GetX()) * (i * 300 + 150 - GetX()) + (j * 300 + 150 - GetY()) * (j * 300 + 150 - GetY())) <= v81 * v81) { Tile tile = v80.GetTile(i, j, true); if (tile != null) tile.Destruct(); } } } } public SkillData GetCurrentCastingSkill() { foreach (Skill skill in m_skills) { if (skill.OnActivate && skill.SkillData.CastingTime > 0) return skill.SkillData; if (skill.TicksActive >= 1) return skill.SkillData; } return null; } public int GetDamageBuffTemporary() { int buff = 0; foreach (Buff buff1 in m_buffs) { if (buff1.Type == 1 || buff1.Type == 2 || buff1.Type == 5) buff += buff1.Modifier; } if (GetPlayer()?.OverCharging ?? false) { if (CharacterData.OverchargeDamagePercent > 0) buff += CharacterData.OverchargeDamagePercent; else buff += 20; } return buff; } public int GetBuffedHealthRegen() { int buff = 0; foreach (Buff buff1 in m_buffs) { if (buff1.Type == 10) buff += 1; } return buff; } public void TickRapidFire() { SkillData v2; // r0 int v3; // r1 int v4; // r2 int v5; // r3 SkillData v6; // r5 int v7; // r0 int v8; // r6 int v9; // r7 int v10; // r0 int v11; // r0 bool v12; // zf int v13; // r8 int v14; // r0 int v15; // r0 int BuffsCount; // r1 int v18; // r2 int v20; // r0 int v21; // r0 int v22; // r6 int v23; // r5 int v25; // r0 int result; // r0 State = 2; v2 = GetCurrentCastingSkill(); v6 = v2; if (v2 != null /*|| v2.CanMoveAtSameTime*/) { if (v6.Projectile == null || !DataTables.GetProjectileByName(v6.Projectile).Indirect && DataTables.GetProjectileByName(v6.Projectile).TravelType != 6) { AttackTarget.X = AttackVector.X + GetX(); AttackTarget.Y = AttackVector.Y + GetY(); } } int Damage = RapidFireDamage; v23 = 0; if (RapidFireProjectile == null) v23 = 3; Damage += GetDamageBuffTemporary() * Damage / 100; if (RapidFireAttackPattern == 12) { Attack( null, GetX() + LogicMath.GetRotatedX(ChargeSpeed / 20 * RapidFireMsBetweenAttacks / 50, 0, MoveAngle), GetY() + LogicMath.GetRotatedY(ChargeSpeed / 20 * RapidFireMsBetweenAttacks / 50, 0, MoveAngle), RapidFireRange, RapidFireProjectile, Damage, RapidFireNormalDMG, RapidFireSpread, RapidFireBulletsPerShoot, v23); } else Attack( null, AttackTarget.X, AttackTarget.Y, RapidFireRange, RapidFireProjectile, Damage, RapidFireNormalDMG, RapidFireSpread, RapidFireBulletsPerShoot, v23); Attacking = true; RapidFireTick = TicksGone; } public bool HasCcImmunity() { return CcImmunityTicks > 0; } public int UpdateMoveDirection( int a1, LogicVector2 a2, LogicVector2 a3, int a4, int a5) { int v9; // r6 int v10; // r9 int v11; // r1 int v12; // r0 int v13; // r2 int v14; // r1 int result; // r0 int v16; // r1 int v17; // r0 bool v18; // zf v9 = a5; v10 = a2.GetDistanceSquared(a3); v11 = 0; MovementVector = new LogicVector2(); if (v10 >= v11) { v9 = a3.Y; v14 = a2.X - a3.X; } else { v14 = a2.X - a4; } MovementVector.X = v14; MovementVector.Y = a2.Y - v9; MovementVector.Normalize(256); result = LogicMath.GetAngle(MovementVector.X, MovementVector.Y); if (Slippery) { int angleDiff = (result - MoveAngle) % 360; if (angleDiff > 180) angleDiff -= 360; if (angleDiff < -180) angleDiff += 360; if (angleDiff > 6) result = MoveAngle + 6; else if (angleDiff < -6) result = MoveAngle - 6; result = LogicMath.NormalizeAngle360(result); } if (MovementVector.X != 0 || MovementVector.Y != 0) MoveAngle = result; if (KnockBacked) { if (!(Knockback1 || Knockback3)) { MoveAngle = result + 180; if (result + 180 >= 360) { result -= 180; MoveAngle = result; } } } return result; } public void TriggerPushback( int TriggerPosX, int TriggerPosY, int PushbackLength, bool a5, int a6, bool IgnoreInvincible, bool a8, bool a9, bool IgnoreCcImmunity, bool a11, bool a12, bool a13, int a14, int MaxX = -1, int MaxY = -1) { if(this.CharacterData.IsCarryable()) return; if ((!Knockback2 || a12) && (!IsInvincible || IgnoreInvincible)) { bool v20 = !KnockBacked; if (KnockBacked) v20 = !Knockback1; if (!v20 && !a9) { if (!a13) return; int v35 = TicksGone - 1; Knockback1 = false; MoveStart = v35; MoveEnd = v35; } bool v22 = false; if (!v22 || CharacterData.Hitpoints <= 2) { if (IgnoreCcImmunity || !HasCcImmunity()) { Knockback2 = a12; bool IsCarryable = CharacterData.IsCarryable(); if (v22 || IsCarryable) { if (PushbackLength > 0) PushbackLength <<= a6; else PushbackLength = 10; } bool v26 = !a8; if (!a8) v26 = !a12; if (IsCarryable | v22 | CharacterData.Speed > 0) { LABEL_24: if (IsCharging && (m_activeChargeType <= 0xA) && ((1 << m_activeChargeType) & 0x482) != 0)//1 7 (Bull&&Darrel) { if (PushbackLength == 0 || !a9) return; } else if (PushbackLength == 0) { return; } int v37 = PushbackLength; if (!a12) v37 = PushbackLength / 2; if (a9) v37 = PushbackLength; if (a8) v37 = PushbackLength; if (CharacterData.CollisionRadius < 150) v37 = PushbackLength; if (PushbackLength < 1) v37 = PushbackLength; int v170 = v37; if (GetX() == TriggerPosX && GetY() == TriggerPosY) { int v40 = GameObjectManager.GetBattle().GetRandomInt(10, 100); int v42 = GameObjectManager.GetBattle().GetRandomInt(10, 100); if (GameObjectManager.GetBattle().GetRandomInt(0, 2) == 1) v42 = -v42; if (GameObjectManager.GetBattle().GetRandomInt(0, 2) == 1) v40 = -v40; TriggerPosX = LogicMath.Clamp(v40 + TriggerPosX, 1, GameObjectManager.GetBattle().GetTileMap().LogicWidth - 2); TriggerPosY = LogicMath.Clamp(v42 + TriggerPosY, 1, GameObjectManager.GetBattle().GetTileMap().LogicHeight - 2); } LogicVector2 v200 = new LogicVector2(GetX() - TriggerPosX, GetY() - TriggerPosY); int v52 = 6 * LogicMath.Abs(v170); if (v170 <= -1) { int v53 = v200.GetLength(); if (v52 > v53) v52 = v53; } int v179 = v52; v200.Normalize(v52); int v199 = 0; int v198 = 0; int v54 = GetX(); int v56; if (v170 < 1) { v199 = v54 - v200.X; v56 = GetY() - v200.Y; } else { v199 = v200.X + v54; v56 = v200.Y + GetY(); } v198 = v56; Knockback1 = false; KnockBacked = true; TileMap v59 = GameObjectManager.GetBattle().GetTileMap(); if (!IgnoreInvincible) { int v63 = GetX(); int v64 = GetY(); if (MaxX != -1) { if (GetX() > MaxX) v199 = LogicMath.Max(MaxX, v199); else v199 = LogicMath.Min(MaxX, v199); if (GetY() > MaxY) v198 = LogicMath.Max(MaxY, v198); else v198 = LogicMath.Min(MaxY, v198); } bool v65; int v177 = 0; int v182 = 0; LogicVector2 v188 = new LogicVector2(-1, -1); if (IsCarryable) { v65 = GamePlayUtil.GetClosestAnyCollision( v63, v64, v199, v198, v59, v188, 0, 1, 0, 1); } else { v65 = GamePlayUtil.GetClosestAnyCollision( v63, v64, v199, v198, v59, v188, 0, 1, 0, 1, ImmunToPushbackOutOfWalls); // v65 = false; } if (v188.X != -1) { int v73 = v188.X - v63; bool v74 = v65; int v75 = v64; int v76 = v188.Y - v64; int v77 = LogicMath.Sqrt(v73 * v73 + v76 * v76); if (v77 > 0) { int v79 = 20; if (v77 <= 20) v79 = LogicMath.Max(1, v77 - 5); v73 = (v77 - v79) * v73 / v77; v76 = (v77 - v79) * v76 / v77; } v198 = v76 + v75; v64 = v75; v199 = v73 + v63; v65 = v74; } v199 = LogicMath.Clamp(v199, 101, GameObjectManager.GetBattle().GetTileMap().LogicWidth - 102); v198 = LogicMath.Clamp(v198, 101, GameObjectManager.GetBattle().GetTileMap().LogicHeight - 102); goto LABEL_119; } Knockback3 = true; LogicVector2 v190 = new LogicVector2(); if (GamePlayUtil.GetClosestLevelBorderCollision( GetX(), GetY(), v199, v198, v59, 1, v190)) { GamePlayUtil.GetClosestPassableSpot(1, v199, v198, 10, GetBattle().GetTileMap(), v190, false); v198 = v190.Y; v199 = v190.X; } else { GamePlayUtil.GetClosestPassableSpot(1, v199, v198, 10, GetBattle().GetTileMap(), v190, false); v198 = v190.Y; v199 = v190.X; } v199 = LogicMath.Clamp(v199, 101, GameObjectManager.GetBattle().GetTileMap().LogicWidth - 102); v198 = LogicMath.Clamp(v198, 101, GameObjectManager.GetBattle().GetTileMap().LogicHeight - 102); LABEL_119: InterruptAllSkills(); if (GetCardValueForPassive("ulti_defense", 1) >= 0) { ShieldTicks = 0; } { PathfindTo(0, v199, v198, 0, 0, 0, 0, 0, 0); } int v153 = 12 * v170; if (v170 < 0) v153 = -8 * v170; ChargeSpeed = v153; int v154; int v155; if (a12) { v154 = 2 * v153; } else if (a11) { v154 = LogicMath.Max(1, v153 / 2); } else if (IsCarryable) { int v156 = (int)(14725602162 * v153) >> 32; v155 = (v156 >> 3) + (v156 >> 31); v154 = LogicMath.Max(1, v155 / 2); } else { if (!a8) { if (!IgnoreInvincible) goto LABEL_152; v155 = v153 / 2; v154 = LogicMath.Max(1, v155); goto LABEL_151; } int v157 = 6; if (v170 > 500) v157 = 4; int v156 = (int)(2454267027 * v157 * v153) >> 32; v155 = (v156 >> 3) + (v156 >> 31); v154 = LogicMath.Max(1, v155 / 2); } LABEL_151: ChargeSpeed = v154; LABEL_152: int v158 = GetPathLength(); PathLength = v158; if (v158 >= 1) { MoveStart = TicksGone; MoveEnd = LogicMath.Max(1, 20 * v158 / ChargeSpeed) + TicksGone; } if (IsCarryable) { ChargeSpeed = 9 * ChargeSpeed / 4; } if (a8) ChargeSpeed = LogicMath.Max(1, 13 * ChargeSpeed / 14); if (!a5) ChargeSpeed = 0; Projectile v166 = GetControlledProjectile(); if (v166 != null) v166.TargetReached(5); return; } } } } } public int GetNextSteeredPos(LogicVector2 a2) { int v4; // r8 int v5; // r0 int v6; // r5 int v8; // r6 int v9; // r9 MAPDST int v10; // r5 int v11; // r9 Character v15; // r7 int v16; // r10 Character v17; // r9 int v18; // r0 int v19; // r0 int v20; // r0 int v21; // r1 int v22; // r5 int v23; // r5 int v24; // r5 int v25; // r6 int v28; // r0 int v29; // r6 int v30; // r5 int v31; // r0 int v32; // r0 int v33; // r5 int v34; // r5 int v35; // r0 float v39; // [sp+Ch] [bp-3Ch] float v40; // [sp+10h] [bp-38h] float v41; // [sp+14h] [bp-34h] float v42; // [sp+18h] [bp-30h] v9 = ChargeSpeed; v22 = MoveAngle; v29 = -1; if (LogicMath.NormalizeAngle360(v22 - SteerAngle) < 180) v29 = 1; v30 = LogicMath.GetAngleBetween(SteerAngle, v22); v31 = 8; v32 = LogicMath.Min(v30, v31); MoveAngle = LogicMath.NormalizeAngle360(MoveAngle + v32 * v29); v33 = GetX(); a2.X = v33 + LogicMath.Cos(MoveAngle) * v9 / 1024 / 20; v34 = GetY(); a2.Y = v34 + LogicMath.Sin(MoveAngle) * v9 / 1024 / 20; a2.X = LogicMath.Clamp(a2.X, 101, GetBattle().GetTileMap().LogicWidth - 102); a2.Y = LogicMath.Clamp(a2.Y, 101, GetBattle().GetTileMap().LogicHeight - 102); AttackAngle = MoveAngle; float v310 = 0.1F; float v320 = 0.1F; float v330 = 8400; if ((ChargeSpeed * 0.1) > 0.1) v320 = ChargeSpeed * 0.1F; v39 = -0.015F; v41 = v39 * 300.0F; if ((v330 / v320) > 0.1) v310 = v330 / v320; v42 = (8400 * (TicksGone - SteerStartTicks) / 120) / v320; v40 = (v41 * v42) * (v42 - v310); return LogicMath.Clamp((int)v40, 0, 1500); } public int GetPosAtTick(int a1, int a2, LogicVector2 a3, int a4) { float v4; // d1 float v5; // d2 float v6; // d4 int v9; // r0 int v11; // r2 int v12; // r0 int v13; // r1 int v14; // r3 int v15; // r10 int v16; // r4 int v17; // r0 int v18; // r7 int v19; // r0 int v20; // r1 int v21; // r9 int v22; // r5 int v23; // r6 int v24; // r8 int v25; // r0 int v26; // r2 int v27; // r7 int v28; // r0 int v29; // r0 int v30; // r0 double v31; // s18 double v32; // s16 int v33; // r0 int v34; // r5 int v35; double v36; // s20 double v37; // s0 int v38; // r0 double v39; // s4 double v40; // s4 double v41; // r0 double v42; // [sp+Ch] [bp-4Ch] int v43; // [sp+10h] [bp-48h] int v44; int v45; // [sp+18h] [bp-40h] v9 = MoveStart; v11 = MoveEnd; if (v11 == v9) { PosDelta.X = GetX(); PosDelta.Y = GetY(); return 0; } v12 = 1000 * LogicMath.Min(a2 - v9 + (m_isBot == 0 ? 1 : 0), v11 - v9) / (v11 - v9); v44 = v12; v13 = PathLength; v14 = 2; v42 = v12; v45 = v13 * v12 / 1000; v17 = 0; if (TicksGone > MoveEnd) { PosDelta.X = GetX(); PosDelta.Y = GetY(); return 0; } v18 = v17; v21 = WayPoint.X; v22 = WayPoint.Y; v23 = WayPointStart.X - v21; v24 = WayPointStart.Y - v22; v25 = LogicMath.Sqrt(v23 * v23 + v24 * v24);//pathlen v26 = v18; v27 = v25; v17 = v25 + v26; v18 = v17; v26 = v18;//pathlen if (v27 < 1) { v28 = v24; } else { v23 = v23 * (v45 - v26) / v27; v28 = v24 * (v45 - v26) / v27; } PosDelta.X = v21 - v23; PosDelta.Y = v22 - v28; if (!IsCharging || !GamePlayUtil.IsJumpCharge(m_activeChargeType)) { if (!KnockBacked) return 0; } if (ChargeSpeed == 0) return 0; v31 = 0.1; v32 = 0.1; v33 = PathLength; if ((ChargeSpeed * 0.1) > 0.1) v32 = ChargeSpeed * 0.1; if (!IsCharging) { v35 = LogicMath.Sqrt(v33); v36 = -6.25; v39 = v36 / v35; } else switch (m_activeChargeType) { case 2: v39 = -0.35; break; case 6: v39 = -0.1; break; case 3: v35 = LogicMath.Sqrt(v33); v36 = -5.0; LABEL_25: v39 = v36 / v35; break; case 11: v39 = -0.2; break; case 16: v39 = -0.25; break; default: v39 = -8.75 / LogicMath.Sqrt(v33); break; } double d = 0; if (IsCharging && m_activeChargeType == 9) { v40 = sub_518AB8(v44, v44 * 0.001); } else { v41 = v39 * 300.0; if ((v33 / v32) > 0.1) v31 = v33 / v32; v42 = (PathLength * v44 / 1000) / v32; v40 = (v41 * v42) * (v42 - v31); } v37 = LogicMath.Clamp((int)v40, 0, 3000); return (int)v37; } int sub_518AB8(int a1, double a2) { int result; // r0 if (a2 >= 0.5) { result = 2250; if (a2 < 0.7) return result; return (int)sub_4771CC((a2 * 3.3333) + -2.0, 2250.0, 0.0); } else { return (int)sub_3A5150(a2 + a2, 0.0, 2250.0); } } double sub_4771CC(double a1, double a2, double a3) { return a2 + (a1 * a1 * a1 * (a3 - a2)); } double sub_3A5150(double a1, double a2, double a3) { return a2 + (((((a1 + -1.0) * (a1 + -1.0)) * (a1 + -1.0)) + 1.0) * (a3 - a2)); } public int GetSkillHoldedTicks() { if (SkillHoldTicks < 0) return 0; return LogicMath.Min(SkillHoldTicks, GetMaxHoldTicks()); } public void TickInvisibility() { SkillData result; VisibilityState = 0; if (InvisibleTicks < 1) { IsInvisible = false; YellowEye = false; goto LABEL_20; } else { InvisibleTicks--; if (InvisibleTicks < 1) { VisibilityState = 2; InvisibleTicks = 0; IsInvisible = false; YellowEye = false; goto LABEL_20; } } IsInvisible = true; LABEL_20: result = GetActiveSkill("Invisibility"); if (result != null) { if (InvisibleTicks <= 0) VisibilityState = 1; InvisibleTicks = 3; BreakInvisibilityOnAttack = result.BreakInvisibilityOnAttack; SeeInvisibilityDistance = result.SeeInvisibilityDistance; if (GetCardValueForPassive("speed_invisible", 1) >= 0) ApplyBuff(4, 10, GetCardValueForPassive("speed_invisible", 1), 0); } } public CharacterData GetData() => CharacterData; public void TriggerRapidFire(int x, int y, int attp, int bps, int msb, ProjectileData projectileData, int damage, int range, int spread, int actime, int normalDMG, bool EFAI) { int v16; // r7 int v21; // r0 bool v22; // zf char v23; // r6 int v24; // r0 int v25; // r0 int v26; // r0 int v27; // r1 int v28; // r8 int v29; // r10 int v30; // r7 int v31; // r0 int v32; // r9 int result; // r0 int v34; // r0 int v35; // r1 bool v36; // zf int i; // r7 int v38; // r5 MeleeAttackPushBacks = false; if (CharacterData.Name == "CannonGirlSmall") { if (ChargeUpType == 1) { if (ChargeUp >= ChargeUpMax) { damage += 240; AddShield(10, 40); ChargeUp = 0; } } } else if (ChargeUpType == 1) { if (ChargeUp >= ChargeUpMax) { MeleeAttackPushBacks = true; MeleeAttackPushBack = m_skills[0].SkillData.ChargePushback; } ChargeUp = 0; } LABEL_12: Attacking = true; if (projectileData != null && (projectileData.Indirect || projectileData.TravelType == 6)) { AttackTarget = new LogicVector2(x, y); v30 = x - GetX(); v29 = y - GetY(); } else { v30 = x - GetX(); v29 = y - GetY(); v31 = LogicMath.Sqrt(v30 * v30 + v29 * v29); if (v31 > 0) { v32 = 100 * range; v30 = v30 * v32 / v31; v29 = v29 * v32 / v31; } } AttackVector = new LogicVector2(v30, v29); SkillHoldTicks = -1; RapidFireAttackPattern = attp; RapidFireBulletsPerShoot = bps; RapidFireDamage = damage; RapidFireNormalDMG = normalDMG; RapidFireMsBetweenAttacks = msb; RapidFireProjectile = projectileData; RapidFireRange = range; RapidFireSpread = spread; RapidFireX = x; RapidFireY = y; ShootIndex = 0; LeftHand = 0; if (UltiSkill && GetCardValueForPassive("more_bullets_ulti", 1) >= 1) { RapidFireMsBetweenAttacks = GetCardValueForPassive("more_bullets_ulti", 0); } int unloadspeed = GetCardValueForPassive("decrease_unload_time", 1); if (!UltiSkill && unloadspeed >= 1) { RapidFireMsBetweenAttacks -= RapidFireMsBetweenAttacks * unloadspeed / 100; } if (GetData().UniqueProperty == 1) { RapidFireDamage += RapidFireDamage * GetPowerLevel() / 2; } if (Accessory != null && Accessory.Type == "take_damage" && Accessory.AccessoryData.SubType == 3 && Accessory.IsActive) { RapidFireDamage += Accessory.RewindHP / 2; Accessory.EndAccessoryActivation(); } RapidFireShootTimes = actime / msb; Accessory accessory = GetPlayer()?.Accessory; if (!UltiSkill && accessory != null) { if (accessory.IsActive && accessory.Type == "next_attack_change" && accessory.AccessoryData.SubType == 14) { RapidFireBulletsPerShoot = accessory.AccessoryData.CustomValue1; RapidFireSpread = accessory.AccessoryData.CustomValue2; RapidFireDamage += RapidFireDamage * accessory.AccessoryData.CustomValue3 / 100; if (accessory.AccessoryData.ActiveTicks == 100000) accessory.EndAccessoryActivation(); } } if (EFAI) { LastAttckTick = -100; } else { LastAttckTick = TicksGone; } if (IsInvisible && BreakInvisibilityOnAttack) { foreach (Skill skill in m_skills) { if (skill.SkillData.BehaviorType == "Invisibility") skill.TicksActive = 0; } } foreach (Skill skill in m_skills) { if (skill.SkillData.BehaviorType == "ProjectileShield") skill.TicksActive = 0; } } public void PauseMovement() { if (MoveEnd >= TicksGone) { MoveStart++; MoveEnd++; } } public int GetPathLength() { return LogicMath.Sqrt( (WayPoint.X - WayPointStart.X) * (WayPoint.X - WayPointStart.X) + (WayPoint.Y - WayPointStart.Y) * (WayPoint.Y - WayPointStart.Y)); } public void SetForcedAngle(int a2) { MoveAngle = a2; AttackAngle = a2; ForcedAngleTicks = TicksGone; } public void TickProjectileShield() { ProjectileShieldCoolDown = LogicMath.Max(0, ProjectileShieldCoolDown - 1); foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 1) continue; if (gameObject.GetIndex() / 16 == GetIndex() / 16) continue; if (gameObject.GetPosition().GetDistance(Position) > (ProjectileShieldScale + 100) || gameObject.GetPosition().GetDistance(Position) < (ProjectileShieldScale - 100)) continue; int Angle = LogicMath.GetAngle(gameObject.GetX() - GetX(), gameObject.GetY() - GetY()); if (Angle < AttackAngle - ProjectileShieldAngle / 2 || Angle > AttackAngle + ProjectileShieldAngle / 2) continue; Projectile projectile = (Projectile)gameObject; projectile.TargetReached(3); if (ProjectileShieldCoolDown == 0) { ProjectileShieldCoolDown = 8; } } } public bool IsPet() { if (TeamIndex != -1) return false; if (GetIndex() < 0) return false; return !CharacterData.IsHero(); } private void HandleMoveAndAttack() { int v2; // r9 int v3; // r6 int MoveStartTime; // r5 bool active; // r7 int v7; // r0 bool v8; // zf int v9; // r8 int v10; // r2 int v11; // r1 int v12; // r0 int v13; // r0 bool v14; // zf int v15; // r0 int v16; // r8 int v17; // r0 bool v18; // zf int v19; // r0 int v20; // r6 int v21; // r5 int v22; // r0 int v23; // r5 int v24; // r6 int v25; // r10 int v26; // r9 int v27; // r7 int v28; // r0 int v29; // r0 int v30; // r6 int v31; // r5 int v32; // r5 int v33; // r2 int v34; // r1 int v35; // r0 int v36; // r3 int v37; // r0 int v38; // r0 int v39; // r1 int v40; // r2 int v41; // r3 int v42; // r0 Character v43; // r5 int v44; // r7 int v45 = 0; // r0 int ChargeType; // r0 bool v47; // zf int v48; // r0 int v49; // r0 int v50; // r1 int v51; // r1 int v52; // r8 int v53; // r6 int v54; // r0 int v55; // r10 int v56; // r5 int v57; // r0 int v58; // r0 bool v59; // zf int v60; // r5 int v61; // r0 int v62; // r0 int v63; // r5 int v64; // r6 int v65; // r0 int v66; // r8 int v67; // r7 int v68; // r6 int v69; // r0 int v70; // r0 int v71; // r0 int v72; // r9 int v73; // r0 int v74; // r6 int v75; // r0 int v76; // r0 int v77; // r0 int v78; // r6 int v79; // r5 int v80; // r9 bool v81; // zf int v82; // r8 int v83; // r5 int v84; // r0 int v85; // r0 int v86; // r5 int v87; // r6 int v88; // r5 int v89; // r8 int v90; // r0 int v91; // r6 int v92; // r0 int v93; // r5 int v94; // r10 int v95; // r0 int v96; // r6 int v97; // r7 int v98; // r0 int v99; // r0 int v100; // r0 int v101; // r1 int v102; // r0 int v103; // r0 int v104; // r0 int v105; // r0 int v106; // r1 int v107; // r2 int v108; // r3 int v109; // r0 int v110; // r0 int v111; // r1 int v112; // r6 int v113; // r7 int v114; // r5 int v115; // r6 int v116; // r5 int v117; // r0 int v118; // r2 int v119; // r0 int v120; // r0 int v121; // r0 int v122; // r0 int v123; // r6 int v124; // r0 int v125; // r0 bool v126; // zf bool v127 = true; // zf bool Charging = false; // r7 int v129; // r8 int v130; // r0 int v131; // r1 int v132; // r0 int v133; // r0 int v134; // r8 int v135; // r0 int v136; // r8 int v137; // r0 int v138; // r0 int v139; // r0 int v140; // r0 int v142; // r0 int v143; // r1 int v146; // r0 int v147; // r0 int v148; // r3 int v149; // r2 int v150; // r7 int v151; // r6 int v152; // r8 int v153; // r5 int v154; // r7 int v155; // r6 int v156; // r9 int v157; // r0 int v158; // r1 int v159; // r0 int v160; // r0 int v161; // r1 int v162; // r2 int v163; // r3 bool v164; // zf int dword3B8; // r5 int v166; // r0 int v167; // r0 int v168; // r5 int v169; // r0 int v170; // r6 int v171; // r0 int v172; // r6 int v173; // r5 LogicVector2 v174; // r0 LogicVector2 v175; // r7 int v176; // r6 int v177; // r9 int v178; // r5 int v179; // r6 int v180; // r10 int v181; // r6 int v182; // r8 int v183; // r8 int v184; // r8 int v185; // r10 int v186; // r6 int v187; // r7 int v188; // r0 int v189; // r1 bool v190; // zf int v191; // r0 int v192; // r0 int v193; // r7 int v194; // r10 int TargetY; // r9 int v196; // r6 int v197; // r7 int v198; // r0 int TargetX; // r2 int FangUltiCount; // r9 int v201; // r0 int v202; // r0 int v203; // r0 int v204; // r0 int v205; // r9 int BuffsCount; // r2 int v207; // r8 int v208; // r0 int Buffs; // r3 int v210; // r0 int v211; // r6 int v212; // r8 int v213; // r6 int v214; // r5 int v215; // r6 int v216; // r0 bool v217; // zf int v218; // r2 int v219; // r5 int v220; // r0 int v222; // r0 bool v223; // zf int v224; // r10 int v225; // r6 int v226; // r9 int v227; // r7 int v228; // r8 int v229; // r5 int v230; // r0 int v231; // r1 int v232; // r7 int v233; // r9 int v234; // r0 int v235; // r0 int v236; // r9 int v237; // r6 int v238; // r0 Character v239; // r5 int v240; // r7 int v241; // r6 int v242; // r5 int v243; // r7 int v244; // r0 int v245; // r8 int v246; // r0 int v247; // r9 int v248; // r0 int v249; // r6 int v250; // r0 int v251; // r0 int v252; // r0 int v253; // r0 int v254; // r6 int v255; // r0 int v256; // r0 int v257; // r1 int v258; // r0 int v259; // r7 int v260; // r5 int v262; // r8 int v263; // r10 int v264; // r7 int v265; // r0 int v266; // r1 int v268; // r2 int v269; // r5 int v270; // [sp+0h] [bp-B0h] int v271; // [sp+10h] [bp-A0h] int v272; // [sp+38h] [bp-78h] int v273; // [sp+40h] [bp-70h] int v274; // [sp+40h] [bp-70h] int v275; // [sp+44h] [bp-6Ch] int v276; // [sp+44h] [bp-6Ch] int v277; // [sp+48h] [bp-68h] int v278; // [sp+48h] [bp-68h] int v279; // [sp+48h] [bp-68h] int v280; // [sp+48h] [bp-68h] bool v281; // [sp+4Ch] [bp-64h] int v282; // [sp+4Ch] [bp-64h] int MoveEndTime; // [sp+50h] [bp-60h] int v284; // [sp+50h] [bp-60h] int v285; // [sp+50h] [bp-60h] int v286; // [sp+50h] [bp-60h] int v287; // [sp+50h] [bp-60h] int v288; // [sp+50h] [bp-60h] int v289; // [sp+54h] [bp-5Ch] int v290; // [sp+54h] [bp-5Ch] int v291; // [sp+54h] [bp-5Ch] int v292; // [sp+54h] [bp-5Ch] int v293; // [sp+54h] [bp-5Ch] int unsigned___int81B0; // [sp+58h] [bp-58h] int v295; // [sp+58h] [bp-58h] int v296; // [sp+58h] [bp-58h] int v297; // [sp+58h] [bp-58h] int v298; // [sp+58h] [bp-58h] int v299; // [sp+58h] [bp-58h] int v300; // [sp+58h] [bp-58h] int v301; // [sp+5Ch] [bp-54h] int v302; // [sp+5Ch] [bp-54h] int v303; // [sp+60h] [bp-50h] int v304; // [sp+64h] [bp-4Ch] if (CharacterData.Name == "Voodoo") { if (!IsInBush() && !IsInWater()) { m_skills[0] = new Skill(DataTables.Get(DataType.Skill).GetData("VoodooWeaponEarth").GetGlobalId(), false, this); } if (IsInBush() && !IsInWater()) { m_skills[0] = new Skill(DataTables.Get(DataType.Skill).GetData("VoodooWeaponForest").GetGlobalId(), false, this); } if (IsInWater() && !IsInBush()) { m_skills[0] = new Skill(DataTables.Get(DataType.Skill).GetData("VoodooWeaponWater").GetGlobalId(), false, this); } } if (CharacterData.Name == "KnightPet_Fixed") // ������� �� ���� ������ � ���� ������������� { v239 = GetEnemy(); if (IsHealer) v239 = GetTeammateForHeal(); if (v239 == null) v239 = (Character)GameObjectManager.GetGameObjectByID(ParentGID); if (v239 != null) { var closest = v239.GetPosition(); TileMap tileMap = GameObjectManager.GetBattle().GetTileMap(); var Tiles = new byte[tileMap.LogicWidth / 300, tileMap.LogicHeight / 300]; for (int i = 0; i < tileMap.LogicWidth / 300; i++) { for (int j = 0; j < tileMap.LogicHeight / 300; j++) { Tile tile = tileMap.GetTile(i, j, true); bool blocksMovement = tile.Data.BlocksMovement; char tileCode = tile.Code; if (CharacterData.CanWalkOverWater && tileCode == 'W') Tiles[i, j] = 1; else Tiles[i, j] = (byte)(blocksMovement ? 0 : 1); } } PathFinder pathFinder = new PathFinder(Tiles); pathFinder.Diagonals = false; var start = new Point(LogicMath.Clamp(GetX(), 300, tileMap.LogicWidth - 300) / 300, LogicMath.Clamp(GetY(), 300, tileMap.LogicHeight - 300) / 300); var end = new Point(LogicMath.Clamp(closest.X, 300, tileMap.LogicHeight - 300) / 300, LogicMath.Clamp(closest.Y, 300, tileMap.LogicWidth - 300) / 300); var Points = pathFinder.FindPath(start, end); if (Points != null) { m_botHadPathThisTick = true; PathFinderNode node = Points[0]; for (int i = 0; i < Points.Count; i++) { if (Points[i].X != node.X && Points[i].Y != node.Y) { node = Points[i - 1]; break; } if (i == Points.Count - 1) { node = Points[i]; break; } } MoveTo(0, node.X * 300 + 150, node.Y * 300 + 150, 0, 0, 0, 0); } } m_ticksSinceBotEnemyCheck = TicksGone; var playersInZone = GameObjectManager.GetGameObjects() .Where(g => g.GetObjectType() == 0) .Cast() .Where(c => Position.GetDistance(c.GetPosition()) <= 600) .Where(c => c.GetTeamIndex() != GetTeamIndex()) .ToList(); if (playersInZone.Count > 0) { Console.WriteLine("ok"); AreaEffect v1 = GameObjectFactory.CreateGameObjectByData(DataTables.GetAreaEffectByName("KnightPetExplosion")); v1.SetPosition(GetX(), GetY(), 0); v1.SetIndex(GetIndex()); Character owner = (Character)GameObjectManager.GetGameObjectByID(ParentGID); int tmpDamage = 160; v1.SetSource(owner, 1); v1.Damage = tmpDamage; GameObjectManager.AddGameObject(v1); v1.Trigger(); if (owner != null) owner.ChargeUp += tmpDamage / 6 + tmpDamage / 6 * owner.GetPowerLevel() / 4; GameObjectManager.RemoveGameObject(this); } } if (GetBattle().GetGameModeVariation() == 16 && GetBattle().CarryableTeam0 != null && GetBattle().CarryableTeam1 != null) { if (GetTeamIndex() == 0) { if (Position.GetDistance(GetBattle().CarryableTeam0.GetPosition()) < 300 && CharacterData.IsHero()) { GetBattle().CarryableTeam0.CarringCharacter = this; } } else if (GetTeamIndex() == 1) { if (Position.GetDistance(GetBattle().CarryableTeam1.GetPosition()) < 300 && GetBattle().Carryable != this) { GetBattle().CarryableTeam1.CarringCharacter = this; } } if (GetBattle().GetGameModeVariation() == 16 && GetBattle().CarryableTeam0 != null && GetBattle().CarryableTeam1 != null) { if (GetTeamIndex() == 0) { if (Position.GetDistance(GetBattle().CarryableTeam0.GetPosition()) < 300 && CharacterData.IsHero()) { GetBattle().CarryableTeam0.CarringCharacter = this; } } else if (GetTeamIndex() == 1) { if (Position.GetDistance(GetBattle().CarryableTeam1.GetPosition()) < 300 && GetBattle().Carryable != this) { GetBattle().CarryableTeam1.CarringCharacter = this; } } } if (CharacterData.IsCarryable()) { if (CarringCharacter != null && !CarringCharacter.IsAlive()) CarringCharacter = null; if (CarringCharacter != null && CarringCharacter.CharacterData.IsHero()) { SetPosition( CarringCharacter.GetX() + LogicMath.GetRotatedX(-150, 0, CarringCharacter.AttackAngle), CarringCharacter.GetY() + LogicMath.GetRotatedY(-150, 0, CarringCharacter.AttackAngle), 0 ); } } } if (GetBattle()?.GetGameModeVariation() == 5) { var battle = GetBattle(); var carryable = battle?.Carryable; if (battle != null && carryable != null && Position.GetDistance(carryable.GetPosition()) < 300 && carryable != this && CarryablePersonImunTicks <= 0 && carryable.CarringCharacter == null && CharacterData?.IsHero() == true && GetZ() <= 0 && !KnockBacked && carryable.CarryablePickTicks <= 0 && !IsChargeActive()) { carryable.CarringCharacter = this; } if (CharacterData?.IsCarryable() == true) { if (CarringCharacter != null && !CarringCharacter.IsAlive()) { CarringCharacter = null; } if (CarringCharacter?.CharacterData?.IsHero() == true) { SetPosition( CarringCharacter.GetX() + LogicMath.GetRotatedX(200, 0, CarringCharacter.AttackAngle), CarringCharacter.GetY() + LogicMath.GetRotatedY(200, 0, CarringCharacter.AttackAngle), 0 ); } var player = CarringCharacter?.GetPlayer(); if (player != null && CarringCharacter?.CharacterData?.IsHero() == true) { LastPickupPlayerIndex = player.TeamIndex; LastPickupPlayerIndexTOCHNO = player.PlayerIndex; } } } bool ShouldHandleMoveAndAttack = false; foreach (GameObject obj in GameObjectManager.GetGameObjects()) { if (Position.GetDistance(obj.GetPosition()) <= 900 && obj.GetIndex() / 16 != GetIndex() / 16) { obj.SetForcedVisible(); } if (CharacterData.IsHero()) { if (obj.GetObjectType() == 3) { Item item = (Item)obj; if (Position.GetDistance(item.GetPosition()) < 350 && item.CanBePickedUp(this) && !IsImmuneAndBulletsGoThrough(item.IsInRealm)) { item.PickUp(this); } } } } active = HasActiveSkill("Attack"); if (!active && !IsCharging && !HasActiveSkill("ProjectileShield")) Ultiing = false; v281 = active || HasActiveSkill("ProjectileShield"); if (TicksGone < DeployedTick + DEPLOY_TICKS) { if (!CharacterData.IsHero()) { State = 4; BlockHealthRegen(); ShouldHandleMoveAndAttack = false; PauseMovement(); goto LABEL_19; } } ShouldHandleMoveAndAttack = true; if (CastingTime >= 1) { State = 0; BlockHealthRegen(); if (!(GetCurrentCastingSkill()?.CanMoveAtSameTime ?? true)) PauseMovement(); v16 = 1; goto LABEL_19; } if (HasActiveSkill("Ww")) { State = 0; BlockHealthRegen(); TickWhirlwind(); v16 = 1; goto LABEL_19; } if (active) { State = 2; SetForcedVisible(); BlockHealthRegen(); if (RapidFireTick != TicksGone) TickRapidFire(); } else { v16 = 1; if (m_stunTicks >= 1) { State = 0; HealthRegenBlockedTick = TicksGone; m_stunTicks--; } else IsWeaklyStunned = false; } if (HasActiveSkill("ProjectileShield")) { State = 2; TickProjectileShield(); } LABEL_19: if (DraggingObject != null) { if (DraggingObject.GetObjectType() == 0) { Character DraggingObject = (Character)this.DraggingObject; if (DraggingObject.IsAlive() && TicksGone < DraggingObject.MoveEnd - 2 && DraggingObject.IsCharging) { v277 = DraggingObject.GetX(); v24 = DraggingObject.GetY(); LogicVector2 v309 = new LogicVector2(-1, -1); v26 = GetX(); v27 = GetY(); v30 = DraggingOffsetY + v24; v31 = DraggingOffsetX + v277; if (GamePlayUtil.GetClosestAnyCollision( v26, v27, v31, v30, GameObjectManager.GetBattle().GetTileMap(), v309, 0, 0, 0, 0, DraggingObject.ImmunToPushbackOutOfWalls)) { v32 = DraggingObject.GetX(); v33 = DraggingObject.GetY(); v34 = v32 + 1; v36 = 0; } else { v36 = GetZ(); v34 = v31; v33 = v30; } SetPosition(v34, v33, v36); } else this.DraggingObject = null; } else { Projectile DO = (Projectile)DraggingObject; if (DO.IsAlive() && DO.State == 0) SetPosition(DraggingOffsetX + DO.GetX(), DraggingOffsetY + DO.GetY(), 0); else DraggingObject = null; } } if (!ShouldHandleMoveAndAttack) return; v43 = null; if (IsCharging) { SetForcedVisible(); if (!GamePlayUtil.IsJumpCharge(m_activeChargeType) || TicksGone == MoveEnd) TickCharge(); v50 = MoveStart; v45 = LogicMath.Clamp(TicksGone - v50, 0, 255); } ChargeAnimation = v45; if (!IsPlayerControlRemoved() && CharacterData.HasAutoAttack() && CharacterData.AutoAttackRange >= 1 && !IsInvincible) { v52 = TicksGone; v53 = 0; v43 = GetClosestEnemy(CharacterData.AutoAttackRange, 1, CharacterData.IsBase(), false, null, false, false, false); if (Attacking) v43 = null; } if (Attacking) Attacking = false; if (v43 != null && !Attacking && GamePlayUtil.LOSCleared(Position.X, Position.Y, v43.Position.X, v43.Position.Y, GetBattle().GetTileMap())) { Attacking = true; AutoAttackTarget = v43; } if (AutoAttackTarget == null) ; else { if (AutoAttackTarget.Position.GetDistance(Position) <= CharacterData.AutoAttackRange * 100 && AutoAttackTarget.IsAlive()) { if (!CharacterData.IsHero() && !IsPlayerControlRemoved()) StopMovement(); } else { ; } } LABEL_118: if ((!v127 || (TicksGone > MoveEnd)) && !IsSteerMovementActive()) { Charging = IsCharging; if (IsCharging && (m_activeChargeType == 2 || m_activeChargeType == 11)) { AreaEffect areaEffect = new AreaEffect(ChargeAreaEffectData); areaEffect.SetPosition(GetX(), GetY(), 0); areaEffect.SetIndex(GetIndex()); areaEffect.SetSource(this, 2); areaEffect.Damage = ChargeDamage; areaEffect.NormalDMG = ChargeNormalDMG; v15 = GetCardValueForPassive("prey_on_the_weak", 1); if (v15 >= 0) { areaEffect.SetPreyOnTheWeak(v15, GetCardValueForPassive("prey_on_the_weak", 0)); } GameObjectManager.AddGameObject(areaEffect); areaEffect.Trigger(); if (GetCardValueForPassive("charge_end_damage", 1) >= 0) { AreaEffect areaEffect1 = new AreaEffect(DataTables.GetAreaEffectByName("EnragerStarPowerDamage")); areaEffect1.SetPosition(GetX(), GetY(), 0); areaEffect1.SetIndex(GetIndex()); areaEffect1.SetSource(this, 2); areaEffect1.NormalDMG = 0; GameObjectManager.AddGameObject(areaEffect1); areaEffect1.Trigger(); } } if (m_activeChargeType == 19) { foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 0) continue; Character c = (Character)gameObject; if (!c.CharacterData.IsHero()) continue; if (Position.GetDistance(c.GetPosition()) > 1000) continue; Attached = true; AttachedCharacter = c; } } if (IsCharging && m_activeChargeType == 105) { AreaEffect areaEffect = new AreaEffect(DataTables.GetAreaEffectByName("PullRopeStun")); areaEffect.SetPosition(GetX(), GetY(), 0); areaEffect.SetIndex(GetIndex()); areaEffect.SetSource(this, 2); areaEffect.Damage = ChargeDamage; areaEffect.NormalDMG = ChargeNormalDMG; v15 = GetCardValueForPassive("prey_on_the_weak", 1); if (v15 >= 0) { areaEffect.SetPreyOnTheWeak(v15, GetCardValueForPassive("prey_on_the_weak", 0)); } GameObjectManager.AddGameObject(areaEffect); areaEffect.Trigger(); } if (IsCharging && m_activeChargeType == 101) { _spawnedEffects.Clear(); _lastX = -1; _lastY = -1; } IsCharging = false; Knockback3 = false; ChargeAnimation = 0; Knockback2 = false; KnockBacked = false; ViusalChargeType = 0; if (Charging) { if (ShouldExecuteColetteChargeOnReturn) { TriggerCharge(WayPoint2.X, WayPoint2.Y, ChargeSpeed, m_activeChargeType, ChargeDamage, ChargePushback, false); } v137 = GetCardValueForPassive("speed_after_ulti", 1); if (v137 >= 0) { v79 = v137; v138 = GetCardValueForPassive("speed_after_ulti", 0); GiveSpeedFasterBuff(v79, v138, true); } if (GetCardValueForPassive("barrel_defense", 1) >= 0) AddShield(GetCardValueForPassive("barrel_defense", 1), GetCardValueForPassive("barrel_defense", 0)); } if (!CharacterData.HasAutoAttack() || AutoAttackTarget == null) { State = active || HasActiveSkill("ProjectileShield") ? 2 : 0; goto LABEL_241; } State = 2; if (CharacterData.Name != "KnightPet_Fixed" && !IsHealer && AutoAttackTarget.Position.GetDistance(Position) <= CharacterData.AutoAttackRange * 100 && GamePlayUtil.LOSCleared(Position.X, Position.Y, AutoAttackTarget.Position.X, AutoAttackTarget.Position.Y, GetBattle().GetTileMap())) Attack(AutoAttackTarget, AutoAttackTarget.GetX(), AutoAttackTarget.GetY(), CharacterData.AutoAttackRange, DataTables.GetProjectileByName(CharacterData.AutoAttackProjectile), CharacterData.AutoAttackDamage + AutoAttackDamangeBoost, CharacterData.AutoAttackDamage, CharacterData.AutoAttackProjectileSpread, CharacterData.AutoAttackBulletsPerShot); else if (GetTeammateForHeal() != null) Attack(GetTeammateForHeal(), GetTeammateForHeal().GetX(), GetTeammateForHeal().GetY(), CharacterData.AutoAttackRange, DataTables.GetProjectileByName(CharacterData.AutoAttackProjectile), CharacterData.AutoAttackDamage + AutoAttackDamangeBoost, CharacterData.AutoAttackDamage, CharacterData.AutoAttackProjectileSpread, CharacterData.AutoAttackBulletsPerShot); else AutoAttackTarget = null; goto LABEL_241; } if (IsSteerMovementActive()) v176 = GetNextSteeredPos(PosDelta); else v176 = GetPosAtTick(0, TicksGone, PosDelta, 0); LogicVector2 PrePos = Position.Clone(); SetPosition(PosDelta.X, PosDelta.Y, v176); if (false) { } else { v159 = 1; if (v281) v159 = 3; State = v159; } LABEL_262: if (Position != PrePos) { if (ForcedAngleTicks + 1 < TicksGone && !IsSteerMovementActive()) UpdateMoveDirection(0, WayPoint, PosDelta, WayPoint.X, WayPoint.Y); if (State == 1) AttackAngle = MoveAngle; v167 = GetCardValueForPassive("running_charges_ulti", 0); if (v167 >= 0) { if (GetPlayer() != null && !GetPlayer().HasUlti()) { if (!IsPlayerControlRemoved()) { v262 = GetCardValueForPassive("running_charges_ulti", 1); v264 = RunningChargingUlti + Position.GetDistance(PrePos); v265 = v264 / v262; v266 = v264 - v265 * v262; RunningChargingUlti = v266; if (v265 >= 1) ChargeUlti(v265 * v167, false, true, GetPlayer(), this); } } else { RunningChargingUlti = 0; } } v171 = GetCardValueForPassive("running_charges_weapon", 1); if (v171 >= 0) { v172 = v171; if (GetWeaponSkill().HasFullCharge(this)) { RunningChargingUlti = 0; } else if (!IsPlayerControlRemoved()) { v232 = RunningChargingUlti + Position.GetDistance(PrePos); v233 = v232 / v172; RunningChargingUlti = v232 - v233 * v172; if (v233 >= 1) { v234 = GetCardValueForPassive("running_charges_weapon", 0); GetWeaponSkill().AddCharge(this, v234 * v233); } } } } LABEL_241: if (CharacterData.Name == "SpawnerPet") { if (GameObjectManager.GetGameObjectByID(ParentGID) == null) GameObjectManager.RemoveGameObject(this); } // ClusterBombPet (Tick ult): detonate on contact with nearest enemy hitbox. // Checked every tick (no throttle) so the reaction is instant. // CauseDamage with IgnoreInvincible=true passes through the full death pipeline // and triggers DeathAreaEffect = ClusterBombPetExplosion. if (CharacterData.Name == "ClusterBombPet") { Character cbpEnemy = GetEnemy(); if (cbpEnemy != null) { int cbpDx = cbpEnemy.GetX() - GetX(); int cbpDy = cbpEnemy.GetY() - GetY(); int cbpDist = LogicMath.Sqrt(cbpDx * cbpDx + cbpDy * cbpDy); if (cbpDist <= CharacterData.CollisionRadius + cbpEnemy.CharacterData.CollisionRadius) { CauseDamage(null, m_hitpoints, 0, false, null, false, true); } } } if (CharacterData.Name == "SpawnerDudeTurret" && TicksGone > m_ticksSinceBotEnemyCheck + 10) { bool spawn = true; Character summoned = SummonMinion( DataTables.GetCharacterByName(CharacterData.Pet), GetX(), GetY(), 0, 1, 1, 0, 0, GetBattle(), GetIndex() % 16, 0, GetGlobalID(), false, false, 0, false, 0 ); foreach (Character character in GameObjectManager.GetCharacters()) { if (character.CharacterData.IsPet() && character.ParentGID == GetGlobalID()) { if (summoned == character) { spawn = false; return; } } } m_ticksSinceBotEnemyCheck = TicksGone; } if (CharacterData.Type == "Minion_FindEnemies" && TicksGone > m_ticksSinceBotEnemyCheck + 10 && CharacterData.Name != "KnightPet_Fixed") { v239 = GetEnemy(); if (IsHealer) v239 = GetTeammateForHeal(); if (v239 == null) v239 = (Character)GameObjectManager.GetGameObjectByID(ParentGID); if (v239 != null) { var closest = v239.GetPosition(); TileMap tileMap = GameObjectManager.GetBattle().GetTileMap(); var Tiles = new byte[tileMap.LogicWidth / 300, tileMap.LogicHeight / 300]; for (int i = 0; i < tileMap.LogicWidth / 300; i++) { for (int j = 0; j < tileMap.LogicHeight / 300; j++) { Tile tile = tileMap.GetTile(i, j, true); bool blocksMovement = tile.Data.BlocksMovement; char tileCode = tile.Code; if (CharacterData.CanWalkOverWater && tileCode == 'W') Tiles[i, j] = 1; else Tiles[i, j] = (byte)(blocksMovement ? 0 : 1); } } PathFinder pathFinder = new PathFinder(Tiles); pathFinder.Diagonals = false; var start = new Point(LogicMath.Clamp(GetX(), 300, tileMap.LogicWidth - 300) / 300, LogicMath.Clamp(GetY(), 300, tileMap.LogicHeight - 300) / 300); var end = new Point(LogicMath.Clamp(closest.X, 300, tileMap.LogicHeight - 300) / 300, LogicMath.Clamp(closest.Y, 300, tileMap.LogicWidth - 300) / 300); var Points = pathFinder.FindPath(start, end); if (Points != null) { PathFinderNode node = Points[0]; for (int i = 0; i < Points.Count; i++) { if (Points[i].X != node.X && Points[i].Y != node.Y) { node = Points[i - 1]; break; } if (i == Points.Count - 1) { node = Points[i]; break; } } MoveTo(0, node.X * 300 + 150, node.Y * 300 + 150, 0, 0, 0, 0); } } m_ticksSinceBotEnemyCheck = TicksGone; } if (CharacterData.Type == "Minion_Duplicate") { if (ParentGID == 0) CauseDamage(null, 99999, 99999, false, null); else { Character owner = (Character)GameObjectManager.GetGameObjectByID(ParentGID); } } if (DisplayUltiTmp) { if (!IsCharging) DisplayUltiTmp = false; } return; } private bool CheckObstacle(int nextTiles) { int movingSpeed = CharacterData.Speed / 20; movingSpeed *= (100 - slowingModifier) / 100; movingSpeed *= (100 + AcceleratingModifier) / 100; int deltaX; int deltaY; int newX = this.Position.X; int newY = this.Position.Y; for (int i = 0; i < nextTiles; i++) { if (PosDelta.X - Position.X > 0) deltaX = LogicMath.Min(movingSpeed, PosDelta.X - Position.X); else deltaX = LogicMath.Max(-movingSpeed, PosDelta.X - Position.X); if (PosDelta.Y - Position.Y > 0) deltaY = LogicMath.Min(movingSpeed, PosDelta.Y - Position.Y); else deltaY = LogicMath.Max(-movingSpeed, PosDelta.Y - Position.Y); newX += deltaX; newY += deltaY; if (!GameObjectManager.GetBattle().IsInPlayArea(newX, newY)) return true; Tile nextTile = GameObjectManager.GetBattle().GetTileMap().GetTile(newX, newY); if (nextTile == null) return true; if (nextTile.Data.BlocksMovement && !nextTile.IsDestructed()) return true; } return false; } public void UltiEnabled() { m_usingUltiCurrently = true; } public void UltiDisabled() { m_usingUltiCurrently = false; } public override bool IsAlive() { return m_hitpoints > 0; } public override int GetRadius() { return CharacterData.CollisionRadius; } public int GetWeaponSkillDamage() { return (int)Math.Floor((double)WeaponSkillData.Damage * (1.0 + ((m_heroLevel) / 10.0))); } public void SetHeroLevel(int level) { m_heroLevel = level; m_maxHitpoints = (int)Math.Floor((double)CharacterData.Hitpoints * (1.0 + ((level) / 10.0))); m_hitpoints = m_maxHitpoints; OrginalMaxHP = m_maxHitpoints; SetStarPowerBoosts(); } public int GetHeroLevel() { return m_heroLevel; } public int GetNormalWeaponDamage() { return m_skills[0].SkillData.Damage + ((int)(((float)5 / 100) * (float)m_skills[0].SkillData.Damage)) * (m_heroLevel + m_damageMultiplier); } public int GetAbsoluteDamage(int damage) { return damage + ((int)(((float)5 / 100) * (float)damage)) * (m_heroLevel + m_damageMultiplier) + damage * (DamageModifier) / 100; } public int PathfindTo( int a1, int x, int y, int a4, int a5, int a6, int a7, int a8, int a9) { int v9; // r6 int v10; // r2 int v11; // r0 int v12; // r7 int v13; // r3 int v14; // r1 int v15; // r5 int v16; // r3 int v17; // r4 int v18; // r2 int v19; // r6 int v20; // d16 int v21; // d17 int v22; // r2 int v23; // r5 int v24; // r4 int v25; // r0 int v26; // r4 int v27; // r0 int v28; // r1 int v29; // r0 int v30; // r5 int valid; // r0 int v32; // r4 int v33; // r7 int v34; // r0 int v35; // r1 int v36; // r0 int v37; // r0 int v38; // r6 int v39; // r0 int v40; // r0 int v41; // r4 int v42; // r0 int v43; // r0 int v44; // r1 int v45; // r0 int v46; // r9 int v47; // r1 int v48; // r10 int v49; // r5 int v50; // r9 int v51; // r0 int v52; // r8 int v53; // r0 int v54; // r1 int v55; // r2 int v56; // r3 int v57; // t1 int v58; // r0 int v59; // r5 int v60; // r9 int v61; // r0 int v62; // r8 int v63; // r0 int v64; // r1 int v65; // r2 int v66; // r3 int v67; // t1 int v68; // r0 int v69; // r5 int v70; // r9 int v71; // r0 int v72; // r8 int v73; // r0 int v74; // r1 int v75; // r2 int v76; // r3 int v77; // t1 int v78; // r0 int v79; // r5 int v80; // r9 int v81; // r0 int v82; // r8 int v83; // r0 int v84; // r1 int v85; // r2 int v86; // r3 int v87; // t1 int v88; // r0 int v89; // r0 int v90; // r8 int v91; // r7 int v92; // r0 int v93; // r1 int v94; // r2 int v95; // r3 int v96; // t1 int v97; // r0 int v98; // r8 int v99; // r7 int v100; // r0 int v101; // r1 int v102; // r2 int v103; // r3 int v104; // t1 int v105; // r5 int v106; // r7 int v107; // r0 int v108; // r5 int v109; // r4 int v110; // r7 bool v111; // zf bool v112; // zf int v113; // r0 int v114; // r4 int v115; // r0 int v116; // r0 int v117; // r4 int v118; // r6 int v119; // r9 int v120; // r7 int v121; // r5 int v122; // r0 int v123; // r1 int v124; // r7 int v125; // r4 int v126; // r9 int v127; // r5 int v128; // r8 int v129; // r10 int v130; // r0 int v131; // r4 int v132; // r0 int v133; // r1 int v134; // r2 int v135; // r3 int v136; // t1 int v137; // r0 int v138; // r9 int v139; // r10 int v140; // r0 int v141; // r8 int v142; // r0 int v143; // r1 int v144; // r2 int v145; // r3 int v146; // t1 int v147; // r5 int v148; // r9 int v149; // r0 int v150; // r8 int v151; // r0 int v152; // r1 int v153; // r2 int v154; // r3 int v155; // t1 int v156; // r0 int v157; // r5 int v158; // r9 int v159; // r0 int v160; // r8 int v161; // r0 int v162; // r1 int v163; // r2 int v164; // r3 int v165; // t1 int v166; // r0 int v167; // r0 int v168; // r4 int v169; // r0 int v170; // r8 int v171; // r4 int v172; // r6 int v173; // r7 int v174; // r5 int v175; // r0 int v176; // r8 int v177; // r7 int v178; // r10 int v179; // r0 int v180; // r9 int v181; // r0 int v182; // r1 int v183; // r2 int v184; // r3 int v185; // t1 int v186; // r0 int v187; // r7 int v188; // r10 int v189; // r0 int v190; // r9 int v191; // r0 int v192; // r1 int v193; // r2 int v194; // r3 int v195; // t1 int v196; // r0 int v197; // r6 int v198; // lr int v199; // r7 int v200; // r4 int v201; // d16 int v202; // d17 int v203; // r6 int v204; // r4 int v205; // r5 int v206; // d16 int v207; // d17 int v208; // r7 int v209; // r6 int v210; // r4 int v211; // d16 int v212; // d17 int v213; // r7 int v214; // r6 int v215; // r4 int v216; // d16 int v217; // d17 int v218; // r4 int v219; // r6 int v220; // r5 int v221; // d16 int v222; // d17 int v223; // r4 int v224; // r6 int v225; // r5 int v226; // d16 int v227; // d17 int v228; // r5 int v229; // r9 int v230; // r0 int v231; // r8 int v232; // r0 int v233; // r1 int v234; // r2 int v235; // r3 int v236; // t1 int v237; // r0 int v238; // r5 int v239; // r9 int v240; // r0 int v241; // r8 int v242; // r0 int v243; // r1 int v244; // r2 int v245; // r3 int v246; // t1 int v247; // r0 int v249; // r4 int v250; // r6 int v251; // r5 int v252; // d16 int v253; // d17 int v254; // r4 int v255; // r6 int v256; // r5 int v257; // d16 int v258; // d17 int v259; // r7 int v260; // r6 int v261; // r4 int v262; // d16 int v263; // d17 int v264; // r7 int v265; // r6 int v266; // r4 int v267; // d16 int v268; // d17 int v269; // r7 int v270; // r6 int v271; // r4 int v272; // d16 int v273; // d17 int v274; // r7 int v275; // r6 int v276; // r4 int v277; // d16 int v278; // d17 int v279; // r7 int v280; // r6 int v281; // r4 int v282; // d16 int v283; // d17 int v284; // r7 int v285; // r6 int v286; // r4 int v287; // d16 int v288; // d17 char v289; // [sp+18h] [bp-60h] int v292; // [sp+24h] [bp-54h] int v293; // [sp+28h] [bp-50h] int v295; // [sp+30h] [bp-48h] int v296; // [sp+34h] [bp-44h] int v298; // [sp+3Ch] [bp-3Ch] int v299; // [sp+40h] [bp-38h] int v300; // [sp+44h] [bp-34h] int v301; // [sp+48h] [bp-30h] int v302; // [sp+48h] [bp-30h] int v303; // [sp+4Ch] [bp-2Ch] int v304; // [sp+58h] [bp-20h] WayPoint.X = x; WayPoint.Y = y; WayPointStart.X = GetX(); WayPointStart.Y = GetY(); return 0; } public int GetGearBoost(int LogicType) { if (Gear1 != null) { if (Gear1.GearData.LogicType == LogicType) { Gear1.OnBoost(); return Gear1.GearData.ModifierValue; } } if (Gear2 != null) { if (Gear2.GearData.LogicType == LogicType) { Gear2.OnBoost(); return Gear2.GearData.ModifierValue; } } return 0; } public void Watch(Character Target) { SetStartRotation(LogicMath.GetAngle(Target.GetX() - GetX(), Target.GetY() - GetY())); } public bool IsPlayerControlRemoved() { BattlePlayer v2; // r0 int v3; // r5 bool v4; // zf bool v6; // zf int v7; // r0 bool v9; // zf int v10; // r0 int v11; // r1 int v12; // r1 if (ViusalChargeType > 0) return false; bool result = true; v2 = GetPlayer(); if (v2 == null) goto LABEL_6; if (v2.Accessory != null) { if (v2.Accessory.IsActive && v2.Accessory.AccessoryData.StopMovement) return result; } if (true) ; else return result; LABEL_6: result = true; if (!IsCharging) { v6 = !KnockBacked; if (!KnockBacked) v6 = m_stunTicks <= 0; if (v6) return DraggingObject != null; } return result; } public void UltiUsed() { BattlePlayer player = GetPlayer(); if (player != null) { if (!GetBattle().HasEventModifier(13)) player.UseUlti(); m_usingUltiCurrently = false; } Ultiing = true; } public Character ReloadPlayer(CharacterData data) { Character n = GetBattle().SpawnHero(data, m_heroLevel, GetIndex(), 0, false); n.SetPosition(GetX(), GetY(), 0); GetPlayer().OwnObjectId = n.GetGlobalID(); n.m_hitpoints = m_hitpoints; n.m_skills[0].Charge = m_skills[0].Charge; CauseDamage(this, 99999, 0, false, null, false, true); GameObjectManager.RemoveGameObject(this); return n; } public int MoveTo(int X, int Y) { MoveTo(0, X, Y, 0, 0, 0, 0); return 0; } public int MoveTo(int a1, int deltax, int deltay, int a4, int a5, int a6, int a7) { int v10; // r6 int v11; // r7 int v12; // r0 int v13; // r0 int v14; // r0 bool v15; // zf int v16; // r10 int v17; // r5 int x1; // r7 MAPDST int y1; // r6 MAPDST int v20; // r0 int v21; // r8 int v22; // r5 int v23; // r9 int v24; // r7 int v25; // r5 int i; // r10 int v27; // r6 int v28; // r9 int v29; // r0 int v30; // r0 int v31; // r8 int v32; // r2 int v33; // r0 int v34; // r6 int v35; // r0 int v36; // r0 int v37; // r7 int x; // r5 int v39; // r6 int y; // r9 int v41; // r0 int v42; // r1 int v43; // r7 int v44; // r5 int v45; // r0 int v46; // r8 int v47; // r6 int v48; // r0 int v49; // r0 int v50; // r0 int v51; // r6 int v52; // r9 int v53; // r5 int v54; // r1 int v55; // r6 int v56; // r0 int v57; // r0 int v58; // r0 int v59; // r9 int v60; // r6 int v61; // r10 int v62; // r7 int v63; // r0 char v64; // r8 int v65; // r6 int v66; // r0 int v67; // r7 int v68; // r0 int v69; // r0 int v70; // r0 int v71; // r7 int v72; // r5 int v73; // r0 int v74; // r6 int v75; // r0 int v76; // r0 int v77; // r5 int v78; // r0 int v80; // r6 int v81; // r5 int v82; // r7 int v83; // r0 int v84; // [sp+0h] [bp-58h] int v85; // [sp+4h] [bp-54h] int v86; // [sp+18h] [bp-40h] int v87; // [sp+1Ch] [bp-3Ch] int v88; // [sp+20h] [bp-38h] int v91; // [sp+28h] [bp-30h] int v93; // [sp+30h] [bp-28h] BYREF if (!IsPlayerControlRemoved()) { LogicVector2 vector = new LogicVector2(deltax, deltay); GamePlayUtil.GetClosestLevelBorderCollision(GetX(), GetY(), deltax, deltay, GameObjectManager.GetBattle().GetTileMap(), 0, vector); if (vector.X > deltax) vector.X += 50; if (vector.X < deltax) vector.X -= 50; if (vector.Y > deltay) vector.Y += 50; if (vector.Y < deltay) vector.Y -= 50; v46 = CharacterData.Speed; PathfindTo( a1, vector.X, vector.Y, 0, 0, 0, a6, 1, a7); PathLength = LogicMath.Sqrt( (WayPoint.X - WayPointStart.X) * (WayPoint.X - WayPointStart.X) + (WayPoint.Y - WayPointStart.Y) * (WayPoint.Y - WayPointStart.Y)); if (PathLength >= 1) { v55 = TicksGone; v56 = PathLength; MoveStart = v55; v57 = 5 * v56; v46 += GetBuffedSpeed(); v46 += GetUnbuffedSpeed(); MoveEnd = LogicMath.Max(1, 4 * v57 / v46) + v55; } } return 0; } public void AddConsumableShield(int a2, int a3) { if (ConsumableShield < a2) { ConsumableShield = a2; ConsumableShieldMax = a2; ConsumableShieldTick = TicksGone; ConsumableShieldDuration = a3; } } public Character GetActivePet(bool IgnoreBase) { foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 0) continue; Character character = (Character)gameObject; if (character != this && character.GetIndex() == GetIndex() && character.IsAlive()) { if (!IgnoreBase || character.CharacterData.Speed > 0) return character; } } return null; } //v32 savsravl /* public override void Encode(BitStream bitStream, bool isOwnObject, int visionTeam) { isOwnObject = isOwnObject && CharacterData.IsHero(); base.Encode(bitStream, isOwnObject, visionTeam); bitStream.WritePositiveInt(visionTeam == this.GetIndex() / 16 ? 10 : GetFadeCounter(), 4); if (CharacterData.HasAutoAttack() || CharacterData.Speed != 0) { if (isOwnObject) { bitStream.WriteBoolean(IsPlayerControlRemoved()); // 0xa1aff8 if (bitStream.WriteBoolean(ForcedAngleTicks + 1 >= TicksGone || IsSteerMovementActive()) || IsPlayerControlRemoved()) { bitStream.WritePositiveIntMax511(AttackAngle); bitStream.WritePositiveIntMax511(MoveAngle); } } else { bitStream.WritePositiveIntMax511(AttackAngle); bitStream.WritePositiveIntMax511(MoveAngle); } bitStream.WritePositiveInt(State, 3); // State bitStream.WriteBoolean(false); // Coctail used bitStream.WriteInt(m_attackingTicks, 6); // Animation Playing bitStream.WriteBoolean(KnockBacked); // ������ � �� rotate bitStream.WriteBoolean(m_stunTicks >= 1); // Stun bitStream.WriteBoolean(Shaking > 0); // unk bitStream.WriteBoolean(StarPowerIC); // star power indicator } else { bitStream.WritePositiveIntMax7(State); // State if (CharacterData.IsTrain() || CharacterData.ManualRotations) { bitStream.WritePositiveIntMax511(AttackAngle); bitStream.WritePositiveIntMax511(MoveAngle); } else if (CharacterData.AreaEffect != null) bitStream.WritePositiveIntMax511(MoveAngle); } bitStream.WritePositiveVIntMax65535OftenZero(HitEffectProjectile); // 0xa1b0d8 bitStream.WritePositiveVIntMax65535OftenZero(HitEffectSkin); // 0xa1b0e4 bitStream.WriteBoolean(Slippery); bitStream.WriteBoolean(HasBuff(4)); // Speed up (Arrows up) bitStream.WriteBoolean(HasBuff(3)); // Slow down bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); int freezeLevel = LogicMath.Clamp((int)FrozenPercentage, 0, 100); bitStream.WritePositiveVIntMax255OftenZero(freezeLevel); bitStream.WritePositiveVIntMax255OftenZero(Poisons.Count); if (Poisons.Count >= 1) { foreach (Poison poison in Poisons) { bitStream.WritePositiveInt(poison.Type, 3); } if (Poisons.Count > 0) { bitStream.WriteBoolean(false); } } bitStream.WritePositiveVIntMax255OftenZero(GetBuffedHealthRegen()); if (CharacterData.HasVeryMuchHitPoints() || GameObjectManager.GetBattle().GetGameModeVariation() == 6 || GameObjectManager.GetBattle().GetGameModeVariation() == 9) { bitStream.WritePositiveVIntMax65535(m_hitpoints); bitStream.WritePositiveVIntMax65535(m_maxHitpoints); } else { List BrawlersHP = new() { "Rosa" }; if (BrawlersHP.Contains(CharacterData.Name)) { bitStream.WritePositiveVIntMax65535(m_hitpoints); bitStream.WritePositiveVIntMax65535(m_maxHitpoints); } else { bitStream.WritePositiveInt(m_hitpoints, 13); bitStream.WritePositiveInt(m_maxHitpoints, 13); } } if (CharacterData.IsHero()) { bitStream.WritePositiveVIntMax255OftenZero(m_itemCount + BattleRoyaleBuffs); } if (CharacterData.IsHero()) { if (GameModeUtil.ModeHasCarryables(GameObjectManager.GetBattle().GetGameModeVariation())) { bitStream.WriteBoolean(false); } bitStream.WritePositiveVIntMax255OftenZero(BattleRoyaleBuffs); bitStream.WriteBoolean(false); // big brawler bitStream.WriteBoolean(true); { bitStream.WriteBoolean(IsChargeActive()); bitStream.WriteBoolean(IsInvincible); // immunity bitStream.WriteBoolean(false); // ����� ������ ������ � ��� �� rotate bitStream.WriteBoolean(false); // bull rage bitStream.WriteBoolean(Ultiing); // using ulti } bitStream.WriteBoolean(false); if (isOwnObject) { if (bitStream.WriteBoolean(VisionOverrideTicks >= 1)) { bitStream.WriteIntMax65535(VisionOverrideX); bitStream.WriteIntMax65535(VisionOverrideY); } } if (GetWeaponSkill() != null) { if (GetWeaponSkill().SkillData.ChargedShotCount >= 1) { bitStream.WriteIntMax3(ChargedShotCount); } } if (CharacterData.ShouldEncodePetStatus || CharacterData.UniqueProperty == 13 && CharacterData.IsHero()) bitStream.WriteBoolean(false); if (CharacterData.HasPowerLevels || CharacterData.UniqueProperty == 1) { bitStream.WritePositiveIntMax3(GetPowerLevel()); } bitStream.WriteBoolean(false); if (IsChargeActive()) { bitStream.WritePositiveInt(ChargeAnimation, 8); bitStream.WritePositiveInt(m_activeChargeType, 4); } switch (ChargeUpType) { case 0: break; case 1: case 7: case 11: case 12: bitStream.WritePositiveVIntMax255OftenZero(ChargeUp / 50); break; case 5: break; case 8: bitStream.WritePositiveIntMax1023(LogicMath.Clamp(ChargeUp, 0, 1023)); break; case 9: bitStream.WritePositiveIntMax7(ChargedShotCount); break; default: bitStream.WritePositiveIntMax1023(LogicMath.Clamp(ChargeUp / 50, 0, 1023)); break; } } else if (CharacterData.SecondaryPet) bitStream.WritePositiveIntMax31(0); else { if ((GetWeaponSkill() != null && GetWeaponSkill().SkillData.BehaviorType == "Charge") || (GetUltimateSkill() != null && GetUltimateSkill().SkillData.BehaviorType == "Charge")) { if (bitStream.WriteBoolean(IsCharging)) bitStream.WritePositiveIntMax15(m_activeChargeType); } } bitStream.WriteBoolean(ShieldTicks > 0); bitStream.WritePositiveIntMax3(VisibilityState); bitStream.WriteBoolean(IsInvisible); // not fully visible bitStream.WritePositiveIntMax511(0); if (isOwnObject) { if (GetUltimateSkill()?.SeemToBeActive ?? false) { bitStream.WriteBoolean(true); bitStream.WriteIntMax1023(1 - CharacterData.Speed); } else if (bitStream.WriteBoolean(GetBuffedSpeed() != 0)) bitStream.WriteIntMax1023(GetBuffedSpeed()); bitStream.WriteBoolean(YellowEye);//Getting seen } BattlePlayer encodePlayer = GetPlayer(); if (DamageNumbers.Count <= 0 || encodePlayer == null) { bitStream.WritePositiveIntMax31(0); } else { int v71 = 0; foreach (DamageNumber damageNumber in DamageNumbers) { if (damageNumber == null) continue; if (damageNumber.Delay == 0 && (damageNumber.Dealer == encodePlayer.PlayerIndex || GetIndex() == encodePlayer.PlayerIndex)) v71++; } bitStream.WritePositiveIntMax31(v71); foreach (DamageNumber damageNumber in DamageNumbers) { if (damageNumber == null) continue; if (damageNumber.Delay == 0 && (damageNumber.Dealer == encodePlayer.PlayerIndex || GetIndex() == encodePlayer.PlayerIndex)) { bitStream.WriteInt(LogicMath.Clamp(damageNumber.Value, -32767, 32767), 15); } } } for (int i = 0; i < m_skills.Count; i++) { m_skills[i].Encode(bitStream); } }*/ public override void Encode(BitStream bitStream, bool isOwnObject, int visionTeam) { base.Encode(bitStream, isOwnObject, visionTeam); // base.Encode(bitStream, isOwnObject, visionIndex, visionTeam); var v0 = isOwnObject && CharacterData!.IsHero(); var v1 = IsPlayerControlRemoved(); var v2 = LogicMath.Clamp(-1, 0, 255); var v3 = CharacterData!.IsBoss(); var v4 = (CharacterData!.HasVeryMuchHitPoints() && CharacterData.IsHero()) || m_maxHitpoints > 65535; var v5 = CharacterData.IsBoss(); // isBigGameBoss; var v6 = false; // getChargedShotCount >= 1; var v7 = HasBuff(3); // var v8 = LogicMath.Clamp((int)_localSpeedFactor * 100, 1, 1023); var v9 = LogicMath.Clamp(m_attackingTicks, 0, 63); var v10 = false; if (CharacterData.IsHero()) v6 = GetWeaponSkill().SkillData.ChargedShotCount >= 1; if (CharacterData.HasAutoAttack() || CharacterData.Speed != 0 || CharacterData.IsTrainingDummy()) { if (isOwnObject) { bitStream.WriteBoolean(IsPlayerControlRemoved()); // 0xa1aff8 if (bitStream.WriteBoolean(ForcedAngleTicks + 1 >= TicksGone || IsSteerMovementActive()) || IsPlayerControlRemoved()) { bitStream.WritePositiveIntMax511(AttackAngle); bitStream.WritePositiveIntMax511(MoveAngle); } } else { bitStream.WritePositiveIntMax511(AttackAngle); bitStream.WritePositiveIntMax511(MoveAngle); } bitStream.WritePositiveInt(State, 3); // State bitStream.WriteBoolean(false); // Coctail used bitStream.WriteInt(m_attackingTicks, 6); // Animation Playing bitStream.WriteBoolean(KnockBacked); // ������ � �� rotate if (bitStream.WriteBoolean(m_stunTicks >= 1)) bitStream.WriteBoolean(false); // if (stunned); bitStream.WriteBoolean(Shaking > 0); // unk bitStream.WriteBoolean(StarPowerIC); // star power indicator } else { bitStream.WritePositiveIntMax7(State); // State if (CharacterData.IsTrain() || CharacterData.ManualRotations) { bitStream.WritePositiveIntMax511(AttackAngle); bitStream.WritePositiveIntMax511(MoveAngle); } else if (CharacterData.AreaEffect != null) bitStream.WritePositiveIntMax511(MoveAngle); } /* if (CharacterData.HasAutoAttack() || CharacterData.Speed != 0) { switch (isOwnObject) { case true: { bitStream.WriteBoolean(IsPlayerControlRemoved()); // isPlayerControlRemoved; bitStream.WriteBoolean(false); // only false; if (v1) { bitStream.WritePositiveIntMax511(MoveAngle); // moveAngle; bitStream.WritePositiveIntMax511(AttackAngle); // attackAngle; } break; } case false: { bitStream.WritePositiveIntMax511(MoveAngle); // moveAngle; bitStream.WritePositiveIntMax511(AttackAngle); // attackAngle; break; } } bitStream.WritePositiveIntMax7(State); // character state; { if (m_hitpoints > 0) { bitStream.WriteBoolean(false); // mini buff; bitStream.WriteIntMax63(v9); // attacking ticks; bitStream.WriteBoolean(false); // angle mirroring; if (bitStream.WriteBoolean(m_stunTicks >= 1)) bitStream.WriteBoolean(false); // if (stunned); bitStream.WriteBoolean(false); //accessory // bitStream.WriteBoolean(LogicAccessory != null); // accessory visualization (gadget) [in v36 not work]; bitStream.WriteBoolean(StarPowerIC); // accessory visualization (star power); } } } else { bitStream.WritePositiveIntMax7(State); // character state; if (CharacterData.IsTrain()) { bitStream.WritePositiveIntMax511(MoveAngle); // moveAngle; bitStream.WritePositiveIntMax511(AttackAngle); // attackAngle; } else if (CharacterData.AreaEffect != "") { bitStream.WritePositiveIntMax511(MoveAngle); // moveAngle; } }*/ bitStream.WritePositiveVIntMax65535OftenZero(HitEffectProjectile); // 0xa1b0d8 bitStream.WritePositiveVIntMax65535OftenZero(HitEffectSkin); // 0xa1b0e4 bitStream.WriteBoolean(Slippery); // mega speed buff without movement animation; bitStream.WriteBoolean(HasBuff(4)); // micro speed buff with movement animation; bitStream.WriteBoolean(HasBuff(3)); // slow mode; bitStream.WriteBoolean(false); // red animation before slow mode; bitStream.WriteBoolean(false); // only false; if (bitStream.WriteBoolean(HasBuff(14))) bitStream.WritePositiveIntMax3(GetBuff(14).EffectType); bitStream.WriteBoolean(HasBuff(15)); // belle ultimate effect; bitStream.WriteBoolean(false); // only false (otis prototype); // bitStream.WriteIntMax127(0); // ZN9BitStream13readIntMax127Ev int freezeLevel = LogicMath.Clamp((int)FrozenPercentage, 0, 100); bitStream.WritePositiveVIntMax255OftenZero(freezeLevel); bitStream.WritePositiveVIntMax255OftenZero(Poisons.Count); if (Poisons.Count >= 1) { foreach (Poison poison in Poisons) { bitStream.WritePositiveInt(poison.Type, 3); } if (Poisons.Count > 0) { bitStream.WriteBoolean(false); } } bitStream.WritePositiveVIntMax255OftenZero(v2); // heal animation tick; { if (v5) { bitStream.WritePositiveIntMax2097151(m_hitpoints); // now hp; bitStream.WritePositiveIntMax2097151(m_maxHitpoints); // max hp; } else { if (v4 && !CharacterData.IsHero()) { bitStream.WritePositiveIntMax524287(m_hitpoints); // now hp; bitStream.WritePositiveIntMax524287(m_maxHitpoints); // max hp; } else { if (v5) { bitStream.WritePositiveIntMax262143(m_hitpoints); // now hp; bitStream.WritePositiveIntMax262143(m_maxHitpoints); // max hp; } else { bitStream.WritePositiveVIntMax65535(m_hitpoints); // now hp; bitStream.WritePositiveVIntMax65535(m_maxHitpoints); // max hp; } } } } if (CharacterData.IsDecoy()) bitStream.WriteBoolean(false); // clone have ultimate; if (CharacterData.IsHero() || CharacterData.IsDecoy()) { bitStream.WritePositiveVIntMax255OftenZero(m_itemCount + BattleRoyaleBuffs); if (bitStream.WriteBoolean(ConsumableShield > 0)) // custom shield; { bitStream.WritePositiveIntMax2047(ConsumableShield); // percentage now; bitStream.WritePositiveIntMax2047(ConsumableShieldMax); // percentage start; } bitStream.WriteBoolean(HasBuff(13)); // purple rage; ruffs buff } /* public enum BuffTypes { Damage = 1, DamageAndSize = 2, SpeedSlower = 3, SpeedFaster = 4, Damage2 = 5, HealthRegen = 10, BelleWeapon = 14, BelleUlti = 15, RuffsBuff = 13, }*/ if (CharacterData.IsHero()) { if(GetBattle().Carryable != null && GetBattle().Carryable.CarringCharacter == this) { bitStream.WriteBoolean(true); bitStream.WritePositiveVIntMax65535OftenZero(0); bitStream.WritePositiveVIntMax65535OftenZero(0); bitStream.WritePositiveVIntMax65535(GlobalId.GetInstanceId(GetBattle().Carryable.GetGlobalID())); // carryable person instance } else if (GameModeUtil.ModeHasCarryables(GameObjectManager.GetBattle().GetGameModeVariation())) bitStream.WriteBoolean(false); bitStream.WritePositiveVIntMax255OftenZero(0); // only 0; bitStream.WriteBoolean(BigState); // big hero; bitStream.WriteBoolean(false); // poison and down effect; if (bitStream.WriteBoolean(true)) // only true; { bitStream.WriteBoolean(IsChargeActive()); bitStream.WriteBoolean(IsInvincible); // immunity bitStream.WriteBoolean(false); // ����� ������ ������ � ��� �� rotate bitStream.WriteBoolean(false); // bull rage bitStream.WriteBoolean(Ultiing); // using ulti bitStream.WriteBoolean(m_usingUltiCurrently); // ultimate visualization; } // bitStream.WriteBoolean(false); // unknown; if (isOwnObject) { if (bitStream.WriteBoolean(VisionOverrideTicks >= 1)) { bitStream.WriteIntMax65535(VisionOverrideX); bitStream.WriteIntMax65535(VisionOverrideY); } } if (GetWeaponSkill() != null) { if (GetWeaponSkill().SkillData.ChargedShotCount >= 1) { bitStream.WriteIntMax3(ChargedShotCount); } } if (CharacterData.ShouldEncodePetStatus || CharacterData.UniqueProperty == 13 && CharacterData.IsHero()) bitStream.WriteBoolean(false); if (CharacterData.HasPowerLevels || CharacterData.UniqueProperty == 1) { bitStream.WritePositiveIntMax3(GetPowerLevel()); } bitStream.WriteBoolean(false); if (IsChargeActive()) { bitStream.WritePositiveInt(ChargeAnimation, 8); bitStream.WritePositiveInt(m_activeChargeType, 4); } switch (ChargeUpType) { case 0: break; case 1: case 7: case 11: case 12: bitStream.WritePositiveVIntMax255OftenZero(ChargeUp / 50); break; case 5: break; case 8: bitStream.WritePositiveIntMax1023(LogicMath.Clamp(ChargeUp, 0, 1023)); break; case 9: bitStream.WritePositiveIntMax7(ChargedShotCount); break; default: bitStream.WritePositiveIntMax1023(LogicMath.Clamp(ChargeUp / 50, 0, 1023)); break; } } if (CharacterData.SecondaryPet) bitStream.WritePositiveIntMax7(0); if (!CharacterData.IsCarryable()) { switch (CharacterData.GetName()) { case "RopeDude": bitStream.WriteBoolean(false); // zone fixer; поводок базза при ульте // bitStream.WritePositiveIntMax1023(0); //поводок базза при ульте break; case "PowerLeveler": //bitStream.WritePositiveIntMax3(GetPowerLevel()); // level fixer; break; case "Baseball": //bitStream.WritePositiveIntMax31(0); // home-run fixer; break; case "FireDude": //bitStream.WritePositiveIntMax31(0); // petrol fixer; //Я ЕБАЛ МАТЬ РАЗРАБУ ВЕЛАСРАВЛА break; } } else { if (CharacterData.IsCarryable()) { int trail = 0; if (GetZ() > 0) { if (TotalKickDistance > 2400) trail = 2; else trail = 1; } bitStream.WritePositiveIntMax7(trail); // fly trail type bitStream.WritePositiveIntMax3(0); //bitStream.WriteBoolean(false); } } if (CharacterData.Name == "SpawnerDudeTurret" || CharacterData.Name == "SpawnerDudeTurret003" || CharacterData.Name == "SpawnerDudeTurret002") { bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); } /* if (CharacterData.Name == "SpawnerPet") { if (bitStream.WriteBoolean(false)) { bitStream.WriteBoolean(true); bitStream.WriteBoolean(true); bitStream.WriteBoolean(true); bitStream.WriteBoolean(true); bitStream.WriteBoolean(true); } }*/ if (v3) bitStream.WriteBoolean(false); // unknown boss parameter; (size boss) bitStream.WriteBoolean(ShieldTicks > 0); bitStream.WritePositiveIntMax3(VisibilityState); bitStream.WriteBoolean(IsInvisible); // not fully visible bitStream.WritePositiveIntMax511(0); if (v0) { int buffedSpeed = GetBuffedSpeed(); if (GetUltimateSkill()?.SeemToBeActive ?? false) { bitStream.WriteBoolean(true); bitStream.WriteIntMax1023(1 - CharacterData.Speed); } else if (bitStream.WriteBoolean(GetBuffedSpeed() != 0)) bitStream.WriteIntMax1023(GetBuffedSpeed()); bitStream.WriteBoolean(YellowEye); //шоколадный глаз } BattlePlayer encodePlayer = GetViewerPlayer(); if (DamageNumbers.Count <= 0 || encodePlayer == null) { bitStream.WritePositiveIntMax31(0); } else { int v71 = 0; foreach (DamageNumber damageNumber in DamageNumbers) { if (damageNumber == null) continue; if (damageNumber.Delay == 0 && (damageNumber.Dealer == encodePlayer.PlayerIndex || GetIndex() == encodePlayer.PlayerIndex)) v71++; } bitStream.WritePositiveIntMax31(v71); foreach (DamageNumber damageNumber in DamageNumbers) { if (damageNumber == null) continue; if (damageNumber.Delay == 0 && (damageNumber.Dealer == encodePlayer.PlayerIndex || GetIndex() == encodePlayer.PlayerIndex)) { bitStream.WriteInt(LogicMath.Clamp(damageNumber.Value, -32767, 32767), 15); } } } foreach (var skill in m_skills) { skill.Encode(bitStream, isOwnObject, this); } //foreach (var logicSkillServer in _logicSkillServers) // logicSkillServer.Encode(bitStream, _interruptSkillsTick > 0); } public override int GetObjectType() { return 0; } } }