diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..94f480d --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d9dc9db --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +*/.DS_Store +.DS_Store +.DS_Store? +*/thumbs.db +thumbs.db +.thumbs.db? +.luxe/ +_luxe.data/ +_luxe.deploy/ +log.txt \ No newline at end of file diff --git a/assets/system/first_person_player.modifier.api.wren b/assets/system/first_person_player.modifier.api.wren new file mode 100644 index 0000000..9c05c5f --- /dev/null +++ b/assets/system/first_person_player.modifier.api.wren @@ -0,0 +1,105 @@ + +class Modifier { + static id : String { "fpkit: system/first_person_player.modifier" } + static system(world: World) : System { World.get_system(world, Modifier.id) } + static get(entity: Entity) : Data { Mod.get(entity, Modifier.id) } + construct new(world: World) { + _world = world + _block = World.get_modifier_block(_world, Modifier.id) + } + world : World { _world } + attached_count : Num { Block.count(_block) } + + init(world: World) : None {} + pre(entity: Entity, data) : None {} + attach(entity: Entity, data) : None {} + detach(entity: Entity, data) : None {} + change(entity: Entity, change: ModifierChange) : None {} + tick(delta: Num) : None {} + + internal_tick(delta: Num) : None { + } + + editor_init(world: World) : None {} + editor_pre(entity: Entity, data) : None {} + editor_attach(entity: Entity, data) : None {} + editor_detach(entity: Entity, data) : None {} + editor_change(entity: Entity, change: ModifierChange) : None {} + + editor_tick(delta: Num) : None {} + + get(entity: Entity) : Data { Mod.get(entity, Modifier.id) } + each(fn: Fn) { + var count = attached_count + for(idx in 0 ... count) { + var inst = Block.get_at(_block, idx) + var data = Block.instance(_block, inst) + var entity = Block.get_handle(_block, inst, HandleTag.entity) + fn.call(entity, data) + } + } + each(start: Num, count: Num, fn: Fn) { + for(idx in start ... start + count) { + var inst = Block.get_at(_block, idx) + var data = Block.instance(_block, inst) + var entity = Block.get_handle(_block, inst, HandleTag.entity) + fn.call(entity, data) + } + } +} + +class API { + static id { Modifier.id } + static create(entity: Entity) { Mod.create(Modifier.id, entity) } + static has(entity: Entity) { Mod.has(Modifier.id, entity) } + static destroy(entity: Entity) { Mod.destroy(Modifier.id, entity) } + static get(entity: Entity) : Data { Mod.get(entity, Modifier.id) } + static system_in(world: World) : System { World.get_system(world, Modifier.id) } + static system(entity: Entity) : System { World.get_system(Entity.get_world(entity), Modifier.id) } + static count(world: World) : Num { system_in(world).attached_count } + static each(world: World, fn: Fn) : System { system_in(world).each(fn) } + static get : APIGet { APIGetter } + static set : APISet { APISetter } + static connect : APIWireConnect { APIWireConnects } + static send : APIWireSend { APIWireSends } +} + +class Fields { +} + +import "luxe: world/states" for AState, States, Op +#doc="The base class for a state, and our API for accessing it" +class State is AState { + construct create(in_name: String, in_parent: State) { super(in_name, in_parent) } + goto_on(entity: Entity, state: State, wire: Num) { this.goto_on(entity, state, This, wire) } +} + +class APIWireSend { + construct new() {} +} + +class APIWireConnect { + construct new() {} +} + +class APIGet { + construct new() {} +} + +class APISet { + construct new() {} +} + +var APIGetter = APIGet.new() +var APISetter = APISet.new() +var APIWireSends = APIWireSend.new() +var APIWireConnects = APIWireConnect.new() + +import "fpkit: system/first_person_player.modifier" for Data, System +import "luxe: world/world" for World, Wire +import "luxe: world" for Entity +import "luxe: world/modifier" for Modifier as Mod, ModifierChange +import "luxe: blocks" for Block +import "luxe: io" for HandleTag + + diff --git a/assets/system/first_person_player.modifier.api.wren.meta.lx b/assets/system/first_person_player.modifier.api.wren.meta.lx new file mode 100644 index 0000000..04f078b --- /dev/null +++ b/assets/system/first_person_player.modifier.api.wren.meta.lx @@ -0,0 +1,2 @@ +tags = [] +uuid = "a6edbb1f-6920-484a-9f7f-82485d7054f9" diff --git a/assets/system/first_person_player.modifier.wren b/assets/system/first_person_player.modifier.wren new file mode 100644 index 0000000..788edde --- /dev/null +++ b/assets/system/first_person_player.modifier.wren @@ -0,0 +1,88 @@ +import "fpkit: system/first_person_player.modifier.api" for API, Modifier, APIGet, APISet, Wire, Fields, State, Op +import "luxe: io" for IO +import "luxe: assets" for Strings +import "luxe: world" for Entity, World, Transform +import "luxe.project/asset" for Asset +import "luxe: math" for Math +import "luxe: system/physics/physics3D.modifier" for Phyiscs3D +import "luxe: system/physics/character3D.modifier" for Character3D + +#block = data +class Data { + var camera: Link + + var acceleration: Num = 0.6 + var decelleration: Num = 0.6 + var ground_check_dist: Num = 0.15 + + var jump_impulse: Num = 2.25 + var jump_force: Num = 1.0 + var jump_force_falloff: Num = 0.3 + + #hidden + var is_grounded: Bool = false + + #hidden + var target_input: Float3 = [0, 0, 0] +} + +#api +#display = "First-Person Player" +#desc = "**A new modifier**. You should update this description" +#icon = "luxe: image/modifier/modifier.svg" +class FirstPersonPlayer is API { + //add public facing API here +} + +#system +#phase(on, tick) +class System is Modifier { + + //required atm + construct new(world: World) { super(world) } + + init(world: World) { + _world = world + Log.print("init `%(This)` in world `%(world)`") + Physics3D.create_in(world) + } + + #hidden + attach(entity: Entity, data: Data) { + Log.print("attached to `%(Strings.get(Entity.get_name(entity)))` `%(entity)` - `%(This)`") + + if (data.camera == null) { + data.camera = Entity.get_named(world, "app.camera") + } + } + + #hidden + tick(delta: Num) { + var fore = Input.event_active("up", "game") ? -1 : 0 + var back = Input.event_active("down", "game") ? 1 : 0 + var left = Input.event_active("left", "game") ? -1 : 0 + var right = Input.event_active("right", "game") ? 1 : 0 + + each {|entity: Entity, data: Data| + if (data.camera == null) return + if (!Character3D.has(entity)) return + + target_input = Transform.local_vector_to_world(data.camera, right + left, 0, fore + back) + target_input.y = 0 + Math.normalize(target_input) + target_input.y = Input.event_began("jump", "game") && data.is_grounded ? data.jump_impulse : 0 + + Character3D.set.input(entity, input) + } + } + + check_if_grounded(player: Entity, data: Data): Bool { + var half_height: Num = Character3D.get.height(player) * 0.5 + var padding: Num = Character3D.get.character_padding(player) + var dist = half_height + padding + data.ground_check_dist + + var result = Physics3D.cast_ray_closest(_world, Transform.get_pos_world(player), [0,-1,0], dist) + + return result != null + } +} \ No newline at end of file diff --git a/assets/system/first_person_player.modifier.wren.meta.lx b/assets/system/first_person_player.modifier.wren.meta.lx new file mode 100644 index 0000000..ab9ccd2 --- /dev/null +++ b/assets/system/first_person_player.modifier.wren.meta.lx @@ -0,0 +1,2 @@ +tags = [] +uuid = "ca5d1912-99bd-483c-8bc2-f76151287ffb" diff --git a/assets/system/firstpersonplayer.modifier.wren.meta.lx b/assets/system/firstpersonplayer.modifier.wren.meta.lx new file mode 100644 index 0000000..d88201d --- /dev/null +++ b/assets/system/firstpersonplayer.modifier.wren.meta.lx @@ -0,0 +1,2 @@ +tags = [] +uuid = "d23d2a2e-e607-495b-81c6-a0413bbc9ca8" diff --git a/assets/system/folder.meta.lx b/assets/system/folder.meta.lx new file mode 100644 index 0000000..58326a6 --- /dev/null +++ b/assets/system/folder.meta.lx @@ -0,0 +1,2 @@ +tags = [] +uuid = "42ef825b-1c30-4b91-b9fc-a4f2796c3241" diff --git a/module.lx b/module.lx new file mode 100644 index 0000000..9711077 --- /dev/null +++ b/module.lx @@ -0,0 +1,4 @@ +description = "Provides a first-person controller ready to rock." +name = "fpkit" +owner = "Brody Brooks +version = "0.0.1"