420 lines
No EOL
14 KiB
Text
420 lines
No EOL
14 KiB
Text
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 UIBehave, UIContain
|
|
|
|
import "blocks/human/human" for Human
|
|
import "blocks/ui/box" for UIBox
|
|
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 "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 "math/math" for M
|
|
import "math/observable" for Observable
|
|
import "math/stringUtil" for StringUtil
|
|
import "math/util" for Util
|
|
|
|
class UiAdventure{
|
|
root{_root}
|
|
|
|
static direction{"direction"}
|
|
static people{"people"}
|
|
static resources{"resources"}
|
|
static depart{"depart"}
|
|
static abort{"abort"}
|
|
|
|
adventure{_game.adventures.planning} //shortcut to get currently planning adventure (observable)
|
|
|
|
construct new(ent, ui){
|
|
_ent = ent
|
|
_ui = ui
|
|
_game = Globals["Game"]
|
|
_page = Observable.new(UiAdventure.direction)
|
|
|
|
setup()
|
|
}
|
|
|
|
setup(){
|
|
var ui_rect = Globals["UiRect"]
|
|
|
|
_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(){
|
|
//list
|
|
var list = Control.create(_ent)
|
|
Control.child_add(_root, list)
|
|
Control.set_size(list, 0, 16)
|
|
Control.set_behave(list, UIBehave.left | UIBehave.right | UIBehave.bottom)//|
|
|
Control.set_margin(list, 0, 0, 0, 0)
|
|
Control.set_contain(list, UIContain.row | UIContain.start) //|
|
|
|
|
//toolbar icons
|
|
_ui.list_button(list, [1, 0], "Info") {_ui.ui_mode = Ui.Info}
|
|
_ui.list_button(list, [3, 0], "Direction") {_page.value = UiAdventure.direction}
|
|
_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") {_page.value = UiAdventure.abort}
|
|
}
|
|
|
|
direction(){
|
|
var page = Control.create(_ent)
|
|
Control.child_add(_root, page)
|
|
Control.set_behave(page, UIBehave.fill)
|
|
Control.set_margin(page, 0, 0, 0, 16)
|
|
Control.set_contain(page, UIContain.row | UIContain.start) //|
|
|
|
|
_page.on_change(true){|val|
|
|
Control.set_visible(page, val == UiAdventure.direction)
|
|
}
|
|
|
|
//compass
|
|
var compass = UiCompass.create(_ent)
|
|
Control.child_add(page, compass)
|
|
Control.set_size(compass, 32, 32)
|
|
Control.set_margin(compass, 8, 0, 0, 0)
|
|
var steps = 16 //compass steps
|
|
|
|
adventure.on_change(true){|val|
|
|
if(val == null) return
|
|
var angle = -val.direction * 360 / steps
|
|
UiCompass.set_angle(compass, angle)
|
|
}
|
|
|
|
Control.set_events(compass){|event|
|
|
if(event.type == UIEvent.change){
|
|
var angle = event.change
|
|
var angleIndex = M.mod(-(steps * angle / 360).round, steps)
|
|
adventure.value.direction = angleIndex
|
|
adventure.emit()
|
|
}
|
|
}
|
|
|
|
//other parent
|
|
var colParent = Control.create(_ent)
|
|
Control.set_id(colParent, "dir col parent")
|
|
Control.child_add(page, colParent)
|
|
Control.set_behave(colParent, UIBehave.fill)
|
|
Control.set_margin(colParent, 8, 0, 0, 0)
|
|
Control.set_contain(colParent, UIContain.column | UIContain.start) //|
|
|
|
|
//slider
|
|
var slider = UiSlider.create(_ent)
|
|
Control.set_id(slider, "dir dist slider")
|
|
Control.child_add(colParent, slider)
|
|
Control.set_size(slider, 0, 11)
|
|
Control.set_behave(slider, UIBehave.left | UIBehave.right) //|
|
|
Control.set_margin(slider, 4, 4, 4, 0)
|
|
|
|
adventure.on_change(true){|val|
|
|
if(val == null) return
|
|
var relative_distance = val.distance / _game.adventures.max_distance
|
|
UiSlider.set_value(slider, relative_distance)
|
|
}
|
|
|
|
Control.set_events(slider){|event|
|
|
if(event.type == UIEvent.change){
|
|
var distance = (event.change * _game.adventures.max_distance).round
|
|
adventure.value.distance = distance
|
|
adventure.emit()
|
|
}
|
|
}
|
|
|
|
//text
|
|
var text = UILabel.create(_ent)
|
|
Control.set_id(text, "dir text")
|
|
Control.child_add(colParent, text)
|
|
UILabel.set_font(text, _ui.font)
|
|
UILabel.set_text_size(text, 8)
|
|
UILabel.set_align_vertical(text, TextAlign.top)
|
|
Control.set_behave(text, UIBehave.left) //|
|
|
Control.set_margin(text, 4, 8, 4, 0)
|
|
|
|
adventure.on_change(true) { |val|
|
|
if(val == null) return
|
|
//this stuff does bad things
|
|
var dir = StringUtil.direction(val.direction)
|
|
var dist = val.distance
|
|
UILabel.set_text(text, "%(dist)km\n%(dir)")
|
|
}
|
|
}
|
|
|
|
people(){
|
|
var page = Control.create(_ent)
|
|
Control.child_add(_root, page)
|
|
Control.set_behave(page, UIBehave.fill)
|
|
Control.set_margin(page, 0, 0, 0, 16)
|
|
|
|
_page.on_change(true){|val|
|
|
Control.set_visible(page, val == UiAdventure.people)
|
|
}
|
|
|
|
_game.focus.on_change(true) {|val|
|
|
if(!val) return
|
|
if(_ui.ui_mode == Ui.Planning && _page.value == UiAdventure.people){
|
|
var adventure = adventure
|
|
if(adventure.value && !adventure.value.adventurers.contains(val)) {
|
|
adventure.value.adventurers.insert(0, val)
|
|
adventure.emit()
|
|
}
|
|
}
|
|
}
|
|
|
|
var list = UiScrollBox.create(_ent)
|
|
Control.child_add(page, list)
|
|
Control.set_behave(list, UIBehave.fill)
|
|
Control.set_margin(list, 40, 0, 0, 0)
|
|
|
|
var tiny_head = Assets.image("assets/wip/8Head")
|
|
var x_image = Assets.image("assets/wip/8Cross")
|
|
|
|
_adventurerListItems = []
|
|
adventure.on_change(true) {|planning|
|
|
//cleanup
|
|
_adventurerListItems.each{|item|
|
|
Control.destroy(item)
|
|
}
|
|
_adventurerListItems.clear()
|
|
|
|
if(!planning) return
|
|
|
|
//rebuild
|
|
var i = -1
|
|
planning.adventurers.each{ |adventurer|
|
|
i = i + 1
|
|
var item = UIBox.create(_ent)
|
|
Control.set_behave(item, UIBehave.left | UIBehave.right)//|
|
|
Control.set_margin(item, 0, 0, 0, 0)
|
|
Control.set_contain(item, UIContain.row | UIContain.start)//|
|
|
Control.set_size(item, -1, 12)
|
|
Control.set_id(item, "Person %(i) : %(adventurer.name)")
|
|
Clickable.make_clickable(item)
|
|
Clickable.set_on_click(item) {
|
|
_ui.ui_mode = Ui.Info
|
|
_ui.info.page.value = UiInfo.human
|
|
_game.focus.value = adventurer
|
|
}
|
|
UiScrollBox.add(list, item)
|
|
|
|
var head = UIImage.create(_ent)
|
|
Control.child_add(item, head)
|
|
Control.set_size(head, 8, 8)
|
|
UIImage.set_image(head, tiny_head)
|
|
UIImage.set_color(head, adventurer.color)
|
|
Control.set_margin(head, 2, 0, 0, 0)
|
|
|
|
var name = UILabel.create(_ent)
|
|
Control.child_add(item, name)
|
|
UILabel.set_align_vertical(name, TextAlign.bottom)
|
|
UILabel.set_font(name, _ui.font)
|
|
UILabel.set_text_size(name, 8)
|
|
UILabel.set_text(name, adventurer.name)
|
|
Control.set_behave(name, UIBehave.hfill | UIBehave.left)//|
|
|
Control.set_margin(name, 2, 1, 0, 1)
|
|
|
|
var remove = UIImage.create(_ent)
|
|
Clickable.make_clickable(remove)
|
|
Control.child_add(item, remove)
|
|
Control.set_size(remove, 8, 8)
|
|
UIImage.set_image(remove, x_image)
|
|
UIImage.set_color(remove, Color.hex(0xec172a))
|
|
Control.set_margin(remove, 0, 0, 2, 0)
|
|
Clickable.set_tooltip(remove, "remove")
|
|
Clickable.set_on_click(remove) {
|
|
Frame.end{
|
|
Globals["Tooltip"].clear(remove)
|
|
Lists.remove(planning.adventurers, adventurer)
|
|
adventure.emit()
|
|
}
|
|
}
|
|
|
|
_adventurerListItems.add(item)
|
|
}
|
|
|
|
UI.commit(_ent)
|
|
}
|
|
}
|
|
|
|
resources(){
|
|
var page = Control.create(_ent)
|
|
Control.child_add(_root, page)
|
|
Control.set_behave(page, UIBehave.fill)
|
|
Control.set_margin(page, 0, 0, 0, 16)
|
|
|
|
_page.on_change(true){|val|
|
|
Control.set_visible(page, val == UiAdventure.resources)
|
|
}
|
|
|
|
var list = UiScrollBox.create(_ent)
|
|
UiScrollBox.set_drag_cancelled(list, false)
|
|
Control.child_add(page, list)
|
|
Control.set_behave(list, UIBehave.fill)
|
|
Control.set_margin(list, 40, 0, 0, 0)
|
|
|
|
var x_image = Assets.image("assets/wip/8Cross")
|
|
|
|
_itemListItems = []
|
|
_itemEvents = MultiListenerToken.new()
|
|
adventure.on_change(true) {|adventure|
|
|
//cleanup
|
|
_itemListItems.each{|item|
|
|
Control.destroy(item)
|
|
}
|
|
_itemListItems.clear()
|
|
_itemEvents.discard()
|
|
|
|
if(!adventure) return
|
|
|
|
//rebuild
|
|
_game.resources.list().each{ |resource|
|
|
var item = UIBox.create(_ent)
|
|
Control.set_behave(item, UIBehave.left | UIBehave.right)//|
|
|
Control.set_margin(item, 0, 0, 0, 0)
|
|
Control.set_contain(item, UIContain.row | UIContain.start)//|
|
|
Control.set_size(item, -1, 12)
|
|
UiScrollBox.add(list, item)
|
|
|
|
var name = UILabel.create(_ent)
|
|
Control.child_add(item, name)
|
|
UILabel.set_align_vertical(name, TextAlign.bottom)
|
|
UILabel.set_font(name, _ui.font)
|
|
UILabel.set_text_size(name, 8)
|
|
UILabel.set_text(name, "%(resource["name"])(%(resource["amount"]))")
|
|
Control.set_behave(name, UIBehave.hfill | UIBehave.left)//|
|
|
Control.set_margin(name, 2, 1, 0, 1)
|
|
|
|
var amount = NumberField.create(_ent)
|
|
NumberField.set_value(amount, adventure.resources.get(resource["name"]))
|
|
Control.set_margin(amount, 0, 1, 2, 1)
|
|
Control.child_add(item, amount)
|
|
//change resource data
|
|
Control.set_events(amount){|event|
|
|
if(event.type == UIEvent.change){
|
|
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, value.get(resource["base_name"]))
|
|
}
|
|
_itemEvents.add(token)
|
|
_itemListItems.add(item)
|
|
}
|
|
UI.commit(_ent)
|
|
}
|
|
}
|
|
|
|
depart(){
|
|
var page = Control.create(_ent)
|
|
Control.child_add(_root, page)
|
|
Control.set_behave(page, UIBehave.fill)
|
|
Control.set_margin(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)
|
|
Control.set_size(ready, 100, 20)
|
|
UILabel.set_align_vertical(ready, TextAlign.bottom)
|
|
UILabel.set_font(ready, _ui.font)
|
|
UILabel.set_text_size(ready, 16)
|
|
UILabel.set_text(ready, "READY?")
|
|
Control.set_behave(ready, UIBehave.left | UIBehave.top) //|
|
|
Control.set_margin(ready, 56, 8, 0, 0)
|
|
|
|
var go = UILabel.create(_ent)
|
|
Control.child_add(page, go)
|
|
Control.set_size(go, 100, 20)
|
|
UILabel.set_align_vertical(go, TextAlign.bottom)
|
|
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])
|
|
Control.set_behave(go, UIBehave.left | UIBehave.top) //|
|
|
Control.set_margin(go, 56, 24, 0, 0)
|
|
Clickable.make_clickable(go)
|
|
Clickable.set_state_change(go){ |data, button|
|
|
UILabel.set_text(go, data["hover"]?"GO!":"GO")
|
|
}
|
|
Clickable.set_on_click(go){
|
|
_game.adventures.dispatch()
|
|
}
|
|
}
|
|
|
|
abort(){
|
|
var page = Control.create(_ent)
|
|
Control.child_add(_root, page)
|
|
Control.set_behave(page, UIBehave.fill)
|
|
Control.set_margin(page, 0, 0, 0, 16)
|
|
_page.on_change(true){|val|
|
|
Control.set_visible(page, val == UiAdventure.abort)
|
|
}
|
|
|
|
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")
|
|
Control.set_behave(ready, UIBehave.left | UIBehave.top) //|
|
|
Control.set_margin(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])
|
|
Control.set_behave(abort, UIBehave.left | UIBehave.top) //|
|
|
Control.set_margin(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()
|
|
}
|
|
}
|
|
} |