make ItemCAO 3D
This commit is contained in:
parent
8a767623d3
commit
5480e0b404
|
@ -177,9 +177,9 @@ void Camera::step(f32 dtime)
|
|||
float lim = 0.15;
|
||||
if (m_digging_anim_was < lim && m_digging_anim >= lim) {
|
||||
if (m_digging_button == 0) {
|
||||
m_client->playDigSound();
|
||||
m_client->playDigSound(CONTENT_IGNORE);
|
||||
}else if(m_digging_button == 1) {
|
||||
m_client->playPlaceSound();
|
||||
m_client->playPlaceSound(CONTENT_IGNORE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,9 @@
|
|||
#include "http.h"
|
||||
#include "sound.h"
|
||||
#include "content_clothesitem.h"
|
||||
#include "content_toolitem.h"
|
||||
#include "content_craftitem.h"
|
||||
#include "content_mob.h"
|
||||
|
||||
/*
|
||||
QueuedMeshUpdate
|
||||
|
@ -212,6 +215,7 @@ Client::Client(
|
|||
m_server_ser_ver(SER_FMT_VER_INVALID),
|
||||
m_inventory_updated(false),
|
||||
m_pointed_node(-32768,-32768,-32768),
|
||||
m_pointed_content(CONTENT_IGNORE),
|
||||
m_time_of_day(0),
|
||||
m_map_seed(0),
|
||||
m_map_type(MGT_DEFAULT),
|
||||
|
@ -1581,8 +1585,10 @@ void Client::groundAction(u8 action, v3s16 nodepos_undersurface,
|
|||
writeV3S16(&data[9], nodepos_oversurface);
|
||||
writeU16(&data[15], item);
|
||||
Send(0, data, true);
|
||||
if (action == 3)
|
||||
playDigSound();
|
||||
if (action == 3) {
|
||||
content_t c = m_env.getMap().getNodeNoEx(nodepos_undersurface).getContent();
|
||||
playDigSound(c);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::clickActiveObject(u8 button, u16 id, u16 item_i)
|
||||
|
@ -2086,18 +2092,15 @@ ClientActiveObject * Client::getSelectedActiveObject(
|
|||
|
||||
m_env.getActiveObjects(from_pos_f_on_map, max_d, objects);
|
||||
|
||||
//infostream<<"Collected "<<objects.size()<<" nearby objects"<<std::endl;
|
||||
|
||||
// Sort them.
|
||||
// After this, the closest object is the first in the array.
|
||||
objects.sort();
|
||||
|
||||
for(u32 i=0; i<objects.size(); i++)
|
||||
{
|
||||
for (u32 i=0; i<objects.size(); i++) {
|
||||
ClientActiveObject *obj = objects[i].obj;
|
||||
|
||||
core::aabbox3d<f32> *selection_box = obj->getSelectionBox();
|
||||
if(selection_box == NULL)
|
||||
if (selection_box == NULL)
|
||||
continue;
|
||||
|
||||
v3f pos = obj->getPosition();
|
||||
|
@ -2107,31 +2110,19 @@ ClientActiveObject * Client::getSelectedActiveObject(
|
|||
selection_box->MaxEdge + pos
|
||||
);
|
||||
|
||||
if(offsetted_box.intersectsWithLine(shootline_on_map))
|
||||
{
|
||||
//infostream<<"Returning selected object"<<std::endl;
|
||||
if (offsetted_box.intersectsWithLine(shootline_on_map))
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
//infostream<<"No object selected; returning NULL."<<std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Client::printDebugInfo(std::ostream &os)
|
||||
{
|
||||
//JMutexAutoLock lock1(m_fetchblock_mutex);
|
||||
/*JMutexAutoLock lock2(m_incoming_queue_mutex);
|
||||
|
||||
os<<"m_incoming_queue.getSize()="<<m_incoming_queue.getSize()
|
||||
//<<", m_fetchblock_history.size()="<<m_fetchblock_history.size()
|
||||
//<<", m_opt_not_found_history.size()="<<m_opt_not_found_history.size()
|
||||
<<std::endl;*/
|
||||
}
|
||||
|
||||
u32 Client::getDayNightRatio()
|
||||
{
|
||||
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
|
||||
return m_env.getDayNightRatio();
|
||||
}
|
||||
|
||||
|
@ -2330,7 +2321,7 @@ void Client::playStepSound()
|
|||
}
|
||||
}
|
||||
|
||||
void Client::playDigSound()
|
||||
void Client::playDigSound(content_t c)
|
||||
{
|
||||
if (!m_sound)
|
||||
return;
|
||||
|
@ -2341,9 +2332,12 @@ void Client::playDigSound()
|
|||
if (volume > 100.0)
|
||||
volume = 100.0;
|
||||
volume /= 100.0;
|
||||
v3s16 p = getPointedNode();
|
||||
MapNode n = m_env.getMap().getNodeNoEx(p);
|
||||
switch (content_features(n).type) {
|
||||
if (c == CONTENT_IGNORE) {
|
||||
c = getPointedContent();
|
||||
if ((c&CONTENT_MOB_MASK) != 0)
|
||||
return;
|
||||
}
|
||||
switch (content_features(c).type) {
|
||||
case CMT_PLANT:
|
||||
m_sound->playSound("plant-dig",false,volume);
|
||||
break;
|
||||
|
@ -2363,7 +2357,7 @@ void Client::playDigSound()
|
|||
}
|
||||
}
|
||||
|
||||
void Client::playPlaceSound()
|
||||
void Client::playPlaceSound(content_t c)
|
||||
{
|
||||
if (!m_sound)
|
||||
return;
|
||||
|
|
|
@ -328,12 +328,15 @@ public:
|
|||
virtual ISoundManager* getSoundManager();
|
||||
|
||||
void playStepSound();
|
||||
void playDigSound();
|
||||
void playPlaceSound();
|
||||
void playDigSound(content_t c);
|
||||
void playPlaceSound(content_t c);
|
||||
|
||||
void setPointedNode(v3s16 p) {m_pointed_node = p;}
|
||||
v3s16 getPointedNode() {return m_pointed_node;}
|
||||
|
||||
void setPointedContent(content_t c) {m_pointed_content = c;}
|
||||
content_t getPointedContent() {return m_pointed_content;}
|
||||
|
||||
bool getServerDamage() {return m_server_damage;}
|
||||
bool getServerSuffocation() {return m_server_suffocation;}
|
||||
bool getServerHunger() {return m_server_hunger;}
|
||||
|
@ -385,6 +388,7 @@ private:
|
|||
|
||||
core::map<v3s16, bool> m_active_blocks;
|
||||
v3s16 m_pointed_node;
|
||||
content_t m_pointed_content;
|
||||
|
||||
PacketCounter m_packetcounter;
|
||||
|
||||
|
|
|
@ -82,6 +82,9 @@ public:
|
|||
virtual bool directReportPunch(content_t punch_item, v3f dir)
|
||||
{ return false; }
|
||||
|
||||
// get the content type of whatever this is
|
||||
virtual content_t getContent() {return CONTENT_IGNORE;}
|
||||
|
||||
protected:
|
||||
// Used for creating objects based on type
|
||||
typedef ClientActiveObject* (*Factory)();
|
||||
|
|
|
@ -47,9 +47,11 @@ ItemCAO::ItemCAO():
|
|||
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)),
|
||||
m_camera_offset(v3s16(0,0,0))
|
||||
m_camera_offset(v3s16(0,0,0)),
|
||||
m_content(CONTENT_IGNORE)
|
||||
{
|
||||
ClientActiveObject::registerType(getType(), create);
|
||||
m_rot = myrand_range(0,360);
|
||||
}
|
||||
|
||||
ItemCAO::~ItemCAO()
|
||||
|
@ -63,80 +65,17 @@ ClientActiveObject* ItemCAO::create()
|
|||
|
||||
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();
|
||||
|
||||
/*
|
||||
Update image of node
|
||||
*/
|
||||
|
||||
// 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);
|
||||
infostream<<__FUNCTION_NAME<<": m_inventorystring=\""
|
||||
<<m_inventorystring<<"\" -> item="<<item
|
||||
<<std::endl;
|
||||
if(item)
|
||||
{
|
||||
texture = item->getImage();
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
catch(SerializationError &e)
|
||||
{
|
||||
infostream<<"WARNING: "<<__FUNCTION_NAME
|
||||
<<": error deSerializing inventorystring \""
|
||||
<<m_inventorystring<<"\""<<std::endl;
|
||||
if (m_node == NULL) {
|
||||
m_node = new ExtrudedSpriteSceneNode(smgr->getRootSceneNode(),smgr,-1,v3f(0,0,0),v3f(0,0,0),v3f(5,5,5));
|
||||
m_node->setVisible(false);
|
||||
}
|
||||
|
||||
// Set meshbuffer texture
|
||||
buf->getMaterial().setTexture(0, texture);
|
||||
updateVisual();
|
||||
}
|
||||
|
||||
void ItemCAO::removeFromScene()
|
||||
{
|
||||
if(m_node == NULL)
|
||||
if (m_node == NULL)
|
||||
return;
|
||||
|
||||
m_node->remove();
|
||||
|
@ -145,12 +84,11 @@ void ItemCAO::removeFromScene()
|
|||
|
||||
void ItemCAO::updateLight(u8 light_at_pos)
|
||||
{
|
||||
if(m_node == NULL)
|
||||
if (m_node == NULL)
|
||||
return;
|
||||
|
||||
u8 li = decode_light(light_at_pos);
|
||||
video::SColor color(255,li,li,li);
|
||||
setMeshVerticesColor(m_node->getMesh(), color);
|
||||
m_node->updateLight(li);
|
||||
}
|
||||
|
||||
v3s16 ItemCAO::getLightPosition()
|
||||
|
@ -160,25 +98,26 @@ v3s16 ItemCAO::getLightPosition()
|
|||
|
||||
void ItemCAO::updateNodePos()
|
||||
{
|
||||
if(m_node == NULL)
|
||||
if (m_node == NULL)
|
||||
return;
|
||||
|
||||
m_node->setPosition(m_position-intToFloat(m_camera_offset, BS));
|
||||
m_node->setPosition(m_position-intToFloat(m_camera_offset, BS)+v3f(0,3,0));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if (m_node == NULL)
|
||||
return;
|
||||
|
||||
updateVisual();
|
||||
|
||||
LocalPlayer *player = env->getLocalPlayer();
|
||||
assert(player);
|
||||
v3f rot = m_node->getRotation();
|
||||
rot.Y = m_rot++;
|
||||
if (m_rot > 360)
|
||||
m_rot -= 360;
|
||||
m_node->setRotation(rot);
|
||||
}
|
||||
|
||||
void ItemCAO::processMessage(const std::string &data)
|
||||
|
@ -187,8 +126,7 @@ void ItemCAO::processMessage(const std::string &data)
|
|||
std::istringstream is(data, std::ios::binary);
|
||||
// command
|
||||
u8 cmd = readU8(is);
|
||||
if(cmd == 0)
|
||||
{
|
||||
if (cmd == 0) {
|
||||
// pos
|
||||
m_position = readV3F1000(is);
|
||||
updateNodePos();
|
||||
|
@ -215,6 +153,61 @@ void ItemCAO::initialize(const std::string &data)
|
|||
updateNodePos();
|
||||
}
|
||||
|
||||
void ItemCAO::updateVisual()
|
||||
{
|
||||
InventoryItem *item = NULL;
|
||||
|
||||
// Create an inventory item to see what is its image
|
||||
std::istringstream is(m_inventorystring, std::ios_base::binary);
|
||||
try{
|
||||
item = InventoryItem::deSerialize(is);
|
||||
infostream<<__FUNCTION_NAME<<": m_inventorystring=\""
|
||||
<<m_inventorystring<<"\" -> item="<<item
|
||||
<<std::endl;
|
||||
}
|
||||
catch(SerializationError &e)
|
||||
{
|
||||
infostream<<"WARNING: "<<__FUNCTION_NAME
|
||||
<<": error deSerializing inventorystring \""
|
||||
<<m_inventorystring<<"\""<<std::endl;
|
||||
}
|
||||
if (item == NULL)
|
||||
return;
|
||||
|
||||
bool haveWield = false;
|
||||
|
||||
// Try to make a MaterialItem cube.
|
||||
if (std::string(item->getName()) == "MaterialItem") {
|
||||
// A block-type material
|
||||
MaterialItem* mat_item = (MaterialItem*)item;
|
||||
content_t content = mat_item->getMaterial();
|
||||
if (content_features(content).solidness || content_features(content).visual_solidness) {
|
||||
m_node->setCube(content_features(content).tiles);
|
||||
haveWield = true;
|
||||
}else if (
|
||||
(
|
||||
content_features(content).draw_type == CDT_NODEBOX
|
||||
|| content_features(content).draw_type == CDT_NODEBOX_META
|
||||
|| content_features(content).draw_type == CDT_FENCELIKE
|
||||
|| content_features(content).draw_type == CDT_WALLLIKE
|
||||
)
|
||||
&& content_features(content).wield_nodebox == true
|
||||
) {
|
||||
m_node->setNodeBox(content);
|
||||
haveWield = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If that failed, make an extruded sprite.
|
||||
if (!haveWield)
|
||||
m_node->setSprite(item->getImageRaw());
|
||||
|
||||
m_node->setVisible(true);
|
||||
updateNodePos();
|
||||
m_content = item->getContent();
|
||||
delete item;
|
||||
}
|
||||
|
||||
/*
|
||||
MobCAO
|
||||
*/
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "content_mob.h"
|
||||
class Settings;
|
||||
#include <IBillboardSceneNode.h>
|
||||
#include "mesh.h"
|
||||
|
||||
/*
|
||||
SmoothTranslator
|
||||
|
@ -160,12 +161,18 @@ public:
|
|||
m_camera_offset = camera_offset;
|
||||
}
|
||||
|
||||
virtual content_t getContent() {return m_content;}
|
||||
|
||||
private:
|
||||
void updateVisual();
|
||||
|
||||
core::aabbox3d<f32> m_selection_box;
|
||||
scene::IMeshSceneNode *m_node;
|
||||
ExtrudedSpriteSceneNode *m_node;
|
||||
v3f m_position;
|
||||
v3s16 m_camera_offset;
|
||||
std::string m_inventorystring;
|
||||
content_t m_content;
|
||||
f32 m_rot;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -208,6 +215,8 @@ public:
|
|||
|
||||
// If returns true, punch will not be sent to the server
|
||||
bool directReportPunch(content_t punch_item, v3f dir);
|
||||
|
||||
virtual content_t getContent() {return m_content;}
|
||||
private:
|
||||
void setAnimation(MobAnimation anim);
|
||||
aabb3f m_selection_box;
|
||||
|
|
25
src/game.cpp
25
src/game.cpp
|
@ -383,6 +383,8 @@ void getPointedNode(Client *client, v3f player_position,
|
|||
bool wield_is_craft = (wield && wield->getContent()&CONTENT_CRAFTITEM_MASK);
|
||||
bool wield_is_material = (!wield_is_hand && !wield_is_tool && !wield_is_craft);
|
||||
|
||||
content_t content = CONTENT_IGNORE;
|
||||
|
||||
for(s16 y = ystart; y <= yend; y++)
|
||||
for(s16 z = zstart; z <= zend; z++)
|
||||
for(s16 x = xstart; x <= xend; x++)
|
||||
|
@ -463,6 +465,7 @@ void getPointedNode(Client *client, v3f player_position,
|
|||
{
|
||||
nodefound = true;
|
||||
nodepos = np;
|
||||
content = n.getContent();
|
||||
neighbourpos = np;
|
||||
mindistance = distance;
|
||||
box.MinEdge -= intToFloat(camera_offset,BS);
|
||||
|
@ -500,6 +503,7 @@ void getPointedNode(Client *client, v3f player_position,
|
|||
{
|
||||
nodefound = true;
|
||||
nodepos = np;
|
||||
content = n.getContent();
|
||||
neighbourpos = np;
|
||||
mindistance = distance;
|
||||
box.MinEdge -= intToFloat(camera_offset,BS);
|
||||
|
@ -576,6 +580,7 @@ void getPointedNode(Client *client, v3f player_position,
|
|||
{
|
||||
nodefound = true;
|
||||
nodepos = np;
|
||||
content = n.getContent();
|
||||
neighbourpos = np + dirs[i];
|
||||
mindistance = distance;
|
||||
|
||||
|
@ -632,6 +637,7 @@ void getPointedNode(Client *client, v3f player_position,
|
|||
{
|
||||
nodefound = true;
|
||||
nodepos = np;
|
||||
content = n.getContent();
|
||||
neighbourpos = np + dirs[i];
|
||||
mindistance = distance;
|
||||
|
||||
|
@ -649,8 +655,12 @@ void getPointedNode(Client *client, v3f player_position,
|
|||
} // for dirs
|
||||
} // regular block
|
||||
} // for coords
|
||||
if (nodefound)
|
||||
if (nodefound) {
|
||||
client->setPointedNode(nodepos);
|
||||
client->setPointedContent(content);
|
||||
}else{
|
||||
client->setPointedContent(CONTENT_IGNORE);
|
||||
}
|
||||
}
|
||||
|
||||
void update_skybox(video::IVideoDriver* driver,
|
||||
|
@ -1667,11 +1677,10 @@ void the_game(
|
|||
bool left_punch = false;
|
||||
bool left_punch_muted = false;
|
||||
|
||||
if(selected_active_object != NULL)
|
||||
{
|
||||
if (selected_active_object != NULL) {
|
||||
client.setPointedContent(selected_active_object->getContent());
|
||||
/* Clear possible cracking animation */
|
||||
if(nodepos_old != v3s16(-32768,-32768,-32768))
|
||||
{
|
||||
if (nodepos_old != v3s16(-32768,-32768,-32768)) {
|
||||
client.clearTempMod(nodepos_old);
|
||||
dig_time = 0.0;
|
||||
nodepos_old = v3s16(-32768,-32768,-32768);
|
||||
|
@ -2060,11 +2069,11 @@ void the_game(
|
|||
guitext2->setVisible(false);
|
||||
}
|
||||
|
||||
if (show_debug) {
|
||||
// nothing
|
||||
}else if (g_menumgr.menuCount() == 0) {
|
||||
if (!show_debug && g_menumgr.menuCount() == 0) {
|
||||
guitext_info->setText(infotext.c_str());
|
||||
guitext_info->setVisible(show_hud);
|
||||
}else{
|
||||
guitext_info->setVisible(false);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -37,14 +37,11 @@ class MainMenuManager : public IMenuManager
|
|||
public:
|
||||
virtual void createdMenu(GUIModalMenu *menu)
|
||||
{
|
||||
for(core::list<GUIModalMenu*>::Iterator
|
||||
i = m_stack.begin();
|
||||
i != m_stack.end(); i++)
|
||||
{
|
||||
for (core::list<GUIModalMenu*>::Iterator i = m_stack.begin(); i != m_stack.end(); i++) {
|
||||
assert(*i != menu);
|
||||
}
|
||||
|
||||
if(m_stack.size() != 0)
|
||||
if (m_stack.size() != 0)
|
||||
(*m_stack.getLast())->setVisible(false);
|
||||
m_stack.push_back(menu);
|
||||
}
|
||||
|
@ -55,24 +52,16 @@ public:
|
|||
bool removed_entry;
|
||||
do{
|
||||
removed_entry = false;
|
||||
for(core::list<GUIModalMenu*>::Iterator
|
||||
i = m_stack.begin();
|
||||
i != m_stack.end(); i++)
|
||||
{
|
||||
if(*i == menu)
|
||||
{
|
||||
for (core::list<GUIModalMenu*>::Iterator i = m_stack.begin(); i != m_stack.end(); i++) {
|
||||
if (*i == menu) {
|
||||
m_stack.erase(i);
|
||||
removed_entry = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}while(removed_entry);
|
||||
} while(removed_entry);
|
||||
|
||||
/*core::list<GUIModalMenu*>::Iterator i = m_stack.getLast();
|
||||
assert(*i == menu);
|
||||
m_stack.erase(i);*/
|
||||
|
||||
if(m_stack.size() != 0)
|
||||
if (m_stack.size() != 0)
|
||||
(*m_stack.getLast())->setVisible(true);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue