4b825dc642cb6eb9a060e54bf8d69288fbee490494a6641b73026d662261604d7d192beae70b11dc
 
 
1
#include "system.h"
 
 
2
#include "prototyp.h"
 
 
3
#include "stratdef.h"
 
 
4
#include "bh_types.h"
 
 
5
#include "pheromon.h"
 
 
6
#include "pfarlocs.h"
 
 
7
#include "pldghost.h"
 
 
8
#include <stdlib.h>
 
 
9
#include <assert.h>
 
 
10
 
 
 
11
static uint32_t *Pher_Player1;
 
 
12
static uint32_t *Pher_Player2;
 
 
13
 
 
 
14
extern int CheckAdjacencyValidity(AIMODULE *target,AIMODULE *source,int alien);
 
 
15
 
 
 
16
/* these pointers indicate the current read from and write to
 
 
17
buffers for the player and ai pheromone systems */
 
 
18
uint32_t *PherPl_ReadBuf;
 
 
19
uint32_t *PherPl_WriteBuf;
 
 
20
 
 
 
21
#if SUPER_PHEROMONE_SYSTEM
 
 
22
static uint32_t *Pher_Aliens1;
 
 
23
static uint32_t *Pher_Aliens2;
 
 
24
 
 
 
25
uint32_t *PherAls_ReadBuf;
 
 
26
uint32_t *PherAls_WriteBuf;
 
 
27
 
 
 
28
/* Marine pheromones: a pathfinding system only. */
 
 
29
static uint32_t *Pher_Marines1;
 
 
30
static uint32_t *Pher_Marines2;
 
 
31
 
 
 
32
uint32_t *PherMars_ReadBuf;
 
 
33
uint32_t *PherMars_WriteBuf;
 
 
34
 
 
 
35
#endif
 
 
36
 
 
 
37
/* This global is used to store    the current player phermone intensity */
 
 
38
unsigned int PlayerSmell;
 
 
39
 
 
 
40
/* this define enables diagnostic text 'dump' for pheromone system */
 
 
41
#define logPheromoneDiagnostics 0
 
 
42
 
 
 
43
#if logPheromoneDiagnostics
 
 
44
static void LogPlayerPherValues();
 
 
45
static void LogModuleAdjacencies();
 
 
46
int printModAdj = 1;
 
 
47
#endif
 
 
48
 
 
 
