public void Update(GameTime time) { switch (state) { case State.WaitingGathering: { bool passed = true; for (int i = 0; i < subBalls.Count; i++) { if (!subBalls[i].IsDied && subBalls[i].State != RBallState.Gathered) { passed = false; break; } } if (passed) { ChangeState(State.WaitingThrow); } break; } case State.Flying: { UpdateFly(time); // keep the RBalls inside the same position as this GatheredBall for (int i = 0; i < subBalls.Count; i++) { subBalls[i].Position = ballOffsets[i] + position; } break; } } catchSound.Position = position; catchSound.Update(time); throwSound.Position = position; throwSound.Update(time); }
public override void Update(GameTime gameTime) { float dt = (float)gameTime.ElapsedGameTimeSeconds; if (weaponCoolDown > 0) { weaponCoolDown -= dt; } // accelerating and decelerating if (speedModifier < speedModifierTarget) { speedModifier += dt; } else if (speedModifier > speedModifierTarget) { speedModifier -= dt; } switch (state) { case RBallState.Standby: { IntegrateRoundAngle(dt); Vector3 pos; CalculateRoundTransform(currentRadius, false, out pos, out orientation); Position = pos; // stand by balls can contribute their docking city if (dockCity.Owner != null) { if (dockCity.Owner == Owner) { dockCity.Heal(dt * props.Heal, props.HealthIncr * dt); dockCity.Develop(props.Contribution, dt); } else { dockCity.Develop(-props.Contribution * 5, dt); } } break; } case RBallState.Gathering: { NewMoveUpdate(dt); if (!isMoving) { ChangeState(RBallState.Gathered); } break; } case RBallState.Free: { NewMoveUpdate(dt); if (!isMoving) { ChangeState(RBallState.Standby); } break; } case RBallState.BeginingAttackCity: { NewMoveUpdate(dt); if (!isMoving) { ChangeState(RBallState.AttackCity); } break; } case RBallState.AttackCity: { // attack when city not owned if (dockCity.Owner != Owner) { IntegrateRoundAngle(dt); Vector3 pos; CalculateRoundTransform(CityAttackRadius, true, out pos, out orientation); Position = pos; //tail.Update(gameTime, position, orientation.Forward); if (speedModifier >= AttackCitySpeedMod - 0.5f) { if (weaponCoolDown <= 0) { float dmg = props.Damage; dockCity.Damage(dmg, Owner); Damage(dmg * 0.075f); weaponCoolDown = WeaponCoolDownTime; } } } else { // when owned, check if the speed has decreased low enough if (speedModifier < AttackCitySpeedMod * 0.3f || speedModifier < MinSpeedMod) { // if so, go back to normal standby position Reposition(); } else { // otherwise, keep moveing, decelerating IntegrateRoundAngle(dt); Vector3 pos; CalculateRoundTransform(CityAttackRadius, true, out pos, out orientation); Position = pos; speedModifierTarget = MinSpeedMod; } } break; } case RBallState.Defend: case RBallState.Attack: { if (target == null || target.Owner == Owner || target.IsDied) { Reposition(); } else { NewMove(target.position); NewMoveUpdate(dt); float dist = Vector3.DistanceSquared(ref position, ref target.position); if (dist < AttackRange * AttackRange) { if (weaponCoolDown <= 0) { float dmg = props.Damage; target.Damage(dmg); weaponCoolDown = WeaponCoolDownTime; } } } break; } case RBallState.Float: { NewMoveUpdate(dt); float dist = Vector3.DistanceSquared(position, floatingTarget.Position); if (dist < City.CityOutterRadius * City.CityOutterRadius) { Free(floatingTarget); } break; } } base.Update(gameTime); // try attack if any attackable, and when in a suitable state if (dockCity != null && (state != RBallState.Gathered && state != RBallState.Gathering && state != RBallState.Free && state != RBallState.Float)) { if (dockCity.Owner != Owner) { // In an enemy city enemyCheckTime -= dt; if (enemyCheckTime <= 0 && props.Damage > 10) { if (dockCity.NearbyOwnedBallCount == 0) { if (state != RBallState.AttackCity && state != RBallState.BeginingAttackCity) { AttackCity(); } } else { if (state != RBallState.Attack) { Attack(); } } enemyCheckTime = EnemyCheckTime; } } else { switch (Type) { case RBallType.Oil: case RBallType.Green: case RBallType.Education: case RBallType.Volience: if (props.Damage > 10) { // defend if any if (dockCity.NearbyEnemyBallCount > 0) { if (state != RBallState.Attack) { Defend(); } } } break; case RBallType.Health: case RBallType.Disease: // These type of balls // defend if able to attack and the city is in good condition if (dockCity.HPRate > 1 - float.Epsilon && props.Damage > 10) { if (dockCity.NearbyEnemyBallCount > 0) { if (state != RBallState.Attack) { Defend(); } } } break; } } } if (shouldPlayDeathSonds) { soundObject.Position = position; soundObject.Update(gameTime); soundObject.Fire(); shouldPlayDeathSonds = false; } }