-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathinit.lua
More file actions
192 lines (157 loc) · 5.09 KB
/
init.lua
File metadata and controls
192 lines (157 loc) · 5.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
grenades = {
grenade_deaccel = 8
}
local cooldowns = {}
function grenades.throw_grenade(name, startspeed, player)
local dir = player:get_look_dir()
local pos = vector.offset(player:get_pos(), 0, player:get_properties().eye_height, 0)
local obj = minetest.add_entity(pos, name)
if not obj then
return
end
obj:set_velocity(vector.add(vector.multiply(dir, startspeed), player:get_velocity()))
obj:set_acceleration({x = 0, y = -9.8, z = 0})
local data = obj:get_luaentity()
data.thrower_name = player:get_player_name()
return data
end
function grenades.register_grenade(name, def)
if not def.clock then
def.clock = 4
end
local grenade_entity = {
initial_properties = {
physical = true,
sliding = 1,
collide_with_objects = def.collide_with_objects or false,
visual = "sprite",
visual_size = {x = 0.5, y = 0.5, z = 0.5},
textures = {def.image},
collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2},
pointable = false,
static_save = false,
},
particle = 0,
timer = 0,
on_step = function(self, dtime, moveresult)
local obj = self.object
local vel = obj:get_velocity()
local pos = obj:get_pos()
local norm_vel -- Normalized velocity
self.timer = self.timer + dtime
if not self.last_vel then
self.last_vel = vel
end
-- Check for a collision on the x/y/z axis
if moveresult.collides and moveresult.collisions then
if def.on_collide then
local c_result = def:on_collide(obj, self.thrower_name, moveresult)
if c_result == true then
if self.thrower_name then
minetest.log("action", "[Grenades] A grenade thrown by " .. self.thrower_name ..
" explodes at " .. minetest.pos_to_string(vector.round(pos)))
def:on_explode(obj, pos, self.thrower_name)
end
obj:remove()
elseif c_result == false then
vel = vector.new()
self.last_vel = vector.new()
obj:set_velocity(vector.new())
obj:set_acceleration(vector.new(0, 0, 0))
end
else
if moveresult.collisions[1] and moveresult.collisions[1].axis then
local axis = moveresult.collisions[1].axis
vel[axis] = self.last_vel[axis] * -0.3
end
end
obj:set_velocity(vel)
end
self.last_vel = vel
norm_vel = vector.normalize(vel)
if not vector.equals(vel, vector.new()) then
obj:set_acceleration({
x = -norm_vel.x * grenades.grenade_deaccel * (moveresult.touching_ground and 2 or 1),
y = -9.8,
z = -norm_vel.z * grenades.grenade_deaccel * (moveresult.touching_ground and 2 or 1),
})
end
if moveresult.touching_ground then -- Is the grenade sliding?
-- If grenade is barely moving, make sure it stays that way
if vector.distance(vector.new(), vel) <= 2 and not vector.equals(vel, vector.new()) then
obj:set_velocity(vector.new())
obj:set_acceleration(vector.new(0, -9.8, 0))
end
end
-- Grenade Particles
if def.particle and self.particle >= def.particle.interval then
self.particle = 0
minetest.add_particle({
pos = obj:get_pos(),
velocity = vector.divide(vel, 2),
acceleration = vector.divide(obj:get_acceleration() or vector.new(1, 1, 1), -5),
expirationtime = def.particle.life,
size = def.particle.size,
collisiondetection = false,
collision_removal = false,
vertical = false,
texture = def.particle.image,
glow = def.particle.glow
})
elseif def.particle and self.particle < def.particle.interval then
self.particle = self.particle + dtime
end
-- Explode when clock is up
if self.timer > def.clock or not self.thrower_name then
if self.thrower_name then
minetest.log("action", "[Grenades] A grenade thrown by " .. self.thrower_name ..
" explodes at " .. minetest.pos_to_string(vector.round(pos)))
def:on_explode(obj, pos, self.thrower_name)
end
obj:remove()
end
end
}
minetest.register_entity(name, grenade_entity)
local newdef = {grenade = def}
newdef.description = def.description
newdef.stack_max = math.max(1, def.stack_max or 1)
newdef.inventory_image = def.image
newdef.touch_interaction = "short_dig_long_place" -- throw with short tap
local on_use = function(itemstack, user, pointed_thing)
grenades.throw_grenade(name, 17, user)
if not minetest.settings:get_bool("creative_mode") and (def.stack_max or 99) > -1 then
itemstack:take_item(1)
end
return itemstack
end
if def.throw_cooldown then
newdef.on_use = function(itemstack, user, ...)
local uname = user:get_player_name()
if cooldowns[uname] then
return
else
cooldowns[uname] = true
minetest.after(def.throw_cooldown, function() cooldowns[uname] = nil end)
end
return on_use(itemstack, user, ...)
end
else
newdef.on_use = on_use
end
if def.placeable == true then
newdef.tiles = {def.image}
newdef.selection_box = {
type = "fixed",
fixed = {-0.3, -0.5, -0.3, 0.3, 0.4, 0.3},
}
newdef.groups = {oddly_breakable_by_hand = 2}
newdef.paramtype = "light"
newdef.sunlight_propagates = true
newdef.walkable = false
newdef.drawtype = "plantlike"
minetest.register_node(name, newdef)
else
minetest.register_craftitem(name, newdef)
end
end