From d28dfac423887fcebd3b974abdbdb0cc2448298d Mon Sep 17 00:00:00 2001 From: Ronja Date: Fri, 18 Sep 2020 18:48:07 +0200 Subject: [PATCH] simple resources system --- Luxe/assets/names.lx | 2 +- Luxe/assets/resources.lx | 15 ++++++++ Luxe/blocks/human/human.wren | 2 +- Luxe/blocks/info.wren | 40 ++++++++++++++++++-- Luxe/blocks/resources.wren | 65 ++++++++++++++++++++++++++++++++ Luxe/blocks/ui/image_button.wren | 2 +- Luxe/game.wren | 11 +++++- Luxe/math/observable.wren | 7 +++- Luxe/math/util.wren | 10 +++++ 9 files changed, 144 insertions(+), 10 deletions(-) create mode 100644 Luxe/assets/resources.lx create mode 100644 Luxe/blocks/resources.wren diff --git a/Luxe/assets/names.lx b/Luxe/assets/names.lx index c74a9f1..a22d269 100644 --- a/Luxe/assets/names.lx +++ b/Luxe/assets/names.lx @@ -1,4 +1,4 @@ -names = [ +[ //todo: make more sophisticated to allow first + last name relationships, make common matches for those, //make groups based on origin culture / meaning //probably better to do when I have a procgen text engine diff --git a/Luxe/assets/resources.lx b/Luxe/assets/resources.lx new file mode 100644 index 0000000..bc0a603 --- /dev/null +++ b/Luxe/assets/resources.lx @@ -0,0 +1,15 @@ +[ + //the text decides how the resources are actually dealt with + //this is mainly here to define a order in the UI + {name: "wood", "alwaysSingular": true}, + {name: "clothes", "alwaysSingular":true}, + {name: "tent"}, + {name: "water bag"}, + {name: "dog"}, + {name: "map"}, + {name: "marble"}, + {name: "gold", "alwaysSingular":true}, + {name: "tea", "alwaysSingular": true}, + {name: "spices", "alwaysSingular": true}, + {name: "sunscreen", "alwaysSingular": true}, +] \ No newline at end of file diff --git a/Luxe/blocks/human/human.wren b/Luxe/blocks/human/human.wren index 132e658..f2c7eef 100644 --- a/Luxe/blocks/human/human.wren +++ b/Luxe/blocks/human/human.wren @@ -110,7 +110,7 @@ class HumanSystem is ModifierSystem { if(Input.mouse_state_pressed(MouseButton.left)){ var game = Globals["Game"] - if(game.ui.ui_mode == Ui.Info && _hoverEnt){ //remove &&hoverEnt to allow unfocussing + if(_hoverEnt){ //remove if statement to allow clicking away (probably needs extra code to allow ui clicking) game.Focus.value = _hoverEnt } } diff --git a/Luxe/blocks/info.wren b/Luxe/blocks/info.wren index 2d601c3..6e7f74b 100644 --- a/Luxe/blocks/info.wren +++ b/Luxe/blocks/info.wren @@ -31,6 +31,16 @@ class UiInfo{ _page = Observable.new(UiInfo.human) + _focus = Observable.new() + Globals["Game"].Focus.on_change(true) {|val| + if(ui.ui_mode == Ui.Info){ + _focus.value = val + if(_page.value == UiInfo.resources){ + _page.value = UiInfo.human + } + } + } + setup() } @@ -44,6 +54,7 @@ class UiInfo{ toolbar() human() diary() + resources() } toolbar(){ @@ -132,7 +143,7 @@ class UiInfo{ Control.set_id(frame, "person info frame") Control.child_add(portrait, frame) - Globals["Game"].Focus.on_change(true) {|val| + _focus.on_change(true) {|val| //todo: more sophisticated portrait generation UIImage.set_image(portrait, Assets.image("assets/wip/Portrait")) UIImage.set_color(portrait, Human.get_color(val) || [0, 0, 0, 1]) @@ -147,7 +158,7 @@ class UiInfo{ var name = UISimpleText.create(_ent) Control.child_add(statBlock, name) Control.set_id(name, "human name info") - Globals["Game"].Focus.on_change(true) {|val| + _focus.on_change(true) {|val| var name_string = Human.get_name(val) || "-" UISimpleText.set_text(name, name_string) } @@ -155,7 +166,7 @@ class UiInfo{ var adventures = UISimpleText.create(_ent) Control.child_add(statBlock, adventures) Control.set_id(name, "human adventure count") - Globals["Game"].Focus.on_change(true) {|val| + _focus.on_change(true) {|val| var count = Human.get_adventure_count(val) var text = count ? "Adventures: %(count)" : "" UISimpleText.set_text(adventures, text) @@ -177,10 +188,31 @@ class UiInfo{ Control.set_id(title, "human name info") UILayout.set_behave(_ent, title, UILayoutBehave.left | UILayoutBehave.top) //| UILayout.set_margin(_ent, title, 1, 1, 0, 0) - Globals["Game"].Focus.on_change(true) {|val| + _focus.on_change(true) {|val| var name = Human.get_name(val) var diary_title = name ? "%(StringUtil.possesive(name)) Diary" : "Diary" UISimpleText.set_text(title, diary_title) } } + + resources(){ + 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 == UiInfo.resources) + } + + var resList = UISimpleText.create(_ent) + Control.child_add(page, resList) + UILayout.set_behave(_ent, resList, UILayoutBehave.left | UILayoutBehave.top) //| + UILayout.set_margin(_ent, resList, 7, 3, 0, 0) + Globals["Game"].resources.on_change{|val| + var resources = val.list() + var text = resources.map{|res| "%(res["name"]): %(res["amount"])"}.join("\n") + UISimpleText.set_text(resList, text) + } + } } \ No newline at end of file diff --git a/Luxe/blocks/resources.wren b/Luxe/blocks/resources.wren new file mode 100644 index 0000000..d2bda09 --- /dev/null +++ b/Luxe/blocks/resources.wren @@ -0,0 +1,65 @@ +import "luxe: assets" for Assets +import "math/event" for Event +import "math/observable" for Observable +import "math/stringUtil" for StringUtil + +class Resources is Observable{ + + construct new(){ + super() + _resources = {} + _nameList = Assets.lx("assets/resources.lx") + value_no_update = this + } + + list(){ + //construct map from name and amount + var list = _nameList.map{ |res| {"name": res, "amount": _resources[res["name"]]}}.//<-- butt dot! + //filter out the ones without an amount + where{ |res| res["amount"] }. + //get correct name and respect plural rules //also this is its own line because each returns void >.> + map{ |res| {"name": res["amount"] != 1 && !res["name"]["alwaysSingular"] ? StringUtil.plural(res["name"]["name"]) : res["name"]["name"], + "amount": res["amount"] }} + return list + } + + get(resource){ + return _resources[resource] || 0 + } + + set(resource, amount){ + _resources[resource] = amount + emit() + } + + add(resource, amount){ + var value = get(resource) + set(resource, value + amount) + } + + remove(resource, amount){ + add(resource, -amount) + } + + empty(resource){ + var value = get(resource) + if(value > 0){ //this check is to not initialize undefined resource types + set(resource, 0) + } + return value + } + + tryRemove(resource, amount){ + if(has(resource, amount)){ + remove(resource, amount) + return true + } else { + return false + } + } + + has(resource, amount){ + var value = _resources[resource] + return value && value >= amount //check if not null, and bigger than amount + } +} \ No newline at end of file diff --git a/Luxe/blocks/ui/image_button.wren b/Luxe/blocks/ui/image_button.wren index 643b818..1233dbd 100644 --- a/Luxe/blocks/ui/image_button.wren +++ b/Luxe/blocks/ui/image_button.wren @@ -38,7 +38,7 @@ class ImageButton{ } if(data){ - System.print(string_type + " " + data["tooltip"]) + //System.print(string_type + " " + data["tooltip"]) var func = data["state_change"] if(func){ func.call(data, button) diff --git a/Luxe/game.wren b/Luxe/game.wren index 8077d9d..c6d76fd 100644 --- a/Luxe/game.wren +++ b/Luxe/game.wren @@ -18,6 +18,7 @@ import "math/util" for Util import "math/observable" for Observable import "blocks/tooltip" for Tooltip import "blocks/human/human" for Human +import "blocks/resources" for Resources class Game is Ready { construct ready() { @@ -28,8 +29,9 @@ class Game is Ready { _adventure = Observable.new() app = App.new() - _ui = Ui.new(app) + _resources = Resources.new() _tooltip = Tooltip.new(app) + _ui = Ui.new(app) setup() DrawDebug.setup(app.world) @@ -76,6 +78,10 @@ class Game is Ready { var material = Util.material_from_image_path("assets/wip/Room") Sprite.create(bg, material, 128, 128) + _resources.add("dog", 2) + _resources.add("wood", 5) + _resources.add("tent", 0) + create_human() create_human() create_human() @@ -89,13 +95,14 @@ class Game is Ready { Human.create(human) Human.set_color(human, Util.hsv(RandomInst.float(), 0.5, 1)) - var names = Assets.lx("assets/names.lx")["names"] + var names = Assets.lx("assets/names.lx") var name = names[RandomInst.int(0, names.count)] Human.set_name(human, name) } Focus{_focus} Adventure{_adventure} + resources{_resources} app { _app } app=(v) { _app=v } diff --git a/Luxe/math/observable.wren b/Luxe/math/observable.wren index 73223f7..4725df3 100644 --- a/Luxe/math/observable.wren +++ b/Luxe/math/observable.wren @@ -3,7 +3,7 @@ import "math/event" for Event class Observable{ value{_value} value=(v){ - _event.emit([v]) + _event.emit([v]) //do extra list wrapping here to allow list values _value = v } value_no_update=(v){_value = v} @@ -20,6 +20,11 @@ class Observable{ _event = Event.new() } + //manually emit an update + emit(){ + _event.emit([_value]) + } + on_change(fn){ return _event.listen(fn) } diff --git a/Luxe/math/util.wren b/Luxe/math/util.wren index 90c9e83..e0dcbb2 100644 --- a/Luxe/math/util.wren +++ b/Luxe/math/util.wren @@ -34,6 +34,16 @@ class Util{ } static call_arg_list(fn, args){ + //cover non-list cases + if(args is Null){ + fn.call() + return + } + if(!(args is Sequence)){ + fn.call(args) + return + } + //list cases var l = args.count if(l == 0){ fn.call()