From 2f31e7a55f3c9a3ed1aa63785a0ab91a2ef619e0 Mon Sep 17 00:00:00 2001 From: Ronja Date: Sat, 31 Oct 2020 15:13:01 +0100 Subject: [PATCH] adventure stuff --- Luxe/blocks/adventures.wren | 39 ++++++++++ Luxe/blocks/resources.wren | 17 +++-- Luxe/blocks/ui/adventure.wren | 132 +++++++++++++++++++++------------- 3 files changed, 131 insertions(+), 57 deletions(-) diff --git a/Luxe/blocks/adventures.wren b/Luxe/blocks/adventures.wren index 8a6cf4d..8496891 100644 --- a/Luxe/blocks/adventures.wren +++ b/Luxe/blocks/adventures.wren @@ -2,6 +2,8 @@ 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 class Adventures{ planning{_planning} @@ -12,14 +14,41 @@ class Adventures{ _in_progress = [] _archive = [] _max_distance = 10 + _game = Globals["Game"] } plan_new(){ + System.print("Start planning new Adventure") var adventure = Adventure.new() + adventure.distance = 2 _planning.value = adventure return adventure } + dispatch(){ + var adventure = _planning.value + if(!adventure){ + System.print("Tried to dispatch adventure, but none is planned") + return + } + System.print("Dispatching adventure \"%(adventure)\"") + + adventure.setup() + adventure.adventurers.each{|human| + Human.set_active(human, false) + } + adventure.resources.list().each{|resource| + _game.resources.remove(resource["base_name"], resource["amount"]) + } + _in_progress.add(adventure) + _planning.value = null + } + + tick(){ + //check some stuff that needs to be checked from time to time + //once per second/minute/whatever should be enough + } + new_or_current(){ if(_planning.value) return _planning.value return plan_new() @@ -44,6 +73,12 @@ class Adventure{ distance{_distance} distance=(dist){_distance = dist} + toString{ + return "%(adventurers.map{|id| Human.get_name(id)}.toList)"+ + " travelling %(distance)km towards %(StringUtil.direction(direction))"+ + " with %(resources.list().map{|resource| "%(resource["amount"]) %(resource["name"])"}.toList)" + } + construct new(){ _adventurers = [] _resources = Resources.new() @@ -53,6 +88,10 @@ class Adventure{ _distance = 0 } + setup(){ + + } + add_adventurer(adventurer){ _adventurers.add(adventurer) } diff --git a/Luxe/blocks/resources.wren b/Luxe/blocks/resources.wren index fe74366..98d7ce3 100644 --- a/Luxe/blocks/resources.wren +++ b/Luxe/blocks/resources.wren @@ -14,19 +14,24 @@ class Resources is Observable{ value_no_update = this } + toString{ + return list().map{|resource| "%(resource["amount"]) %(resource["name"])"}.toList.toString + } + list(){ //construct map from name and amount - var list = _nameList.map{ |res| {"name": res, "amount": _resources[res["name"]]}}.//<-- butt dot! + var list = _nameList.map{ |res| {"name": res, "amount": _resources[res["name"]]}}. //filter out the ones without an amount where{ |res| res["amount"] }. toList //toList makes the each work ^^ otherwise the result sequence runs map twice //get correct name and respect plural rules //also this is its own line because each returns void >.> list.each{ |res| - var name = res["name"]["name"] - var singular = res["amount"] == 1 || res["name"]["alwaysSingular"] - res["name"] = singular ? name : StringUtil.plural(name) - } - + var name = res["name"]["name"] + var singular = res["amount"] == 1 || res["name"]["alwaysSingular"] + res["name"] = singular ? name : StringUtil.plural(name) + res["base_name"] = name + } + return list } diff --git a/Luxe/blocks/ui/adventure.wren b/Luxe/blocks/ui/adventure.wren index a98b9cf..0ab1362 100644 --- a/Luxe/blocks/ui/adventure.wren +++ b/Luxe/blocks/ui/adventure.wren @@ -1,32 +1,33 @@ +import "luxe: assets" for Assets, Strings +import "luxe: color" for Color +import "luxe: containers" for Lists import "luxe: draw" for Draw, PathStyle +import "luxe: game" for Frame +import "luxe: math" for Math +import "luxe: render" for Material, TextAlign +import "luxe: ui/control" for Control +import "luxe: ui/image" for UIImage +import "luxe: ui/label" for UILabel import "luxe: world" for Entity, Transform, UI, UIRenderMode, UIEvent import "luxe: world" for UILayout, UILayoutBehave, UILayoutContain -import "luxe: ui/control" for Control -import "luxe: ui/label" for UILabel -import "luxe: ui/image" for UIImage -import "luxe: assets" for Assets, Strings -import "luxe: render" for Material, TextAlign -import "luxe: color" for Color -import "luxe: game" for Frame -import "luxe: containers" for Lists -import "luxe: math" for Math -import "globals" for Globals -import "blocks/ui/clickable" for Clickable -import "blocks/ui/image_util" for UiImageUtil -import "math/observable" for Observable -import "blocks/ui/simple_text" for UISimpleText -import "blocks/ui/ui" for Ui -import "blocks/ui/slider" for UiSlider +import "blocks/human/human" for Human import "blocks/ui/box" for UIBox -import "blocks/ui/scroll_box" for UiScrollBox +import "blocks/ui/clickable" for Clickable import "blocks/ui/compass" for UiCompass +import "blocks/ui/image_util" for UiImageUtil import "blocks/ui/info" for UiInfo //this is a cyclic dependency waiting to happen... import "blocks/ui/number_field" for NumberField -import "math/math" for M -import "math/util" for Util +import "blocks/ui/scroll_box" for UiScrollBox +import "blocks/ui/simple_text" for UISimpleText +import "blocks/ui/slider" for UiSlider +import "blocks/ui/ui" for Ui +import "globals" for Globals import "math/event" for MultiListenerToken -import "blocks/human/human" for Human +import "math/math" for M +import "math/observable" for Observable +import "math/stringUtil" for StringUtil +import "math/util" for Util class UiAdventure{ root{_root} @@ -35,6 +36,7 @@ class UiAdventure{ static people{"people"} static resources{"resources"} static depart{"depart"} + static abort{"abort"} adventure{_game.adventures.planning} //shortcut to get currently planning adventure (observable) @@ -50,17 +52,25 @@ class UiAdventure{ setup(){ var ui_rect = Globals["UiRect"] - var game = Globals["Game"] _root = Control.create(_ent) Control.set_allow_input(_root, true) Control.set_size(_root, ui_rect.width, ui_rect.height) + //if no adventure is planned anymore, leave adventure planning ui + _game.adventures.planning.on_change{|adventure| + if(!adventure){ + _ui.ui_mode = Ui.Info + _page.value = UiAdventure.direction + } + } + toolbar() direction() people() resources() depart() + abort() } toolbar(){ @@ -78,11 +88,7 @@ class UiAdventure{ _ui.list_button(list, [2, 0], "People") {_page.value = UiAdventure.people} _ui.list_button(list, [4, 0], "Stuff") {_page.value = UiAdventure.resources} _ui.list_button(list, [5, 0], "Depart") {_page.value = UiAdventure.depart} - _ui.list_button(list, [0, 0], "Abort") { - _ui.ui_mode = Ui.Info - _game.adventures.discard() - _page.value = UiAdventure.direction - } + _ui.list_button(list, [0, 0], "Abort") {_page.value = UiAdventure.abort} } direction(){ @@ -102,21 +108,6 @@ class UiAdventure{ Control.set_size(compass, 32, 32) UILayout.set_margin(_ent, compass, 8, 0, 0, 0) var steps = 16 //compass steps - var step_names = ["N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"] - var full_step_names = step_names.map{|short| - var shorts = "NESW" - var base_directions = ["north","east","south","west"] - if(short.count == 1){ - return base_directions[shorts.indexOf(short)] - } else if(short.count == 2) { - return base_directions[shorts.indexOf(short[0])] + - base_directions[shorts.indexOf(short[1])] - } else { //assume 3 - return base_directions[shorts.indexOf(short[0])] + "-" + - base_directions[shorts.indexOf(short[1])] + - base_directions[shorts.indexOf(short[2])] - } - }.toList adventure.on_change(true){|val| if(val == null) return @@ -176,7 +167,7 @@ class UiAdventure{ adventure.on_change(true) { |val| if(val == null) return //this stuff does bad things - var dir = full_step_names[val.direction] + var dir = StringUtil.direction(val.direction) var dist = val.distance UILabel.set_text(text, "%(dist)km\n%(dir)") } @@ -333,13 +324,13 @@ class UiAdventure{ //change resource data Control.set_events(amount){|event| if(event.type == UIEvent.change){ - var value = event.change.round - adventure.resources.set(resource["name"], value) + var value = Math.clamp(event.change.round, 0, resource["amount"]) + adventure.resources.set(resource["base_name"], value) } } //change ui on resource data change var token = adventure.resources.on_change{|value| - NumberField.set_value(amount, Math.clamp(value.get(resource["name"]), 0, resource["amount"])) + NumberField.set_value(amount, value.get(resource["base_name"])) } _itemEvents.add(token) _itemListItems.add(item) @@ -354,6 +345,9 @@ class UiAdventure{ Control.child_add(_root, page) UILayout.set_behave(_ent, page, UILayoutBehave.fill) UILayout.set_margin(_ent, page, 0, 0, 0, 16) + _page.on_change(true){|val| + Control.set_visible(page, val == UiAdventure.depart) + } var ready = UILabel.create(_ent) Control.child_add(page, ready) @@ -372,6 +366,8 @@ class UiAdventure{ UILabel.set_font(go, _ui.font) UILabel.set_text_size(go, 16) UILabel.set_text(go, "GO") + UILabel.set_color(go, [1,1,1,1]) + UILabel.set_color_hover(go, [1,1,1,1]) UILayout.set_behave(_ent, go, UILayoutBehave.left | UILayoutBehave.top) //| UILayout.set_margin(_ent, go, 56, 24, 0, 0) Clickable.make_clickable(go) @@ -379,14 +375,48 @@ class UiAdventure{ UILabel.set_text(go, data["hover"]?"GO!":"GO") } Clickable.set_on_click(go){ - //todo, start adventure, not discard!! - _ui.ui_mode = Ui.Info - _game.adventures.discard() - _page.value = UiAdventure.direction + _game.adventures.dispatch() + } + } + + abort(){ + var page = Control.create(_ent) + Control.child_add(_root, page) + UILayout.set_behave(_ent, page, UILayoutBehave.fill) + UILayout.set_margin(_ent, page, 0, 0, 0, 16) + _page.on_change(true){|val| + Control.set_visible(page, val == UiAdventure.abort) } - _page.on_change(true){|val| - Control.set_visible(page, val == UiAdventure.depart) + var ready = UILabel.create(_ent) + Control.child_add(page, ready) + Control.set_size(ready, 100, 10) + UILabel.set_align_vertical(ready, TextAlign.bottom) + UILabel.set_font(ready, _ui.font) + UILabel.set_text_size(ready, 8) + UILabel.set_text(ready, "This will discard the adventure") + UILayout.set_behave(_ent, ready, UILayoutBehave.left | UILayoutBehave.top) //| + UILayout.set_margin(_ent, ready, 12, 0, 0, 0) + UILabel.set_color(ready, [0.7, 0.7, 0.7, 1]) + + var abort = UILabel.create(_ent) + Control.child_add(page, abort) + Control.set_size(abort, 100, 20) + UILabel.set_align_vertical(abort, TextAlign.bottom) + UILabel.set_align(abort, TextAlign.right) + UILabel.set_font(abort, _ui.font) + UILabel.set_text_size(abort, 16) + UILabel.set_text(abort, "ABORT") + UILabel.set_color(abort, [1,1,1,1]) + UILabel.set_color_hover(abort, [1,1,1,1]) + UILayout.set_behave(_ent, abort, UILayoutBehave.left | UILayoutBehave.top) //| + UILayout.set_margin(_ent, abort, 25, 8, 0, 0) + Clickable.make_clickable(abort) + Clickable.set_state_change(abort){ |data, button| + UILabel.set_text(abort, data["hover"]?"ABORT!":"ABORT") + } + Clickable.set_on_click(abort){ + _game.adventures.discard() } } } \ No newline at end of file