4b825dc642cb6eb9a060e54bf8d69288fbee4904ebd360ec63ec976c05699f3180e866b3f69e5472
 
 
1
/*------------------------Patrick 14/1/97-----------------------------
 
 
2
  This source file contains all the functions for the object visibility 
 
 
3
  management system     (which controls visibility for aliens, objects,
 
 
4
  pickups, autoguns, etc....)
 
 
5
  It also contains initialisation and behaviour functions for 
 
 
6
  inanimate objects (like chairs, weapons, etc...).
 
 
7
  --------------------------------------------------------------------*/
 
 
8
#include <string.h>
 
 
9
#include <stdlib.h>
 
 
10
#include <stdio.h>
 
 
11
#include <assert.h>
 
 
12
#include "system.h"
 
 
13
#include "stratdef.h"
 
 
14
#include "bh_types.h"
 
 
15
#include "npc_alien.h"
 
 
16
#include "npc_xenoborg.h"
 
 
17
#include "npc_queen.h"
 
 
18
#include "npc_marine.h"
 
 
19
#include "npc_facehugger.h"
 
 
20
#include "debris.h"
 
 
21
#include "placedhierarchy.h"
 
 
22
#include "lighting.h"
 
 
23
#include "npc_dummy.h"
 
 
24
#include "platformlift.h"
 
 
25
#include "bh_light.h"
 
 
26
#include "weapons.h"
 
 
27
#include "npc_sentrygun.h"
 
 
28
#include "corpse.h"
 
 
29
#include "pfarlocs.h"
 
 
30
#include "pldghost.h"
 
 
31
#include "generator.h"
 
 
32
 
 
 
33
size_t ModuleArraySize = 0;
 
 
34
 
 
 
35
extern int GlobalFrameCounter;
 
 
36
extern SCENEMODULE MainScene;
 
 
37
 
 
 
38
extern SECTION * GetNamedHierarchyFromLibrary(const char * rif_name, const char * hier_name);
 
 
39
 
 
 
40
/* this is a default map used in visibility management 
 
 
41
NB If you use this, you MUST set the shapeIndex field appropriately*/
 
 
42
 
 
 
43
#define ModuleFromPositionTolerance 50
 
 
44
 
 
 
45
static int WorldPointIsInModule_WithTolerance(MODULE* thisModule, VECTORCH* thisPoint)
 
 
46
{               
 
 
47
    VECTORCH localpoint = *thisPoint;
 
 
48
    localpoint.vx -= thisModule->m_world.vx;
 
 
49
    localpoint.vy -= thisModule->m_world.vy;
 
 
50
    localpoint.vz -= thisModule->m_world.vz;
 
 
51
 
 
 
52
    return
 
 
53
    (
 
 
54
        (localpoint.vx <= thisModule->m_maxx + ModuleFromPositionTolerance)
 
 
55
        &&
 
 
56
        (localpoint.vx >= thisModule->m_minx - ModuleFromPositionTolerance)
 
 
57
        &&
 
 
58
        (localpoint.vy <= thisModule->m_maxy + ModuleFromPositionTolerance)
 
 
59
        &&
 
 
60
        (localpoint.vy >= thisModule->m_miny - ModuleFromPositionTolerance)
 
 
61
        &&
 
 
62
        (localpoint.vz <= thisModule->m_maxz + ModuleFromPositionTolerance)
 
 
63
        &&
 
 
64
        (localpoint.vz >= thisModule->m_minz - ModuleFromPositionTolerance)
 
 
65
    );
 
 
66
}
 
 
67
 
 
 
68
static int WorldPointIsInModule(MODULE* thisModule, VECTORCH* thisPoint)
 
 
69
{               
 
 
70
    VECTORCH localpoint = *thisPoint;
 
 
71
    localpoint.vx -= thisModule->m_world.vx;
 
 
72
    localpoint.vy -= thisModule->m_world.vy;
 
 
73
    localpoint.vz -= thisModule->m_world.vz;
 
 
74
 
 
 
75
    return
 
 
76
    (
 
 
77
        (localpoint.vx <= thisModule->m_maxx)
 
 
78
        &&
 
 
79
        (localpoint.vx >= thisModule->m_minx)
 
 
80
        &&
 
 
81
        (localpoint.vy <= thisModule->m_maxy)
 
 
82
        &&
 
 
83
        (localpoint.vy >= thisModule->m_miny)
 
 
84
        &&
 
 
85
        (localpoint.vz <= thisModule->m_maxz)
 
 
86
        &&
 
 
87
        (localpoint.vz >= thisModule->m_minz)
 
 
88
    );
 
 
89
}
 
 
90
 
 
 
