diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/clientsimpleobject.h | 38 | ||||
-rw-r--r-- | src/content_cao.cpp | 23 | ||||
-rw-r--r-- | src/content_cso.cpp | 89 | ||||
-rw-r--r-- | src/content_cso.h | 30 | ||||
-rw-r--r-- | src/content_sao.cpp | 46 | ||||
-rw-r--r-- | src/environment.cpp | 29 | ||||
-rw-r--r-- | src/environment.h | 8 | ||||
-rw-r--r-- | src/scriptapi.cpp | 24 | ||||
-rw-r--r-- | src/scriptapi.h | 3 |
10 files changed, 259 insertions, 32 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 860722712..d72128e01 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -157,6 +157,7 @@ endif() # Client sources set(minetest_SRCS ${common_SRCS} + content_cso.cpp content_mapblock.cpp content_cao.cpp mesh.cpp diff --git a/src/clientsimpleobject.h b/src/clientsimpleobject.h new file mode 100644 index 000000000..ad0abfe3c --- /dev/null +++ b/src/clientsimpleobject.h @@ -0,0 +1,38 @@ +/* +Minetest-c55 +Copyright (C) 2012 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 CLIENTSIMPLEOBJECT_HEADER +#define CLIENTSIMPLEOBJECT_HEADER + +#include "irrlichttypes.h" +class ClientEnvironment; + +class ClientSimpleObject +{ +protected: +public: + bool m_to_be_removed; + + ClientSimpleObject(): m_to_be_removed(false) {} + virtual ~ClientSimpleObject(){} + virtual void step(float dtime){} +}; + +#endif + diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 01f13df4e..3aba4c7cb 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "utility.h" // For IntervalLimiter #include "itemdef.h" #include "tool.h" +#include "content_cso.h" class Settings; struct ToolCapabilities; @@ -538,6 +539,7 @@ void ItemCAO::initialize(const std::string &data) class LuaEntityCAO : public ClientActiveObject { private: + scene::ISceneManager *m_smgr; core::aabbox3d<f32> m_selection_box; scene::IMeshSceneNode *m_meshnode; scene::IBillboardSceneNode *m_spritenode; @@ -562,6 +564,7 @@ private: public: LuaEntityCAO(IGameDef *gamedef, ClientEnvironment *env): ClientActiveObject(0, gamedef, env), + m_smgr(NULL), m_selection_box(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.), m_meshnode(NULL), m_spritenode(NULL), @@ -646,6 +649,8 @@ public: void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, IrrlichtDevice *irr) { + m_smgr = smgr; + if(m_meshnode != NULL || m_spritenode != NULL) return; @@ -701,15 +706,16 @@ public: void updateLight(u8 light_at_pos) { + bool is_visible = (m_hp != 0); u8 li = decode_light(light_at_pos); video::SColor color(255,li,li,li); if(m_meshnode){ setMeshColor(m_meshnode->getMesh(), color); - m_meshnode->setVisible(true); + m_meshnode->setVisible(is_visible); } if(m_spritenode){ m_spritenode->setColor(color); - m_spritenode->setVisible(true); + m_spritenode->setVisible(is_visible); } } @@ -947,12 +953,19 @@ public: if(result.did_punch && result.damage != 0) { - if(result.damage < m_hp) + if(result.damage < m_hp){ m_hp -= result.damage; - else + } else { m_hp = 0; + // TODO: Execute defined fast response + // As there is no definition, make a smoke puff + ClientSimpleObject *simple = createSmokePuff( + m_smgr, m_env, m_position, + m_prop->visual_size * BS); + m_env->addSimpleObject(simple); + } // TODO: Execute defined fast response - // I guess flashing is fine as of now + // Flashing shall suffice as there is no definition updateTextures("^[brighten"); m_reset_textures_timer = 0.1; } diff --git a/src/content_cso.cpp b/src/content_cso.cpp new file mode 100644 index 000000000..ce6ce0a21 --- /dev/null +++ b/src/content_cso.cpp @@ -0,0 +1,89 @@ +/* +Minetest-c55 +Copyright (C) 2012 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_cso.h" +#include <IBillboardSceneNode.h> +#include "tile.h" +#include "environment.h" +#include "gamedef.h" +#include "log.h" + +static void setBillboardTextureMatrix(scene::IBillboardSceneNode *bill, + float txs, float tys, int col, int row) +{ + video::SMaterial& material = bill->getMaterial(0); + core::matrix4& matrix = material.getTextureMatrix(0); + matrix.setTextureTranslate(txs*col, tys*row); + matrix.setTextureScale(txs, tys); +} + +class SmokePuffCSO: public ClientSimpleObject +{ + float m_age; + scene::IBillboardSceneNode *m_spritenode; +public: + SmokePuffCSO(scene::ISceneManager *smgr, + ClientEnvironment *env, v3f pos, v2f size): + m_age(0), + m_spritenode(NULL) + { + infostream<<"SmokePuffCSO: constructing"<<std::endl; + m_spritenode = smgr->addBillboardSceneNode( + NULL, v2f(1,1), pos, -1); + m_spritenode->setMaterialTexture(0, + env->getGameDef()->tsrc()->getTextureRaw("smoke_puff.png")); + m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false); + m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); + //m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); + m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL); + m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true); + m_spritenode->setColor(video::SColor(255,0,0,0)); + m_spritenode->setVisible(true); + m_spritenode->setSize(size); + /* Update brightness */ + u8 light = 64; + try{ + MapNode n = env->getMap().getNode(floatToInt(pos, BS)); + light = decode_light(n.getLightBlend(env->getDayNightRatio(), + env->getGameDef()->ndef())); + } + catch(InvalidPositionException &e){} + video::SColor color(255,light,light,light); + m_spritenode->setColor(color); + } + virtual ~SmokePuffCSO() + { + infostream<<"SmokePuffCSO: destructing"<<std::endl; + m_spritenode->remove(); + } + void step(float dtime) + { + m_age += dtime; + if(m_age > 1.0){ + m_to_be_removed = true; + } + } +}; + +ClientSimpleObject* createSmokePuff(scene::ISceneManager *smgr, + ClientEnvironment *env, v3f pos, v2f size) +{ + return new SmokePuffCSO(smgr, env, pos, size); +} + diff --git a/src/content_cso.h b/src/content_cso.h new file mode 100644 index 000000000..127107c16 --- /dev/null +++ b/src/content_cso.h @@ -0,0 +1,30 @@ +/* +Minetest-c55 +Copyright (C) 2012 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_CSO_HEADER +#define CONTENT_CSO_HEADER + +#include "common_irrlicht.h" +#include "clientsimpleobject.h" + +ClientSimpleObject* createSmokePuff(scene::ISceneManager *smgr, + ClientEnvironment *env, v3f pos, v2f size); + +#endif + diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 568e4b1da..b04f03f26 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -381,42 +381,45 @@ void LuaEntitySAO::addedToEnvironment() { ServerActiveObject::addedToEnvironment(); - // Create entity from name and state + // Create entity from name lua_State *L = m_env->getLua(); - m_registered = scriptapi_luaentity_add(L, m_id, m_init_name.c_str(), - m_init_state.c_str()); + m_registered = scriptapi_luaentity_add(L, m_id, m_init_name.c_str()); if(m_registered){ // Get properties scriptapi_luaentity_get_properties(L, m_id, m_prop); + // Initialize HP from properties + m_hp = m_prop->hp_max; } + + // Activate entity, supplying serialized state + scriptapi_luaentity_activate(L, m_id, m_init_state.c_str()); } ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos, const std::string &data) { - std::istringstream is(data, std::ios::binary); - // read version - u8 version = readU8(is); std::string name; std::string state; s16 hp = 1; v3f velocity; float yaw = 0; - // check if version is supported - if(version == 0){ - name = deSerializeString(is); - state = deSerializeLongString(is); - } - else if(version == 1){ - name = deSerializeString(is); - state = deSerializeLongString(is); - hp = readS16(is); - velocity = readV3F1000(is); - yaw = readF1000(is); - } - else{ - return NULL; + if(data != ""){ + std::istringstream is(data, std::ios::binary); + // read version + u8 version = readU8(is); + // check if version is supported + if(version == 0){ + name = deSerializeString(is); + state = deSerializeLongString(is); + } + else if(version == 1){ + name = deSerializeString(is); + state = deSerializeLongString(is); + hp = readS16(is); + velocity = readV3F1000(is); + yaw = readF1000(is); + } } // create object infostream<<"LuaEntitySAO::create(name=\""<<name<<"\" state=\"" @@ -581,6 +584,9 @@ int LuaEntitySAO::punch(v3f dir, ActiveObjectMessage aom(getId(), true, os.str()); m_messages_out.push_back(aom); } + + if(getHP() == 0) + m_removed = true; } lua_State *L = m_env->getLua(); diff --git a/src/environment.cpp b/src/environment.cpp index 6f1d8ff55..6a8943d12 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -1806,6 +1806,8 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) #ifndef SERVER +#include "clientsimpleobject.h" + /* ClientEnvironment */ @@ -1831,6 +1833,12 @@ ClientEnvironment::~ClientEnvironment() delete i.getNode()->getValue(); } + for(core::list<ClientSimpleObject*>::Iterator + i = m_simple_objects.begin(); i != m_simple_objects.end(); i++) + { + delete *i; + } + // Drop/delete map m_map->drop(); } @@ -2108,6 +2116,22 @@ void ClientEnvironment::step(float dtime) obj->updateLight(light); } } + + /* + Step and handle simple objects + */ + for(core::list<ClientSimpleObject*>::Iterator + i = m_simple_objects.begin(); i != m_simple_objects.end();) + { + ClientSimpleObject *simple = *i; + core::list<ClientSimpleObject*>::Iterator cur = i; + i++; + simple->step(dtime); + if(simple->m_to_be_removed){ + delete simple; + m_simple_objects.erase(cur); + } + } } void ClientEnvironment::updateMeshes(v3s16 blockpos) @@ -2119,6 +2143,11 @@ void ClientEnvironment::expireMeshes(bool only_daynight_diffed) { m_map->expireMeshes(only_daynight_diffed); } + +void ClientEnvironment::addSimpleObject(ClientSimpleObject *simple) +{ + m_simple_objects.push_back(simple); +} ClientActiveObject* ClientEnvironment::getActiveObject(u16 id) { diff --git a/src/environment.h b/src/environment.h index 89c9fd676..fcd16e296 100644 --- a/src/environment.h +++ b/src/environment.h @@ -356,6 +356,7 @@ private: #ifndef SERVER #include "clientobject.h" +class ClientSimpleObject; /* The client-side environment. @@ -425,6 +426,12 @@ public: } /* + ClientSimpleObjects + */ + + void addSimpleObject(ClientSimpleObject *simple); + + /* ActiveObjects */ @@ -469,6 +476,7 @@ private: IGameDef *m_gamedef; IrrlichtDevice *m_irr; core::map<u16, ClientActiveObject*> m_active_objects; + core::list<ClientSimpleObject*> m_simple_objects; Queue<ClientEnvEvent> m_client_event_queue; IntervalLimiter m_active_object_light_update_interval; IntervalLimiter m_lava_hurt_interval; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 541baa61c..7bdf7a9f4 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -4226,8 +4226,7 @@ void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp) luaentity */ -bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name, - const std::string &staticdata) +bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name) { realitycheck(L); assert(lua_checkstack(L, 20)); @@ -4274,6 +4273,21 @@ bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name, lua_pushvalue(L, object); // Copy object to top of stack lua_settable(L, -3); + return true; +} + +void scriptapi_luaentity_activate(lua_State *L, u16 id, + const std::string &staticdata) +{ + realitycheck(L); + assert(lua_checkstack(L, 20)); + infostream<<"scriptapi_luaentity_activate: id="<<id<<std::endl; + StackUnroller stack_unroller(L); + + // Get minetest.luaentities[id] + luaentity_get(L, id); + int object = lua_gettop(L); + // Get on_activate function lua_pushvalue(L, object); lua_getfield(L, -1, "on_activate"); @@ -4283,11 +4297,9 @@ bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name, lua_pushlstring(L, staticdata.c_str(), staticdata.size()); // Call with 2 arguments, 0 results if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error running function %s:on_activate: %s\n", - name, lua_tostring(L, -1)); + script_error(L, "error running function on_activate: %s\n", + lua_tostring(L, -1)); } - - return true; } void scriptapi_luaentity_rm(lua_State *L, u16 id) diff --git a/src/scriptapi.h b/src/scriptapi.h index aa2d9d4c7..f63cab368 100644 --- a/src/scriptapi.h +++ b/src/scriptapi.h @@ -75,7 +75,8 @@ bool scriptapi_node_on_dig(lua_State *L, v3s16 p, MapNode node, /* luaentity */ // Returns true if succesfully added into Lua; false otherwise. -bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name, +bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name); +void scriptapi_luaentity_activate(lua_State *L, u16 id, const std::string &staticdata); void scriptapi_luaentity_rm(lua_State *L, u16 id); std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id); |