z_mirror/MouseOverConstruction
git clone https://git.raiguard.me/z_mirror/MouseOverConstruction
2af5331
trunk
1--- @param box1 BoundingBox 2--- @param box2 BoundingBox 3local function bounding_boxes_equal ( box1 , box2 ) 4return box1 . left_top . x == box2 . left_top . x 5and box1 . left_top . y == box2 . left_top . y 6and box1 . right_bottom . x == box2 . right_bottom . x 7and box1 . right_bottom . y == box2 . right_bottom . y 8end 9 10--- @param entity LuaEntity 11--- @return string 12local function get_useful_type ( entity ) 13if entity . type == "entity-ghost" then 14return entity . ghost_type 15end 16return entity . type 17end 18 19--- @class common 20local common ={} 21 22--- Builds an entity over the top of an existing entity. 23--- @param player LuaPlayer 24--- @param entity LuaEntity 25--- @param new_prototype LuaEntityPrototype 26--- @param new_quality LuaQualityPrototype 27--- @return LuaEntity? 28function common . build ( player , entity , new_prototype , new_quality ) 29local item , consume_count =common . get_item ( player , new_prototype , new_quality ) 30if not item then 31return nil 32end 33 34local bounding_box =entity . bounding_box 35local surface =entity . surface 36local position =entity . position 37local direction =entity . direction 38local quality =entity . quality 39local force =entity . force 40 41local new_entity =surface . create_entity ( { 42name =new_prototype . name , 43position =position , 44direction =direction , 45quality =new_quality , 46force =force , 47fast_replace =true , 48player =player , 49character =player . character , 50raise_built =true , 51create_build_effect_smoke =true , 52spawn_decorations =true , 53move_stuck_players =true , 54item =item , 55register_plant =true , 56mirror =entity . mirroring , 57-- Undergound belt 58type =get_useful_type ( entity ) == "underground-belt" and entity . belt_to_ground_type or nil , 59} ) 60if not new_entity or not new_entity . valid then 61-- Some mods will immediately replace the entity with a different one. Let's see if we can detect this. 62for _ , replaced_entity in 63pairs ( surface . find_entities_filtered ( { 64direction =direction , 65position =position , 66quality =quality . name , 67force =force , 68} )) 69do 70if 71replaced_entity . type ~= "entity-ghost" 72and replaced_entity . type ~= "tile-ghost" 73and bounding_boxes_equal ( replaced_entity . bounding_box , bounding_box ) 74then 75new_entity =replaced_entity 76break 77else 78return 79end 80end 81end 82 83if not new_entity or not new_entity . valid then 84return 85end 86 87item . count =item . count - consume_count 88 89local stats =force . get_entity_build_count_statistics ( surface ) 90stats . on_flow ( new_entity , 1 ) 91 92player . play_sound ( { 93path ="entity-build/" .. new_entity . name , 94position =new_entity . position , 95} ) 96 97return new_entity 98end 99 100--- @param player LuaPlayer 101--- @param entity LuaEntity 102--- @param new_prototype LuaEntityPrototype 103--- @return boolean 104function common . check_can_place_entity ( player , entity , new_prototype ) 105if 106not player . can_place_entity ( { 107name =new_prototype . name , 108position =entity . position , 109direction =entity . direction , 110} ) 111then 112storage . recheck_on_move [ player . index ] =true 113return false 114end 115return true 116end 117 118--- Returns the first LuaItemStack that can build the given entity and quality. 119--- @param player LuaPlayer 120--- @param prototype LuaEntityPrototype 121--- @param quality LuaQualityPrototype 122--- @return LuaItemStack?, uint? 123function common . get_item ( player , prototype , quality ) 124local cursor_stack =player . cursor_stack 125local inventory =player . get_main_inventory () 126for _ , item_to_place in pairs ( prototype . items_to_place_this or {} ) do 127if 128cursor_stack 129and cursor_stack . valid_for_read 130and cursor_stack . name == item_to_place . name 131and cursor_stack . quality == quality 132and cursor_stack . count >= item_to_place . count 133then 134return cursor_stack , item_to_place . count 135end 136if inventory then 137local item =inventory . find_item_stack ( { name =item_to_place . name , quality =quality . name } ) 138if item and item . count >= item_to_place . count then 139return item , item_to_place . count 140end 141end 142end 143end 144 145return common