91
/*------------------------Patrick 14/1/97-----------------------------
 
 
92
  This function returns the module in which a given world-space 
 
 
93
  position is located.  A starting point for the search may also be
 
 
94
  passed, so that the following search pattern is used:
 
 
95
  1. is the location in the indicated starting module.
 
 
96
  2. is the location in any of the starting module's visible-links.
 
 
97
  3. finally, all modules in the environment are searched until
 
 
98
     a containing module is found.
 
 
99
 
 
 
100
  If no module is found, a null module pointer is returned.
 
 
101
  NB only 'physical' modules are returned, ie infinite and
 
 
102
  terminator modules are ignored.
 
 
103
 
 
 
104
  The function is designed to be used for objects which move over small
 
 
105
  distances, and for which a recently containing module is known (eg 
 
 
106
  avp aliens).... so that the first stage of the search will be successful
 
 
107
  in the majority of cases, and the third stage rarely used.  
 
 
108
  Note that the fn returns the first module which contains the given 
 
 
109
  point, so problems may arise if the point exists in more than one 
 
 
110
  module. This should be ok for environments like avp, where v-linking 
 
 
111
  is not used.
 
 
112
  --------------------------------------------------------------------*/
 
 
113
 
 
 
114
static MODULE* ModuleFromPosition_WithTolerance(VECTORCH *position, MODULE* startingModule)
 
 
115
{
 
 
116
    if(startingModule && ModuleIsPhysical(startingModule))
 
 
117
    {
 
 
118
        /* first test for the most trivial, and most likely case */
 
 
119
        if(WorldPointIsInModule_WithTolerance(startingModule, position)) 
 
 
120
            return startingModule;
 
 
121
 
 
 
122
        /* now test visible-linked modules (If there are any) */
 
 
123
        {
 
 
124
            VMODULE *vlPtr = startingModule->m_vmptr;
 
 
125
 
 
 
126
            if(vlPtr)
 
 
127
            {
 
 
128
                while(!vlPtr->end_module)
 
 
129
                {
 
 
130
                    MODULE *mPtr = vlPtr->vmod_mref.mref_ptr;
 
 
131
 
 
 
132
                    if(mPtr && ModuleIsPhysical(mPtr) && WorldPointIsInModule_WithTolerance(mPtr, position)) 
 
 
133
                    {
 
 
134
                        return mPtr;
 
 
135
                    }
 
 
136
 
 
 
137
                    vlPtr++;
 
 
138
                }
 
 
139
            }
 
 
140
        }
 
 
141
    }
 
 
142
 
 
 
143
    /* either there is no starting module; the starting module is not physical;
 
 
144
    we are not in the starting module and it has no visibility-linked modules;
 
 
145
    or we haven't found a module yet: so search the entire module list */
 
 
146
    {
 
 
147
        int moduleCounter = ModuleArraySize;
 
 
148
        MODULE **moduleListPointer = MainScene.sm_marray;
 
 
149
 
 
 
150
        while(moduleCounter-- > 0)
 
 
151
        {
 
 
152
            MODULE *thisModule = *moduleListPointer++;
 
 
153
 
 
 
154
            if(ModuleIsPhysical(thisModule) && WorldPointIsInModule_WithTolerance(thisModule, position)) 
 
 
155
                return thisModule;
 
 
156
        }
 
 
157
    }
 
 
158
 
 
 
159
/* couldn't find a module */
 
 
160
return NULL;
 
 
161
}
 
 
162
 
 
 
163
MODULE* ModuleFromPosition(VECTORCH *position, MODULE* startingModule)
 
 
164
{
 
 
165
    if((NULL != startingModule) && ModuleIsPhysical(startingModule))
 
 
166
    {
 
 
167
        /* first test for the most trivial, and most likely case */
 
 
168
        if(WorldPointIsInModule(startingModule, position)) 
 
 
169
            return startingModule;
 
 
170
 
 
 
171
        /* now test visible-linked modules (If there are any) */
 
 
172
        {
 
 
173
            VMODULE *vlPtr = startingModule->m_vmptr;
 
 
174
 
 
 
175
            if(NULL != vlPtr)
 
 
176
            {
 
 
177
                while(!vlPtr->end_module)
 
 
178
                {
 
 
179
                    MODULE *mPtr = vlPtr->vmod_mref.mref_ptr;
 
 
180
 
 
 
181
                    if((NULL != mPtr) && ModuleIsPhysical(mPtr) && WorldPointIsInModule(mPtr, position))
 
 
182
                            return mPtr;
 
 
183
 
 
 
184
                    vlPtr++;
 
 
185
                }
 
 
186
            }
 
 
187
        }
 
 
188
    }
 
 
189
 
 
 
190
    /* either there is no starting module; the starting module is not physical;
 
 
191
    we are not in the starting module and it has no visibility-linked modules;
 
 
192
    or we haven't found a module yet: so search the entire module list */
 
 
193
    {
 
 
194
        int moduleCounter = ModuleArraySize;
 
 
195
        MODULE **moduleListPointer = MainScene.sm_marray;
 
 
196
 
 
 
197
        while(moduleCounter-- > 0)
 
 
198
        {
 
 
199
            MODULE *thisModule = *moduleListPointer++;
 
 
200
 
 
 
201
            if(ModuleIsPhysical(thisModule) && WorldPointIsInModule(thisModule, position))
 
 
202
                    return thisModule;
 
 
203
        }
 
 
204
    }
 
 
205
 
 
 
206
/* couldn't find a module */
 
 
207
/*Try with slightly larger module bounding boxes*/
 
 
208
return ModuleFromPosition_WithTolerance(position, startingModule);
 
 
209
}