aboutsummaryrefslogtreecommitdiff
path: root/src/script/lua_api/l_object.h
blob: 9801ce02b3b5c2c7b7a839d741bba5f57d840dd6 (plain)
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef L_OBJECT_H_
#define L_OBJECT_H_

#include "lua_api/l_base.h"
#include "irrlichttypes.h"

class ServerActiveObject;
class LuaEntitySAO;
class PlayerSAO;
class RemotePlayer;

/*
	ObjectRef
*/

class ObjectRef : public ModApiBase {
private:
	ServerActiveObject *m_object;

	static const char className[];
	static const luaL_Reg methods[];
public:
	static ObjectRef *checkobject(lua_State *L, int narg);

	static ServerActiveObject* getobject(ObjectRef *ref);
private:
	static LuaEntitySAO* getluaobject(ObjectRef *ref);

	static PlayerSAO* getplayersao(ObjectRef *ref);

	static RemotePlayer *getplayer(ObjectRef *ref);

	// Exported functions

	// garbage collector
	static int gc_object(lua_State *L);

	// remove(self)
	static int l_remove(lua_State *L);

	// get_pos(self)
	// returns: {x=num, y=num, z=num}
	static int l_get_pos(lua_State *L);

	// set_pos(self, pos)
	static int l_set_pos(lua_State *L);

	// move_to(self, pos, continuous=false)
	static int l_move_to(lua_State *L);

	// punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
	static int l_punch(lua_State *L);

	// right_click(self, clicker); clicker = an another ObjectRef
	static int l_right_click(lua_State *L);

	// set_hp(self, hp)
	// hp = number of hitpoints (2 * number of hearts)
	// returns: nil
	static int l_set_hp(lua_State *L);

	// get_hp(self)
	// returns: number of hitpoints (2 * number of hearts)
	// 0 if not applicable to this type of object
	static int l_get_hp(lua_State *L);

	// get_inventory(self)
	static int l_get_inventory(lua_State *L);

	// get_wield_list(self)
	static int l_get_wield_list(lua_State *L);

	// get_wield_index(self)
	static int l_get_wield_index(lua_State *L);

	// get_wielded_item(self)
	static int l_get_wielded_item(lua_State *L);

	// set_wielded_item(self, itemstack or itemstring or table or nil)
	static int l_set_wielded_item(lua_State *L);

	// set_armor_groups(self, groups)
	static int l_set_armor_groups(lua_State *L);

	// get_armor_groups(self)
	static int l_get_armor_groups(lua_State *L);

	// set_physics_override(self, physics_override_speed, physics_override_jump,
	//                      physics_override_gravity, sneak, sneak_glitch, new_move)
	static int l_set_physics_override(lua_State *L);

	// get_physics_override(self)
	static int l_get_physics_override(lua_State *L);

	// set_animation(self, frame_range, frame_speed, frame_blend, frame_loop)
	static int l_set_animation(lua_State *L);

	// get_animation(self)
	static int l_get_animation(lua_State *L);

	// set_bone_position(self, std::string bone, v3f position, v3f rotation)
	static int l_set_bone_position(lua_State *L);

	// get_bone_position(self, bone)
	static int l_get_bone_position(lua_State *L);

	// set_attach(self, parent, bone, position, rotation)
	static int l_set_attach(lua_State *L);

	// get_attach(self)
	static int l_get_attach(lua_State *L);

	// set_detach(self)
	static int l_set_detach(lua_State *L);

	// set_properties(self, properties)
	static int l_set_properties(lua_State *L);

	// get_properties(self)
	static int l_get_properties(lua_State *L);

	// is_player(self)
	static int l_is_player(lua_State *L);

	/* LuaEntitySAO-only */

	// set_velocity(self, {x=num, y=num, z=num})
	static int l_set_velocity(lua_State *L);

	// get_velocity(self)
	static int l_get_velocity(lua_State *L);

	// set_acceleration(self, {x=num, y=num, z=num})
	static int l_set_acceleration(lua_State *L);

	// get_acceleration(self)
	static int l_get_acceleration(lua_State *L);

	// set_yaw(self, radians)
	static int l_set_yaw(lua_State *L);

	// get_yaw(self)
	static int l_get_yaw(lua_State *L);

	// set_texture_mod(self, mod)
	static int l_set_texture_mod(lua_State *L);

	// l_get_texture_mod(self)
	static int l_get_texture_mod(lua_State *L);

	// set_sprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
	//           select_horiz_by_yawpitch=false)
	static int l_set_sprite(lua_State *L);

	// DEPRECATED
	// get_entity_name(self)
	static int l_get_entity_name(lua_State *L);