49
void InitPheromoneSystem()
 
 
50
{
 
 
51
    int i;
 
 
52
 
 
 
53
    /* allocate the pheromone buffers */
 
 
54
 
 
 
55
    Pher_Player1 = malloc((AIModuleArraySize + 1) * sizeof(uint32_t));
 
 
56
    Pher_Player2 = malloc((AIModuleArraySize + 1) * sizeof(uint32_t));
 
 
57
 
 
 
58
    if(!Pher_Player1 || !Pher_Player2) 
 
 
59
    {
 
 
60
        memoryInitialisationFailure = 1;
 
 
61
        return;
 
 
62
    }
 
 
63
 
 
 
64
    #if SUPER_PHEROMONE_SYSTEM
 
 
65
 
 
 
66
    Pher_Aliens1 = calloc(AIModuleArraySize + 1, sizeof(uint32_t));
 
 
67
 
 
 
68
    if(!Pher_Aliens1) 
 
 
69
    {
 
 
70
        memoryInitialisationFailure = 1;
 
 
71
        return;
 
 
72
    }
 
 
73
 
 
 
74
    Pher_Aliens2 = calloc(AIModuleArraySize + 1, sizeof(uint32_t));
 
 
75
 
 
 
76
    if(!Pher_Aliens2) 
 
 
77
    {
 
 
78
        memoryInitialisationFailure = 1;
 
 
79
        return;
 
 
80
    }
 
 
81
 
 
 
82
    Pher_Marines1 = calloc(AIModuleArraySize + 1, sizeof(uint32_t));
 
 
83
 
 
 
84
    if(!Pher_Marines1) 
 
 
85
    {
 
 
86
        memoryInitialisationFailure = 1;
 
 
87
        return;
 
 
88
    }
 
 
89
 
 
 
90
    Pher_Marines2 = calloc(AIModuleArraySize + 1, sizeof(uint32_t));
 
 
91
 
 
 
92
    if(!Pher_Marines2) 
 
 
93
    {
 
 
94
        memoryInitialisationFailure = 1;
 
 
95
        return;
 
 
96
    }
 
 
97
    #endif
 
 
98
 
 
 
99
    /* init the player phermone system */
 
 
100
    for(i=0; i < AIModuleArraySize; i++) 
 
 
101
        Pher_Player1[i] = Pher_Player2[i] = 1;
 
 
102
 
 
 
103
    PherPl_ReadBuf = &Pher_Player1[0]; 
 
 
104
    PherPl_WriteBuf = &Pher_Player2[0]; 
 
 
105
    PlayerSmell = 3;
 
 
106
 
 
 
107
    #if SUPER_PHEROMONE_SYSTEM
 
 
108
 
 
 
109
    PherAls_ReadBuf = &Pher_Aliens1[0]; 
 
 
110
    PherAls_WriteBuf = &Pher_Aliens2[0]; 
 
 
111
 
 
 
112
    PherMars_ReadBuf = &Pher_Marines1[0]; 
 
 
113
    PherMars_WriteBuf = &Pher_Marines2[0]; 
 
 
114
 
 
 
115
    #endif
 
 
116
 
 
 
117
    #if logPheromoneDiagnostics
 
 
118
    printModAdj = 1;
 
 
119
    #endif
 
 
120
}
 
 
121
 
 
 
122
/*----------------------Patrick 14/3/96--------------------------- 
 
 
123
End of level clean up for pheromone system
 
 
124
-------------------------------------------------------------------*/
 
 
125
void CleanUpPheromoneSystem()
 
 
126
{
 
 
127
    #if 1
 
 
128
    if (Pher_Player1 != NULL)
 
 
129
    {
 
 
130
        free(Pher_Player1); 
 
 
131
        Pher_Player1 = NULL;
 
 
132
    }
 
 
133
 
 
 
134
    if (Pher_Player2 != NULL)
 
 
135
    {
 
 
136
        free(Pher_Player2);
 
 
137
        Pher_Player2 = NULL;
 
 
138
    }
 
 
139
 
 
 
140
    PherPl_ReadBuf = NULL;
 
 
141
    PherPl_WriteBuf = NULL;
 
 
142
    #endif
 
 
143
 
 
 
144
    #if SUPER_PHEROMONE_SYSTEM
 
 
145
    if (Pher_Aliens1 != NULL)
 
 
146
    {
 
 
147
        free(Pher_Aliens1);
 
 
148
        Pher_Aliens1 = NULL;
 
 
149
    }
 
 
150
 
 
 
151
    if (Pher_Aliens2 != NULL)
 
 
152
    {
 
 
153
        free(Pher_Aliens2);
 
 
154
        Pher_Aliens2 = NULL;
 
 
155
    }
 
 
156
 
 
 
157
    if (Pher_Marines1 != NULL)
 
 
158
    {
 
 
159
        free(Pher_Marines1);
 
 
160
        Pher_Marines1 = NULL;
 
 
161
    }
 
 
162
 
 
 
163
    if (Pher_Marines2 != NULL)
 
 
164
    {
 
 
165
        free(Pher_Marines2);
 
 
166
        Pher_Marines2 = NULL;
 
 
167
    }
 
 
168
 
 
 
169
    PherAls_ReadBuf = NULL;
 
 
170
    PherAls_WriteBuf = NULL;
 
 
171
    PherMars_ReadBuf = NULL;
 
 
172
    PherMars_WriteBuf = NULL;
 
 
173
    #endif
 
 
174
}
 
 
175
 
 
 
