From 2a2d115f4d64efb4561a3e35e621d54eeae5e3ed Mon Sep 17 00:00:00 2001 From: Matei Date: Thu, 4 May 2006 07:40:31 +0000 Subject: [PATCH] # Updates to construction: Added a start construction net message and made the selected units start working on a newly placed building after you place it. This was SVN commit r3845. --- source/ps/GameSetup/GameSetup.cpp | 1 + source/ps/Interact.cpp | 15 +++++++++++++-- source/ps/Network/AllNetMessages.h | 9 +++++++++ source/ps/Network/NetMessage.cpp | 19 ++++++++++++++++++- source/scripting/EventTypes.h | 2 ++ source/simulation/Entity.cpp | 7 +++++++ source/simulation/EntityOrders.h | 1 + source/simulation/EventHandlers.cpp | 6 ++++++ source/simulation/EventHandlers.h | 7 +++++++ source/simulation/Simulation.cpp | 24 ++++++++++++++++++++++++ 10 files changed, 88 insertions(+), 3 deletions(-) diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 6be9e881b1..9869550c7d 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -531,6 +531,7 @@ static void InitScripting() g_ScriptingHost.DefineConstant( "ORDER_PATROL", CEntityOrder::ORDER_PATROL ); g_ScriptingHost.DefineConstant( "ORDER_GENERIC", CEntityOrder::ORDER_GENERIC ); g_ScriptingHost.DefineConstant( "ORDER_PRODUCE", CEntityOrder::ORDER_PRODUCE ); + g_ScriptingHost.DefineConstant( "ORDER_START_CONSTRUCTION", CEntityOrder::ORDER_START_CONSTRUCTION ); #define REG_JS_CONSTANT(_name) g_ScriptingHost.DefineConstant(#_name, _name) diff --git a/source/ps/Interact.cpp b/source/ps/Interact.cpp index 8a7bd71a7f..a4b52ef777 100644 --- a/source/ps/Interact.cpp +++ b/source/ps/Interact.cpp @@ -10,6 +10,7 @@ #include "gui/MiniMap.h" #include "timer.h" #include "Game.h" +#include "Simulation.h" #include "ps/Globals.h" #include "ps/VFSUtil.h" #include "Network/NetMessage.h" @@ -1320,8 +1321,18 @@ void CBuildingPlacer::mouseReleased() if(m_valid) { - HEntity ent = g_EntityManager.createFoundation( m_templateName, clickPos, m_angle ); - ent->SetPlayer(g_Game->GetLocalPlayer()); + //HEntity ent = g_EntityManager.createFoundation( m_templateName, clickPos, m_angle ); + //ent->SetPlayer(g_Game->GetLocalPlayer()); + + // Issue a command accross the network + CPlaceObject *msg = new CPlaceObject(); + msg->m_Entities = g_Selection.m_selected; + msg->m_Template = m_templateName; + msg->m_X = (u32) (clickPos.X * 1000); + msg->m_Y = (u32) (clickPos.Y * 1000); + msg->m_Z = (u32) (clickPos.Z * 1000); + msg->m_Angle = (u32) (m_angle * 1000); + g_Game->GetSimulation()->QueueLocalCommand(msg); } } diff --git a/source/ps/Network/AllNetMessages.h b/source/ps/Network/AllNetMessages.h index f04bf790d9..b88f0c94a4 100644 --- a/source/ps/Network/AllNetMessages.h +++ b/source/ps/Network/AllNetMessages.h @@ -61,6 +61,7 @@ enum ENetMessageType NMT_AddWaypoint, NMT_Generic, NMT_Produce, + NMT_PlaceObject, NMT_Run, NMT_NotifyRequest, NMT_FormationGoto, @@ -241,6 +242,14 @@ DERIVE_NMT_CLASS_(NetCommand, Produce) NMT_FIELD(CStrW, m_Name) END_NMT_CLASS() +DERIVE_NMT_CLASS_(NetCommand, PlaceObject) + NMT_FIELD(CStrW, m_Template) + NMT_FIELD_INT(m_X, u32, 4) + NMT_FIELD_INT(m_Y, u32, 4) + NMT_FIELD_INT(m_Z, u32, 4) + NMT_FIELD_INT(m_Angle, u32, 4) // Orientation angle +END_NMT_CLASS() + DERIVE_NMT_CLASS_(NetCommand, NotifyRequest) NMT_FIELD(HEntity, m_Target) NMT_FIELD_INT(m_Action, u32, 4) diff --git a/source/ps/Network/NetMessage.cpp b/source/ps/Network/NetMessage.cpp index f7618d71ed..3229c70366 100644 --- a/source/ps/Network/NetMessage.cpp +++ b/source/ps/Network/NetMessage.cpp @@ -83,6 +83,7 @@ void CNetMessage::ScriptingInit() def(NMT_AddWaypoint); def(NMT_Generic); def(NMT_Produce); + def(NMT_PlaceObject); def(NMT_NotifyRequest); def(NMT_FormationGoto); def(NMT_FormationGeneric); @@ -193,6 +194,19 @@ CNetCommand *CNetMessage::CommandFromJSArgs(const CEntityList &entities, JSConte return msg; \ } + #define PlaceObjectMessage(_msg) \ + case NMT_ ## _msg: \ + { \ + C##_msg *msg = new C##_msg(); \ + msg->m_Entities = entities; \ + ReadString(msg, m_Template); \ + ReadInt(msg, m_X); \ + ReadInt(msg, m_Y); \ + ReadInt(msg, m_Z); \ + ReadInt(msg, m_Angle); \ + return msg; \ + } + // argIndex, incremented by reading macros. We have already "eaten" the // first argument (message type) uint argIndex = 1; @@ -204,15 +218,18 @@ CNetCommand *CNetMessage::CommandFromJSArgs(const CEntityList &entities, JSConte PositionMessage(Patrol) PositionMessage(AddWaypoint) PositionMessage(FormationGoto) + // NMT_Generic, target, action EntityIntMessage(Generic) EntityIntMessage(NotifyRequest) EntityIntMessage(FormationGeneric) - // NMT_Produce, type, name ProduceMessage(Produce) + // NMT_PlaceObject, template, x, y, z, angle, action + PlaceObjectMessage(PlaceObject) + default: JS_ReportError(cx, "Invalid order type"); return NULL; diff --git a/source/scripting/EventTypes.h b/source/scripting/EventTypes.h index 965a7eb900..b927504200 100644 --- a/source/scripting/EventTypes.h +++ b/source/scripting/EventTypes.h @@ -14,6 +14,7 @@ enum EEventType EVENT_DEATH, EVENT_TICK, EVENT_GENERIC, + EVENT_START_CONSTRUCTION, EVENT_START_PRODUCTION, EVENT_CANCEL_PRODUCTION, EVENT_FINISH_PRODUCTION, @@ -44,6 +45,7 @@ static const wchar_t* const EventNames[EVENT_LAST] = /* EVENT_DEATH */ L"onDeath", /* EVENT_TICK */ L"onTick", /* EVENT_GENERIC */ L"onGeneric", /* For generic actions on a target unit, like attack or gather */ + /* EVENT_START_CONSTRUCTION */ L"onStartConstruction", /* We were selected when the user placed a building */ /* EVENT_START_PRODUCTION */ L"onStartProduction", /* We're about to start training/researching something (deduct resources, etc) */ /* EVENT_CANCEL_PRODUCTION */ L"onCancelProduction", /* Something in production has been cancelled */ /* EVENT_FINISH_PRODUCTION */ L"onFinishProduction", /* We've finished something in production */ diff --git a/source/simulation/Entity.cpp b/source/simulation/Entity.cpp index 707fe1b54d..f720ca7081 100644 --- a/source/simulation/Entity.cpp +++ b/source/simulation/Entity.cpp @@ -467,6 +467,13 @@ void CEntity::update( size_t timestep ) break; updateCollisionPatch(); return; + case CEntityOrder::ORDER_START_CONSTRUCTION: + { + CEventStartConstruction evt( current->m_data[0].entity ); + m_orderQueue.pop_front(); + DispatchEvent( &evt ); + } + break; case CEntityOrder::ORDER_PRODUCE: processProduce( current ); m_orderQueue.pop_front(); diff --git a/source/simulation/EntityOrders.h b/source/simulation/EntityOrders.h index 080822b95c..788e143670 100644 --- a/source/simulation/EntityOrders.h +++ b/source/simulation/EntityOrders.h @@ -95,6 +95,7 @@ public: ORDER_GENERIC, ORDER_GENERIC_NOPATHING, ORDER_PRODUCE, + ORDER_START_CONSTRUCTION, ORDER_NOTIFY_REQUEST, ORDER_LAST } m_type; diff --git a/source/simulation/EventHandlers.cpp b/source/simulation/EventHandlers.cpp index 4116cd1cd5..702679396b 100644 --- a/source/simulation/EventHandlers.cpp +++ b/source/simulation/EventHandlers.cpp @@ -10,6 +10,12 @@ CEventGeneric::CEventGeneric( CEntity* target, int action ) : CScriptEvent( L"ge AddLocalProperty( L"action", &m_action ); } +CEventStartConstruction::CEventStartConstruction( CEntity* target ) : CScriptEvent( L"startConstruction", EVENT_START_CONSTRUCTION, true) +{ + m_target = target; + AddLocalProperty( L"target", &m_target ); +} + CEventStartProduction::CEventStartProduction( int productionType, const CStrW& name ) : CScriptEvent( L"startProduction", EVENT_START_PRODUCTION, true) { diff --git a/source/simulation/EventHandlers.h b/source/simulation/EventHandlers.h index 5bcd2be8f7..9a8450a076 100644 --- a/source/simulation/EventHandlers.h +++ b/source/simulation/EventHandlers.h @@ -35,6 +35,13 @@ public: CEventGeneric( CEntity* target, int action ); }; +class CEventStartConstruction : public CScriptEvent +{ + CEntity* m_target; +public: + CEventStartConstruction( CEntity* target ); +}; + class CEventStartProduction : public CScriptEvent { int m_productionType; diff --git a/source/simulation/Simulation.cpp b/source/simulation/Simulation.cpp index f9d1eae0f3..68e2838cef 100644 --- a/source/simulation/Simulation.cpp +++ b/source/simulation/Simulation.cpp @@ -331,6 +331,30 @@ uint CSimulation::TranslateMessage(CNetMessage* pMsg, uint clientMask, void* UNU case NMT_NotifyRequest: ENTITY_ENTITY_INT(CNotifyRequest, ORDER_NOTIFY_REQUEST); break; + case NMT_PlaceObject: + { + CPlaceObject *msg = (CPlaceObject *) pMsg; + + // Create the object + CVector3D pos(msg->m_X/1000.0f, msg->m_Y/1000.0f, msg->m_Z/1000.0f); + HEntity newObj = g_EntityManager.createFoundation( msg->m_Template, pos, msg->m_Angle/1000.0f ); + + if(msg->m_Entities.size() > 0) + { + newObj->SetPlayer(msg->m_Entities[0]->GetPlayer()); + } + else + { + // Object might have been placed from the console just for testing + newObj->SetPlayer(g_Game->GetLocalPlayer()); + } + + // Order all the selected units to work on the new object using the given action + order.m_type = CEntityOrder::ORDER_START_CONSTRUCTION; + order.m_data[0].entity = newObj; + QueueOrder(order, msg->m_Entities, false); + } while(0) + break; }