private void BattleWithdrawAttacker(IBattleManager battle, ICombatGroup group) { ICity city; ITroopObject troopObject; IStronghold targetStronghold; if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject) || !gameObjectLocator.TryGetObjects(targetStrongholdId, out targetStronghold)) { throw new ArgumentException(); } if (group.Id != groupId) { return; } DeregisterBattleListeners(targetStronghold); troopObject.BeginUpdate(); troopObject.Stub.BeginUpdate(); troopObject.State = GameObjectStateFactory.NormalState(); troopObject.Stub.State = TroopState.Idle; troopObject.Stub.EndUpdate(); troopObject.EndUpdate(); StateChange(ActionState.Completed); }
/// <summary> /// Handles ending this action if our group has been killed /// </summary> private void BattleGroupKilled(IBattleManager battle, ICombatGroup combatGroup) { if (combatGroup.Id != groupId) { return; } ICity city; ITroopObject troopObject; if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject)) { throw new Exception(); } DeregisterBattleListeners(city); troopObject.BeginUpdate(); troopObject.State = GameObjectStateFactory.NormalState(); troopObject.EndUpdate(); troopObject.Stub.BeginUpdate(); troopObject.Stub.State = TroopState.Idle; troopObject.Stub.EndUpdate(); StateChange(ActionState.Completed); }
public override void ExitBattle() { base.ExitBattle(); Structure.BeginUpdate(); Structure.State = GameObjectStateFactory.NormalState(); Structure.EndUpdate(); // Remove structure from the world if our combat object died if (hp > 0) { return; } ICity city = Structure.City; var lockedRegions = regionManager.LockMultitileRegions(Structure.PrimaryPosition.X, Structure.PrimaryPosition.Y, Structure.Size); if (Structure.Lvl > 1) { Structure.City.Worker.DoPassive(Structure.City, actionFactory.CreateStructureDowngradePassiveAction(Structure.City.Id, Structure.ObjectId), false); } else { Structure.BeginUpdate(); regionManager.Remove(Structure); city.ScheduleRemove(Structure, true); Structure.EndUpdate(); } regionManager.UnlockRegions(lockedRegions); }
/// <summary> /// Takes care of finishing this action up if all our units are killed /// </summary> private void BattleGroupKilled(IBattleManager battle, ICombatGroup group) { // Ignore if not our group if (group.Id != groupId) { return; } IBarbarianTribe barbarianTribe; ICity city; ITroopObject troopObject; if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject) || !gameObjectLocator.TryGetObjects(targetObjectId, out barbarianTribe)) { throw new ArgumentException(); } DeregisterBattleListeners(barbarianTribe); troopObject.BeginUpdate(); troopObject.State = GameObjectStateFactory.NormalState(); troopObject.EndUpdate(); StateChange(ActionState.Completed); }
public void SenseOfUrgency_WhenCityHasMultipleSenseOfUrgencyTechnologies_ShouldStackUpTo100Percent( ICity city, IStructure structure, BattleProcedure battleProcedure) { structure.State = GameObjectStateFactory.NormalState(); structure.Stats.Hp.Returns(50m); structure.Stats.Base.Battle.MaxHp.Returns(200m); city.GetEnumerator().Returns(x => new List <IStructure> { structure }.GetEnumerator()); city.Technologies.GetEffects(EffectCode.SenseOfUrgency).Returns(new List <Effect> { new Effect { Id = EffectCode.SenseOfUrgency, Value = new object[] { 50 } }, new Effect { Id = EffectCode.SenseOfUrgency, Value = new object[] { 25 } }, new Effect { Id = EffectCode.SenseOfUrgency, Value = new object[] { 50 } } }); battleProcedure.SenseOfUrgency(city, 50); structure.Stats.Hp.Should().Be(100m); }
public override Error Execute() { ICity city; ITroopObject troopObject; if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject)) { return(Error.ObjectNotFound); } if (city.Battle == null) { StateChange(ActionState.Completed); return(Error.Ok); } RegisterBattleListeners(city); troopObject.BeginUpdate(); troopObject.State = GameObjectStateFactory.BattleState(city.Battle.BattleId); troopObject.EndUpdate(); troopObject.Stub.BeginUpdate(); troopObject.Stub.State = TroopState.Battle; troopObject.Stub.EndUpdate(); // Add units to battle groupId = battleProcedure.AddReinforcementToBattle(city.Battle, troopObject.Stub, formationType); cityBattleProcedure.AddLocalUnitsToBattle(city.Battle, city); return(Error.Ok); }
public override Error Execute() { IStronghold stronghold; if (!gameObjectLocator.TryGetObjects(strongholdId, out stronghold)) { return(Error.ObjectNotFound); } world.Add(stronghold.GateBattle); dbManager.Save(stronghold.GateBattle); //Add gate to battle var combatGroup = strongholdBattleProcedure.AddStrongholdGateToBattle(stronghold.GateBattle, stronghold); localGroupId = combatGroup.Id; stronghold.BeginUpdate(); stronghold.State = GameObjectStateFactory.BattleState(stronghold.GateBattle.BattleId); stronghold.EndUpdate(); beginTime = SystemClock.Now; endTime = SystemClock.Now.Add(formula.GetBattleDelayStartInterval()); return(Error.Ok); }
public override void Callback(object custom) { IBarbarianTribe barbarianTribe; if (!gameObjectLocator.TryGetObjects(barbarianTribeId, out barbarianTribe)) { throw new Exception("Barb tribe is missing"); } CallbackLock.CallbackLockHandler lockHandler = delegate { var toBeLocked = new List <ILockable>(); toBeLocked.AddRange(barbarianTribe.Battle.LockList); toBeLocked.Add(barbarianTribe); return(toBeLocked.ToArray()); }; locker.Lock(lockHandler, null, barbarianTribe).Do(() => { if (barbarianTribe.Battle.ExecuteTurn()) { // Battle continues, just save it and reschedule dbManager.Save(barbarianTribe.Battle); endTime = SystemClock.Now.AddSeconds(formula.GetBattleInterval(barbarianTribe.Battle.Defenders, barbarianTribe.Battle.Attackers)); StateChange(ActionState.Fired); return; } // Battle has ended // Delete the battle world.Remove(barbarianTribe.Battle); dbManager.Delete(barbarianTribe.Battle); barbarianTribe.BeginUpdate(); barbarianTribe.Battle = null; barbarianTribe.State = GameObjectStateFactory.NormalState(); var initialBarbResources = formula.BarbarianTribeResources(barbarianTribe); if (!initialBarbResources.Equals(barbarianTribe.Resource)) { // Lower camps remaining barbarianTribe.CampRemains--; // Reset resources barbarianTribe.Resource.Clear(); barbarianTribe.Resource.Add(formula.BarbarianTribeResources(barbarianTribe)); } barbarianTribe.EndUpdate(); StateChange(ActionState.Completed); }); }
public override Error Execute() { ICity city; ITroopObject troopObj; if (!world.TryGetObjects(cityId, troopObjectId, out city, out troopObj)) { return(Error.ObjectNotFound); } distanceRemaining = Math.Max(1, tileLocator.TileDistance(troopObj.PrimaryPosition, troopObj.Size, new Position(x, y), 1)); double moveTimeTotal = formula.MoveTimeTotal(troopObj.Stub, distanceRemaining, isAttacking); var actionConfigTime = ActionConfigTime(); if (actionConfigTime != null) { moveTime = actionConfigTime.Value; } else { moveTime = moveTimeTotal / distanceRemaining; } beginTime = DateTime.UtcNow; endTime = DateTime.UtcNow.AddSeconds(moveTimeTotal); nextTime = DateTime.UtcNow.AddSeconds(moveTime); troopObj.Stub.BeginUpdate(); troopObj.Stub.State = !isReturningHome ? TroopState.Moving : TroopState.ReturningHome; if (!CalculateNextPosition(troopObj)) { troopObj.Stub.State = TroopState.Idle; StateChange(ActionState.Completed); troopObj.Stub.EndUpdate(); return(Error.Ok); } troopObj.Stub.EndUpdate(); troopObj.BeginUpdate(); troopObj.TargetX = x; troopObj.TargetY = y; troopObj.State = GameObjectStateFactory.MovingState(); troopObj.EndUpdate(); return(Error.Ok); }
protected virtual void AddLocalStructuresToBattle(IBattleManager battleManager, ICity targetCity, ITroopObject attackerTroopObject) { var localGroup = GetOrCreateLocalGroup(targetCity.Battle, targetCity); foreach (IStructure structure in GetStructuresInRadius(targetCity, attackerTroopObject) .Where(structure => structure.State.Type == ObjectState.Normal && CanStructureBeAttacked(structure) == Error.Ok)) { structure.BeginUpdate(); structure.State = GameObjectStateFactory.BattleState(battleManager.BattleId); structure.EndUpdate(); localGroup.Add(combatUnitFactory.CreateStructureCombatUnit(battleManager, structure)); } }
public override Error Execute() { ICity city; ICity targetCity; ITroopObject troopObject; if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject) || !gameObjectLocator.TryGetObjects(targetCityId, out targetCity)) { return(Error.ObjectNotFound); } // Save original unit count to know when to bail out of battle originalUnitCount = troopObject.Stub.TotalCount; // Create the group in the battle uint battleId; ICombatGroup combatGroup; cityBattleProcedure.JoinOrCreateCityBattle(targetCity, troopObject, dbManager, out combatGroup, out battleId); groupId = combatGroup.Id; // Register the battle listeners RegisterBattleListeners(targetCity); // Create stamina monitor StaminaMonitor = staminaMonitorFactory.CreateStaminaMonitor(targetCity.Battle, combatGroup, battleFormula.GetStamina(troopObject.Stub, targetCity)); StaminaMonitor.PropertyChanged += (sender, args) => dbManager.Save(this); // Create attack mode monitor AttackModeMonitor = new AttackModeMonitor(targetCity.Battle, combatGroup, troopObject.Stub); // Set the attacking troop object to the correct state and stamina troopObject.BeginUpdate(); troopObject.State = GameObjectStateFactory.BattleState(battleId); troopObject.EndUpdate(); // Set the troop stub to the correct state troopObject.Stub.BeginUpdate(); troopObject.Stub.State = TroopState.Battle; troopObject.Stub.EndUpdate(); return(Error.Ok); }
public void SenseOfUrgency_WhenCityHasNoSenseOfUrgencyTechnologies_HealsHurtStructuresThatArentInBattle( ICity city, IStructure inBattleStructure, IStructure fullyHealedStructure, IStructure hurtStructure, BattleProcedure battleProcedure) { inBattleStructure.State = GameObjectStateFactory.BattleState(0); inBattleStructure.Stats.Hp.Returns(50m); inBattleStructure.Stats.Base.Battle.MaxHp.Returns(100m); fullyHealedStructure.State = GameObjectStateFactory.NormalState(); fullyHealedStructure.Stats.Hp.Returns(75m); fullyHealedStructure.Stats.Base.Battle.MaxHp.Returns(75m); hurtStructure.State = GameObjectStateFactory.NormalState(); hurtStructure.Stats.Hp.Returns(100m); hurtStructure.Stats.Base.Battle.MaxHp.Returns(200m); city.GetEnumerator().Returns(x => new List <IStructure> { inBattleStructure, fullyHealedStructure, hurtStructure }.GetEnumerator()); city.Technologies.GetEffects(EffectCode.SenseOfUrgency).Returns(new List <Effect> { new Effect { Id = EffectCode.SenseOfUrgency, Value = new object[] { 50 } } }); battleProcedure.SenseOfUrgency(city, 50); inBattleStructure.Stats.Hp.Should().Be(50m); hurtStructure.Stats.Hp.Should().Be(125m); fullyHealedStructure.Stats.Hp.Should().Be(75m); hurtStructure.Received(1).BeginUpdate(); hurtStructure.Received(1).EndUpdate(); fullyHealedStructure.Received(0).BeginUpdate(); fullyHealedStructure.Received(0).EndUpdate(); inBattleStructure.Received(0).BeginUpdate(); inBattleStructure.Received(0).EndUpdate(); }
public override void Callback(object custom) { IStronghold stronghold; if (!gameObjectLocator.TryGetObjects(strongholdId, out stronghold)) { throw new Exception("Stronghold is missing"); } CallbackLock.CallbackLockHandler lockHandler = delegate { return(stronghold.LockList().ToArray()); }; locker.Lock(lockHandler, null, stronghold).Do(() => { if (stronghold.GateBattle.ExecuteTurn()) { // Battle continues, just save it and reschedule dbManager.Save(stronghold.GateBattle); endTime = SystemClock.Now.AddSeconds(formula.GetGateBattleInterval(stronghold)); StateChange(ActionState.Fired); return; } // Battle has ended // Delete the battle stronghold.GateBattle.GroupKilled -= BattleOnGroupKilled; stronghold.GateBattle.ActionAttacked -= BattleOnActionAttacked; world.Remove(stronghold.GateBattle); dbManager.Delete(stronghold.GateBattle); stronghold.BeginUpdate(); stronghold.GateBattle = null; stronghold.State = GameObjectStateFactory.NormalState(); // Heal the gate if no one made through otherwise we let it be healed after the main battle if (stronghold.GateOpenTo == null) { stronghold.GateMax = (int)formula.StrongholdGateLimit(stronghold.Lvl); stronghold.Gate = Math.Max(Math.Min(stronghold.GateMax, stronghold.Gate), formula.StrongholdGateHealHp(stronghold.StrongholdState, stronghold.Lvl)); } stronghold.EndUpdate(); StateChange(ActionState.Completed); }); }
public override Error Execute() { ICity city; ITroopObject troopObject; IStronghold targetStronghold; if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject) || !gameObjectLocator.TryGetObjects(targetStrongholdId, out targetStronghold)) { return(Error.ObjectNotFound); } // Create the group in the battle uint battleId; ICombatGroup combatGroup; strongholdBattleProcedure.JoinOrCreateStrongholdGateBattle(targetStronghold, troopObject, out combatGroup, out battleId); groupId = combatGroup.Id; // Register the battle listeners RegisterBattleListeners(targetStronghold); // Create stamina monitor StaminaMonitor = staminaMonitorFactory.CreateStaminaMonitor(targetStronghold.GateBattle, combatGroup, battleFormula.GetStamina(troopObject.Stub, targetStronghold)); StaminaMonitor.PropertyChanged += (sender, args) => dbManager.Save(this); // Set the attacking troop object to the correct state and stamina troopObject.BeginUpdate(); troopObject.State = GameObjectStateFactory.BattleState(battleId); troopObject.EndUpdate(); // Set the troop stub to the correct state troopObject.Stub.BeginUpdate(); troopObject.Stub.State = TroopState.Battle; troopObject.Stub.EndUpdate(); return(Error.Ok); }
public override Error Execute() { IStronghold stronghold; if (!gameObjectLocator.TryGetObjects(strongholdId, out stronghold)) { return(Error.ObjectNotFound); } world.Add(stronghold.MainBattle); dbManager.Save(stronghold.MainBattle); if (stronghold.StrongholdState == StrongholdState.Occupied) { // Add stationed to battle foreach (var stub in stronghold.Troops.StationedHere()) { stub.BeginUpdate(); stub.State = TroopState.BattleStationed; stub.EndUpdate(); battleProcedure.AddReinforcementToBattle(stronghold.MainBattle, stub, FormationType.Defense); } } else { var strongholdGroup = strongholdBattleProcedure.AddStrongholdUnitsToBattle(stronghold.MainBattle, stronghold, strongholdManager.GenerateNeutralStub(stronghold)); npcGroupId = strongholdGroup.Id; } stronghold.BeginUpdate(); stronghold.State = GameObjectStateFactory.BattleState(stronghold.MainBattle.BattleId); stronghold.EndUpdate(); beginTime = SystemClock.Now; endTime = SystemClock.Now.Add(formula.GetBattleDelayStartInterval()); return(Error.Ok); }
public override Error Execute() { ICity city; ITroopObject troopObject; IStronghold targetStronghold; if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject) || !gameObjectLocator.TryGetObjects(targetStrongholdId, out targetStronghold)) { return(Error.ObjectNotFound); } // Create the group in the battle uint battleId; ICombatGroup combatGroup; strongholdBattleProcedure.JoinOrCreateStrongholdMainBattle(targetStronghold, troopObject, out combatGroup, out battleId); groupId = combatGroup.Id; // Create attack mode monitor originalUnitCount = troopObject.Stub.TotalCount; AttackModeMonitor = new AttackModeMonitor(targetStronghold.MainBattle, combatGroup, troopObject.Stub); // Register the battle listeners RegisterBattleListeners(targetStronghold); // Set the attacking troop object to the correct state and stamina troopObject.BeginUpdate(); troopObject.State = GameObjectStateFactory.BattleState(battleId); troopObject.EndUpdate(); // Set the troop stub to the correct state troopObject.Stub.BeginUpdate(); troopObject.Stub.State = TroopState.Battle; troopObject.Stub.EndUpdate(); return(Error.Ok); }
public override void Callback(object custom) { ICity city; ITroopObject troopObj; locker.Lock(cityId, troopObjectId, out city, out troopObj).Do(() => { if (!IsValid()) { return; } --distanceRemaining; troopObj.BeginUpdate(); troopObj.Move(new Position(nextX, nextY)); troopObj.EndUpdate(); // Fire updated to force sending new position troopObj.Stub.BeginUpdate(); troopObj.Stub.FireUpdated(); troopObj.Stub.EndUpdate(); if (!CalculateNextPosition(troopObj)) { troopObj.Stub.BeginUpdate(); troopObj.Stub.State = TroopState.Idle; troopObj.Stub.EndUpdate(); troopObj.BeginUpdate(); troopObj.State = GameObjectStateFactory.NormalState(); troopObj.EndUpdate(); StateChange(ActionState.Completed); return; } nextTime = DateTime.UtcNow.AddSeconds(moveTime); StateChange(ActionState.Fired); }); }
public virtual void JoinOrCreateStrongholdGateBattle(IStronghold targetStronghold, ITroopObject attackerTroopObject, out ICombatGroup combatGroup, out uint battleId) { // If battle already exists, then we just join it in also bringing any new units if (targetStronghold.GateBattle != null) { combatGroup = battleProcedure.AddAttackerToBattle(targetStronghold.GateBattle, attackerTroopObject); } // Otherwise, the battle has to be created else { var battleOwner = targetStronghold.Tribe == null ? new BattleOwner(BattleOwnerType.Stronghold, targetStronghold.ObjectId) : new BattleOwner(BattleOwnerType.Tribe, targetStronghold.Tribe.Id); targetStronghold.GateBattle = battleManagerFactory.CreateStrongholdGateBattleManager( new BattleLocation(BattleLocationType.StrongholdGate, targetStronghold.ObjectId), battleOwner, targetStronghold); combatGroup = battleProcedure.AddAttackerToBattle(targetStronghold.GateBattle, attackerTroopObject); var battlePassiveAction = actionFactory.CreateStrongholdGateBattlePassiveAction(targetStronghold.ObjectId); Error result = targetStronghold.Worker.DoPassive(targetStronghold, battlePassiveAction, false); if (result != Error.Ok) { throw new Exception(string.Format("Failed to start a battle due to error {0}", result)); } targetStronghold.BeginUpdate(); targetStronghold.State = GameObjectStateFactory.BattleState(targetStronghold.GateBattle.BattleId); targetStronghold.EndUpdate(); } battleId = targetStronghold.GateBattle.BattleId; }
private void BattleExitBattle(IBattleManager battle, ICombatList atk, ICombatList def) { ICity city; ITroopObject troopObject; if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject)) { throw new Exception(); } DeregisterBattleListeners(city); troopObject.BeginUpdate(); troopObject.State = GameObjectStateFactory.NormalState(); troopObject.EndUpdate(); troopObject.Stub.BeginUpdate(); troopObject.Stub.State = TroopState.Idle; troopObject.Stub.EndUpdate(); StateChange(ActionState.Completed); }
public virtual void JoinOrCreateBarbarianTribeBattle(IBarbarianTribe barbarianTribe, ITroopObject attackerTroopObject, out ICombatGroup combatGroup, out uint battleId) { // If battle already exists, then we just join it in also bringing any new units if (barbarianTribe.Battle != null) { combatGroup = battleProcedure.AddAttackerToBattle(barbarianTribe.Battle, attackerTroopObject); } // Otherwise, the battle has to be created else { var battleOwner = new BattleOwner(BattleOwnerType.BarbarianTribe, barbarianTribe.ObjectId); barbarianTribe.Battle = battleManagerFactory.CreateBarbarianBattleManager(new BattleLocation(BattleLocationType.BarbarianTribe, barbarianTribe.ObjectId), battleOwner, barbarianTribe); combatGroup = battleProcedure.AddAttackerToBattle(barbarianTribe.Battle, attackerTroopObject); var battlePassiveAction = actionFactory.CreateBarbarianTribeBattlePassiveAction(barbarianTribe.ObjectId); Error result = barbarianTribe.Worker.DoPassive(barbarianTribe, battlePassiveAction, false); if (result != Error.Ok) { throw new Exception(string.Format("Failed to start a battle due to error {0}", result)); } barbarianTribe.BeginUpdate(); barbarianTribe.LastAttacked = DateTime.UtcNow; barbarianTribe.State = GameObjectStateFactory.BattleState(barbarianTribe.Battle.BattleId); barbarianTribe.EndUpdate(); } battleId = barbarianTribe.Battle.BattleId; }
public override void Callback(object custom) { IStronghold stronghold; if (!gameObjectLocator.TryGetObjects(strongholdId, out stronghold)) { throw new Exception("Stronghold is missing"); } CallbackLock.CallbackLockHandler lockHandler = delegate { return(stronghold.LockList().ToArray()); }; locker.Lock(lockHandler, null, stronghold).Do(() => { if (stronghold.MainBattle.ExecuteTurn()) { // Battle continues, just save it and reschedule dbManager.Save(stronghold.MainBattle); endTime = SystemClock.Now.AddSeconds(formula.GetBattleInterval(stronghold.MainBattle.Defenders, stronghold.MainBattle.Attackers)); StateChange(ActionState.Fired); return; } // Battle has ended // Delete the battle stronghold.MainBattle.UnitCountDecreased -= MainBattleOnUnitKilled; stronghold.MainBattle.GroupKilled -= MainBattleOnGroupKilled; stronghold.MainBattle.ActionAttacked -= MainBattleOnActionAttacked; stronghold.MainBattle.ExitTurn -= MainBattleOnExitTurn; stronghold.MainBattle.EnterBattle -= MainBattleOnEnterBattle; // Set troop states to stationed and // send back anyone stationed here that doesn't belong // Make copy because it may change var stationedHere = stronghold.Troops.StationedHere().ToList(); foreach (var stub in stationedHere) { stub.BeginUpdate(); stub.State = TroopState.Stationed; stub.EndUpdate(); if (stub.City.Owner.IsInTribe && stub.City.Owner.Tribesman.Tribe == stronghold.Tribe) { continue; } var troopInitializer = troopInitializerFactory.CreateStationedTroopObjectInitializer(stub); var retreatChainAction = actionFactory.CreateRetreatChainAction(stub.City.Id, troopInitializer); var result = stub.City.Worker.DoPassive(stub.City, retreatChainAction, true); if (result != Error.Ok) { throw new Exception("Unexpected failure when retreating a unit from stronghold"); } } world.Remove(stronghold.MainBattle); dbManager.Delete(stronghold.MainBattle); stronghold.BeginUpdate(); stronghold.GateOpenTo = null; stronghold.MainBattle = null; stronghold.GateMax = (int)formula.StrongholdGateLimit(stronghold.Lvl); stronghold.Gate = Math.Max(Math.Min(stronghold.GateMax, stronghold.Gate), formula.StrongholdGateHealHp(stronghold.StrongholdState, stronghold.Lvl)); stronghold.State = GameObjectStateFactory.NormalState(); stronghold.EndUpdate(); StateChange(ActionState.Completed); }); }