import "math/observable" for Observable import "luxe: world" for Entity, Values, Tags import "globals" for Globals import "blocks/resources" for Resources import "math/stringUtil" for StringUtil import "blocks/human/human" for Human import "luxe: containers" for Lists import "blocks/narrative/diary/diary" for Diary import "blocks/narrative/progress/progress" for Progress class AdventureManager{ planning : Observable {_planning} max_distance : Num {_max_distance} construct new(){ _planning = Observable.new() _in_progress = [] _archive = [] _max_distance = 10 _game = Globals["Game"] } plan_new(){ Log.print("Start planning new Adventure") var adventure = Adventure.new() adventure.distance = 2 _planning.value = adventure return adventure } dispatch(){ var adventure = _planning.value if(!adventure){ Log.print("Tried to dispatch adventure, but none is planned") return } adventure.setup() adventure.adventurers.each{|human| human.active = false if(_game.focus.value == human) _game.focus.value = null } adventure.resources.list().each{|resource| _game.resources.remove(resource["base_name"], resource["amount"]) } Log.print("Dispatching adventure \"%(adventure)\"") _in_progress.add(adventure) _planning.value = null } arrive(adventure: Adventure){ Lists.remove(_in_progress, adventure) //bring resources back into main storage adventure.resources.list().each{|resource| _game.resources.add(resource["base_name"], resource["amount"]) } adventure.adventurers.each{|adventurer| adventurer.active = true } Log.print("Adventure arrived \"%(adventure)\"") } tick(){ //check some stuff that needs to be checked from time to time //once per second/minute/whatever should be enough _in_progress.each{|adventure : Adventure| adventure.tick(this) } } new_or_current(){ if(_planning.value) return _planning.value return plan_new() } discard(){ _planning.value = null } set_max_distance(dist){ _max_distance = dist planning.emit() } } class Adventure{ adventurers{_adventurers} resources{_resources} data{_data} direction{_direction} direction=(dir){_direction = dir} distance{_distance} distance=(dist){_distance = dist} toString{ return "%(adventurers.map{|human| human.name}.toList)"+ " travelling %(distance)km towards %(StringUtil.direction(direction))"+ " with %(resources.list().map{|resource| "%(resource["amount"]) %(resource["name"])"}.toList)" } construct new(){ _adventurers = [] _resources = Resources.new() _data = {} _direction = 0 _distance = 0 } setup(){ _resources.removeEmpty() } tick(manager : AdventureManager){ //generate what happens on the day var dayData = Progress.progress(this) //make everyone (try to) write a diary entry about it adventurers.each{|adventurer| Diary.write(adventurer, dayData) } if(dayData["arrive"]) manager.arrive(this) } add_adventurer(adventurer){ _adventurers.add(adventurer) } add_resource(resource, amount){ _resources.add(resource, amount) } }