176
int AIModuleAdmitsPheromones(AIMODULE *targetModule)
 
 
177
{
 
 
178
    switch(AIModuleIsADoor(targetModule))
 
 
179
    {
 
 
180
        case MDT_ProxDoor:
 
 
181
        {
 
 
182
            /* Go thru UNLOCKED proxdoors... */
 
 
183
 
 
 
184
            MODULE *renderModule = *(targetModule->m_module_ptrs);
 
 
185
            PROXDOOR_BEHAV_BLOCK *pdbblk = ((PROXDOOR_BEHAV_BLOCK *)renderModule->m_sbptr->dataptr);
 
 
186
 
 
 
187
            return !(pdbblk->door_locked);
 
 
188
        }
 
 
189
        case MDT_LiftDoor:
 
 
190
        case MDT_SecurityDoor:
 
 
191
             assert(targetModule->m_module_ptrs);
 
 
192
             assert(*(targetModule->m_module_ptrs));
 
 
193
             return GetState((*(targetModule->m_module_ptrs))->m_sbptr);
 
 
194
        //case MDT_NotADoor: assert(0);
 
 
195
        default:
 
 
196
            return 1;
 
 
197
    }
 
 
198
}
 
 
199
 
 
 
200
#if SUPER_PHEROMONE_SYSTEM
 
 
201
void AddPheromones(AIMODULE *targetModule)
 
 
202
{
 
 
203
    PherAls_WriteBuf[targetModule->m_index] += 3;
 
 
204
}
 
 
205
 
 
 
206
void MaintainMarineTargetZone(AIMODULE *targetModule)
 
 
207
{
 
 
208
    PherMars_WriteBuf[targetModule->m_index] += 3;
 
 
209
}
 
 
210
 
 
 
211
#endif
 
 
212
 
 
 
