private int Combat_Compute_Defender_Power(PlayerAction action, Player target_player) { //Compute Defender combat power //Add raw power from ships defending int defender_power = 0; foreach (KeyValuePair<SHIP_TYPE, int> pair in target_player.Ships_Defending) { defender_power += GameManager.Ship_Templates[pair.Key].Combat_Rating * pair.Value * TechManager.Tech_Mod(TECH_TYPE.TECH_SHIP_WEAPONS, target_player.tech_ship_weapons); } //If the defending fleet is at home, it adds its raw combat power to the defense if (target_player.fleet_at_home) { foreach (KeyValuePair<SHIP_TYPE, int> pair in target_player.Ships_Attacking) { defender_power += GameManager.Ship_Templates[pair.Key].Combat_Rating * pair.Value * TechManager.Tech_Mod(TECH_TYPE.TECH_SHIP_WEAPONS, target_player.tech_ship_weapons); } } //Add powers from all structures with combat power foreach (KeyValuePair<STRUCTURE_TYPE, int> pair in target_player.Structures) { defender_power += GameManager.Structure_Templates[pair.Key].Bonus_Combat * pair.Value * TechManager.Tech_Mod(TECH_TYPE.TECH_STRUCT_WEAPONS, target_player.tech_struct_weapons); } //Determine which attacking and defending specialty ships (Covert Ops, et al) to add to the scores //Using the same mechanism as above based on attack type switch (action.Type) { case PLAYER_ACTION.ACTION_ATTACK_COMBAT: break; case PLAYER_ACTION.ACTION_ATTACK_DIPLOMACY: foreach (KeyValuePair<SHIP_TYPE, int> pair in target_player.Ships_Defending) { defender_power += GameManager.Ship_Templates[pair.Key].Bonus_Diplomacy * pair.Value; } if (target_player.fleet_at_home) { foreach (KeyValuePair<SHIP_TYPE, int> pair in target_player.Ships_Attacking) { defender_power += GameManager.Ship_Templates[pair.Key].Bonus_Diplomacy * pair.Value; } } break; case PLAYER_ACTION.ACTION_ATTACK_ECON: foreach (KeyValuePair<SHIP_TYPE, int> pair in target_player.Ships_Defending) { defender_power += GameManager.Ship_Templates[pair.Key].Bonus_Econ * pair.Value; } if (target_player.fleet_at_home) { foreach (KeyValuePair<SHIP_TYPE, int> pair in target_player.Ships_Attacking) { defender_power += GameManager.Ship_Templates[pair.Key].Bonus_Econ * pair.Value; } } break; case PLAYER_ACTION.ACTION_ATTACK_TECH: foreach (KeyValuePair<SHIP_TYPE, int> pair in target_player.Ships_Defending) { defender_power += GameManager.Ship_Templates[pair.Key].Bonus_Tech * pair.Value; } if (target_player.fleet_at_home) { foreach (KeyValuePair<SHIP_TYPE, int> pair in target_player.Ships_Attacking) { defender_power += GameManager.Ship_Templates[pair.Key].Bonus_Tech * pair.Value; } } break; default: break; } return defender_power; }
private void Combat_Compute_Credit_Transfer(float differential, Player target_player) { //Compute Credit Transfer if (target_player.credits_current > differential) { target_player.credits_current -= (int)differential; if (this.strategy == PLAYER_STRAT.STRAT_PIRATE) { this.credits_current += (int)differential / PIRATE_DIVISOR; } else { this.credits_current += (int)differential; } } //Else the target was massively outclassed, no plundering the weak }
private void Combat_Compute_Defender_losses(float differential, int defender_power, bool attacker_victory, Player target_player, PlayerAction action) { //Defender can lose any ship present and any structure that was targeted int defender_hp_loss = 0; int total_defend_hp = 0; foreach (KeyValuePair<SHIP_TYPE, int> pair in this.Ships_Defending) { total_defend_hp += GameManager.Ship_Templates[pair.Key].HP * pair.Value; } if (target_player.fleet_at_home) { foreach (KeyValuePair<SHIP_TYPE, int> pair in target_player.Ships_Attacking) { total_defend_hp += GameManager.Ship_Templates[pair.Key].Bonus_Tech * pair.Value; } } //Add only structures that have a stat that was targeted by the attack action. ACTION_ATTACK_COMBAT targets all. foreach (KeyValuePair<STRUCTURE_TYPE, int> pair in target_player.Structures) { bool add = false; if (action.Type == PLAYER_ACTION.ACTION_ATTACK_COMBAT) { add = true; } else if (action.Type == PLAYER_ACTION.ACTION_ATTACK_DIPLOMACY && GameManager.Structure_Templates[pair.Key].Bonus_Diplomacy > 0) { add = true; } else if (action.Type == PLAYER_ACTION.ACTION_ATTACK_ECON && GameManager.Structure_Templates[pair.Key].Bonus_Econ > 0) { add = true; } else if (action.Type == PLAYER_ACTION.ACTION_ATTACK_TECH && GameManager.Structure_Templates[pair.Key].Bonus_Tech > 0) { add = true; } if (add) { total_defend_hp += GameManager.Structure_Templates[pair.Key].HP * pair.Value * TechManager.Tech_Mod(TECH_TYPE.TECH_STRUCT_HP, target_player.tech_struct_hp); } } //If defender won, limit losses to 20% float defender_loss_mod = attacker_victory ? 0.8f : 0.2f; defender_hp_loss = (int)((differential / (float)defender_power) * total_defend_hp * defender_loss_mod); //Defender losses, decide between ships and structures int defense_combat_rolls = 0; int max_defense_combat_rolls = defender_hp_loss; while (defender_hp_loss > 0) { Random rand = new Random(); int target_roll = rand.Next(100); if (target_roll < STRUCT_DESTROYED_CHANCE && action.Type == PLAYER_ACTION.ACTION_ATTACK_COMBAT) { STRUCTURE_TYPE destroyed_struct = (STRUCTURE_TYPE)rand.Next((int)STRUCTURE_TYPE.STRUCT_LAST_STRUCT); //If the selected structure type exists, destroy it if (target_player.Structures[destroyed_struct] > 0) { target_player.Structures[destroyed_struct]--; defender_hp_loss -= GameManager.Structure_Templates[destroyed_struct].HP * TechManager.Tech_Mod(TECH_TYPE.TECH_STRUCT_HP, target_player.tech_struct_hp); } } else if (target_roll < STRUCT_DESTROYED_CHANCE_TARGET && action.Type != PLAYER_ACTION.ACTION_ATTACK_COMBAT) { List<STRUCTURE_TYPE> target_types = new List<STRUCTURE_TYPE>(); switch (action.Type) { case PLAYER_ACTION.ACTION_ATTACK_DIPLOMACY: foreach (KeyValuePair<STRUCTURE_TYPE, Structure> struct_type in GameManager.Structure_Templates) { if (struct_type.Value.Bonus_Diplomacy > 0) { target_types.Add(struct_type.Key); } } break; case PLAYER_ACTION.ACTION_ATTACK_ECON: foreach (KeyValuePair<STRUCTURE_TYPE, Structure> struct_type in GameManager.Structure_Templates) { if (struct_type.Value.Bonus_Econ > 0) { target_types.Add(struct_type.Key); } } break; case PLAYER_ACTION.ACTION_ATTACK_TECH: foreach (KeyValuePair<STRUCTURE_TYPE, Structure> struct_type in GameManager.Structure_Templates) { if (struct_type.Value.Bonus_Tech > 0) { target_types.Add(struct_type.Key); } } break; } //If the target has one of the valid structures, destroy it //If not, the loop continues to find a ship foreach (STRUCTURE_TYPE destroyed_struct in target_types) { if (target_player.Structures[destroyed_struct] > 0) { target_player.Structures[destroyed_struct]--; defender_hp_loss -= GameManager.Structure_Templates[destroyed_struct].HP * TechManager.Tech_Mod(TECH_TYPE.TECH_STRUCT_HP, target_player.tech_struct_hp); break; } } } else { SHIP_TYPE destroyed_ship = (SHIP_TYPE)rand.Next((int)SHIP_TYPE.SHIP_LAST_SHIP); //If there is an defending ship of this type, destroy it, reduce HP loss by its HP if (target_player.Ships_Defending[destroyed_ship] > 0) { target_player.Ships_Defending[destroyed_ship]--; defender_hp_loss -= GameManager.Ship_Templates[destroyed_ship].HP * TechManager.Tech_Mod(TECH_TYPE.TECH_SHIP_HP, target_player.tech_ship_hp); } //Else if target player has a ship marked for attack that is at home, destroy it else if (target_player.Ships_Attacking[destroyed_ship] > 0 && target_player.fleet_at_home) { target_player.Ships_Defending[destroyed_ship]--; defender_hp_loss -= GameManager.Ship_Templates[destroyed_ship].HP * TechManager.Tech_Mod(TECH_TYPE.TECH_SHIP_HP, target_player.tech_ship_hp); } } //Terminate combat eventually if not losing anything defense_combat_rolls++; if (defense_combat_rolls > max_defense_combat_rolls) { break; } } }
private void Combat_Compute_Attacker_losses(float differential, int attacker_power, bool attacker_victory, Player target_player) { //Attacker can only lose HP from ships that attacked //If they won, limit losses to 20% of differential int attacker_hp_loss = 0; int total_attack_hp = 0; foreach (KeyValuePair<SHIP_TYPE, int> pair in this.Ships_Attacking) { total_attack_hp += GameManager.Ship_Templates[pair.Key].HP * pair.Value * TechManager.Tech_Mod(TECH_TYPE.TECH_SHIP_HP, target_player.tech_ship_hp); ; } float attacker_loss_mod = attacker_victory ? 0.2f : 0.8f; attacker_hp_loss = (int)((differential / (float)attacker_power) * total_attack_hp * attacker_loss_mod); //Select destroyed ships and structures Random rand = new Random(); int offense_combat_rolls = 0; int max_offense_combat_rolls = attacker_hp_loss; while (attacker_hp_loss > 0) { SHIP_TYPE destroyed_ship = (SHIP_TYPE)rand.Next((int)SHIP_TYPE.SHIP_LAST_SHIP); //If there is an attacking ship of this type, destroy it, reduce HP loss by its HP if (this.Ships_Attacking[destroyed_ship] > 0) { this.Ships_Attacking[destroyed_ship]--; attacker_hp_loss -= GameManager.Ship_Templates[destroyed_ship].HP * TechManager.Tech_Mod(TECH_TYPE.TECH_SHIP_HP, this.tech_ship_hp); } //Terminate combat eventually if not losing anything offense_combat_rolls++; if (offense_combat_rolls > max_offense_combat_rolls) { break; } } }