import "luxe: io" for IO import "luxe: world" for World, Entity, Modifiers, ModifierSystem, Transform import "random" for Random import "luxe: draw" for Draw, PathStyle import "luxe: math" for Math import "luxe: color" for Color import "luxe: render" for Render import "util" for Util import "modifiers/circle/circle.modifier" for ModifierData as CircleData import "luxe: world" for Block //User facing API //This is what the user of your modifier will interact with class Circle { static create(entity) { Modifiers.create(This, entity) } static destroy(entity) { Modifiers.destroy(This, entity) } static has(entity) { Modifiers.has(This, entity) } static set_radius(entity, radius) { var data = Modifiers.get(This, entity) data.radius = radius } static get_radius(entity) { var data = Modifiers.get(This, entity) return data.radius } } //Circle //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 CircleSystem is ModifierSystem { construct new() { _rng = Random.new() //setup draw styles _circle_style = PathStyle.new() _circle_style.color = Color.white _circle_style.thickness = 1 _intersection_style = PathStyle.new() _intersection_style.color = Color.hex(0xFFFF99) _intersection_style.thickness = 2 } init(world) { _world = world _draw = Draw.create(World.render_set(world)) } destroy() { Draw.destroy(_draw) } attach(entity, data) { //called when attached to an entity } detach(entity, data) { //called when detached from an entity, like on destroy } tick(delta) { //called usually once every frame. //called when the world that this modifier lives in, is ticked //draw each circle each{|entity: Entity, data: CircleData| var pos = Transform.get_pos(entity) Draw.ring(_draw, pos.x, pos.y, pos.z, data.radius, data.radius, 0, 360, 8, _circle_style) } //then do intersections between all circle pairs for(i in 0...count){ //get data of 1st entity var slot_1 = Block.get_slot_at(data.block, i) var entity_1 = Block.get_handle(data.block, slot_1) var radius_1 = data[slot_1, true].radius //its important to get out the radius here because data always gives out the same reference if(!Entity.valid(entity_1)) continue var pos_1 = Transform.get_pos(entity_1) for(ii in 0...i){ //get data of second entity var slot_2 = Block.get_slot_at(data.block, ii) var entity_2 = Block.get_handle(data.block, slot_2) var radius_2 = data[slot_2, true].radius if(!Entity.valid(entity_2)) continue var pos_2 = Transform.get_pos(entity_2) var intersections = Util.circle_intersect_circle(pos_1, radius_1, pos_2, radius_2) if(intersections){ //and if we found any, draw them Draw.line(_draw, intersections[0].x, intersections[0].y, intersections[1].x, intersections[1].y, 0, _intersection_style) Draw.circle(_draw, intersections[0].x, intersections[0].y, 0, 8, 8, [1, 1, 1, 0.2]) Draw.circle(_draw, intersections[1].x, intersections[1].y, 0, 8, 8, [1, 1, 1, 0.2]) Draw.circle(_draw, intersections[0].x, intersections[0].y, 0, 3, 3, [1, 1, 1, 1]) Draw.circle(_draw, intersections[1].x, intersections[1].y, 0, 3, 3, [1, 1, 1, 1]) } } } Draw.commit(_draw) } //tick } //CircleSystem var Modifier = CircleSystem //required