	// get_luaentity(self)
	static int l_get_luaentity(lua_State *L);

	/* Player-only */

	// is_player_connected(self)
	static int l_is_player_connected(lua_State *L);

	// get_player_name(self)
	static int l_get_player_name(lua_State *L);

	// get_player_velocity(self)
	static int l_get_player_velocity(lua_State *L);

	// get_look_dir(self)
	static int l_get_look_dir(lua_State *L);

	// DEPRECATED
	// get_look_pitch(self)
	static int l_get_look_pitch(lua_State *L);

	// DEPRECATED
	// get_look_yaw(self)
	static int l_get_look_yaw(lua_State *L);

	// get_look_pitch2(self)
	static int l_get_look_vertical(lua_State *L);

	// get_look_yaw2(self)
	static int l_get_look_horizontal(lua_State *L);

	// set_look_vertical(self, radians)
	static int l_set_look_vertical(lua_State *L);

	// set_look_horizontal(self, radians)
	static int l_set_look_horizontal(lua_State *L);

	// DEPRECATED
	// set_look_pitch(self, radians)
	static int l_set_look_pitch(lua_State *L);

	// DEPRECATED
	// set_look_yaw(self, radians)
	static int l_set_look_yaw(lua_State *L);

	// set_breath(self, breath)
	static int l_set_breath(lua_State *L);

	// get_breath(self, breath)
	static int l_get_breath(lua_State *L);

	// set_attribute(self, attribute, value)
	static int l_set_attribute(lua_State *L);

	// get_attribute(self, attribute)
	static int l_get_attribute(lua_State *L);

	// set_inventory_formspec(self, formspec)
	static int l_set_inventory_formspec(lua_State *L);

	// get_inventory_formspec(self) -> formspec
	static int l_get_inventory_formspec(lua_State *L);

	// get_player_control(self)
	static int l_get_player_control(lua_State *L);

	// get_player_control_bits(self)
	static int l_get_player_control_bits(lua_State *L);

	// hud_add(self, id, form)
	static int l_hud_add(lua_State *L);

	// hud_rm(self, id)
	static int l_hud_remove(lua_State *L);

	// hud_change(self, id, stat, data)
	static int l_hud_change(lua_State *L);

	// hud_get_next_id(self)
	static u32 hud_get_next_id(lua_State *L);

	// hud_get(self, id)
	static int l_hud_get(lua_State *L);

	// hud_set_flags(self, flags)
	static int l_hud_set_flags(lua_State *L);

	// hud_get_flags()
	static int l_hud_get_flags(lua_State *L);

	// hud_set_hotbar_itemcount(self, hotbar_itemcount)
	static int l_hud_set_hotbar_itemcount(lua_State *L);

	// hud_get_hotbar_itemcount(self)
	static int l_hud_get_hotbar_itemcount(lua_State *L);

	// hud_set_hotbar_image(self, name)
	static int l_hud_set_hotbar_image(lua_State *L);

	// hud_get_hotbar_image(self)
	static int l_hud_get_hotbar_image(lua_State *L);

	// hud_set_hotbar_selected_image(self, name)
	static int l_hud_set_hotbar_selected_image(lua_State *L);

	// hud_get_hotbar_selected_image(self)
	static int l_hud_get_hotbar_selected_image(lua_State *L);

	// set_sky(self, bgcolor, type, list, clouds = true)
	static int l_set_sky(lua_State *L);

	// get_sky(self)
	static int l_get_sky(lua_State *L);

	// set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=})
	static int l_set_clouds(lua_State *L);

	// get_clouds(self)
	static int l_get_clouds(lua_State *L);

	// override_day_night_ratio(self, type)
	static int l_override_day_night_ratio(lua_State *L);

	// get_day_night_ratio(self)
	static int l_get_day_night_ratio(lua_State *L);

	// set_local_animation(self, {stand/idle}, {walk}, {dig}, {walk+dig}, frame_speed)
	static int l_set_local_animation(lua_State *L);

	// get_local_animation(self)
	static int l_get_local_animation(lua_State *L);

	// set_eye_offset(self, v3f first pv, v3f third pv)
	static int l_set_eye_offset(lua_State *L);

	// get_eye_offset(self)
	static int l_get_eye_offset(lua_State *L);

	// set_nametag_attributes(self, attributes)
	static int l_set_nametag_attributes(lua_State *L);

	// get_nametag_attributes(self)
	static int l_get_nametag_attributes(lua_State *L);

public:
	ObjectRef(ServerActiveObject *object);

	~ObjectRef();

	// Creates an ObjectRef and leaves it on top of stack
	// Not callable from Lua; all references are created on the C side.
	static void create(lua_State *L, ServerActiveObject *object);

