public Target(GameEntity entity, GameContext gameContext) { Id = entity.id.value; Radius = entity.circleCollider.radius; SqrRadius = Radius * Radius; float globalAngle; if (entity.hasGlobalTransform) { GlobalPosition = entity.globalTransform.position; globalAngle = entity.globalTransform.angle; } else { entity.ToGlobal(gameContext, out GlobalPosition, out globalAngle, out _, out _, out _); } CoordinatesExtensions.GetSinCosFromDegrees(-globalAngle, out NegativeAngleSin, out NegativeAngleCos); //GrandOwnerId = entity.hasGrandOwner ? entity.grandOwner.id : Id; TeamId = entity.hasTeam ? entity.team.id : byte.MaxValue; IsPlayer = entity.hasPlayer; SqrChildrenTargetingRadiuses = entity.GetAllChildrenGameEntities(gameContext, c => c.hasTargetingParameters) .Select(c => c.targetingParameters.radius).Select(r => r * r).ToArray(); ChildrenGrandTargetIds = entity.GetAllChildrenGameEntities(gameContext, c => c.hasTarget) .Select(c => gameContext.GetEntityWithId(c.target.id)) .Select(t => t.hasGrandOwner ? t.grandOwner.id : t.GetGrandOwnerId(gameContext)).ToArray(); DirectionTargetingChildrenCount = entity.GetAllChildrenGameEntities(gameContext, c => c.hasDirectionTargeting).Count(); }
public void Initialize() { for (float angle = 0f; angle < 360f; angle += Step) { var position = CoordinatesExtensions.GetRotatedUnitVector2(angle) * Radius; var entity = spaceStation.CreateEntity(gameContext, position, angle, 0); } }
public void Initialize() { for (float angle = 0f; angle < 360f; angle += Step) { for (int i = 0; i < bonuses.Length; i++) { var currentAngle = angle + i * deltaStep; var position = CoordinatesExtensions.GetRotatedUnitVector2(currentAngle) * Radius; bonuses[i].CreateEntity(gameContext, position, 0f); } } }
public void Execute() { foreach (var e in movingGroup.GetEntities(buffer)) { var delta = e.targetMovingPoint.position - e.GetGlobalPositionVector2(gameContext); var deltaSqrMagnitude = delta.sqrMagnitude; if (deltaSqrMagnitude <= positionSqrDelta) { e.RemoveTargetMovingPoint(); continue; } var newVelocity = delta / Chronometer.DeltaTime; if (!e.isDirectionTargetingShooting) { var directionAngle = Mathf.Atan2(newVelocity.y, newVelocity.x) * Mathf.Rad2Deg; if (directionAngle < 0) { directionAngle += 360f; } if (e.hasDirectionTargeting) { e.ReplaceDirectionTargeting(directionAngle); } else { e.AddDirectionTargeting(directionAngle); } } if (e.hasChaser && !e.GetAllChildrenGameEntities(gameContext, c => c.hasCannon).Any()) { var directedVelocity = delta.magnitude * CoordinatesExtensions.GetRotatedUnitVector2(e.GetGlobalAngle(gameContext)); var angle = Vector2.Angle(newVelocity, directedVelocity); if (angle > angleDelta) { newVelocity = directedVelocity * (1f - angle / 180f); } } if (e.hasVelocity) { e.ReplaceVelocity(newVelocity); } else { e.AddVelocity(newVelocity); } } }
// Update is called once per frame void Update() { if (spawnOne && prototype != null) { var entity = prototype.CreateEntity(gameContext, position, direction); if (entity.isNotDecelerating && entity.hasMaxVelocity && !entity.isUnmovable) { entity.AddVelocity(CoordinatesExtensions.GetRotatedUnitVector2(direction)); } spawnOne = false; } systems.Execute(); systems.Cleanup(); }
protected override void Execute(List <GameEntity> entities) { foreach (var e in entities) { var angle = e.GetGlobalAngle(gameContext); if (Math.Abs(angle) > sameAngleDelta) { e.AddGlobalPathCollider(CoordinatesExtensions.GetRotatedVectors(e.pathCollider.dots, e.direction.angle)); e.AddGlobalNoncollinearAxises(CoordinatesExtensions.GetRotatedVectors(e.noncollinearAxises.vectors, e.direction.angle)); } else { e.AddGlobalPathCollider((Vector2[])e.pathCollider.dots.Clone()); e.AddGlobalNoncollinearAxises((Vector2[])e.noncollinearAxises.vectors.Clone()); } } }
public void Execute() { foreach (var e in collisionGroup) { CoordinatesExtensions.GetSinCosFromDegrees(e.GetGlobalAngle(gameContext), out var sin, out var cos); var dots = e.pathCollider.dots; var globalDots = e.globalPathCollider.dots; for (var i = 0; i < dots.Length; i++) { globalDots[i] = dots[i].GetRotated(sin, cos) + e.GetGlobalPositionVector2(gameContext); } var axises = e.noncollinearAxises.vectors; var globalAxises = e.globalNoncollinearAxises.vectors; for (var i = 0; i < axises.Length; i++) { globalAxises[i] = axises[i].GetRotated(sin, cos); } } }
public void Initialize() { // Log.Info($"Создание игровой комнаты с номером {matchModel.MatchId}"); Dictionary <int, ushort> playerInfos = new Dictionary <int, ushort>(matchModel.GameUnits.Count()); var zoneEntity = FlameCircle.CreateEntity(gameContext, Vector2.zero, 0f); gameContext.SetZone(zoneEntity.id.value); var step = 360f / matchModel.GameUnits.Count(); var halfStep = step * 0.5f; GameUnitsFactory factory = new GameUnitsFactory(); List <GameUnitModel> gameUnits = factory.Create(matchModel); for (int gameUnitIndex = 0; gameUnitIndex < gameUnits.Count; gameUnitIndex++) { GameUnitModel gameUnit = gameUnits[gameUnitIndex]; float angle = gameUnitIndex * step + halfStep; Vector2 position = CoordinatesExtensions.GetRotatedUnitVector2(angle) * 40f; GameEntity playerEntity = PlayerPrototypes[gameUnit.WarshipName.ToLower()] .CreateEntity(gameContext, position, 180f + angle, (byte)(gameUnitIndex + 1)); if (playerEntity.hasDrop) { playerEntity.drop.objects.Add(UpgradeBonus); } else { playerEntity.AddDrop(new List <EntityCreatorObject> { UpgradeBonus }); } playerEntity.AddPlayer(gameUnit.TemporaryId); playerEntity.AddAccount(gameUnit.AccountId); playerInfos.Add(playerEntity.account.id, playerEntity.id.value); if (gameUnit.IsBot()) { Match.MakeBot(playerEntity); } if (Skins.TryGetValue(gameUnit.SkinName, out var skin)) { skin.AddSkin(playerEntity, gameContext); } var powerLevel = gameUnit.WarshipPowerLevel - 1; if (powerLevel > 0) { var newHp = playerEntity.maxHealthPoints.value * (1f + powerLevel * WarshipImprovementConstants.HealthPointsCoefficient); var newSpeed = playerEntity.maxVelocity.value * (1f + powerLevel * WarshipImprovementConstants.LinearVelocityCoefficient); var newRotation = playerEntity.maxAngularVelocity.value * (1f + powerLevel * WarshipImprovementConstants.AngularVelocityCoefficient); var attackCoefficient = 1f + powerLevel * WarshipImprovementConstants.AttackCoefficient; playerEntity.ReplaceMaxHealthPoints(newHp); playerEntity.ReplaceHealthPoints(newHp); playerEntity.ReplaceMaxVelocity(newSpeed); playerEntity.ReplaceMaxAngularVelocity(newRotation); foreach (var child in playerEntity.GetAllChildrenGameEntities(gameContext)) { child.AddAttackIncreasing(attackCoefficient); } } var wallAngle = angle + halfStep; var wallDirection = CoordinatesExtensions.GetRotatedUnitVector2(wallAngle); for (var r = 11; r < 50; r += 25) { for (var j = r; j < r + 10; j++) { RandomAsteroid.CreateEntity(gameContext, wallDirection * j, (float)random.NextDouble() * 360f); } } SpaceStation.CreateEntity(gameContext, wallDirection * 10f, wallAngle, 0); SpaceStation.CreateEntity(gameContext, wallDirection * 25f, wallAngle, 0); SpaceStation.CreateEntity(gameContext, wallDirection * 35f, 180f + wallAngle, 0); RandomBonus.CreateEntity(gameContext, wallDirection * 30f, 0); } Boss.CreateEntity(gameContext, Vector2.zero, (float)random.NextDouble() * 360f, 0); foreach (var playerInfo in matchModel.GameUnits.Players) { udpSendUtils.SendPlayerInfo(matchModel.MatchId, playerInfo.TemporaryId, playerInfos); } }
public void Execute() { foreach (var targetEntity in targetGroup) { targets.Add(new Target(targetEntity, gameContext)); } foreach (var e in targetingGroup.GetEntities(buffer)) { var currentPosition = e.GetGlobalPositionVector2(gameContext); var currentDirection = CoordinatesExtensions.GetRotatedUnitVector2(e.GetGlobalAngle(gameContext)); var onlyPlayerTargeting = e.targetingParameters.onlyPlayerTargeting; var targetingRadius = e.targetingParameters.radius; var sqrTargetingRadius = targetingRadius * targetingRadius; var grandParent = e.GetGrandParent(gameContext); var currentGrandOwnerId = e.hasGrandOwner ? e.grandOwner.id : e.GetGrandOwnerId(gameContext); var currentTeamId = e.hasTeam ? e.team.id : byte.MaxValue; var minVal = float.PositiveInfinity; ushort targetId = 0; var targetFound = false; foreach (var target in targets) { if (onlyPlayerTargeting && target.TeamId == byte.MaxValue) { continue; } if (e.id.value == target.Id || currentTeamId == target.TeamId) { continue; } var targetPosition = target.GlobalPosition; var direction = targetPosition - currentPosition; var sqrDirection = direction.sqrMagnitude; if (sqrDirection <= sqrTargetingRadius) { targetFound = true; float currentVal; if (e.targetingParameters.angularTargeting) { currentVal = Vector2.Angle(currentDirection, direction); currentVal *= currentVal; } else { currentVal = sqrDirection - target.SqrRadius; } // Установка приоритетности цели: // стреляем по игрокам с большей вероятностью if (target.IsPlayer) { currentVal *= 0.15f; } // не стрелять по нейтрально-пассивным if (target.TeamId == byte.MaxValue) { currentVal *= 10000f; } // стрельба по объектам из другой команды else if (e.hasTeam && target.TeamId != e.team.id) { currentVal *= 0.01f; } // обращаем внимание на целящиеся объекты foreach (var sqrChildTargetingRadius in target.SqrChildrenTargetingRadiuses) { if (sqrDirection <= sqrChildTargetingRadius) { currentVal *= 0.125f; } } // нужно проверить, стреляют ли в нас foreach (var childGrandTargetId in target.ChildrenGrandTargetIds) { if (childGrandTargetId == currentGrandOwnerId) { currentVal *= 0.05f; } } // летят ли в нас выстрелы if (target.DirectionTargetingChildrenCount > 0) { var grandParentDirection = targetPosition - grandParent.GetGlobalPositionVector2(gameContext); var localTargetPosition = grandParentDirection.GetRotated(target.NegativeAngleSin, target.NegativeAngleCos); var absProjectionY = Mathf.Abs(localTargetPosition.y); var overlapLine = target.Radius; if (grandParent.hasCircleCollider) { overlapLine += grandParent.circleCollider.radius; } var antiOverlap = absProjectionY / overlapLine; if (antiOverlap < 1f) { currentVal *= antiOverlap / target.DirectionTargetingChildrenCount; } } if (currentVal < minVal) { minVal = currentVal; targetId = target.Id; } } } if (targetFound) { e.AddTarget(targetId); } } targets.Clear(); }
public void Execute() { foreach (var e in botsGroup.GetEntities(buffer)) { var currentPosition = e.GetGlobalPositionVector2(gameContext); var zonePosition = zone.GetGlobalPositionVector2(gameContext); var zoneRadius = zone.circleCollider.radius; float maxRadius = e.circleCollider.radius + (float)random.NextDouble() * e.maxVelocity.value; var sqrMaxRadius = maxRadius * maxRadius; Vector2 targetPosition = currentPosition + maxRadius * CoordinatesExtensions.GetRandomUnitVector2(); //if (e.hasTargetingParameters) //{ // maxRadius = e.targetingParameters.radius; // targetPosition = Random.Range(e.circleCollider.radius, maxRadius) * CoordinatesExtensions.GetRandomUnitVector2(); // targetPosition += currentPosition; //} //else //{ // maxRadius = zoneRadius; // targetPosition = Random.Range(e.circleCollider.radius, maxRadius) * CoordinatesExtensions.GetRandomUnitVector2(); // targetPosition += zonePosition; //} if (e.hasMaxHealthPoints) { var dangerAvoidanceVector = new Vector2(0f, 0f); // считаем здоровье, учитывая щиты и остальные объекты var fullHp = e.GetAllChildrenGameEntities(gameContext, c => c.hasHealthPoints).Sum(c => c.healthPoints.value); // может быть > 1, потому что считаем со щитами var healthPercentage = fullHp / e.maxHealthPoints.value; var combatPower = e.GetAllChildrenGameEntities(gameContext, c => c.hasCannon).Sum(GetEntityCombatPower); combatPower *= healthPercentage; var visionRadius = maxRadius + (e.hasTargetingParameters ? e.targetingParameters.radius : maxRadius); var sqrVisionRadius = visionRadius * visionRadius; dangerAvoidanceVector += GetAvoidanceVector(withCannonGroup, cE => GetEntityCombatPower(cE) / combatPower); dangerAvoidanceVector += GetAvoidanceVector(withDamageGroup, cE => GetEntityDamagePower(cE) / fullHp); if (e.isBonusPickable && healthPercentage < 1f) { //TODO: учитывать мощность бонуса var healthLackPercentage = 1f - healthPercentage; dangerAvoidanceVector -= GetAvoidanceVector(withBonusGroup, cE => healthLackPercentage); } if (dangerAvoidanceVector.sqrMagnitude > sqrMaxRadius) { targetPosition += Vector2.ClampMagnitude(dangerAvoidanceVector, maxRadius); } else { targetPosition += dangerAvoidanceVector; } /*static*/ float GetEntityCombatPower(GameEntity combatEntity) { var cannon = combatEntity.cannon; var bullet = cannon.bullet; var power = bullet.collisionDamage; if (!bullet.isCollapses) { power *= bullet.lifetime; } power /= cannon.cooldown; return(power); } /*static*/ float GetEntityDamagePower(GameEntity combatEntity) { var damage = combatEntity.damage.value; if (!combatEntity.isCollapses && combatEntity.TryGetFirstGameEntity(gameContext, p => p.hasLifetime, out var withLifetime)) { damage *= withLifetime.lifetime.value; } return(damage); } Vector2 GetAvoidanceVector(IGroup <GameEntity> dangerGroup, Func <GameEntity, float> calculatingFunc) { var avoidanceVector = new Vector2(0f, 0f); foreach (var danger in dangerGroup) { if (danger.GetGrandOwnerId(gameContext) == e.GetGrandOwnerId(gameContext)) { continue; } var reverseDirection = targetPosition - danger.GetGlobalPositionVector2(gameContext); var sqrReverseDirection = reverseDirection.sqrMagnitude; if (sqrReverseDirection > sqrVisionRadius) { continue; } var dangerPercentage = calculatingFunc(danger); dangerPercentage *= 1f - sqrReverseDirection / sqrVisionRadius; avoidanceVector += reverseDirection.normalized * dangerPercentage; } return(avoidanceVector); } } var safeRadius = zoneRadius - zoneWarningDistance; if ((targetPosition - zonePosition).sqrMagnitude >= safeRadius * safeRadius) { var vectorToCenter = zonePosition - currentPosition; var randomLength = zoneWarningDistance + (float)random.NextDouble() * (maxRadius - zoneWarningDistance); var savingVector = randomLength * vectorToCenter.normalized; targetPosition += savingVector; } e.AddTargetMovingPoint(targetPosition); } }
private void Draw() { if (changeContext && contextIndex >= 0 && contextIndex < contextsList.Count) { if (!ChangeContext(contextsList[contextIndex].game)) { return; } changeContext = false; } if (currentGameContext == null || collidableGroup == null) { return; } foreach (var e in collidableGroup) { var recursion = false; var firstParent = e; while (firstParent.hasParent) { firstParent = currentGameContext.GetEntityWithId(firstParent.parent.id); if (firstParent.id.value == e.id.value) { Log.Error(nameof(CollidersDrawer) + " detected recursion!"); recursion = true; break; } } if (recursion) { continue; } e.ToGlobal(currentGameContext, out var position, out var angle, out var layer, out var velocity, out var angularVelocity); var hasDirection = Math.Abs(angle) > 0.001; float sin = 0, cos = 1; if (hasDirection) { CoordinatesExtensions.GetSinCosFromDegrees(angle, out sin, out cos); } Gizmos.color = e.isCollidable ? Color.green : Color.gray; if (e.hasPathCollider) { var absoluteDots = new Vector2[e.pathCollider.dots.Length]; for (var i = 0; i < e.pathCollider.dots.Length; i++) { absoluteDots[i] = e.pathCollider.dots[i]; if (hasDirection) { absoluteDots[i].Rotate(sin, cos); } absoluteDots[i] += position; } var prevDot = absoluteDots[absoluteDots.Length - 1]; foreach (var absoluteDot in absoluteDots) { Gizmos.DrawLine(prevDot, absoluteDot); prevDot = absoluteDot; } if (drawAxises && e.hasNoncollinearAxises) { Gizmos.color = Color.yellow; foreach (var axis in e.noncollinearAxises.vectors) { var absoluteVector = position; if (hasDirection) { absoluteVector += axis.GetRotated(sin, cos); } else { absoluteVector += axis; } Gizmos.DrawLine(position, absoluteVector); } } } else if (e.hasCircleCollider) { Gizmos.DrawWireSphere(position, e.circleCollider.radius); } if (drawGuns && e.hasCannon) { Gizmos.color = Color.red; var absoluteVector = position; if (hasDirection) { absoluteVector += e.cannon.position.GetRotated(sin, cos); } else { absoluteVector += e.cannon.position; } Gizmos.DrawLine(position, absoluteVector); } if (drawTargetingRadius && e.hasTargetingParameters) { Gizmos.color = Color.magenta; Gizmos.DrawWireSphere(position, e.targetingParameters.radius); } if (drawTargetLines && e.hasTarget) { Gizmos.color = Color.cyan; var target = currentGameContext.GetEntityWithId(e.target.id); var targetPosition = target.GetGlobalPositionVector2(currentGameContext); Gizmos.DrawLine(position, targetPosition); } if (drawAuras && e.hasAura && e.hasCircleCollider) { Gizmos.color = Color.blue; Gizmos.DrawWireSphere(position, e.circleCollider.radius + e.aura.outerRadius); } if (drawTargetMovingPoints && e.hasTargetMovingPoint) { Gizmos.color = Color.black; var movingPosition = e.targetMovingPoint.position; Gizmos.DrawLine(position, movingPosition); } } }