From f9da2c9507f10a9193c9bd94d69cc85e53b58ba2 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 10 Mar 2012 01:38:48 +0200 Subject: [PATCH] Immediate smoke puff when a normal entity is punched to death --- data/clienttextures/smoke_puff.png | Bin 0 -> 2182 bytes data/mods/experimental/init.lua | 29 +++++++++- src/CMakeLists.txt | 1 + src/clientsimpleobject.h | 38 ++++++++++++ src/content_cao.cpp | 23 ++++++-- src/content_cso.cpp | 89 +++++++++++++++++++++++++++++ src/content_cso.h | 30 ++++++++++ src/content_sao.cpp | 46 ++++++++------- src/environment.cpp | 29 ++++++++++ src/environment.h | 8 +++ src/scriptapi.cpp | 24 ++++++-- src/scriptapi.h | 3 +- 12 files changed, 286 insertions(+), 34 deletions(-) create mode 100644 data/clienttextures/smoke_puff.png create mode 100644 src/clientsimpleobject.h create mode 100644 src/content_cso.cpp create mode 100644 src/content_cso.h diff --git a/data/clienttextures/smoke_puff.png b/data/clienttextures/smoke_puff.png new file mode 100644 index 0000000000000000000000000000000000000000..e346d204ce5af072890042beae581140c39a3d03 GIT binary patch literal 2182 zcmV;12zmF3P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyY* z7B?T3Br&Z30013nR9JLFZ*6U5Zgc_CX>@2HM@dakWG-a~000Nw zNklaY{s?iP_b-&d_Wb zTSzS>!GxIY1Ug8%w$g%SgD?vcEVv=GYk>lOU=~3bz+v1BtOyLlbkK2_amH@jna*tg z$bCE4C#2K&*LmmMd(YSJ+;c9l#778;({pok005iK28+dVJv}{ry)4Urq?GyzA^Rhd z$S*>n(35R#ZT|!SO6gGmDHRnJCxgLY!&2uqH#a}7*kCXK0L*4Hd_Lb(01yZSwgABO z>(>+X>-~OzGNp87Sy@?9ZEfwpBaz5^g1Fh^@mvD{#@OE}rEvjc>`|*+E*AhGFE6i1 zujI;=E1&!Q{@sL-3;=LCoht!gY;0^Z0H~^Z4gi9|V6wJ{QaT0zilTgR>C&a!Q&Usv znoO2u1Ofr{_xA%vMd`)OG`7oUhf`RmTL(izaxY=M@B~e zLpNp2IrlzJpVrouK&N@QK0;TkQjW;zlwN_kXu~<^L zfyV%B0`RP=s&QB=iju$>I|2ax{rzio(Kt;AS-vPJBuTOWKzn=pCB3Y!u5On`+ibR@ z0MOIZ^9tX$hl^sA(sBX)YBUIRJ-9UWb_*a4K%R)Jo5;>3wUokzKp(z5_CJ3G6VQu;iA)4cA#!5BM62-yT+ zYhPcVU6$qKKpnOdC-ye*ZLmGANM59T_Uo52SdU|>uaQYB{mpJ%VL?V$&4yO3b zI5INwEdaQE`?dmLC$FkS(>6IdnE>F$`uci{HZ6(r^=)l!xn{FDK2lXzSI4w)5klVK zE%~oPlR6@RZk{o=Px#NLl%|)KmOddWxqSKZ&-ktQJ^&MdFaY4eg9lq#~5Ro_4V~1DvI)!xc1z+b0;;rv9U2nlx1aQJ7sKK3N*;*q;k1b}cj{I=0(oYeLf6clLF7SP+<3ji1z8bUA_ z1Y;~kXYdO=zi;r+A9lOl+l5Qz6UJDKJMaa7pR}~JB($})6$l>3AA}_(C67PPw2+w1 zW=%Guy~+ebzRMMEAcX7{rsrH8rk3$&ea2ZI0(g@#c1ZJFz)`&9P*G6 + +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 01f13df4..3aba4c7c 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 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 00000000..ce6ce0a2 --- /dev/null +++ b/src/content_cso.cpp @@ -0,0 +1,89 @@ +/* +Minetest-c55 +Copyright (C) 2012 celeron55, Perttu Ahola + +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 +#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"<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"<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 00000000..127107c1 --- /dev/null +++ b/src/content_cso.h @@ -0,0 +1,30 @@ +/* +Minetest-c55 +Copyright (C) 2012 celeron55, Perttu Ahola + +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 568e4b1d..b04f03f2 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=\""<getLua(); diff --git a/src/environment.cpp b/src/environment.cpp index 6f1d8ff5..6a8943d1 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::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::Iterator + i = m_simple_objects.begin(); i != m_simple_objects.end();) + { + ClientSimpleObject *simple = *i; + core::list::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 89c9fd67..fcd16e29 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. @@ -424,6 +425,12 @@ public: } } + /* + ClientSimpleObjects + */ + + void addSimpleObject(ClientSimpleObject *simple); + /* ActiveObjects */ @@ -469,6 +476,7 @@ private: IGameDef *m_gamedef; IrrlichtDevice *m_irr; core::map m_active_objects; + core::list m_simple_objects; Queue 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 541baa61..7bdf7a9f 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="<