11local Event = require ' utils.event'
22local Global = require ' utils.global'
33local math = require ' utils.math'
4+ local Token = require ' utils.token'
5+ local Task = require ' utils.task'
46
57local floor = math.floor
68local max = math.max
79
810local chest = defines .inventory .chest
11+ local stun_sticker_duration = 3 -- seconds
912
1013local died_entities = {}
1114
@@ -18,89 +21,162 @@ Global.register(
1821
1922local Public = {}
2023
24+ local cause_by_type = {
25+ [' character' ] = function (cause )
26+ return cause .player
27+ end ,
28+ [' car' ] = function (cause )
29+ local d = cause .get_driver ()
30+ if d then
31+ return (d .object_name == ' LuaEntity' ) and d .player or d
32+ else
33+ return cause .last_user
34+ end
35+ end ,
36+ [' spider-vehicle' ] = function (cause )
37+ local d = cause .get_driver ()
38+ if d then
39+ return (d .object_name == ' LuaEntity' ) and d .player or d
40+ else
41+ return cause .last_user
42+ end
43+ end ,
44+ [' land-mine' ] = function (cause )
45+ return cause .last_user
46+ end ,
47+ }
48+
49+ local stun_player_callback
50+ stun_player_callback = Token .register (function (data )
51+ local entity = data .entity
52+ if not entity .valid then
53+ return
54+ end
55+
56+ local time_to_live = data .time_to_live
57+ if time_to_live <= 0 then
58+ return
59+ end
60+
61+ data .time_to_live = time_to_live - stun_sticker_duration
62+ entity .surface .create_entity {
63+ name = ' stun-sticker' ,
64+ target = entity ,
65+ position = entity .position ,
66+ }
67+ Task .set_timeout (stun_sticker_duration , stun_player_callback , data )
68+ end )
69+
70+ --- @param config table
71+ --- @field entity_name ? string , resource to be spawned (default : coal )
72+ --- @field time_penalty ? number , time lost by the player when misbehaving (default : 18s , 0 to apply none )
73+ --- @field spare_vehicle ? boolean , saves the involved vehicle , if any (default : false )
2174Public .register = function (config )
2275 local entity_name = config .entity_name or ' coal'
23- Event .add (
24- defines .events .on_entity_died ,
25- function (event )
26- local entity = event .entity
76+ local time_penalty = config .time_penalty or 18
77+ local spare_vehicle = config .spare_vehicle or false
2778
28- if not entity .valid then
29- return
30- end
79+ Event .add (defines .events .on_entity_died , function (event )
80+ local entity = event .entity
3181
32- local type = entity .type
33- if type ~= ' container' and type ~= ' logistic-container' then
34- return
35- end
82+ if not entity .valid then
83+ return
84+ end
3685
37- local inventory = entity .get_inventory ( chest )
38- if not inventory or not inventory . valid then
39- return
40- end
86+ local type = entity .type
87+ if type ~= ' container ' and type ~= ' logistic-container ' then
88+ return
89+ end
4190
42- local count = 0
43- local deadlock_stack_size = (settings .startup [' deadlock-stack-size' ] or {}).value or 1
44- local contents = inventory .get_contents ()
45- for _ , item_stack in pairs (contents ) do
46- local real_count
47- if item_stack .name :sub (1 , # ' deadlock-stack' ) == ' deadlock-stack' then
48- real_count = item_stack .count * deadlock_stack_size
49- else
50- real_count = item_stack .count
51- end
52-
53- count = count + real_count
54- end
91+ local inventory = entity .get_inventory (chest )
92+ if not inventory or not inventory .valid then
93+ return
94+ end
5595
56- if count == 0 then
57- return
96+ local count = 0
97+ local deadlock_stack_size = (settings .startup [' deadlock-stack-size' ] or {}).value or 1
98+ local contents = inventory .get_contents ()
99+ for _ , item_stack in pairs (contents ) do
100+ local real_count
101+ if item_stack .name :sub (1 , # ' deadlock-stack' ) == ' deadlock-stack' then
102+ real_count = item_stack .count * deadlock_stack_size
103+ else
104+ real_count = item_stack .count
58105 end
59106
60- local area = entity .bounding_box
61- local left_top , right_bottom = area .left_top , area .right_bottom
62- local x1 , y1 = floor (left_top .x ), floor (left_top .y )
63- local x2 , y2 = floor (right_bottom .x ), floor (right_bottom .y )
107+ count = count + real_count
108+ end
109+
110+ if count == 0 then
111+ return
112+ end
113+
114+ local area = entity .bounding_box
115+ local left_top , right_bottom = area .left_top , area .right_bottom
116+ local x1 , y1 = floor (left_top .x ), floor (left_top .y )
117+ local x2 , y2 = floor (right_bottom .x ), floor (right_bottom .y )
64118
65- local size_x = x2 - x1 + 1
66- local size_y = y2 - y1 + 1
67- local amount = floor (count / (size_x * size_y ))
68- amount = max (amount , 1 )
119+ local size_x = x2 - x1 + 1
120+ local size_y = y2 - y1 + 1
121+ local amount = floor (count / (size_x * size_y ))
122+ amount = max (amount , 1 )
69123
70- local create_entity = entity .surface .create_entity
124+ local create_entity = entity .surface .create_entity
71125
72- for x = x1 , x2 do
73- for y = y1 , y2 do
74- create_entity ({name = entity_name , position = {x , y }, amount = amount })
75- end
126+ for x = x1 , x2 do
127+ for y = y1 , y2 do
128+ create_entity ({name = entity_name , position = {x , y }, amount = amount })
76129 end
130+ end
77131
78- died_entities [entity .unit_number ] = true
132+ died_entities [entity .unit_number ] = true
133+
134+ local cause = event .cause
135+ if not (cause and cause .valid and cause .force and cause .force .name == ' player' ) then
136+ return
79137 end
80- )
81-
82- Event .add (
83- defines .events .on_post_entity_died ,
84- function (event )
85- local unit_number = event .unit_number
86- if not unit_number then
87- return
88- end
89138
90- if not died_entities [unit_number ] then
91- return
92- end
139+ local handler = cause_by_type [cause .type ]
140+ local actor = handler and handler (cause )
141+ if not (actor and actor .valid ) then
142+ return
143+ end
93144
94- died_entities [unit_number ] = nil
145+ local character = actor .character
146+ if not (character and character .valid ) then
147+ return
148+ end
95149
96- local ghost = event .ghost
97- if not ghost or not ghost .valid then
98- return
99- end
150+ actor .print (' The ore fights back!' , { color = { 255 , 128 , 0 } })
151+ Task .set_timeout_in_ticks (1 , stun_player_callback , {
152+ entity = character ,
153+ time_to_live = time_penalty ,
154+ })
100155
101- ghost .destroy ()
156+ if (not spare_vehicle ) and (cause .type == ' car' or cause .type == ' spider-vehicle' ) then
157+ cause .die (' neutral' )
102158 end
103- )
159+ end )
160+
161+ Event .add (defines .events .on_post_entity_died , function (event )
162+ local unit_number = event .unit_number
163+ if not unit_number then
164+ return
165+ end
166+
167+ if not died_entities [unit_number ] then
168+ return
169+ end
170+
171+ died_entities [unit_number ] = nil
172+
173+ local ghost = event .ghost
174+ if not ghost or not ghost .valid then
175+ return
176+ end
177+
178+ ghost .destroy ()
179+ end )
104180end
105181
106182return Public
0 commit comments