convert line ends
[canaan.git] / prj / cam / src / script / netscrpt.cpp
blob91272923a87d53c5fe7c453083ca9ed9cfc9da51
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/script/netscrpt.cpp,v 1.23 2000/02/19 12:36:16 toml Exp $
8 #include <mprintf.h>
9 #include <appagg.h>
11 #include <playrobj.h> // for IsAPlayer()
13 #include <scrptapi.h>
14 #include <scrptsrv.h>
15 #include <scrptbas.h>
17 #include <netman.h>
18 #include <iobjnet.h>
19 #include <netmsg.h>
21 #include <netscrpt.h>
23 #include <cfgdbg.h>
24 #include <memall.h>
25 #include <dbmem.h> // must be last header!
27 //////////
29 // The network message handler
31 // This code accepts network messages and dispatches them to the appropriate
32 // scripts.
35 static cNetMsg *g_pBroadcastScriptMsg = NULL;
36 static cNetMsg *g_pProxyScriptMsg = NULL;
38 static void SendScriptMsg(ObjID obj,
39 const char *pText,
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;
46 msg.data = data;
48 // And send it along
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
55 // one message.
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
61 // in Shock.
62 static sNetMsgDesc sBroadcastScriptDesc =
64 kNMF_Broadcast,
65 "BroadScrpt",
66 "Broadcast Script Message",
67 NULL,
68 SendScriptMsg,
69 {{kNMPT_GlobalObjID, kNMPF_None, "Obj"},
70 {kNMPT_String, kNMPF_None, "Message"},
71 {kNMPT_MultiParm, kNMPF_None, "Data"},
72 {kNMPT_End}}
75 static sNetMsgDesc sProxyScriptDesc =
77 kNMF_None,
78 "ProxyScrpt",
79 "Script Message to Proxy",
80 NULL,
81 SendScriptMsg,
82 {{kNMPT_GlobalObjID, kNMPF_None, "Obj"},
83 {kNMPT_String, kNMPF_None, "Message"},
84 {kNMPT_GlobalObjIDMultiParm, kNMPF_None, "Data"},
85 {kNMPT_End}}
88 //////////
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)
98 protected:
99 INetManager *m_pNetMan;
100 IObjectNetworking *m_pObjNet;
101 // An iterator over the players, if we're iterating:
102 sPropertyObjIter playerIter;
104 public:
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);
114 #endif
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;
125 #endif
128 // Send this message to the specified object on all other machines.
129 STDMETHOD(Broadcast)(const object ref scrObj,
130 const char *pText,
131 BOOL sendFromProxy,
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:
138 return FALSE;
140 if (m_pObjNet->ObjLocalOnly(obj)) {
141 // Never broadcast about local-only objects
142 return FALSE;
144 g_pBroadcastScriptMsg->Send(OBJ_NULL, obj, pText, &data);
145 #endif
146 return TRUE;
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,
158 const char *pText,
159 const cMultiParm ref data)
161 ObjID target = ScriptObjID(obj);
163 #ifdef NEW_NETWORK_ENABLED
164 g_pProxyScriptMsg->Send(ScriptObjID(toPlayer), target, pText, &data);
165 #else
166 // If we don't have any networking, just do a short-circuit here
167 SendScriptMsg(target, pText, data);
168 #endif
169 return TRUE;
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
177 return TRUE;
178 #endif
179 if (!m_pNetMan->Networking()) {
180 return TRUE;
183 ObjID target = ScriptObjID(obj);
184 m_pObjNet->ObjTakeOver(target);
186 return TRUE;
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
194 return TRUE;
195 #endif
196 if (!m_pNetMan->Networking()) {
197 return TRUE;
200 ObjID target = ScriptObjID(obj);
201 ObjID to = ScriptObjID(toPlayer);
202 m_pObjNet->ObjGiveWithoutObjID(target, to);
204 return TRUE;
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
216 return FALSE;
217 #endif
218 return m_pNetMan->IsNetworkGame();
221 STDMETHOD_(timer_handle, SetProxyOneShotTimer)
222 (const object ref toObj,
223 const char *msg,
224 float time,
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,
233 (time*1000),
234 kSTM_OneShot);
235 pMsg->Release();
236 return result;
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))
249 return player;
250 else
251 return OBJ_NULL;
254 STDMETHOD(Suspend)()
256 m_pNetMan->SuspendMessaging();
257 return S_OK;
260 STDMETHOD(Resume)()
262 m_pNetMan->ResumeMessaging();
263 return S_OK;
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();
292 } else {
293 return m_pObjNet->ObjHostPlayer(obj);
298 IMPLEMENT_SCRIPT_SERVICE_IMPL(cNetworkingSrv, Networking);