Move more code into gather file

This commit is contained in:
Nate Bowman
2026-07-30 21:02:14 -04:00
parent e25abd87ab
commit 194925ab04
4 changed files with 151 additions and 84 deletions

View File

@@ -5,6 +5,10 @@ from aoe.types import *
class Costs(): class Costs():
def compute_cost(self, purchase):
return self.costs[purchase]
def __init__(self): def __init__(self):
self.costs = { self.costs = {
Ages.DARK: (0, 0, 0, 0), Ages.DARK: (0, 0, 0, 0),

View File

@@ -154,6 +154,59 @@ class Gather():
raise GatherBuildingNotAvailableException raise GatherBuildingNotAvailableException
def permanently_modify_gather_rate(self, task, rate_multiplier):
self.gather_rates[task] *= rate_multiplier
self.original_gather_rates[task] *= rate_multiplier
def decrease_gather_rate_by_overuse(self, task):
# assumes rate decrease should trigger; does not check
new_rate = self.gather_decrease_rates[task]*self.gather_rates[task]
self.gather_rates[task] = new_rate
return new_rate
def improve_gather_rate_by_building(self, building, tasks):
if building == Buildings.FARM:
raise ValueError('Do not call this routine with a farm')
if building not in self.buildings_gather_increase.keys():
return []
if not tasks:
tasks = self.buildings_gather_increase[building].keys()
elif type(tasks) == Tasks:
tasks = [tasks]
for task in tasks:
amount = self.buildings_gather_increase[building][task]
if self.gather_rates[task] < self.original_gather_rates[task]:
self.gather_rates[task] = self.original_gather_rates[task]
self.gatherable_amounts[task] = amount
else:
self.gatherable_amounts[task] += amount
return tasks
def permanently_modify_consumable_capacity(self, building, task, increase):
current_initial_capacity = self.buildings_gather_increase[building]
self.buildings_gather_increase[building] += increase
return increase/current_initial_farm
def compute_gathered_resources_for_duration(self, villager_tasks, duration):
all_gathered = [0, 0, 0, 0]
for task, count in villager_tasks.items():
rate = self.gather_rates[task]
gathered = self.gathered_resources[task]
for resource, mult in gathered.items():
all_gathered[resource] += count*rate*mult*duration
return all_gathered
def __init__(self): def __init__(self):
self.gather_rates = { self.gather_rates = {
Tasks.BERRIES: 18.6/60, Tasks.BERRIES: 18.6/60,

View File

@@ -43,28 +43,28 @@ class ResearchEffects():
case Research.HANDCART: case Research.HANDCART:
cls._modify_rates_with_wheelbarrow_line(world, 1.1, 1.11) cls._modify_rates_with_wheelbarrow_line(world, 1.1, 1.11)
case Research.DOUBLEBITAXE: case Research.DOUBLEBITAXE:
world._permanently_modify_gather_rate(Tasks.WOOD, 1.2) world.permanently_modify_gather_rate(Tasks.WOOD, 1.2)
case Research.BOWSAW: case Research.BOWSAW:
world._permanently_modify_gather_rate(Tasks.WOOD, 1.2) world.permanently_modify_gather_rate(Tasks.WOOD, 1.2)
case Research.TWOMANSAW: case Research.TWOMANSAW:
world._permanently_modify_gather_rate(Tasks.WOOD, 1.1) world.permanently_modify_gather_rate(Tasks.WOOD, 1.1)
case Research.HORSECOLLAR: case Research.HORSECOLLAR:
world._permanently_modify_farm_capacity(75) world.permanently_modify_farm_capacity(75)
case Research.HEAVYPLOW: case Research.HEAVYPLOW:
world._permanently_modify_farm_capacity(125) world.permanently_modify_farm_capacity(125)
case Research.CROPROTATION: case Research.CROPROTATION:
world._permanently_modify_farm_capacity(175) world.permanently_modify_farm_capacity(175)
case Research.GOLDMINING: case Research.GOLDMINING:
world._permanently_modify_gather_rate(Tasks.GOLD, 1.15) world.permanently_modify_gather_rate(Tasks.GOLD, 1.15)
case Research.GOLDSHAFTMINING: case Research.GOLDSHAFTMINING:
world._permanently_modify_gather_rate(Tasks.GOLD, 1.15) world.permanently_modify_gather_rate(Tasks.GOLD, 1.15)
case Research.STONEMINING: case Research.STONEMINING:
world._permanently_modify_gather_rate(Tasks.STONE, 1.15) world.permanently_modify_gather_rate(Tasks.STONE, 1.15)
case Research.STONESHAFTMINING: case Research.STONESHAFTMINING:
world._permanently_modify_gather_rate(Tasks.STONE, 1.15) world.permanently_modify_gather_rate(Tasks.STONE, 1.15)
case Research.CARAVAN: case Research.CARAVAN:
world._permanently_modify_gather_rate(Tasks.TRADECART, 1.20) world.permanently_modify_gather_rate(Tasks.TRADECART, 1.20)
world._permanently_modify_gather_rate(Tasks.TRADECOG, 1.20) world.permanently_modify_gather_rate(Tasks.TRADECOG, 1.20)
#case Research.FISHINGLINES: #case Research.FISHINGLINES:
# probably looks like wheelbarrow # probably looks like wheelbarrow
#case Research.GILLNETS: #case Research.GILLNETS:
@@ -90,6 +90,6 @@ class ResearchEffects():
Tasks.GOLD, Tasks.GOLD,
Tasks.STONE] Tasks.STONE]
for task in affected: for task in affected:
world._permanently_modify_gather_rate(task, non_farm_rate) world.permanently_modify_gather_rate(task, non_farm_rate)
world._permanently_modify_gather_rate(Tasks.FARM, farm_rate) world.permanently_modify_gather_rate(Tasks.FARM, farm_rate)

View File

@@ -61,12 +61,30 @@ class World():
MAX_WORLD_TIME = 3*60*60 # 3 hours MAX_WORLD_TIME = 3*60*60 # 3 hours
def _pay_cost(self, purchase): def add_resources(self, gathered):
for i in range(len(self.resources)): for i in range(len(self.resources)):
if self.resources[i] < self.costs.costs[purchase][i]: self.resources[i] += gathered[i]
def pay_cost(self, thing):
spent = self.costs.compute_cost(thing)
for i in range(len(self.resources)):
if self.resources[i] < spent[i]:
raise NotEnoughResourcesException raise NotEnoughResourcesException
for i in range(len(self.resources)): for i in range(len(self.resources)):
self.resources[i] -= self.costs.costs[purchase][i] self.resources[i] -= spent[i]
def _remove_event_at_time(self, removed_event, scheduled_time):
if not scheduled_time:
return
for i, event in enumerate(self.events[scheduled_time]):
if event[0] == removed_event:
del self.events[scheduled_time][i]
break
def _schedule_next_gather_rate_decrease(self, task): def _schedule_next_gather_rate_decrease(self, task):
@@ -74,14 +92,8 @@ class World():
return return
# remove old decrease # remove old decrease
scheduled_decrease = self.rate_decrease_event_times[task] self._remove_event_at_time(self._decrease_gather_rate_by_overuse,
if scheduled_decrease is not None: self.rate_decrease_event_times[task])
decrease_index = None
for i, event in enumerate(self.events[scheduled_decrease]):
if event[0] == self._decrease_gather_rate:
decrease_index = i
break
del self.events[scheduled_decrease][i]
rate = self.gather.gather_rates[task] rate = self.gather.gather_rates[task]
@@ -107,53 +119,51 @@ class World():
if task == Tasks.FARM: if task == Tasks.FARM:
self.events[next_decrease].append((self._remove_farm, ())) self.events[next_decrease].append((self._remove_farm, ()))
else: else:
self.events[next_decrease].append((self._decrease_gather_rate, self.events[next_decrease].append((self._decrease_gather_rate_by_overuse,
(task,))) (task,)))
def _decrease_gather_rate(self, task): def _decrease_gather_rate_by_overuse(self, task):
# assumes rate decrease should trigger; does not check new_rate = self.gather.decrease_gather_rate_by_overuse(task)
new_rate = self.gather_decrease_rates[task]*self.gather_rates[task]
self.gather_rates[task] = new_rate
if new_rate > 0: if new_rate > 0:
self._schedule_next_gather_rate_decrease(task) self._schedule_next_gather_rate_decrease(task)
else: else:
self.assign_villager(task, task.IDLE, self.villager_tasks[task]) self.assign_villager(task, Tasks.IDLE, self.villager_tasks[task])
def _improve_gather_rate(self, building, tasks): def _improve_gather_rate_by_building(self, building, tasks):
if building == Buildings.FARM: tasks_improved = self.gather.improve_gather_rate_by_building(building,
raise ValueError('Do not call this routine with a farm') tasks)
for task in tasks_improved:
if tasks is None:
tasks = self.gather.buildings_gather_increase[building].keys()
for task in tasks:
amount = self.gather.buildings_gather_increase[building][task]
if self.gather.gather_rates[task] < self.gather.original_gather_rates[task]:
self.gather.gather_rates[task] = self.gather.original_gather_rates[task]
self.gather.gatherable_amounts[task] = amount
else:
self.gather.gatherable_amounts[task] += amount
self._schedule_next_gather_rate_decrease(task) self._schedule_next_gather_rate_decrease(task)
def _permanently_modify_farm_capacity(self, increase): def permanently_modify_gather_rate(self, task, multiplier):
current_initial_farm = self.gather.buildings_gather_increase[Buildings.FARM] self.gather.permanently_modify_gather_rate(task, multiplier)
for i in range(len(farms)): self._schedule_next_gather_rate_decrease(task)
farms[i] += (farms[i]/current_initial_farm)*increase
for i in range(len(unused_farms)):
unused_farms[i] += (unused_farms[i]/current_initial_farm)*increase
self.gather.buildings_gather_increase[Buildings.FARM] += increase
self._schedule_next_gather_rate_decrease(Task.FARM)
def _permanently_modify_gather_rate(self, task, rate_multiplier): def permanently_modify_farm_capacity(self, increase):
self.gather.gather_rates[tasks] *= rate_multiplier self._permanently_modify_consumable_capacity(Buildings.FARM,
self.gather.original_gather_rates[tasks] *= rate_multiplier Tasks.FARM,
increase)
def _permanently_modify_consumable_capacity(self, building, task, increase):
multiplier = self.gather.permanently_modify_consumable_capacity(building,
task,
increase)
if building == Buildings.FARM:
used = self.farms
unused = self.unused_farms
for i in range(len(used)):
used[i] += used[i]*multiplier
for i in range(len(unused)):
unused[i] += unused[i]*multiplier
self._schedule_next_gather_rate_decrease(task) self._schedule_next_gather_rate_decrease(task)
@@ -216,7 +226,7 @@ class World():
self.dependencies.check_dependencies(self, building) self.dependencies.check_dependencies(self, building)
self._pay_cost(building) self.pay_cost(building)
self._move_villagers_to_build(villagers_from_count) self._move_villagers_to_build(villagers_from_count)
villagers_to_count = Counter(villagers_to) villagers_to_count = Counter(villagers_to)
@@ -241,8 +251,8 @@ class World():
if building == Buildings.FARM: if building == Buildings.FARM:
self._add_farm() self._add_farm()
elif building in self.gather.buildings_gather_increase.keys(): else:
self._improve_gather_rate(building, tasks_improved) self._improve_gather_rate_by_building(building, tasks_improved)
for task, count in villagers_to.items(): for task, count in villagers_to.items():
self.assign_villager(Tasks.BUILD, task, count) self.assign_villager(Tasks.BUILD, task, count)
@@ -280,7 +290,12 @@ class World():
def _run_clock_without_events(self, end_time): def _run_clock_without_events(self, end_time):
self._gather_resources_for_duration(end_time - self.current_time) duration = end_time - self.current_time
gathered = self.gather.compute_gathered_resources_for_duration(self.villager_tasks,
duration)
self.add_resources(gathered)
self.current_time = end_time self.current_time = end_time
@@ -322,21 +337,23 @@ class World():
def _free_production_building(self, building): def _free_production_building(self, building):
# This will not respect the order of a queue in a particular building.
# For example, if there is a TC with the queue [villager, loom] and
# there is no available housing, the TC will research loom. In the
# actual game, the villager would block the researching of loom.
# There is no easy way around this as long as we are treating the
# production queue as a shared pool, and I don't really care.
self.production_available[building] += 1 self.production_available[building] += 1
# Start the next queued thing if one exists i = 0
ready_index = None while i < len(self.production_queue):
ready_thing = None
for i in range(len(self.production_queue)):
thing = self.production_queue[i] thing = self.production_queue[i]
if self.production.building[thing] == building: if self.production.building[thing] == building and \
ready_index = i self.housing.check_housing(self, thing):
ready_thing = thing self._start_producing(thing)
del self.production_queue[i]
break break
i += 1
if ready_index:
self.production_queue.remove(i)
self._start_producing(thing)
def _use_housing_and_production(self, thing): def _use_housing_and_production(self, thing):
@@ -390,7 +407,8 @@ class World():
def _queue_thing(self, thing, initial_task=None): def _queue_thing(self, thing, initial_task=None):
self.dependencies.check_dependencies(self, thing) self.dependencies.check_dependencies(self, thing)
self._pay_cost(thing) self.costs.compute_cost(thing)
self.pay_cost(thing)
self._start_producing(thing, initial_task) self._start_producing(thing, initial_task)
@@ -407,14 +425,6 @@ class World():
self._queue_thing(Units.VILLAGER, initial_task) self._queue_thing(Units.VILLAGER, initial_task)
def _gather_resources_for_duration(self, duration):
for task, count in self.villager_tasks.items():
rate = self.gather.gather_rates[task]
gathered = self.gather.gathered_resources[task]
for resource, mult in gathered.items():
self.resources[resource] += count*rate*mult*duration
def _handle_events(self): def _handle_events(self):
for func, args in self.events[self.current_time]: for func, args in self.events[self.current_time]:
func(*args) func(*args)
@@ -431,8 +441,8 @@ class World():
new_age = self.age + 1 new_age = self.age + 1
self._check_age_dependencies(new_age) self.dependencies.check_dependencies(new_age)
self._pay_cost(new_age) self.pay_cost(new_age)
update_time = self.current_time + self.build_times.build_times[new_age] update_time = self.current_time + self.build_times.build_times[new_age]
self.events[update_time].append((self._update_age, (new_age,))) self.events[update_time].append((self._update_age, (new_age,)))