| | 1 | #include "system.h" |
| | 2 | #include "prototyp.h" |
| | 3 | #include <assert.h> |
| | 4 | #include "stratdef.h" |
| | 5 | #include "bh_types.h" |
| | 6 | #include "pheromon.h" |
| | 7 | #include "sequnces.h" |
| | 8 | #include "npc_dummy.h" |
| | 9 | #include "extents.h" |
| | 10 | #include "pldghost.h" |
| | 11 | #include <stdlib.h> |
| | 12 | |
| | 13 | extern SECTION * GetNamedHierarchyFromLibrary(const char * rif_name, const char * hier_name); |
| | 14 | |
| | 15 | void MakeDummyNear(STRATEGYBLOCK *sbPtr) |
| | 16 | { |
| | 17 | DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr; |
| | 18 | DUMMY_STATUS_BLOCK *dummyStatusPointer = (DUMMY_STATUS_BLOCK *)(sbPtr->dataptr); |
| | 19 | |
| | 20 | DISPLAYBLOCK *dPtr = CreateActiveObject(); |
| | 21 | |
| | 22 | if(dPtr == NULL) |
| | 23 | return; /* cannot allocate displayblock, so leave far */ |
| | 24 | |
| | 25 | sbPtr->DisplayBlock = dPtr; |
| | 26 | dPtr->ObStrategyBlock = sbPtr; |
| | 27 | |
| | 28 | /* need to initialise positional information in the new display block */ |
| | 29 | dPtr->ObWorld = dynPtr->Position; |
| | 30 | dPtr->ObEuler = dynPtr->OrientEuler; |
| | 31 | dPtr->ObMat = dynPtr->OrientMat; |
| | 32 | |
| | 33 | dPtr->HModelControlBlock = &dummyStatusPointer->HModelController; |
| | 34 | |
| | 35 | ProveHModel(dPtr->HModelControlBlock, dPtr); |
| | 36 | } |
| | 37 | |
| | 38 | void CreateDummy(VECTORCH *Position, int type) |
| | 39 | { |
| | 40 | STRATEGYBLOCK* sbPtr = CreateActiveStrategyBlock(I_BehaviourDummy); |
| | 41 | |
| | 42 | if(!sbPtr) |
| | 43 | { |
| | 44 | GADGET_NewOnScreenMessage("FAILED TO CREATE DUMMY: SB CREATION FAILURE"); |
| | 45 | return; |
| | 46 | } |
| | 47 | |
| | 48 | AssignNewSBName(sbPtr); |
| | 49 | |
| | 50 | /* create, initialise and attach a dynamics block */ |
| | 51 | sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_DEFAULT); |
| | 52 | sbPtr->dataptr = malloc(sizeof(DUMMY_STATUS_BLOCK)); |
| | 53 | |
| | 54 | if(sbPtr->DynPtr && sbPtr->dataptr) |
| | 55 | { |
| | 56 | DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr; |
| | 57 | dynPtr->PrevPosition = dynPtr->Position = *Position; |
| | 58 | dynPtr->CanClimbStairs = 0; |
| | 59 | CreateEulerMatrix(&dynPtr->OrientEuler, &dynPtr->OrientMat); |
| | 60 | TransposeMatrixCH(&dynPtr->OrientMat); |
| | 61 | } |
| | 62 | else |
| | 63 | { |
| | 64 | /* dynamics block allocation failed... */ |
| | 65 | RemoveBehaviourStrategy(sbPtr); |
| | 66 | GADGET_NewOnScreenMessage("FAILED TO CREATE DUMMY: DYNBLOCK CREATION FAILURE"); |
| | 67 | return; |
| | 68 | } |
| | 69 | |
| | 70 | sbPtr->maintainVisibility = 1; |
| | 71 | sbPtr->containingModule = ModuleFromPosition(&sbPtr->DynPtr->Position, NULL); |
| | 72 | |
| | 73 | sbPtr->DamageBlock.Health = 100 << ONE_FIXED_SHIFT; |
| | 74 | sbPtr->DamageBlock.Armour = 100 << ONE_FIXED_SHIFT; |
| | 75 | sbPtr->DamageBlock.AcidResistant = 0; |
| | 76 | sbPtr->DamageBlock.FireResistant = 0; |
| | 77 | sbPtr->DamageBlock.ElectricResistant = 0; |
| | 78 | sbPtr->DamageBlock.PerfectArmour = 0; |
| | 79 | sbPtr->DamageBlock.ElectricSensitive = 0; |
| | 80 | sbPtr->DamageBlock.Combustability = 0; |
| | 81 | sbPtr->DamageBlock.Indestructable = 1; |
| | 82 | |
| | 83 | { |
| | 84 | SECTION *root_section; |
| | 85 | DUMMY_STATUS_BLOCK *dummyStatus = (DUMMY_STATUS_BLOCK *)sbPtr->dataptr; |
| | 86 | assert(dummyStatus); |
| | 87 | |
| | 88 | dummyStatus->incidentFlag = 0; |
| | 89 | dummyStatus->incidentTimer = 0; |
| | 90 | dummyStatus->HModelController.section_data = NULL; |
| | 91 | dummyStatus->HModelController.Deltas = NULL; |
| | 92 | dummyStatus->HModelController.Root_Section = NULL; |
| | 93 | |
| | 94 | if (!type || (type < 1) || (type > 3)) |
| | 95 | { |
| | 96 | switch(AvP.PlayerType) |
| | 97 | { |
| | 98 | default: |
| | 99 | case I_Marine: |
| | 100 | type = 1; |
| | 101 | break; |
| | 102 | case I_Alien: |
| | 103 | type = 2; |
| | 104 | break; |
| | 105 | case I_Predator: |
| | 106 | type = 3; |
| | 107 | } |
| | 108 | } |
| | 109 | |
| | 110 | if (1 == type) |
| | 111 | { |
| | 112 | dummyStatus->PlayerType = I_Marine; |
| | 113 | root_section = GetNamedHierarchyFromLibrary("hnpcmarine", "marine with pulse rifle"); |
| | 114 | |
| | 115 | if (!root_section) |
| | 116 | { |
| | 117 | RemoveBehaviourStrategy(sbPtr); |
| | 118 | GADGET_NewOnScreenMessage("FAILED TO CREATE DUMMY: NO HMODEL"); |
| | 119 | return; |
| | 120 | } |
| | 121 | |
| | 122 | Create_HModel(&dummyStatus->HModelController, root_section); |
| | 123 | InitHModelSequence(&dummyStatus->HModelController, (int)HMSQT_MarineStand, (int)MSSS_Fidget_A, -1); |
| | 124 | sbPtr->DynPtr->Mass = 80; |
| | 125 | } |
| | 126 | else if (2 == type) |
| | 127 | { |
| | 128 | dummyStatus->PlayerType = I_Alien; |
| | 129 | root_section = GetNamedHierarchyFromLibrary("hnpcalien", "alien"); |
| | 130 | |
| | 131 | if (!root_section) |
| | 132 | { |
| | 133 | RemoveBehaviourStrategy(sbPtr); |
| | 134 | GADGET_NewOnScreenMessage("FAILED TO CREATE DUMMY: NO HMODEL"); |
| | 135 | return; |
| | 136 | } |
| | 137 | |
| | 138 | Create_HModel(&dummyStatus->HModelController,root_section); |
| | 139 | InitHModelSequence(&dummyStatus->HModelController, (int)HMSQT_AlienStand, (int)ASSS_Standard, -1); |
| | 140 | sbPtr->DynPtr->Mass = 160; |
| | 141 | } |
| | 142 | else |
| | 143 | { |
| | 144 | dummyStatus->PlayerType = I_Predator; |
| | 145 | //root_section = GetNamedHierarchyFromLibrary("hnpcpredator", "pred with wristblade"); |
| | 146 | root_section = GetNamedHierarchyFromLibrary("hnpcpredator", "pred with disk"); |
| | 147 | |
| | 148 | if (!root_section) |
| | 149 | { |
| | 150 | RemoveBehaviourStrategy(sbPtr); |
| | 151 | GADGET_NewOnScreenMessage("FAILED TO CREATE DUMMY: NO HMODEL"); |
| | 152 | return; |
| | 153 | } |
| | 154 | |
| | 155 | sbPtr->DynPtr->Mass = 180; |
| | 156 | Create_HModel(&dummyStatus->HModelController,root_section); |
| | 157 | InitHModelSequence(&dummyStatus->HModelController, (int)HMSQT_PredatorStand, (int)PSSS_Standard, -1); |
| | 158 | } |
| | 159 | |
| | 160 | ProveHModel_Far(&dummyStatus->HModelController,sbPtr); |
| | 161 | |
| | 162 | if(!sbPtr->containingModule) |
| | 163 | { |
| | 164 | /* no containing module can be found... abort*/ |
| | 165 | RemoveBehaviourStrategy(sbPtr); |
| | 166 | GADGET_NewOnScreenMessage("FAILED TO CREATE DUMMY: MODULE CONTAINMENT FAILURE"); |
| | 167 | return; |
| | 168 | } |
| | 169 | assert(sbPtr->containingModule); |
| | 170 | |
| | 171 | MakeDummyNear(sbPtr); |
| | 172 | } |
| | 173 | } |
| | 174 | |
| | 175 | void CastDummy(int type) |
| | 176 | { |
| | 177 | #define BOTRANGE 2000 |
| | 178 | |
| | 179 | VECTORCH position; |
| | 180 | |
| | 181 | position = PlayerStatus.sbptr->DynPtr->Position; |
| | 182 | position.vx += MUL_FIXED(PlayerStatus.sbptr->DynPtr->OrientMat.mat31, BOTRANGE); |
| | 183 | position.vy += MUL_FIXED(PlayerStatus.sbptr->DynPtr->OrientMat.mat32, BOTRANGE); |
| | 184 | position.vz += MUL_FIXED(PlayerStatus.sbptr->DynPtr->OrientMat.mat33, BOTRANGE); |
| | 185 | |
| | 186 | CreateDummy(&position, type); |
| | 187 | } |
| | 188 | |
| | 189 | void MakeDummyFar(STRATEGYBLOCK *sbPtr) |
| | 190 | { |
| | 191 | DestroyActiveObject(&sbPtr->DisplayBlock); |
| | 192 | |
| | 193 | /* zero linear velocity in dynamics block */ |
| | 194 | sbPtr->DynPtr->LinVelocity.vx = sbPtr->DynPtr->LinVelocity.vy = sbPtr->DynPtr->LinVelocity.vz = 0; |
| | 195 | } |
| | 196 | |
| | 197 | void DummyBehaviour(STRATEGYBLOCK *sbPtr) |
| | 198 | { |
| | 199 | assert(sbPtr); |
| | 200 | assert(sbPtr->containingModule); |
| | 201 | DUMMY_STATUS_BLOCK *dummyStatusPointer = (DUMMY_STATUS_BLOCK *)(sbPtr->dataptr); |
| | 202 | assert(dummyStatusPointer); |
| | 203 | |
| | 204 | /* Should be the same near as far. */ |
| | 205 | /* test if we've got a containing module: if we haven't, do nothing. |
| | 206 | This is important as the object could have been marked for deletion by the visibility |
| | 207 | management system...*/ |
| | 208 | |
| | 209 | if(!sbPtr->containingModule) |
| | 210 | { |
| | 211 | sbPtr->please_destroy_me = 1; /* just to make sure */ |
| | 212 | return; |
| | 213 | } |
| | 214 | else if (dummyStatusPointer->PlayerType != I_Alien) |
| | 215 | { |
| | 216 | AddPheromones(sbPtr->containingModule->m_aimodule); |
| | 217 | } |
| | 218 | |
| | 219 | /* Incident handling. */ |
| | 220 | /* |
| | 221 | dummyStatusPointer->incidentFlag = 0; |
| | 222 | dummyStatusPointer->incidentTimer -= NormalFrameTime; |
| | 223 | |
| | 224 | if (dummyStatusPointer->incidentTimer < 0) |
| | 225 | { |
| | 226 | dummyStatusPointer->incidentFlag = 1; |
| | 227 | dummyStatusPointer->incidentTimer = 32767 + (FastRandom() & 65535); |
| | 228 | } |
| | 229 | */ |
| | 230 | } |