public static bool FindPoint(LogicTileMap tileMap, LogicVector2 pos1, LogicVector2 pos2, LogicVector2 pos3, LogicVector2 pos4) { pos1.Set(pos2.m_x, pos2.m_y); pos1.Substract(pos3); int length = pos1.GetLength(); pos1.m_x = (pos1.m_x << 7) / length; pos1.m_y = (pos1.m_y << 7) / length; pos4.Set(pos3.m_x, pos3.m_y); int radius = LogicMath.Clamp(length / 128, 10, 25); for (int i = 0; i < radius; i++) { if (tileMap.IsPassablePathFinder(pos4.m_x >> 8, pos4.m_y >> 8)) { pos4.m_x = (int)((pos4.m_x & 0xFFFFFF00) | 128); pos4.m_y = (int)((pos4.m_y & 0xFFFFFF00) | 128); return(true); } pos4.Add(pos1); } return(false); }
public LogicArrayList <LogicVector2> CreatePatrolPath() { int parentWidth = this.m_parent.GetWidthInTiles() << 8; int parentHeight = this.m_parent.GetHeightInTiles() << 8; int patrolRadius = this.m_hero.GetPatrolRadius(); if (patrolRadius * patrolRadius >= parentWidth * parentWidth + parentHeight * parentHeight) { LogicVector2 tmp1 = new LogicVector2(); LogicVector2 tmp2 = new LogicVector2(); LogicVector2 tmp3 = new LogicVector2(); LogicVector2 tmp4 = new LogicVector2(); int parentMidX = this.m_parent.GetMidX(); int parentMidY = this.m_parent.GetMidY(); tmp2.Set(parentMidX, parentMidY); LogicArrayList <LogicVector2> wayPoints = new LogicArrayList <LogicVector2>(LogicHeroBaseComponent.PATROL_PATHS); for (int i = 0, j = 22; i < LogicHeroBaseComponent.PATROL_PATHS; i++, j += 45) { tmp1.Set(parentMidX + LogicMath.Cos(j, patrolRadius), parentMidY + LogicMath.Sin(j, patrolRadius)); LogicHeroBaseComponent.FindPoint(this.m_parent.GetLevel().GetTileMap(), tmp3, tmp2, tmp1, tmp4); wayPoints.Add(new LogicVector2(tmp4.m_x, tmp4.m_y)); } tmp1.Destruct(); tmp2.Destruct(); tmp3.Destruct(); tmp4.Destruct(); return(wayPoints); } else { int startX = this.m_parent.GetX() + (this.m_parent.GetWidthInTiles() << 9) - 128; int startY = this.m_parent.GetY() + (this.m_parent.GetWidthInTiles() << 9) - 128; int endX = this.m_parent.GetX() + 128; int endY = this.m_parent.GetY() + 128; LogicArrayList <LogicVector2> wayPoints = new LogicArrayList <LogicVector2>(4); wayPoints.Add(new LogicVector2(startX, startY)); wayPoints.Add(new LogicVector2(endX, startY)); wayPoints.Add(new LogicVector2(endX, endY)); wayPoints.Add(new LogicVector2(startX, endY)); return(wayPoints); } }
public void SpawnSummon(int x, int y) { LogicSpellData data = this.GetSpellData(); LogicCharacterData summonData = data.GetSummonTroop(); LogicVector2 position = new LogicVector2(); int summonCount = data.GetUnitsToSpawn(this.m_upgradeLevel); int spawnDuration = data.GetSpawnDuration(this.m_upgradeLevel); int totalSpawnDuration = -(spawnDuration * data.GetSpawnFirstGroupSize()); for (int i = 0, k = 0, angle = y + 7 * x; i < summonCount; i++, k += 7, angle += 150, totalSpawnDuration += spawnDuration) { if (!summonData.IsFlying()) { if (!this.m_level.GetTileMap().GetNearestPassablePosition(this.GetX(), this.GetY(), position, 1536)) { return; } } else { position.m_x = x + LogicMath.GetRotatedX(summonData.GetSecondarySpawnOffset(), 0, angle); position.m_y = y + LogicMath.GetRotatedY(summonData.GetSecondarySpawnOffset(), 0, angle); } LogicCharacter summon = (LogicCharacter)LogicGameObjectFactory.CreateGameObject(summonData, this.m_level, this.m_villageType); summon.GetHitpointComponent().SetTeam(0); summon.SetInitialPosition(position.m_x, position.m_y); LogicRandom random = new LogicRandom(k + this.m_globalId); int rnd = ((random.Rand(150) << 9) + 38400) / 100; position.Set(LogicMath.Cos(angle, rnd), LogicMath.Sin(angle, rnd)); int pushBackSpeed = summonData.GetPushbackSpeed() > 0 ? summonData.GetPushbackSpeed() : 1; int pushBackTime = 2 * rnd / (3 * pushBackSpeed); int spawnDelay = pushBackTime + totalSpawnDuration / summonCount; if (data.GetSpawnFirstGroupSize() > 0) { spawnDelay = LogicMath.Max(200, spawnDelay); } summon.SetSpawnTime(spawnDelay); summon.GetMovementComponent().GetMovementSystem().PushTrap(position, pushBackTime, 0, false, false); if (summon.GetCharacterData().IsJumper()) { summon.GetMovementComponent().EnableJump(3600000); summon.GetCombatComponent().RefreshTarget(true); } LogicCombatComponent combatComponent = summon.GetCombatComponent(); if (combatComponent != null) { combatComponent.SetSkeletonSpell(); } this.GetGameObjectManager().AddGameObject(summon, -1); } }
public void CheckSpawning(LogicCharacterData spawnCharacterData, int spawnCount, int spawnUpgradeLevel, int invulnerabilityTime) { LogicCharacterData data = this.GetCharacterData(); if (spawnCharacterData == null) { spawnCharacterData = data.GetSecondaryTroop(); if (spawnCharacterData == null) { spawnCharacterData = data.GetAttackerItemData(this.m_upgradeLevel).GetSummonTroop(); if (spawnCharacterData == null) { return; } } } if (spawnCharacterData.IsSecondaryTroop() || this.IsHero()) { int totalSpawnCount = spawnCount; int upgLevel = this.m_upgradeLevel; if (upgLevel >= spawnCharacterData.GetUpgradeLevelCount()) { upgLevel = spawnCharacterData.GetUpgradeLevelCount() - 1; } if (this.IsHero()) { if (this.m_summonSpawnCount >= spawnCount) { return; } upgLevel = spawnUpgradeLevel; totalSpawnCount = LogicMath.Max(0, LogicMath.Min(3, spawnCount - this.m_summonSpawnCount)); } else { if (data.GetSecondaryTroopCount(this.m_upgradeLevel) != 0) { totalSpawnCount = data.GetSecondaryTroopCount(this.m_upgradeLevel); } else if (spawnCount == 0) { totalSpawnCount = data.GetAttackerItemData(this.m_upgradeLevel).GetSummonTroopCount(); if (this.m_summonTroops.Size() + totalSpawnCount > data.GetAttackerItemData(this.m_upgradeLevel).GetSummonLimit()) { totalSpawnCount = data.GetAttackerItemData(this.m_upgradeLevel).GetSummonLimit() - this.m_summonTroops.Size(); } } } if (totalSpawnCount > 0) { LogicVector2 position = new LogicVector2(); LogicRandom random = new LogicRandom(this.m_globalId); int team = this.GetHitpointComponent().GetTeam(); bool randomizeSecSpawnDist = this.GetCharacterData().GetRandomizeSecSpawnDist(); for (int i = 0, j = 0, k = 0; i < totalSpawnCount; i++, j += 360, k += 100) { int seed = j / totalSpawnCount; if (this.IsHero()) { seed = 360 * (i + this.m_summonSpawnCount) / LogicMath.Max(1, LogicMath.Min(6, spawnCount)); } int rnd = 59 * this.m_globalId % 360 + seed; if (spawnCharacterData.IsFlying()) { LogicCharacterData parentData = this.GetCharacterData(); position.Set(this.GetX() + LogicMath.GetRotatedX(parentData.GetSecondarySpawnOffset(), 0, rnd), this.GetY() + LogicMath.GetRotatedY(parentData.GetSecondarySpawnOffset(), 0, rnd)); } else if (spawnCharacterData.GetSpeed() == 0) { position.Set(this.GetX(), this.GetY()); } else { if (!this.m_level.GetTileMap().GetNearestPassablePosition(this.GetX(), this.GetY(), position, 1536)) { continue; } } LogicCharacter spawnGameObject = (LogicCharacter)LogicGameObjectFactory.CreateGameObject(spawnCharacterData, this.m_level, this.m_villageType); if (this.GetCharacterData().GetAttackerItemData(this.m_upgradeLevel).GetSummonTroop() != null || this.IsHero()) { this.m_summonTroops.Add(spawnGameObject); } spawnGameObject.GetHitpointComponent().SetTeam(team); spawnGameObject.SetUpgradeLevel(upgLevel); spawnGameObject.SetInitialPosition(position.m_x, position.m_y); if (this.m_duplicate) { spawnGameObject.m_duplicateLifeTime = this.m_duplicateLifeTime; spawnGameObject.m_duplicate = true; } if (!this.IsHero()) { spawnGameObject.m_summoner = (LogicCharacterData)this.m_data; } if (invulnerabilityTime > 0) { spawnGameObject.GetHitpointComponent().SetInvulnerabilityTime(invulnerabilityTime); } int secondarySpawnDistance = this.IsHero() ? 768 : this.GetCharacterData().GetSecondarySpawnDistance(); if (secondarySpawnDistance > 0) { if (randomizeSecSpawnDist) { secondarySpawnDistance = (int)(random.Rand(secondarySpawnDistance) + ((uint)secondarySpawnDistance >> 1)); } position.Set(LogicMath.Cos(rnd, secondarySpawnDistance), LogicMath.Sin(rnd, secondarySpawnDistance)); int pushBackSpeed = spawnGameObject.GetCharacterData().GetPushbackSpeed(); if (pushBackSpeed <= 0) { pushBackSpeed = 1; } int pushBackTime = 2 * secondarySpawnDistance / (3 * pushBackSpeed); if (this.GetHitpointComponent().GetHitpoints() > 0) { if (this.GetAttackerItemData().GetSummonTroop() != null) { spawnGameObject.SetSpawnTime(pushBackTime); } else if (this.IsHero()) { spawnGameObject.SetSpawnTime(pushBackTime + k); } } spawnGameObject.GetMovementComponent().GetMovementSystem().PushTrap(position, pushBackTime, 0, false, false); } if (team == 1 || spawnGameObject.GetCharacterData().IsJumper()) { spawnGameObject.GetMovementComponent().EnableJump(3600000); spawnGameObject.GetCombatComponent().RefreshTarget(true); } if (team == 1) { if (LogicDataTables.GetGlobals().AllianceTroopsPatrol()) { spawnGameObject.GetCombatComponent().SetSearchRadius(LogicDataTables.GetGlobals().GetClanCastleRadius() >> 9); if (this.GetMovementComponent().GetBaseBuilding() != null) { spawnGameObject.GetMovementComponent().SetBaseBuilding(this.GetMovementComponent().GetBaseBuilding()); } } } this.GetGameObjectManager().AddGameObject(spawnGameObject, -1); if (this.IsHero()) { ++this.m_summonSpawnCount; } } position.Destruct(); } } else { Debugger.Warning("checkSpawning: trying to spawn normal troops!"); } }
public void UpdatePenetrating(int damageMultiplier) { LogicVector2 pos1 = new LogicVector2((this.m_targetPosition.m_x >> 3) - this.m_unk248.m_x, (this.m_targetPosition.m_y >> 3) - this.m_unk248.m_y); pos1.Normalize(512); LogicVector2 pos2 = new LogicVector2(-pos1.m_y, pos1.m_x); int distance = ((200 - this.m_areaShieldDelay) * (8 * this.GetSpeed() - 8 * this.m_areaShieldSpeed) / 200 + 8 * this.m_areaShieldSpeed) >> 3; LogicArrayList <LogicComponent> components = this.GetComponentManager().GetComponents(LogicComponentType.MOVEMENT); for (int i = 0, damage = damageMultiplier * this.m_damage / 100; i < components.Size(); i++) { LogicMovementComponent component = (LogicMovementComponent)components[i]; LogicGameObject parent = component.GetParent(); LogicHitpointComponent hitpointComponent = parent.GetHitpointComponent(); if (!parent.IsHidden() && hitpointComponent.GetTeam() != this.m_myTeam && hitpointComponent.GetHitpoints() > 0) { int distanceX = parent.GetMidX() - this.GetMidX(); int distanceY = parent.GetMidY() - this.GetMidY(); if (parent.GetGameObjectType() == LogicGameObjectType.CHARACTER) { distanceX += parent.GetWidthInTiles() << 8; distanceY += parent.GetHeightInTiles() << 8; } if ((!component.IsFlying() || this.m_flyingTarget) && LogicMath.Abs(distanceX) <= this.m_penetratingRadius && LogicMath.Abs(distanceY) <= this.m_penetratingRadius && distanceX * distanceX + distanceY * distanceY <= (uint)(this.m_penetratingRadius * this.m_penetratingRadius)) { LogicVector2 position = new LogicVector2(); if (parent.GetGameObjectType() == LogicGameObjectType.CHARACTER && hitpointComponent.GetMaxHitpoints() <= damage) { int rnd = (byte)this.Rand(parent.GetGlobalID()); if (rnd > 170u) { position.Set((pos1.m_x >> 2) + pos2.m_x, (pos1.m_y >> 2) + pos2.m_y); } else { if (rnd > 85) { position.Set(pos1.m_x, pos1.m_y); } else { position.Set((pos1.m_x >> 2) - pos2.m_x, (pos1.m_y >> 2) - pos2.m_y); } } if (hitpointComponent.GetInvulnerabilityTime() <= 0) { ((LogicCharacter)parent).Eject(position); } position.Destruct(); } else { position.Set(pos1.m_x, pos1.m_y); position.Normalize(distance); if (parent.GetMovementComponent().GetMovementSystem().ManualPushTrap(position, 150, this.m_globalId) || parent.IsHero()) { this.UpdateTargetDamage(parent, damage); } } } } } pos1.Destruct(); pos2.Destruct(); }
public void UpdateShockwavePush(int team, int targetType) { LogicVector2 position = new LogicVector2(this.GetMidX() - this.m_unk248.m_x, this.GetMidY() - this.m_unk248.m_y); int length = position.GetLength(); if (length >= this.m_minAttackRange) { int maxRangeDistance = length - this.m_maxAttackRange; int maxRadius = length; int minRadius = length - 512; if (minRadius < this.m_minAttackRange) { minRadius = this.m_minAttackRange; } uint minRadiusSquared = (uint)(minRadius * minRadius); uint maxRadiusSquared = (uint)(maxRadius * maxRadius); int boostSpeed = this.m_speedMod * maxRangeDistance / this.m_maxAttackRange; int boostTime = this.m_statusEffectTime * maxRangeDistance / (16 * this.m_maxAttackRange); int shockwaveArcLength = this.GetShockwaveArcLength(); LogicArrayList <LogicComponent> components = this.GetComponentManager().GetComponents(LogicComponentType.MOVEMENT); LogicVector2 pushBackPosition = new LogicVector2(); for (int i = 0; i < components.Size(); i++) { LogicMovementComponent movementComponent = (LogicMovementComponent)components[i]; LogicGameObject parent = movementComponent.GetParent(); LogicHitpointComponent hitpointComponent = parent.GetHitpointComponent(); if (!parent.IsHidden()) { if (hitpointComponent == null || hitpointComponent.GetTeam() != team) { if (hitpointComponent != null && hitpointComponent.GetParent().IsFlying()) { if (targetType == 1) { continue; } } else if (targetType == 0) { continue; } int distanceX = parent.GetMidX() - this.m_unk248.m_x; int distanceY = parent.GetMidY() - this.m_unk248.m_y; if (LogicMath.Abs(distanceX) <= maxRadius && LogicMath.Abs(distanceY) <= maxRadius) { int distance = distanceX * distanceX + distanceY * distanceY; if (distance <= maxRadiusSquared && distance >= minRadiusSquared) { if ((distanceX | distanceY) == 0) { distanceX = 1; } pushBackPosition.Set(distanceX, distanceY); int pushBackLength = pushBackPosition.Normalize(512); int angle = LogicMath.Abs(LogicMath.NormalizeAngle180(LogicMath.NormalizeAngle180(pushBackPosition.GetAngle()) - LogicMath.NormalizeAngle180(this.m_shockwaveAngle))); if (angle < shockwaveArcLength / 2) { int pushBack = 100 * (this.m_maxAttackRange + 256 - pushBackLength) / 512; if (pushBack > this.m_shockwavePushStrength) { pushBack = this.m_shockwavePushStrength; } movementComponent.GetMovementSystem().ManualPushBack(pushBackPosition, pushBack, 750, this.m_globalId); if (boostSpeed != 0) { movementComponent.GetMovementSystem().Boost(boostSpeed, boostTime); } } } } } } } } }
public void CreatePatrolArea(LogicGameObject patrolPost, LogicLevel level, bool unk, int idx) { LogicArrayList <LogicVector2> wayPoints = new LogicArrayList <LogicVector2>(8); if (this.m_patrolPost == null) { this.m_patrolPost = patrolPost; } int startX = 0; int startY = 0; int endX = 0; int endY = 0; int midX = 0; int midY = 0; int width = 0; int height = 0; int radius = 0; if (patrolPost != null) { startX = patrolPost.GetX() - 128; startY = patrolPost.GetY() - 128; endX = patrolPost.GetX() + (patrolPost.GetWidthInTiles() << 9) + 128; endY = patrolPost.GetY() + (patrolPost.GetHeightInTiles() << 9) + 128; midX = patrolPost.GetMidX(); midY = patrolPost.GetMidY(); width = patrolPost.GetWidthInTiles() << 8; height = patrolPost.GetHeightInTiles() << 8; radius = 1536; } if (radius * radius >= (uint)(width * width + height * height)) { LogicVector2 tmp1 = new LogicVector2(); LogicVector2 tmp2 = new LogicVector2(); LogicVector2 tmp3 = new LogicVector2(); LogicVector2 tmp4 = new LogicVector2(); tmp2.Set(midX, midY); int rnd = patrolPost.GetLevel().GetLogicTime().GetTick() + idx; midX = midX + 127 * rnd % 1024 - 512; midY = midY + 271 * rnd % 1024 - 512; for (int i = 0, j = 45; i < 4; i++, j += 90) { tmp1.Set(midX + LogicMath.Cos(j, radius), midY + LogicMath.Sin(j, radius)); LogicHeroBaseComponent.FindPoint(patrolPost.GetLevel().GetTileMap(), tmp3, tmp2, tmp1, tmp4); wayPoints.Add(new LogicVector2(tmp4.m_x, tmp4.m_y)); } tmp1.Destruct(); tmp2.Destruct(); tmp3.Destruct(); tmp4.Destruct(); } else { wayPoints.Add(new LogicVector2(endX, endY)); wayPoints.Add(new LogicVector2(startX, endY)); wayPoints.Add(new LogicVector2(startX, startY)); wayPoints.Add(new LogicVector2(endX, startY)); } this.ClearPatrolArea(); this.m_wayPoints = wayPoints; this.m_patrolAreaCounter = 0; if (this.m_wayPoints.Size() > 1) { int closestLength = 0x7FFFFFFF; for (int i = 1, size = this.m_wayPoints.Size(); i < size; i++) { LogicVector2 wayPoint = this.m_wayPoints[i]; int length = (wayPoint.m_x - (this.m_position.m_x >> 16)) * (wayPoint.m_x - (this.m_position.m_x >> 16)) + (wayPoint.m_y - (this.m_position.m_y >> 16)) * (wayPoint.m_y - (this.m_position.m_y >> 16)); if (length < closestLength) { this.m_patrolAreaCounter = i; closestLength = length; } } } this.MoveTo(this.m_wayPoints[this.m_patrolAreaCounter].m_x, this.m_wayPoints[this.m_patrolAreaCounter].m_y, level.GetTileMap(), true); }