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