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