4b825dc642cb6eb9a060e54bf8d69288fbee4904ebd360ec63ec976c05699f3180e866b3f69e5472
 
 
1
#include "system.h"
 
 
2
#include "stratdef.h"
 
 
3
#include "bh_deathvol.h"
 
 
4
#include "dynamics.h"
 
 
5
#include "weapons.h"
 
 
6
#include <assert.h>
 
 
7
#include "equipmnt.h"
 
 
8
#include <stdlib.h>
 
 
9
 
 
 
10
extern int NumActiveBlocks;
 
 
11
extern DISPLAYBLOCK* ActiveBlockList[];
 
 
12
 
 
 
13
void DeathVolumeBehaveInit(void* bhdata,STRATEGYBLOCK* sbptr)
 
 
14
{
 
 
15
    assert(sbptr);
 
 
16
    assert(bhdata);
 
 
17
 
 
 
18
    DEATH_VOLUME_BEHAV_BLOCK* dv_bhv = malloc(sizeof(DEATH_VOLUME_BEHAV_BLOCK));
 
 
19
 
 
 
20
    if(dv_bhv)
 
 
21
    {
 
 
22
        sbptr->dataptr = dv_bhv;
 
 
23
        dv_bhv->bhvr_type = I_BehaviourDeathVolume;
 
 
24
        DEATH_VOLUME_TOOLS_TEMPLATE* dv_tt = (DEATH_VOLUME_TOOLS_TEMPLATE*)bhdata;
 
 
25
        //copy stuff from tools template
 
 
26
        COPY_NAME(sbptr->SBname, dv_tt->nameID);
 
 
27
        dv_bhv->volume_min = dv_tt->volume_min;
 
 
28
        dv_bhv->volume_max = dv_tt->volume_max;
 
 
29
        dv_bhv->damage_per_second = dv_tt->damage_per_second;
 
 
30
        dv_bhv->active = dv_tt->active;
 
 
31
        dv_bhv->collision_required = dv_tt->collision_required;
 
 
32
    }
 
 
33
    else
 
 
34
    {
 
 
35
        RemoveBehaviourStrategy(sbptr);
 
 
36
    }
 
 
37
}
 
 
38
 
 
 
39
void DeathVolumeBehaveFun(STRATEGYBLOCK* vol_sbptr)
 
 
40
{
 
 
41
     assert(vol_sbptr);
 
 
42
    DEATH_VOLUME_BEHAV_BLOCK* dv_bhv = (DEATH_VOLUME_BEHAV_BLOCK*)vol_sbptr->dataptr;
 
 
43
    assert((dv_bhv->bhvr_type == I_BehaviourDeathVolume));
 
 
44
 
 
 
45
    if(dv_bhv->active)
 
 
46
    {
 
 
47
        int miny,maxy;
 
 
48
        int i=0;
 
 
49
 
 
 
50
        for(; i < NumActiveBlocks; i++)
 
 
51
        {
 
 
52
            //search for objects that have has a collision this frame
 
 
53
            //(or all objects if collisions aren't required)
 
 
54
            DISPLAYBLOCK* dptr = ActiveBlockList[i];
 
 
55
            STRATEGYBLOCK* sbPtr = ActiveBlockList[i]->ObStrategyBlock;
 
 
56
 
 
 
57
            if(!sbPtr || !sbPtr->DynPtr)
 
 
58
                continue;
 
 
59
 
 
 
60
            DYNAMICSBLOCK* dynPtr = sbPtr->DynPtr;
 
 
61
 
 
 
62
            if(dv_bhv->collision_required)
 
 
63
            {
 
 
64
                if(!dynPtr->CollisionReportPtr)
 
 
65
                    continue;
 
 
66
            }
 
 
67
 
 
 
68
            //is the object within the death volume?
 
 
69
            //check a vertical line against the death volume's bounding box
 
 
70
 
 
 
71
            //first check the object's centre x and centre z values against the volume
 
 
72
            if(dptr->ObWorld.vx < dv_bhv->volume_min.vx)
 
 
73
                continue;
 
 
74
 
 
 
75
            if(dptr->ObWorld.vx > dv_bhv->volume_max.vx)
 
 
76
                continue;
 
 
77
 
 
 
78
            if(dptr->ObWorld.vz < dv_bhv->volume_min.vz)
 
 
79
                continue;
 
 
80
 
 
 
81
            if(dptr->ObWorld.vz > dv_bhv->volume_max.vz)
 
 
82
                continue;
 
 
83
 
 
 
84
            //now check  the object's vertical extents for overlap with the death volume bounding box
 
 
85
            miny = dptr->ObWorld.vy + dptr->extent.min_y;
 
 
86
            maxy = dptr->ObWorld.vy + dptr->extent.max_y;
 
 
87
 
 
 
88
            if(max(miny, dv_bhv->volume_min.vy) > min(maxy, dv_bhv->volume_max.vy))
 
 
89
                continue;
 
 
90
            /*
 
 
91
            if(dynPtr->Position.vx > dv_bhv->volume_min.vx &&
 
 
92
               dynPtr->Position.vx < dv_bhv->volume_max.vx &&
 
 
93
               dynPtr->Position.vz > dv_bhv->volume_min.vz &&
 
 
94
               dynPtr->Position.vz < dv_bhv->volume_max.vz &&
 
 
95
               dynPtr->Position.vy > dv_bhv->volume_min.vy &&
 
 
96
               dynPtr->Position.vy < dv_bhv->volume_max.vy)
 
 
97
            */
 
 
98
            {
 
 
99
                //finally see if the object is one of the types that can be harmed by the death volume
 
 
100
                switch(sbPtr->type)
 
 
101
                {
 
 
102
                    case I_BehaviourAlien:
 
 
103
                    case I_BehaviourMarine:
 
 
104
                    case I_BehaviourMarinePlayer:
 
 
105
                    case I_BehaviourPredatorPlayer:
 
 
106
                    case I_BehaviourAlienPlayer: 
 
 
107
                    case I_BehaviourPredator:
 
 
108
                    case I_BehaviourFaceHugger:
 
 
109
                    case I_BehaviourXenoborg:
 
 
110
                    case I_BehaviourQueenAlien:
 
 
111
                    {
 
 
112
                        extern int myNetworkKillerId;
 
 
113
                        extern int AVPDPNetID;
 
 
114
 
 
 
115
                        //this is a neutral source of damage (for cooperative multiplayer games)
 
 
116
                        myNetworkKillerId = 0;
 
 
117
 
 
 
118
                        if(dv_bhv->damage_per_second)
 
 
119
                        {
 
 
120
                            VECTORCH direction = {0, -ONE_FIXED, 0};
 
 
121
                            DAMAGE_PROFILE damage = {0,0,1,0,0,0,0,0,0,0,0,AMMO_NONE};
 
 
122
                            damage.Penetrative = dv_bhv->damage_per_second;
 
 
123
                            CauseDamageToObject(sbPtr, &damage, NormalFrameTime, &direction);
 
 
124
                        }
 
 
125
                        else
 
 
126
                        {
 
 
127
                            //kill the creature/player
 
 
128
                            VECTORCH direction = {0, -ONE_FIXED, 0};
 
 
129
                            CauseDamageToObject(sbPtr, &damage_profiles[CERTAINDEATH], ONE_FIXED, &direction);
 
 
130
                        }
 
 
131
 
 
 
132
                        //reset network killer id
 
 
133
                        myNetworkKillerId = AVPDPNetID;
 
 
134
                    }
 
 
135
                    default:
 
 
136
                    break;
 
 
137
                }
 
 
138
            }
 
 
139
        }
 
 
140
    }
 
 
141
}
 
 
142
 
 
 
