public void processWars() { //Every society decides which other to attack, assuming it is over threshold combat strength foreach (SocialGroup sg in socialGroups) { if (sg.lastBattle == turn) { continue; } //Only one battle permitted per social group (that they initiate, at least) if (checkDefensiveAttackHold(sg)) { continue; } //Should you stop attacking, to conserve strength? if (sg.currentMilitary < sg.maxMilitary * param.combat_thresholdAttackStrength) { continue; } //Below min strength sg.lastBattle = turn; int c = 0; Location attackFrom = null; Location attackTo = null; foreach (Location l in locations) { if (l.soc == sg) { foreach (Link link in l.links) { if (link.other(l).soc != null && link.other(l).soc != sg && link.other(l).soc.getRel(sg).state == DipRel.dipState.war) { if (link.other(l).lastTaken == turn) { continue; } //Can't retake on this turn c += 1; if (Eleven.random.Next(c) == 0) { attackFrom = l; attackTo = link.other(l); } } } } } if (attackFrom != null) { SocialGroup defender = attackTo.soc; //sg.lastBattle = turn; //defender.lastBattle = turn; World.log(sg.getName() + " attacking into " + attackTo.getName()); double myStr = sg.currentMilitary * Eleven.random.NextDouble(); double theirStr = defender.currentMilitary * Eleven.random.NextDouble(); if (myStr < 1) { myStr = Math.Min(1, sg.currentMilitary); } if (theirStr < 1) { theirStr = Math.Min(1, defender.currentMilitary); } //Note the defensive fortifications only reduce losses, not increase chance of taking territory double myLosses = theirStr * param.combat_lethality; sg.currentMilitary -= myLosses; if (sg.currentMilitary < 0) { sg.currentMilitary = 0; } double theirLosses = myStr * param.combat_lethality; theirLosses = computeDefensiveBonuses(theirLosses, sg, defender); theirLosses = attackTo.takeMilitaryDamage(theirLosses); defender.currentMilitary -= theirLosses; if (defender.currentMilitary < 0) { defender.currentMilitary = 0; } addMessage(sg.getName() + " attacks " + defender.getName() + ". Inflicts " + (int)(theirLosses) + " dmg, takes " + (int)(myLosses), MsgEvent.LEVEL_YELLOW, false); if (attackTo.settlement != null) { attackTo.settlement.takeAssault(sg, defender, theirLosses); } //Can only take land if there are no defenses in place if (myStr > theirStr * param.combat_takeLandThreshold && (attackTo.getMilitaryDefence() <= 0.01)) { takeLocationFromOther(sg, defender, attackTo); attackTo.lastTaken = turn; } if (sg is Society && defender is Society) { Property.addProperty(this, attackTo, "Recent Human Battle"); } world.prefabStore.particleCombat(attackFrom.hex, attackTo.hex); } } foreach (SocialGroup group in socialGroups) { foreach (DipRel rel in group.getAllRelations()) { if (rel.state == DipRel.dipState.war && rel.war.canTimeOut) { if (turn - rel.war.startTurn > param.war_defaultLength) { declarePeace(rel); } } } } }