2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
6 // $Header: r:/t2repos/thief2/src/script/netscrpt.cpp,v 1.23 2000/02/19 12:36:16 toml Exp $
11 #include <playrobj.h> // for IsAPlayer()
25 #include <dbmem.h> // must be last header!
29 // The network message handler
31 // This code accepts network messages and dispatches them to the appropriate
35 static cNetMsg
*g_pBroadcastScriptMsg
= NULL
;
36 static cNetMsg
*g_pProxyScriptMsg
= NULL
;
38 static void SendScriptMsg(ObjID obj
,
40 const cMultiParm ref data
)
42 sScrMsg
msg(obj
, pText
);
43 // Since this message was explicitly sent to us, allow it to run even
44 // if it's to a proxy object:
45 msg
.flags
|= kSMF_MsgSendToProxy
;
49 AutoAppIPtr(ScriptMan
);
50 pScriptMan
->SendMessage(&msg
);
53 // @TBD: These message differ only in that one is broadcast, and the other
54 // directed. We should enhance cNetMsg to allow both to be combined into
57 // @HACK: Note that the Send version treats its param as an objID. This
58 // should go away once we have a chance to make cMultiParm grok the
59 // difference between an int and an object. This hack is in place because
60 // we specifically use SendToProxy in a place that needs to send an object
62 static sNetMsgDesc sBroadcastScriptDesc
=
66 "Broadcast Script Message",
69 {{kNMPT_GlobalObjID
, kNMPF_None
, "Obj"},
70 {kNMPT_String
, kNMPF_None
, "Message"},
71 {kNMPT_MultiParm
, kNMPF_None
, "Data"},
75 static sNetMsgDesc sProxyScriptDesc
=
79 "Script Message to Proxy",
82 {{kNMPT_GlobalObjID
, kNMPF_None
, "Obj"},
83 {kNMPT_String
, kNMPF_None
, "Message"},
84 {kNMPT_GlobalObjIDMultiParm
, kNMPF_None
, "Data"},
90 // The Script handling side
92 // This stuff creates a simple script service, which lets a script tell
93 // all other clients of this object to also run the script.
96 DECLARE_SCRIPT_SERVICE_IMPL(cNetworkingSrv
, Networking
)
99 INetManager
*m_pNetMan
;
100 IObjectNetworking
*m_pObjNet
;
101 // An iterator over the players, if we're iterating:
102 sPropertyObjIter playerIter
;
106 STDMETHOD_(void,Init
)()
108 #ifdef NEW_NETWORK_ENABLED
109 m_pNetMan
= AppGetObj(INetManager
);
110 m_pObjNet
= AppGetObj(IObjectNetworking
);
112 g_pBroadcastScriptMsg
= new cNetMsg(&sBroadcastScriptDesc
);
113 g_pProxyScriptMsg
= new cNetMsg(&sProxyScriptDesc
);
117 STDMETHOD_(void, End
)()
119 #ifdef NEW_NETWORK_ENABLED
120 SafeRelease(m_pNetMan
);
121 SafeRelease(m_pObjNet
);
123 delete g_pBroadcastScriptMsg
;
124 delete g_pProxyScriptMsg
;
128 // Send this message to the specified object on all other machines.
129 STDMETHOD(Broadcast
)(const object ref scrObj
,
132 const cMultiParm ref data
)
134 #ifdef NEW_NETWORK_ENABLED
135 ObjID obj
= ScriptObjID(scrObj
);
136 if (!sendFromProxy
&& m_pObjNet
->ObjIsProxy(obj
)) {
137 // We don't own it, so suppress the message:
140 if (m_pObjNet
->ObjLocalOnly(obj
)) {
141 // Never broadcast about local-only objects
144 g_pBroadcastScriptMsg
->Send(OBJ_NULL
, obj
, pText
, &data
);
149 // Send the specified message to the specified object on just the
150 // specified player's machine. The object should not be local-only.
151 // It may be called from any machine; that is, it can be used to
152 // send messages from the proxy to itself.
154 // Note that this method should work, even if networking is not
155 // enabled; the message will loop back to the local player.
156 STDMETHOD(SendToProxy
)(const object ref toPlayer
,
157 const object ref obj
,
159 const cMultiParm ref data
)
161 ObjID target
= ScriptObjID(obj
);
163 #ifdef NEW_NETWORK_ENABLED
164 g_pProxyScriptMsg
->Send(ScriptObjID(toPlayer
), target
, pText
, &data
);
166 // If we don't have any networking, just do a short-circuit here
167 SendScriptMsg(target
, pText
, data
);
172 // Take over the specified object
173 STDMETHOD(TakeOver
)(const object ref obj
)
175 // Make sure we should do anything
176 #ifndef NEW_NETWORK_ENABLED
179 if (!m_pNetMan
->Networking()) {
183 ObjID target
= ScriptObjID(obj
);
184 m_pObjNet
->ObjTakeOver(target
);
189 // Hand off the specified object
190 STDMETHOD(GiveTo
)(const object ref obj
, const object ref toPlayer
)
192 // Make sure we should do anything
193 #ifndef NEW_NETWORK_ENABLED
196 if (!m_pNetMan
->Networking()) {
200 ObjID target
= ScriptObjID(obj
);
201 ObjID to
= ScriptObjID(toPlayer
);
202 m_pObjNet
->ObjGiveWithoutObjID(target
, to
);
207 STDMETHOD_(BOOL
, IsPlayer
)(const object ref obj
)
209 ObjID Obj
= ScriptObjID(obj
);
210 return IsAPlayer(Obj
);
213 STDMETHOD_(BOOL
, IsMultiplayer
)()
215 #ifndef NEW_NETWORK_ENABLED
218 return m_pNetMan
->IsNetworkGame();
221 STDMETHOD_(timer_handle
, SetProxyOneShotTimer
)
222 (const object ref toObj
,
225 const cMultiParm
& data
= NULL_PARM
)
227 ObjID to
= ScriptObjID(toObj
);
228 sScrMsg
* pMsg
= new sScrTimerMsg(to
, msg
, data
);
229 pMsg
->flags
|= kSMF_MsgSendToProxy
;
230 AutoAppIPtr(ScriptMan
);
231 timer_handle result
=
232 (timer_handle
) pScriptMan
->SetTimedMessage(pMsg
,
239 STDMETHOD_(object
, FirstPlayer
)()
241 m_pNetMan
->NetPlayerIterStart(&playerIter
);
242 return PlayerObject();
245 STDMETHOD_(object
, NextPlayer
)()
247 ObjID player
= OBJ_NULL
;
248 if (m_pNetMan
->NetPlayerIterNext(&playerIter
, &player
))
256 m_pNetMan
->SuspendMessaging();
262 m_pNetMan
->ResumeMessaging();
266 STDMETHOD_(BOOL
, HostedHere
)(const object ref obj
)
268 return m_pObjNet
->ObjHostedHere(ScriptObjID(obj
));
271 STDMETHOD_(BOOL
, IsProxy
)(const object ref obj
)
273 return m_pObjNet
->ObjIsProxy(ScriptObjID(obj
));
276 STDMETHOD_(BOOL
, LocalOnly
)(const object ref obj
)
278 return m_pObjNet
->ObjLocalOnly(ScriptObjID(obj
));
281 STDMETHOD_(BOOL
, IsNetworking
)()
283 return m_pNetMan
->Networking();
286 STDMETHOD_(object
, Owner
)(const object ref objRef
)
288 ObjID obj
= ScriptObjID(objRef
);
289 if (m_pObjNet
->ObjLocalOnly(obj
))
291 return PlayerObject();
293 return m_pObjNet
->ObjHostPlayer(obj
);
298 IMPLEMENT_SCRIPT_SERVICE_IMPL(cNetworkingSrv
, Networking
);