| | 1 | #include "system.h" |
| | 2 | #include "stratdef.h" |
| | 3 | #include "track.h" |
| | 4 | #include "fan.h" |
| | 5 | #include "dynamics.h" |
| | 6 | #include "weapons.h" |
| | 7 | #include "pvisible.h" |
| | 8 | #include <stdlib.h> |
| | 9 | #include <assert.h> |
| | 10 | |
| | 11 | static DAMAGE_PROFILE fan_damage = {0,100,0,0,0,0,2,1,1,0,0,AMMO_FAN}; |
| | 12 | |
| | 13 | void FanBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr) |
| | 14 | { |
| | 15 | assert(sbptr); |
| | 16 | assert(bhdata); |
| | 17 | |
| | 18 | FAN_BEHAV_BLOCK* f_bhv = malloc(sizeof(FAN_BEHAV_BLOCK)); |
| | 19 | sbptr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC); |
| | 20 | sbptr->dataptr = f_bhv; |
| | 21 | sbptr->containingModule = ModuleFromPosition(&sbptr->DynPtr->Position, NULL); |
| | 22 | |
| | 23 | if(!f_bhv || !sbptr->DynPtr)// || (NULL == sbptr->containingModule)) |
| | 24 | { |
| | 25 | RemoveBehaviourStrategy(sbptr); |
| | 26 | return; |
| | 27 | } |
| | 28 | |
| | 29 | sbptr->maintainVisibility = 1; |
| | 30 | |
| | 31 | f_bhv->bhvr_type = I_BehaviourFan; |
| | 32 | |
| | 33 | FAN_TOOLS_TEMPLATE* f_tt = (FAN_TOOLS_TEMPLATE*)bhdata; |
| | 34 | |
| | 35 | //sbptr->shapeIndex = f_tt->shape_num; |
| | 36 | COPY_NAME(sbptr->SBname, f_tt->nameID); |
| | 37 | |
| | 38 | sbptr->DynPtr->Position = sbptr->DynPtr->PrevPosition = f_tt->position; |
| | 39 | sbptr->DynPtr->OrientEuler = f_tt->orientation; |
| | 40 | CreateEulerMatrix(&sbptr->DynPtr->OrientEuler, &sbptr->DynPtr->OrientMat); |
| | 41 | TransposeMatrixCH(&sbptr->DynPtr->OrientMat); |
| | 42 | |
| | 43 | f_bhv->track = f_tt->track; |
| | 44 | assert(f_bhv->track); |
| | 45 | f_bhv->track->sbptr = sbptr; |
| | 46 | f_bhv->track->use_speed_mult = 1; |
| | 47 | |
| | 48 | f_bhv->speed_up_mult = f_tt->speed_up_mult; |
| | 49 | f_bhv->slow_down_mult = f_tt->slow_down_mult; |
| | 50 | f_bhv->fan_wind_direction = f_tt->fan_wind_direction; |
| | 51 | f_bhv->fan_wind_strength = f_tt->fan_wind_strength; |
| | 52 | |
| | 53 | if(f_bhv->track->playing) |
| | 54 | { |
| | 55 | f_bhv->speed_mult = ONE_FIXED; |
| | 56 | f_bhv->track->speed_mult = ONE_FIXED; |
| | 57 | f_bhv->spinning = 1; |
| | 58 | } |
| | 59 | else |
| | 60 | { |
| | 61 | f_bhv->speed_mult = 0; |
| | 62 | f_bhv->spinning = 0; |
| | 63 | } |
| | 64 | |
| | 65 | f_bhv->wind_speed = MUL_FIXED(f_bhv->speed_mult, f_bhv->fan_wind_strength); |
| | 66 | } |
| | 67 | |
| | 68 | void FanBehaveFun(STRATEGYBLOCK* sbptr) |
| | 69 | { |
| | 70 | assert(sbptr); |
| | 71 | FAN_BEHAV_BLOCK *f_bhv = (FAN_BEHAV_BLOCK*)sbptr->dataptr; |
| | 72 | assert((f_bhv->bhvr_type == I_BehaviourFan)); |
| | 73 | assert(f_bhv->track); |
| | 74 | |
| | 75 | if(!sbptr->DisplayBlock) |
| | 76 | return; |
| | 77 | |
| | 78 | //printf("I am a fan\n"); |
| | 79 | |
| | 80 | if(f_bhv->spinning) |
| | 81 | { |
| | 82 | if(!f_bhv->speed_mult) |
| | 83 | { |
| | 84 | //fan just starting |
| | 85 | Start_Track_Playing(f_bhv->track); |
| | 86 | } |
| | 87 | |
| | 88 | if(f_bhv->speed_mult < ONE_FIXED) |
| | 89 | { |
| | 90 | //fan currently accelerating |
| | 91 | f_bhv->speed_mult += MUL_FIXED(NormalFrameTime,f_bhv->speed_up_mult); |
| | 92 | |
| | 93 | if(f_bhv->speed_mult >= ONE_FIXED) |
| | 94 | f_bhv->speed_mult = ONE_FIXED; |
| | 95 | |
| | 96 | f_bhv->track->speed_mult = f_bhv->speed_mult; |
| | 97 | //update wind speed |
| | 98 | f_bhv->wind_speed = MUL_FIXED(f_bhv->speed_mult,f_bhv->fan_wind_strength); |
| | 99 | } |
| | 100 | } |
| | 101 | else |
| | 102 | { |
| | 103 | if(f_bhv->speed_mult > 0) |
| | 104 | { |
| | 105 | //fan currently slowing down |
| | 106 | f_bhv->speed_mult -= MUL_FIXED(NormalFrameTime,f_bhv->slow_down_mult); |
| | 107 | |
| | 108 | if(f_bhv->speed_mult < 0) |
| | 109 | { |
| | 110 | //fan has come to a stop |
| | 111 | f_bhv->speed_mult = 0; |
| | 112 | Stop_Track_Playing(f_bhv->track); |
| | 113 | } |
| | 114 | |
| | 115 | f_bhv->track->speed_mult = f_bhv->speed_mult; |
| | 116 | //update wind speed |
| | 117 | f_bhv->wind_speed = MUL_FIXED(f_bhv->speed_mult,f_bhv->fan_wind_strength); |
| | 118 | } |
| | 119 | } |
| | 120 | |
| | 121 | if(f_bhv->speed_mult) |
| | 122 | Update_Track_Position(f_bhv->track); |
| | 123 | |
| | 124 | //see if fan has hit anything |
| | 125 | if(sbptr->DynPtr->CollisionReportPtr) |
| | 126 | { |
| | 127 | //don't cause damage unless fan is going reasonably fast |
| | 128 | if(f_bhv->speed_mult > ONE_FIXED/4) |
| | 129 | { |
| | 130 | COLLISIONREPORT* reportptr = sbptr->DynPtr->CollisionReportPtr; |
| | 131 | |
| | 132 | fan_damage.Cutting = MUL_FIXED(f_bhv->speed_mult, 200); |
| | 133 | //go through all the collision reports and damage any creatures found |
| | 134 | |
| | 135 | while(reportptr) |
| | 136 | { |
| | 137 | if(reportptr->ObstacleSBPtr) |
| | 138 | { |
| | 139 | STRATEGYBLOCK* hit_sbptr = reportptr->ObstacleSBPtr; |
| | 140 | |
| | 141 | switch(hit_sbptr->type) |
| | 142 | { |
| | 143 | case I_BehaviourAlien: |
| | 144 | case I_BehaviourQueenAlien: |
| | 145 | case I_BehaviourFaceHugger: |
| | 146 | case I_BehaviourPredator: |
| | 147 | case I_BehaviourXenoborg: |
| | 148 | case I_BehaviourMarine: |
| | 149 | case I_BehaviourMarinePlayer: |
| | 150 | case I_BehaviourPredatorPlayer: |
| | 151 | case I_BehaviourAlienPlayer: |
| | 152 | case I_BehaviourInanimateObject: |
| | 153 | { |
| | 154 | hit_sbptr->DamageBlock.Indestructable = 0; |
| | 155 | |
| | 156 | if(f_bhv->speed_mult == ONE_FIXED) |
| | 157 | { |
| | 158 | //ensure death if fan is going at full speed |
| | 159 | CauseDamageToObject(hit_sbptr, &fan_damage, 100*ONE_FIXED, &f_bhv->fan_wind_direction); |
| | 160 | } |
| | 161 | else |
| | 162 | { |
| | 163 | CauseDamageToObject(hit_sbptr, &fan_damage, NormalFrameTime, &f_bhv->fan_wind_direction); |
| | 164 | } |
| | 165 | } |
| | 166 | default: |
| | 167 | break; |
| | 168 | } |
| | 169 | } |
| | 170 | |
| | 171 | reportptr = reportptr->NextCollisionReportPtr; |
| | 172 | } |
| | 173 | } |
| | 174 | } |
| | 175 | } |
| | 176 | |
| | 177 | /*--------------------** |
| | 178 | ** Loading and Saving ** |
| | 179 | **--------------------*/ |
| | 180 | #include "savegame.h" |
| | 181 | typedef struct fan_save_block |
| | 182 | { |
| | 183 | SAVE_BLOCK_STRATEGY_HEADER header; |
| | 184 | |
| | 185 | int spinning:1; |
| | 186 | int speed_mult; //0 to one_fixed : current speed relative to full speed |
| | 187 | int wind_speed;//fixed point multiplier , taking the fan's current speed into account |
| | 188 | |
| | 189 | } FAN_SAVE_BLOCK; |
| | 190 | |
| | 191 | //defines for load/save macros |
| | 192 | #define SAVELOAD_BLOCK block |
| | 193 | #define SAVELOAD_BEHAV f_bhv |
| | 194 | |
| | 195 | void LoadStrategy_Fan(SAVE_BLOCK_STRATEGY_HEADER* header) |
| | 196 | { |
| | 197 | FAN_SAVE_BLOCK* block = (FAN_SAVE_BLOCK*) header; |
| | 198 | |
| | 199 | //check the size of the save block |
| | 200 | if(header->size != sizeof(*block)) |
| | 201 | return; |
| | 202 | |
| | 203 | //find the existing strategy block |
| | 204 | STRATEGYBLOCK* sbPtr = FindSBWithName(header->SBname); |
| | 205 | |
| | 206 | if(!sbPtr) |
| | 207 | return; |
| | 208 | |
| | 209 | //make sure the strategy found is of the right type |
| | 210 | if(sbPtr->type != I_BehaviourFan) |
| | 211 | return; |
| | 212 | |
| | 213 | FAN_BEHAV_BLOCK *f_bhv = (FAN_BEHAV_BLOCK*)sbPtr->dataptr; |
| | 214 | |
| | 215 | //start copying stuff |
| | 216 | |
| | 217 | COPYELEMENT_LOAD(spinning) |
| | 218 | COPYELEMENT_LOAD(speed_mult) |
| | 219 | COPYELEMENT_LOAD(wind_speed) |
| | 220 | |
| | 221 | //load the track position |
| | 222 | if(f_bhv->track) |
| | 223 | { |
| | 224 | SAVE_BLOCK_HEADER* track_header = GetNextBlockIfOfType(SaveBlock_Track); |
| | 225 | |
| | 226 | if(track_header) |
| | 227 | LoadTrackPosition(track_header,f_bhv->track); |
| | 228 | } |
| | 229 | } |
| | 230 | |
| | 231 | void SaveStrategy_Fan(STRATEGYBLOCK* sbPtr) |
| | 232 | { |
| | 233 | FAN_SAVE_BLOCK* block; |
| | 234 | FAN_BEHAV_BLOCK *f_bhv = (FAN_BEHAV_BLOCK*)sbPtr->dataptr; |
| | 235 | |
| | 236 | GET_STRATEGY_SAVE_BLOCK(block,sbPtr); |
| | 237 | |
| | 238 | //start copying stuff |
| | 239 | |
| | 240 | COPYELEMENT_SAVE(spinning) |
| | 241 | COPYELEMENT_SAVE(speed_mult) |
| | 242 | COPYELEMENT_SAVE(wind_speed) |
| | 243 | |
| | 244 | //save the track position |
| | 245 | if(f_bhv->track) |
| | 246 | SaveTrackPosition(f_bhv->track); |
| | 247 | } |