Skip to content

Commit 4cebffc

Browse files
committed
Replace kill mechanic with stun mechanic
1 parent 5e92acf commit 4cebffc

1 file changed

Lines changed: 108 additions & 78 deletions

File tree

Lines changed: 108 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
local Event = require 'utils.event'
22
local Global = require 'utils.global'
33
local math = require 'utils.math'
4+
local Token = require 'utils.token'
5+
local Task = require 'utils.task'
46

57
local floor = math.floor
68
local max = math.max
79

810
local chest = defines.inventory.chest
11+
local stun_sticker_duration = 3 -- seconds
912

1013
local died_entities = {}
1114

@@ -43,108 +46,135 @@ local cause_by_type = {
4346
end,
4447
}
4548

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)
4673
Public.register = function(config)
4774
local entity_name = config.entity_name or 'coal'
48-
Event.add(
49-
defines.events.on_entity_died,
50-
function(event)
51-
local entity = event.entity
75+
local time_penalty = config.time_penalty or 18
5276

53-
if not entity.valid then
54-
return
55-
end
77+
Event.add(defines.events.on_entity_died, function(event)
78+
local entity = event.entity
5679

57-
local type = entity.type
58-
if type ~= 'container' and type ~= 'logistic-container' then
59-
return
60-
end
80+
if not entity.valid then
81+
return
82+
end
6183

62-
local inventory = entity.get_inventory(chest)
63-
if not inventory or not inventory.valid then
64-
return
65-
end
84+
local type = entity.type
85+
if type ~= 'container' and type ~= 'logistic-container' then
86+
return
87+
end
6688

67-
local count = 0
68-
local deadlock_stack_size = (settings.startup['deadlock-stack-size'] or {}).value or 1
69-
local contents = inventory.get_contents()
70-
for _, item_stack in pairs(contents) do
71-
local real_count
72-
if item_stack.name:sub(1, #'deadlock-stack') == 'deadlock-stack' then
73-
real_count = item_stack.count * deadlock_stack_size
74-
else
75-
real_count = item_stack.count
76-
end
77-
78-
count = count + real_count
79-
end
89+
local inventory = entity.get_inventory(chest)
90+
if not inventory or not inventory.valid then
91+
return
92+
end
8093

81-
if count == 0 then
82-
return
94+
local count = 0
95+
local deadlock_stack_size = (settings.startup['deadlock-stack-size'] or {}).value or 1
96+
local contents = inventory.get_contents()
97+
for _, item_stack in pairs(contents) do
98+
local real_count
99+
if item_stack.name:sub(1, #'deadlock-stack') == 'deadlock-stack' then
100+
real_count = item_stack.count * deadlock_stack_size
101+
else
102+
real_count = item_stack.count
83103
end
84104

85-
local area = entity.bounding_box
86-
local left_top, right_bottom = area.left_top, area.right_bottom
87-
local x1, y1 = floor(left_top.x), floor(left_top.y)
88-
local x2, y2 = floor(right_bottom.x), floor(right_bottom.y)
105+
count = count + real_count
106+
end
89107

90-
local size_x = x2 - x1 + 1
91-
local size_y = y2 - y1 + 1
92-
local amount = floor(count / (size_x * size_y))
93-
amount = max(amount, 1)
108+
if count == 0 then
109+
return
110+
end
94111

95-
local create_entity = entity.surface.create_entity
112+
local area = entity.bounding_box
113+
local left_top, right_bottom = area.left_top, area.right_bottom
114+
local x1, y1 = floor(left_top.x), floor(left_top.y)
115+
local x2, y2 = floor(right_bottom.x), floor(right_bottom.y)
96116

97-
for x = x1, x2 do
98-
for y = y1, y2 do
99-
create_entity({name = entity_name, position = {x, y}, amount = amount})
100-
end
101-
end
117+
local size_x = x2 - x1 + 1
118+
local size_y = y2 - y1 + 1
119+
local amount = floor(count / (size_x * size_y))
120+
amount = max(amount, 1)
102121

103-
died_entities[entity.unit_number] = true
122+
local create_entity = entity.surface.create_entity
104123

105-
local cause = event.cause
106-
if not (cause and cause.valid and cause.force and cause.force.name == 'player') then
107-
return
124+
for x = x1, x2 do
125+
for y = y1, y2 do
126+
create_entity({name = entity_name, position = {x, y}, amount = amount})
108127
end
128+
end
109129

110-
local handler = cause_by_type[cause.type]
111-
local actor = handler and handler(cause)
112-
if not (actor and actor.valid) then
113-
return
114-
end
130+
died_entities[entity.unit_number] = true
115131

116-
local character = actor.character
117-
if not (character and character.valid) then
118-
return
119-
end
132+
local cause = event.cause
133+
if not (cause and cause.valid and cause.force and cause.force.name == 'player') then
134+
return
135+
end
120136

121-
actor.print('The ore fights back!', { color = { 255, 128, 0 } })
122-
character.die(game.forces.neutral)
137+
local handler = cause_by_type[cause.type]
138+
local actor = handler and handler(cause)
139+
if not (actor and actor.valid) then
140+
return
123141
end
124-
)
125-
126-
Event.add(
127-
defines.events.on_post_entity_died,
128-
function(event)
129-
local unit_number = event.unit_number
130-
if not unit_number then
131-
return
132-
end
133142

134-
if not died_entities[unit_number] then
135-
return
136-
end
143+
local character = actor.character
144+
if not (character and character.valid) then
145+
return
146+
end
137147

138-
died_entities[unit_number] = nil
148+
actor.print('The ore fights back!', { color = { 255, 128, 0 } })
149+
Task.set_timeout_in_ticks(1, stun_player_callback, {
150+
entity = character,
151+
time_to_live = time_penalty,
152+
})
139153

140-
local ghost = event.ghost
141-
if not ghost or not ghost.valid then
142-
return
143-
end
154+
if cause.type == 'car' or cause.type == 'spider-vehicle' then
155+
cause.die('neutral')
156+
end
157+
end)
158+
159+
Event.add(defines.events.on_post_entity_died, function(event)
160+
local unit_number = event.unit_number
161+
if not unit_number then
162+
return
163+
end
144164

145-
ghost.destroy()
165+
if not died_entities[unit_number] then
166+
return
146167
end
147-
)
168+
169+
died_entities[unit_number] = nil
170+
171+
local ghost = event.ghost
172+
if not ghost or not ghost.valid then
173+
return
174+
end
175+
176+
ghost.destroy()
177+
end)
148178
end
149179

150180
return Public

0 commit comments

Comments
 (0)