143
/*--------------------**
 
 
144
** Loading and Saving **
 
 
145
**--------------------*/
 
 
146
#include "savegame.h"
 
 
147
 
 
 
148
typedef struct death_volume_save_block
 
 
149
{
 
 
150
    SAVE_BLOCK_STRATEGY_HEADER header;
 
 
151
 
 
 
152
    int active;
 
 
153
 
 
 
154
} DEATH_VOLUME_SAVE_BLOCK;
 
 
155
 
 
 
156
void LoadStrategy_DeathVolume(SAVE_BLOCK_STRATEGY_HEADER* header)
 
 
157
{
 
 
158
    DEATH_VOLUME_SAVE_BLOCK* block = (DEATH_VOLUME_SAVE_BLOCK*) header; 
 
 
159
 
 
 
160
    //check the size of the save block
 
 
161
    if(header->size != sizeof(*block))
 
 
162
        return;
 
 
163
 
 
 
164
    //find the existing strategy block
 
 
165
    STRATEGYBLOCK* sbPtr = FindSBWithName(header->SBname);
 
 
166
 
 
 
167
    if(!sbPtr)
 
 
168
        return;
 
 
169
 
 
 
170
    //make sure the strategy found is of the right type
 
 
171
    if(sbPtr->type != I_BehaviourDeathVolume)
 
 
172
        return;
 
 
173
 
 
 
174
    DEATH_VOLUME_BEHAV_BLOCK* dv_bhv = (DEATH_VOLUME_BEHAV_BLOCK*)sbPtr->dataptr;
 
 
175
 
 
 
176
    //start copying stuff
 
 
177
     dv_bhv->active = block->active;
 
 
178
}
 
 
179
 
 
 
180
void SaveStrategy_DeathVolume(STRATEGYBLOCK* sbPtr)
 
 
181
{
 
 
182
    DEATH_VOLUME_SAVE_BLOCK *block;
 
 
183
    DEATH_VOLUME_BEHAV_BLOCK* dv_bhv = (DEATH_VOLUME_BEHAV_BLOCK*)sbPtr->dataptr;
 
 
184
 
 
 
185
    GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
 
 
186
 
 
 
187
    //start copying stuff
 
 
188
     block->active = dv_bhv->active;
 
 
189
}