z_mirror/Tapeline
git clone https://git.raiguard.me/z_mirror/Tapeline
223dcef
3.0
1local flib_bounding_box =require ( "__flib__.bounding-box" ) 2 3--- @class Tape 4--- @field anchor MapPosition 5--- @field box BoundingBox 6--- @field cursor MapPosition 7--- @field entity LuaEntity 8--- @field tick_to_die MapTick 9--- @field id integer 10--- @field player LuaPlayer 11--- @field background LuaRenderObject 12--- @field border LuaRenderObject 13--- @field label_north LuaRenderObject 14--- @field label_west LuaRenderObject 15 16--- @param player LuaPlayer 17--- @param entity LuaEntity 18--- @return Tape 19local function new_tape ( player , entity ) 20local id =storage . next_tape_id 21storage . next_tape_id =id + 1 22local box =flib_bounding_box . from_position ( entity . position , true ) 23local center =flib_bounding_box . center ( box ) 24--- @type Tape 25local self ={ 26anchor =entity . position , 27box =box , 28cursor =entity . position , 29entity =entity , 30id =id , 31player =player , 32tick_to_die =math . huge , 33background =rendering . draw_rectangle ( { 34color =player . mod_settings [ "tl-tape-background-color" ]. value --[[@as Color]] , 35filled =true , 36players ={ player } , 37surface =entity . surface , 38left_top =box . left_top , 39right_bottom =box . right_bottom , 40} ), 41border =rendering . draw_rectangle ( { 42color =player . mod_settings [ "tl-tape-border-color" ]. value --[[@as Color]] , 43filled =false , 44width =player . mod_settings [ "tl-tape-line-width" ]. value --[[@as double]] , 45players ={ player } , 46surface =entity . surface , 47left_top =box . left_top , 48right_bottom =box . right_bottom , 49} ), 50label_north =rendering . draw_text ( { 51text =flib_bounding_box . width ( box ), 52surface =entity . surface , 53target ={ x =center . x , y =box . left_top . y } , 54color =player . mod_settings [ "tl-tape-label-color" ]. value --[[@as Color]] , 55scale =2 , 56alignment ="center" , 57vertical_alignment ="bottom" , 58} ), 59label_west =rendering . draw_text ( { 60text =flib_bounding_box . height ( box ), 61surface =entity . surface , 62target ={ x =box . left_top . x , y =center . y } , 63color =player . mod_settings [ "tl-tape-label-color" ]. value --[[@as Color]] , 64scale =2 , 65alignment ="center" , 66vertical_alignment ="bottom" , 67orientation =0.75 , 68} ), 69} 70storage . tapes [ id ] =self 71return self 72end 73 74--- @param self Tape 75local function update_tape ( self ) 76self . background . left_top =self . box . left_top 77self . background . right_bottom =self . box . right_bottom 78self . border . left_top =self . box . left_top 79self . border . right_bottom =self . box . right_bottom 80local center =flib_bounding_box . center ( self . box ) 81self . label_north . target ={ x =center . x , y =self . box . left_top . y } 82self . label_north . text =flib_bounding_box . width ( self . box ) 83self . label_west . target ={ x =self . box . left_top . x , y =center . y } 84self . label_west . text =flib_bounding_box . height ( self . box ) 85end 86 87--- @param self Tape 88--- @param entity LuaEntity 89local function resize_tape ( self , entity ) 90local old =self . entity 91if old and old . valid then 92old . destroy () 93end 94self . entity =entity 95local position =entity . position 96local box =flib_bounding_box . from_position ( self . anchor , true ) 97box =flib_bounding_box . expand_to_contain_position ( box , position ) 98box =flib_bounding_box . ceil ( box ) 99self . box =box 100self . cursor =position 101update_tape ( self ) 102end 103 104--- @param self Tape 105local function destroy_tape ( self ) 106if self . background . valid then 107self . background . destroy () 108end 109if self . border . valid then 110self . border . destroy () 111end 112if self . label_north . valid then 113self . label_north . destroy () 114end 115if self . label_west . valid then 116self . label_west . destroy () 117end 118local entity =self . entity 119if entity and entity . valid then 120entity . destroy () 121end 122storage . tapes [ self . id ] =nil 123end 124 125local function on_init () 126--- @type table<uint, Tape> 127storage . drawing ={} 128storage . next_tape_id =1 129--- @type table<uint, Tape> 130storage . tapes ={} 131end 132 133--- @param e EventData.on_built_entity 134local function on_built_entity ( e ) 135local entity =e . entity 136if not entity . valid then 137return 138end 139local name =entity . name 140if name == "entity-ghost" then 141name =entity . ghost_name 142end 143if name ~= "tl-dummy-entity" then 144return 145end 146local drawing =storage . drawing [ e . player_index ] 147local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 148if drawing then 149resize_tape ( drawing , entity ) 150else 151drawing =new_tape ( player , e . entity ) 152storage . drawing [ e . player_index ] =drawing 153end 154end 155 156--- @param e EventData.on_player_selected_area|EventData.on_player_alt_selected_area 157local function on_player_selected_area ( e ) 158local tape_data =storage . drawing [ e . player_index ] 159if not tape_data then 160return 161end 162storage . drawing [ e . player_index ] =nil 163if e . name == defines . events . on_player_selected_area then 164local time_to_live =tape_data . player . mod_settings [ "tl-tape-clear-delay" ]. value --[[@as double]] 165tape_data . tick_to_die =game . tick + time_to_live * 60 166end 167storage . tapes [ tape_data . id ] =tape_data 168end 169 170--- @param e EventData.on_tick 171local function on_tick ( e ) 172for _ , tape_data in pairs ( storage . tapes or {} ) do 173if tape_data . tick_to_die > e . tick then 174goto continue 175end 176 177destroy_tape ( tape_data ) 178 179:: continue :: 180end 181end 182 183local tape ={} 184 185tape . on_init =on_init 186 187tape . events ={ 188[ defines . events . on_built_entity ] =on_built_entity , 189[ defines . events . on_player_alt_selected_area ] =on_player_selected_area , 190[ defines . events . on_player_selected_area ] =on_player_selected_area , 191[ defines . events . on_tick ] =on_tick , 192} 193 194return tape