convert line ends
[canaan.git] / prj / cam / src / shock / shkpatch.cpp
blobced56781ab78813209c16e2a8f319836798eec4a
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/shock/shkpatch.cpp,v 1.10 2000/02/19 13:25:51 toml Exp $
7 // code for doing patch like things to the levels
9 #include <string.h>
11 #include <mprintf.h>
12 #include <config.h>
14 #include <iobjsys.h>
15 #include <traitman.h>
16 #include <netprops.h>
17 #include <shkprop.h>
18 #include <scrptpr_.h>
19 #include <frobprop.h>
20 #include <phmtprop.h>
21 #include <aiprcore.h>
22 #include <lockprop.h>
23 #include <shkspawn.h>
24 #include <objpos.h>
26 #include <shkpatch.h>
27 #include <memall.h>
28 #include <dbmem.h> // must be last header!
30 // Objnum conversion. Deals with objnum remapping, as well as making sure
31 // that this really is the right object. May return OBJ_NULL if we can't
32 // safely resolve the objnum.
33 static ObjID RealObj(ObjID old_obj, const char *arch_name)
35 AutoAppIPtr(ObjectSystem);
36 AutoAppIPtr(TraitManager);
37 ObjID obj = pObjectSystem->RemapOnLoad(old_obj);
38 ObjID archetype = pObjectSystem->GetObjectNamed(arch_name);
39 if (pTraitManager->GetArchetype(obj) != archetype)
41 return OBJ_NULL;
42 } else {
43 return obj;
47 // Make an object local-only
48 static void MakeLocal(ObjID old_obj, const char *archetype)
50 AutoAppIPtr(ObjectSystem);
51 ObjID obj = RealObj(old_obj, archetype);
52 if (obj != OBJ_NULL)
53 SetNetworkCategory(obj, kLocalOnly);
56 // Mark an object as moving terrain
57 static void MakeMovingTerrain(ObjID startObj, const char *pArchetype)
59 ObjID obj = RealObj(startObj, pArchetype);
60 if (obj != OBJ_NULL)
62 cMovingTerrainProp pMTProp;
63 pMTProp.active = FALSE;
64 pMTProp.prev_state = FALSE;
65 g_pMovingTerrainProperty->Set(obj, &pMTProp);
69 // Macro to test whether an update is needed. Intended to be used inside
70 // PatchLevelData().
71 #define NEED_UPDATE(target, patchlevel) \
72 ((stricmp(level, target) == 0) &&\
73 (old_ver < patchlevel) &&\
74 (new_ver >= patchlevel))
76 void PatchLevelData(char *level, int old_ver, int new_ver)
78 #ifndef SHIP
79 if (config_is_defined("loud_level_patch"))
80 mprintf("Want to patch %s from %d to %d\n",level,old_ver,new_ver);
81 #endif
83 AutoAppIPtr(ObjectSystem);
85 if (NEED_UPDATE("ops3.mis", 1))
87 // Make the glue elements of the massacre cutscene local-only
88 MakeLocal(136, "Sound Trap");
89 MakeLocal(1066, "Simple Button");
90 MakeLocal(1067, "Sound Trap");
91 MakeLocal(1068, "Trigger Delay");
92 MakeLocal(1069, "Sound Trap");
93 MakeLocal(1070, "Trigger Delay");
94 MakeLocal(1071, "Sound Trap");
95 MakeLocal(1072, "Simple Button");
96 MakeLocal(1073, "Sound Trap");
97 MakeLocal(1323, "Trigger Delay");
100 if (NEED_UPDATE("eng2.mis", 1))
102 // This exp cookie was somehow strangely set up
103 ObjID obj = RealObj(934, "Small BP Pile");
104 if (obj != OBJ_NULL)
105 gPropAutoPickup->Set(obj, FALSE);
107 // The Many ride needs to use the ChangeInterfaceMany script,
108 // instead of ChangeInterface
109 obj = RealObj(1563, "Marker");
110 if (obj != OBJ_NULL)
112 AutoAppIPtr(PropertyManager);
113 sScriptProp *pScripts;
114 IScriptProperty *pScriptProperty =
115 (IScriptProperty*)(pPropertyManager->GetPropertyNamed("Scripts"));
116 if (pScriptProperty->Get(obj, &pScripts))
118 strcpy(pScripts->script[0], "ChangeInterfaceMany");
119 pScriptProperty->Set(obj, pScripts);
124 if (NEED_UPDATE("ops4.mis", 1))
126 // Needs a multiplayer respawn marker; we just rename one of the
127 // start markers
128 ObjID obj = RealObj(343, "Marker");
129 if (obj != OBJ_NULL)
130 pObjectSystem->NameObject(obj, "Multiplayer Respawn");
132 // These are cardslots for a pair of locked security doors. In
133 // retrospect, the key for these is much too separated from the
134 // doors themselves, and they're plot-blocking. So unlock them.
135 obj = RealObj(620, "Card slot");
136 if (obj != OBJ_NULL)
137 ObjSetSelfLocked(obj, FALSE);
138 obj = RealObj(619, "Card slot");
139 if (obj != OBJ_NULL)
140 ObjSetSelfLocked(obj, FALSE);
143 if (NEED_UPDATE("rec1.mis", 1))
145 // This is a Transmitter Tower -- actually a fancy keypad -- and
146 // should be frobLocally
147 ObjID obj = RealObj(89, "Transmitter Tower Off");
148 if (obj != OBJ_NULL)
149 SetFrobHandler(obj, kFrobHandlerLocal);
152 if (NEED_UPDATE("rick3.mis", 1))
154 // This is the "escape tunnel". When the shuttle launches to go to
155 // the Many, we *actually* move the tunnel. But it wasn't set up
156 // properly -- the thing needs the moving terrain property on it...
157 ObjID obj = RealObj(120, "EscapeTunnel");
158 if (obj != OBJ_NULL)
160 cMovingTerrainProp pMTProp;
161 pMTProp.active = FALSE;
162 pMTProp.prev_state = FALSE;
163 g_pMovingTerrainProperty->Set(obj, &pMTProp);
167 if (NEED_UPDATE("command2.mis", 1))
169 // This is the escape pod that leaves just as we try to get to it.
170 // Again, it needs the moving terrain property set...
171 ObjID obj = RealObj(301, "Escape Pod");
172 if (obj != OBJ_NULL)
174 cMovingTerrainProp pMTProp;
175 pMTProp.active = FALSE;
176 pMTProp.prev_state = FALSE;
177 g_pMovingTerrainProperty->Set(obj, &pMTProp);
181 if (NEED_UPDATE("medsci1.mis", 1))
183 // The very first OG is controlled by a pseudoscript; handoff
184 // interferes with that. The result is that, if the client sets
185 // him off, the OG begins to run at him, then turns around and
186 // forgets about him. Better to not hand off, and have poor aim,
187 // than this dumbness.
188 ObjID obj = RealObj(1383, "OG-Pipe");
189 if (obj != OBJ_NULL)
191 g_pAINoHandoffProperty->Set(obj, TRUE);
195 if (NEED_UPDATE("many.mis", 1))
197 // One of these spawn traps is way the heck too hard, and people
198 // have been complaining about it. So switch it from generating
199 // mostly midwives and a few rumblers, to just rumblers.
200 ObjID obj = RealObj(1489, "RandMonsterGen");
201 if (obj != OBJ_NULL)
203 sSpawnInfo *pSpawnInfo;
204 if (gPropSpawn->Get(obj, &pSpawnInfo))
206 pSpawnInfo->m_odds[0] = 0; // Chance of midwife
207 pSpawnInfo->m_odds[1] = 100; // Chance of rumbler
208 gPropSpawn->Set(obj, pSpawnInfo);
213 if (NEED_UPDATE("rec2.mis", 1))
215 // One of the LandingPoint markers, for player 3, is slightly
216 // embedded in the wall. As a result, he can't move when he
217 // teleports in. Shove it a foot in:
218 ObjID obj = RealObj(268, "Marker");
219 if (obj != OBJ_NULL)
221 ObjPos *pos = ObjPosGet(obj);
222 if (pos)
224 // X is about 41.6; should be about 40.6:
225 pos->loc.vec.x -= 1;
226 ObjTranslate(obj, &(pos->loc.vec));