forked from oerkki/voxelands
implement MobCAO
This commit is contained in:
parent
39a8e40aff
commit
ab27c517f5
|
@ -134,7 +134,6 @@ set(common_SRCS
|
|||
log.cpp
|
||||
content_sao.cpp
|
||||
mapgen.cpp
|
||||
content_inventory.cpp
|
||||
content_nodemeta.cpp
|
||||
content_craft.cpp
|
||||
content_craftitem.cpp
|
||||
|
|
|
@ -1306,6 +1306,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||
is.read(buf, 1);
|
||||
u8 type = readU8((u8*)buf);
|
||||
std::string data = deSerializeLongString(is);
|
||||
printf("mob add: %d %d\n",id,type);
|
||||
// Add it
|
||||
{
|
||||
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "clientobject.h"
|
||||
#include "content_object.h"
|
||||
#include "utility.h" // For IntervalLimiter
|
||||
#include "mapnode.h"
|
||||
#include "content_mob.h"
|
||||
class Settings;
|
||||
#include <IBillboardSceneNode.h>
|
||||
|
||||
|
@ -96,39 +98,6 @@ struct SmoothTranslator
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
TestCAO
|
||||
*/
|
||||
|
||||
class TestCAO : public ClientActiveObject
|
||||
{
|
||||
public:
|
||||
TestCAO();
|
||||
virtual ~TestCAO();
|
||||
|
||||
u8 getType() const
|
||||
{
|
||||
return ACTIVEOBJECT_TYPE_TEST;
|
||||
}
|
||||
|
||||
static ClientActiveObject* create();
|
||||
|
||||
void addToScene(scene::ISceneManager *smgr);
|
||||
void removeFromScene();
|
||||
void updateLight(u8 light_at_pos);
|
||||
v3s16 getLightPosition();
|
||||
void updateNodePos();
|
||||
|
||||
void step(float dtime, ClientEnvironment *env);
|
||||
|
||||
void processMessage(const std::string &data);
|
||||
|
||||
private:
|
||||
scene::IMeshSceneNode *m_node;
|
||||
v3f m_position;
|
||||
};
|
||||
|
||||
/*
|
||||
ItemCAO
|
||||
*/
|
||||
|
@ -158,10 +127,8 @@ public:
|
|||
|
||||
void initialize(const std::string &data);
|
||||
|
||||
core::aabbox3d<f32>* getSelectionBox()
|
||||
{return &m_selection_box;}
|
||||
v3f getPosition()
|
||||
{return m_position;}
|
||||
core::aabbox3d<f32>* getSelectionBox() {return &m_selection_box;}
|
||||
v3f getPosition() {return m_position;}
|
||||
|
||||
void updateCameraOffset(v3s16 camera_offset)
|
||||
{
|
||||
|
@ -177,18 +144,18 @@ private:
|
|||
};
|
||||
|
||||
/*
|
||||
RatCAO
|
||||
MobCAO
|
||||
*/
|
||||
|
||||
class RatCAO : public ClientActiveObject
|
||||
class MobCAO : public ClientActiveObject
|
||||
{
|
||||
public:
|
||||
RatCAO();
|
||||
virtual ~RatCAO();
|
||||
MobCAO();
|
||||
virtual ~MobCAO();
|
||||
|
||||
u8 getType() const
|
||||
{
|
||||
return ACTIVEOBJECT_TYPE_RAT;
|
||||
return ACTIVEOBJECT_TYPE_MOB;
|
||||
}
|
||||
|
||||
static ClientActiveObject* create();
|
||||
|
@ -205,160 +172,8 @@ public:
|
|||
|
||||
void initialize(const std::string &data);
|
||||
|
||||
core::aabbox3d<f32>* getSelectionBox()
|
||||
{return &m_selection_box;}
|
||||
v3f getPosition()
|
||||
{return pos_translator.vect_show;}
|
||||
|
||||
void updateCameraOffset(v3s16 camera_offset)
|
||||
{
|
||||
m_camera_offset = camera_offset;
|
||||
}
|
||||
|
||||
private:
|
||||
core::aabbox3d<f32> m_selection_box;
|
||||
scene::IAnimatedMeshSceneNode *m_node;
|
||||
v3f m_position;
|
||||
v3s16 m_camera_offset;
|
||||
float m_yaw;
|
||||
SmoothTranslator pos_translator;
|
||||
};
|
||||
|
||||
/*
|
||||
Oerkki1CAO
|
||||
*/
|
||||
|
||||
class Oerkki1CAO : public ClientActiveObject
|
||||
{
|
||||
public:
|
||||
Oerkki1CAO();
|
||||
virtual ~Oerkki1CAO();
|
||||
|
||||
u8 getType() const
|
||||
{
|
||||
return ACTIVEOBJECT_TYPE_OERKKI1;
|
||||
}
|
||||
|
||||
static ClientActiveObject* create();
|
||||
|
||||
void addToScene(scene::ISceneManager *smgr);
|
||||
void removeFromScene();
|
||||
void updateLight(u8 light_at_pos);
|
||||
v3s16 getLightPosition();
|
||||
void updateNodePos();
|
||||
|
||||
void step(float dtime, ClientEnvironment *env);
|
||||
|
||||
void processMessage(const std::string &data);
|
||||
|
||||
void initialize(const std::string &data);
|
||||
|
||||
core::aabbox3d<f32>* getSelectionBox()
|
||||
{return &m_selection_box;}
|
||||
v3f getPosition()
|
||||
{return pos_translator.vect_show;}
|
||||
|
||||
void updateCameraOffset(v3s16 camera_offset)
|
||||
{
|
||||
m_camera_offset = camera_offset;
|
||||
}
|
||||
|
||||
// If returns true, punch will not be sent to the server
|
||||
bool directReportPunch(const std::string &toolname, v3f dir);
|
||||
|
||||
private:
|
||||
IntervalLimiter m_attack_interval;
|
||||
core::aabbox3d<f32> m_selection_box;
|
||||
scene::IAnimatedMeshSceneNode *m_node;
|
||||
v3f m_position;
|
||||
v3s16 m_camera_offset;
|
||||
float m_yaw;
|
||||
SmoothTranslator pos_translator;
|
||||
float m_damage_visual_timer;
|
||||
bool m_damage_texture_enabled;
|
||||
};
|
||||
|
||||
/*
|
||||
FireflyCAO
|
||||
*/
|
||||
|
||||
class FireflyCAO : public ClientActiveObject
|
||||
{
|
||||
public:
|
||||
FireflyCAO();
|
||||
virtual ~FireflyCAO();
|
||||
|
||||
u8 getType() const
|
||||
{
|
||||
return ACTIVEOBJECT_TYPE_FIREFLY;
|
||||
}
|
||||
|
||||
static ClientActiveObject* create();
|
||||
|
||||
void addToScene(scene::ISceneManager *smgr);
|
||||
void removeFromScene();
|
||||
void updateLight(u8 light_at_pos);
|
||||
v3s16 getLightPosition();
|
||||
void updateNodePos();
|
||||
|
||||
void step(float dtime, ClientEnvironment *env);
|
||||
|
||||
void processMessage(const std::string &data);
|
||||
|
||||
void initialize(const std::string &data);
|
||||
|
||||
core::aabbox3d<f32>* getSelectionBox()
|
||||
{return &m_selection_box;}
|
||||
v3f getPosition()
|
||||
{return m_position;}
|
||||
|
||||
void updateCameraOffset(v3s16 camera_offset)
|
||||
{
|
||||
m_camera_offset = camera_offset;
|
||||
}
|
||||
|
||||
private:
|
||||
core::aabbox3d<f32> m_selection_box;
|
||||
scene::IMeshSceneNode *m_node;
|
||||
v3f m_position;
|
||||
v3s16 m_camera_offset;
|
||||
float m_yaw;
|
||||
SmoothTranslator pos_translator;
|
||||
};
|
||||
|
||||
/*
|
||||
MobV2CAO
|
||||
*/
|
||||
|
||||
class MobV2CAO : public ClientActiveObject
|
||||
{
|
||||
public:
|
||||
MobV2CAO();
|
||||
virtual ~MobV2CAO();
|
||||
|
||||
u8 getType() const
|
||||
{
|
||||
return ACTIVEOBJECT_TYPE_MOBV2;
|
||||
}
|
||||
|
||||
static ClientActiveObject* create();
|
||||
|
||||
void addToScene(scene::ISceneManager *smgr);
|
||||
void removeFromScene();
|
||||
void updateLight(u8 light_at_pos);
|
||||
v3s16 getLightPosition();
|
||||
void updateNodePos();
|
||||
|
||||
void step(float dtime, ClientEnvironment *env);
|
||||
|
||||
void processMessage(const std::string &data);
|
||||
|
||||
void initialize(const std::string &data);
|
||||
|
||||
core::aabbox3d<f32>* getSelectionBox()
|
||||
{return &m_selection_box;}
|
||||
v3f getPosition()
|
||||
{return pos_translator.vect_show;}
|
||||
core::aabbox3d<f32>* getSelectionBox() {m_selection_box = content_mob_features(m_content).getCollisionBox(); return &m_selection_box;}
|
||||
v3f getPosition() {return pos_translator.vect_show;}
|
||||
|
||||
void updateCameraOffset(v3s16 camera_offset)
|
||||
{
|
||||
|
@ -368,39 +183,21 @@ public:
|
|||
|
||||
// If returns true, punch will not be sent to the server
|
||||
bool directReportPunch(const std::string &toolname, v3f dir);
|
||||
|
||||
private:
|
||||
void setLooks(const std::string &looks);
|
||||
|
||||
IntervalLimiter m_attack_interval;
|
||||
core::aabbox3d<f32> m_selection_box;
|
||||
scene::IBillboardSceneNode *m_node;
|
||||
aabb3f m_selection_box;
|
||||
content_t m_content;
|
||||
scene::IAnimatedMeshSceneNode *m_node;
|
||||
v3f m_position;
|
||||
v3s16 m_camera_offset;
|
||||
std::string m_texture_name;
|
||||
float m_yaw;
|
||||
SmoothTranslator pos_translator;
|
||||
bool m_walking;
|
||||
float m_walking_unset_timer;
|
||||
float m_walk_timer;
|
||||
int m_walk_frame;
|
||||
float m_damage_visual_timer;
|
||||
u8 m_last_light;
|
||||
float m_player_hit_timer;
|
||||
float m_damage_visual_timer;
|
||||
bool m_shooting;
|
||||
float m_shooting_unset_timer;
|
||||
v2f m_sprite_size;
|
||||
float m_sprite_y;
|
||||
bool m_bright_shooting;
|
||||
std::string m_sprite_type;
|
||||
int m_simple_anim_frames;
|
||||
float m_simple_anim_frametime;
|
||||
bool m_lock_full_brightness;
|
||||
int m_player_hit_damage;
|
||||
float m_player_hit_distance;
|
||||
float m_player_hit_interval;
|
||||
float m_player_hit_timer;
|
||||
|
||||
Settings *m_properties;
|
||||
bool m_walking;
|
||||
float m_walking_unset_timer;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2010-2011 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 General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU 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.
|
||||
*/
|
||||
|
||||
#include "content_inventory.h"
|
||||
#include "inventory.h"
|
||||
#include "content_mapnode.h"
|
||||
//#include "serverobject.h"
|
||||
#include "content_sao.h"
|
||||
|
||||
|
||||
ServerActiveObject* item_craft_create_object(const std::string &subname,
|
||||
ServerEnvironment *env, u16 id, v3f pos)
|
||||
{
|
||||
if(subname == "rat")
|
||||
{
|
||||
ServerActiveObject *obj = new RatSAO(env, id, pos);
|
||||
return obj;
|
||||
}
|
||||
else if(subname == "firefly")
|
||||
{
|
||||
ServerActiveObject *obj = new FireflySAO(env, id, pos);
|
||||
return obj;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2010-2011 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 General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU 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 CONTENT_INVENTORY_HEADER
|
||||
#define CONTENT_INVENTORY_HEADER
|
||||
|
||||
#include "common_irrlicht.h" // For u8, s16
|
||||
#include <string>
|
||||
#include "mapnode.h" // For content_t
|
||||
|
||||
class InventoryItem;
|
||||
class ServerActiveObject;
|
||||
class ServerEnvironment;
|
||||
|
||||
ServerActiveObject* item_craft_create_object(const std::string &subname,
|
||||
ServerEnvironment *env, u16 id, v3f pos);
|
||||
|
||||
#endif
|
||||
|
|
@ -19,8 +19,13 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
************************************************************************/
|
||||
|
||||
#include "serverobject.h"
|
||||
#include "content_sao.h"
|
||||
#include "content_mob.h"
|
||||
#include "main.h"
|
||||
#include "settings.h"
|
||||
#include "environment.h"
|
||||
#include "map.h"
|
||||
|
||||
std::map<content_t,struct MobFeatures> g_content_mob_features;
|
||||
|
||||
|
@ -52,6 +57,116 @@ void MobFeatures::setBoxTexture(u16 i, std::string name, u8 alpha)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
void MobFeatures::getAnimationFrames(MobAnimation type, int *start, int *end)
|
||||
{
|
||||
*start = 0;
|
||||
*end = 0;
|
||||
switch (type) {
|
||||
case MA_STAND:
|
||||
*start = animations[MA_STAND_START];
|
||||
*end = animations[MA_STAND_END];
|
||||
break;
|
||||
case MA_MOVE:
|
||||
*start = animations[MA_MOVE_START];
|
||||
*end = animations[MA_MOVE_END];
|
||||
break;
|
||||
case MA_ATTACK:
|
||||
*start = animations[MA_ATTACK_START];
|
||||
*end = animations[MA_ATTACK_END];
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
if (type != MA_STAND && start == end) {
|
||||
*start = animations[MA_STAND_START];
|
||||
*end = animations[MA_STAND_END];
|
||||
}
|
||||
}
|
||||
void MobFeatures::setAnimationFrames(MobAnimation type, int start, int end)
|
||||
{
|
||||
switch (type) {
|
||||
case MA_STAND:
|
||||
animations[MA_STAND_START] = start;
|
||||
animations[MA_STAND_END] = end;
|
||||
break;
|
||||
case MA_MOVE:
|
||||
animations[MA_MOVE_START] = start;
|
||||
animations[MA_MOVE_END] = end;
|
||||
break;
|
||||
case MA_ATTACK:
|
||||
animations[MA_ATTACK_START] = start;
|
||||
animations[MA_ATTACK_END] = end;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
||||
bool content_mob_spawn(ServerEnvironment *env, v3s16 pos)
|
||||
{
|
||||
assert(env);
|
||||
Map *map = &env->getMap();
|
||||
|
||||
std::vector<content_t> can;
|
||||
MapNode n = map->getNodeNoEx(pos);
|
||||
MapNode a1 = map->getNodeNoEx(pos+v3s16(0,1,0));
|
||||
MapNode a2 = map->getNodeNoEx(pos+v3s16(0,2,0));
|
||||
content_t c0 = n.getContent();
|
||||
content_t c1 = a1.getContent();
|
||||
content_t c2 = a2.getContent();
|
||||
u8 light = n.getLightBlend(env->getDayNightRatio());
|
||||
u8 level = mobLevelI(g_settings->get("max_mob_level"));
|
||||
|
||||
if (c0 == CONTENT_IGNORE || c1 == CONTENT_IGNORE || c2 == CONTENT_IGNORE)
|
||||
return false;
|
||||
|
||||
for (std::map<content_t,struct MobFeatures>::iterator i = g_content_mob_features.begin(); i != g_content_mob_features.end(); i++) {
|
||||
MobFeatures m = i->second;
|
||||
if (m.spawn_in == CONTENT_IGNORE && m.spawn_on == CONTENT_IGNORE)
|
||||
continue;
|
||||
if (m.spawn_in != CONTENT_IGNORE) {
|
||||
if (m.spawn_in != c1)
|
||||
continue;
|
||||
if (m.spawn_in != c2)
|
||||
continue;
|
||||
}
|
||||
if (m.spawn_on != CONTENT_IGNORE) {
|
||||
if (m.spawn_on != c0)
|
||||
continue;
|
||||
}
|
||||
if (m.spawn_min_light > light)
|
||||
continue;
|
||||
if (m.spawn_max_light < light)
|
||||
continue;
|
||||
if (m.level > level)
|
||||
continue;
|
||||
can.push_back(i->first);
|
||||
}
|
||||
|
||||
if (can.size() == 0)
|
||||
return false;
|
||||
|
||||
MobFeatures m;
|
||||
u32 index = 0;
|
||||
|
||||
if (can.size() > 1)
|
||||
index = myrand_range(0,can.size()-1);
|
||||
|
||||
m = g_content_mob_features[can[index]];
|
||||
|
||||
if (m.content == CONTENT_IGNORE)
|
||||
return false;
|
||||
|
||||
v3f p = intToFloat(pos+v3s16(0,1,0), BS);
|
||||
actionstream<<"A mob of type "<<m.content<<" spawns at "<<PP(floatToInt(p,BS))<<std::endl;
|
||||
ServerActiveObject *obj = new MobSAO(env, 0, p, m.content);
|
||||
u16 id = env->addActiveObject(obj);
|
||||
if (id)
|
||||
return true;
|
||||
actionstream<<"A mob of type "<<m.content<<" didn't spawn at "<<PP(floatToInt(p,BS))<<std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void content_mob_init()
|
||||
{
|
||||
|
@ -66,33 +181,40 @@ void content_mob_init()
|
|||
f->level = MOB_PASSIVE;
|
||||
f->model = "rat.x";
|
||||
f->setTexture("mob_rat.png");
|
||||
f->setAnimationFrames(MA_STAND,0,79);
|
||||
f->punch_action = MPA_PICKUP;
|
||||
f->motion = MM_WANDER;
|
||||
f->spawn_on = CONTENT_GRASS;
|
||||
f->spawn_in = CONTENT_AIR;
|
||||
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
|
||||
|
||||
i = CONTENT_MOB_FIREFLY;
|
||||
f = &g_content_mob_features[i];
|
||||
f->content = i;
|
||||
//f->content = i;
|
||||
f->level = MOB_PASSIVE;
|
||||
f->setTexture("mob_firefly.png");
|
||||
f->punch_action = MPA_PICKUP;
|
||||
f->motion = MM_WANDER;
|
||||
f->glow_light = LIGHT_MAX-1;
|
||||
f->spawn_on = CONTENT_JUNGLETREE;
|
||||
f->spawn_in = CONTENT_AIR;
|
||||
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
|
||||
|
||||
i = CONTENT_MOB_OERKKI;
|
||||
f = &g_content_mob_features[i];
|
||||
f->content = i;
|
||||
//f->content = i;
|
||||
f->level = MOB_AGGRESSIVE;
|
||||
f->model = "oerkki.x";
|
||||
f->setTexture("mob_oerkki.png");
|
||||
f->setAnimationFrames(MA_STAND,24,36);
|
||||
f->setAnimationFrames(MA_ATTACK,37,49);
|
||||
f->punch_action = MPA_HARM;
|
||||
f->motion = MM_SEEKER;
|
||||
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.));
|
||||
|
||||
i = CONTENT_MOB_DUNGEON_MASTER;
|
||||
f = &g_content_mob_features[i];
|
||||
f->content = i;
|
||||
//f->content = i;
|
||||
f->level = MOB_DESTRUCTIVE;
|
||||
f->model = "dungeon_master.x";
|
||||
f->setTexture("mob_dungeon_master.png");
|
||||
|
@ -104,7 +226,7 @@ void content_mob_init()
|
|||
|
||||
i = CONTENT_MOB_FIREBALL;
|
||||
f = &g_content_mob_features[i];
|
||||
f->content = i;
|
||||
//f->content = i;
|
||||
f->level = MOB_DESTRUCTIVE;
|
||||
f->setTexture("mob_fireball.png");
|
||||
f->punch_action = MPA_IGNORE;
|
||||
|
@ -115,18 +237,18 @@ void content_mob_init()
|
|||
|
||||
i = CONTENT_MOB_DEER;
|
||||
f = &g_content_mob_features[i];
|
||||
f->content = i;
|
||||
//f->content = i;
|
||||
i = CONTENT_MOB_SHEEP;
|
||||
f = &g_content_mob_features[i];
|
||||
f->content = i;
|
||||
//f->content = i;
|
||||
i = CONTENT_MOB_FISH;
|
||||
f = &g_content_mob_features[i];
|
||||
f->content = i;
|
||||
//f->content = i;
|
||||
i = CONTENT_MOB_SHARK;
|
||||
f = &g_content_mob_features[i];
|
||||
f->content = i;
|
||||
//f->content = i;
|
||||
i = CONTENT_MOB_WOLF;
|
||||
f = &g_content_mob_features[i];
|
||||
f->content = i;
|
||||
//f->content = i;
|
||||
|
||||
}
|
||||
|
|
|
@ -69,6 +69,16 @@ enum MobAnimation
|
|||
MA_ATTACK
|
||||
};
|
||||
|
||||
enum MobAnimationKey
|
||||
{
|
||||
MA_STAND_START = 0,
|
||||
MA_STAND_END,
|
||||
MA_MOVE_START,
|
||||
MA_MOVE_END,
|
||||
MA_ATTACK_START,
|
||||
MA_ATTACK_END
|
||||
};
|
||||
|
||||
#define CONTENT_MOB_MASK 0x2000
|
||||
|
||||
struct MobFeatures {
|
||||
|
@ -79,7 +89,9 @@ struct MobFeatures {
|
|||
video::ITexture *texture;
|
||||
#endif
|
||||
std::string model;
|
||||
std::map<MobAnimation,int[2]> animations;
|
||||
std::map<MobAnimationKey,int> animations;
|
||||
v3f model_scale;
|
||||
v3f model_offset;
|
||||
std::vector<aabb3f> nodeboxes;
|
||||
aabb3f collisionbox;
|
||||
|
||||
|
@ -93,6 +105,7 @@ struct MobFeatures {
|
|||
content_t attack_throw_object;
|
||||
v3f attack_throw_offset;
|
||||
u8 attack_player_damage;
|
||||
v3f attack_player_range;
|
||||
u8 glow_light;
|
||||
u8 attack_glow_light;
|
||||
u16 hp;
|
||||
|
@ -100,6 +113,11 @@ struct MobFeatures {
|
|||
f32 lifetime;
|
||||
u16 contact_explosion_diameter;
|
||||
|
||||
content_t spawn_on;
|
||||
content_t spawn_in;
|
||||
u8 spawn_min_light;
|
||||
u8 spawn_max_light;
|
||||
|
||||
MobFeatures()
|
||||
{
|
||||
reset();
|
||||
|
@ -153,6 +171,9 @@ struct MobFeatures {
|
|||
return v3s16(s.X+0.5,s.Y+0.5,s.Z+0.5);
|
||||
}
|
||||
|
||||
void getAnimationFrames(MobAnimation type, int *start, int *end);
|
||||
void setAnimationFrames(MobAnimation type, int start, int end);
|
||||
|
||||
#ifdef SERVER
|
||||
void setTexture(std::string name)
|
||||
{}
|
||||
|
@ -176,6 +197,8 @@ struct MobFeatures {
|
|||
{
|
||||
content = CONTENT_IGNORE;
|
||||
model = "";
|
||||
model_scale = v3f(0,0,0);
|
||||
model_offset = v3f(0,0,0);
|
||||
nodeboxes.clear();
|
||||
punch_action = MPA_DIE;
|
||||
motion = MM_STATIC;
|
||||
|
@ -187,12 +210,17 @@ struct MobFeatures {
|
|||
attack_throw_object = CONTENT_IGNORE;
|
||||
attack_throw_offset = v3f(0,0,0);
|
||||
attack_player_damage = 0;
|
||||
attack_player_range = v3f(0,0,0);
|
||||
glow_light = 0;
|
||||
attack_glow_light = 0;
|
||||
hp = 20;
|
||||
dropped_item = "";
|
||||
lifetime = 0.0;
|
||||
contact_explosion_diameter = 0;
|
||||
spawn_on = CONTENT_IGNORE;
|
||||
spawn_in = CONTENT_IGNORE;
|
||||
spawn_min_light = 0;
|
||||
spawn_max_light = LIGHT_MAX;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -214,6 +242,9 @@ inline std::string mobLevelS(u8 level)
|
|||
return std::string("passive");
|
||||
}
|
||||
|
||||
class ServerEnvironment;
|
||||
bool content_mob_spawn(ServerEnvironment *env, v3s16 pos);
|
||||
|
||||
MobFeatures & content_mob_features(content_t i);
|
||||
void content_mob_init();
|
||||
|
||||
|
|
1580
src/content_sao.cpp
1580
src/content_sao.cpp
File diff suppressed because it is too large
Load Diff
|
@ -46,142 +46,6 @@ private:
|
|||
IntervalLimiter m_move_interval;
|
||||
};
|
||||
|
||||
class RatSAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
RatSAO(ServerEnvironment *env, u16 id, v3f pos);
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_RAT;}
|
||||
static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
|
||||
const std::string &data);
|
||||
void step(float dtime, bool send_recommended);
|
||||
std::string getClientInitializationData();
|
||||
std::string getStaticData();
|
||||
InventoryItem* createPickedUpItem();
|
||||
private:
|
||||
bool m_is_active;
|
||||
IntervalLimiter m_inactive_interval;
|
||||
v3f m_speed_f;
|
||||
v3f m_oldpos;
|
||||
v3f m_last_sent_position;
|
||||
float m_yaw;
|
||||
float m_counter1;
|
||||
float m_counter2;
|
||||
float m_age;
|
||||
bool m_touching_ground;
|
||||
};
|
||||
|
||||
class Oerkki1SAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
Oerkki1SAO(ServerEnvironment *env, u16 id, v3f pos);
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_OERKKI1;}
|
||||
static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
|
||||
const std::string &data);
|
||||
void step(float dtime, bool send_recommended);
|
||||
std::string getClientInitializationData();
|
||||
std::string getStaticData();
|
||||
InventoryItem* createPickedUpItem();
|
||||
u16 punch(const std::string &toolname, v3f dir,
|
||||
const std::string &playername);
|
||||
u8 level(){return MOB_AGGRESSIVE;}
|
||||
private:
|
||||
void doDamage(u16 d);
|
||||
|
||||
bool m_is_active;
|
||||
IntervalLimiter m_inactive_interval;
|
||||
v3f m_speed_f;
|
||||
v3f m_oldpos;
|
||||
v3f m_last_sent_position;
|
||||
float m_yaw;
|
||||
float m_counter1;
|
||||
float m_counter2;
|
||||
float m_age;
|
||||
bool m_touching_ground;
|
||||
u8 m_hp;
|
||||
float m_after_jump_timer;
|
||||
};
|
||||
|
||||
class FireflySAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
FireflySAO(ServerEnvironment *env, u16 id, v3f pos);
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_FIREFLY;}
|
||||
static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
|
||||
const std::string &data);
|
||||
void step(float dtime, bool send_recommended);
|
||||
std::string getClientInitializationData();
|
||||
std::string getStaticData();
|
||||
InventoryItem* createPickedUpItem();
|
||||
private:
|
||||
bool m_is_active;
|
||||
IntervalLimiter m_inactive_interval;
|
||||
v3f m_speed_f;
|
||||
v3f m_oldpos;
|
||||
v3f m_last_sent_position;
|
||||
float m_yaw;
|
||||
float m_counter1;
|
||||
float m_counter2;
|
||||
float m_age;
|
||||
bool m_touching_ground;
|
||||
};
|
||||
|
||||
class Settings;
|
||||
|
||||
class MobV2SAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
MobV2SAO(ServerEnvironment *env, u16 id, v3f pos,
|
||||
Settings *init_properties);
|
||||
virtual ~MobV2SAO();
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_MOBV2;}
|
||||
static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
|
||||
const std::string &data);
|
||||
std::string getStaticData();
|
||||
std::string getClientInitializationData();
|
||||
void step(float dtime, bool send_recommended);
|
||||
InventoryItem* createPickedUpItem(){return NULL;}
|
||||
u16 punch(const std::string &toolname, v3f dir,
|
||||
const std::string &playername);
|
||||
u8 level();
|
||||
private:
|
||||
void sendPosition();
|
||||
void setPropertyDefaults();
|
||||
void readProperties();
|
||||
void updateProperties();
|
||||
void doDamage(u16 d);
|
||||
|
||||
std::string m_move_type;
|
||||
v3f m_speed;
|
||||
v3f m_last_sent_position;
|
||||
v3f m_oldpos;
|
||||
float m_yaw;
|
||||
float m_counter1;
|
||||
float m_counter2;
|
||||
float m_age;
|
||||
bool m_touching_ground;
|
||||
int m_hp;
|
||||
bool m_walk_around;
|
||||
float m_walk_around_timer;
|
||||
bool m_next_pos_exists;
|
||||
v3s16 m_next_pos_i;
|
||||
float m_shoot_reload_timer;
|
||||
bool m_shooting;
|
||||
float m_shooting_timer;
|
||||
float m_die_age;
|
||||
v2f m_size;
|
||||
bool m_falling;
|
||||
float m_disturb_timer;
|
||||
std::string m_disturbing_player;
|
||||
float m_random_disturb_timer;
|
||||
float m_shoot_y;
|
||||
|
||||
Settings *m_properties;
|
||||
};
|
||||
|
||||
class MobSAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
|
@ -216,6 +80,7 @@ private:
|
|||
v3f m_speed;
|
||||
v3f m_last_sent_position;
|
||||
v3f m_oldpos;
|
||||
v3f m_initial_pos;
|
||||
float m_yaw;
|
||||
bool m_touching_ground;
|
||||
bool m_falling;
|
||||
|
@ -223,7 +88,7 @@ private:
|
|||
v3s16 m_next_pos_i;
|
||||
|
||||
float m_age;
|
||||
int m_hp;
|
||||
u8 m_hp;
|
||||
|
||||
float m_disturb_timer;
|
||||
std::string m_disturbing_player;
|
||||
|
|
|
@ -542,56 +542,6 @@ void ServerEnvironment::loadMeta(const std::string &savedir)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// This is probably very useless
|
||||
void spawnRandomObjects(MapBlock *block)
|
||||
{
|
||||
for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
|
||||
for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
|
||||
{
|
||||
bool last_node_walkable = false;
|
||||
for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
|
||||
{
|
||||
v3s16 p(x0,y0,z0);
|
||||
MapNode n = block->getNodeNoEx(p);
|
||||
if(n.getContent() == CONTENT_IGNORE)
|
||||
continue;
|
||||
if(content_features(n).liquid_type != LIQUID_NONE)
|
||||
continue;
|
||||
if(content_features(n).walkable)
|
||||
{
|
||||
last_node_walkable = true;
|
||||
continue;
|
||||
}
|
||||
if(last_node_walkable)
|
||||
{
|
||||
// If block contains light information
|
||||
if(content_features(n).param_type == CPT_LIGHT)
|
||||
{
|
||||
if(n.getLight(LIGHTBANK_DAY) <= 5)
|
||||
{
|
||||
if(myrand() % 1000 == 0)
|
||||
{
|
||||
v3f pos_f = intToFloat(p+block->getPosRelative(), BS);
|
||||
pos_f.Y -= BS*0.4;
|
||||
ServerActiveObject *obj = new Oerkki1SAO(NULL,0,pos_f);
|
||||
std::string data = obj->getStaticData();
|
||||
StaticObject s_obj(obj->getType(),
|
||||
obj->getBasePosition(), data);
|
||||
// Add one
|
||||
block->m_static_objects.insert(0, s_obj);
|
||||
delete obj;
|
||||
block->setChangedFlag();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
last_node_walkable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
|
||||
{
|
||||
// Get time difference
|
||||
|
@ -708,29 +658,6 @@ void ServerEnvironment::clearAllObjects()
|
|||
<<" in "<<num_blocks_cleared<<" blocks"<<std::endl;
|
||||
}
|
||||
|
||||
static void getMob_dungeon_master(Settings &properties)
|
||||
{
|
||||
properties.set("looks", "dungeon_master");
|
||||
properties.set("visual", "mesh");
|
||||
properties.set("visual_model","dungeon_master.x");
|
||||
properties.set("visual_model_texture","dungeon_master_mob.png");
|
||||
properties.set("visual_model_","");
|
||||
properties.set("visual_sprite","dungeon_master.png");
|
||||
properties.set("visual_sprite_size","(2.0,0.85,3.0)");
|
||||
properties.set("visual_sprite_type","humanoid_1");
|
||||
properties.set("visual_selection_size","(0.4,-0.4,2.6)");
|
||||
properties.setFloat("yaw", 1.57);
|
||||
properties.setFloat("hp", 30);
|
||||
properties.setBool("bright_shooting", true);
|
||||
properties.set("shoot_type", "fireball");
|
||||
properties.set("shoot_y", "0.7");
|
||||
properties.set("player_hit_damage", "1");
|
||||
properties.set("player_hit_distance", "1.0");
|
||||
properties.set("player_hit_interval", "0.5");
|
||||
properties.set("level","destructive");
|
||||
properties.setBool("mindless_rage", myrand_range(0,100)==0);
|
||||
}
|
||||
|
||||
bool ServerEnvironment::searchNear(v3s16 pos, v3s16 radius_min, v3s16 radius_max, std::vector<content_t> c, v3s16 *found)
|
||||
{
|
||||
v3s16 blockpos = getNodeBlockPos(pos);
|
||||
|
@ -1022,6 +949,11 @@ void ServerEnvironment::step(float dtime)
|
|||
v3s16 p = p0 + block->getPosRelative();
|
||||
MapNode n = block->getNodeNoEx(p0);
|
||||
|
||||
if (active_object_count_wider < 3 && myrand()%100 == 0) {
|
||||
if (content_mob_spawn(this,p))
|
||||
active_object_count_wider++;
|
||||
}
|
||||
|
||||
switch(n.getContent()) {
|
||||
case CONTENT_GRASS_FOOTSTEPS:
|
||||
{
|
||||
|
@ -2032,105 +1964,6 @@ void ServerEnvironment::step(float dtime)
|
|||
break;
|
||||
}
|
||||
|
||||
// Rats spawn around regular trees
|
||||
case CONTENT_TREE:
|
||||
case CONTENT_APPLE_TREE:
|
||||
case CONTENT_CONIFER_TREE:
|
||||
{
|
||||
if(myrand()%200 == 0 && active_object_count_wider == 0)
|
||||
{
|
||||
v3s16 p1 = p + v3s16(myrand_range(-2, 2),
|
||||
0, myrand_range(-2, 2));
|
||||
MapNode n1 = m_map->getNodeNoEx(p1);
|
||||
MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,-1,0));
|
||||
if(n1b.getContent() == CONTENT_GRASS &&
|
||||
n1.getContent() == CONTENT_AIR)
|
||||
{
|
||||
v3f pos = intToFloat(p1, BS);
|
||||
ServerActiveObject *obj = new RatSAO(this, 0, pos);
|
||||
addActiveObject(obj);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
// fireflies spawn in jungles at night
|
||||
case CONTENT_JUNGLETREE:
|
||||
{
|
||||
if (myrand()%100 == 0 && active_object_count_wider < 10) {
|
||||
v3s16 p1 = p + v3s16(myrand_range(-2, 2),
|
||||
0, myrand_range(-2, 2));
|
||||
MapNode n1 = m_map->getNodeNoEx(p1);
|
||||
MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,-1,0));
|
||||
if (
|
||||
(
|
||||
n1b.getContent() == CONTENT_AIR
|
||||
|| n1b.getContent() == CONTENT_JUNGLETREE
|
||||
|| n1b.getContent() == CONTENT_JUNGLEGRASS
|
||||
)
|
||||
&& n1.getContent() == CONTENT_AIR
|
||||
&& n1.getLightBlend(getDayNightRatio()) <= LIGHT_MAX/2
|
||||
) {
|
||||
v3f pos = intToFloat(p1, BS);
|
||||
ServerActiveObject *obj = new FireflySAO(this, 0, pos);
|
||||
addActiveObject(obj);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Fun things spawn in caves and dungeons
|
||||
case CONTENT_STONE:
|
||||
case CONTENT_MOSSYCOBBLE:
|
||||
{
|
||||
if(myrand()%500 == 0 && active_object_count_wider == 0)
|
||||
{
|
||||
v3s16 p1 = p + v3s16(0,1,0);
|
||||
MapNode n1a = m_map->getNodeNoEx(p1+v3s16(0,0,0));
|
||||
if(n1a.getLightBlend(getDayNightRatio()) <= 3){
|
||||
MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,1,0));
|
||||
if(n1a.getContent() == CONTENT_AIR &&
|
||||
n1b.getContent() == CONTENT_AIR)
|
||||
{
|
||||
v3f pos = intToFloat(p1, BS);
|
||||
ServerActiveObject *obj;
|
||||
Settings properties;
|
||||
int i = myrand()%5;
|
||||
u8 mob_level = mobLevelI(g_settings->get("max_mob_level"));
|
||||
switch (i) {
|
||||
case 0:
|
||||
getMob_dungeon_master(properties);
|
||||
if (mobLevelI(properties.get("level")) >= mob_level) {
|
||||
actionstream<<"A dungeon master spawns at "
|
||||
<<PP(p1)<<std::endl;
|
||||
obj = new MobV2SAO(this, 0, pos, &properties);
|
||||
addActiveObject(obj);
|
||||
active_object_count_wider++;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
actionstream<<"Rat spawns at "
|
||||
<<PP(p1)<<std::endl;
|
||||
obj = new RatSAO(this, 0, pos);
|
||||
addActiveObject(obj);
|
||||
active_object_count_wider++;
|
||||
break;
|
||||
case 2:
|
||||
if (mob_level > MOB_PASSIVE) {
|
||||
actionstream<<"An oerkki spawns at "
|
||||
<<PP(p1)<<std::endl;
|
||||
obj = new Oerkki1SAO(this, 0, pos);
|
||||
addActiveObject(obj);
|
||||
active_object_count_wider++;
|
||||
}
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Make trees from saplings!
|
||||
case CONTENT_SAPLING:
|
||||
{
|
||||
|
@ -3385,8 +3218,7 @@ ActiveObjectMessage ServerEnvironment::getActiveObjectMessage()
|
|||
************ Private methods *************
|
||||
*/
|
||||
|
||||
u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
|
||||
bool set_changed)
|
||||
u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object, bool set_changed)
|
||||
{
|
||||
assert(object);
|
||||
if(object->getId() == 0){
|
||||
|
@ -3434,7 +3266,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
|
|||
object->m_static_exists = true;
|
||||
object->m_static_block = blockpos;
|
||||
|
||||
if(set_changed)
|
||||
if (set_changed)
|
||||
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
||||
}
|
||||
else{
|
||||
|
@ -4227,12 +4059,11 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object)
|
|||
return object->getId();
|
||||
}
|
||||
|
||||
void ClientEnvironment::addActiveObject(u16 id, u8 type,
|
||||
const std::string &init_data)
|
||||
void ClientEnvironment::addActiveObject(u16 id, u8 type, const std::string &init_data)
|
||||
{
|
||||
// TODO: convert old to new
|
||||
ClientActiveObject* obj = ClientActiveObject::create(type);
|
||||
if(obj == NULL)
|
||||
{
|
||||
if (obj == NULL) {
|
||||
infostream<<"ClientEnvironment::addActiveObject(): "
|
||||
<<"id="<<id<<" type="<<type<<": Couldn't create object"
|
||||
<<std::endl;
|
||||
|
|
|
@ -234,9 +234,9 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
|
|||
case GUI_ID_MOBS_AGGRESSIVE:
|
||||
max_mob_level = L"aggressive";
|
||||
break;
|
||||
//case GUI_ID_MOBS_DESTRUCTIVE:
|
||||
//max_mob_level = L"destructive";
|
||||
//break;
|
||||
case GUI_ID_MOBS_DESTRUCTIVE:
|
||||
max_mob_level = L"destructive";
|
||||
break;
|
||||
default:
|
||||
max_mob_level = L"aggressive";
|
||||
}
|
||||
|
@ -648,11 +648,11 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
|
|||
gui::IGUIComboBox *c = Environment->addComboBox(rect, this, GUI_ID_MOBS_COMBO);
|
||||
u32 pm = c->addItem(wgettext("Passive"),GUI_ID_MOBS_PASSIVE);
|
||||
u32 am = c->addItem(wgettext("Passive & Aggressive"),GUI_ID_MOBS_AGGRESSIVE);
|
||||
//u32 dm = c->addItem(wgettext("Passive, Aggressive, & Destructive"),GUI_ID_MOBS_DESTRUCTIVE);
|
||||
u32 dm = c->addItem(wgettext("Passive, Aggressive, & Destructive"),GUI_ID_MOBS_DESTRUCTIVE);
|
||||
if (max_mob_level == L"passive") {
|
||||
c->setSelected(pm);
|
||||
//}else if (max_mob_level == L"destructive") {
|
||||
//c->setSelected(dm);
|
||||
}else if (max_mob_level == L"destructive") {
|
||||
c->setSelected(dm);
|
||||
}else{
|
||||
c->setSelected(am);
|
||||
}
|
||||
|
@ -947,8 +947,8 @@ void GUIMainMenu::acceptInput()
|
|||
s32 i;
|
||||
if (m_data->max_mob_level == L"passive") {
|
||||
i = c->getIndexForItemData(GUI_ID_MOBS_PASSIVE);
|
||||
//}else if (m_data->max_mob_level == L"destructive") {
|
||||
//i = c->getIndexForItemData(GUI_ID_MOBS_DESTRUCTIVE);
|
||||
}else if (m_data->max_mob_level == L"destructive") {
|
||||
i = c->getIndexForItemData(GUI_ID_MOBS_DESTRUCTIVE);
|
||||
}else{
|
||||
i = c->getIndexForItemData(GUI_ID_MOBS_AGGRESSIVE);
|
||||
}
|
||||
|
@ -987,9 +987,9 @@ void GUIMainMenu::acceptInput()
|
|||
case GUI_ID_MOBS_AGGRESSIVE:
|
||||
m_data->max_mob_level = L"aggressive";
|
||||
break;
|
||||
//case GUI_ID_MOBS_DESTRUCTIVE:
|
||||
//m_data->max_mob_level = L"destructive";
|
||||
//break;
|
||||
case GUI_ID_MOBS_DESTRUCTIVE:
|
||||
m_data->max_mob_level = L"destructive";
|
||||
break;
|
||||
default:
|
||||
m_data->max_mob_level = L"aggressive";
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "main.h"
|
||||
#include "serverobject.h"
|
||||
#include "content_mapnode.h"
|
||||
#include "content_inventory.h"
|
||||
#include "content_sao.h"
|
||||
#include "content_mob.h"
|
||||
#include "player.h"
|
||||
#include "log.h"
|
||||
|
||||
|
@ -206,9 +206,11 @@ std::wstring CraftItem::getGuiName()
|
|||
ServerActiveObject* CraftItem::createSAO(ServerEnvironment *env, u16 id, v3f pos)
|
||||
{
|
||||
// Special cases
|
||||
ServerActiveObject *obj = item_craft_create_object(m_subname, env, id, pos);
|
||||
if(obj)
|
||||
return obj;
|
||||
if ((m_content&CONTENT_MOB_MASK) == CONTENT_MOB_MASK) {
|
||||
ServerActiveObject *obj = new MobSAO(env,id,pos,m_content);
|
||||
if (obj)
|
||||
return obj;
|
||||
}
|
||||
// Default
|
||||
return InventoryItem::createSAO(env, id, pos);
|
||||
}
|
||||
|
|
|
@ -1388,21 +1388,19 @@ void Server::AsyncRunStep()
|
|||
// Handle added objects
|
||||
writeU16((u8*)buf, added_objects.size());
|
||||
data_buffer.append(buf, 2);
|
||||
for(core::map<u16, bool>::Iterator
|
||||
i = added_objects.getIterator();
|
||||
i.atEnd()==false; i++)
|
||||
{
|
||||
for (core::map<u16, bool>::Iterator i = added_objects.getIterator(); i.atEnd()==false; i++) {
|
||||
// Get object
|
||||
u16 id = i.getNode()->getKey();
|
||||
ServerActiveObject* obj = m_env.getActiveObject(id);
|
||||
|
||||
// Get object type
|
||||
u8 type = ACTIVEOBJECT_TYPE_INVALID;
|
||||
if(obj == NULL)
|
||||
if (obj == NULL) {
|
||||
infostream<<"WARNING: "<<__FUNCTION_NAME
|
||||
<<": NULL object"<<std::endl;
|
||||
else
|
||||
}else{
|
||||
type = obj->getType();
|
||||
}
|
||||
|
||||
// Add to data buffer for sending
|
||||
writeU16((u8*)buf, id);
|
||||
|
@ -1410,11 +1408,11 @@ void Server::AsyncRunStep()
|
|||
writeU8((u8*)buf, type);
|
||||
data_buffer.append(buf, 1);
|
||||
|
||||
if(obj)
|
||||
data_buffer.append(serializeLongString(
|
||||
obj->getClientInitializationData()));
|
||||
else
|
||||
if (obj) {
|
||||
data_buffer.append(serializeLongString(obj->getClientInitializationData()));
|
||||
}else{
|
||||
data_buffer.append(serializeLongString(""));
|
||||
}
|
||||
|
||||
// Add to known objects
|
||||
client->m_known_objects.insert(i.getNode()->getKey(), false);
|
||||
|
@ -1426,8 +1424,7 @@ void Server::AsyncRunStep()
|
|||
// Send packet
|
||||
SharedBuffer<u8> reply(2 + data_buffer.size());
|
||||
writeU16(&reply[0], TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD);
|
||||
memcpy((char*)&reply[2], data_buffer.c_str(),
|
||||
data_buffer.size());
|
||||
memcpy((char*)&reply[2], data_buffer.c_str(), data_buffer.size());
|
||||
// Send as reliable
|
||||
m_con.Send(client->peer_id, 0, reply, true);
|
||||
|
||||
|
|
|
@ -239,12 +239,21 @@ inline void writeU16(std::ostream &os, u16 p)
|
|||
writeU16((u8*)buf, p);
|
||||
os.write(buf, 2);
|
||||
}
|
||||
inline void writeS16(std::ostream &os, s16 i){
|
||||
writeU16(os, (u16)i);
|
||||
}
|
||||
inline u16 readU16(std::istream &is)
|
||||
{
|
||||
char buf[2];
|
||||
is.read(buf, 2);
|
||||
return readU16((u8*)buf);
|
||||
}
|
||||
inline u16 readS16(std::istream &is)
|
||||
{
|
||||
char buf[2];
|
||||
is.read(buf, 2);
|
||||
return readS16((u8*)buf);
|
||||
}
|
||||
|
||||
inline void writeU32(std::ostream &os, u32 p)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue