reorganized a lot of stuff and modified mapgen and objects slightly while doing it
parent
3b098fd5dc
commit
91cfbe2891
|
@ -9,7 +9,12 @@ src/jthread/CMakeFiles/*
|
||||||
src/jthread/Makefile
|
src/jthread/Makefile
|
||||||
src/jthread/cmake_config.h
|
src/jthread/cmake_config.h
|
||||||
src/jthread/cmake_install.cmake
|
src/jthread/cmake_install.cmake
|
||||||
|
src/.*.swp
|
||||||
|
src/sqlite/libsqlite3.a
|
||||||
|
src/session.vim
|
||||||
|
util/uloste.png
|
||||||
minetest.conf
|
minetest.conf
|
||||||
|
debug.txt
|
||||||
bin/
|
bin/
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CPackConfig.cmake
|
CPackConfig.cmake
|
||||||
|
|
BIN
data/oerkki1.png
BIN
data/oerkki1.png
Binary file not shown.
Before Width: | Height: | Size: 212 B After Width: | Height: | Size: 250 B |
Binary file not shown.
After Width: | Height: | Size: 341 B |
|
@ -61,6 +61,7 @@ configure_file(
|
||||||
)
|
)
|
||||||
|
|
||||||
set(common_SRCS
|
set(common_SRCS
|
||||||
|
content_sao.cpp
|
||||||
mapgen.cpp
|
mapgen.cpp
|
||||||
content_inventory.cpp
|
content_inventory.cpp
|
||||||
content_nodemeta.cpp
|
content_nodemeta.cpp
|
||||||
|
@ -102,6 +103,7 @@ set(common_SRCS
|
||||||
# Client sources
|
# Client sources
|
||||||
set(minetest_SRCS
|
set(minetest_SRCS
|
||||||
${common_SRCS}
|
${common_SRCS}
|
||||||
|
content_cao.cpp
|
||||||
mapblock_mesh.cpp
|
mapblock_mesh.cpp
|
||||||
farmesh.cpp
|
farmesh.cpp
|
||||||
keycode.cpp
|
keycode.cpp
|
||||||
|
|
|
@ -23,6 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "common_irrlicht.h"
|
#include "common_irrlicht.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#define ACTIVEOBJECT_TYPE_INVALID 0
|
||||||
|
// Other types are defined in content_object.h
|
||||||
|
|
||||||
struct ActiveObjectMessage
|
struct ActiveObjectMessage
|
||||||
{
|
{
|
||||||
ActiveObjectMessage(u16 id_, bool reliable_=true, std::string data_=""):
|
ActiveObjectMessage(u16 id_, bool reliable_=true, std::string data_=""):
|
||||||
|
@ -36,12 +39,6 @@ struct ActiveObjectMessage
|
||||||
std::string datastring;
|
std::string datastring;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ACTIVEOBJECT_TYPE_INVALID 0
|
|
||||||
#define ACTIVEOBJECT_TYPE_TEST 1
|
|
||||||
#define ACTIVEOBJECT_TYPE_ITEM 2
|
|
||||||
#define ACTIVEOBJECT_TYPE_RAT 3
|
|
||||||
#define ACTIVEOBJECT_TYPE_OERKKI1 4
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parent class for ServerActiveObject and ClientActiveObject
|
Parent class for ServerActiveObject and ClientActiveObject
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -21,9 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "utility.h"
|
|
||||||
#include "environment.h"
|
|
||||||
#include "tile.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ClientActiveObject
|
ClientActiveObject
|
||||||
|
@ -68,674 +65,4 @@ void ClientActiveObject::registerType(u16 type, Factory f)
|
||||||
m_types.insert(type, f);
|
m_types.insert(type, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
TestCAO
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Prototype
|
|
||||||
TestCAO proto_TestCAO;
|
|
||||||
|
|
||||||
TestCAO::TestCAO():
|
|
||||||
ClientActiveObject(0),
|
|
||||||
m_node(NULL),
|
|
||||||
m_position(v3f(0,10*BS,0))
|
|
||||||
{
|
|
||||||
ClientActiveObject::registerType(getType(), create);
|
|
||||||
}
|
|
||||||
|
|
||||||
TestCAO::~TestCAO()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientActiveObject* TestCAO::create()
|
|
||||||
{
|
|
||||||
return new TestCAO();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestCAO::addToScene(scene::ISceneManager *smgr)
|
|
||||||
{
|
|
||||||
if(m_node != NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
video::IVideoDriver* driver = smgr->getVideoDriver();
|
|
||||||
|
|
||||||
scene::SMesh *mesh = new scene::SMesh();
|
|
||||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
|
||||||
video::SColor c(255,255,255,255);
|
|
||||||
video::S3DVertex vertices[4] =
|
|
||||||
{
|
|
||||||
video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
|
|
||||||
video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
|
|
||||||
video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
|
|
||||||
video::S3DVertex(-BS/2,BS/4,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("rat.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;
|
|
||||||
// Add to mesh
|
|
||||||
mesh->addMeshBuffer(buf);
|
|
||||||
buf->drop();
|
|
||||||
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
|
||||||
mesh->drop();
|
|
||||||
updateNodePos();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestCAO::removeFromScene()
|
|
||||||
{
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_node->remove();
|
|
||||||
m_node = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestCAO::updateLight(u8 light_at_pos)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
v3s16 TestCAO::getLightPosition()
|
|
||||||
{
|
|
||||||
return floatToInt(m_position, BS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestCAO::updateNodePos()
|
|
||||||
{
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_node->setPosition(m_position);
|
|
||||||
//m_node->setRotation(v3f(0, 45, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestCAO::step(float dtime, ClientEnvironment *env)
|
|
||||||
{
|
|
||||||
if(m_node)
|
|
||||||
{
|
|
||||||
v3f rot = m_node->getRotation();
|
|
||||||
//dstream<<"dtime="<<dtime<<", rot.Y="<<rot.Y<<std::endl;
|
|
||||||
rot.Y += dtime * 180;
|
|
||||||
m_node->setRotation(rot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestCAO::processMessage(const std::string &data)
|
|
||||||
{
|
|
||||||
dstream<<"TestCAO: Got data: "<<data<<std::endl;
|
|
||||||
std::istringstream is(data, std::ios::binary);
|
|
||||||
u16 cmd;
|
|
||||||
is>>cmd;
|
|
||||||
if(cmd == 0)
|
|
||||||
{
|
|
||||||
v3f newpos;
|
|
||||||
is>>newpos.X;
|
|
||||||
is>>newpos.Y;
|
|
||||||
is>>newpos.Z;
|
|
||||||
m_position = newpos;
|
|
||||||
updateNodePos();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
ItemCAO
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "inventory.h"
|
|
||||||
|
|
||||||
// Prototype
|
|
||||||
ItemCAO proto_ItemCAO;
|
|
||||||
|
|
||||||
ItemCAO::ItemCAO():
|
|
||||||
ClientActiveObject(0),
|
|
||||||
m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.),
|
|
||||||
m_node(NULL),
|
|
||||||
m_position(v3f(0,10*BS,0))
|
|
||||||
{
|
|
||||||
ClientActiveObject::registerType(getType(), create);
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemCAO::~ItemCAO()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientActiveObject* ItemCAO::create()
|
|
||||||
{
|
|
||||||
return new ItemCAO();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemCAO::addToScene(scene::ISceneManager *smgr)
|
|
||||||
{
|
|
||||||
if(m_node != NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
video::IVideoDriver* driver = smgr->getVideoDriver();
|
|
||||||
|
|
||||||
scene::SMesh *mesh = new scene::SMesh();
|
|
||||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
|
||||||
video::SColor c(255,255,255,255);
|
|
||||||
video::S3DVertex vertices[4] =
|
|
||||||
{
|
|
||||||
/*video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
|
|
||||||
video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
|
|
||||||
video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
|
|
||||||
video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),*/
|
|
||||||
video::S3DVertex(BS/3.,0,0, 0,0,0, c, 0,1),
|
|
||||||
video::S3DVertex(-BS/3.,0,0, 0,0,0, c, 1,1),
|
|
||||||
video::S3DVertex(-BS/3.,0+BS*2./3.,0, 0,0,0, c, 1,0),
|
|
||||||
video::S3DVertex(BS/3.,0+BS*2./3.,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, NULL);
|
|
||||||
// Initialize with the stick texture
|
|
||||||
buf->getMaterial().setTexture
|
|
||||||
(0, driver->getTexture(getTexturePath("stick.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;
|
|
||||||
// Add to mesh
|
|
||||||
mesh->addMeshBuffer(buf);
|
|
||||||
buf->drop();
|
|
||||||
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
|
||||||
mesh->drop();
|
|
||||||
// Set it to use the materials of the meshbuffers directly.
|
|
||||||
// This is needed for changing the texture in the future
|
|
||||||
m_node->setReadOnlyMaterials(true);
|
|
||||||
updateNodePos();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemCAO::removeFromScene()
|
|
||||||
{
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_node->remove();
|
|
||||||
m_node = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemCAO::updateLight(u8 light_at_pos)
|
|
||||||
{
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
u8 li = decode_light(light_at_pos);
|
|
||||||
video::SColor color(255,li,li,li);
|
|
||||||
|
|
||||||
scene::IMesh *mesh = m_node->getMesh();
|
|
||||||
if(mesh == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
u16 mc = mesh->getMeshBufferCount();
|
|
||||||
for(u16 j=0; j<mc; j++)
|
|
||||||
{
|
|
||||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
|
||||||
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
|
|
||||||
u16 vc = buf->getVertexCount();
|
|
||||||
for(u16 i=0; i<vc; i++)
|
|
||||||
{
|
|
||||||
vertices[i].Color = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v3s16 ItemCAO::getLightPosition()
|
|
||||||
{
|
|
||||||
return floatToInt(m_position, BS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemCAO::updateNodePos()
|
|
||||||
{
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_node->setPosition(m_position);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemCAO::step(float dtime, ClientEnvironment *env)
|
|
||||||
{
|
|
||||||
if(m_node)
|
|
||||||
{
|
|
||||||
/*v3f rot = m_node->getRotation();
|
|
||||||
rot.Y += dtime * 120;
|
|
||||||
m_node->setRotation(rot);*/
|
|
||||||
LocalPlayer *player = env->getLocalPlayer();
|
|
||||||
assert(player);
|
|
||||||
v3f rot = m_node->getRotation();
|
|
||||||
rot.Y = 180.0 - (player->getYaw());
|
|
||||||
m_node->setRotation(rot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemCAO::processMessage(const std::string &data)
|
|
||||||
{
|
|
||||||
dstream<<"ItemCAO: Got message"<<std::endl;
|
|
||||||
std::istringstream is(data, std::ios::binary);
|
|
||||||
// command
|
|
||||||
u8 cmd = readU8(is);
|
|
||||||
if(cmd == 0)
|
|
||||||
{
|
|
||||||
// pos
|
|
||||||
m_position = readV3F1000(is);
|
|
||||||
updateNodePos();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemCAO::initialize(const std::string &data)
|
|
||||||
{
|
|
||||||
dstream<<"ItemCAO: Got init data"<<std::endl;
|
|
||||||
|
|
||||||
{
|
|
||||||
std::istringstream is(data, std::ios::binary);
|
|
||||||
// version
|
|
||||||
u8 version = readU8(is);
|
|
||||||
// check version
|
|
||||||
if(version != 0)
|
|
||||||
return;
|
|
||||||
// pos
|
|
||||||
m_position = readV3F1000(is);
|
|
||||||
// inventorystring
|
|
||||||
m_inventorystring = deSerializeString(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateNodePos();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Update image of node
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
scene::IMesh *mesh = m_node->getMesh();
|
|
||||||
|
|
||||||
if(mesh == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
|
|
||||||
|
|
||||||
if(buf == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Create an inventory item to see what is its image
|
|
||||||
std::istringstream is(m_inventorystring, std::ios_base::binary);
|
|
||||||
video::ITexture *texture = NULL;
|
|
||||||
try{
|
|
||||||
InventoryItem *item = NULL;
|
|
||||||
item = InventoryItem::deSerialize(is);
|
|
||||||
dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
|
|
||||||
<<m_inventorystring<<"\" -> item="<<item
|
|
||||||
<<std::endl;
|
|
||||||
if(item)
|
|
||||||
{
|
|
||||||
texture = item->getImage();
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(SerializationError &e)
|
|
||||||
{
|
|
||||||
dstream<<"WARNING: "<<__FUNCTION_NAME
|
|
||||||
<<": error deSerializing inventorystring \""
|
|
||||||
<<m_inventorystring<<"\""<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set meshbuffer texture
|
|
||||||
buf->getMaterial().setTexture(0, texture);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
RatCAO
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "inventory.h"
|
|
||||||
|
|
||||||
// Prototype
|
|
||||||
RatCAO proto_RatCAO;
|
|
||||||
|
|
||||||
RatCAO::RatCAO():
|
|
||||||
ClientActiveObject(0),
|
|
||||||
m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
|
|
||||||
m_node(NULL),
|
|
||||||
m_position(v3f(0,10*BS,0)),
|
|
||||||
m_yaw(0)
|
|
||||||
{
|
|
||||||
ClientActiveObject::registerType(getType(), create);
|
|
||||||
}
|
|
||||||
|
|
||||||
RatCAO::~RatCAO()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientActiveObject* RatCAO::create()
|
|
||||||
{
|
|
||||||
return new RatCAO();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RatCAO::addToScene(scene::ISceneManager *smgr)
|
|
||||||
{
|
|
||||||
if(m_node != NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
video::IVideoDriver* driver = smgr->getVideoDriver();
|
|
||||||
|
|
||||||
scene::SMesh *mesh = new scene::SMesh();
|
|
||||||
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, NULL);
|
|
||||||
buf->getMaterial().setTexture
|
|
||||||
(0, driver->getTexture(getTexturePath("rat.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;
|
|
||||||
// Add to mesh
|
|
||||||
mesh->addMeshBuffer(buf);
|
|
||||||
buf->drop();
|
|
||||||
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
|
||||||
mesh->drop();
|
|
||||||
// Set it to use the materials of the meshbuffers directly.
|
|
||||||
// This is needed for changing the texture in the future
|
|
||||||
m_node->setReadOnlyMaterials(true);
|
|
||||||
updateNodePos();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RatCAO::removeFromScene()
|
|
||||||
{
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_node->remove();
|
|
||||||
m_node = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RatCAO::updateLight(u8 light_at_pos)
|
|
||||||
{
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
u8 li = decode_light(light_at_pos);
|
|
||||||
video::SColor color(255,li,li,li);
|
|
||||||
|
|
||||||
scene::IMesh *mesh = m_node->getMesh();
|
|
||||||
if(mesh == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
u16 mc = mesh->getMeshBufferCount();
|
|
||||||
for(u16 j=0; j<mc; j++)
|
|
||||||
{
|
|
||||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
|
||||||
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
|
|
||||||
u16 vc = buf->getVertexCount();
|
|
||||||
for(u16 i=0; i<vc; i++)
|
|
||||||
{
|
|
||||||
vertices[i].Color = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v3s16 RatCAO::getLightPosition()
|
|
||||||
{
|
|
||||||
return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RatCAO::updateNodePos()
|
|
||||||
{
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//m_node->setPosition(m_position);
|
|
||||||
m_node->setPosition(pos_translator.vect_show);
|
|
||||||
|
|
||||||
v3f rot = m_node->getRotation();
|
|
||||||
rot.Y = 180.0 - m_yaw;
|
|
||||||
m_node->setRotation(rot);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RatCAO::step(float dtime, ClientEnvironment *env)
|
|
||||||
{
|
|
||||||
pos_translator.translate(dtime);
|
|
||||||
updateNodePos();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RatCAO::processMessage(const std::string &data)
|
|
||||||
{
|
|
||||||
//dstream<<"RatCAO: Got message"<<std::endl;
|
|
||||||
std::istringstream is(data, std::ios::binary);
|
|
||||||
// command
|
|
||||||
u8 cmd = readU8(is);
|
|
||||||
if(cmd == 0)
|
|
||||||
{
|
|
||||||
// pos
|
|
||||||
m_position = readV3F1000(is);
|
|
||||||
pos_translator.update(m_position);
|
|
||||||
// yaw
|
|
||||||
m_yaw = readF1000(is);
|
|
||||||
updateNodePos();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RatCAO::initialize(const std::string &data)
|
|
||||||
{
|
|
||||||
//dstream<<"RatCAO: Got init data"<<std::endl;
|
|
||||||
|
|
||||||
{
|
|
||||||
std::istringstream is(data, std::ios::binary);
|
|
||||||
// version
|
|
||||||
u8 version = readU8(is);
|
|
||||||
// check version
|
|
||||||
if(version != 0)
|
|
||||||
return;
|
|
||||||
// pos
|
|
||||||
m_position = readV3F1000(is);
|
|
||||||
pos_translator.init(m_position);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateNodePos();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Oerkki1CAO
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "inventory.h"
|
|
||||||
|
|
||||||
// Prototype
|
|
||||||
Oerkki1CAO proto_Oerkki1CAO;
|
|
||||||
|
|
||||||
Oerkki1CAO::Oerkki1CAO():
|
|
||||||
ClientActiveObject(0),
|
|
||||||
m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.),
|
|
||||||
m_node(NULL),
|
|
||||||
m_position(v3f(0,10*BS,0)),
|
|
||||||
m_yaw(0)
|
|
||||||
{
|
|
||||||
ClientActiveObject::registerType(getType(), create);
|
|
||||||
}
|
|
||||||
|
|
||||||
Oerkki1CAO::~Oerkki1CAO()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientActiveObject* Oerkki1CAO::create()
|
|
||||||
{
|
|
||||||
return new Oerkki1CAO();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Oerkki1CAO::addToScene(scene::ISceneManager *smgr)
|
|
||||||
{
|
|
||||||
if(m_node != NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
video::IVideoDriver* driver = smgr->getVideoDriver();
|
|
||||||
|
|
||||||
scene::SMesh *mesh = new scene::SMesh();
|
|
||||||
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, NULL);
|
|
||||||
buf->getMaterial().setTexture
|
|
||||||
(0, driver->getTexture(getTexturePath("oerkki1.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;
|
|
||||||
// Add to mesh
|
|
||||||
mesh->addMeshBuffer(buf);
|
|
||||||
buf->drop();
|
|
||||||
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
|
||||||
mesh->drop();
|
|
||||||
// Set it to use the materials of the meshbuffers directly.
|
|
||||||
// This is needed for changing the texture in the future
|
|
||||||
m_node->setReadOnlyMaterials(true);
|
|
||||||
updateNodePos();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Oerkki1CAO::removeFromScene()
|
|
||||||
{
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_node->remove();
|
|
||||||
m_node = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Oerkki1CAO::updateLight(u8 light_at_pos)
|
|
||||||
{
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(light_at_pos <= 2)
|
|
||||||
{
|
|
||||||
m_node->setVisible(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_node->setVisible(true);
|
|
||||||
|
|
||||||
u8 li = decode_light(light_at_pos);
|
|
||||||
video::SColor color(255,li,li,li);
|
|
||||||
|
|
||||||
scene::IMesh *mesh = m_node->getMesh();
|
|
||||||
if(mesh == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
u16 mc = mesh->getMeshBufferCount();
|
|
||||||
for(u16 j=0; j<mc; j++)
|
|
||||||
{
|
|
||||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
|
||||||
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
|
|
||||||
u16 vc = buf->getVertexCount();
|
|
||||||
for(u16 i=0; i<vc; i++)
|
|
||||||
{
|
|
||||||
vertices[i].Color = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v3s16 Oerkki1CAO::getLightPosition()
|
|
||||||
{
|
|
||||||
return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Oerkki1CAO::updateNodePos()
|
|
||||||
{
|
|
||||||
if(m_node == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//m_node->setPosition(m_position);
|
|
||||||
m_node->setPosition(pos_translator.vect_show);
|
|
||||||
|
|
||||||
v3f rot = m_node->getRotation();
|
|
||||||
rot.Y = 180.0 - m_yaw + 90.0;
|
|
||||||
m_node->setRotation(rot);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Oerkki1CAO::step(float dtime, ClientEnvironment *env)
|
|
||||||
{
|
|
||||||
pos_translator.translate(dtime);
|
|
||||||
updateNodePos();
|
|
||||||
|
|
||||||
LocalPlayer *player = env->getLocalPlayer();
|
|
||||||
assert(player);
|
|
||||||
|
|
||||||
v3f playerpos = player->getPosition();
|
|
||||||
v2f playerpos_2d(playerpos.X,playerpos.Z);
|
|
||||||
v2f objectpos_2d(m_position.X,m_position.Z);
|
|
||||||
|
|
||||||
if(fabs(m_position.Y - playerpos.Y) < 3.0*BS &&
|
|
||||||
objectpos_2d.getDistanceFrom(playerpos_2d) < 1.0*BS)
|
|
||||||
{
|
|
||||||
if(m_attack_interval.step(dtime, 0.5))
|
|
||||||
{
|
|
||||||
env->damageLocalPlayer(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Oerkki1CAO::processMessage(const std::string &data)
|
|
||||||
{
|
|
||||||
//dstream<<"Oerkki1CAO: Got message"<<std::endl;
|
|
||||||
std::istringstream is(data, std::ios::binary);
|
|
||||||
// command
|
|
||||||
u8 cmd = readU8(is);
|
|
||||||
if(cmd == 0)
|
|
||||||
{
|
|
||||||
// pos
|
|
||||||
m_position = readV3F1000(is);
|
|
||||||
pos_translator.update(m_position);
|
|
||||||
// yaw
|
|
||||||
m_yaw = readF1000(is);
|
|
||||||
updateNodePos();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Oerkki1CAO::initialize(const std::string &data)
|
|
||||||
{
|
|
||||||
//dstream<<"Oerkki1CAO: Got init data"<<std::endl;
|
|
||||||
|
|
||||||
{
|
|
||||||
std::istringstream is(data, std::ios::binary);
|
|
||||||
// version
|
|
||||||
u8 version = readU8(is);
|
|
||||||
// check version
|
|
||||||
if(version != 0)
|
|
||||||
return;
|
|
||||||
// pos
|
|
||||||
m_position = readV3F1000(is);
|
|
||||||
pos_translator.init(m_position);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateNodePos();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include "common_irrlicht.h"
|
#include "common_irrlicht.h"
|
||||||
#include "activeobject.h"
|
#include "activeobject.h"
|
||||||
#include "utility.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -36,63 +35,6 @@ Some planning
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
SmoothTranslator
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct SmoothTranslator
|
|
||||||
{
|
|
||||||
v3f vect_old;
|
|
||||||
f32 anim_counter;
|
|
||||||
f32 anim_time;
|
|
||||||
f32 anim_time_counter;
|
|
||||||
v3f vect_show;
|
|
||||||
v3f vect_aim;
|
|
||||||
|
|
||||||
SmoothTranslator():
|
|
||||||
vect_old(0,0,0),
|
|
||||||
anim_counter(0),
|
|
||||||
anim_time(0),
|
|
||||||
anim_time_counter(0),
|
|
||||||
vect_show(0,0,0),
|
|
||||||
vect_aim(0,0,0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void init(v3f vect)
|
|
||||||
{
|
|
||||||
vect_old = vect;
|
|
||||||
vect_show = vect;
|
|
||||||
vect_aim = vect;
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(v3f vect_new)
|
|
||||||
{
|
|
||||||
vect_old = vect_show;
|
|
||||||
vect_aim = vect_new;
|
|
||||||
if(anim_time < 0.001 || anim_time > 1.0)
|
|
||||||
anim_time = anim_time_counter;
|
|
||||||
else
|
|
||||||
anim_time = anim_time * 0.9 + anim_time_counter * 0.1;
|
|
||||||
anim_time_counter = 0;
|
|
||||||
anim_counter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void translate(f32 dtime)
|
|
||||||
{
|
|
||||||
anim_time_counter = anim_time_counter + dtime;
|
|
||||||
anim_counter = anim_counter + dtime;
|
|
||||||
v3f vect_move = vect_aim - vect_old;
|
|
||||||
f32 moveratio = 1.0;
|
|
||||||
if(anim_time > 0.001)
|
|
||||||
moveratio = anim_time_counter / anim_time;
|
|
||||||
// Move a bit less than should, to avoid oscillation
|
|
||||||
moveratio = moveratio * 0.8;
|
|
||||||
if(moveratio > 1.5)
|
|
||||||
moveratio = 1.5;
|
|
||||||
vect_show = vect_old + vect_move * moveratio;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ClientEnvironment;
|
class ClientEnvironment;
|
||||||
|
|
||||||
class ClientActiveObject : public ActiveObject
|
class ClientActiveObject : public ActiveObject
|
||||||
|
@ -153,164 +95,5 @@ struct DistanceSortedActiveObject
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ItemCAO : public ClientActiveObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ItemCAO();
|
|
||||||
virtual ~ItemCAO();
|
|
||||||
|
|
||||||
u8 getType() const
|
|
||||||
{
|
|
||||||
return ACTIVEOBJECT_TYPE_ITEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
core::aabbox3d<f32> m_selection_box;
|
|
||||||
scene::IMeshSceneNode *m_node;
|
|
||||||
v3f m_position;
|
|
||||||
std::string m_inventorystring;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
RatCAO
|
|
||||||
*/
|
|
||||||
|
|
||||||
class RatCAO : public ClientActiveObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RatCAO();
|
|
||||||
virtual ~RatCAO();
|
|
||||||
|
|
||||||
u8 getType() const
|
|
||||||
{
|
|
||||||
return ACTIVEOBJECT_TYPE_RAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
core::aabbox3d<f32> m_selection_box;
|
|
||||||
scene::IMeshSceneNode *m_node;
|
|
||||||
v3f m_position;
|
|
||||||
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;}
|
|
||||||
//{return m_position;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
IntervalLimiter m_attack_interval;
|
|
||||||
core::aabbox3d<f32> m_selection_box;
|
|
||||||
scene::IMeshSceneNode *m_node;
|
|
||||||
v3f m_position;
|
|
||||||
float m_yaw;
|
|
||||||
SmoothTranslator pos_translator;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -182,4 +182,58 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
|
||||||
|
const core::aabbox3d<f32> &box_0,
|
||||||
|
f32 dtime, v3f &pos_f, v3f &speed_f)
|
||||||
|
{
|
||||||
|
collisionMoveResult final_result;
|
||||||
|
|
||||||
|
// Maximum time increment (for collision detection etc)
|
||||||
|
// time = distance / speed
|
||||||
|
f32 dtime_max_increment = pos_max_d / speed_f.getLength();
|
||||||
|
|
||||||
|
// Maximum time increment is 10ms or lower
|
||||||
|
if(dtime_max_increment > 0.01)
|
||||||
|
dtime_max_increment = 0.01;
|
||||||
|
|
||||||
|
// Don't allow overly huge dtime
|
||||||
|
if(dtime > 2.0)
|
||||||
|
dtime = 2.0;
|
||||||
|
|
||||||
|
f32 dtime_downcount = dtime;
|
||||||
|
|
||||||
|
u32 loopcount = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
loopcount++;
|
||||||
|
|
||||||
|
f32 dtime_part;
|
||||||
|
if(dtime_downcount > dtime_max_increment)
|
||||||
|
{
|
||||||
|
dtime_part = dtime_max_increment;
|
||||||
|
dtime_downcount -= dtime_part;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dtime_part = dtime_downcount;
|
||||||
|
/*
|
||||||
|
Setting this to 0 (no -=dtime_part) disables an infinite loop
|
||||||
|
when dtime_part is so small that dtime_downcount -= dtime_part
|
||||||
|
does nothing
|
||||||
|
*/
|
||||||
|
dtime_downcount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
collisionMoveResult result = collisionMoveSimple(map, pos_max_d,
|
||||||
|
box_0, dtime_part, pos_f, speed_f);
|
||||||
|
|
||||||
|
if(result.touching_ground)
|
||||||
|
final_result.touching_ground = true;
|
||||||
|
}
|
||||||
|
while(dtime_downcount > 0.001);
|
||||||
|
|
||||||
|
|
||||||
|
return final_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,15 @@ struct collisionMoveResult
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Moves using a single iteration; speed should not exceed pos_max_d/dtime
|
||||||
collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
|
collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
|
||||||
const core::aabbox3d<f32> &box_0,
|
const core::aabbox3d<f32> &box_0,
|
||||||
f32 dtime, v3f &pos_f, v3f &speed_f);
|
f32 dtime, v3f &pos_f, v3f &speed_f);
|
||||||
//{return collisionMoveResult();}
|
|
||||||
|
// Moves using as many iterations as needed
|
||||||
|
collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
|
||||||
|
const core::aabbox3d<f32> &box_0,
|
||||||
|
f32 dtime, v3f &pos_f, v3f &speed_f);
|
||||||
|
|
||||||
enum CollisionType
|
enum CollisionType
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,753 @@
|
||||||
|
/*
|
||||||
|
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_cao.h"
|
||||||
|
#include "tile.h"
|
||||||
|
#include "environment.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
TestCAO
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Prototype
|
||||||
|
TestCAO proto_TestCAO;
|
||||||
|
|
||||||
|
TestCAO::TestCAO():
|
||||||
|
ClientActiveObject(0),
|
||||||
|
m_node(NULL),
|
||||||
|
m_position(v3f(0,10*BS,0))
|
||||||
|
{
|
||||||
|
ClientActiveObject::registerType(getType(), create);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestCAO::~TestCAO()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientActiveObject* TestCAO::create()
|
||||||
|
{
|
||||||
|
return new TestCAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCAO::addToScene(scene::ISceneManager *smgr)
|
||||||
|
{
|
||||||
|
if(m_node != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||||
|
|
||||||
|
scene::SMesh *mesh = new scene::SMesh();
|
||||||
|
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||||
|
video::SColor c(255,255,255,255);
|
||||||
|
video::S3DVertex vertices[4] =
|
||||||
|
{
|
||||||
|
video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
|
||||||
|
video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
|
||||||
|
video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
|
||||||
|
video::S3DVertex(-BS/2,BS/4,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("rat.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;
|
||||||
|
// Add to mesh
|
||||||
|
mesh->addMeshBuffer(buf);
|
||||||
|
buf->drop();
|
||||||
|
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
||||||
|
mesh->drop();
|
||||||
|
updateNodePos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCAO::removeFromScene()
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_node->remove();
|
||||||
|
m_node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCAO::updateLight(u8 light_at_pos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
v3s16 TestCAO::getLightPosition()
|
||||||
|
{
|
||||||
|
return floatToInt(m_position, BS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCAO::updateNodePos()
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_node->setPosition(m_position);
|
||||||
|
//m_node->setRotation(v3f(0, 45, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCAO::step(float dtime, ClientEnvironment *env)
|
||||||
|
{
|
||||||
|
if(m_node)
|
||||||
|
{
|
||||||
|
v3f rot = m_node->getRotation();
|
||||||
|
//dstream<<"dtime="<<dtime<<", rot.Y="<<rot.Y<<std::endl;
|
||||||
|
rot.Y += dtime * 180;
|
||||||
|
m_node->setRotation(rot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCAO::processMessage(const std::string &data)
|
||||||
|
{
|
||||||
|
dstream<<"TestCAO: Got data: "<<data<<std::endl;
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
u16 cmd;
|
||||||
|
is>>cmd;
|
||||||
|
if(cmd == 0)
|
||||||
|
{
|
||||||
|
v3f newpos;
|
||||||
|
is>>newpos.X;
|
||||||
|
is>>newpos.Y;
|
||||||
|
is>>newpos.Z;
|
||||||
|
m_position = newpos;
|
||||||
|
updateNodePos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ItemCAO
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "inventory.h"
|
||||||
|
|
||||||
|
// Prototype
|
||||||
|
ItemCAO proto_ItemCAO;
|
||||||
|
|
||||||
|
ItemCAO::ItemCAO():
|
||||||
|
ClientActiveObject(0),
|
||||||
|
m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.),
|
||||||
|
m_node(NULL),
|
||||||
|
m_position(v3f(0,10*BS,0))
|
||||||
|
{
|
||||||
|
ClientActiveObject::registerType(getType(), create);
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemCAO::~ItemCAO()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientActiveObject* ItemCAO::create()
|
||||||
|
{
|
||||||
|
return new ItemCAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemCAO::addToScene(scene::ISceneManager *smgr)
|
||||||
|
{
|
||||||
|
if(m_node != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||||
|
|
||||||
|
scene::SMesh *mesh = new scene::SMesh();
|
||||||
|
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||||
|
video::SColor c(255,255,255,255);
|
||||||
|
video::S3DVertex vertices[4] =
|
||||||
|
{
|
||||||
|
/*video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
|
||||||
|
video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
|
||||||
|
video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
|
||||||
|
video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),*/
|
||||||
|
video::S3DVertex(BS/3.,0,0, 0,0,0, c, 0,1),
|
||||||
|
video::S3DVertex(-BS/3.,0,0, 0,0,0, c, 1,1),
|
||||||
|
video::S3DVertex(-BS/3.,0+BS*2./3.,0, 0,0,0, c, 1,0),
|
||||||
|
video::S3DVertex(BS/3.,0+BS*2./3.,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, NULL);
|
||||||
|
// Initialize with the stick texture
|
||||||
|
buf->getMaterial().setTexture
|
||||||
|
(0, driver->getTexture(getTexturePath("stick.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;
|
||||||
|
// Add to mesh
|
||||||
|
mesh->addMeshBuffer(buf);
|
||||||
|
buf->drop();
|
||||||
|
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
||||||
|
mesh->drop();
|
||||||
|
// Set it to use the materials of the meshbuffers directly.
|
||||||
|
// This is needed for changing the texture in the future
|
||||||
|
m_node->setReadOnlyMaterials(true);
|
||||||
|
updateNodePos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemCAO::removeFromScene()
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_node->remove();
|
||||||
|
m_node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemCAO::updateLight(u8 light_at_pos)
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u8 li = decode_light(light_at_pos);
|
||||||
|
video::SColor color(255,li,li,li);
|
||||||
|
|
||||||
|
scene::IMesh *mesh = m_node->getMesh();
|
||||||
|
if(mesh == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u16 mc = mesh->getMeshBufferCount();
|
||||||
|
for(u16 j=0; j<mc; j++)
|
||||||
|
{
|
||||||
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||||
|
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
|
||||||
|
u16 vc = buf->getVertexCount();
|
||||||
|
for(u16 i=0; i<vc; i++)
|
||||||
|
{
|
||||||
|
vertices[i].Color = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v3s16 ItemCAO::getLightPosition()
|
||||||
|
{
|
||||||
|
return floatToInt(m_position, BS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemCAO::updateNodePos()
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_node->setPosition(m_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemCAO::step(float dtime, ClientEnvironment *env)
|
||||||
|
{
|
||||||
|
if(m_node)
|
||||||
|
{
|
||||||
|
/*v3f rot = m_node->getRotation();
|
||||||
|
rot.Y += dtime * 120;
|
||||||
|
m_node->setRotation(rot);*/
|
||||||
|
LocalPlayer *player = env->getLocalPlayer();
|
||||||
|
assert(player);
|
||||||
|
v3f rot = m_node->getRotation();
|
||||||
|
rot.Y = 180.0 - (player->getYaw());
|
||||||
|
m_node->setRotation(rot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemCAO::processMessage(const std::string &data)
|
||||||
|
{
|
||||||
|
dstream<<"ItemCAO: Got message"<<std::endl;
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
// command
|
||||||
|
u8 cmd = readU8(is);
|
||||||
|
if(cmd == 0)
|
||||||
|
{
|
||||||
|
// pos
|
||||||
|
m_position = readV3F1000(is);
|
||||||
|
updateNodePos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemCAO::initialize(const std::string &data)
|
||||||
|
{
|
||||||
|
dstream<<"ItemCAO: Got init data"<<std::endl;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
// version
|
||||||
|
u8 version = readU8(is);
|
||||||
|
// check version
|
||||||
|
if(version != 0)
|
||||||
|
return;
|
||||||
|
// pos
|
||||||
|
m_position = readV3F1000(is);
|
||||||
|
// inventorystring
|
||||||
|
m_inventorystring = deSerializeString(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateNodePos();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update image of node
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
scene::IMesh *mesh = m_node->getMesh();
|
||||||
|
|
||||||
|
if(mesh == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
|
||||||
|
|
||||||
|
if(buf == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Create an inventory item to see what is its image
|
||||||
|
std::istringstream is(m_inventorystring, std::ios_base::binary);
|
||||||
|
video::ITexture *texture = NULL;
|
||||||
|
try{
|
||||||
|
InventoryItem *item = NULL;
|
||||||
|
item = InventoryItem::deSerialize(is);
|
||||||
|
dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
|
||||||
|
<<m_inventorystring<<"\" -> item="<<item
|
||||||
|
<<std::endl;
|
||||||
|
if(item)
|
||||||
|
{
|
||||||
|
texture = item->getImage();
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(SerializationError &e)
|
||||||
|
{
|
||||||
|
dstream<<"WARNING: "<<__FUNCTION_NAME
|
||||||
|
<<": error deSerializing inventorystring \""
|
||||||
|
<<m_inventorystring<<"\""<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set meshbuffer texture
|
||||||
|
buf->getMaterial().setTexture(0, texture);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
RatCAO
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "inventory.h"
|
||||||
|
|
||||||
|
// Prototype
|
||||||
|
RatCAO proto_RatCAO;
|
||||||
|
|
||||||
|
RatCAO::RatCAO():
|
||||||
|
ClientActiveObject(0),
|
||||||
|
m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
|
||||||
|
m_node(NULL),
|
||||||
|
m_position(v3f(0,10*BS,0)),
|
||||||
|
m_yaw(0)
|
||||||
|
{
|
||||||
|
ClientActiveObject::registerType(getType(), create);
|
||||||
|
}
|
||||||
|
|
||||||
|
RatCAO::~RatCAO()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientActiveObject* RatCAO::create()
|
||||||
|
{
|
||||||
|
return new RatCAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RatCAO::addToScene(scene::ISceneManager *smgr)
|
||||||
|
{
|
||||||
|
if(m_node != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||||
|
|
||||||
|
scene::SMesh *mesh = new scene::SMesh();
|
||||||
|
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, NULL);
|
||||||
|
buf->getMaterial().setTexture
|
||||||
|
(0, driver->getTexture(getTexturePath("rat.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;
|
||||||
|
// Add to mesh
|
||||||
|
mesh->addMeshBuffer(buf);
|
||||||
|
buf->drop();
|
||||||
|
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
||||||
|
mesh->drop();
|
||||||
|
// Set it to use the materials of the meshbuffers directly.
|
||||||
|
// This is needed for changing the texture in the future
|
||||||
|
m_node->setReadOnlyMaterials(true);
|
||||||
|
updateNodePos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RatCAO::removeFromScene()
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_node->remove();
|
||||||
|
m_node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RatCAO::updateLight(u8 light_at_pos)
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u8 li = decode_light(light_at_pos);
|
||||||
|
video::SColor color(255,li,li,li);
|
||||||
|
|
||||||
|
scene::IMesh *mesh = m_node->getMesh();
|
||||||
|
if(mesh == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u16 mc = mesh->getMeshBufferCount();
|
||||||
|
for(u16 j=0; j<mc; j++)
|
||||||
|
{
|
||||||
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||||
|
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
|
||||||
|
u16 vc = buf->getVertexCount();
|
||||||
|
for(u16 i=0; i<vc; i++)
|
||||||
|
{
|
||||||
|
vertices[i].Color = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v3s16 RatCAO::getLightPosition()
|
||||||
|
{
|
||||||
|
return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RatCAO::updateNodePos()
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//m_node->setPosition(m_position);
|
||||||
|
m_node->setPosition(pos_translator.vect_show);
|
||||||
|
|
||||||
|
v3f rot = m_node->getRotation();
|
||||||
|
rot.Y = 180.0 - m_yaw;
|
||||||
|
m_node->setRotation(rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RatCAO::step(float dtime, ClientEnvironment *env)
|
||||||
|
{
|
||||||
|
pos_translator.translate(dtime);
|
||||||
|
updateNodePos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RatCAO::processMessage(const std::string &data)
|
||||||
|
{
|
||||||
|
//dstream<<"RatCAO: Got message"<<std::endl;
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
// command
|
||||||
|
u8 cmd = readU8(is);
|
||||||
|
if(cmd == 0)
|
||||||
|
{
|
||||||
|
// pos
|
||||||
|
m_position = readV3F1000(is);
|
||||||
|
pos_translator.update(m_position);
|
||||||
|
// yaw
|
||||||
|
m_yaw = readF1000(is);
|
||||||
|
updateNodePos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RatCAO::initialize(const std::string &data)
|
||||||
|
{
|
||||||
|
//dstream<<"RatCAO: Got init data"<<std::endl;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
// version
|
||||||
|
u8 version = readU8(is);
|
||||||
|
// check version
|
||||||
|
if(version != 0)
|
||||||
|
return;
|
||||||
|
// pos
|
||||||
|
m_position = readV3F1000(is);
|
||||||
|
pos_translator.init(m_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateNodePos();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Oerkki1CAO
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "inventory.h"
|
||||||
|
|
||||||
|
// Prototype
|
||||||
|
Oerkki1CAO proto_Oerkki1CAO;
|
||||||
|
|
||||||
|
Oerkki1CAO::Oerkki1CAO():
|
||||||
|
ClientActiveObject(0),
|
||||||
|
m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.),
|
||||||
|
m_node(NULL),
|
||||||
|
m_position(v3f(0,10*BS,0)),
|
||||||
|
m_yaw(0),
|
||||||
|
m_damage_visual_timer(0),
|
||||||
|
m_damage_texture_enabled(false)
|
||||||
|
{
|
||||||
|
ClientActiveObject::registerType(getType(), create);
|
||||||
|
}
|
||||||
|
|
||||||
|
Oerkki1CAO::~Oerkki1CAO()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientActiveObject* Oerkki1CAO::create()
|
||||||
|
{
|
||||||
|
return new Oerkki1CAO();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oerkki1CAO::addToScene(scene::ISceneManager *smgr)
|
||||||
|
{
|
||||||
|
if(m_node != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||||
|
|
||||||
|
scene::SMesh *mesh = new scene::SMesh();
|
||||||
|
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||||
|
video::SColor c(255,255,255,255);
|
||||||
|
video::S3DVertex vertices[4] =
|
||||||
|
{
|
||||||
|
video::S3DVertex(-BS/2-BS,0,0, 0,0,0, c, 0,1),
|
||||||
|
video::S3DVertex(BS/2+BS,0,0, 0,0,0, c, 1,1),
|
||||||
|
video::S3DVertex(BS/2+BS,BS*2,0, 0,0,0, c, 1,0),
|
||||||
|
video::S3DVertex(-BS/2-BS,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, NULL);
|
||||||
|
buf->getMaterial().setTexture
|
||||||
|
(0, driver->getTexture(getTexturePath("oerkki1.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;
|
||||||
|
// Add to mesh
|
||||||
|
mesh->addMeshBuffer(buf);
|
||||||
|
buf->drop();
|
||||||
|
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
||||||
|
mesh->drop();
|
||||||
|
// Set it to use the materials of the meshbuffers directly.
|
||||||
|
// This is needed for changing the texture in the future
|
||||||
|
m_node->setReadOnlyMaterials(true);
|
||||||
|
updateNodePos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oerkki1CAO::removeFromScene()
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_node->remove();
|
||||||
|
m_node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oerkki1CAO::updateLight(u8 light_at_pos)
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(light_at_pos <= 2)
|
||||||
|
{
|
||||||
|
m_node->setVisible(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_node->setVisible(true);
|
||||||
|
|
||||||
|
u8 li = decode_light(light_at_pos);
|
||||||
|
video::SColor color(255,li,li,li);
|
||||||
|
|
||||||
|
scene::IMesh *mesh = m_node->getMesh();
|
||||||
|
if(mesh == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u16 mc = mesh->getMeshBufferCount();
|
||||||
|
for(u16 j=0; j<mc; j++)
|
||||||
|
{
|
||||||
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||||
|
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
|
||||||
|
u16 vc = buf->getVertexCount();
|
||||||
|
for(u16 i=0; i<vc; i++)
|
||||||
|
{
|
||||||
|
vertices[i].Color = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v3s16 Oerkki1CAO::getLightPosition()
|
||||||
|
{
|
||||||
|
return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oerkki1CAO::updateNodePos()
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//m_node->setPosition(m_position);
|
||||||
|
m_node->setPosition(pos_translator.vect_show);
|
||||||
|
|
||||||
|
v3f rot = m_node->getRotation();
|
||||||
|
rot.Y = 180.0 - m_yaw + 90.0;
|
||||||
|
m_node->setRotation(rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oerkki1CAO::step(float dtime, ClientEnvironment *env)
|
||||||
|
{
|
||||||
|
pos_translator.translate(dtime);
|
||||||
|
updateNodePos();
|
||||||
|
|
||||||
|
LocalPlayer *player = env->getLocalPlayer();
|
||||||
|
assert(player);
|
||||||
|
|
||||||
|
v3f playerpos = player->getPosition();
|
||||||
|
v2f playerpos_2d(playerpos.X,playerpos.Z);
|
||||||
|
v2f objectpos_2d(m_position.X,m_position.Z);
|
||||||
|
|
||||||
|
if(fabs(m_position.Y - playerpos.Y) < 3.0*BS &&
|
||||||
|
objectpos_2d.getDistanceFrom(playerpos_2d) < 1.5*BS)
|
||||||
|
{
|
||||||
|
if(m_attack_interval.step(dtime, 0.5))
|
||||||
|
{
|
||||||
|
env->damageLocalPlayer(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_damage_visual_timer > 0)
|
||||||
|
{
|
||||||
|
if(!m_damage_texture_enabled)
|
||||||
|
{
|
||||||
|
// Enable damage texture
|
||||||
|
if(m_node)
|
||||||
|
{
|
||||||
|
video::IVideoDriver* driver =
|
||||||
|
m_node->getSceneManager()->getVideoDriver();
|
||||||
|
|
||||||
|
scene::IMesh *mesh = m_node->getMesh();
|
||||||
|
if(mesh == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u16 mc = mesh->getMeshBufferCount();
|
||||||
|
for(u16 j=0; j<mc; j++)
|
||||||
|
{
|
||||||
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||||
|
buf->getMaterial().setTexture(0, driver->getTexture(
|
||||||
|
getTexturePath("oerkki1_damaged.png").c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_damage_texture_enabled = true;
|
||||||
|
}
|
||||||
|
m_damage_visual_timer -= dtime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(m_damage_texture_enabled)
|
||||||
|
{
|
||||||
|
// Disable damage texture
|
||||||
|
if(m_node)
|
||||||
|
{
|
||||||
|
video::IVideoDriver* driver =
|
||||||
|
m_node->getSceneManager()->getVideoDriver();
|
||||||
|
|
||||||
|
scene::IMesh *mesh = m_node->getMesh();
|
||||||
|
if(mesh == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u16 mc = mesh->getMeshBufferCount();
|
||||||
|
for(u16 j=0; j<mc; j++)
|
||||||
|
{
|
||||||
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||||
|
buf->getMaterial().setTexture(0, driver->getTexture(
|
||||||
|
getTexturePath("oerkki1.png").c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_damage_texture_enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oerkki1CAO::processMessage(const std::string &data)
|
||||||
|
{
|
||||||
|
//dstream<<"Oerkki1CAO: Got message"<<std::endl;
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
// command
|
||||||
|
u8 cmd = readU8(is);
|
||||||
|
if(cmd == 0)
|
||||||
|
{
|
||||||
|
// pos
|
||||||
|
m_position = readV3F1000(is);
|
||||||
|
pos_translator.update(m_position);
|
||||||
|
// yaw
|
||||||
|
m_yaw = readF1000(is);
|
||||||
|
updateNodePos();
|
||||||
|
}
|
||||||
|
else if(cmd == 1)
|
||||||
|
{
|
||||||
|
u16 damage = readU8(is);
|
||||||
|
m_damage_visual_timer = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oerkki1CAO::initialize(const std::string &data)
|
||||||
|
{
|
||||||
|
//dstream<<"Oerkki1CAO: Got init data"<<std::endl;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
// version
|
||||||
|
u8 version = readU8(is);
|
||||||
|
// check version
|
||||||
|
if(version != 0)
|
||||||
|
return;
|
||||||
|
// pos
|
||||||
|
m_position = readV3F1000(is);
|
||||||
|
pos_translator.init(m_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateNodePos();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,248 @@
|
||||||
|
/*
|
||||||
|
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_CAO_HEADER
|
||||||
|
#define CONTENT_CAO_HEADER
|
||||||
|
|
||||||
|
#include "clientobject.h"
|
||||||
|
#include "content_object.h"
|
||||||
|
#include "utility.h" // For IntervalLimiter
|
||||||
|
|
||||||
|
/*
|
||||||
|
SmoothTranslator
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct SmoothTranslator
|
||||||
|
{
|
||||||
|
v3f vect_old;
|
||||||
|
f32 anim_counter;
|
||||||
|
f32 anim_time;
|
||||||
|
f32 anim_time_counter;
|
||||||
|
v3f vect_show;
|
||||||
|
v3f vect_aim;
|
||||||
|
|
||||||
|
SmoothTranslator():
|
||||||
|
vect_old(0,0,0),
|
||||||
|
anim_counter(0),
|
||||||
|
anim_time(0),
|
||||||
|
anim_time_counter(0),
|
||||||
|
vect_show(0,0,0),
|
||||||
|
vect_aim(0,0,0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void init(v3f vect)
|
||||||
|
{
|
||||||
|
vect_old = vect;
|
||||||
|
vect_show = vect;
|
||||||
|
vect_aim = vect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(v3f vect_new)
|
||||||
|
{
|
||||||
|
vect_old = vect_show;
|
||||||
|
vect_aim = vect_new;
|
||||||
|
if(anim_time < 0.001 || anim_time > 1.0)
|
||||||
|
anim_time = anim_time_counter;
|
||||||
|
else
|
||||||
|
anim_time = anim_time * 0.9 + anim_time_counter * 0.1;
|
||||||
|
anim_time_counter = 0;
|
||||||
|
anim_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void translate(f32 dtime)
|
||||||
|
{
|
||||||
|
anim_time_counter = anim_time_counter + dtime;
|
||||||
|
anim_counter = anim_counter + dtime;
|
||||||
|
v3f vect_move = vect_aim - vect_old;
|
||||||
|
f32 moveratio = 1.0;
|
||||||
|
if(anim_time > 0.001)
|
||||||
|
moveratio = anim_time_counter / anim_time;
|
||||||
|
// Move a bit less than should, to avoid oscillation
|
||||||
|
moveratio = moveratio * 0.8;
|
||||||
|
if(moveratio > 1.5)
|
||||||
|
moveratio = 1.5;
|
||||||
|
vect_show = vect_old + vect_move * moveratio;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ItemCAO : public ClientActiveObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ItemCAO();
|
||||||
|
virtual ~ItemCAO();
|
||||||
|
|
||||||
|
u8 getType() const
|
||||||
|
{
|
||||||
|
return ACTIVEOBJECT_TYPE_ITEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
core::aabbox3d<f32> m_selection_box;
|
||||||
|
scene::IMeshSceneNode *m_node;
|
||||||
|
v3f m_position;
|
||||||
|
std::string m_inventorystring;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
RatCAO
|
||||||
|
*/
|
||||||
|
|
||||||
|
class RatCAO : public ClientActiveObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RatCAO();
|
||||||
|
virtual ~RatCAO();
|
||||||
|
|
||||||
|
u8 getType() const
|
||||||
|
{
|
||||||
|
return ACTIVEOBJECT_TYPE_RAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
core::aabbox3d<f32> m_selection_box;
|
||||||
|
scene::IMeshSceneNode *m_node;
|
||||||
|
v3f m_position;
|
||||||
|
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;}
|
||||||
|
//{return m_position;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
IntervalLimiter m_attack_interval;
|
||||||
|
core::aabbox3d<f32> m_selection_box;
|
||||||
|
scene::IMeshSceneNode *m_node;
|
||||||
|
v3f m_position;
|
||||||
|
float m_yaw;
|
||||||
|
SmoothTranslator pos_translator;
|
||||||
|
float m_damage_visual_timer;
|
||||||
|
bool m_damage_texture_enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -19,8 +19,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include "content_inventory.h"
|
#include "content_inventory.h"
|
||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#include "serverobject.h"
|
|
||||||
#include "content_mapnode.h"
|
#include "content_mapnode.h"
|
||||||
|
//#include "serverobject.h"
|
||||||
|
#include "content_sao.h"
|
||||||
|
|
||||||
bool item_material_is_cookable(u8 content)
|
bool item_material_is_cookable(u8 content)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
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_OBJECT_HEADER
|
||||||
|
#define CONTENT_OBJECT_HEADER
|
||||||
|
|
||||||
|
#define ACTIVEOBJECT_TYPE_TEST 1
|
||||||
|
#define ACTIVEOBJECT_TYPE_ITEM 2
|
||||||
|
#define ACTIVEOBJECT_TYPE_RAT 3
|
||||||
|
#define ACTIVEOBJECT_TYPE_OERKKI1 4
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,694 @@
|
||||||
|
/*
|
||||||
|
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_sao.h"
|
||||||
|
#include "collision.h"
|
||||||
|
#include "environment.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
TestSAO
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Prototype
|
||||||
|
TestSAO proto_TestSAO(NULL, 0, v3f(0,0,0));
|
||||||
|
|
||||||
|
TestSAO::TestSAO(ServerEnvironment *env, u16 id, v3f pos):
|
||||||
|
ServerActiveObject(env, id, pos),
|
||||||
|
m_timer1(0),
|
||||||
|
m_age(0)
|
||||||
|
{
|
||||||
|
ServerActiveObject::registerType(getType(), create);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerActiveObject* TestSAO::create(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
|
const std::string &data)
|
||||||
|
{
|
||||||
|
return new TestSAO(env, id, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestSAO::step(float dtime, bool send_recommended)
|
||||||
|
{
|
||||||
|
m_age += dtime;
|
||||||
|
if(m_age > 10)
|
||||||
|
{
|
||||||
|
m_removed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_base_position.Y += dtime * BS * 2;
|
||||||
|
if(m_base_position.Y > 8*BS)
|
||||||
|
m_base_position.Y = 2*BS;
|
||||||
|
|
||||||
|
if(send_recommended == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_timer1 -= dtime;
|
||||||
|
if(m_timer1 < 0.0)
|
||||||
|
{
|
||||||
|
m_timer1 += 0.125;
|
||||||
|
//dstream<<"TestSAO: id="<<getId()<<" sending data"<<std::endl;
|
||||||
|
|
||||||
|
std::string data;
|
||||||
|
|
||||||
|
data += itos(0); // 0 = position
|
||||||
|
data += " ";
|
||||||
|
data += itos(m_base_position.X);
|
||||||
|
data += " ";
|
||||||
|
data += itos(m_base_position.Y);
|
||||||
|
data += " ";
|
||||||
|
data += itos(m_base_position.Z);
|
||||||
|
|
||||||
|
ActiveObjectMessage aom(getId(), false, data);
|
||||||
|
m_messages_out.push_back(aom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
ItemSAO
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Prototype
|
||||||
|
ItemSAO proto_ItemSAO(NULL, 0, v3f(0,0,0), "");
|
||||||
|
|
||||||
|
ItemSAO::ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
|
const std::string inventorystring):
|
||||||
|
ServerActiveObject(env, id, pos),
|
||||||
|
m_inventorystring(inventorystring),
|
||||||
|
m_speed_f(0,0,0),
|
||||||
|
m_last_sent_position(0,0,0)
|
||||||
|
{
|
||||||
|
ServerActiveObject::registerType(getType(), create);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerActiveObject* ItemSAO::create(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
|
const std::string &data)
|
||||||
|
{
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
char buf[1];
|
||||||
|
// read version
|
||||||
|
is.read(buf, 1);
|
||||||
|
u8 version = buf[0];
|
||||||
|
// check if version is supported
|
||||||
|
if(version != 0)
|
||||||
|
return NULL;
|
||||||
|
std::string inventorystring = deSerializeString(is);
|
||||||
|
dstream<<"ItemSAO::create(): Creating item \""
|
||||||
|
<<inventorystring<<"\""<<std::endl;
|
||||||
|
return new ItemSAO(env, id, pos, inventorystring);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemSAO::step(float dtime, bool send_recommended)
|
||||||
|
{
|
||||||
|
assert(m_env);
|
||||||
|
|
||||||
|
const float interval = 0.2;
|
||||||
|
if(m_move_interval.step(dtime, interval)==false)
|
||||||
|
return;
|
||||||
|
dtime = interval;
|
||||||
|
|
||||||
|
core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.);
|
||||||
|
collisionMoveResult moveresult;
|
||||||
|
// Apply gravity
|
||||||
|
m_speed_f += v3f(0, -dtime*9.81*BS, 0);
|
||||||
|
// Maximum movement without glitches
|
||||||
|
f32 pos_max_d = BS*0.25;
|
||||||
|
// Limit speed
|
||||||
|
if(m_speed_f.getLength()*dtime > pos_max_d)
|
||||||
|
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
|
||||||
|
v3f pos_f = getBasePosition();
|
||||||
|
v3f pos_f_old = pos_f;
|
||||||
|
moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
|
||||||
|
box, dtime, pos_f, m_speed_f);
|
||||||
|
|
||||||
|
if(send_recommended == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
|
||||||
|
{
|
||||||
|
setBasePosition(pos_f);
|
||||||
|
m_last_sent_position = pos_f;
|
||||||
|
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
char buf[6];
|
||||||
|
// command (0 = update position)
|
||||||
|
buf[0] = 0;
|
||||||
|
os.write(buf, 1);
|
||||||
|
// pos
|
||||||
|
writeS32((u8*)buf, m_base_position.X*1000);
|
||||||
|
os.write(buf, 4);
|
||||||
|
writeS32((u8*)buf, m_base_position.Y*1000);
|
||||||
|
os.write(buf, 4);
|
||||||
|
writeS32((u8*)buf, m_base_position.Z*1000);
|
||||||
|
os.write(buf, 4);
|
||||||
|
// create message and add to list
|
||||||
|
ActiveObjectMessage aom(getId(), false, os.str());
|
||||||
|
m_messages_out.push_back(aom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ItemSAO::getClientInitializationData()
|
||||||
|
{
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
char buf[6];
|
||||||
|
// version
|
||||||
|
buf[0] = 0;
|
||||||
|
os.write(buf, 1);
|
||||||
|
// pos
|
||||||
|
writeS32((u8*)buf, m_base_position.X*1000);
|
||||||
|
os.write(buf, 4);
|
||||||
|
writeS32((u8*)buf, m_base_position.Y*1000);
|
||||||
|
os.write(buf, 4);
|
||||||
|
writeS32((u8*)buf, m_base_position.Z*1000);
|
||||||
|
os.write(buf, 4);
|
||||||
|
// inventorystring
|
||||||
|
os<<serializeString(m_inventorystring);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ItemSAO::getStaticData()
|
||||||
|
{
|
||||||
|
dstream<<__FUNCTION_NAME<<std::endl;
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
char buf[1];
|
||||||
|
// version
|
||||||
|
buf[0] = 0;
|
||||||
|
os.write(buf, 1);
|
||||||
|
// inventorystring
|
||||||
|
os<<serializeString(m_inventorystring);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
InventoryItem * ItemSAO::createInventoryItem()
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
std::istringstream is(m_inventorystring, std::ios_base::binary);
|
||||||
|
InventoryItem *item = InventoryItem::deSerialize(is);
|
||||||
|
dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
|
||||||
|
<<m_inventorystring<<"\" -> item="<<item
|
||||||
|
<<std::endl;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
catch(SerializationError &e)
|
||||||
|
{
|
||||||
|
dstream<<__FUNCTION_NAME<<": serialization error: "
|
||||||
|
<<"m_inventorystring=\""<<m_inventorystring<<"\""<<std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
RatSAO
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Prototype
|
||||||
|
RatSAO proto_RatSAO(NULL, 0, v3f(0,0,0));
|
||||||
|
|
||||||
|
RatSAO::RatSAO(ServerEnvironment *env, u16 id, v3f pos):
|
||||||
|
ServerActiveObject(env, id, pos),
|
||||||
|
m_is_active(false),
|
||||||
|
m_speed_f(0,0,0)
|
||||||
|
{
|
||||||
|
ServerActiveObject::registerType(getType(), create);
|
||||||
|
|
||||||
|
m_oldpos = v3f(0,0,0);
|
||||||
|
m_last_sent_position = v3f(0,0,0);
|
||||||
|
m_yaw = 0;
|
||||||
|
m_counter1 = 0;
|
||||||
|
m_counter2 = 0;
|
||||||
|
m_age = 0;
|
||||||
|
m_touching_ground = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerActiveObject* RatSAO::create(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
|
const std::string &data)
|
||||||
|
{
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
char buf[1];
|
||||||
|
// read version
|
||||||
|
is.read(buf, 1);
|
||||||
|
u8 version = buf[0];
|
||||||
|
// check if version is supported
|
||||||
|
if(version != 0)
|
||||||
|
return NULL;
|
||||||
|
return new RatSAO(env, id, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RatSAO::step(float dtime, bool send_recommended)
|
||||||
|
{
|
||||||
|
assert(m_env);
|
||||||
|
|
||||||
|
if(m_is_active == false)
|
||||||
|
{
|
||||||
|
if(m_inactive_interval.step(dtime, 0.5)==false)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The AI
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*m_age += dtime;
|
||||||
|
if(m_age > 60)
|
||||||
|
{
|
||||||
|
// Die
|
||||||
|
m_removed = true;
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Apply gravity
|
||||||
|
m_speed_f.Y -= dtime*9.81*BS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Move around if some player is close
|
||||||
|
*/
|
||||||
|
bool player_is_close = false;
|
||||||
|
// Check connected players
|
||||||
|
core::list<Player*> players = m_env->getPlayers(true);
|
||||||
|
core::list<Player*>::Iterator i;
|
||||||
|
for(i = players.begin();
|
||||||
|
i != players.end(); i++)
|
||||||
|
{
|
||||||
|
Player *player = *i;
|
||||||
|
v3f playerpos = player->getPosition();
|
||||||
|
if(m_base_position.getDistanceFrom(playerpos) < BS*10.0)
|
||||||
|
{
|
||||||
|
player_is_close = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_is_active = player_is_close;
|
||||||
|
|
||||||
|
if(player_is_close == false)
|
||||||
|
{
|
||||||
|
m_speed_f.X = 0;
|
||||||
|
m_speed_f.Z = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Move around
|
||||||
|
v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
|
||||||
|
f32 speed = 2*BS;
|
||||||
|
m_speed_f.X = speed * dir.X;
|
||||||
|
m_speed_f.Z = speed * dir.Z;
|
||||||
|
|
||||||
|
if(m_touching_ground && (m_oldpos - m_base_position).getLength()
|
||||||
|
< dtime*speed/2)
|
||||||
|
{
|
||||||
|
m_counter1 -= dtime;
|
||||||
|
if(m_counter1 < 0.0)
|
||||||
|
{
|
||||||
|
m_counter1 += 1.0;
|
||||||
|
m_speed_f.Y = 5.0*BS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
m_counter2 -= dtime;
|
||||||
|
if(m_counter2 < 0.0)
|
||||||
|
{
|
||||||
|
m_counter2 += (float)(myrand()%100)/100*3.0;
|
||||||
|
m_yaw += ((float)(myrand()%200)-100)/100*180;
|
||||||
|
m_yaw = wrapDegrees(m_yaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_oldpos = m_base_position;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Move it, with collision detection
|
||||||
|
*/
|
||||||
|
|
||||||
|
core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.);
|
||||||
|
collisionMoveResult moveresult;
|
||||||
|
// Maximum movement without glitches
|
||||||
|
f32 pos_max_d = BS*0.25;
|
||||||
|
// Limit speed
|
||||||
|
if(m_speed_f.getLength()*dtime > pos_max_d)
|
||||||
|
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
|
||||||
|
v3f pos_f = getBasePosition();
|
||||||
|
v3f pos_f_old = pos_f;
|
||||||
|
moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
|
||||||
|
box, dtime, pos_f, m_speed_f);
|
||||||
|
m_touching_ground = moveresult.touching_ground;
|
||||||
|
|
||||||
|
setBasePosition(pos_f);
|
||||||
|
|
||||||
|
if(send_recommended == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
|
||||||
|
{
|
||||||
|
m_last_sent_position = pos_f;
|
||||||
|
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// command (0 = update position)
|
||||||
|
writeU8(os, 0);
|
||||||
|
// pos
|
||||||
|
writeV3F1000(os, m_base_position);
|
||||||
|
// yaw
|
||||||
|
writeF1000(os, m_yaw);
|
||||||
|
// create message and add to list
|
||||||
|
ActiveObjectMessage aom(getId(), false, os.str());
|
||||||
|
m_messages_out.push_back(aom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RatSAO::getClientInitializationData()
|
||||||
|
{
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// version
|
||||||
|
writeU8(os, 0);
|
||||||
|
// pos
|
||||||
|
writeV3F1000(os, m_base_position);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RatSAO::getStaticData()
|
||||||
|
{
|
||||||
|
//dstream<<__FUNCTION_NAME<<std::endl;
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// version
|
||||||
|
writeU8(os, 0);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
InventoryItem* RatSAO::createPickedUpItem()
|
||||||
|
{
|
||||||
|
std::istringstream is("CraftItem rat 1", std::ios_base::binary);
|
||||||
|
InventoryItem *item = InventoryItem::deSerialize(is);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Oerkki1SAO
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Y is copied, X and Z change is limited
|
||||||
|
void accelerate_xz(v3f &speed, v3f target_speed, f32 max_increase)
|
||||||
|
{
|
||||||
|
v3f d_wanted = target_speed - speed;
|
||||||
|
d_wanted.Y = 0;
|
||||||
|
f32 dl_wanted = d_wanted.getLength();
|
||||||
|
f32 dl = dl_wanted;
|
||||||
|
if(dl > max_increase)
|
||||||
|
dl = max_increase;
|
||||||
|
|
||||||
|
v3f d = d_wanted.normalize() * dl;
|
||||||
|
|
||||||
|
speed.X += d.X;
|
||||||
|
speed.Z += d.Z;
|
||||||
|
speed.Y = target_speed.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prototype
|
||||||
|
Oerkki1SAO proto_Oerkki1SAO(NULL, 0, v3f(0,0,0));
|
||||||
|
|
||||||
|
Oerkki1SAO::Oerkki1SAO(ServerEnvironment *env, u16 id, v3f pos):
|
||||||
|
ServerActiveObject(env, id, pos),
|
||||||
|
m_is_active(false),
|
||||||
|
m_speed_f(0,0,0)
|
||||||
|
{
|
||||||
|
ServerActiveObject::registerType(getType(), create);
|
||||||
|
|
||||||
|
m_oldpos = v3f(0,0,0);
|
||||||
|
m_last_sent_position = v3f(0,0,0);
|
||||||
|
m_yaw = 0;
|
||||||
|
m_counter1 = 0;
|
||||||
|
m_counter2 = 0;
|
||||||
|
m_age = 0;
|
||||||
|
m_touching_ground = false;
|
||||||
|
m_hp = 20;
|
||||||
|
m_after_jump_timer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerActiveObject* Oerkki1SAO::create(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
|
const std::string &data)
|
||||||
|
{
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
// read version
|
||||||
|
u8 version = readU8(is);
|
||||||
|
// read hp
|
||||||
|
u8 hp = readU8(is);
|
||||||
|
// check if version is supported
|
||||||
|
if(version != 0)
|
||||||
|
return NULL;
|
||||||
|
Oerkki1SAO *o = new Oerkki1SAO(env, id, pos);
|
||||||
|
o->m_hp = hp;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oerkki1SAO::step(float dtime, bool send_recommended)
|
||||||
|
{
|
||||||
|
assert(m_env);
|
||||||
|
|
||||||
|
if(m_is_active == false)
|
||||||
|
{
|
||||||
|
if(m_inactive_interval.step(dtime, 0.5)==false)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The AI
|
||||||
|
*/
|
||||||
|
|
||||||
|
m_age += dtime;
|
||||||
|
if(m_age > 120)
|
||||||
|
{
|
||||||
|
// Die
|
||||||
|
m_removed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_after_jump_timer -= dtime;
|
||||||
|
|
||||||
|
v3f old_speed = m_speed_f;
|
||||||
|
|
||||||
|
// Apply gravity
|
||||||
|
m_speed_f.Y -= dtime*9.81*BS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Move around if some player is close
|
||||||
|
*/
|
||||||
|
bool player_is_close = false;
|
||||||
|
bool player_is_too_close = false;
|
||||||
|
v3f near_player_pos;
|
||||||
|
// Check connected players
|
||||||
|
core::list<Player*> players = m_env->getPlayers(true);
|
||||||
|
core::list<Player*>::Iterator i;
|
||||||
|
for(i = players.begin();
|
||||||
|
i != players.end(); i++)
|
||||||
|
{
|
||||||
|
Player *player = *i;
|
||||||
|
v3f playerpos = player->getPosition();
|
||||||
|
f32 dist = m_base_position.getDistanceFrom(playerpos);
|
||||||
|
if(dist < BS*1.45)
|
||||||
|
{
|
||||||
|
player_is_too_close = true;
|
||||||
|
near_player_pos = playerpos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(dist < BS*15.0)
|
||||||
|
{
|
||||||
|
player_is_close = true;
|
||||||
|
near_player_pos = playerpos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_is_active = player_is_close;
|
||||||
|
|
||||||
|
v3f target_speed = m_speed_f;
|
||||||
|
|
||||||
|
if(!player_is_close)
|
||||||
|
{
|
||||||
|
target_speed = v3f(0,0,0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Move around
|
||||||
|
|
||||||
|
v3f ndir = near_player_pos - m_base_position;
|
||||||
|
ndir.Y = 0;
|
||||||
|
ndir.normalize();
|
||||||
|
|
||||||
|
f32 nyaw = 180./PI*atan2(ndir.Z,ndir.X);
|
||||||
|
if(nyaw < m_yaw - 180)
|
||||||
|
nyaw += 360;
|
||||||
|
else if(nyaw > m_yaw + 180)
|
||||||
|
nyaw -= 360;
|
||||||
|
m_yaw = 0.95*m_yaw + 0.05*nyaw;
|
||||||
|
m_yaw = wrapDegrees(m_yaw);
|
||||||
|
|
||||||
|
f32 speed = 2*BS;
|
||||||
|
|
||||||
|
if((m_touching_ground || m_after_jump_timer > 0.0)
|
||||||
|
&& !player_is_too_close)
|
||||||
|
{
|
||||||
|
v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
|
||||||
|
target_speed.X = speed * dir.X;
|
||||||
|
target_speed.Z = speed * dir.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_touching_ground && (m_oldpos - m_base_position).getLength()
|
||||||
|
< dtime*speed/2)
|
||||||
|
{
|
||||||
|
m_counter1 -= dtime;
|
||||||
|
if(m_counter1 < 0.0)
|
||||||
|
{
|
||||||
|
m_counter1 += 0.2;
|
||||||
|
// Jump
|
||||||
|
target_speed.Y = 5.0*BS;
|
||||||
|
m_after_jump_timer = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
m_counter2 -= dtime;
|
||||||
|
if(m_counter2 < 0.0)
|
||||||
|
{
|
||||||
|
m_counter2 += (float)(myrand()%100)/100*3.0;
|
||||||
|
//m_yaw += ((float)(myrand()%200)-100)/100*180;
|
||||||
|
m_yaw += ((float)(myrand()%200)-100)/100*90;
|
||||||
|
m_yaw = wrapDegrees(m_yaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((m_speed_f - target_speed).getLength() > BS*4 || player_is_too_close)
|
||||||
|
accelerate_xz(m_speed_f, target_speed, dtime*BS*8);
|
||||||
|
else
|
||||||
|
accelerate_xz(m_speed_f, target_speed, dtime*BS*4);
|
||||||
|
|
||||||
|
m_oldpos = m_base_position;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Move it, with collision detection
|
||||||
|
*/
|
||||||
|
|
||||||
|
core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*5./3.,BS/3.);
|
||||||
|
collisionMoveResult moveresult;
|
||||||
|
// Maximum movement without glitches
|
||||||
|
f32 pos_max_d = BS*0.25;
|
||||||
|
/*// Limit speed
|
||||||
|
if(m_speed_f.getLength()*dtime > pos_max_d)
|
||||||
|
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);*/
|
||||||
|
v3f pos_f = getBasePosition();
|
||||||
|
v3f pos_f_old = pos_f;
|
||||||
|
moveresult = collisionMovePrecise(&m_env->getMap(), pos_max_d,
|
||||||
|
box, dtime, pos_f, m_speed_f);
|
||||||
|
m_touching_ground = moveresult.touching_ground;
|
||||||
|
|
||||||
|
// Do collision damage
|
||||||
|
float tolerance = BS*12;
|
||||||
|
float factor = BS*0.5;
|
||||||
|
v3f speed_diff = old_speed - m_speed_f;
|
||||||
|
// Increase effect in X and Z
|
||||||
|
speed_diff.X *= 2;
|
||||||
|
speed_diff.Z *= 2;
|
||||||
|
float vel = speed_diff.getLength();
|
||||||
|
if(vel > tolerance)
|
||||||
|
{
|
||||||
|
f32 damage_f = (vel - tolerance)/BS*factor;
|
||||||
|
u16 damage = (u16)(damage_f+0.5);
|
||||||
|
doDamage(damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
setBasePosition(pos_f);
|
||||||
|
|
||||||
|
if(send_recommended == false && m_speed_f.getLength() < 3.0*BS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
|
||||||
|
{
|
||||||
|
m_last_sent_position = pos_f;
|
||||||
|
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// command (0 = update position)
|
||||||
|
writeU8(os, 0);
|
||||||
|
// pos
|
||||||
|
writeV3F1000(os, m_base_position);
|
||||||
|
// yaw
|
||||||
|
writeF1000(os, m_yaw);
|
||||||
|
// create message and add to list
|
||||||
|
ActiveObjectMessage aom(getId(), false, os.str());
|
||||||
|
m_messages_out.push_back(aom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Oerkki1SAO::getClientInitializationData()
|
||||||
|
{
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// version
|
||||||
|
writeU8(os, 0);
|
||||||
|
// pos
|
||||||
|
writeV3F1000(os, m_base_position);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Oerkki1SAO::getStaticData()
|
||||||
|
{
|
||||||
|
//dstream<<__FUNCTION_NAME<<std::endl;
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// version
|
||||||
|
writeU8(os, 0);
|
||||||
|
// hp
|
||||||
|
writeU8(os, m_hp);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 Oerkki1SAO::punch(const std::string &toolname, v3f dir)
|
||||||
|
{
|
||||||
|
m_speed_f += dir*12*BS;
|
||||||
|
|
||||||
|
u16 amount = 5;
|
||||||
|
doDamage(amount);
|
||||||
|
return 65536/100;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oerkki1SAO::doDamage(u16 d)
|
||||||
|
{
|
||||||
|
dstream<<"oerkki damage: "<<d<<std::endl;
|
||||||
|
|
||||||
|
if(d < m_hp)
|
||||||
|
{
|
||||||
|
m_hp -= d;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Die
|
||||||
|
m_hp = 0;
|
||||||
|
m_removed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// command (1 = damage)
|
||||||
|
writeU8(os, 1);
|
||||||
|
// amount
|
||||||
|
writeU8(os, d);
|
||||||
|
// create message and add to list
|
||||||
|
ActiveObjectMessage aom(getId(), false, os.str());
|
||||||
|
m_messages_out.push_back(aom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
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_SAO_HEADER
|
||||||
|
#define CONTENT_SAO_HEADER
|
||||||
|
|
||||||
|
#include "serverobject.h"
|
||||||
|
#include "content_object.h"
|
||||||
|
|
||||||
|
class TestSAO : public ServerActiveObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TestSAO(ServerEnvironment *env, u16 id, v3f pos);
|
||||||
|
u8 getType() const
|
||||||
|
{return ACTIVEOBJECT_TYPE_TEST;}
|
||||||
|
static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
|
const std::string &data);
|
||||||
|
void step(float dtime, bool send_recommended);
|
||||||
|
private:
|
||||||
|
float m_timer1;
|
||||||
|
float m_age;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ItemSAO : public ServerActiveObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
|
const std::string inventorystring);
|
||||||
|
u8 getType() const
|
||||||
|
{return ACTIVEOBJECT_TYPE_ITEM;}
|
||||||
|
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* createInventoryItem();
|
||||||
|
InventoryItem* createPickedUpItem(){return createInventoryItem();}
|
||||||
|
private:
|
||||||
|
std::string m_inventorystring;
|
||||||
|
v3f m_speed_f;
|
||||||
|
v3f m_last_sent_position;
|
||||||
|
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(){return NULL;}
|
||||||
|
u16 punch(const std::string &toolname, v3f dir);
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "collision.h"
|
#include "collision.h"
|
||||||
#include "content_mapnode.h"
|
#include "content_mapnode.h"
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
|
#include "serverobject.h"
|
||||||
|
#include "content_sao.h"
|
||||||
|
|
||||||
Environment::Environment():
|
Environment::Environment():
|
||||||
m_time_of_day(9000)
|
m_time_of_day(9000)
|
||||||
|
@ -918,8 +920,14 @@ void ServerEnvironment::step(float dtime)
|
||||||
// Don't step if is to be removed or stored statically
|
// Don't step if is to be removed or stored statically
|
||||||
if(obj->m_removed || obj->m_pending_deactivation)
|
if(obj->m_removed || obj->m_pending_deactivation)
|
||||||
continue;
|
continue;
|
||||||
// Step object, putting messages directly to the queue
|
// Step object
|
||||||
obj->step(dtime, m_active_object_messages, send_recommended);
|
obj->step(dtime, send_recommended);
|
||||||
|
// Read messages from object
|
||||||
|
while(obj->m_messages_out.size() > 0)
|
||||||
|
{
|
||||||
|
m_active_object_messages.push_back(
|
||||||
|
obj->m_messages_out.pop_front());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1660,17 +1668,21 @@ void ClientEnvironment::step(float dtime)
|
||||||
ClientActiveObject* obj = i.getNode()->getValue();
|
ClientActiveObject* obj = i.getNode()->getValue();
|
||||||
// Step object
|
// Step object
|
||||||
obj->step(dtime, this);
|
obj->step(dtime, this);
|
||||||
// Update lighting
|
|
||||||
//u8 light = LIGHT_MAX;
|
if(m_active_object_light_update_interval.step(dtime, 0.5))
|
||||||
u8 light = 0;
|
{
|
||||||
try{
|
// Update lighting
|
||||||
// Get node at head
|
//u8 light = LIGHT_MAX;
|
||||||
v3s16 p = obj->getLightPosition();
|
u8 light = 0;
|
||||||
MapNode n = m_map->getNode(p);
|
try{
|
||||||
light = n.getLightBlend(getDayNightRatio());
|
// Get node at head
|
||||||
|
v3s16 p = obj->getLightPosition();
|
||||||
|
MapNode n = m_map->getNode(p);
|
||||||
|
light = n.getLightBlend(getDayNightRatio());
|
||||||
|
}
|
||||||
|
catch(InvalidPositionException &e) {}
|
||||||
|
obj->updateLight(light);
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e) {}
|
|
||||||
obj->updateLight(light);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
#include "activeobject.h"
|
||||||
|
|
||||||
|
class Server;
|
||||||
|
class ActiveBlockModifier;
|
||||||
|
class ServerActiveObject;
|
||||||
|
|
||||||
class Environment
|
class Environment
|
||||||
{
|
{
|
||||||
|
@ -118,11 +123,6 @@ private:
|
||||||
This is not thread-safe. Server uses an environment mutex.
|
This is not thread-safe. Server uses an environment mutex.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "serverobject.h"
|
|
||||||
|
|
||||||
class Server;
|
|
||||||
class ActiveBlockModifier;
|
|
||||||
|
|
||||||
class ServerEnvironment : public Environment
|
class ServerEnvironment : public Environment
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -412,6 +412,7 @@ private:
|
||||||
scene::ISceneManager *m_smgr;
|
scene::ISceneManager *m_smgr;
|
||||||
core::map<u16, ClientActiveObject*> m_active_objects;
|
core::map<u16, ClientActiveObject*> m_active_objects;
|
||||||
Queue<ClientEnvEvent> m_client_event_queue;
|
Queue<ClientEnvEvent> m_client_event_queue;
|
||||||
|
IntervalLimiter m_active_object_light_update_interval;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
12
src/game.cpp
12
src/game.cpp
|
@ -661,7 +661,9 @@ void the_game(
|
||||||
screensize = driver->getScreenSize();
|
screensize = driver->getScreenSize();
|
||||||
|
|
||||||
const s32 hotbar_itemcount = 8;
|
const s32 hotbar_itemcount = 8;
|
||||||
const s32 hotbar_imagesize = 36;
|
//const s32 hotbar_imagesize = 36;
|
||||||
|
//const s32 hotbar_imagesize = 64;
|
||||||
|
s32 hotbar_imagesize = 48;
|
||||||
|
|
||||||
// The color of the sky
|
// The color of the sky
|
||||||
|
|
||||||
|
@ -967,6 +969,14 @@ void the_game(
|
||||||
screensize = driver->getScreenSize();
|
screensize = driver->getScreenSize();
|
||||||
v2s32 displaycenter(screensize.X/2,screensize.Y/2);
|
v2s32 displaycenter(screensize.X/2,screensize.Y/2);
|
||||||
//bool screensize_changed = screensize != last_screensize;
|
//bool screensize_changed = screensize != last_screensize;
|
||||||
|
|
||||||
|
// Resize hotbar
|
||||||
|
if(screensize.Y <= 600)
|
||||||
|
hotbar_imagesize = 32;
|
||||||
|
else if(screensize.Y <= 1024)
|
||||||
|
hotbar_imagesize = 48;
|
||||||
|
else
|
||||||
|
hotbar_imagesize = 64;
|
||||||
|
|
||||||
// Hilight boxes collected during the loop and displayed
|
// Hilight boxes collected during the loop and displayed
|
||||||
core::list< core::aabbox3d<f32> > hilightboxes;
|
core::list< core::aabbox3d<f32> > hilightboxes;
|
||||||
|
|
|
@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "serverobject.h"
|
#include "serverobject.h"
|
||||||
#include "content_mapnode.h"
|
#include "content_mapnode.h"
|
||||||
#include "content_inventory.h"
|
#include "content_inventory.h"
|
||||||
|
#include "content_sao.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
InventoryItem
|
InventoryItem
|
||||||
|
|
10
src/map.cpp
10
src/map.cpp
|
@ -26,10 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "voxel.h"
|
#include "voxel.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "mineral.h"
|
|
||||||
#include "noise.h"
|
|
||||||
#include "serverobject.h"
|
|
||||||
#include "content_mapnode.h"
|
|
||||||
#include "mapgen.h"
|
#include "mapgen.h"
|
||||||
#include "nodemetadata.h"
|
#include "nodemetadata.h"
|
||||||
|
|
||||||
|
@ -901,7 +897,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
/*
|
/*
|
||||||
If the new node is solid and there is grass below, change it to mud
|
If the new node is solid and there is grass below, change it to mud
|
||||||
*/
|
*/
|
||||||
|
@ -2869,10 +2865,10 @@ MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load
|
||||||
// format. Just go ahead and create the sector.
|
// format. Just go ahead and create the sector.
|
||||||
if(fs::PathExists(sectordir))
|
if(fs::PathExists(sectordir))
|
||||||
{
|
{
|
||||||
dstream<<"ServerMap::loadSectorMeta(): Sector metafile "
|
/*dstream<<"ServerMap::loadSectorMeta(): Sector metafile "
|
||||||
<<fullpath<<" doesn't exist but directory does."
|
<<fullpath<<" doesn't exist but directory does."
|
||||||
<<" Continuing with a sector with no metadata."
|
<<" Continuing with a sector with no metadata."
|
||||||
<<std::endl;
|
<<std::endl;*/
|
||||||
sector = new ServerMapSector(this, p2d);
|
sector = new ServerMapSector(this, p2d);
|
||||||
m_sectors.insert(p2d, sector);
|
m_sectors.insert(p2d, sector);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "noise.h"
|
#include "noise.h"
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "serverobject.h"
|
|
||||||
#include "mineral.h"
|
#include "mineral.h"
|
||||||
|
//#include "serverobject.h"
|
||||||
|
#include "content_sao.h"
|
||||||
|
|
||||||
namespace mapgen
|
namespace mapgen
|
||||||
{
|
{
|
||||||
|
@ -503,7 +504,7 @@ static void make_corridor(VoxelManipulator &vmanip, v3s16 doorplace,
|
||||||
else
|
else
|
||||||
length = random.range(1,6);
|
length = random.range(1,6);
|
||||||
length = random.range(1,13);
|
length = random.range(1,13);
|
||||||
u32 partlength = random.range(1,length);
|
u32 partlength = random.range(1,13);
|
||||||
u32 partcount = 0;
|
u32 partcount = 0;
|
||||||
s16 make_stairs = 0;
|
s16 make_stairs = 0;
|
||||||
if(random.next()%2 == 0 && partlength >= 3)
|
if(random.next()%2 == 0 && partlength >= 3)
|
||||||
|
@ -672,14 +673,63 @@ public:
|
||||||
continue;
|
continue;
|
||||||
v3s16 roomplace;
|
v3s16 roomplace;
|
||||||
// X east, Z north, Y up
|
// X east, Z north, Y up
|
||||||
|
#if 0
|
||||||
if(doordir == v3s16(1,0,0)) // X+
|
if(doordir == v3s16(1,0,0)) // X+
|
||||||
roomplace = doorplace + v3s16(0,-1,-roomsize.Z/2+m_random.range(-roomsize.Z/2+1,roomsize.Z/2-1));
|
roomplace = doorplace + v3s16(0,-1,-roomsize.Z/2+
|
||||||
|
m_random.range(-roomsize.Z/2+1,roomsize.Z/2-1));
|
||||||
if(doordir == v3s16(-1,0,0)) // X-
|
if(doordir == v3s16(-1,0,0)) // X-
|
||||||
roomplace = doorplace + v3s16(-roomsize.X+1,-1,-roomsize.Z/2+m_random.range(-roomsize.Z/2+1,roomsize.Z/2-1));
|
roomplace = doorplace + v3s16(-roomsize.X+1,-1,-roomsize.Z/2
|
||||||
|
+m_random.range(-roomsize.Z/2+1,roomsize.Z/2-1));
|
||||||
if(doordir == v3s16(0,0,1)) // Z+
|
if(doordir == v3s16(0,0,1)) // Z+
|
||||||
roomplace = doorplace + v3s16(-roomsize.X/2+m_random.range(-roomsize.X/2+1,roomsize.X/2-1),-1,0);
|
roomplace = doorplace + v3s16(-roomsize.X/2
|
||||||
|
+m_random.range(-roomsize.X/2+1,roomsize.X/2-1),-1,0);
|
||||||
if(doordir == v3s16(0,0,-1)) // Z-
|
if(doordir == v3s16(0,0,-1)) // Z-
|
||||||
roomplace = doorplace + v3s16(-roomsize.X/2+m_random.range(-roomsize.X/2+1,roomsize.X/2-1),-1,-roomsize.Z+1);
|
roomplace = doorplace + v3s16(-roomsize.X/2
|
||||||
|
+m_random.range(-roomsize.X/2+1,roomsize.X/2-1),-1,
|
||||||
|
-roomsize.Z+1);
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
if(doordir == v3s16(1,0,0)) // X+
|
||||||
|
roomplace = doorplace + v3s16(0,-1,-roomsize.Z/2+
|
||||||
|
m_random.range(-roomsize.Z/2+(roomsize.Z%2==0?2:1),
|
||||||
|
roomsize.Z/2-1));
|
||||||
|
if(doordir == v3s16(-1,0,0)) // X-
|
||||||
|
roomplace = doorplace + v3s16(-roomsize.X+1,-1,-roomsize.Z/2
|
||||||
|
+m_random.range(-roomsize.Z/2+(roomsize.Z%2==0?2:1),
|
||||||
|
roomsize.Z/2-1));
|
||||||
|
if(doordir == v3s16(0,0,1)) // Z+
|
||||||
|
roomplace = doorplace + v3s16(-roomsize.X/2
|
||||||
|
+m_random.range(-roomsize.X/2+(roomsize.X%2==0?2:1),
|
||||||
|
roomsize.X/2-1),-1,0);
|
||||||
|
if(doordir == v3s16(0,0,-1)) // Z-
|
||||||
|
roomplace = doorplace + v3s16(-roomsize.X/2
|
||||||
|
+m_random.range(-roomsize.X/2+(roomsize.X%2==0?2:1),
|
||||||
|
roomsize.X/2-1),-1, -roomsize.Z+1);
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
|
if(doordir == v3s16(1,0,0)) // X+
|
||||||
|
roomplace = doorplace +
|
||||||
|
v3s16(0,-1,m_random.range(-roomsize.Z+1,-2));
|
||||||
|
if(doordir == v3s16(-1,0,0)) // X-
|
||||||
|
roomplace = doorplace +
|
||||||
|
v3s16(-roomsize.X+1,-1,m_random.range(-roomsize.Z+1,-2));
|
||||||
|
if(doordir == v3s16(0,0,1)) // Z+
|
||||||
|
roomplace = doorplace +
|
||||||
|
v3s16(m_random.range(-roomsize.X+1,-2),-1,0);
|
||||||
|
if(doordir == v3s16(0,0,-1)) // Z-
|
||||||
|
roomplace = doorplace +
|
||||||
|
v3s16(m_random.range(-roomsize.X+1,-2),-1,-roomsize.Z+1);
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
if(doordir == v3s16(1,0,0)) // X+
|
||||||
|
roomplace = doorplace + v3s16(0,-1,-roomsize.Z/2);
|
||||||
|
if(doordir == v3s16(-1,0,0)) // X-
|
||||||
|
roomplace = doorplace + v3s16(-roomsize.X+1,-1,-roomsize.Z/2);
|
||||||
|
if(doordir == v3s16(0,0,1)) // Z+
|
||||||
|
roomplace = doorplace + v3s16(-roomsize.X/2,-1,0);
|
||||||
|
if(doordir == v3s16(0,0,-1)) // Z-
|
||||||
|
roomplace = doorplace + v3s16(-roomsize.X/2,-1,-roomsize.Z+1);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check fit
|
// Check fit
|
||||||
bool fits = true;
|
bool fits = true;
|
||||||
|
@ -790,7 +840,7 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random)
|
||||||
|
|
||||||
// Determine walker start position
|
// Determine walker start position
|
||||||
|
|
||||||
bool start_in_last_room = (random.range(0,1)==0);
|
bool start_in_last_room = (random.range(0,2)!=0);
|
||||||
//bool start_in_last_room = true;
|
//bool start_in_last_room = true;
|
||||||
|
|
||||||
v3s16 walker_start_place;
|
v3s16 walker_start_place;
|
||||||
|
@ -858,7 +908,9 @@ NoiseParams get_cave_noise1_params(u64 seed)
|
||||||
{
|
{
|
||||||
/*return NoiseParams(NOISE_PERLIN_CONTOUR, seed+52534, 5, 0.7,
|
/*return NoiseParams(NOISE_PERLIN_CONTOUR, seed+52534, 5, 0.7,
|
||||||
200, CAVE_NOISE_SCALE);*/
|
200, CAVE_NOISE_SCALE);*/
|
||||||
return NoiseParams(NOISE_PERLIN_CONTOUR, seed+52534, 4, 0.7,
|
/*return NoiseParams(NOISE_PERLIN_CONTOUR, seed+52534, 4, 0.7,
|
||||||
|
100, CAVE_NOISE_SCALE);*/
|
||||||
|
return NoiseParams(NOISE_PERLIN_CONTOUR, seed+52534, 5, 0.6,
|
||||||
100, CAVE_NOISE_SCALE);
|
100, CAVE_NOISE_SCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,7 +918,9 @@ NoiseParams get_cave_noise2_params(u64 seed)
|
||||||
{
|
{
|
||||||
/*return NoiseParams(NOISE_PERLIN_CONTOUR_FLIP_YZ, seed+10325, 5, 0.7,
|
/*return NoiseParams(NOISE_PERLIN_CONTOUR_FLIP_YZ, seed+10325, 5, 0.7,
|
||||||
200, CAVE_NOISE_SCALE);*/
|
200, CAVE_NOISE_SCALE);*/
|
||||||
return NoiseParams(NOISE_PERLIN_CONTOUR_FLIP_YZ, seed+10325, 4, 0.7,
|
/*return NoiseParams(NOISE_PERLIN_CONTOUR_FLIP_YZ, seed+10325, 4, 0.7,
|
||||||
|
100, CAVE_NOISE_SCALE);*/
|
||||||
|
return NoiseParams(NOISE_PERLIN_CONTOUR_FLIP_YZ, seed+10325, 5, 0.6,
|
||||||
100, CAVE_NOISE_SCALE);
|
100, CAVE_NOISE_SCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1054,6 +1108,7 @@ double get_sector_maximum_ground_level(u64 seed, v2s16 sectorpos, double p)
|
||||||
v2s16 node_min = sectorpos*MAP_BLOCKSIZE;
|
v2s16 node_min = sectorpos*MAP_BLOCKSIZE;
|
||||||
v2s16 node_max = (sectorpos+v2s16(1,1))*MAP_BLOCKSIZE-v2s16(1,1);
|
v2s16 node_max = (sectorpos+v2s16(1,1))*MAP_BLOCKSIZE-v2s16(1,1);
|
||||||
double a = -31000;
|
double a = -31000;
|
||||||
|
// Corners
|
||||||
a = MYMAX(a, find_ground_level_from_noise(seed,
|
a = MYMAX(a, find_ground_level_from_noise(seed,
|
||||||
v2s16(node_min.X, node_min.Y), p));
|
v2s16(node_min.X, node_min.Y), p));
|
||||||
a = MYMAX(a, find_ground_level_from_noise(seed,
|
a = MYMAX(a, find_ground_level_from_noise(seed,
|
||||||
|
@ -1062,8 +1117,18 @@ double get_sector_maximum_ground_level(u64 seed, v2s16 sectorpos, double p)
|
||||||
v2s16(node_max.X, node_max.Y), p));
|
v2s16(node_max.X, node_max.Y), p));
|
||||||
a = MYMAX(a, find_ground_level_from_noise(seed,
|
a = MYMAX(a, find_ground_level_from_noise(seed,
|
||||||
v2s16(node_min.X, node_min.Y), p));
|
v2s16(node_min.X, node_min.Y), p));
|
||||||
|
// Center
|
||||||
a = MYMAX(a, find_ground_level_from_noise(seed,
|
a = MYMAX(a, find_ground_level_from_noise(seed,
|
||||||
v2s16(node_min.X+MAP_BLOCKSIZE/2, node_min.Y+MAP_BLOCKSIZE/2), p));
|
v2s16(node_min.X+MAP_BLOCKSIZE/2, node_min.Y+MAP_BLOCKSIZE/2), p));
|
||||||
|
// Side middle points
|
||||||
|
a = MYMAX(a, find_ground_level_from_noise(seed,
|
||||||
|
v2s16(node_min.X+MAP_BLOCKSIZE/2, node_min.Y), p));
|
||||||
|
a = MYMAX(a, find_ground_level_from_noise(seed,
|
||||||
|
v2s16(node_min.X+MAP_BLOCKSIZE/2, node_max.Y), p));
|
||||||
|
a = MYMAX(a, find_ground_level_from_noise(seed,
|
||||||
|
v2s16(node_min.X, node_min.Y+MAP_BLOCKSIZE/2), p));
|
||||||
|
a = MYMAX(a, find_ground_level_from_noise(seed,
|
||||||
|
v2s16(node_max.X, node_min.Y+MAP_BLOCKSIZE/2), p));
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1074,6 +1139,7 @@ double get_sector_minimum_ground_level(u64 seed, v2s16 sectorpos, double p)
|
||||||
v2s16 node_min = sectorpos*MAP_BLOCKSIZE;
|
v2s16 node_min = sectorpos*MAP_BLOCKSIZE;
|
||||||
v2s16 node_max = (sectorpos+v2s16(1,1))*MAP_BLOCKSIZE-v2s16(1,1);
|
v2s16 node_max = (sectorpos+v2s16(1,1))*MAP_BLOCKSIZE-v2s16(1,1);
|
||||||
double a = 31000;
|
double a = 31000;
|
||||||
|
// Corners
|
||||||
a = MYMIN(a, find_ground_level_from_noise(seed,
|
a = MYMIN(a, find_ground_level_from_noise(seed,
|
||||||
v2s16(node_min.X, node_min.Y), p));
|
v2s16(node_min.X, node_min.Y), p));
|
||||||
a = MYMIN(a, find_ground_level_from_noise(seed,
|
a = MYMIN(a, find_ground_level_from_noise(seed,
|
||||||
|
@ -1082,8 +1148,18 @@ double get_sector_minimum_ground_level(u64 seed, v2s16 sectorpos, double p)
|
||||||
v2s16(node_max.X, node_max.Y), p));
|
v2s16(node_max.X, node_max.Y), p));
|
||||||
a = MYMIN(a, find_ground_level_from_noise(seed,
|
a = MYMIN(a, find_ground_level_from_noise(seed,
|
||||||
v2s16(node_min.X, node_min.Y), p));
|
v2s16(node_min.X, node_min.Y), p));
|
||||||
|
// Center
|
||||||
a = MYMIN(a, find_ground_level_from_noise(seed,
|
a = MYMIN(a, find_ground_level_from_noise(seed,
|
||||||
v2s16(node_min.X+MAP_BLOCKSIZE/2, node_min.Y+MAP_BLOCKSIZE/2), p));
|
v2s16(node_min.X+MAP_BLOCKSIZE/2, node_min.Y+MAP_BLOCKSIZE/2), p));
|
||||||
|
// Side middle points
|
||||||
|
a = MYMIN(a, find_ground_level_from_noise(seed,
|
||||||
|
v2s16(node_min.X+MAP_BLOCKSIZE/2, node_min.Y), p));
|
||||||
|
a = MYMIN(a, find_ground_level_from_noise(seed,
|
||||||
|
v2s16(node_min.X+MAP_BLOCKSIZE/2, node_max.Y), p));
|
||||||
|
a = MYMIN(a, find_ground_level_from_noise(seed,
|
||||||
|
v2s16(node_min.X, node_min.Y+MAP_BLOCKSIZE/2), p));
|
||||||
|
a = MYMIN(a, find_ground_level_from_noise(seed,
|
||||||
|
v2s16(node_max.X, node_min.Y+MAP_BLOCKSIZE/2), p));
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1328,7 +1404,7 @@ void make_block(BlockMakeData *data)
|
||||||
If block is deep underground, this is set to true and ground
|
If block is deep underground, this is set to true and ground
|
||||||
density noise is not generated, for speed optimization.
|
density noise is not generated, for speed optimization.
|
||||||
*/
|
*/
|
||||||
bool all_is_ground_except_caves = (minimum_ground_depth > 16);
|
bool all_is_ground_except_caves = (minimum_ground_depth > 40);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a block-specific seed
|
Create a block-specific seed
|
||||||
|
|
|
@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "content_craft.h"
|
#include "content_craft.h"
|
||||||
#include "content_nodemeta.h"
|
#include "content_nodemeta.h"
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
|
#include "serverobject.h"
|
||||||
|
|
||||||
#define BLOCK_EMERGE_FLAG_FROMDISK (1<<0)
|
#define BLOCK_EMERGE_FLAG_FROMDISK (1<<0)
|
||||||
|
|
||||||
|
@ -2411,8 +2412,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
toolname = titem->getToolName();
|
toolname = titem->getToolName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v3f playerpos = player->getPosition();
|
||||||
|
v3f objpos = obj->getBasePosition();
|
||||||
|
v3f dir = (objpos - playerpos).normalize();
|
||||||
|
|
||||||
u16 wear = obj->punch(toolname);
|
u16 wear = obj->punch(toolname, dir);
|
||||||
|
|
||||||
if(titem)
|
if(titem)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,9 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include "serverobject.h"
|
#include "serverobject.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "environment.h"
|
|
||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#include "collision.h"
|
|
||||||
|
|
||||||
core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
|
core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
|
||||||
|
|
||||||
|
@ -71,600 +69,4 @@ void ServerActiveObject::registerType(u16 type, Factory f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
TestSAO
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Prototype
|
|
||||||
TestSAO proto_TestSAO(NULL, 0, v3f(0,0,0));
|
|
||||||
|
|
||||||
TestSAO::TestSAO(ServerEnvironment *env, u16 id, v3f pos):
|
|
||||||
ServerActiveObject(env, id, pos),
|
|
||||||
m_timer1(0),
|
|
||||||
m_age(0)
|
|
||||||
{
|
|
||||||
ServerActiveObject::registerType(getType(), create);
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerActiveObject* TestSAO::create(ServerEnvironment *env, u16 id, v3f pos,
|
|
||||||
const std::string &data)
|
|
||||||
{
|
|
||||||
return new TestSAO(env, id, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
|
|
||||||
bool send_recommended)
|
|
||||||
{
|
|
||||||
m_age += dtime;
|
|
||||||
if(m_age > 10)
|
|
||||||
{
|
|
||||||
m_removed = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_base_position.Y += dtime * BS * 2;
|
|
||||||
if(m_base_position.Y > 8*BS)
|
|
||||||
m_base_position.Y = 2*BS;
|
|
||||||
|
|
||||||
if(send_recommended == false)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_timer1 -= dtime;
|
|
||||||
if(m_timer1 < 0.0)
|
|
||||||
{
|
|
||||||
m_timer1 += 0.125;
|
|
||||||
//dstream<<"TestSAO: id="<<getId()<<" sending data"<<std::endl;
|
|
||||||
|
|
||||||
std::string data;
|
|
||||||
|
|
||||||
data += itos(0); // 0 = position
|
|
||||||
data += " ";
|
|
||||||
data += itos(m_base_position.X);
|
|
||||||
data += " ";
|
|
||||||
data += itos(m_base_position.Y);
|
|
||||||
data += " ";
|
|
||||||
data += itos(m_base_position.Z);
|
|
||||||
|
|
||||||
ActiveObjectMessage aom(getId(), false, data);
|
|
||||||
messages.push_back(aom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
ItemSAO
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Prototype
|
|
||||||
ItemSAO proto_ItemSAO(NULL, 0, v3f(0,0,0), "");
|
|
||||||
|
|
||||||
ItemSAO::ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
|
|
||||||
const std::string inventorystring):
|
|
||||||
ServerActiveObject(env, id, pos),
|
|
||||||
m_inventorystring(inventorystring),
|
|
||||||
m_speed_f(0,0,0),
|
|
||||||
m_last_sent_position(0,0,0)
|
|
||||||
{
|
|
||||||
ServerActiveObject::registerType(getType(), create);
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerActiveObject* ItemSAO::create(ServerEnvironment *env, u16 id, v3f pos,
|
|
||||||
const std::string &data)
|
|
||||||
{
|
|
||||||
std::istringstream is(data, std::ios::binary);
|
|
||||||
char buf[1];
|
|
||||||
// read version
|
|
||||||
is.read(buf, 1);
|
|
||||||
u8 version = buf[0];
|
|
||||||
// check if version is supported
|
|
||||||
if(version != 0)
|
|
||||||
return NULL;
|
|
||||||
std::string inventorystring = deSerializeString(is);
|
|
||||||
dstream<<"ItemSAO::create(): Creating item \""
|
|
||||||
<<inventorystring<<"\""<<std::endl;
|
|
||||||
return new ItemSAO(env, id, pos, inventorystring);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItemSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
|
|
||||||
bool send_recommended)
|
|
||||||
{
|
|
||||||
assert(m_env);
|
|
||||||
|
|
||||||
const float interval = 0.2;
|
|
||||||
if(m_move_interval.step(dtime, interval)==false)
|
|
||||||
return;
|
|
||||||
dtime = interval;
|
|
||||||
|
|
||||||
core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.);
|
|
||||||
collisionMoveResult moveresult;
|
|
||||||
// Apply gravity
|
|
||||||
m_speed_f += v3f(0, -dtime*9.81*BS, 0);
|
|
||||||
// Maximum movement without glitches
|
|
||||||
f32 pos_max_d = BS*0.25;
|
|
||||||
// Limit speed
|
|
||||||
if(m_speed_f.getLength()*dtime > pos_max_d)
|
|
||||||
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
|
|
||||||
v3f pos_f = getBasePosition();
|
|
||||||
v3f pos_f_old = pos_f;
|
|
||||||
moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
|
|
||||||
box, dtime, pos_f, m_speed_f);
|
|
||||||
|
|
||||||
if(send_recommended == false)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
|
|
||||||
{
|
|
||||||
setBasePosition(pos_f);
|
|
||||||
m_last_sent_position = pos_f;
|
|
||||||
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
char buf[6];
|
|
||||||
// command (0 = update position)
|
|
||||||
buf[0] = 0;
|
|
||||||
os.write(buf, 1);
|
|
||||||
// pos
|
|
||||||
writeS32((u8*)buf, m_base_position.X*1000);
|
|
||||||
os.write(buf, 4);
|
|
||||||
writeS32((u8*)buf, m_base_position.Y*1000);
|
|
||||||
os.write(buf, 4);
|
|
||||||
writeS32((u8*)buf, m_base_position.Z*1000);
|
|
||||||
os.write(buf, 4);
|
|
||||||
// create message and add to list
|
|
||||||
ActiveObjectMessage aom(getId(), false, os.str());
|
|
||||||
messages.push_back(aom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ItemSAO::getClientInitializationData()
|
|
||||||
{
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
char buf[6];
|
|
||||||
// version
|
|
||||||
buf[0] = 0;
|
|
||||||
os.write(buf, 1);
|
|
||||||
// pos
|
|
||||||
writeS32((u8*)buf, m_base_position.X*1000);
|
|
||||||
os.write(buf, 4);
|
|
||||||
writeS32((u8*)buf, m_base_position.Y*1000);
|
|
||||||
os.write(buf, 4);
|
|
||||||
writeS32((u8*)buf, m_base_position.Z*1000);
|
|
||||||
os.write(buf, 4);
|
|
||||||
// inventorystring
|
|
||||||
os<<serializeString(m_inventorystring);
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ItemSAO::getStaticData()
|
|
||||||
{
|
|
||||||
dstream<<__FUNCTION_NAME<<std::endl;
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
char buf[1];
|
|
||||||
// version
|
|
||||||
buf[0] = 0;
|
|
||||||
os.write(buf, 1);
|
|
||||||
// inventorystring
|
|
||||||
os<<serializeString(m_inventorystring);
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
InventoryItem * ItemSAO::createInventoryItem()
|
|
||||||
{
|
|
||||||
try{
|
|
||||||
std::istringstream is(m_inventorystring, std::ios_base::binary);
|
|
||||||
InventoryItem *item = InventoryItem::deSerialize(is);
|
|
||||||
dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
|
|
||||||
<<m_inventorystring<<"\" -> item="<<item
|
|
||||||
<<std::endl;
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
catch(SerializationError &e)
|
|
||||||
{
|
|
||||||
dstream<<__FUNCTION_NAME<<": serialization error: "
|
|
||||||
<<"m_inventorystring=\""<<m_inventorystring<<"\""<<std::endl;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
RatSAO
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Prototype
|
|
||||||
RatSAO proto_RatSAO(NULL, 0, v3f(0,0,0));
|
|
||||||
|
|
||||||
RatSAO::RatSAO(ServerEnvironment *env, u16 id, v3f pos):
|
|
||||||
ServerActiveObject(env, id, pos),
|
|
||||||
m_is_active(false),
|
|
||||||
m_speed_f(0,0,0)
|
|
||||||
{
|
|
||||||
ServerActiveObject::registerType(getType(), create);
|
|
||||||
|
|
||||||
m_oldpos = v3f(0,0,0);
|
|
||||||
m_last_sent_position = v3f(0,0,0);
|
|
||||||
m_yaw = 0;
|
|
||||||
m_counter1 = 0;
|
|
||||||
m_counter2 = 0;
|
|
||||||
m_age = 0;
|
|
||||||
m_touching_ground = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerActiveObject* RatSAO::create(ServerEnvironment *env, u16 id, v3f pos,
|
|
||||||
const std::string &data)
|
|
||||||
{
|
|
||||||
std::istringstream is(data, std::ios::binary);
|
|
||||||
char buf[1];
|
|
||||||
// read version
|
|
||||||
is.read(buf, 1);
|
|
||||||
u8 version = buf[0];
|
|
||||||
// check if version is supported
|
|
||||||
if(version != 0)
|
|
||||||
return NULL;
|
|
||||||
return new RatSAO(env, id, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RatSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
|
|
||||||
bool send_recommended)
|
|
||||||
{
|
|
||||||
assert(m_env);
|
|
||||||
|
|
||||||
if(m_is_active == false)
|
|
||||||
{
|
|
||||||
if(m_inactive_interval.step(dtime, 0.5)==false)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
The AI
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*m_age += dtime;
|
|
||||||
if(m_age > 60)
|
|
||||||
{
|
|
||||||
// Die
|
|
||||||
m_removed = true;
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Apply gravity
|
|
||||||
m_speed_f.Y -= dtime*9.81*BS;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Move around if some player is close
|
|
||||||
*/
|
|
||||||
bool player_is_close = false;
|
|
||||||
// Check connected players
|
|
||||||
core::list<Player*> players = m_env->getPlayers(true);
|
|
||||||
core::list<Player*>::Iterator i;
|
|
||||||
for(i = players.begin();
|
|
||||||
i != players.end(); i++)
|
|
||||||
{
|
|
||||||
Player *player = *i;
|
|
||||||
v3f playerpos = player->getPosition();
|
|
||||||
if(m_base_position.getDistanceFrom(playerpos) < BS*10.0)
|
|
||||||
{
|
|
||||||
player_is_close = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_is_active = player_is_close;
|
|
||||||
|
|
||||||
if(player_is_close == false)
|
|
||||||
{
|
|
||||||
m_speed_f.X = 0;
|
|
||||||
m_speed_f.Z = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Move around
|
|
||||||
v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
|
|
||||||
f32 speed = 2*BS;
|
|
||||||
m_speed_f.X = speed * dir.X;
|
|
||||||
m_speed_f.Z = speed * dir.Z;
|
|
||||||
|
|
||||||
if(m_touching_ground && (m_oldpos - m_base_position).getLength()
|
|
||||||
< dtime*speed/2)
|
|
||||||
{
|
|
||||||
m_counter1 -= dtime;
|
|
||||||
if(m_counter1 < 0.0)
|
|
||||||
{
|
|
||||||
m_counter1 += 1.0;
|
|
||||||
m_speed_f.Y = 5.0*BS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
m_counter2 -= dtime;
|
|
||||||
if(m_counter2 < 0.0)
|
|
||||||
{
|
|
||||||
m_counter2 += (float)(myrand()%100)/100*3.0;
|
|
||||||
m_yaw += ((float)(myrand()%200)-100)/100*180;
|
|
||||||
m_yaw = wrapDegrees(m_yaw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_oldpos = m_base_position;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Move it, with collision detection
|
|
||||||
*/
|
|
||||||
|
|
||||||
core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.);
|
|
||||||
collisionMoveResult moveresult;
|
|
||||||
// Maximum movement without glitches
|
|
||||||
f32 pos_max_d = BS*0.25;
|
|
||||||
// Limit speed
|
|
||||||
if(m_speed_f.getLength()*dtime > pos_max_d)
|
|
||||||
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
|
|
||||||
v3f pos_f = getBasePosition();
|
|
||||||
v3f pos_f_old = pos_f;
|
|
||||||
moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
|
|
||||||
box, dtime, pos_f, m_speed_f);
|
|
||||||
m_touching_ground = moveresult.touching_ground;
|
|
||||||
|
|
||||||
setBasePosition(pos_f);
|
|
||||||
|
|
||||||
if(send_recommended == false)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
|
|
||||||
{
|
|
||||||
m_last_sent_position = pos_f;
|
|
||||||
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
// command (0 = update position)
|
|
||||||
writeU8(os, 0);
|
|
||||||
// pos
|
|
||||||
writeV3F1000(os, m_base_position);
|
|
||||||
// yaw
|
|
||||||
writeF1000(os, m_yaw);
|
|
||||||
// create message and add to list
|
|
||||||
ActiveObjectMessage aom(getId(), false, os.str());
|
|
||||||
messages.push_back(aom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string RatSAO::getClientInitializationData()
|
|
||||||
{
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
// version
|
|
||||||
writeU8(os, 0);
|
|
||||||
// pos
|
|
||||||
writeV3F1000(os, m_base_position);
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string RatSAO::getStaticData()
|
|
||||||
{
|
|
||||||
//dstream<<__FUNCTION_NAME<<std::endl;
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
// version
|
|
||||||
writeU8(os, 0);
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
InventoryItem* RatSAO::createPickedUpItem()
|
|
||||||
{
|
|
||||||
std::istringstream is("CraftItem rat 1", std::ios_base::binary);
|
|
||||||
InventoryItem *item = InventoryItem::deSerialize(is);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Oerkki1SAO
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Prototype
|
|
||||||
Oerkki1SAO proto_Oerkki1SAO(NULL, 0, v3f(0,0,0));
|
|
||||||
|
|
||||||
Oerkki1SAO::Oerkki1SAO(ServerEnvironment *env, u16 id, v3f pos):
|
|
||||||
ServerActiveObject(env, id, pos),
|
|
||||||
m_is_active(false),
|
|
||||||
m_speed_f(0,0,0)
|
|
||||||
{
|
|
||||||
ServerActiveObject::registerType(getType(), create);
|
|
||||||
|
|
||||||
m_oldpos = v3f(0,0,0);
|
|
||||||
m_last_sent_position = v3f(0,0,0);
|
|
||||||
m_yaw = 0;
|
|
||||||
m_counter1 = 0;
|
|
||||||
m_counter2 = 0;
|
|
||||||
m_age = 0;
|
|
||||||
m_touching_ground = false;
|
|
||||||
m_hp = 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerActiveObject* Oerkki1SAO::create(ServerEnvironment *env, u16 id, v3f pos,
|
|
||||||
const std::string &data)
|
|
||||||
{
|
|
||||||
std::istringstream is(data, std::ios::binary);
|
|
||||||
// read version
|
|
||||||
u8 version = readU8(is);
|
|
||||||
// read hp
|
|
||||||
u8 hp = readU8(is);
|
|
||||||
// check if version is supported
|
|
||||||
if(version != 0)
|
|
||||||
return NULL;
|
|
||||||
Oerkki1SAO *o = new Oerkki1SAO(env, id, pos);
|
|
||||||
o->m_hp = hp;
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Oerkki1SAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
|
|
||||||
bool send_recommended)
|
|
||||||
{
|
|
||||||
assert(m_env);
|
|
||||||
|
|
||||||
if(m_is_active == false)
|
|
||||||
{
|
|
||||||
if(m_inactive_interval.step(dtime, 0.5)==false)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
The AI
|
|
||||||
*/
|
|
||||||
|
|
||||||
m_age += dtime;
|
|
||||||
if(m_age > 120)
|
|
||||||
{
|
|
||||||
// Die
|
|
||||||
m_removed = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply gravity
|
|
||||||
m_speed_f.Y -= dtime*9.81*BS;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Move around if some player is close
|
|
||||||
*/
|
|
||||||
bool player_is_close = false;
|
|
||||||
v3f near_player_pos;
|
|
||||||
// Check connected players
|
|
||||||
core::list<Player*> players = m_env->getPlayers(true);
|
|
||||||
core::list<Player*>::Iterator i;
|
|
||||||
for(i = players.begin();
|
|
||||||
i != players.end(); i++)
|
|
||||||
{
|
|
||||||
Player *player = *i;
|
|
||||||
v3f playerpos = player->getPosition();
|
|
||||||
if(m_base_position.getDistanceFrom(playerpos) < BS*15.0)
|
|
||||||
{
|
|
||||||
player_is_close = true;
|
|
||||||
near_player_pos = playerpos;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_is_active = player_is_close;
|
|
||||||
|
|
||||||
if(player_is_close == false)
|
|
||||||
{
|
|
||||||
m_speed_f.X = 0;
|
|
||||||
m_speed_f.Z = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Move around
|
|
||||||
|
|
||||||
v3f ndir = near_player_pos - m_base_position;
|
|
||||||
ndir.Y = 0;
|
|
||||||
ndir /= ndir.getLength();
|
|
||||||
f32 nyaw = 180./PI*atan2(ndir.Z,ndir.X);
|
|
||||||
if(nyaw < m_yaw - 180)
|
|
||||||
nyaw += 360;
|
|
||||||
else if(nyaw > m_yaw + 180)
|
|
||||||
nyaw -= 360;
|
|
||||||
m_yaw = 0.95*m_yaw + 0.05*nyaw;
|
|
||||||
m_yaw = wrapDegrees(m_yaw);
|
|
||||||
|
|
||||||
v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
|
|
||||||
f32 speed = 2*BS;
|
|
||||||
m_speed_f.X = speed * dir.X;
|
|
||||||
m_speed_f.Z = speed * dir.Z;
|
|
||||||
|
|
||||||
if(m_touching_ground && (m_oldpos - m_base_position).getLength()
|
|
||||||
< dtime*speed/2)
|
|
||||||
{
|
|
||||||
m_counter1 -= dtime;
|
|
||||||
if(m_counter1 < 0.0)
|
|
||||||
{
|
|
||||||
m_counter1 += 1.0;
|
|
||||||
// Jump
|
|
||||||
m_speed_f.Y = 5.0*BS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
m_counter2 -= dtime;
|
|
||||||
if(m_counter2 < 0.0)
|
|
||||||
{
|
|
||||||
m_counter2 += (float)(myrand()%100)/100*3.0;
|
|
||||||
//m_yaw += ((float)(myrand()%200)-100)/100*180;
|
|
||||||
m_yaw += ((float)(myrand()%200)-100)/100*90;
|
|
||||||
m_yaw = wrapDegrees(m_yaw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_oldpos = m_base_position;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Move it, with collision detection
|
|
||||||
*/
|
|
||||||
|
|
||||||
core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*5./3.,BS/3.);
|
|
||||||
collisionMoveResult moveresult;
|
|
||||||
// Maximum movement without glitches
|
|
||||||
f32 pos_max_d = BS*0.25;
|
|
||||||
// Limit speed
|
|
||||||
if(m_speed_f.getLength()*dtime > pos_max_d)
|
|
||||||
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
|
|
||||||
v3f pos_f = getBasePosition();
|
|
||||||
v3f pos_f_old = pos_f;
|
|
||||||
moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
|
|
||||||
box, dtime, pos_f, m_speed_f);
|
|
||||||
m_touching_ground = moveresult.touching_ground;
|
|
||||||
|
|
||||||
setBasePosition(pos_f);
|
|
||||||
|
|
||||||
if(send_recommended == false)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
|
|
||||||
{
|
|
||||||
m_last_sent_position = pos_f;
|
|
||||||
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
// command (0 = update position)
|
|
||||||
writeU8(os, 0);
|
|
||||||
// pos
|
|
||||||
writeV3F1000(os, m_base_position);
|
|
||||||
// yaw
|
|
||||||
writeF1000(os, m_yaw);
|
|
||||||
// create message and add to list
|
|
||||||
ActiveObjectMessage aom(getId(), false, os.str());
|
|
||||||
messages.push_back(aom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Oerkki1SAO::getClientInitializationData()
|
|
||||||
{
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
// version
|
|
||||||
writeU8(os, 0);
|
|
||||||
// pos
|
|
||||||
writeV3F1000(os, m_base_position);
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Oerkki1SAO::getStaticData()
|
|
||||||
{
|
|
||||||
//dstream<<__FUNCTION_NAME<<std::endl;
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
// version
|
|
||||||
writeU8(os, 0);
|
|
||||||
// hp
|
|
||||||
writeU8(os, m_hp);
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 Oerkki1SAO::punch(const std::string &toolname)
|
|
||||||
{
|
|
||||||
u16 amount = 5;
|
|
||||||
if(amount < m_hp)
|
|
||||||
{
|
|
||||||
m_hp -= amount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Die
|
|
||||||
m_removed = true;
|
|
||||||
}
|
|
||||||
return 65536/100;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,7 @@ public:
|
||||||
same time so that the data can be combined in a single
|
same time so that the data can be combined in a single
|
||||||
packet.
|
packet.
|
||||||
*/
|
*/
|
||||||
virtual void step(float dtime, Queue<ActiveObjectMessage> &messages,
|
virtual void step(float dtime, bool send_recommended){}
|
||||||
bool send_recommended){}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The return value of this is passed to the client-side object
|
The return value of this is passed to the client-side object
|
||||||
|
@ -104,7 +103,8 @@ public:
|
||||||
If the object doesn't return an item, this will be called.
|
If the object doesn't return an item, this will be called.
|
||||||
Return value is tool wear.
|
Return value is tool wear.
|
||||||
*/
|
*/
|
||||||
virtual u16 punch(const std::string &toolname){return 0;}
|
virtual u16 punch(const std::string &toolname, v3f dir)
|
||||||
|
{return 0;}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Number of players which know about this object. Object won't be
|
Number of players which know about this object. Object won't be
|
||||||
|
@ -144,6 +144,11 @@ public:
|
||||||
*/
|
*/
|
||||||
v3s16 m_static_block;
|
v3s16 m_static_block;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Queue of messages to be sent to the client
|
||||||
|
*/
|
||||||
|
Queue<ActiveObjectMessage> m_messages_out;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Used for creating objects based on type
|
// Used for creating objects based on type
|
||||||
typedef ServerActiveObject* (*Factory)
|
typedef ServerActiveObject* (*Factory)
|
||||||
|
@ -159,96 +164,5 @@ private:
|
||||||
static core::map<u16, Factory> m_types;
|
static core::map<u16, Factory> m_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestSAO : public ServerActiveObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TestSAO(ServerEnvironment *env, u16 id, v3f pos);
|
|
||||||
u8 getType() const
|
|
||||||
{return ACTIVEOBJECT_TYPE_TEST;}
|
|
||||||
static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
|
|
||||||
const std::string &data);
|
|
||||||
void step(float dtime, Queue<ActiveObjectMessage> &messages,
|
|
||||||
bool send_recommended);
|
|
||||||
private:
|
|
||||||
float m_timer1;
|
|
||||||
float m_age;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ItemSAO : public ServerActiveObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
|
|
||||||
const std::string inventorystring);
|
|
||||||
u8 getType() const
|
|
||||||
{return ACTIVEOBJECT_TYPE_ITEM;}
|
|
||||||
static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
|
|
||||||
const std::string &data);
|
|
||||||
void step(float dtime, Queue<ActiveObjectMessage> &messages,
|
|
||||||
bool send_recommended);
|
|
||||||
std::string getClientInitializationData();
|
|
||||||
std::string getStaticData();
|
|
||||||
InventoryItem* createInventoryItem();
|
|
||||||
InventoryItem* createPickedUpItem(){return createInventoryItem();}
|
|
||||||
private:
|
|
||||||
std::string m_inventorystring;
|
|
||||||
v3f m_speed_f;
|
|
||||||
v3f m_last_sent_position;
|
|
||||||
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, Queue<ActiveObjectMessage> &messages,
|
|
||||||
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, Queue<ActiveObjectMessage> &messages,
|
|
||||||
bool send_recommended);
|
|
||||||
std::string getClientInitializationData();
|
|
||||||
std::string getStaticData();
|
|
||||||
InventoryItem* createPickedUpItem(){return NULL;}
|
|
||||||
u16 punch(const std::string &toolname);
|
|
||||||
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;
|
|
||||||
u8 m_hp;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue