#pragma once //======================================================================== // Events.h : defines common game events // // Part of the GameCode4 Application // // GameCode4 is the sample application that encapsulates much of the source code // discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David // "Rez" Graham, published by Charles River Media. // ISBN-10: 1133776574 | ISBN-13: 978-1133776574 // // If this source code has found it's way to you, and you think it has helped you // in any way, do the authors a favor and buy a new copy of the book - there are // detailed explanations in it that compliment this code well. Buy a copy at Amazon.com // by clicking here: // http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller= // // There's a companion web site at http://www.mcshaffry.com/GameCode/ // // The source code is managed and maintained through Google Code: // http://code.google.com/p/gamecode4/ // // (c) Copyright 2012 Michael L. McShaffry and David Graham // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser GPL v3 // as published by the Free Software Foundation. // // 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 // http://www.gnu.org/licenses/lgpl-3.0.txt for more details. // // You should have received a copy of the GNU Lesser GPL v3 // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //======================================================================== #include "EventManager.h" #include "../GameCode4/GameCode.h" #include "../LUAScripting/ScriptEvent.h" #include "../Graphics3D/Scene.h" //--------------------------------------------------------------------------------------------------------------------- // EvtData_New_Actor - This event is sent out when an actor is *actually* created. //--------------------------------------------------------------------------------------------------------------------- class EvtData_New_Actor : public BaseEventData { ActorId m_actorId; GameViewId m_viewId; public: static const EventType sk_EventType; EvtData_New_Actor(void) { m_actorId = INVALID_ACTOR_ID; m_viewId = gc_InvalidGameViewId; } explicit EvtData_New_Actor(ActorId actorId, GameViewId viewId = gc_InvalidGameViewId) : m_actorId(actorId), m_viewId(viewId) { } virtual void VDeserialize(std::istrstream& in) { in >> m_actorId; in >> m_viewId; } virtual const EventType& VGetEventType(void) const { return sk_EventType; } virtual IEventDataPtr VCopy(void) const { return IEventDataPtr(GCC_NEW EvtData_New_Actor(m_actorId, m_viewId)); } virtual void VSerialize(std::ostream& out) const { out << m_actorId << " "; out << m_viewId << " "; } virtual const char* GetName(void) const { return "EvtData_New_Actor"; } const ActorId GetActorId(void) const { return m_actorId; } GameViewId GetViewId(void) const { return m_viewId; } }; //--------------------------------------------------------------------------------------------------------------------- // EvtData_Destroy_Actor - sent when actors are destroyed //--------------------------------------------------------------------------------------------------------------------- class EvtData_Destroy_Actor : public BaseEventData { ActorId m_id; public: static const EventType sk_EventType; explicit EvtData_Destroy_Actor(ActorId id = INVALID_ACTOR_ID) : m_id(id) { // } virtual const EventType& VGetEventType(void) const { return sk_EventType; } virtual IEventDataPtr VCopy(void) const { return IEventDataPtr(GCC_NEW EvtData_Destroy_Actor(m_id)); } virtual void VSerialize(std::ostrstream &out) const { out << m_id; } virtual void VDeserialize(std::istrstream& in) { in >> m_id; } virtual const char* GetName(void) const { return "EvtData_Destroy_Actor"; } ActorId GetId(void) const { return m_id; } }; //--------------------------------------------------------------------------------------------------------------------- // EvtData_New_Render_Component - This event is sent out when an actor is *actually* created. //--------------------------------------------------------------------------------------------------------------------- class EvtData_New_Render_Component : public BaseEventData { ActorId m_actorId; std::shared_ptr m_pSceneNode; public: static const EventType sk_EventType; EvtData_New_Render_Component(void) { m_actorId = INVALID_ACTOR_ID; } explicit EvtData_New_Render_Component(ActorId actorId, std::shared_ptr pSceneNode) : m_actorId(actorId), m_pSceneNode(pSceneNode) { } virtual void VSerialize(std::ostrstream& out) const { GCC_ERROR(GetName() + std::string(" should not be serialzied!")); } virtual void VDeserialize(std::istrstream& in) { GCC_ERROR(GetName() + std::string(" should not be serialzied!")); } virtual const EventType& VGetEventType(void) const { return sk_EventType; } virtual IEventDataPtr VCopy(void) const { return IEventDataPtr(GCC_NEW EvtData_New_Render_Component(m_actorId, m_pSceneNode)); } virtual const char* GetName(void) const { return "EvtData_New_Render_Component"; } const ActorId GetActorId(void) const { return m_actorId; } std::shared_ptr GetSceneNode(void) const { return m_pSceneNode; } }; //--------------------------------------------------------------------------------------------------------------------- // EvtData_Modified_Render_Component - This event is sent out when a render component is changed // NOTE: This class is not described in the book! //--------------------------------------------------------------------------------------------------------------------- class EvtData_Modified_Render_Component : public BaseEventData { ActorId m_id; public: static const EventType sk_EventType; virtual const EventType& VGetEventType(void) const { return sk_EventType; } EvtData_Modified_Render_Component(void) { m_id = INVALID_ACTOR_ID; } EvtData_Modified_Render_Component(ActorId id) : m_id(id) { } virtual void VSerialize(std::ostrstream &out) const { out << m_id; } virtual void VDeserialize(std::istrstream& in) { in >> m_id; } virtual IEventDataPtr VCopy() const { return IEventDataPtr(GCC_NEW EvtData_Modified_Render_Component(m_id)); } virtual const char* GetName(void) const { return "EvtData_Modified_Render_Component"; } ActorId GetActorId(void) const { return m_id; } }; //--------------------------------------------------------------------------------------------------------------------- // EvtData_Environment_Loaded - this event is sent when a new game is started //--------------------------------------------------------------------------------------------------------------------- class EvtData_Environment_Loaded : public BaseEventData { public: static const EventType sk_EventType; EvtData_Environment_Loaded(void) { } virtual const EventType& VGetEventType(void) const { return sk_EventType; } virtual IEventDataPtr VCopy(void) const { return IEventDataPtr( GCC_NEW EvtData_Environment_Loaded( ) ); } virtual const char* GetName(void) const { return "EvtData_Environment_Loaded"; } }; //--------------------------------------------------------------------------------------------------------------------- // EvtData_Environment_Loaded - this event is sent when a client has loaded its environment // This is special because we only want this event to go from client to server, and stop there. The // EvtData_Environment_Loaded is received by server and proxy logics alike. Thy to do this with just the above // event and you'll get into an endless loop of the EvtData_Environment_Loaded event making infinite round trips // from client to server. // // FUTURE_WORK: It would be an interesting idea to add a "Private" type of event that is addressed only to a specific // listener. Of course, that might be a really dumb idea too - someone will have to try it! //--------------------------------------------------------------------------------------------------------------------- class EvtData_Remote_Environment_Loaded : public BaseEventData { public: static const EventType sk_EventType; EvtData_Remote_Environment_Loaded(void) { } virtual const EventType& VGetEventType(void) const { return sk_EventType; } virtual IEventDataPtr VCopy(void) const { return IEventDataPtr( GCC_NEW EvtData_Remote_Environment_Loaded( ) ); } virtual const char* GetName(void) const { return "EvtData_Remote_Environment_Loaded"; } }; //--------------------------------------------------------------------------------------------------------------------- // EvtData_Request_Start_Game - this is sent by the authoritative game logic to all views so they will load a game level. //--------------------------------------------------------------------------------------------------------------------- class EvtData_Request_Start_Game : public BaseEventData { public: static const EventType sk_EventType; EvtData_Request_Start_Game(void) { } virtual const EventType& VGetEventType(void) const { return sk_EventType; } virtual IEventDataPtr VCopy() const { return IEventDataPtr( GCC_NEW EvtData_Request_Start_Game( ) ); } virtual const char* GetName(void) const { return "EvtData_Request_Start_Game"; } }; //--------------------------------------------------------------------------------------------------------------------- // EvtData_Update_Tick - sent by the game logic each game tick //--------------------------------------------------------------------------------------------------------------------- class EvtData_Update_Tick : public BaseEventData { int m_DeltaMilliseconds; public: static const EventType sk_EventType; explicit EvtData_Update_Tick( const int deltaMilliseconds ) : m_DeltaMilliseconds( deltaMilliseconds ) { } virtual const EventType& VGetEventType( void ) const { return sk_EventType; } virtual IEventDataPtr VCopy() const { return IEventDataPtr (GCC_NEW EvtData_Update_Tick ( m_DeltaMilliseconds ) ); } virtual void Serialize( std::ostrstream & out ) { GCC_ERROR("You should not be serializing update ticks!"); } virtual const char* GetName(void) const { return "EvtData_Update_Tick"; } }; //--------------------------------------------------------------------------------------------------------------------- // class EvtData_Request_New_Actor // This event is sent by a server asking Client proxy logics to create new actors from their local resources. // It can be sent from script or via code. // This event is also sent from the server game logic to client logics AFTER it has created a new actor. The logics will allow follow suit to stay in sync. //--------------------------------------------------------------------------------------------------------------------- class EvtData_Request_New_Actor : public BaseEventData { std::string m_actorResource; bool m_hasInitialTransform; glm::mat4 m_initialTransform; ActorId m_serverActorId; GameViewId m_viewId; public: static const EventType sk_EventType; EvtData_Request_New_Actor() { m_actorResource = ""; m_hasInitialTransform = false; m_initialTransform = glm::mat4(1.0f); m_serverActorId = -1; m_viewId = gc_InvalidGameViewId; } explicit EvtData_Request_New_Actor(const std::string &actorResource, std::optional initialTransform=std::nullopt, const ActorId serverActorId = INVALID_ACTOR_ID, const GameViewId viewId = gc_InvalidGameViewId) { m_actorResource = actorResource; if (initialTransform) { m_hasInitialTransform = true; m_initialTransform = *initialTransform; } else m_hasInitialTransform = false; m_serverActorId = serverActorId; m_viewId = viewId; } virtual const EventType& VGetEventType(void) const { return sk_EventType; } virtual void VDeserialize(std::istrstream & in) { in >> m_actorResource; in >> m_hasInitialTransform; if (m_hasInitialTransform) { for (int i=0; i<4; i++) { for (int j=0; j<4; ++j) { in >> m_initialTransform[i][j]; } } } in >> m_serverActorId; in >> m_viewId; } virtual IEventDataPtr VCopy() const { return IEventDataPtr (GCC_NEW EvtData_Request_New_Actor(m_actorResource, (m_hasInitialTransform) ? std::optional(m_initialTransform) : std::nullopt, m_serverActorId, m_viewId)); } virtual void VSerialize( std::ostrstream & out ) const { out << m_actorResource << " "; out << m_hasInitialTransform << " "; if (m_hasInitialTransform) { for (int i=0; i<4; ++i) { for (int j=0; j<4; ++j) { out << m_initialTransform[i][j]; } } } } virtual const char* GetName(void) const { return "EvtData_Request_New_Actor"; } const std::string &GetActorResource(void) const { return m_actorResource; } const glm::mat4 *GetInitialTransform(void) const { return (m_hasInitialTransform) ? &m_initialTransform : NULL; } const ActorId GetServerActorId(void) const { return m_serverActorId; } GameViewId GetViewId(void) const { return m_viewId; } }; //--------------------------------------------------------------------------------------------------------------------- // EvtData_PlaySound - sent by any system wishing for a HumanView to play a sound //--------------------------------------------------------------------------------------------------------------------- class EvtData_PlaySound : public ScriptEvent { std::string m_soundResource; public: static const EventType sk_EventType; EvtData_PlaySound(void) { } EvtData_PlaySound(const std::string& soundResource) : m_soundResource(soundResource) { } virtual const EventType& VGetEventType(void) const { return sk_EventType; } virtual IEventDataPtr VCopy() const { return IEventDataPtr(GCC_NEW EvtData_PlaySound(m_soundResource)); } virtual void VSerialize(std::ostrstream& out) const { out << m_soundResource; } virtual void VDeserialize(std::istrstream& in) { in >> m_soundResource; } const std::string& GetResource(void) const { return m_soundResource; } virtual const char* GetName(void) const { return "EvtData_PlaySound"; } virtual bool VBuildEventFromScript(void); EXPORT_FOR_SCRIPT_EVENT(EvtData_PlaySound); };