213
/*----------------------Patrick 12/11/96--------------------------- 
 
 
214
Updates the player pheromone system:
 
 
215
this is used by the NPC far behaviour for hunting the player.
 
 
216
-------------------------------------------------------------------*/
 
 
217
void PlayerPheromoneSystem()
 
 
218
{
 
 
219
    int moduleCounter = 0;
 
 
220
 
 
 
221
    #if logPheromoneDiagnostics    
 
 
222
        if(printModAdj)
 
 
223
        {
 
 
224
            printModAdj = 0;
 
 
225
            LogModuleAdjacencies();
 
 
226
        }
 
 
227
    #endif
 
 
228
 
 
 
229
    /* get a pointer to the global array of pointers to the modules
 
 
230
    in the environment (interfaces'r'us).  */
 
 
231
 
 
 
232
    AIMODULE *ModuleListPointer = AIModuleArray;
 
 
233
 
 
 
234
    /* go through each module in the environment  */    
 
 
235
    for(; moduleCounter < AIModuleArraySize; moduleCounter++)
 
 
236
    {
 
 
237
        /* get a pointer to the next current module */
 
 
238
        AIMODULE *ThisModulePtr = &ModuleListPointer[moduleCounter]; 
 
 
239
        assert(ThisModulePtr);
 
 
240
 
 
 
241
        /* get it's index */
 
 
242
        int ThisModuleIndex = ThisModulePtr->m_index;
 
 
243
 
 
 
244
        assert(ThisModuleIndex >= 0);
 
 
245
        assert(ThisModuleIndex < AIModuleArraySize);
 
 
246
 
 
 
247
        /* !!!!!!!!!!!!!!!!!!!!!
 
 
248
        check for closed non-traversable door module here if detected, do not update its smell.
 
 
249
 
 
 
250
        Actually, no: allow smell to pass thro' non-openable doors. Otherwise AIs that can open
 
 
251
        doors will choose not to 
 
 
252
        !!!!!!!!!!!!!!!!!!!!!!!!*/
 
 
253
 
 
 
254
        /* CDF 4/12/97: Actually, yes.  AIs CAN'T open security doors, fool! */
 
 
255
 
 
 
256
        /* check for universal module: don't want to update this! */
 
 
257
        if(AIModuleIsPhysical(ThisModulePtr))
 
 
258
        {
 
 
259
            if (AIModuleAdmitsPheromones(ThisModulePtr))
 
 
260
            {
 
 
261
                /* get a pointer to the list of physically adjacent modules
 
 
262
                and traverse them */
 
 
263
                AIMODULE **AdjModuleRefPtr = ThisModulePtr->m_link_ptrs;
 
 
264
 
 
 
265
                if(AdjModuleRefPtr)    /* check that there is a list of adjacent modules */
 
 
266
                {
 
 
267
                    while(*AdjModuleRefPtr != 0)
 
 
268
                    {
 
 
269
                        /* get the index */
 
 
270
                        int AdjModuleIndex = (*AdjModuleRefPtr)->m_index;
 
 
271
 
 
 
272
                        /* if adjacent module's previous smell is greater than
 
 
273
                        the current module's new smell (so far), then update
 
 
274
                        the current module's newq smell */
 
 
275
 
 
 
276
                        if(PherPl_ReadBuf[AdjModuleIndex] > PherPl_WriteBuf[ThisModuleIndex])
 
 
277
                            PherPl_WriteBuf[ThisModuleIndex] = (PherPl_ReadBuf[AdjModuleIndex] - 1);
 
 
278
 
 
 
279
                        #if SUPER_PHEROMONE_SYSTEM
 
 
280
                        if(PherAls_ReadBuf[AdjModuleIndex] > PherAls_WriteBuf[ThisModuleIndex])
 
 
281
                            PherAls_WriteBuf[ThisModuleIndex] = (PherAls_ReadBuf[AdjModuleIndex] - 1);
 
 
282
 
 
 
283
                        if (CheckAdjacencyValidity((*AdjModuleRefPtr), ThisModulePtr, 0))
 
 
284
                        {
 
 
285
                            if(PherMars_ReadBuf[AdjModuleIndex] > PherMars_WriteBuf[ThisModuleIndex])
 
 
286
                            {
 
 
287
                                PherMars_WriteBuf[ThisModuleIndex] = (PherMars_ReadBuf[AdjModuleIndex] - 1);
 
 
288
                            }
 
 
289
                        }
 
 
290
                        #endif
 
 
291
 
 
 
292
                        /* next adjacent module reference pointer */
 
 
293
                        AdjModuleRefPtr++;
 
 
294
                    }
 
 
295
                }
 
 
296
            }
 
 
297
 
 
 
298
            #if SUPER_PHEROMONE_SYSTEM
 
 
299
            /* Decay pheromones. */
 
 
300
            if (PherAls_WriteBuf[ThisModuleIndex] > 0)
 
 
301
                PherAls_WriteBuf[ThisModuleIndex]--;
 
 
302
 
 
 
303
            if (PherMars_WriteBuf[ThisModuleIndex] > 0)
 
 
304
                PherMars_WriteBuf[ThisModuleIndex]--;
 
 
305
            #endif
 
 
306
        }
 
 
307
    }
 
 
308
 
 
 
309
    switch(AvP.PlayMode)
 
 
310
    {
 
 
311
    case NetworkHost:
 
 
312
    case Skirmish:
 
 
313
        /*If in a network game add pheromon's for other players*/
 
 
314
        {
 
 
315
            /* go through the strategy blocks looking for players*/
 
 
316
            int sbIndex = 0;
 
 
317
            for(; sbIndex < NumActiveStBlocks; sbIndex++)
 
 
318
            {
 
 
319
                STRATEGYBLOCK *playerSbPtr = ActiveStBlockList[sbIndex];
 
 
320
 
 
 
321
                if(playerSbPtr->type != I_BehaviourNetGhost)
 
 
322
                    continue;
 
 
323
 
 
 
324
                NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)playerSbPtr->dataptr;
 
 
325
 
 
 
326
                if(ghostData->type == I_BehaviourMarinePlayer || ghostData->type == I_BehaviourPredatorPlayer)
 
 
327
                {
 
 
328
                    /*this is another player*/
 
 
329
                    if(playerSbPtr->containingModule)
 
 
330
                    {
 
 
331
                        PherPl_WriteBuf[playerSbPtr->containingModule->m_aimodule->m_index] = PlayerSmell;
 
 
332
                        AddPheromones(playerSbPtr->containingModule->m_aimodule);
 
 
333
                    }
 
 
334
                }
 
 
335
            }
 
 
336
        }
 
 
337
    default:
 
 
338
    break;
 
 
339
    }
 
 
