mirror of
https://github.com/moparisthebest/minetest
synced 2024-12-22 15:48:48 -05:00
reorganized a lot of stuff and modified mapgen and objects slightly while doing it
This commit is contained in:
parent
3b098fd5dc
commit
91cfbe2891
@ -9,7 +9,12 @@ src/jthread/CMakeFiles/*
|
||||
src/jthread/Makefile
|
||||
src/jthread/cmake_config.h
|
||||
src/jthread/cmake_install.cmake
|
||||
src/.*.swp
|
||||
src/sqlite/libsqlite3.a
|
||||
src/session.vim
|
||||
util/uloste.png
|
||||
minetest.conf
|
||||
debug.txt
|
||||
bin/
|
||||
CMakeCache.txt
|
||||
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 |
BIN
data/oerkki1_damaged.png
Normal file
BIN
data/oerkki1_damaged.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 341 B |
@ -61,6 +61,7 @@ configure_file(
|
||||
)
|
||||
|
||||
set(common_SRCS
|
||||
content_sao.cpp
|
||||
mapgen.cpp
|
||||
content_inventory.cpp
|
||||
content_nodemeta.cpp
|
||||
@ -102,6 +103,7 @@ set(common_SRCS
|
||||
# Client sources
|
||||
set(minetest_SRCS
|
||||
${common_SRCS}
|
||||
content_cao.cpp
|
||||
mapblock_mesh.cpp
|
||||
farmesh.cpp
|
||||
keycode.cpp
|
||||
|
@ -23,6 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "common_irrlicht.h"
|
||||
#include <string>
|
||||
|
||||
#define ACTIVEOBJECT_TYPE_INVALID 0
|
||||
// Other types are defined in content_object.h
|
||||
|
||||
struct ActiveObjectMessage
|
||||
{
|
||||
ActiveObjectMessage(u16 id_, bool reliable_=true, std::string data_=""):
|
||||
@ -36,12 +39,6 @@ struct ActiveObjectMessage
|
||||
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
|
||||
*/
|
||||
|
@ -21,9 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "debug.h"
|
||||
#include "porting.h"
|
||||
#include "constants.h"
|
||||
#include "utility.h"
|
||||
#include "environment.h"
|
||||
#include "tile.h"
|
||||
|
||||
/*
|
||||
ClientActiveObject
|
||||
@ -68,674 +65,4 @@ void ClientActiveObject::registerType(u16 type, Factory 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 "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 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
|
||||
|
||||
|
@ -182,4 +182,58 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
|
||||
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,
|
||||
const core::aabbox3d<f32> &box_0,
|
||||
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
|
||||
{
|
||||
|
753
src/content_cao.cpp
Normal file
753
src/content_cao.cpp
Normal file
@ -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();
|
||||
}
|
||||
|
||||
|
248
src/content_cao.h
Normal file
248
src/content_cao.h
Normal file
@ -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 "inventory.h"
|
||||
#include "serverobject.h"
|
||||
#include "content_mapnode.h"
|
||||
//#include "serverobject.h"
|
||||
#include "content_sao.h"
|
||||
|
||||
bool item_material_is_cookable(u8 content)
|
||||
{
|
||||
|
29
src/content_object.h
Normal file
29
src/content_object.h
Normal file
@ -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
|
||||
|
694
src/content_sao.cpp
Normal file
694
src/content_sao.cpp
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
118
src/content_sao.h
Normal file
118
src/content_sao.h
Normal file
@ -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 "content_mapnode.h"
|
||||
#include "mapblock.h"
|
||||
#include "serverobject.h"
|
||||
#include "content_sao.h"
|
||||
|
||||
Environment::Environment():
|
||||
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
|
||||
if(obj->m_removed || obj->m_pending_deactivation)
|
||||
continue;
|
||||
// Step object, putting messages directly to the queue
|
||||
obj->step(dtime, m_active_object_messages, send_recommended);
|
||||
// Step object
|
||||
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();
|
||||
// Step object
|
||||
obj->step(dtime, this);
|
||||
// Update lighting
|
||||
//u8 light = LIGHT_MAX;
|
||||
u8 light = 0;
|
||||
try{
|
||||
// Get node at head
|
||||
v3s16 p = obj->getLightPosition();
|
||||
MapNode n = m_map->getNode(p);
|
||||
light = n.getLightBlend(getDayNightRatio());
|
||||
|
||||
if(m_active_object_light_update_interval.step(dtime, 0.5))
|
||||
{
|
||||
// Update lighting
|
||||
//u8 light = LIGHT_MAX;
|
||||
u8 light = 0;
|
||||
try{
|
||||
// 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 <ostream>
|
||||
#include "utility.h"
|
||||
#include "activeobject.h"
|
||||
|
||||
class Server;
|
||||
class ActiveBlockModifier;
|
||||
class ServerActiveObject;
|
||||
|
||||
class Environment
|
||||
{
|
||||
@ -118,11 +123,6 @@ private:
|
||||
This is not thread-safe. Server uses an environment mutex.
|
||||
*/
|
||||
|
||||
#include "serverobject.h"
|
||||
|
||||
class Server;
|
||||
class ActiveBlockModifier;
|
||||
|
||||
class ServerEnvironment : public Environment
|
||||
{
|
||||
public:
|
||||
@ -412,6 +412,7 @@ private:
|
||||
scene::ISceneManager *m_smgr;
|
||||
core::map<u16, ClientActiveObject*> m_active_objects;
|
||||
Queue<ClientEnvEvent> m_client_event_queue;
|
||||
IntervalLimiter m_active_object_light_update_interval;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
12
src/game.cpp
12
src/game.cpp
@ -661,7 +661,9 @@ void the_game(
|
||||
screensize = driver->getScreenSize();
|
||||
|
||||
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
|
||||
|
||||
@ -967,6 +969,14 @@ void the_game(
|
||||
screensize = driver->getScreenSize();
|
||||
v2s32 displaycenter(screensize.X/2,screensize.Y/2);
|
||||
//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
|
||||
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 "content_mapnode.h"
|
||||
#include "content_inventory.h"
|
||||
#include "content_sao.h"
|
||||
|
||||
/*
|
||||
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 "voxel.h"
|
||||
#include "porting.h"
|
||||
#include "mineral.h"
|
||||
#include "noise.h"
|
||||
#include "serverobject.h"
|
||||
#include "content_mapnode.h"
|
||||
#include "mapgen.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
|
||||
*/
|
||||
@ -2869,10 +2865,10 @@ MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load
|
||||
// format. Just go ahead and create the sector.
|
||||
if(fs::PathExists(sectordir))
|
||||
{
|
||||
dstream<<"ServerMap::loadSectorMeta(): Sector metafile "
|
||||
/*dstream<<"ServerMap::loadSectorMeta(): Sector metafile "
|
||||
<<fullpath<<" doesn't exist but directory does."
|
||||
<<" Continuing with a sector with no metadata."
|
||||
<<std::endl;
|
||||
<<std::endl;*/
|
||||
sector = new ServerMapSector(this, p2d);
|
||||
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 "mapblock.h"
|
||||
#include "map.h"
|
||||
#include "serverobject.h"
|
||||
#include "mineral.h"
|
||||
//#include "serverobject.h"
|
||||
#include "content_sao.h"
|
||||
|
||||
namespace mapgen
|
||||
{
|
||||
@ -503,7 +504,7 @@ static void make_corridor(VoxelManipulator &vmanip, v3s16 doorplace,
|
||||
else
|
||||
length = random.range(1,6);
|
||||
length = random.range(1,13);
|
||||
u32 partlength = random.range(1,length);
|
||||
u32 partlength = random.range(1,13);
|
||||
u32 partcount = 0;
|
||||
s16 make_stairs = 0;
|
||||
if(random.next()%2 == 0 && partlength >= 3)
|
||||
@ -672,14 +673,63 @@ public:
|
||||
continue;
|
||||
v3s16 roomplace;
|
||||
// X east, Z north, Y up
|
||||
#if 0
|
||||
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-
|
||||
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+
|
||||
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-
|
||||
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
|
||||
bool fits = true;
|
||||
@ -790,7 +840,7 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random)
|
||||
|
||||
// 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;
|
||||
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -866,7 +918,9 @@ NoiseParams get_cave_noise2_params(u64 seed)
|
||||
{
|
||||
/*return NoiseParams(NOISE_PERLIN_CONTOUR_FLIP_YZ, seed+10325, 5, 0.7,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1054,6 +1108,7 @@ double get_sector_maximum_ground_level(u64 seed, v2s16 sectorpos, double p)
|
||||
v2s16 node_min = sectorpos*MAP_BLOCKSIZE;
|
||||
v2s16 node_max = (sectorpos+v2s16(1,1))*MAP_BLOCKSIZE-v2s16(1,1);
|
||||
double a = -31000;
|
||||
// Corners
|
||||
a = MYMAX(a, find_ground_level_from_noise(seed,
|
||||
v2s16(node_min.X, node_min.Y), p));
|
||||
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));
|
||||
a = MYMAX(a, find_ground_level_from_noise(seed,
|
||||
v2s16(node_min.X, node_min.Y), p));
|
||||
// Center
|
||||
a = MYMAX(a, find_ground_level_from_noise(seed,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1074,6 +1139,7 @@ double get_sector_minimum_ground_level(u64 seed, v2s16 sectorpos, double p)
|
||||
v2s16 node_min = sectorpos*MAP_BLOCKSIZE;
|
||||
v2s16 node_max = (sectorpos+v2s16(1,1))*MAP_BLOCKSIZE-v2s16(1,1);
|
||||
double a = 31000;
|
||||
// Corners
|
||||
a = MYMIN(a, find_ground_level_from_noise(seed,
|
||||
v2s16(node_min.X, node_min.Y), p));
|
||||
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));
|
||||
a = MYMIN(a, find_ground_level_from_noise(seed,
|
||||
v2s16(node_min.X, node_min.Y), p));
|
||||
// Center
|
||||
a = MYMIN(a, find_ground_level_from_noise(seed,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1328,7 +1404,7 @@ void make_block(BlockMakeData *data)
|
||||
If block is deep underground, this is set to true and ground
|
||||
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
|
||||
|
@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "content_craft.h"
|
||||
#include "content_nodemeta.h"
|
||||
#include "mapblock.h"
|
||||
#include "serverobject.h"
|
||||
|
||||
#define BLOCK_EMERGE_FLAG_FROMDISK (1<<0)
|
||||
|
||||
@ -2411,8 +2412,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||
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)
|
||||
{
|
||||
|
@ -19,9 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include "serverobject.h"
|
||||
#include <fstream>
|
||||
#include "environment.h"
|
||||
#include "inventory.h"
|
||||
#include "collision.h"
|
||||
|
||||
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
|
||||
packet.
|
||||
*/
|
||||
virtual void step(float dtime, Queue<ActiveObjectMessage> &messages,
|
||||
bool send_recommended){}
|
||||
virtual void step(float dtime, bool send_recommended){}
|
||||
|
||||
/*
|
||||
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.
|
||||
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
|
||||
@ -144,6 +144,11 @@ public:
|
||||
*/
|
||||
v3s16 m_static_block;
|
||||
|
||||
/*
|
||||
Queue of messages to be sent to the client
|
||||
*/
|
||||
Queue<ActiveObjectMessage> m_messages_out;
|
||||
|
||||
protected:
|
||||
// Used for creating objects based on type
|
||||
typedef ServerActiveObject* (*Factory)
|
||||
@ -159,96 +164,5 @@ private:
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user