mirror of
https://github.com/minetest/minetest.git
synced 2024-09-12 00:26:50 +02:00
Players are more like objects + related stuff
This commit is contained in:
parent
ee0d3bacbc
commit
af32240545
@ -7,13 +7,32 @@
|
||||
-- name "foomod", a texture could be called "foomod_superfurnace.png"
|
||||
-- Due to historical reasons, the default mod does not follow this rule.
|
||||
--
|
||||
-- MapNode representation:
|
||||
-- {name="name", param1=num, param2=num}
|
||||
--
|
||||
-- Position representation:
|
||||
-- {x=num, y=num, z=num}
|
||||
--
|
||||
-- stackstring/itemstring: A stack of items in serialized format.
|
||||
-- eg. 'NodeItem "dirt" 5'
|
||||
-- eg. 'ToolItem "WPick" 21323'
|
||||
-- eg. 'CraftItem "apple" 2'
|
||||
--
|
||||
-- item: A single item in Lua table format.
|
||||
-- eg. {type="NodeItem", name="dirt"}
|
||||
-- ^ a single dirt node
|
||||
-- eg. {type="ToolItem", name="WPick", wear=21323}
|
||||
-- ^ a wooden pick about 1/3 weared out
|
||||
-- eg. {type="CraftItem", name="apple"}
|
||||
-- ^ an apple.
|
||||
--
|
||||
-- Global functions:
|
||||
-- minetest.register_entity(name, prototype_table)
|
||||
-- minetest.register_tool(name, {lots of stuff})
|
||||
-- minetest.register_node(name, {lots of stuff})
|
||||
-- minetest.register_craftitem(name, {lots of stuff})
|
||||
-- minetest.register_craft({output=item, recipe={...})
|
||||
-- minetest.register_globalstep(func)
|
||||
-- minetest.register_entity(name, prototype table)
|
||||
-- minetest.register_tool(name, tool definition)
|
||||
-- minetest.register_node(name, node definition)
|
||||
-- minetest.register_craftitem(name, craftitem definition)
|
||||
-- minetest.register_craft(recipe)
|
||||
-- minetest.register_globalstep(func(dtime))
|
||||
-- minetest.register_on_placenode(func(pos, newnode, placer))
|
||||
-- minetest.register_on_dignode(func(pos, oldnode, digger))
|
||||
-- minetest.register_on_punchnode(func(pos, node, puncher))
|
||||
@ -22,11 +41,14 @@
|
||||
-- minetest.register_on_respawnplayer(func(ObjectRef))
|
||||
-- ^ return true in func to disable regular player placement
|
||||
-- minetest.register_on_chat_message(func(name, message))
|
||||
-- minetest.setting_get(name)
|
||||
-- minetest.setting_getbool(name)
|
||||
-- minetest.setting_get(name) -> string or nil
|
||||
-- minetest.setting_getbool(name) -> boolean value or nil
|
||||
-- minetest.chat_send_all(text)
|
||||
-- minetest.chat_send_player(name, text)
|
||||
-- minetest.get_player_privs(name)
|
||||
-- minetest.get_player_privs(name) -> set of privs
|
||||
-- stackstring_take_item(stackstring) -> stackstring, item
|
||||
-- stackstring_put_item(stackstring, item) -> stackstring, success
|
||||
-- stackstring_put_stackstring(stackstring, stackstring) -> stackstring, success
|
||||
--
|
||||
-- Global objects:
|
||||
-- minetest.env - environment reference
|
||||
@ -79,29 +101,28 @@
|
||||
-- ObjectRef is basically ServerActiveObject.
|
||||
-- ObjectRef methods:
|
||||
-- - remove(): remove object (after returning from Lua)
|
||||
-- - getpos(): returns {x=num, y=num, z=num}
|
||||
-- - getpos() -> {x=num, y=num, z=num}
|
||||
-- - setpos(pos); pos={x=num, y=num, z=num}
|
||||
-- - moveto(pos, continuous=false): interpolated move
|
||||
-- - punch(puncher); puncher = an another ObjectRef
|
||||
-- - right_click(clicker); clicker = an another ObjectRef
|
||||
-- - get_wielded_itemstring()
|
||||
-- - get_wielded_item()
|
||||
-- - damage_wielded_item(num) (item damage/wear range is 0-65535)
|
||||
-- - add_to_inventory(itemstring): add an item to object inventory
|
||||
-- - get_wield_digging_properties() -> digging property table
|
||||
-- - add_to_inventory_later(itemstring): like above, but after callback returns (only allowed for craftitem callbacks)
|
||||
-- - get_hp(): returns number of hitpoints (2 * number of hearts)
|
||||
-- - set_hp(hp): set number of hitpoints (2 * number of hearts)
|
||||
-- LuaEntitySAO-only:
|
||||
-- - setvelocity({x=num, y=num, z=num})
|
||||
-- - setacceleration({x=num, y=num, z=num})
|
||||
-- - getacceleration()
|
||||
-- - getacceleration() -> {x=num, y=num, z=num}
|
||||
-- - settexturemod(mod)
|
||||
-- - setsprite(p={x=0,y=0}, num_frames=1, framelength=0.2,
|
||||
-- - select_horiz_by_yawpitch=false)
|
||||
-- Player-only:
|
||||
-- - get_player_name(): will return nil if is not a player
|
||||
-- - inventory_set_list(name, {item1, item2, ...})
|
||||
-- - inventory_get_list(name)
|
||||
-- - inventory_get_list(name) -> {item1, item2, ...}
|
||||
-- - damage_wielded_item(num) (item damage/wear range is 0-65535)
|
||||
-- - add_to_inventory(itemstring): add an item to object inventory
|
||||
--
|
||||
-- Registered entities:
|
||||
-- - Functions receive a "luaentity" as self:
|
||||
@ -112,13 +133,113 @@
|
||||
-- - on_step(self, dtime)
|
||||
-- - on_punch(self, hitter)
|
||||
-- - on_rightclick(self, clicker)
|
||||
-- - get_staticdata(self): return string
|
||||
-- - get_staticdata(self)
|
||||
-- ^ return string that will be passed to on_activate when the object
|
||||
-- is created next time
|
||||
--
|
||||
-- MapNode representation:
|
||||
-- {name="name", param1=num, param2=num}
|
||||
-- Entity prototype table:
|
||||
-- {
|
||||
-- physical = true,
|
||||
-- collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
||||
-- visual = "cube",
|
||||
-- textures = {texture,texture,texture,texture,texture,texture},
|
||||
-- on_activate = function(self, staticdata),
|
||||
-- on_step = function(self, dtime),
|
||||
-- on_punch = function(self, hitter),
|
||||
-- on_rightclick = function(self, clicker),
|
||||
-- get_staticdata = function(self),
|
||||
-- # Also you can define arbitrary member variables here
|
||||
-- myvariable = whatever,
|
||||
-- }
|
||||
--
|
||||
-- Position representation:
|
||||
-- {x=num, y=num, z=num}
|
||||
-- Tool definition:
|
||||
-- {
|
||||
-- image = "tool_steelaxe.png",
|
||||
-- full_punch_interval = 1.0,
|
||||
-- basetime = 1.0,
|
||||
-- dt_weight = 0.5,
|
||||
-- dt_crackiness = -0.2,
|
||||
-- dt_crumbliness = 1,
|
||||
-- dt_cuttability = -0.5,
|
||||
-- basedurability = 330,
|
||||
-- dd_weight = 0,
|
||||
-- dd_crackiness = 0,
|
||||
-- dd_crumbliness = 0,
|
||||
-- dd_cuttability = 0,
|
||||
-- }
|
||||
--
|
||||
-- Node definition options:
|
||||
-- {
|
||||
-- name = "somenode",
|
||||
-- drawtype = "normal",
|
||||
-- visual_scale = 1.0,
|
||||
-- tile_images = {"unknown_block.png"},
|
||||
-- inventory_image = "unknown_block.png",
|
||||
-- special_materials = {
|
||||
-- {image="", backface_culling=true},
|
||||
-- {image="", backface_culling=true},
|
||||
-- },
|
||||
-- alpha = 255,
|
||||
-- post_effect_color = {a=0, r=0, g=0, b=0},
|
||||
-- paramtype = "none",
|
||||
-- is_ground_content = false,
|
||||
-- light_propagates = false,
|
||||
-- sunlight_propagates = false,
|
||||
-- walkable = true,
|
||||
-- pointable = true,
|
||||
-- diggable = true,
|
||||
-- climbable = false,
|
||||
-- buildable_to = false,
|
||||
-- wall_mounted = false,
|
||||
-- often_contains_mineral = false,
|
||||
-- dug_item = "",
|
||||
-- extra_dug_item = "",
|
||||
-- extra_dug_item_rarity = 2,
|
||||
-- metadata_name = "",
|
||||
-- liquidtype = "none",
|
||||
-- liquid_alternative_flowing = "",
|
||||
-- liquid_alternative_source = "",
|
||||
-- liquid_viscosity = 0,
|
||||
-- light_source = 0,
|
||||
-- damage_per_second = 0,
|
||||
-- selection_box = {type="regular"},
|
||||
-- material = {
|
||||
-- diggablity = "normal",
|
||||
-- weight = 0,
|
||||
-- crackiness = 0,
|
||||
-- crumbliness = 0,
|
||||
-- cuttability = 0,
|
||||
-- flammability = 0,
|
||||
-- },
|
||||
-- cookresult_item = "", -- Cannot be cooked
|
||||
-- furnace_cooktime = 3.0,
|
||||
-- furnace_burntime = -1, -- Cannot be used as fuel
|
||||
-- }
|
||||
--
|
||||
-- Craftitem definition options:
|
||||
-- minetest.register_craftitem("name", {
|
||||
-- image = "image.png",
|
||||
-- stack_max = <maximum number of items in stack>,
|
||||
-- cookresult_item = itemstring (result of cooking),
|
||||
-- furnace_cooktime = <cooking time>,
|
||||
-- furnace_burntime = <time to burn as fuel in furnace>,
|
||||
-- usable = <uh... some boolean value>,
|
||||
-- dropcount = <amount of items to drop using drop action>
|
||||
-- liquids_pointable = <whether can point liquids>,
|
||||
-- on_drop = func(item, dropper, pos),
|
||||
-- on_place_on_ground = func(item, placer, pos),
|
||||
-- on_use = func(item, player, pointed_thing),
|
||||
-- })
|
||||
--
|
||||
-- Recipe:
|
||||
-- {
|
||||
-- output = 'ToolItem "STPick"',
|
||||
-- recipe = {
|
||||
-- {'NodeItem "cobble"', 'NodeItem "cobble"', 'NodeItem "cobble"'},
|
||||
-- {'', 'CraftItem "Stick"', ''},
|
||||
-- {'', 'CraftItem "Stick"', ''},
|
||||
-- }
|
||||
-- }
|
||||
--
|
||||
|
||||
-- print("minetest dump: "..dump(minetest))
|
||||
|
@ -2126,6 +2126,8 @@ public:
|
||||
if(player && player->isLocal())
|
||||
m_is_local_player = true;
|
||||
|
||||
pos_translator.init(m_position);
|
||||
|
||||
updateNodePos();
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "main.h" // For g_profiler
|
||||
#include "profiler.h"
|
||||
#include "serialization.h" // For compressZlib
|
||||
#include "materials.h" // For MaterialProperties
|
||||
#include "tooldef.h" // ToolDiggingProperties
|
||||
|
||||
core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
|
||||
|
||||
@ -241,7 +243,7 @@ InventoryItem * ItemSAO::createInventoryItem()
|
||||
}
|
||||
}
|
||||
|
||||
void ItemSAO::punch(ServerActiveObject *puncher)
|
||||
void ItemSAO::punch(ServerActiveObject *puncher, float time_from_last_punch)
|
||||
{
|
||||
InventoryItem *item = createInventoryItem();
|
||||
bool fits = puncher->addToInventory(item);
|
||||
@ -432,7 +434,7 @@ std::string RatSAO::getStaticData()
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void RatSAO::punch(ServerActiveObject *puncher)
|
||||
void RatSAO::punch(ServerActiveObject *puncher, float time_from_last_punch)
|
||||
{
|
||||
std::istringstream is("CraftItem rat 1", std::ios_base::binary);
|
||||
IGameDef *gamedef = m_env->getGameDef();
|
||||
@ -687,36 +689,28 @@ std::string Oerkki1SAO::getStaticData()
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void Oerkki1SAO::punch(ServerActiveObject *puncher)
|
||||
void Oerkki1SAO::punch(ServerActiveObject *puncher, float time_from_last_punch)
|
||||
{
|
||||
if(!puncher)
|
||||
return;
|
||||
|
||||
v3f dir = (getBasePosition() - puncher->getBasePosition()).normalize();
|
||||
|
||||
std::string toolname = "";
|
||||
InventoryItem *item = puncher->getWieldedItem();
|
||||
if(item && (std::string)item->getName() == "ToolItem"){
|
||||
ToolItem *titem = (ToolItem*)item;
|
||||
toolname = titem->getToolName();
|
||||
}
|
||||
|
||||
m_speed_f += dir*12*BS;
|
||||
|
||||
u16 amount = 5;
|
||||
/* See tool names in inventory.h */
|
||||
if(toolname == "WSword")
|
||||
amount = 10;
|
||||
if(toolname == "STSword")
|
||||
amount = 12;
|
||||
if(toolname == "SteelSword")
|
||||
amount = 16;
|
||||
if(toolname == "STAxe")
|
||||
amount = 7;
|
||||
if(toolname == "SteelAxe")
|
||||
amount = 9;
|
||||
if(toolname == "SteelPick")
|
||||
amount = 7;
|
||||
doDamage(amount);
|
||||
|
||||
puncher->damageWieldedItem(65536/100);
|
||||
// "Material" properties of an oerkki
|
||||
MaterialProperties mp;
|
||||
mp.diggability = DIGGABLE_NORMAL;
|
||||
mp.crackiness = -1.0;
|
||||
mp.cuttability = 1.0;
|
||||
|
||||
ToolDiggingProperties tp;
|
||||
puncher->getWieldDiggingProperties(&tp);
|
||||
|
||||
HittingProperties hitprop = getHittingProperties(&mp, &tp,
|
||||
time_from_last_punch);
|
||||
|
||||
doDamage(hitprop.hp);
|
||||
puncher->damageWieldedItem(hitprop.wear);
|
||||
}
|
||||
|
||||
void Oerkki1SAO::doDamage(u16 d)
|
||||
@ -1365,25 +1359,20 @@ void MobV2SAO::step(float dtime, bool send_recommended)
|
||||
}
|
||||
}
|
||||
|
||||
void MobV2SAO::punch(ServerActiveObject *puncher)
|
||||
void MobV2SAO::punch(ServerActiveObject *puncher, float time_from_last_punch)
|
||||
{
|
||||
if(!puncher)
|
||||
return;
|
||||
|
||||
v3f dir = (getBasePosition() - puncher->getBasePosition()).normalize();
|
||||
|
||||
std::string toolname = "";
|
||||
InventoryItem *item = puncher->getWieldedItem();
|
||||
if(item && (std::string)item->getName() == "ToolItem"){
|
||||
ToolItem *titem = (ToolItem*)item;
|
||||
toolname = titem->getToolName();
|
||||
}
|
||||
|
||||
// A quick hack; SAO description is player name for player
|
||||
std::string playername = puncher->getDescription();
|
||||
|
||||
Map *map = &m_env->getMap();
|
||||
|
||||
actionstream<<playername<<" punches mob id="<<m_id
|
||||
<<" with a \""<<toolname<<"\" at "
|
||||
<<PP(m_base_position/BS)<<std::endl;
|
||||
<<" at "<<PP(m_base_position/BS)<<std::endl;
|
||||
|
||||
m_disturb_timer = 0;
|
||||
m_disturbing_player = playername;
|
||||
@ -1405,23 +1394,21 @@ void MobV2SAO::punch(ServerActiveObject *puncher)
|
||||
}
|
||||
sendPosition();
|
||||
|
||||
u16 amount = 2;
|
||||
/* See tool names in inventory.h */
|
||||
if(toolname == "WSword")
|
||||
amount = 4;
|
||||
if(toolname == "STSword")
|
||||
amount = 6;
|
||||
if(toolname == "SteelSword")
|
||||
amount = 8;
|
||||
if(toolname == "STAxe")
|
||||
amount = 3;
|
||||
if(toolname == "SteelAxe")
|
||||
amount = 4;
|
||||
if(toolname == "SteelPick")
|
||||
amount = 3;
|
||||
doDamage(amount);
|
||||
|
||||
puncher->damageWieldedItem(65536/100);
|
||||
|
||||
// "Material" properties of the MobV2
|
||||
MaterialProperties mp;
|
||||
mp.diggability = DIGGABLE_NORMAL;
|
||||
mp.crackiness = -1.0;
|
||||
mp.cuttability = 1.0;
|
||||
|
||||
ToolDiggingProperties tp;
|
||||
puncher->getWieldDiggingProperties(&tp);
|
||||
|
||||
HittingProperties hitprop = getHittingProperties(&mp, &tp,
|
||||
time_from_last_punch);
|
||||
|
||||
doDamage(hitprop.hp);
|
||||
puncher->damageWieldedItem(hitprop.wear);
|
||||
}
|
||||
|
||||
bool MobV2SAO::isPeaceful()
|
||||
@ -1686,7 +1673,7 @@ InventoryItem* LuaEntitySAO::createPickedUpItem()
|
||||
return item;
|
||||
}
|
||||
|
||||
void LuaEntitySAO::punch(ServerActiveObject *puncher)
|
||||
void LuaEntitySAO::punch(ServerActiveObject *puncher, float time_from_last_punch)
|
||||
{
|
||||
if(!m_registered)
|
||||
return;
|
||||
@ -1799,96 +1786,3 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
/*
|
||||
PlayerSAO
|
||||
*/
|
||||
|
||||
// Prototype
|
||||
PlayerSAO proto_PlayerSAO(NULL, v3f(0,0,0), NULL);
|
||||
|
||||
PlayerSAO::PlayerSAO(ServerEnvironment *env, v3f pos,
|
||||
ServerRemotePlayer *player):
|
||||
ServerActiveObject(env, pos),
|
||||
m_player(player),
|
||||
m_position_updated(true)
|
||||
{
|
||||
if(m_player)
|
||||
m_player->setSAO(this);
|
||||
}
|
||||
|
||||
PlayerSAO::~PlayerSAO()
|
||||
{
|
||||
if(m_player)
|
||||
m_player->setSAO(NULL);
|
||||
}
|
||||
|
||||
void PlayerSAO::step(float dtime, bool send_recommended)
|
||||
{
|
||||
if(!m_player)
|
||||
return;
|
||||
|
||||
if(send_recommended == false)
|
||||
return;
|
||||
|
||||
if(m_position_updated)
|
||||
{
|
||||
m_position_updated = false;
|
||||
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// command (0 = update position)
|
||||
writeU8(os, 0);
|
||||
// pos
|
||||
writeV3F1000(os, m_player->getPosition());
|
||||
// yaw
|
||||
writeF1000(os, m_player->getYaw());
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), false, os.str());
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
}
|
||||
|
||||
std::string PlayerSAO::getClientInitializationData()
|
||||
{
|
||||
if(!m_player)
|
||||
return "";
|
||||
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// version
|
||||
writeU8(os, 0);
|
||||
// name
|
||||
os<<serializeString(m_player->getName());
|
||||
// pos
|
||||
writeV3F1000(os, m_player->getPosition());
|
||||
// yaw
|
||||
writeF1000(os, m_player->getYaw());
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string PlayerSAO::getStaticData()
|
||||
{
|
||||
assert(0);
|
||||
return "";
|
||||
}
|
||||
|
||||
void PlayerSAO::punch(ServerActiveObject *puncher)
|
||||
{
|
||||
infostream<<"TODO: PlayerSAO::punch()"<<std::endl;
|
||||
}
|
||||
|
||||
void PlayerSAO::setPlayer(ServerRemotePlayer *player)
|
||||
{
|
||||
infostream<<"PlayerSAO id="<<getId()<<" got player \""
|
||||
<<(player?player->getName():"(NULL)")<<"\""<<std::endl;
|
||||
m_player = player;
|
||||
}
|
||||
|
||||
ServerRemotePlayer* PlayerSAO::getPlayer()
|
||||
{
|
||||
return m_player;
|
||||
}
|
||||
|
||||
void PlayerSAO::positionUpdated()
|
||||
{
|
||||
m_position_updated = true;
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
std::string getClientInitializationData();
|
||||
std::string getStaticData();
|
||||
InventoryItem* createInventoryItem();
|
||||
void punch(ServerActiveObject *puncher);
|
||||
void punch(ServerActiveObject *puncher, float time_from_last_punch);
|
||||
float getMinimumSavedMovement(){ return 0.1*BS; }
|
||||
private:
|
||||
std::string m_inventorystring;
|
||||
@ -70,7 +70,7 @@ public:
|
||||
void step(float dtime, bool send_recommended);
|
||||
std::string getClientInitializationData();
|
||||
std::string getStaticData();
|
||||
void punch(ServerActiveObject *puncher);
|
||||
void punch(ServerActiveObject *puncher, float time_from_last_punch);
|
||||
private:
|
||||
bool m_is_active;
|
||||
IntervalLimiter m_inactive_interval;
|
||||
@ -96,7 +96,7 @@ public:
|
||||
std::string getClientInitializationData();
|
||||
std::string getStaticData();
|
||||
InventoryItem* createPickedUpItem(){return NULL;}
|
||||
void punch(ServerActiveObject *puncher);
|
||||
void punch(ServerActiveObject *puncher, float time_from_last_punch);
|
||||
bool isPeaceful(){return false;}
|
||||
private:
|
||||
void doDamage(u16 d);
|
||||
@ -156,7 +156,7 @@ public:
|
||||
std::string getClientInitializationData();
|
||||
void step(float dtime, bool send_recommended);
|
||||
InventoryItem* createPickedUpItem(){return NULL;}
|
||||
void punch(ServerActiveObject *puncher);
|
||||
void punch(ServerActiveObject *puncher, float time_from_last_punch);
|
||||
bool isPeaceful();
|
||||
private:
|
||||
void sendPosition();
|
||||
@ -210,7 +210,7 @@ public:
|
||||
std::string getClientInitializationData();
|
||||
std::string getStaticData();
|
||||
InventoryItem* createPickedUpItem();
|
||||
void punch(ServerActiveObject *puncher);
|
||||
void punch(ServerActiveObject *puncher, float time_from_last_punch);
|
||||
void rightClick(ServerActiveObject *clicker);
|
||||
void setPos(v3f pos);
|
||||
void moveTo(v3f pos, bool continuous);
|
||||
@ -240,30 +240,5 @@ private:
|
||||
float m_last_sent_move_precision;
|
||||
};
|
||||
|
||||
class ServerRemotePlayer;
|
||||
|
||||
class PlayerSAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
PlayerSAO(ServerEnvironment *env, v3f pos,
|
||||
ServerRemotePlayer *player);
|
||||
~PlayerSAO();
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_PLAYER;}
|
||||
void step(float dtime, bool send_recommended);
|
||||
std::string getClientInitializationData();
|
||||
std::string getStaticData();
|
||||
bool isStaticAllowed() const
|
||||
{ return false; }
|
||||
void punch(ServerActiveObject *puncher);
|
||||
/* PlayerSAO-specific */
|
||||
void setPlayer(ServerRemotePlayer *player);
|
||||
ServerRemotePlayer* getPlayer();
|
||||
void positionUpdated();
|
||||
private:
|
||||
ServerRemotePlayer *m_player;
|
||||
bool m_position_updated;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -750,7 +750,8 @@ void ServerEnvironment::clearAllObjects()
|
||||
scriptapi_rm_object_reference(m_lua, obj);
|
||||
|
||||
// Delete active object
|
||||
delete obj;
|
||||
if(obj->environmentDeletes())
|
||||
delete obj;
|
||||
// Id to be removed from m_active_objects
|
||||
objects_to_remove.push_back(id);
|
||||
}
|
||||
@ -1181,7 +1182,8 @@ bool ServerEnvironment::addActiveObjectAsStatic(ServerActiveObject *obj)
|
||||
succeeded = false;
|
||||
}
|
||||
|
||||
delete obj;
|
||||
if(obj->environmentDeletes())
|
||||
delete obj;
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
@ -1296,7 +1298,8 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
|
||||
{
|
||||
errorstream<<"ServerEnvironment::addActiveObjectRaw(): "
|
||||
<<"no free ids available"<<std::endl;
|
||||
delete object;
|
||||
if(object->environmentDeletes())
|
||||
delete object;
|
||||
return 0;
|
||||
}
|
||||
object->setId(new_id);
|
||||
@ -1309,7 +1312,8 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
|
||||
{
|
||||
errorstream<<"ServerEnvironment::addActiveObjectRaw(): "
|
||||
<<"id is not free ("<<object->getId()<<")"<<std::endl;
|
||||
delete object;
|
||||
if(object->environmentDeletes())
|
||||
delete object;
|
||||
return 0;
|
||||
}
|
||||
/*infostream<<"ServerEnvironment::addActiveObjectRaw(): "
|
||||
@ -1411,7 +1415,8 @@ void ServerEnvironment::removeRemovedObjects()
|
||||
scriptapi_rm_object_reference(m_lua, obj);
|
||||
|
||||
// Delete
|
||||
delete obj;
|
||||
if(obj->environmentDeletes())
|
||||
delete obj;
|
||||
// Id to be removed from m_active_objects
|
||||
objects_to_remove.push_back(id);
|
||||
}
|
||||
@ -1699,7 +1704,8 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
||||
scriptapi_rm_object_reference(m_lua, obj);
|
||||
|
||||
// Delete active object
|
||||
delete obj;
|
||||
if(obj->environmentDeletes())
|
||||
delete obj;
|
||||
// Id to be removed from m_active_objects
|
||||
objects_to_remove.push_back(id);
|
||||
}
|
||||
|
@ -49,34 +49,65 @@ void MaterialProperties::deSerialize(std::istream &is)
|
||||
flammability = readF1000(is);
|
||||
}
|
||||
|
||||
DiggingProperties getDiggingProperties(u16 content, ToolDiggingProperties *tp,
|
||||
INodeDefManager *nodemgr)
|
||||
DiggingProperties getDiggingProperties(const MaterialProperties *mp,
|
||||
const ToolDiggingProperties *tp, float time_from_last_punch)
|
||||
{
|
||||
assert(tp);
|
||||
const MaterialProperties &mp = nodemgr->get(content).material;
|
||||
if(mp.diggability == DIGGABLE_NOT)
|
||||
if(mp->diggability == DIGGABLE_NOT)
|
||||
return DiggingProperties(false, 0, 0);
|
||||
if(mp.diggability == DIGGABLE_CONSTANT)
|
||||
return DiggingProperties(true, mp.constant_time, 0);
|
||||
if(mp->diggability == DIGGABLE_CONSTANT)
|
||||
return DiggingProperties(true, mp->constant_time, 0);
|
||||
|
||||
float time = tp->basetime;
|
||||
time += tp->dt_weight * mp.weight;
|
||||
time += tp->dt_crackiness * mp.crackiness;
|
||||
time += tp->dt_crumbliness * mp.crumbliness;
|
||||
time += tp->dt_cuttability * mp.cuttability;
|
||||
time += tp->dt_weight * mp->weight;
|
||||
time += tp->dt_crackiness * mp->crackiness;
|
||||
time += tp->dt_crumbliness * mp->crumbliness;
|
||||
time += tp->dt_cuttability * mp->cuttability;
|
||||
if(time < 0.2)
|
||||
time = 0.2;
|
||||
|
||||
float durability = tp->basedurability;
|
||||
durability += tp->dd_weight * mp.weight;
|
||||
durability += tp->dd_crackiness * mp.crackiness;
|
||||
durability += tp->dd_crumbliness * mp.crumbliness;
|
||||
durability += tp->dd_cuttability * mp.cuttability;
|
||||
durability += tp->dd_weight * mp->weight;
|
||||
durability += tp->dd_crackiness * mp->crackiness;
|
||||
durability += tp->dd_crumbliness * mp->crumbliness;
|
||||
durability += tp->dd_cuttability * mp->cuttability;
|
||||
if(durability < 1)
|
||||
durability = 1;
|
||||
|
||||
if(time_from_last_punch < tp->full_punch_interval){
|
||||
float f = time_from_last_punch / tp->full_punch_interval;
|
||||
time /= f;
|
||||
durability /= f;
|
||||
}
|
||||
|
||||
float wear = 1.0 / durability;
|
||||
u16 wear_i = 65535.*wear;
|
||||
return DiggingProperties(true, time, wear_i);
|
||||
}
|
||||
|
||||
DiggingProperties getDiggingProperties(const MaterialProperties *mp,
|
||||
const ToolDiggingProperties *tp)
|
||||
{
|
||||
return getDiggingProperties(mp, tp, 1000000);
|
||||
}
|
||||
|
||||
DiggingProperties getDiggingProperties(u16 content,
|
||||
const ToolDiggingProperties *tp, INodeDefManager *nodemgr)
|
||||
{
|
||||
const MaterialProperties &mp = nodemgr->get(content).material;
|
||||
return getDiggingProperties(&mp, tp);
|
||||
}
|
||||
|
||||
HittingProperties getHittingProperties(const MaterialProperties *mp,
|
||||
const ToolDiggingProperties *tp, float time_from_last_punch)
|
||||
{
|
||||
DiggingProperties digprop = getDiggingProperties(mp, tp,
|
||||
time_from_last_punch);
|
||||
|
||||
// If digging time would be 1 second, 2 hearts go in 1 second.
|
||||
s16 hp = 2.0 * 2.0 / digprop.time + 0.5;
|
||||
// Wear is the same as for digging a single node
|
||||
s16 wear = (float)digprop.wear + 0.5;
|
||||
|
||||
return HittingProperties(hp, wear);
|
||||
}
|
||||
|
||||
|
@ -74,30 +74,44 @@ struct MaterialProperties
|
||||
|
||||
struct DiggingProperties
|
||||
{
|
||||
DiggingProperties():
|
||||
diggable(false),
|
||||
time(0.0),
|
||||
wear(0)
|
||||
{
|
||||
}
|
||||
DiggingProperties(bool a_diggable, float a_time, u16 a_wear):
|
||||
diggable(a_diggable),
|
||||
time(a_time),
|
||||
wear(a_wear)
|
||||
{
|
||||
}
|
||||
bool diggable;
|
||||
// Digging time in seconds
|
||||
float time;
|
||||
// Caused wear
|
||||
u16 wear;
|
||||
|
||||
DiggingProperties(bool a_diggable=false, float a_time=0, u16 a_wear=0):
|
||||
diggable(a_diggable),
|
||||
time(a_time),
|
||||
wear(a_wear)
|
||||
{}
|
||||
};
|
||||
|
||||
struct ToolDiggingProperties;
|
||||
class INodeDefManager;
|
||||
|
||||
DiggingProperties getDiggingProperties(u16 content, ToolDiggingProperties *tp,
|
||||
INodeDefManager *nodemgr);
|
||||
DiggingProperties getDiggingProperties(const MaterialProperties *mp,
|
||||
const ToolDiggingProperties *tp, float time_from_last_punch);
|
||||
|
||||
DiggingProperties getDiggingProperties(const MaterialProperties *mp,
|
||||
const ToolDiggingProperties *tp);
|
||||
|
||||
DiggingProperties getDiggingProperties(u16 content,
|
||||
const ToolDiggingProperties *tp, INodeDefManager *nodemgr);
|
||||
|
||||
struct HittingProperties
|
||||
{
|
||||
s16 hp;
|
||||
s16 wear;
|
||||
|
||||
HittingProperties(s16 hp_=0, s16 wear_=0):
|
||||
hp(hp_),
|
||||
wear(wear_)
|
||||
{}
|
||||
};
|
||||
|
||||
HittingProperties getHittingProperties(const MaterialProperties *mp,
|
||||
const ToolDiggingProperties *tp, float time_from_last_punch);
|
||||
|
||||
#endif
|
||||
|
||||
|
276
src/player.cpp
276
src/player.cpp
@ -31,6 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "environment.h"
|
||||
#include "gamedef.h"
|
||||
#include "content_sao.h"
|
||||
#include "tooldef.h"
|
||||
#include "materials.h"
|
||||
|
||||
Player::Player(IGameDef *gamedef):
|
||||
touching_ground(false),
|
||||
@ -188,7 +190,9 @@ ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env):
|
||||
m_additional_items(),
|
||||
m_inventory_not_sent(false),
|
||||
m_hp_not_sent(false),
|
||||
m_sao(NULL)
|
||||
m_respawn_active(false),
|
||||
m_is_in_environment(false),
|
||||
m_position_not_sent(false)
|
||||
{
|
||||
}
|
||||
ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
|
||||
@ -197,7 +201,8 @@ ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 pee
|
||||
ServerActiveObject(env, pos_),
|
||||
m_inventory_not_sent(false),
|
||||
m_hp_not_sent(false),
|
||||
m_sao(NULL)
|
||||
m_is_in_environment(false),
|
||||
m_position_not_sent(false)
|
||||
{
|
||||
setPosition(pos_);
|
||||
peer_id = peer_id_;
|
||||
@ -206,32 +211,15 @@ ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 pee
|
||||
ServerRemotePlayer::~ServerRemotePlayer()
|
||||
{
|
||||
clearAddToInventoryLater();
|
||||
if(m_sao)
|
||||
m_sao->setPlayer(NULL);
|
||||
}
|
||||
|
||||
void ServerRemotePlayer::setPosition(const v3f &position)
|
||||
{
|
||||
Player::setPosition(position);
|
||||
ServerActiveObject::setBasePosition(position);
|
||||
if(m_sao)
|
||||
m_sao->positionUpdated();
|
||||
m_position_not_sent = true;
|
||||
}
|
||||
|
||||
void ServerRemotePlayer::setSAO(PlayerSAO *sao)
|
||||
{
|
||||
infostream<<"ServerRemotePlayer \""<<getName()
|
||||
<<"\" got sao="<<sao<<std::endl;
|
||||
m_sao = sao;
|
||||
}
|
||||
|
||||
PlayerSAO* ServerRemotePlayer::getSAO()
|
||||
{
|
||||
return m_sao;
|
||||
}
|
||||
|
||||
/* ServerActiveObject interface */
|
||||
|
||||
InventoryItem* ServerRemotePlayer::getWieldedItem()
|
||||
{
|
||||
InventoryList *list = inventory.getList("main");
|
||||
@ -239,6 +227,120 @@ InventoryItem* ServerRemotePlayer::getWieldedItem()
|
||||
return list->getItem(m_selected_item);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ServerActiveObject interface */
|
||||
|
||||
void ServerRemotePlayer::addedToEnvironment()
|
||||
{
|
||||
assert(!m_is_in_environment);
|
||||
m_is_in_environment = true;
|
||||
}
|
||||
|
||||
void ServerRemotePlayer::removingFromEnvironment()
|
||||
{
|
||||
assert(m_is_in_environment);
|
||||
m_is_in_environment = false;
|
||||
}
|
||||
|
||||
void ServerRemotePlayer::step(float dtime, bool send_recommended)
|
||||
{
|
||||
if(send_recommended == false)
|
||||
return;
|
||||
|
||||
if(m_position_not_sent)
|
||||
{
|
||||
m_position_not_sent = false;
|
||||
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// command (0 = update position)
|
||||
writeU8(os, 0);
|
||||
// pos
|
||||
writeV3F1000(os, getPosition());
|
||||
// yaw
|
||||
writeF1000(os, getYaw());
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), false, os.str());
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ServerRemotePlayer::getClientInitializationData()
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// version
|
||||
writeU8(os, 0);
|
||||
// name
|
||||
os<<serializeString(getName());
|
||||
// pos
|
||||
writeV3F1000(os, getPosition());
|
||||
// yaw
|
||||
writeF1000(os, getYaw());
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string ServerRemotePlayer::getStaticData()
|
||||
{
|
||||
assert(0);
|
||||
return "";
|
||||
}
|
||||
|
||||
void ServerRemotePlayer::punch(ServerActiveObject *puncher,
|
||||
float time_from_last_punch)
|
||||
{
|
||||
if(!puncher)
|
||||
return;
|
||||
|
||||
// "Material" properties of a player
|
||||
MaterialProperties mp;
|
||||
mp.diggability = DIGGABLE_NORMAL;
|
||||
mp.crackiness = -1.0;
|
||||
mp.cuttability = 1.0;
|
||||
|
||||
ToolDiggingProperties tp;
|
||||
puncher->getWieldDiggingProperties(&tp);
|
||||
|
||||
HittingProperties hitprop = getHittingProperties(&mp, &tp,
|
||||
time_from_last_punch);
|
||||
|
||||
infostream<<"1. getHP()="<<getHP()<<std::endl;
|
||||
setHP(getHP() - hitprop.hp);
|
||||
infostream<<"2. getHP()="<<getHP()<<std::endl;
|
||||
puncher->damageWieldedItem(hitprop.wear);
|
||||
}
|
||||
|
||||
void ServerRemotePlayer::rightClick(ServerActiveObject *clicker)
|
||||
{
|
||||
}
|
||||
|
||||
void ServerRemotePlayer::setPos(v3f pos)
|
||||
{
|
||||
setPosition(pos);
|
||||
// Movement caused by this command is always valid
|
||||
m_last_good_position = pos;
|
||||
m_last_good_position_age = 0;
|
||||
}
|
||||
void ServerRemotePlayer::moveTo(v3f pos, bool continuous)
|
||||
{
|
||||
setPosition(pos);
|
||||
// Movement caused by this command is always valid
|
||||
m_last_good_position = pos;
|
||||
m_last_good_position_age = 0;
|
||||
}
|
||||
|
||||
void ServerRemotePlayer::getWieldDiggingProperties(ToolDiggingProperties *dst)
|
||||
{
|
||||
IGameDef *gamedef = m_env->getGameDef();
|
||||
IToolDefManager *tdef = gamedef->tdef();
|
||||
|
||||
InventoryItem *item = getWieldedItem();
|
||||
if(item == NULL || std::string(item->getName()) != "ToolItem"){
|
||||
*dst = ToolDiggingProperties();
|
||||
return;
|
||||
}
|
||||
ToolItem *titem = (ToolItem*)item;
|
||||
*dst = tdef->getDiggingProperties(titem->getToolName());
|
||||
}
|
||||
|
||||
void ServerRemotePlayer::damageWieldedItem(u16 amount)
|
||||
{
|
||||
infostream<<"Damaging "<<getName()<<"'s wielded item for amount="
|
||||
@ -332,13 +434,12 @@ void ServerRemotePlayer::setHP(s16 hp_)
|
||||
{
|
||||
s16 oldhp = hp;
|
||||
|
||||
hp = hp_;
|
||||
|
||||
// FIXME: don't hardcode maximum HP, make configurable per object
|
||||
if(hp < 0)
|
||||
hp = 0;
|
||||
else if(hp > 20)
|
||||
hp = 20;
|
||||
if(hp_ < 0)
|
||||
hp_ = 0;
|
||||
else if(hp_ > 20)
|
||||
hp_ = 20;
|
||||
hp = hp_;
|
||||
|
||||
if(hp != oldhp)
|
||||
m_hp_not_sent = true;
|
||||
@ -348,129 +449,6 @@ s16 ServerRemotePlayer::getHP()
|
||||
return hp;
|
||||
}
|
||||
|
||||
/*
|
||||
RemotePlayer
|
||||
*/
|
||||
|
||||
#ifndef SERVER
|
||||
|
||||
#if 0
|
||||
RemotePlayer::RemotePlayer(
|
||||
IGameDef *gamedef,
|
||||
scene::ISceneNode* parent,
|
||||
IrrlichtDevice *device,
|
||||
s32 id):
|
||||
Player(gamedef),
|
||||
scene::ISceneNode(parent, (device==NULL)?NULL:device->getSceneManager(), id),
|
||||
m_text(NULL)
|
||||
{
|
||||
m_box = core::aabbox3d<f32>(-BS/2,0,-BS/2,BS/2,BS*2,BS/2);
|
||||
|
||||
if(parent != NULL && device != NULL)
|
||||
{
|
||||
// ISceneNode stores a member called SceneManager
|
||||
scene::ISceneManager* mgr = SceneManager;
|
||||
video::IVideoDriver* driver = mgr->getVideoDriver();
|
||||
gui::IGUIEnvironment* gui = device->getGUIEnvironment();
|
||||
|
||||
// Add a text node for showing the name
|
||||
wchar_t wname[1] = {0};
|
||||
m_text = mgr->addTextSceneNode(gui->getBuiltInFont(),
|
||||
wname, video::SColor(255,255,255,255), this);
|
||||
m_text->setPosition(v3f(0, (f32)BS*2.1, 0));
|
||||
|
||||
// Attach a simple mesh to the player for showing an image
|
||||
scene::SMesh *mesh = new scene::SMesh();
|
||||
{ // Front
|
||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||
video::SColor c(255,255,255,255);
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
|
||||
video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
|
||||
video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
|
||||
video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
|
||||
};
|
||||
u16 indices[] = {0,1,2,2,3,0};
|
||||
buf->append(vertices, 4, indices, 6);
|
||||
// Set material
|
||||
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||
//buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||
buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player.png").c_str()));
|
||||
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
|
||||
//buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
// Add to mesh
|
||||
mesh->addMeshBuffer(buf);
|
||||
buf->drop();
|
||||
}
|
||||
{ // Back
|
||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||
video::SColor c(255,255,255,255);
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
|
||||
video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
|
||||
video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
|
||||
video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
|
||||
};
|
||||
u16 indices[] = {0,1,2,2,3,0};
|
||||
buf->append(vertices, 4, indices, 6);
|
||||
// Set material
|
||||
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||
//buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||
buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player_back.png").c_str()));
|
||||
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
|
||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
// Add to mesh
|
||||
mesh->addMeshBuffer(buf);
|
||||
buf->drop();
|
||||
}
|
||||
m_node = mgr->addMeshSceneNode(mesh, this);
|
||||
mesh->drop();
|
||||
m_node->setPosition(v3f(0,0,0));
|
||||
}
|
||||
}
|
||||
|
||||
RemotePlayer::~RemotePlayer()
|
||||
{
|
||||
if(SceneManager != NULL)
|
||||
ISceneNode::remove();
|
||||
}
|
||||
|
||||
void RemotePlayer::updateName(const char *name)
|
||||
{
|
||||
Player::updateName(name);
|
||||
if(m_text != NULL)
|
||||
{
|
||||
wchar_t wname[PLAYERNAME_SIZE];
|
||||
mbstowcs(wname, m_name, strlen(m_name)+1);
|
||||
m_text->setText(wname);
|
||||
}
|
||||
}
|
||||
|
||||
void RemotePlayer::move(f32 dtime, Map &map, f32 pos_max_d)
|
||||
{
|
||||
m_pos_animation_time_counter += dtime;
|
||||
m_pos_animation_counter += dtime;
|
||||
v3f movevector = m_position - m_oldpos;
|
||||
f32 moveratio;
|
||||
if(m_pos_animation_time < 0.001)
|
||||
moveratio = 1.0;
|
||||
else
|
||||
moveratio = m_pos_animation_counter / m_pos_animation_time;
|
||||
if(moveratio > 1.5)
|
||||
moveratio = 1.5;
|
||||
m_showpos = m_oldpos + movevector * moveratio;
|
||||
|
||||
ISceneNode::setPosition(m_showpos);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef SERVER
|
||||
/*
|
||||
LocalPlayer
|
||||
|
143
src/player.h
143
src/player.h
@ -201,32 +201,34 @@ public:
|
||||
|
||||
virtual void setPosition(const v3f &position);
|
||||
|
||||
void setSAO(PlayerSAO *sao);
|
||||
PlayerSAO* getSAO();
|
||||
|
||||
// Returns a reference
|
||||
virtual InventoryItem* getWieldedItem();
|
||||
|
||||
/* ServerActiveObject interface */
|
||||
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_PLAYER;}
|
||||
|
||||
virtual void setPos(v3f pos)
|
||||
{
|
||||
setPosition(pos);
|
||||
// Movement caused by this command is always valid
|
||||
m_last_good_position = pos;
|
||||
m_last_good_position_age = 0;
|
||||
}
|
||||
virtual void moveTo(v3f pos, bool continuous)
|
||||
{
|
||||
setPosition(pos);
|
||||
// Movement caused by this command is always valid
|
||||
m_last_good_position = pos;
|
||||
m_last_good_position_age = 0;
|
||||
}
|
||||
// Called after id has been set and has been inserted in environment
|
||||
void addedToEnvironment();
|
||||
// Called before removing from environment
|
||||
void removingFromEnvironment();
|
||||
|
||||
bool environmentDeletes() const
|
||||
{ return false; }
|
||||
bool isStaticAllowed() const
|
||||
{ return false; }
|
||||
|
||||
void step(float dtime, bool send_recommended);
|
||||
std::string getClientInitializationData();
|
||||
std::string getStaticData();
|
||||
void punch(ServerActiveObject *puncher, float time_from_last_punch);
|
||||
void rightClick(ServerActiveObject *clicker);
|
||||
void setPos(v3f pos);
|
||||
void moveTo(v3f pos, bool continuous);
|
||||
virtual std::string getDescription(){return getName();}
|
||||
// Returns a reference
|
||||
virtual InventoryItem* getWieldedItem();
|
||||
|
||||
virtual void getWieldDiggingProperties(ToolDiggingProperties *dst);
|
||||
virtual void damageWieldedItem(u16 amount);
|
||||
// If all fits, eats item and returns true. Otherwise returns false.
|
||||
virtual bool addToInventory(InventoryItem *item);
|
||||
@ -241,110 +243,13 @@ public:
|
||||
std::vector<InventoryItem*> m_additional_items;
|
||||
bool m_inventory_not_sent;
|
||||
bool m_hp_not_sent;
|
||||
bool m_respawn_active;
|
||||
|
||||
private:
|
||||
|
||||
PlayerSAO *m_sao;
|
||||
bool m_is_in_environment;
|
||||
bool m_position_not_sent;
|
||||
};
|
||||
|
||||
#ifndef SERVER
|
||||
|
||||
#if 0
|
||||
/*
|
||||
All the other players on the client are these
|
||||
*/
|
||||
|
||||
class RemotePlayer : public Player, public scene::ISceneNode
|
||||
{
|
||||
public:
|
||||
RemotePlayer(
|
||||
IGameDef *gamedef,
|
||||
scene::ISceneNode* parent=NULL,
|
||||
IrrlichtDevice *device=NULL,
|
||||
s32 id=0);
|
||||
|
||||
virtual ~RemotePlayer();
|
||||
|
||||
/*
|
||||
ISceneNode methods
|
||||
*/
|
||||
|
||||
virtual void OnRegisterSceneNode()
|
||||
{
|
||||
if (IsVisible)
|
||||
SceneManager->registerNodeForRendering(this);
|
||||
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
|
||||
virtual void render()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const
|
||||
{
|
||||
return m_box;
|
||||
}
|
||||
|
||||
void setPosition(const v3f &position)
|
||||
{
|
||||
m_oldpos = m_showpos;
|
||||
|
||||
if(m_pos_animation_time < 0.001 || m_pos_animation_time > 1.0)
|
||||
m_pos_animation_time = m_pos_animation_time_counter;
|
||||
else
|
||||
m_pos_animation_time = m_pos_animation_time * 0.9
|
||||
+ m_pos_animation_time_counter * 0.1;
|
||||
m_pos_animation_time_counter = 0;
|
||||
m_pos_animation_counter = 0;
|
||||
|
||||
Player::setPosition(position);
|
||||
//ISceneNode::setPosition(position);
|
||||
}
|
||||
|
||||
virtual void setYaw(f32 yaw)
|
||||
{
|
||||
Player::setYaw(yaw);
|
||||
ISceneNode::setRotation(v3f(0, -yaw, 0));
|
||||
}
|
||||
|
||||
bool isLocal() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void updateName(const char *name);
|
||||
|
||||
virtual void updateLight(u8 light_at_pos)
|
||||
{
|
||||
Player::updateLight(light_at_pos);
|
||||
|
||||
if(m_node == NULL)
|
||||
return;
|
||||
|
||||
u8 li = decode_light(light_at_pos);
|
||||
video::SColor color(255,li,li,li);
|
||||
setMeshVerticesColor(m_node->getMesh(), color);
|
||||
}
|
||||
|
||||
void move(f32 dtime, Map &map, f32 pos_max_d);
|
||||
|
||||
private:
|
||||
scene::IMeshSceneNode *m_node;
|
||||
scene::ITextSceneNode* m_text;
|
||||
core::aabbox3d<f32> m_box;
|
||||
|
||||
v3f m_oldpos;
|
||||
f32 m_pos_animation_counter;
|
||||
f32 m_pos_animation_time;
|
||||
f32 m_pos_animation_time_counter;
|
||||
v3f m_showpos;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // !SERVER
|
||||
|
||||
#ifndef SERVER
|
||||
struct PlayerControl
|
||||
{
|
||||
|
@ -386,6 +386,15 @@ static int getenumfield(lua_State *L, int table,
|
||||
return result;
|
||||
}
|
||||
|
||||
static void setfloatfield(lua_State *L, int table,
|
||||
const char *fieldname, float value)
|
||||
{
|
||||
lua_pushnumber(L, value);
|
||||
if(table < 0)
|
||||
table -= 1;
|
||||
lua_setfield(L, table, fieldname);
|
||||
}
|
||||
|
||||
/*
|
||||
Inventory stuff
|
||||
*/
|
||||
@ -455,6 +464,71 @@ static void inventory_get_list_to_lua(Inventory *inv, const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ToolDiggingProperties
|
||||
*/
|
||||
|
||||
static ToolDiggingProperties read_tool_digging_properties(
|
||||
lua_State *L, int table)
|
||||
{
|
||||
ToolDiggingProperties prop;
|
||||
getfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
|
||||
getfloatfield(L, table, "basetime", prop.basetime);
|
||||
getfloatfield(L, table, "dt_weight", prop.dt_weight);
|
||||
getfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
|
||||
getfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
|
||||
getfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
|
||||
getfloatfield(L, table, "basedurability", prop.basedurability);
|
||||
getfloatfield(L, table, "dd_weight", prop.dd_weight);
|
||||
getfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
|
||||
getfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
|
||||
getfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
|
||||
return prop;
|
||||
}
|
||||
|
||||
static void set_tool_digging_properties(lua_State *L, int table,
|
||||
const ToolDiggingProperties &prop)
|
||||
{
|
||||
setfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
|
||||
setfloatfield(L, table, "basetime", prop.basetime);
|
||||
setfloatfield(L, table, "dt_weight", prop.dt_weight);
|
||||
setfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
|
||||
setfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
|
||||
setfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
|
||||
setfloatfield(L, table, "basedurability", prop.basedurability);
|
||||
setfloatfield(L, table, "dd_weight", prop.dd_weight);
|
||||
setfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
|
||||
setfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
|
||||
setfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
|
||||
}
|
||||
|
||||
static void push_tool_digging_properties(lua_State *L,
|
||||
const ToolDiggingProperties &prop)
|
||||
{
|
||||
lua_newtable(L);
|
||||
set_tool_digging_properties(L, -1, prop);
|
||||
}
|
||||
|
||||
/*
|
||||
ToolDefinition
|
||||
*/
|
||||
|
||||
static ToolDefinition read_tool_definition(lua_State *L, int table)
|
||||
{
|
||||
ToolDefinition def;
|
||||
getstringfield(L, table, "image", def.imagename);
|
||||
def.properties = read_tool_digging_properties(L, table);
|
||||
return def;
|
||||
}
|
||||
|
||||
static void push_tool_definition(lua_State *L, const ToolDefinition &def)
|
||||
{
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, def.imagename.c_str());
|
||||
lua_setfield(L, -2, "image");
|
||||
set_tool_digging_properties(L, -1, def.properties);
|
||||
}
|
||||
|
||||
/*
|
||||
EnumString definitions
|
||||
*/
|
||||
@ -672,19 +746,7 @@ static int l_register_tool(lua_State *L)
|
||||
IWritableToolDefManager *tooldef =
|
||||
server->getWritableToolDefManager();
|
||||
|
||||
ToolDefinition def;
|
||||
|
||||
getstringfield(L, table, "image", def.imagename);
|
||||
getfloatfield(L, table, "basetime", def.properties.basetime);
|
||||
getfloatfield(L, table, "dt_weight", def.properties.dt_weight);
|
||||
getfloatfield(L, table, "dt_crackiness", def.properties.dt_crackiness);
|
||||
getfloatfield(L, table, "dt_crumbliness", def.properties.dt_crumbliness);
|
||||
getfloatfield(L, table, "dt_cuttability", def.properties.dt_cuttability);
|
||||
getfloatfield(L, table, "basedurability", def.properties.basedurability);
|
||||
getfloatfield(L, table, "dd_weight", def.properties.dd_weight);
|
||||
getfloatfield(L, table, "dd_crackiness", def.properties.dd_crackiness);
|
||||
getfloatfield(L, table, "dd_crumbliness", def.properties.dd_crumbliness);
|
||||
getfloatfield(L, table, "dd_cuttability", def.properties.dd_cuttability);
|
||||
ToolDefinition def = read_tool_definition(L, table);
|
||||
|
||||
tooldef->registerTool(name, def);
|
||||
return 0; /* number of results */
|
||||
@ -1588,9 +1650,7 @@ private:
|
||||
return NULL;
|
||||
if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
|
||||
return NULL;
|
||||
PlayerSAO *player_sao = static_cast<PlayerSAO*>(obj);
|
||||
return player_sao->getPlayer();
|
||||
//return static_cast<ServerRemotePlayer*>(obj);
|
||||
return static_cast<ServerRemotePlayer*>(obj);
|
||||
}
|
||||
|
||||
// Exported functions
|
||||
@ -1690,65 +1750,16 @@ private:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get_wielded_itemstring(self)
|
||||
static int l_get_wielded_itemstring(lua_State *L)
|
||||
// get_wield_digging_properties(self)
|
||||
static int l_get_wield_digging_properties(lua_State *L)
|
||||
{
|
||||
ObjectRef *ref = checkobject(L, 1);
|
||||
ServerActiveObject *co = getobject(ref);
|
||||
if(co == NULL) return 0;
|
||||
// Do it
|
||||
InventoryItem *item = co->getWieldedItem();
|
||||
if(item == NULL){
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
lua_pushstring(L, item->getItemString().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_wielded_item(self)
|
||||
static int l_get_wielded_item(lua_State *L)
|
||||
{
|
||||
ObjectRef *ref = checkobject(L, 1);
|
||||
ServerActiveObject *co = getobject(ref);
|
||||
if(co == NULL) return 0;
|
||||
// Do it
|
||||
InventoryItem *item0 = co->getWieldedItem();
|
||||
if(item0 == NULL){
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
if(std::string("MaterialItem") == item0->getName()){
|
||||
MaterialItem *item = (MaterialItem*)item0;
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "NodeItem");
|
||||
lua_setfield(L, -2, "type");
|
||||
lua_pushstring(L, item->getNodeName().c_str());
|
||||
lua_setfield(L, -2, "name");
|
||||
}
|
||||
else if(std::string("CraftItem") == item0->getName()){
|
||||
CraftItem *item = (CraftItem*)item0;
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "CraftItem");
|
||||
lua_setfield(L, -2, "type");
|
||||
lua_pushstring(L, item->getSubName().c_str());
|
||||
lua_setfield(L, -2, "name");
|
||||
}
|
||||
else if(std::string("ToolItem") == item0->getName()){
|
||||
ToolItem *item = (ToolItem*)item0;
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "ToolItem");
|
||||
lua_setfield(L, -2, "type");
|
||||
lua_pushstring(L, item->getToolName().c_str());
|
||||
lua_setfield(L, -2, "name");
|
||||
lua_pushstring(L, itos(item->getWear()).c_str());
|
||||
lua_setfield(L, -2, "wear");
|
||||
}
|
||||
else{
|
||||
errorstream<<"l_get_wielded_item: Unknown item name: \""
|
||||
<<item0->getName()<<"\""<<std::endl;
|
||||
lua_pushnil(L);
|
||||
}
|
||||
ToolDiggingProperties prop;
|
||||
co->getWieldDiggingProperties(&prop);
|
||||
push_tool_digging_properties(L, prop);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1976,6 +1987,68 @@ private:
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_wielded_itemstring(self)
|
||||
static int l_get_wielded_itemstring(lua_State *L)
|
||||
{
|
||||
ObjectRef *ref = checkobject(L, 1);
|
||||
ServerRemotePlayer *player = getplayer(ref);
|
||||
if(player == NULL) return 0;
|
||||
// Do it
|
||||
InventoryItem *item = player->getWieldedItem();
|
||||
if(item == NULL){
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
lua_pushstring(L, item->getItemString().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_wielded_item(self)
|
||||
static int l_get_wielded_item(lua_State *L)
|
||||
{
|
||||
ObjectRef *ref = checkobject(L, 1);
|
||||
ServerRemotePlayer *player = getplayer(ref);
|
||||
if(player == NULL) return 0;
|
||||
// Do it
|
||||
InventoryItem *item0 = player->getWieldedItem();
|
||||
if(item0 == NULL){
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
if(std::string("MaterialItem") == item0->getName()){
|
||||
MaterialItem *item = (MaterialItem*)item0;
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "NodeItem");
|
||||
lua_setfield(L, -2, "type");
|
||||
lua_pushstring(L, item->getNodeName().c_str());
|
||||
lua_setfield(L, -2, "name");
|
||||
}
|
||||
else if(std::string("CraftItem") == item0->getName()){
|
||||
CraftItem *item = (CraftItem*)item0;
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "CraftItem");
|
||||
lua_setfield(L, -2, "type");
|
||||
lua_pushstring(L, item->getSubName().c_str());
|
||||
lua_setfield(L, -2, "name");
|
||||
}
|
||||
else if(std::string("ToolItem") == item0->getName()){
|
||||
ToolItem *item = (ToolItem*)item0;
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "ToolItem");
|
||||
lua_setfield(L, -2, "type");
|
||||
lua_pushstring(L, item->getToolName().c_str());
|
||||
lua_setfield(L, -2, "name");
|
||||
lua_pushstring(L, itos(item->getWear()).c_str());
|
||||
lua_setfield(L, -2, "wear");
|
||||
}
|
||||
else{
|
||||
errorstream<<"l_get_wielded_item: Unknown item name: \""
|
||||
<<item0->getName()<<"\""<<std::endl;
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public:
|
||||
ObjectRef(ServerActiveObject *object):
|
||||
m_object(object)
|
||||
@ -2046,8 +2119,7 @@ const luaL_reg ObjectRef::methods[] = {
|
||||
method(ObjectRef, moveto),
|
||||
method(ObjectRef, punch),
|
||||
method(ObjectRef, right_click),
|
||||
method(ObjectRef, get_wielded_itemstring),
|
||||
method(ObjectRef, get_wielded_item),
|
||||
method(ObjectRef, get_wield_digging_properties),
|
||||
method(ObjectRef, damage_wielded_item),
|
||||
method(ObjectRef, add_to_inventory),
|
||||
method(ObjectRef, add_to_inventory_later),
|
||||
@ -2063,6 +2135,8 @@ const luaL_reg ObjectRef::methods[] = {
|
||||
method(ObjectRef, get_player_name),
|
||||
method(ObjectRef, inventory_set_list),
|
||||
method(ObjectRef, inventory_get_list),
|
||||
method(ObjectRef, get_wielded_itemstring),
|
||||
method(ObjectRef, get_wielded_item),
|
||||
{0,0}
|
||||
};
|
||||
|
||||
|
@ -1431,6 +1431,11 @@ void Server::AsyncRunStep()
|
||||
player->m_last_good_position_age = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Handle player HPs
|
||||
*/
|
||||
HandlePlayerHP(player, 0);
|
||||
|
||||
/*
|
||||
Send player inventories and HPs if necessary
|
||||
*/
|
||||
@ -2230,8 +2235,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||
}
|
||||
|
||||
// Add PlayerSAO
|
||||
PlayerSAO *sao = new PlayerSAO(m_env, player->getPosition(), player);
|
||||
m_env->addActiveObject(sao);
|
||||
player->m_removed = false;
|
||||
m_env->addActiveObject(player);
|
||||
|
||||
/*
|
||||
Answer with a TOCLIENT_INIT
|
||||
@ -2983,6 +2988,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||
|
||||
actionstream<<player->getName()<<" respawns at "
|
||||
<<PP(player->getPosition()/BS)<<std::endl;
|
||||
|
||||
srp->m_removed = false;
|
||||
m_env->addActiveObject(srp);
|
||||
}
|
||||
else if(command == TOSERVER_INTERACT)
|
||||
{
|
||||
@ -4523,6 +4531,11 @@ void Server::SendTextures(u16 peer_id)
|
||||
|
||||
void Server::HandlePlayerHP(Player *player, s16 damage)
|
||||
{
|
||||
ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
|
||||
|
||||
if(srp->m_respawn_active)
|
||||
return;
|
||||
|
||||
if(player->hp > damage)
|
||||
{
|
||||
player->hp -= damage;
|
||||
@ -4549,6 +4562,8 @@ void Server::HandlePlayerHP(Player *player, s16 damage)
|
||||
if(client->net_proto_version >= 3)
|
||||
{
|
||||
SendDeathscreen(m_con, player->peer_id, false, v3f(0,0,0));
|
||||
srp->m_removed = true;
|
||||
srp->m_respawn_active = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4561,6 +4576,7 @@ void Server::RespawnPlayer(Player *player)
|
||||
{
|
||||
player->hp = 20;
|
||||
ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
|
||||
srp->m_respawn_active = false;
|
||||
bool repositioned = scriptapi_on_respawnplayer(m_lua, srp);
|
||||
if(!repositioned){
|
||||
v3f pos = findSpawnPos(m_env->getServerMap());
|
||||
@ -4983,16 +4999,9 @@ void Server::handlePeerChange(PeerChange &c)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove PlayerSAO
|
||||
// Remove from environment
|
||||
if(player != NULL)
|
||||
{
|
||||
PlayerSAO *sao = player->getSAO();
|
||||
if(sao){
|
||||
sao->setPlayer(NULL);
|
||||
sao->m_removed = true;
|
||||
}
|
||||
player->setSAO(NULL);
|
||||
}
|
||||
player->m_removed = true;
|
||||
|
||||
// Set player client disconnected
|
||||
if(player != NULL)
|
||||
|
@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "serverobject.h"
|
||||
#include <fstream>
|
||||
#include "inventory.h"
|
||||
#include "tooldef.h"
|
||||
|
||||
ServerActiveObject::ServerActiveObject(ServerEnvironment *env, v3f pos):
|
||||
ActiveObject(0),
|
||||
@ -66,5 +67,10 @@ void ServerActiveObject::registerType(u16 type, Factory f)
|
||||
m_types.insert(type, f);
|
||||
}
|
||||
|
||||
void ServerActiveObject::getWieldDiggingProperties(ToolDiggingProperties *dst)
|
||||
{
|
||||
*dst = ToolDiggingProperties();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -43,6 +43,7 @@ Some planning
|
||||
class ServerEnvironment;
|
||||
class InventoryItem;
|
||||
class Player;
|
||||
struct ToolDiggingProperties;
|
||||
|
||||
class ServerActiveObject : public ActiveObject
|
||||
{
|
||||
@ -128,23 +129,24 @@ public:
|
||||
virtual bool isStaticAllowed() const
|
||||
{return true;}
|
||||
|
||||
virtual void punch(ServerActiveObject *puncher){}
|
||||
virtual void rightClick(ServerActiveObject *clicker){}
|
||||
|
||||
// Returns a reference
|
||||
virtual InventoryItem* getWieldedItem()
|
||||
{ return NULL; }
|
||||
// time_from_last_punch is used for lessening damage if punching fast
|
||||
virtual void punch(ServerActiveObject *puncher,
|
||||
float time_from_last_punch=1000000)
|
||||
{}
|
||||
virtual void rightClick(ServerActiveObject *clicker)
|
||||
{}
|
||||
virtual void getWieldDiggingProperties(ToolDiggingProperties *dst);
|
||||
virtual void damageWieldedItem(u16 amount)
|
||||
{}
|
||||
{}
|
||||
// If all fits, eats item and returns true. Otherwise returns false.
|
||||
virtual bool addToInventory(InventoryItem *item)
|
||||
{return false;}
|
||||
{ return false; }
|
||||
virtual void addToInventoryLater(InventoryItem *item)
|
||||
{}
|
||||
{}
|
||||
virtual void setHP(s16 hp)
|
||||
{}
|
||||
{}
|
||||
virtual s16 getHP()
|
||||
{return 0;}
|
||||
{ return 0; }
|
||||
|
||||
/*
|
||||
Number of players which know about this object. Object won't be
|
||||
|
@ -23,9 +23,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <sstream>
|
||||
#include "utility.h"
|
||||
|
||||
ToolDiggingProperties::ToolDiggingProperties(
|
||||
ToolDiggingProperties::ToolDiggingProperties(float full_punch_interval_,
|
||||
float a, float b, float c, float d, float e,
|
||||
float f, float g, float h, float i, float j):
|
||||
full_punch_interval(full_punch_interval_),
|
||||
basetime(a),
|
||||
dt_weight(b),
|
||||
dt_crackiness(c),
|
||||
@ -60,6 +61,7 @@ void ToolDefinition::serialize(std::ostream &os)
|
||||
writeF1000(os, properties.dd_crackiness);
|
||||
writeF1000(os, properties.dd_crumbliness);
|
||||
writeF1000(os, properties.dd_cuttability);
|
||||
writeF1000(os, properties.full_punch_interval);
|
||||
}
|
||||
|
||||
void ToolDefinition::deSerialize(std::istream &is)
|
||||
@ -78,6 +80,9 @@ void ToolDefinition::deSerialize(std::istream &is)
|
||||
properties.dd_crackiness = readF1000(is);
|
||||
properties.dd_crumbliness = readF1000(is);
|
||||
properties.dd_cuttability = readF1000(is);
|
||||
try{
|
||||
properties.full_punch_interval = readF1000(is);
|
||||
}catch(SerializationError &e){} // Temporary for 0.4.dev
|
||||
}
|
||||
|
||||
class CToolDefManager: public IWritableToolDefManager
|
||||
|
@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
struct ToolDiggingProperties
|
||||
{
|
||||
// time = basetime + sum(feature here * feature in MaterialProperties)
|
||||
float full_punch_interval;
|
||||
float basetime;
|
||||
float dt_weight;
|
||||
float dt_crackiness;
|
||||
@ -37,7 +38,7 @@ struct ToolDiggingProperties
|
||||
float dd_crumbliness;
|
||||
float dd_cuttability;
|
||||
|
||||
ToolDiggingProperties(
|
||||
ToolDiggingProperties(float full_punch_interval_=1.0,
|
||||
float a=0.75, float b=0, float c=0, float d=0, float e=0,
|
||||
float f=50, float g=0, float h=0, float i=0, float j=0);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user