make ItemCAO 3D

This commit is contained in:
darkrose 2014-11-12 00:19:04 +10:00
parent 8a767623d3
commit 5480e0b404
8 changed files with 143 additions and 142 deletions

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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)();

View File

@ -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
*/

View File

@ -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;

View File

@ -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);
}
{

View File

@ -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);
}