340
 
 
 
341
    /* That completed, find which module the player is in, set it's smell to the
 
 
342
    current player smell value, and update the player smell for the next frame */
 
 
343
 
 
 
344
    if(PlayerStatus.sbptr->containingModule)
 
 
345
    {
 
 
346
        //the player must be alive to leave pheromones 
 
 
347
        //(mainly relevant in coop games)
 
 
348
        if(PlayerStatus.Alive)
 
 
349
        {
 
 
350
            PherPl_WriteBuf[PlayerStatus.sbptr->containingModule->m_aimodule->m_index] = PlayerSmell;
 
 
351
/*
 
 
352
            if(PlayerStatus.sbptr->containingModule->name)
 
 
353
            {
 
 
354
printf("Player Module: %d '%s'\n", PlayerStatus.sbptr->containingModule->m_index, PlayerStatus.sbptr->containingModule->name);
 
 
355
printf("Player Module Coords: %d %d %d\n", PlayerStatus.sbptr->containingModule->m_world.vx,
PlayerStatus.sbptr->containingModule->m_world.vy, PlayerStatus.sbptr->containingModule->m_world.vz);
 
 
356
            }
 
 
357
*/
 
 
358
        }
 
 
359
    }
 
 
360
 
 
 
361
    PlayerSmell++;
 
 
362
 
 
 
363
    #if SUPER_PHEROMONE_SYSTEM
 
 
364
    /* Note that marines should add pheromones at the AI level... */
 
 
365
    {
 
 
366
        uint32_t *tempBufPointer = PherAls_ReadBuf;
 
 
367
        PherAls_ReadBuf = PherAls_WriteBuf;
 
 
368
        PherAls_WriteBuf= tempBufPointer;
 
 
369
      }
 
 
370
    /* As should the pathfinding system. */
 
 
371
    {
 
 
372
        uint32_t *tempBufPointer = PherMars_ReadBuf;
 
 
373
        PherMars_ReadBuf = PherMars_WriteBuf;
 
 
374
        PherMars_WriteBuf= tempBufPointer;
 
 
375
      }
 
 
376
    #endif
 
 
377
 
 
 
378
    /* swap the read and write buffers:
 
 
379
       behaviours access most recent data thro' the read buffer */
 
 
380
    {
 
 
381
        uint32_t *tempBufPointer = PherPl_ReadBuf;
 
 
382
        PherPl_ReadBuf = PherPl_WriteBuf;
 
 
383
        PherPl_WriteBuf    = tempBufPointer;
 
 
384
      }
 
 
385
 
 
 
386
    #if logPheromoneDiagnostics
 
 
387
    LogPlayerPherValues();
 
 
388
    #endif
 
 
389
}
 
 
390
 
 
 
391
#if logPheromoneDiagnostics 
 
 
392
 
 
 
393
/* write out a list of module ajacencies */
 
 
394
 
 
 
