mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Avoid negative AI produrement budgets.
This also fixes the double charging that the AI was suffering from, so they have a much better chance of actually affording planes now. Fixes https://github.com/Khopa/dcs_liberation/issues/504
This commit is contained in:
parent
f396ff7f12
commit
7226359e64
@ -1,12 +1,11 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
|
||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
from typing import List, TYPE_CHECKING, Type
|
from typing import List, Optional, TYPE_CHECKING, Type
|
||||||
|
|
||||||
from dcs.task import CAP, CAS
|
from dcs.task import CAP, CAS
|
||||||
from dcs.unittype import FlyingType, UnitType
|
from dcs.unittype import FlyingType, UnitType, VehicleType
|
||||||
|
|
||||||
from game import db
|
from game import db
|
||||||
from game.factions.faction import Faction
|
from game.factions.faction import Faction
|
||||||
@ -62,6 +61,14 @@ class ProcurementAi:
|
|||||||
)
|
)
|
||||||
return budget
|
return budget
|
||||||
|
|
||||||
|
def random_affordable_ground_unit(
|
||||||
|
self, budget: int) -> Optional[Type[VehicleType]]:
|
||||||
|
affordable_units = [u for u in self.faction.frontline_units if
|
||||||
|
db.PRICES[u] <= budget]
|
||||||
|
if not affordable_units:
|
||||||
|
return None
|
||||||
|
return random.choice(affordable_units)
|
||||||
|
|
||||||
def reinforce_front_line(self, budget: int) -> int:
|
def reinforce_front_line(self, budget: int) -> int:
|
||||||
if not self.faction.frontline_units:
|
if not self.faction.frontline_units:
|
||||||
return budget
|
return budget
|
||||||
@ -71,19 +78,16 @@ class ProcurementAi:
|
|||||||
if not candidates:
|
if not candidates:
|
||||||
return budget
|
return budget
|
||||||
|
|
||||||
# TODO: No need to limit?
|
while budget > 0:
|
||||||
for _ in range(50):
|
cp = random.choice(candidates)
|
||||||
if budget <= 0:
|
unit = self.random_affordable_ground_unit(budget)
|
||||||
|
if unit is None:
|
||||||
|
# Can't afford any more units.
|
||||||
break
|
break
|
||||||
|
|
||||||
cp = random.choice(candidates)
|
budget -= db.PRICES[unit]
|
||||||
unit = random.choice(self.faction.frontline_units)
|
cp.base.armor[unit] = cp.base.armor.get(unit, 0) + 1
|
||||||
price = db.PRICES[unit] * 2
|
self.reinforcement_message(unit, cp, group_size=1)
|
||||||
# TODO: Don't allow negative budget.
|
|
||||||
# Build a list of only affordable units and choose from those.
|
|
||||||
budget -= price * 2
|
|
||||||
cp.base.armor[unit] = cp.base.armor.get(unit, 0) + 2
|
|
||||||
self.reinforcement_message(unit, cp)
|
|
||||||
|
|
||||||
if cp.base.total_armor >= armor_limit:
|
if cp.base.total_armor >= armor_limit:
|
||||||
candidates.remove(cp)
|
candidates.remove(cp)
|
||||||
@ -92,6 +96,17 @@ class ProcurementAi:
|
|||||||
|
|
||||||
return budget
|
return budget
|
||||||
|
|
||||||
|
def random_affordable_aircraft_group(
|
||||||
|
self, budget: int, size: int) -> Optional[Type[FlyingType]]:
|
||||||
|
unit_pool = [u for u in self.faction.aircrafts
|
||||||
|
if u in db.UNIT_BY_TASK[CAS] or u in db.UNIT_BY_TASK[CAP]]
|
||||||
|
|
||||||
|
affordable_units = [u for u in unit_pool
|
||||||
|
if db.PRICES[u] * size <= budget]
|
||||||
|
if not affordable_units:
|
||||||
|
return None
|
||||||
|
return random.choice(affordable_units)
|
||||||
|
|
||||||
def purchase_aircraft(self, budget: int) -> int:
|
def purchase_aircraft(self, budget: int) -> int:
|
||||||
aircraft_limit = int(25 * self.game.settings.multiplier)
|
aircraft_limit = int(25 * self.game.settings.multiplier)
|
||||||
candidates = self.airbase_candidates(aircraft_limit)
|
candidates = self.airbase_candidates(aircraft_limit)
|
||||||
@ -103,19 +118,17 @@ class ProcurementAi:
|
|||||||
if not unit_pool:
|
if not unit_pool:
|
||||||
return budget
|
return budget
|
||||||
|
|
||||||
# TODO: No need to limit?
|
while budget > 0:
|
||||||
for _ in range(50):
|
cp = random.choice(candidates)
|
||||||
if budget <= 0:
|
group_size = 2
|
||||||
|
unit = self.random_affordable_aircraft_group(budget, group_size)
|
||||||
|
if unit is None:
|
||||||
|
# Can't afford any more aircraft.
|
||||||
break
|
break
|
||||||
|
|
||||||
cp = random.choice(candidates)
|
budget -= db.PRICES[unit] * group_size
|
||||||
unit = random.choice(unit_pool)
|
cp.base.aircraft[unit] = cp.base.aircraft.get(unit, 0) + group_size
|
||||||
price = db.PRICES[unit] * 2
|
self.reinforcement_message(unit, cp, group_size)
|
||||||
# TODO: Don't allow negative budget.
|
|
||||||
# Build a list of only affordable units and choose from those.
|
|
||||||
budget -= price * 2
|
|
||||||
cp.base.aircraft[unit] = cp.base.aircraft.get(unit, 0) + 2
|
|
||||||
self.reinforcement_message(unit, cp)
|
|
||||||
|
|
||||||
if cp.base.total_aircraft >= aircraft_limit:
|
if cp.base.total_aircraft >= aircraft_limit:
|
||||||
candidates.remove(cp)
|
candidates.remove(cp)
|
||||||
@ -125,8 +138,9 @@ class ProcurementAi:
|
|||||||
return budget
|
return budget
|
||||||
|
|
||||||
def reinforcement_message(self, unit_type: Type[UnitType],
|
def reinforcement_message(self, unit_type: Type[UnitType],
|
||||||
control_point: ControlPoint) -> None:
|
control_point: ControlPoint,
|
||||||
description = f"{unit_type.id} x 2 at {control_point.name}"
|
group_size: int) -> None:
|
||||||
|
description = f"{unit_type.id} x {group_size} at {control_point.name}"
|
||||||
if self.is_player:
|
if self.is_player:
|
||||||
self.game.message(f"Our reinforcements: {description}")
|
self.game.message(f"Our reinforcements: {description}")
|
||||||
else:
|
else:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user