	static void set_null(lua_State *L);

	static void Register(lua_State *L);
};

#endif /* L_OBJECT_H_ */
kwd">getVolume() != 0) result.push_back(b); return; } assert(contains(a)); // Take back area, XY inclusive { v3s16 min(MinEdge.X, MinEdge.Y, a.MaxEdge.Z+1); v3s16 max(MaxEdge.X, MaxEdge.Y, MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take front area, XY inclusive { v3s16 min(MinEdge.X, MinEdge.Y, MinEdge.Z); v3s16 max(MaxEdge.X, MaxEdge.Y, a.MinEdge.Z-1); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take top area, X inclusive { v3s16 min(MinEdge.X, a.MaxEdge.Y+1, a.MinEdge.Z); v3s16 max(MaxEdge.X, MaxEdge.Y, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take bottom area, X inclusive { v3s16 min(MinEdge.X, MinEdge.Y, a.MinEdge.Z); v3s16 max(MaxEdge.X, a.MinEdge.Y-1, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take left area, non-inclusive { v3s16 min(MinEdge.X, a.MinEdge.Y, a.MinEdge.Z); v3s16 max(a.MinEdge.X-1, a.MaxEdge.Y, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take right area, non-inclusive { v3s16 min(a.MaxEdge.X+1, a.MinEdge.Y, a.MinEdge.Z); v3s16 max(MaxEdge.X, a.MaxEdge.Y, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } } /* Translates position from virtual coordinates to array index */ s32 index(s16 x, s16 y, s16 z) const { v3s16 em = getExtent(); v3s16 off = MinEdge; s32 i = (s32)(z-off.Z)*em.Y*em.X + (y-off.Y)*em.X + (x-off.X); //dstream<<" i("<<x<<","<<y<<","<<z<<")="<<i<<" "; return i; } s32 index(v3s16 p) const { return index(p.X, p.Y, p.Z); } // Translate index in the X coordinate void add_x(const v3s16 &extent, u32 &i, s16 a) { i += a; } // Translate index in the Y coordinate void add_y(const v3s16 &extent, u32 &i, s16 a) { i += a * extent.X; } // Translate index in the Z coordinate void add_z(const v3s16 &extent, u32 &i, s16 a) { i += a * extent.X*extent.Y; } // Translate index in space void add_p(const v3s16 &extent, u32 &i, v3s16 a) { i += a.Z*extent.X*extent.Y + a.Y*extent.X + a.X; } /* Print method for debugging */ void print(std::ostream &o) const { v3s16 e = getExtent(); o<<"("<<MinEdge.X <<","<<MinEdge.Y <<","<<MinEdge.Z <<")("<<MaxEdge.X <<","<<MaxEdge.Y <<","<<MaxEdge.Z <<")" <<"="<<e.X<<"x"<<e.Y<<"x"<<e.Z<<"="<<getVolume(); } // Edges are inclusive v3s16 MinEdge; v3s16 MaxEdge; }; // Hasn't been copied from source (emerged) #define VOXELFLAG_NOT_LOADED (1<<0) // Checked as being inexistent in source #define VOXELFLAG_INEXISTENT (1<<1) // Algorithm-dependent #define VOXELFLAG_CHECKED1 (1<<2) // Algorithm-dependent #define VOXELFLAG_CHECKED2 (1<<3) // Algorithm-dependent #define VOXELFLAG_CHECKED3 (1<<4) // Algorithm-dependent #define VOXELFLAG_CHECKED4 (1<<5) enum VoxelPrintMode { VOXELPRINT_NOTHING, VOXELPRINT_MATERIAL, VOXELPRINT_WATERPRESSURE, }; class VoxelManipulator /*: public NodeContainer*/ { public: VoxelManipulator(); virtual ~VoxelManipulator(); /* Virtuals from NodeContainer */ /*virtual u16 nodeContainerId() const { return NODECONTAINER_ID_VOXELMANIPULATOR; } bool isValidPosition(v3s16 p) { emerge(p); return !(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT); }*/ /* These are a bit slow and shouldn't be used internally. Use m_data[m_area.index(p)] instead. */ MapNode getNode(v3s16 p) { emerge(p); if(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT) { dstream<<"EXCEPT: VoxelManipulator::getNode(): " <<"p=("<<p.X<<","<<p.Y<<","<<p.Z<<")" <<", index="<<m_area.index(p) <<", flags="<<(int)m_flags[m_area.index(p)] <<" is inexistent"<<std::endl; throw InvalidPositionException ("VoxelManipulator: getNode: inexistent"); } return m_data[m_area.index(p)]; } MapNode getNodeNoEx(v3s16 p) { emerge(p); if(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT) { return MapNode(CONTENT_IGNORE); } return m_data[m_area.index(p)]; } MapNode getNodeNoExNoEmerge(v3s16 p) { if(m_area.contains(p) == false) return MapNode(CONTENT_IGNORE); if(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT) return MapNode(CONTENT_IGNORE); return m_data[m_area.index(p)]; } MapNode & getNodeRef(v3s16 p) { emerge(p); if(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT) { dstream<<"EXCEPT: VoxelManipulator::getNode(): " <<"p=("<<p.X<<","<<p.Y<<","<<p.Z<<")" <<", index="<<m_area.index(p) <<", flags="<<(int)m_flags[m_area.index(p)] <<" is inexistent"<<std::endl; throw InvalidPositionException ("VoxelManipulator: getNode: inexistent"); } return m_data[m_area.index(p)]; } void setNode(v3s16 p, MapNode &n) { emerge(p); m_data[m_area.index(p)] = n; m_flags[m_area.index(p)] &= ~VOXELFLAG_INEXISTENT; m_flags[m_area.index(p)] &= ~VOXELFLAG_NOT_LOADED; } void setNodeNoRef(v3s16 p, MapNode n) { setNode(p, n); } /*void setExists(VoxelArea a) { emerge(a); for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++) for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++) for(s32 x=a.MinEdge.X; x<=a.MaxEdge.X; x++) { m_flags[m_area.index(x,y,z)] &= ~VOXELFLAG_INEXISTENT; } }*/ /*MapNode & operator[](v3s16 p) { //dstream<<"operator[] p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl; if(isValidPosition(p) == false) emerge(VoxelArea(p)); return m_data[m_area.index(p)]; }*/ /* Set stuff if available without an emerge. Return false if failed. This is convenient but slower than playing around directly with the m_data table with indices. */ bool setNodeNoEmerge(v3s16 p, MapNode n) { if(m_area.contains(p) == false) return false; m_data[m_area.index(p)] = n; return true; } bool setNodeNoEmerge(s32 i, MapNode n) { if(m_area.contains(i) == false) return false; m_data[i] = n; return true; } /*bool setContentNoEmerge(v3s16 p, u8 c) { if(isValidPosition(p) == false) return false; m_data[m_area.index(p)].d = c; }*/ /* Control */ virtual void clear(); void print(std::ostream &o, VoxelPrintMode mode=VOXELPRINT_MATERIAL); void addArea(VoxelArea area); /* Copy data and set flags to 0 dst_area.getExtent() <= src_area.getExtent() */ void copyFrom(MapNode *src, VoxelArea src_area, v3s16 from_pos, v3s16 to_pos, v3s16 size); // Copy data void copyTo(MapNode *dst, VoxelArea dst_area, v3s16 dst_pos, v3s16 from_pos, v3s16 size); /* Algorithms */ void clearFlag(u8 flag); void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight, core::map<v3s16, bool> & light_sources); void unspreadLight(enum LightBank bank, core::map<v3s16, u8> & from_nodes, core::map<v3s16, bool> & light_sources); void spreadLight(enum LightBank bank, v3s16 p); void spreadLight(enum LightBank bank, core::map<v3s16, bool> & from_nodes); /* Virtual functions */ /* Get the contents of the requested area from somewhere. Shall touch only nodes that have VOXELFLAG_NOT_LOADED Shall reset VOXELFLAG_NOT_LOADED If not found from source, add with VOXELFLAG_INEXISTENT */ virtual void emerge(VoxelArea a, s32 caller_id=-1) { //dstream<<"emerge p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl; addArea(a); for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++) for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++) for(s32 x=a.MinEdge.X; x<=a.MaxEdge.X; x++) { s32 i = m_area.index(x,y,z); // Don't touch nodes that have already been loaded if(!(m_flags[i] & VOXELFLAG_NOT_LOADED)) continue; m_flags[i] = VOXELFLAG_INEXISTENT; } } /* Member variables */ /* The area that is stored in m_data. addInternalBox should not be used if getExtent() == v3s16(0,0,0) MaxEdge is 1 higher than maximum allowed position */ VoxelArea m_area; /* NULL if data size is 0 (extent (0,0,0)) Data is stored as [z*h*w + y*h + x] */ MapNode *m_data; /* Flags of all nodes */ u8 *m_flags; //TODO: Use these or remove them //TODO: Would these make any speed improvement? //bool m_pressure_route_valid; //v3s16 m_pressure_route_surface; /* Some settings */ //bool m_disable_water_climb; private: }; #endif