From 42ecec5e7ffa28c3e3060a50bed3ec1b08ba2903 Mon Sep 17 00:00:00 2001 From: Ronja Date: Sat, 29 Aug 2020 21:25:16 +0200 Subject: [PATCH] utterly broken miracle build --- Luxe/assets/wip/Human.image.lx | 3 + Luxe/assets/wip/Human.png | Bin 0 -> 156 bytes Luxe/blocks/human/human.modifier.lx | 18 + Luxe/blocks/human/human.modifier.wren | 514 ++++++++++++++++++++++++++ Luxe/blocks/human/human.wren | 91 +++++ Luxe/blocks/tooltip.wren | 3 +- Luxe/blocks/ui.wren | 5 +- Luxe/game.wren | 17 +- Luxe/math/math.wren | 48 ++- Luxe/math/repNum.wren | 20 + Luxe/math/util.wren | 34 +- Luxe/math/vector.wren | 21 +- Luxe/outline/renderer.wren | 2 +- 13 files changed, 763 insertions(+), 13 deletions(-) create mode 100644 Luxe/assets/wip/Human.image.lx create mode 100644 Luxe/assets/wip/Human.png create mode 100644 Luxe/blocks/human/human.modifier.lx create mode 100644 Luxe/blocks/human/human.modifier.wren create mode 100644 Luxe/blocks/human/human.wren create mode 100644 Luxe/math/repNum.wren diff --git a/Luxe/assets/wip/Human.image.lx b/Luxe/assets/wip/Human.image.lx new file mode 100644 index 0000000..03e4942 --- /dev/null +++ b/Luxe/assets/wip/Human.image.lx @@ -0,0 +1,3 @@ +image = { + source = "assets/wip/Human.png" +} \ No newline at end of file diff --git a/Luxe/assets/wip/Human.png b/Luxe/assets/wip/Human.png new file mode 100644 index 0000000000000000000000000000000000000000..4b92d7a29f458b5bb466775600fb6feab6ff94d4 GIT binary patch literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^AT|#N8<337)>#0g7>k44ofy`glX(f`gn7C+hDc0p z4Y)0MK!KxsFW-vAFMX`S|6H7>wCrc&<4+6>%zQU~I)18Rs8~{TaCJ=Tn>D8H@h+20 zkM|a+u4{^aboQh5vZ*3(s-rv|<(?dsdq4BHr^azUQ|pY!+aq^80ouUe>FVdQ&MBb@ E0MGt8*8l(j literal 0 HcmV?d00001 diff --git a/Luxe/blocks/human/human.modifier.lx b/Luxe/blocks/human/human.modifier.lx new file mode 100644 index 0000000..dc187ed --- /dev/null +++ b/Luxe/blocks/human/human.modifier.lx @@ -0,0 +1,18 @@ +modifier = { + description = "Moves to a point in space at a constant speed." + field = "human" + display = "Human" + class = "Human" + dependency = [] + + blocks = { + data={ + fields = [ + { name="active" type="boolean" default=true } + { name="name" type="id32" default="unnamed" } + { name="color" type="float3" default=[1, 0, 0] } + ] + } + } +} + diff --git a/Luxe/blocks/human/human.modifier.wren b/Luxe/blocks/human/human.modifier.wren new file mode 100644 index 0000000..0ee07ad --- /dev/null +++ b/Luxe/blocks/human/human.modifier.wren @@ -0,0 +1,514 @@ + +//-- this file is generated! don't try editing it. + +import "luxe: io" for IO +import "luxe: bytes" for Byter, Bytes +import "luxe: world" for Block + +//`blocks/human/human > runtime` types + + class ModifierRuntime { + + construct new() { + } //new + + } //ModifierRuntime + +//`blocks/human/human > runtime` compilers + + class ModifierRuntimeCompiler { + + construct new() { + } + + bytes_count(instance) { + + var size = 4 //version + + size = size + 0 + + return size + + } //bytes_count + + validate(from_source_id, elements) { + + var fields = { + "type": false, //:luxe:internal + "uuid": false, //:luxe:internal + "luxe.self.modifier": false, //:luxe:internal + } + for(element in elements) { + var instance = element.value + for(field in instance) { + if(fields[field.key] == null) { + Fiber.abort("node `%(element.key)` in `%(from_source_id)` has extra field `%(field.key)`") + } //if not found + } //each field + for(field in fields) { + var required = field.value + if(required && instance[field.key] == null) { + Fiber.abort("node `%(element.key)` in `%(from_source_id)` is missing a required field `%(field.key)` (and the field has no default value)") + } + } //each field + } //each element + + } //validate + + write(compiler, instance, out) { + + //version + out.write_int32(0) + + return out + + } //write + + bytes_count_block() { + + return 8 + + } //bytes_count_block + + write_block(compiler, out) { + + //source id + out.write_uint32(compiler.string.hash("blocks/human/human > runtime")) + + //fields count + out.write_int32(0) + + } //write_block + + write(instance) { + + var size = bytes_count(instance) + var out = Byter.new(size+8) + + out.write_string("LUXEMRTM") + + write(instance, out) + + return out + + } //write + + } //ModifierRuntimeCompiler + +//`blocks/human/human > runtime` block types + + class BlockModifierRuntime { + + field { "human" } + source { "blocks/human/human > runtime" } + + construct new(block) { + _block = block + _inst_type = instance_type + _inst = _inst_type.new(_block, 0) + } + + construct new() { + _block = Block.create() + _inst_type = instance_type + _inst = _inst_type.new(_block, 0) + Block.set_type(_block, "blocks/human/human > runtime") + } //new + + instance_type { + + class BlockInstModifierRuntime { + slot { _slot } + entity { Block.get_handle(_block, _slot) } + block_set_slot(value) { + _slot=value + return this + } + construct new(block, slot) { + _block = block + _slot = slot + } //new + block { _block } + } //BlockInstModifierRuntime + + return BlockInstModifierRuntime + + } //instance_type + + block { _block } + count { Block.get_count(_block) } + add() { Block.add(_block) } + append(other_block) { Block.append(_block, other_block) } + each(c, fn) { + for(i in 0 ... c) { + fn.call(0, _inst.block_set_slot(i)) + } + } //each + + [slot, inst] { _inst.block_set_slot(slot) } + + [slot] { _inst_type.new(_block, slot) } + } //BlockModifierRuntime + + +//`blocks/human/human > data` types + + class ModifierData { + + construct new() { + _active = true + _name = "unnamed" + _color = [1, 0, 0] + } //new + + active { _active } + active=(vvv) { _active = vvv } + + name { _name } + name=(vvv) { _name = vvv } + + color { _color } + color=(vvv) { _color = vvv } + + } //ModifierData + +//`blocks/human/human > data` compilers + + class ModifierDataCompiler { + + construct new() { + } + + bytes_count(instance) { + + var size = 4 //version + + size = size + 4 // active + + size = size + 4 // name + + size = size + 12 // color + + size = size + 0 + + return size + + } //bytes_count + + validate(from_source_id, elements) { + + var fields = { + "type": false, //:luxe:internal + "uuid": false, //:luxe:internal + "luxe.self.modifier": false, //:luxe:internal + "active": false, + "name": false, + "color": false, + } + for(element in elements) { + var instance = element.value + for(field in instance) { + if(fields[field.key] == null) { + Fiber.abort("node `%(element.key)` in `%(from_source_id)` has extra field `%(field.key)`") + } //if not found + } //each field + for(field in fields) { + var required = field.value + if(required && instance[field.key] == null) { + Fiber.abort("node `%(element.key)` in `%(from_source_id)` is missing a required field `%(field.key)` (and the field has no default value)") + } + } //each field + } //each element + + } //validate + + write(compiler, instance, out) { + + //version + out.write_int32(0) + + var active = instance["active"] + if(active == null) active = true + out.write_int32(active ? 1 : 0) + + + var name = instance["name"] + if(name == null) name = "unnamed" + out.write_uint32((name && name != "") ? compiler.string.hash(name) : 0) + + + var color = instance["color"] + if(color == null) color = [1, 0, 0] + out.write_float32(color[0]) + out.write_float32(color[1]) + out.write_float32(color[2]) + + + return out + + } //write + + bytes_count_block() { + + return 52 + + } //bytes_count_block + + write_block(compiler, out) { + + //source id + out.write_uint32(compiler.string.hash("blocks/human/human > data")) + + //fields count + out.write_int32(3) + + // active + out.write_uint32(compiler.string.hash("active")) + out.write_uint32(1710517951) //type boolean + var active_default = true + out.write_int32(active_default ? 1 : 0) + + + // name + out.write_uint32(compiler.string.hash("name")) + out.write_uint32(2729592961) //type id32 + var name_default = "unnamed" + out.write_uint32((name_default && name_default != "") ? compiler.string.hash(name_default) : 0) + + + // color + out.write_uint32(compiler.string.hash("color")) + out.write_uint32(1025475970) //type float3 + var color_default = [1, 0, 0] + out.write_float32(color_default[0]) + out.write_float32(color_default[1]) + out.write_float32(color_default[2]) + + + } //write_block + + write(instance) { + + var size = bytes_count(instance) + var out = Byter.new(size+8) + + out.write_string("LUXEMDTA") + + write(instance, out) + + return out + + } //write + + } //ModifierDataCompiler + +//`blocks/human/human > data` block types + + class BlockModifierData { + + field { "human" } + source { "blocks/human/human > data" } + + construct new(block) { + _block = block + _inst_type = instance_type + _inst = _inst_type.new(_block, 0) + } + + construct new() { + _block = Block.create() + _inst_type = instance_type + _inst = _inst_type.new(_block, 0) + Block.add(_block, "active", "boolean", true) + Block.add(_block, "name", "id32", "unnamed") + Block.add(_block, "color", "float3", [1, 0, 0]) + Block.set_type(_block, "blocks/human/human > data") + } //new + + instance_type { + + class BlockInstModifierData { + active { Block.get(_block, "active", _slot) } + active=(v) { Block.set(_block, "active", _slot, v) } + name { Block.get(_block, "name", _slot) } + name=(v) { Block.set(_block, "name", _slot, v) } + color { Block.get(_block, "color", _slot) } + color=(v) { Block.set(_block, "color", _slot, v) } + slot { _slot } + entity { Block.get_handle(_block, _slot) } + block_set_slot(value) { + _slot=value + return this + } + construct new(block, slot) { + _block = block + _slot = slot + } //new + block { _block } + } //BlockInstModifierData + + return BlockInstModifierData + + } //instance_type + + block { _block } + count { Block.get_count(_block) } + add() { Block.add(_block) } + append(other_block) { Block.append(_block, other_block) } + each(c, fn) { + for(i in 0 ... c) { + fn.call(0, _inst.block_set_slot(i)) + } + } //each + + [slot, inst] { _inst.block_set_slot(slot) } + + [slot] { _inst_type.new(_block, slot) } + } //BlockModifierData + + +//`blocks/human/human > world` types + + class ModifierWorld { + + construct new() { + } //new + + } //ModifierWorld + +//`blocks/human/human > world` compilers + + class ModifierWorldCompiler { + + construct new() { + } + + bytes_count(instance) { + + var size = 4 //version + + size = size + 0 + + return size + + } //bytes_count + + validate(from_source_id, elements) { + + var fields = { + "type": false, //:luxe:internal + "uuid": false, //:luxe:internal + "luxe.self.modifier": false, //:luxe:internal + } + for(element in elements) { + var instance = element.value + for(field in instance) { + if(fields[field.key] == null) { + Fiber.abort("node `%(element.key)` in `%(from_source_id)` has extra field `%(field.key)`") + } //if not found + } //each field + for(field in fields) { + var required = field.value + if(required && instance[field.key] == null) { + Fiber.abort("node `%(element.key)` in `%(from_source_id)` is missing a required field `%(field.key)` (and the field has no default value)") + } + } //each field + } //each element + + } //validate + + write(compiler, instance, out) { + + //version + out.write_int32(0) + + return out + + } //write + + bytes_count_block() { + + return 8 + + } //bytes_count_block + + write_block(compiler, out) { + + //source id + out.write_uint32(compiler.string.hash("blocks/human/human > world")) + + //fields count + out.write_int32(0) + + } //write_block + + write(instance) { + + var size = bytes_count(instance) + var out = Byter.new(size+8) + + out.write_string("LUXEMWLD") + + write(instance, out) + + return out + + } //write + + } //ModifierWorldCompiler + +//`blocks/human/human > world` block types + + class BlockModifierWorld { + + field { "human" } + source { "blocks/human/human > world" } + + construct new(block) { + _block = block + _inst_type = instance_type + _inst = _inst_type.new(_block, 0) + } + + construct new() { + _block = Block.create() + _inst_type = instance_type + _inst = _inst_type.new(_block, 0) + Block.set_type(_block, "blocks/human/human > world") + } //new + + instance_type { + + class BlockInstModifierWorld { + slot { _slot } + entity { Block.get_handle(_block, _slot) } + block_set_slot(value) { + _slot=value + return this + } + construct new(block, slot) { + _block = block + _slot = slot + } //new + block { _block } + } //BlockInstModifierWorld + + return BlockInstModifierWorld + + } //instance_type + + block { _block } + count { Block.get_count(_block) } + add() { Block.add(_block) } + append(other_block) { Block.append(_block, other_block) } + each(c, fn) { + for(i in 0 ... c) { + fn.call(0, _inst.block_set_slot(i)) + } + } //each + + [slot, inst] { _inst.block_set_slot(slot) } + + [slot] { _inst_type.new(_block, slot) } + } //BlockModifierWorld + diff --git a/Luxe/blocks/human/human.wren b/Luxe/blocks/human/human.wren new file mode 100644 index 0000000..8c03013 --- /dev/null +++ b/Luxe/blocks/human/human.wren @@ -0,0 +1,91 @@ +import "luxe: io" for IO +import "luxe: world" for World, Entity, Modifiers, ModifierSystem, Transform, Sprite +import "math/vector" for Vector +import "math/util" for Util + +//User facing API +//This is what the user of your modifier will interact with +class Human { + + static create(entity) { Modifiers.create(This, entity) } + static destroy(entity) { Modifiers.destroy(This, entity) } + static has(entity) { Modifiers.has(This, entity) } + + static set_color(entity, color){ + var data = Modifiers.get(This, entity) + data.color = color + if(Sprite.has(entity)){ + Sprite.set_color(entity, color.r, color.g, color.b, color.a) + } + } + +} //Human + +//Your modifier system implementation. +//This speaks to the engine and your user facing API +//to do the actual work. You'll get notified when things change +//in the world and respond to them here. +class HumanSystem is ModifierSystem { + + player_start{[26, 90]} + player_size{[10, 12]} + + construct new() { + //called when your system is first created. + } + + init(world) { + _world = world + //called when your modifier is created in a world + + _material = Util.material_from_image_path("assets/wip/Human") + } + + destroy() { + //called when your modifier is removed from a world + } + + attach(entity, data) { + //called when attached to an entity + update() + } + + detach(entity, data) { + //called when detached from an entity, like on destroy + update() + } + + tick(delta) { + //called usually once every frame. + //called when the world that this modifier lives in, is ticked + each {|entity, data| + System.print("%(Transform.get_pos(entity))") + } + } //tick + + update(){ + var i = 0 + var size = Vector.new(player_size) + var start = Vector.new(player_start) + size / 2 + each {|entity, data| + if(!data.active){ + Transform.destroy(entity) + Sprite.destroy(entity) + return + } + var pos = start + pos.x = pos.x + size.x * i + if(!Transform.has(entity)){ + Transform.create(entity) + } + if(!Sprite.has(entity)){ + Sprite.create(entity, _material, 10, 12) + Sprite.set_color(entity, data.color.r, data.color.g, data.color.b, 1) + } + Transform.set_pos(entity, pos.x, pos.y) + i = i + 1 + } + } +} //HumanSystem + +var Modifier = HumanSystem //required diff --git a/Luxe/blocks/tooltip.wren b/Luxe/blocks/tooltip.wren index f805a69..74cbe52 100644 --- a/Luxe/blocks/tooltip.wren +++ b/Luxe/blocks/tooltip.wren @@ -6,11 +6,12 @@ import "math/vector" for Vector class Tooltip{ depth{100} + color{[1, 1, 1, 1]} construct new(app){ _ent = Entity.create(app.ui) _mat_font = Assets.material("luxe: material/font") - Text.create(_ent, _mat_font, 8, "assets/fonts/BabyBlocks", [0.2, 0.01, 0.05, 1]) + Text.create(_ent, _mat_font, 8, "assets/fonts/BabyBlocks", color) Transform.create(_ent) Transform.set_pos(_ent, 64, 128, depth) diff --git a/Luxe/blocks/ui.wren b/Luxe/blocks/ui.wren index a759ea7..ee5ee30 100644 --- a/Luxe/blocks/ui.wren +++ b/Luxe/blocks/ui.wren @@ -64,11 +64,9 @@ class Ui{ UIImage.set_image(button, adventureButtons) ImageButton.set_tooltip(button, "Adventure!") ImageButton.set_tile_uv(button, tiles, [1, 0]) - ImageButton.set_state_change(button) { |data| - System.print(data) + ImageButton.set_state_change(button) { |data| if(data["press"]){ ui_mode = Ui.Planning - } } UIList.add(list, button) @@ -117,7 +115,6 @@ class Ui{ ImageButton.set_tooltip(button, "Info") ImageButton.set_tile_uv(button, tiles, [1, 0]) ImageButton.set_state_change(button) { |data| - System.print(data) if(data["press"]){ ui_mode = Ui.Info } diff --git a/Luxe/game.wren b/Luxe/game.wren index 0ce0897..407406c 100644 --- a/Luxe/game.wren +++ b/Luxe/game.wren @@ -16,10 +16,13 @@ import "math/vector" for Vector import "math/rect" for AABB import "math/util" for Util import "blocks/tooltip" for Tooltip +import "blocks/human/human" for Human +import "random" for Random class game is Game { - construct ready() { + //simple example... in theory (should print `0, 1, a` and `1, 2, b` cause thats the union) + //Util.for_all([[0, 1, 2], [1, 2], ["a", "b", "c", "d"]]){|a, b, c|System.print("%(a), %(b), %(c)")} Globals["Game"] = this @@ -73,6 +76,18 @@ class game is Game { var material = Util.material_from_image_path("assets/wip/Room") Sprite.create(bg, material, 128, 128) + + create_human() + create_human() + } + + create_human(){ + var human = Entity.create(app.world, "human") + var humanMat = Util.material_from_image_path("assets/wip/Human") + Human.create(human) + System.print(Util.hsv(Random.new().float(), 1, 1)) + //var rand = Random.new().float() + //Human.set_color(human, Util.hsv(rand, 1, 1)) } app { _app } diff --git a/Luxe/math/math.wren b/Luxe/math/math.wren index 192cb46..8cbbe3f 100644 --- a/Luxe/math/math.wren +++ b/Luxe/math/math.wren @@ -1,5 +1,7 @@ - - +import "math/vector" for Vector +import "luxe: math" for Math +import "math/repNum" for RepNum +import "math/Util" for Util class M{ static inv_lerp(from, to, inter){ @@ -7,11 +9,51 @@ class M{ } static lerp(from, to, value){ - return from + value * (to - from) + if(from is Num && to is Num) return from + (to - from) * value + if(from is Sequence != to is Sequence) { + if(from is Sequence){ + to = RepNum.new(to, from.count) + } else { + from = RepNum.new(from, to.count) + } + } + if(value is Num) value = RepNum.new(value) + + System.print("%(from.toList) %(to.toList)") + + var result = [] + Util.for_all([from, to, value]) { |from, to, value| + System.print(from) + result.add(lerp(from, to, value)) + } + return result } static remap(min_in, max_in, min_out, max_out, value){ var inter = inv_lerp(min_in, max_in, value) return lerp(min_out, max_out, inter) } + + static clamp(value, min, max){ + //if its a simple number, we assume so are the bounds + if(value is Num){ + return Math.max(Math.min(value, max), min) + } + + //otherwise we assume its a sequence + //if bounds are numbers, just use them + if(min is Num && max is Num){ + return value.map {|val| clamp(val, min, max)}.toList + } + if(min is Sequence && max is Sequence){ + var result = [] + Util.for_all([value, min, max]) { |value, min, max| + result.add(clamp(value, min, max)) + } + return result + } + + System.print("can't clamp %(value.type) between %(min.type) and %(max.type)") + return null + } } \ No newline at end of file diff --git a/Luxe/math/repNum.wren b/Luxe/math/repNum.wren new file mode 100644 index 0000000..b9fc316 --- /dev/null +++ b/Luxe/math/repNum.wren @@ -0,0 +1,20 @@ + +class RepNum is Sequence{ + static new(value){ + return new(value, -1) + } + + construct new(value, count){ + _value = value + _count = count + } + + iterate(iter){ + if(_count < 0) return true + if(!iter) return 0 + if(iter >= _count) return null + return iter + 1 + } + + iteratorValue(iter){_value} +} \ No newline at end of file diff --git a/Luxe/math/util.wren b/Luxe/math/util.wren index 0b33410..00fcee2 100644 --- a/Luxe/math/util.wren +++ b/Luxe/math/util.wren @@ -1,9 +1,11 @@ import "luxe: assets" for Assets import "luxe: render" for Material +import "math/math" for M +import "math/Vector" for Vector class Util{ static material_from_image_path(path){ - var image = Assets.image("assets/wip/Room") + var image = Assets.image(path) return material_from_image(image) } @@ -18,4 +20,34 @@ class Util{ to[i] = from[i] } } + + static for_all(sequences, fn){ + var count = sequences.count + var counter = (0...count) + var iterators = List.filled(count, null) + counter.each{|i| iterators[i] = sequences[i].iterate(iterators[i])} + while(iterators.all{|iter| iter}){ + var values = (0...count).map{|i| sequences[i].iteratorValue(iterators[i])} + fn.call(values) + counter.each{|i| iterators[i] = sequences[i].iterate(iterators[i])} + } + } + + //hue value saturation to rgb colors. all values in 0-1 range + static hsv(h, s, v){ + //hue to rgb + h = h % 1 + var col = [ + (h * 6 - 3).abs - 1, + 2 - (h * 6 - 2).abs, + 2 - (h * 6 - 4).abs + ] + col = M.clamp(col, 0, 1) + //then add saturation + col = M.lerp(1, col, s) + //and value + col = col.map{|comp| comp * v} + + return col.toList + [1] //poor womans add + } } \ No newline at end of file diff --git a/Luxe/math/vector.wren b/Luxe/math/vector.wren index 4c29e49..25037ea 100644 --- a/Luxe/math/vector.wren +++ b/Luxe/math/vector.wren @@ -1,6 +1,6 @@ -class Vector { +class Vector is Sequence{ x{_x} x=(val){_x = val} @@ -44,7 +44,7 @@ class Vector { _y = -_y return this } - + static or_lt(one, other){ return one.x < other.x || one.y < other.y } @@ -62,6 +62,23 @@ class Vector { _x = 0 return this } + + iterate(iter){ + if(!iter) return 0 + if(iter > 1) return null + return iter + 1 + } + + iteratorValue(iter){[iter]} + + [index]{ + if(index == 0){ + return x + } else if(index == 1){ + return y + } + return null + } +(other){ if(other is Num) { diff --git a/Luxe/outline/renderer.wren b/Luxe/outline/renderer.wren index c6e1251..4fef171 100644 --- a/Luxe/outline/renderer.wren +++ b/Luxe/outline/renderer.wren @@ -149,7 +149,7 @@ class Renderer { clear(ctx){ var layer = RenderLayerDesc.new() layer.dest.color[0].render_target = target - layer.dest.color[0].clear_color = [1,1,1,1] + layer.dest.color[0].clear_color = [0,0,0,1] layer.dest.color[0].load_action = LoadAction.clear layer.dest.depth.load_action = LoadAction.clear