395
static void LogModuleAdjacencies()
 
 
396
{
 
 
397
    extern SCENEMODULE MainScene;
 
 
398
    assert(0);
 
 
399
 
 
 
400
    /* This function does not use AI modules yet! */
 
 
401
 
 
 
402
    FILE *logFile;
 
 
403
    int i;
 
 
404
    MODULE **ModuleListPointer = MainScene.sm_marray;
 
 
405
    MODULE *ThisModulePtr;
 
 
406
    int ThisModuleIndex;    
 
 
407
    MREF *AdjModuleRefPtr;
 
 
408
    int AdjModuleIndex;
 
 
409
 
 
 
410
    logFile = fopen("avp/modadj.txt","w");
 
 
411
 
 
 
412
    if(logFile)
 
 
413
    {
 
 
414
        assert(ModuleArraySize);
 
 
415
 
 
 
416
        for(i = 0; i < ModuleArraySize; i++)
 
 
417
        {
 
 
418
            ThisModulePtr = ModuleListPointer[i]; 
 
 
419
            assert(ThisModulePtr);
 
 
420
 
 
 
421
            /* get it's index */
 
 
422
            ThisModuleIndex = ThisModulePtr->m_index;
 
 
423
 
 
 
424
            assert(ThisModuleIndex >= 0);
 
 
425
            assert(ThisModuleIndex < ModuleArraySize);
 
 
426
 
 
 
427
            //fprintf(logFile, "Module %d Adjoing modules: ", ThisModuleIndex);
 
 
428
 
 
 
429
            /* get a pointer to the list of physically adjacent modules
 
 
430
            and traverse them */
 
 
431
            AdjModuleRefPtr = ThisModulePtr->m_link_ptrs;
 
 
432
            if(AdjModuleRefPtr == 0)
 
 
433
            {
 
 
434
                //fprintf(logFile, " None/n");
 
 
435
            }
 
 
436
            else
 
 
437
            {
 
 
438
                while(AdjModuleRefPtr->mref_ptr != 0)
 
 
439
                {
 
 
440
                    /* get the index */
 
 
441
                    AdjModuleIndex = (AdjModuleRefPtr->mref_ptr)->m_index;
 
 
442
 
 
 
443
                    //fprintf(logFile, " %d,", AdjModuleIndex);
 
 
444
 
 
 
445
                    /* next adjacent module reference pointer */
 
 
446
                    AdjModuleRefPtr++;
 
 
447
                }
 
 
448
 
 
 
449
                //fprintf(logFile, "\n");
 
 
450
            }
 
 
451
        }
 
 
452
        fclose(logFile);
 
 
453
    }
 
 
454
 
 
 
455
    /* also, initialise pheromone value file */
 
 
456
 
 
 
457
    logFile = fopen("D:/PATRICK/MODPPHER.TXT","w");
 
 
458
 
 
 
459
    if(logFile) 
 
 
460
    {
 
 
461
        fprintf(logFile, "PLAYER PHEROMONE VALUES \n");
 
 
462
        fclose(logFile);
 
 
463
    }
 
 
464
}
 
 
465
 
 
 
466
/* Log the player pheromone values */
 
 
467
static void LogPlayerPherValues()
 
 
468
{
 
 
469
    int i;
 
 
470
    FILE *logFile = fopen("D:/PATRICK/MODPPHER.TXT","a");
 
 
471
 
 
 
472
    if (!logFile) return;
 
 
473
 
 
 
474
    fprintf(logFile, "\n ***************************** \n");
 
 
475
 
 
 
476
    for(i=0; i < AIModuleArraySize; i++) 
 
 
477
    {
 
 
478
        if(i % 7 == 0)
 
 
479
            fprintf(logFile, "\n");
 
 
480
 
 
 
481
        fprintf(logFile, "%5d", PherPl_ReadBuf[i]);    
 
 
482
    }
 
 
483
 
 
 
484
fclose(logFile);
 
 
485
}
 
 
486
 
 
 
487
#endif