| | 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 | } |