--- /dev/null
+local placed_crystal
+local switched_to_totem = 0
+local used_sneak = true
+
+core.register_globalstep(function(dtime)
+ if not minetest.settings:get_bool("crystal_pvp") then return end
+ local player = core.localplayer
+ if not player then return end
+ local control = player:get_control()
+ local pointed = core.get_pointed_thing()
+ local item = player:get_wielded_item():get_name()
+ if placed_crystal then
+ if core.switch_to_item("mobs_mc:totem") then
+ switched_to_totem = 5
+ end
+ placed_crystal = false
+ elseif switched_to_totem > 0 then
+ if item ~= "mobs_mc:totem" then
+ switched_to_totem = 0
+ elseif pointed and pointed.type == "object" then
+ pointed.ref:punch()
+ switched_to_totem = 0
+ else
+ switched_to_totem = switched_to_totem
+ end
+ elseif control.RMB and item == "mcl_end:crystal" then
+ placed_crystal = true
+ elseif control.sneak then
+ if used_sneak then
+ core.switch_to_item("mobs_mc:totem")
+ return
+ end
+ core.switch_to_item("mcl_end:crystal")
+ if pointed and pointed.type == "node" then
+ local pos = core.get_pointed_thing_position(pointed)
+ local node = core.get_node_or_nil(pos)
+ if node and (node.name == "mcl_core:obsidian" or node.name == "mcl_core:bedrock") then
+ core.place_node(pos)
+ placed_crystal = true
+ end
+ end
+ used_sneak = true
+ else
+ used_sneak = false
+ end
+end)
+
["AntiKnockback"] = "antiknockback",
["FastHit"] = "spamclick",
["AttachmentFloat"] = "float_above_parent",
+ ["CrystalPvP"] = "crystal_pvp",
},
["Movement"] = {
["Freecam"] = "freecam",
local cheatpath = core.get_builtin_path() .. "client" .. DIR_DELIM .. "cheats" .. DIR_DELIM
dofile(cheatpath .. "chat.lua")
+dofile(cheatpath .. "combat.lua")
dofile(cheatpath .. "inventory.lua")
dofile(cheatpath .. "movement.lua")
dofile(cheatpath .. "player.lua")
if success then pos = vector.round(vector.add(core.localplayer:get_pos(), pos)) end
return success, pos
end
+
+function core.switch_to_item(item)
+ for index, stack in ipairs(core.get_inventory("current_player").main) do
+ if stack:get_name() == item then
+ core.localplayer:set_wield_index(index - 1)
+ return true
+ end
+ end
+ return false
+end
+
+function core.get_pointed_thing()
+ local pos = core.camera:get_pos()
+ local pos2 = vector.add(pos, vector.multiply(core.camera:get_look_dir(), 5))
+ local ray = core.raycast(pos, pos2, true, true)
+
+ return ray:next()
+end
return function(str, ...) return core.translate(textdomain or "", str, ...) end
end
+function core.get_pointed_thing_position(pointed_thing, above)
+ if pointed_thing.type == "node" then
+ if above then
+ -- The position where a node would be placed
+ return pointed_thing.above
+ end
+ -- The position where a node would be dug
+ return pointed_thing.under
+ elseif pointed_thing.type == "object" then
+ return pointed_thing.ref and pointed_thing.ref:get_pos()
+ end
+end
+
--------------------------------------------------------------------------------
-- Returns the exact coordinate of a pointed surface
--------------------------------------------------------------------------------
.. "{" .. img3:gsub("%^", "&")
end
-function core.get_pointed_thing_position(pointed_thing, above)
- if pointed_thing.type == "node" then
- if above then
- -- The position where a node would be placed
- return pointed_thing.above
- end
- -- The position where a node would be dug
- return pointed_thing.under
- elseif pointed_thing.type == "object" then
- return pointed_thing.ref and pointed_thing.ref:get_pos()
- end
-end
-
function core.dir_to_facedir(dir, is6d)
--account for y if requested
if is6d and math.abs(dir.y) > math.abs(dir.x) and math.abs(dir.y) > math.abs(dir.z) then
autotnt (PlaceOnTop) bool false
replace (Replace) bool false
+
+crystal_pvp (CrystalPvP) bool false
### pointed_thing
* `{type="nothing"}`
* `{type="node", under=pos, above=pos}`
-* `{type="object", id=ObjectID}`
+* `{type="object", ref=ClientObjectRef}`
Flag Specifier Format
---------------------
* `pos2`: end of the ray
* `objects`: if false, only nodes will be returned. Default is `true`.
* `liquids`: if false, liquid nodes won't be returned. Default is `false`.
+* `minetest.get_pointed_thing()` returns `PointedThing`
+ * Returns the thing currently pointed by player
+* `minetest.get_pointed_thing_position(pointed_thing, above)`
+ * Returns the position of a `pointed_thing` or `nil` if the `pointed_thing`
+ does not refer to a node or entity.
+ * If the optional `above` parameter is true and the `pointed_thing` refers
+ to a node, then it will return the `above` position of the `pointed_thing`.
* `minetest.find_path(pos1,pos2,searchdistance,max_jump,max_drop,algorithm)`
* returns table containing path that can be walked on
* returns a table of 3D points representing a path from `pos1` to `pos2` or
### Client Environment
* `minetest.get_player_names()`
* Returns list of player names on server (nil if CSM_RF_READ_PLAYERINFO is enabled by server)
+* `minetest.get_objects_inside_radius(pos, radius)`: returns a list of
+ ClientObjectRefs.
+ * `radius`: using an euclidean metric
* `minetest.disconnect()`
* Disconnect from the server and exit to main menu.
* Returns `false` if the client is already disconnecting otherwise returns `true`.
* e.g. minetest.set_keypress("jump", true) will cause te player to jump until minetest.set_keypress("jump", false) is called or the player presses & releases the space bar himself
* `minetest.get_inventory(location)`
* Returns the inventory at location
+* `minetest.switch_to_item(item)`
+ * `item` is an Itemstring
+ * searches to item in inventory, sets the wield index to it if found
+ * returns true on success, false if item was not found
* `minetest.register_cheat(name, category, setting | function)`
* Register an entry for the cheat menu
* If the Category is nonexistant, it will be created
* `fields`: key-value storage
* `inventory`: `{list1 = {}, ...}}`
+### ClientObjectRef
+
+Moving things in the game are generally these.
+This is basically a reference to a C++ `GenericCAO`.
+
+#### Methods
+
+* `get_pos()`: returns `{x=num, y=num, z=num}`
+* `get_velocity()`: returns the velocity, a vector
+* `get_acceleration()`: returns the acceleration, a vector
+* `get_rotation()`: returns the rotation, a vector (radians)
+* `is_player()`: returns true if the object is a player
+* `get_attach()`: returns parent or nil if it isn't attached.
+* `get_nametag()`: returns the nametag (string)
+* `get_item_textures()`: returns the textures
+* `get_max_hp()`: returns the maximum heath
+* `punch()`: punches the object
+* `rightclick()`: rightclicks the object
+
### `Raycast`
A raycast on the map. It works with selection boxes.
settings->setDefault("block_water", "false");
settings->setDefault("autotnt", "false");
settings->setDefault("replace", "false");
+ settings->setDefault("crystal_pvp", "false");
// Keymap
settings->setDefault("remote_port", "30000");
#include "object_properties.h"
#include "collision.h"
#include "cpp_api/s_node.h"
+#include "lua_api/l_clientobject.h"
#include "lua_api/l_object.h"
#include "lua_api/l_item.h"
#include "common/c_internal.h"
lua_setfield(L, -2, "type");
if (csm) {
- lua_pushinteger(L, pointed.object_id);
- lua_setfield(L, -2, "id");
+ ClientObjectRef::create(L, pointed.object_id);
} else {
push_objectRef(L, pointed.object_id);
- lua_setfield(L, -2, "ref");
}
+
+ lua_setfield(L, -2, "ref");
} else {
lua_pushstring(L, "nothing");
lua_setfield(L, -2, "type");
#include "common/c_converter.h"
#include "client/client.h"
#include "object_properties.h"
+#include "util/pointedthing.h"
ClientObjectRef *ClientObjectRef::checkobject(lua_State *L, int narg)
{
return 1;
}
+int ClientObjectRef::l_punch(lua_State *L)
+{
+ ClientObjectRef *ref = checkobject(L, 1);
+ GenericCAO *gcao = get_generic_cao(ref, L);
+ PointedThing pointed(gcao->getId(), v3f(0,0,0), v3s16(0,0,0), 0);
+ getClient(L)->interact(INTERACT_START_DIGGING, pointed);
+ return 0;
+}
+
+int ClientObjectRef::l_rightclick(lua_State *L)
+{
+ ClientObjectRef *ref = checkobject(L, 1);
+ GenericCAO *gcao = get_generic_cao(ref, L);
+ PointedThing pointed(gcao->getId(), v3f(0,0,0), v3s16(0,0,0), 0);
+ getClient(L)->interact(INTERACT_PLACE, pointed);
+ return 0;
+}
+
ClientObjectRef::ClientObjectRef(ClientActiveObject *object) : m_object(object)
{
}
}
}
+void ClientObjectRef::create(lua_State *L, s16 id)
+{
+ create(L, ((ClientEnvironment *)getEnv(L))->getActiveObject(id));
+}
+
int ClientObjectRef::gc_object(lua_State *L)
{
ClientObjectRef *obj = *(ClientObjectRef **)(lua_touserdata(L, 1));
luamethod(ClientObjectRef, get_attach),
luamethod(ClientObjectRef, get_nametag),
luamethod(ClientObjectRef, get_item_textures),
- luamethod(ClientObjectRef, get_max_hp), {0, 0}};
+ luamethod(ClientObjectRef, get_max_hp),
+ luamethod(ClientObjectRef, punch),
+ luamethod(ClientObjectRef, rightclick), {0, 0}};
static void Register(lua_State *L);
static void create(lua_State *L, ClientActiveObject *object);
+ static void create(lua_State *L, s16 id);
static ClientObjectRef *checkobject(lua_State *L, int narg);
// get_hp(self)
static int l_get_max_hp(lua_State *L);
+
+ // punch(self)
+ static int l_punch(lua_State *L);
+
+ // rightclick(self)
+ static int l_rightclick(lua_State *L);
};