Import Aliens vs Predator - Gold (Build 116)

Source code release, imported from:
https://www.gamefront.com/games/aliens-vs-predator-3/file/avp-gold-complete-source-code

All text files were converted to Unix format.
This commit is contained in:
Rebellion Developments 2000-03-16 11:25:00 +01:00 committed by Patryk Obara
commit 218ca90543
572 changed files with 434587 additions and 0 deletions

914
3dc/AFONT.C Normal file
View file

@ -0,0 +1,914 @@
#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "gamedef.h"
#include "font.h"
#include "indexfnt.hpp"
#define UseLocalAssert 1
#include "ourasert.h"
/* Roxbys font stuff. any comments will be useful!!!
font control - Fonts description and sturctures game/plat/font.h
Platform dependent processing game/plat/platsup.c or ddplat.cpp
*/
/* general ideas. Crap I know!!!
written to maintain compatiblity with the current texture (bitmap) processing tools.
all the information about spacing of the font is maintained witin the bitmap itself,
using hotspots for the texture processing, that way we dont need extra tools to convert
fonts. It also allows complete font positioning (except different letter combos changing)
I have shifted most of the emphasis onto the artists to set up the font and to mark it how they
see fit. All the fonts must contain hotspots for all the letters. In that way we can easily
expand fonts. The character offests at the mo are simply -32. We may have to set up jump tables
at some later date to get chars for different languages.
Nothing supports anti-aliasing at the moment. Be careful with colours!!!
Most of the info is being passed as locals. Clumsy I know. I didnt want to take up more
space than was nessecery
HARD coded. Names of the fonts
Number of fonts to load
Number of characters in the font. you can leave letters blank. The number of
characters in the fonts can be changed for different languages
AVP-Win95
This loads all the fonts in the structure PFFONT AvpFonts[] that is passed
to while NUM_FONTS. The Imageheader->ImagePtr for the data is maintained
untill we have processd the characters. I dont fancy manipulating the data
in a LPDIRECTDRAWSURFACE. The character descriptors in the font contain
nothing but a src RECT. the void* pointer in the PFFONT structure in this
case is cast to LPDIRECTDRAWSURFACE.
Not that the entire font is placed into a
file That is then processed. CLUT where to
put the CLU???? Put it into the vid memory.
use a void*
*/
/*
Only have 8 bit support a tne moment. More to come!!!
Screen modes. I recommend loading up different fonts for different screen modes.
Simply reference a different structure.
*/
#define CHAR_WIDTH(font_num, offset) ((AvpFonts[font_num].srcRect[offset].right - AvpFonts[font_num].srcRect[offset].left))
#define CHAR_HEIGHT(font_num, offset) ((AvpFonts[font_num].srcRect[offset].bottom - AvpFonts[font_num].srcRect[offset].top))
#define IS_CHAR_WHITE_SPACE(ch) ((ch == '\t' || ch == '\n' || ch == ' ' || (int)ch == 0x0))
static int ProcessFontEntry
(
PFFONT* font,
unsigned char* fontstartaddress,
unsigned pitch,
int* countfromrow,
int* countfromcol,
int charnum
);
static int ProcessLineLength
(
char* start_ch, // start char of string
AVP_FONTS fontnum, // the font we are using
int offset, // the offset from the font
int max_width, // the width of the line
char** end_ch, // filled with end address
int* line_length
);
void LoadAllFonts()
{
// these fonts end up being in memory all the time,
// I will also supply a function which is delete
// specific font.
int fontnum = 0;
while(fontnum < NUM_FONTS)
{
/* load the font in turn */
LoadPFFont(fontnum);
fontnum ++;
}
}
void LoadPFFont(int fontnum)
{
// these fonts end up being in memory all the time,
// I will also supply a function which is delete
// specific font.
PFFONT *font = &AvpFonts[fontnum];
unsigned nPitch;
unsigned char * pSurface;
LoadFont(font);
/* get the hotspot color first entry in */
if(font->fttexBitDepth == 15)font->fttexBitDepth = 16;
pSurface = FontLock(font,&nPitch);
GLOBALASSERT(pSurface);
font->hotSpotValue = *(unsigned *)pSurface & (font->fttexBitDepth<32 ? (1<<font->fttexBitDepth)-1 : 0xffffffffU);
/* the hotspot value is the top-left pixel */
{
int charnum = 0;
int countfromrow = 1;
int countfromcol = 0;
/*
find the hotspots and send everything to the
processing function. This part of routine find the
hotspots in numbers of pixels
*/
/*Top line of the texture is redundent we get the hotspot from this*/
/*edge of the texture has only lines*/
while(charnum < font->num_chars_in_font)
{
ProcessFontEntry(font,pSurface,nPitch,&countfromrow,&countfromcol,charnum);
charnum++;
}
#if 0
// Taken out by DHM 26/11/97:
fontnum++;
#endif
charnum = 0;
}
FontUnlock(font);
#if SupportWindows95
INDEXFNT_PFLoadHook
(
(FontIndex) fontnum,
// FontIndex I_Font_New,
font // PFFONT *pffont_New
);
#endif
}
static int ProcessFontEntry
(
PFFONT* font,
unsigned char* fontstartaddress,
unsigned pitch,
int* countfromrow,
int* countfromcol,
int charnum
)
{
/*
okay set the starting point
countfromrow marks the current depth of the processing row in the texture.
countfromcol marks how far along the current coloum we have processed
* = HOTSPOT .. the first pixel is used as the hotspot
**********************
* ** ** **** * <---- startfromrow
###
#
## # # ###
# # # # # ##
### ### #### ##
* * # * **** * Blank chars marked by two hotspots adjacent
### ^^ |at the top and the bottom
* * || |
^ ||______|
|
|
startfromcol
********************* Note that the spot in col 0 marks a new linw of chars
*/
int curr_row = *countfromrow;
int curr_col = *countfromcol;
int y_offset = 0, x_offset = curr_col;
GLOBALASSERT(font);
GLOBALASSERT(fontstartaddress);
GLOBALASSERT(charnum < font->num_chars_in_font);
GLOBALASSERT(curr_row < font->fttexHeight);
GLOBALASSERT(curr_col <= font->fttexWidth);
/*remember that all the corrdinates are done by pixels
find the x and y corrdinates of the left lower hotspot
we process each line (row) from startfromrow to the end
first find the next marker in startfromrow
*/
// only supported if bit depth is a whole number of bytes
GLOBALASSERT(8==font->fttexBitDepth || 16==font->fttexBitDepth || 24==font->fttexBitDepth || 32==font->fttexBitDepth);
while(1)
{
// this bit processes the chars, finds uvs, extents and fills in the sturcture*/
// count along the row to find the next x position
unsigned int colour_here;
if(x_offset > font->fttexWidth - 1)
{
// reached the end of the line! reset x and then y
x_offset = 0;
curr_col = 0;
curr_row += font->fontHeight; // max line height
*countfromrow = curr_row;
GLOBALASSERT(curr_row < font->fttexHeight);
}
switch (font->fttexBitDepth)
{
default:
GLOBALASSERT(0);
case 8:
colour_here = *(fontstartaddress + (curr_row*pitch + x_offset));
break;
case 16:
colour_here = *(unsigned short *)(fontstartaddress + (curr_row*pitch + 2*x_offset));
break;
case 24:
{
unsigned char * pPixel = fontstartaddress + (curr_row*pitch + 3*x_offset);
// assuming the right endianness
colour_here = pPixel[0] | (unsigned)pPixel[1] << 8 | (unsigned)pPixel[2] << 16;
break;
}
case 32:
colour_here = *(unsigned *)(fontstartaddress + (curr_row*pitch + 4*x_offset));
break;
}
if(colour_here == font->hotSpotValue)
{
int width = -1, height = -1;
/* set up the uv corrds of the top left corner*/
int u = x_offset + 1;
int v = curr_row + 1;
/* scan down to give height*/
for(y_offset = (curr_row + 1); y_offset < font->fttexHeight; y_offset++)
{
switch (font->fttexBitDepth)
{
default:
GLOBALASSERT(0);
case 8:
colour_here = *(fontstartaddress + (y_offset*pitch + x_offset));
break;
case 16:
colour_here = *(unsigned short *)(fontstartaddress + (y_offset*pitch + 2*x_offset));
break;
case 24:
{
unsigned char * pPixel = fontstartaddress + (y_offset*pitch + 3*x_offset);
// assuming the right endianness
colour_here = pPixel[0] | (unsigned)pPixel[1] << 8 | (unsigned)pPixel[2] << 16;
break;
}
case 32:
colour_here = *(unsigned *)(fontstartaddress + (y_offset*pitch + 4*x_offset));
break;
}
if(colour_here == font->hotSpotValue)
{
height = y_offset - curr_row - 1; // -1 because we exclude the top and bottom hotspots
break;
}
}
/* scan along to get the width*/
for(++x_offset; x_offset < font->fttexWidth; x_offset ++)
{
switch (font->fttexBitDepth)
{
default:
GLOBALASSERT(0);
case 8:
colour_here = *(fontstartaddress + (curr_row*pitch + x_offset));
break;
case 16:
colour_here = *(unsigned short *)(fontstartaddress + (curr_row*pitch + 2*x_offset));
break;
case 24:
{
unsigned char * pPixel = fontstartaddress + (curr_row*pitch + 3*x_offset);
// assuming the right endianness
colour_here = pPixel[0] | (unsigned)pPixel[1] << 8 | (unsigned)pPixel[2] << 16;
break;
}
case 32:
colour_here = *(unsigned *)(fontstartaddress + (curr_row*pitch + 4*x_offset));
break;
}
if(colour_here == font->hotSpotValue)
{
width = x_offset - curr_col - 1; // exclude end hotspot
break;
}
}
*countfromcol = x_offset + 1; /* ready for the next char*/
/*fill in the data structure - platform dependent*/
FillCharacterSlot(u, v, width, height, charnum, font);
return 0;
}
x_offset++;
}
return 0;
}
#if 0 // obsolete
static int Process8BitEntry(PFFONT* font,
char* fontstartaddress,
int* countfromrow,
int* countfromcol,
int charnum)
{
/*
okay set the starting point
countfromrow marks the current depth of the processing row in the texture.
countfromcol marks how far along the current coloum we have processed
* = HOTSPOT .. the first pixel is used as the hotspot
**********************
* ** ** **** * <---- startfromrow
###
#
## # # ###
# # # # # ##
### ### #### ##
* * # * **** * Blank chars marked by two hotspots adjacent
### ^^ |at the top and the bottom
* * || |
^ ||______|
|
|
startfromcol
********************* Note that the spot in col 0 marks a new linw of chars
*/
int curr_row = *countfromrow;
int curr_col = *countfromcol;
int y_offset = 0, x_offset = curr_col;
GLOBALASSERT(font);
GLOBALASSERT(fontstartaddress);
GLOBALASSERT(charnum < font->num_chars_in_font);
GLOBALASSERT(curr_row < font->fttexHeight);
GLOBALASSERT(curr_col <= font->fttexWidth);
/*remember that all the corrdinates are done by pixels
find the x and y corrdinates of the left lower hotspot
we process each line (row) from startfromrow to the end
first find the next marker in startfromrow
*/
while(1)
{
// this bit processes the chars, finds uvs, extents and fills in the sturcture*/
// count along the row to find the next x position
unsigned int colour_here;
if(x_offset > font->fttexWidth - 1)
{
// reached the end of the line! reset x and then y
x_offset = 0;
curr_col = 0;
curr_row += font->fontHeight; // max line height
*countfromrow = curr_row;
GLOBALASSERT(curr_row < font->fttexHeight);
}
colour_here = (int)*(fontstartaddress + (curr_row*font->fttexWidth + x_offset));
if(colour_here == font->hotSpotValue)
{
int width = -1, height = -1;
/* set up the uv corrds of the top left corner*/
int u = x_offset + 1;
int v = curr_row + 1;
/* scan down to give height*/
for(y_offset = (curr_row + 1); y_offset < font->fttexHeight; y_offset++)
{
colour_here = (int)*(fontstartaddress + (y_offset*font->fttexWidth + x_offset));
if(colour_here == font->hotSpotValue)
{
height = y_offset - curr_row - 1; // -1 because we exclude the top and bottom hotspots
break;
}
}
/* scan along to get the width*/
for(++x_offset; x_offset < font->fttexWidth; x_offset ++)
{
colour_here = (int)*(fontstartaddress + (curr_row*font->fttexWidth + x_offset));
if(colour_here == font->hotSpotValue)
{
width = x_offset - curr_col - 1; // exclude end hotspot
break;
}
}
*countfromcol = x_offset + 1; /* ready for the next char*/
/*fill in the data structure - platform dependent*/
FillCharacterSlot(u, v, width, height, charnum, font);
return 0;
}
x_offset++;
} a
}
static int Process16BitEntry(PFFONT *font,
char* fontstartaddress,
int* countfromrow,
int* countfromcol,
int charnum)
{
int curr_row = *countfromrow;
int curr_col = *countfromcol;
int y_offset = 0, x_offset = curr_col;
GLOBALASSERT(font);
GLOBALASSERT(fontstartaddress);
GLOBALASSERT(charnum < font->num_chars_in_font);
GLOBALASSERT(curr_row < font->fttexHeight);
GLOBALASSERT(curr_col <= font->fttexWidth);
/*remember that all the corrdinates are done by pixels
find the x and y corrdinates of the left lower hotspot
we process each line (row) from startfromrow to the end
first find the next marker in startfromrow
*/
while(1)
{
// this bit processes the chars, finds uvs, extents and fills in the sturcture*/
// count along the row to find the next x position
unsigned int colour_here;
if(x_offset > font->fttexWidth - 1)
{
// reached the end of the line! reset x and then y
x_offset = 0;
curr_col = 0;
curr_row += font->fontHeight; // max line height
*countfromrow = curr_row;
GLOBALASSERT(curr_row < font->fttexHeight);
}
{
unsigned int colour_high = 0x000000ff & (unsigned int)*(fontstartaddress + (curr_row*font->fttexWidth + x_offset)*2);
unsigned int colour_low = 0x000000ff & (int)*(fontstartaddress + (curr_row*font->fttexWidth + x_offset)*2 + 1);
colour_here = (colour_high << 8) | colour_low;
}
if(colour_here == font->hotSpotValue)
{
int width = -1, height = -1;
/* set up the uv corrds of the top left corner*/
int u = x_offset + 1;
int v = curr_row + 1;
/* scan down to give height*/
for(y_offset = (curr_row + 1); y_offset < font->fttexHeight; y_offset++)
{
{
int colour_high = 0x000000ff & (int)*(fontstartaddress + (y_offset*font->fttexWidth + x_offset)*2);
int colour_low = 0x000000ff & (int)*(fontstartaddress + (y_offset*font->fttexWidth + x_offset)*2 + 1);
colour_here = (colour_high << 8) | colour_low;
}
if(colour_here == font->hotSpotValue)
{
height = y_offset - curr_row - 1; // -1 because we exclude the top and bottom hotspots
break;
}
}
/* scan along to get the width*/
for(++x_offset; x_offset < font->fttexWidth; x_offset ++)
{
{
int colour_high = 0x000000ff & (int)*(fontstartaddress + (curr_row*font->fttexWidth + x_offset)*2);
int colour_low = 0x000000ff & (int)*(fontstartaddress + (curr_row*font->fttexWidth + x_offset)*2 + 1);
colour_here = (colour_high << 8) | colour_low;
}
if(colour_here == font->hotSpotValue)
{
width = x_offset - curr_col - 1; // exclude end hotspot
break;
}
}
*countfromcol = x_offset + 1; /* ready for the next char*/
/*fill in the data structure - platform dependent*/
FillCharacterSlot(u, v, width, height, charnum, font);
return 0;
}
x_offset++;
}
return 0;
}
static int Process24BitEntry(PFFONT* font,
char* fontstartaddress,
int* countfromrow,
int* countfromcol,
int charnum)
{
return 0;
}
#endif
void BLTWholeFont(int fontnum, int x , int y, int win_width)
{
int i = 0;
int plotto_x = x, plotto_y = y;
while(i < AvpFonts[fontnum].num_chars_in_font)
{
int charwidth = AvpFonts[fontnum].srcRect[i].right - AvpFonts[fontnum].srcRect[i].left;
if((charwidth + plotto_x - x) > win_width)
{
plotto_y += AvpFonts[fontnum].fontHeight;
plotto_x= x;
}
BLTFontOffsetToHUD(&AvpFonts[fontnum], plotto_x, plotto_y, i);
plotto_x += charwidth + 1;
i++;
}
return;
}
void BLTString(FONT_DESC str_packet)
{
PFFONT font = AvpFonts[str_packet.fontnum];
unsigned char *strptr = str_packet.string;
int offset = 0;
int not_finished = Yes;
int pos_x = str_packet.destx;
int pos_y = str_packet.desty;
int white_space_width = CHAR_WIDTH(str_packet.fontnum, 0);
// set up the font processing varibles depending on the type of font
switch(font.font_type)
{
case(I_FONT_NUMERIC):
{
offset = 0x30;
break;
}
case(I_FONT_UC_NUMERIC):
{
offset = 0x20;
break;
}
case(I_FONT_UCLC_NUMERIC):
{
offset = 0x20;
break;
}
default:
GLOBALASSERT(2<1);
}
while(not_finished)
{
int line_length;
char *end_char;
// find the line length and the end char in the line
not_finished = ProcessLineLength
(
strptr, // start char of string
str_packet.fontnum, // the font we are using
offset, // the offset from the font
str_packet.width, // the width of the line
&end_char, // filled with end address
&line_length // filled with line length
);
// work out where to print the line
if(line_length)
{
switch(str_packet.just)
{
case FJ_LEFT_JUST:
{
pos_x = str_packet.destx;
break;
}
case FJ_CENTRED:
{
pos_x = str_packet.destx + ((str_packet.width - line_length) >> 1);
break;
}
case FJ_RIGHT_JUST:
{
pos_x = str_packet.destx + (str_packet.width - line_length);
break;
}
default:
{
;
}
}
// now print the line untill we reach the address of
// the end char
do
{
if(*strptr == ' ')
{
pos_x += white_space_width;
}
else if(*strptr == '\t')
{
pos_x += 4*white_space_width;
}
else if(*strptr == '\n' || strptr == 0x0)
{
GLOBALASSERT(strptr == end_char);
}
else if((int)*strptr == 0xD)
{
// carrige return
// do nothing - our next char should be '\n'
GLOBALASSERT(*(strptr + 1) == '\n');
}
else
{
extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
int end_pos = pos_x + CHAR_WIDTH(str_packet.fontnum, ((int)*strptr - offset));
int bottom_pos = pos_y + CHAR_HEIGHT(str_packet.fontnum, ((int)*strptr - offset));
if(end_pos > ScreenDescriptorBlock.SDB_Width || pos_x < 0)
{
//dont draw
//not_finished = No;
}
else if( bottom_pos > ScreenDescriptorBlock.SDB_Height || pos_y < 0)
{
not_finished = No;
}
else
{
pos_x += BLTFontOffsetToHUD
(
&font,
pos_x,
pos_y,
(int)*strptr - offset
);
pos_x ++; // to make space between letters
}
}
}
while(++strptr != end_char);
pos_y += font.fontHeight - 2;
}
strptr++;
}
}
/*
RWH - changes to font line processing
This function takes a pointer to a string a font and a width and
puts the length of the line into line_length AND puts the end char address into end_ch
It returns 0 when we have reached the end of a string
*/
int ProcessLineLength
(
char* start_ch, // start char of string
AVP_FONTS fontnum, // the font we are using
int offset, // the offset from the font
int max_width, // the width of the line
char** end_ch, // filled with end address
int* line_length
)
{
int continue_to_process_word = Yes;
int white_space_width = CHAR_WIDTH(fontnum, 0);
char *word_ptr = start_ch;
*line_length = 0;
if(start_ch == NULL)
{
*end_ch = NULL;
*line_length = 0;
return 0;
}
// first process any white space at the end of the
// line out
while(*start_ch == ' ')
{
// make sure we havent run out
// of chars to process
if(*start_ch == 0x0)
{
*end_ch = NULL;
*line_length = 0;
return 0;
}
start_ch++;
}
// Now we can start on the characters in the line
// note that we have to have two loops. The first
// continues untill we break out of it. The second
// adds up the length of each word and sees if the line
// with the new word will overrun the max_width
// the word_ptr points to the current char - it is only incremented
// when we can be sure that we can add the current letter to the word
while(1)
{
int word_length = 0;
continue_to_process_word = Yes;
while(continue_to_process_word)
{
// is the next char white space ?
// if so close the word
if(IS_CHAR_WHITE_SPACE(*(word_ptr + 1)))
{
// hit white space - finish this current word but only
// AFTER we have processed the current char
continue_to_process_word = No;
}
// need to process every white space seperately
if(*word_ptr == '\t')
{
// a one char word!
word_length = 4 * white_space_width;
continue_to_process_word = No;
word_ptr++;
}
else if(*word_ptr == 0x0)
{
// reached end of file - need to return 0
*end_ch = word_ptr;
return 0;
}
else if(*word_ptr == '\n')
{
*end_ch = word_ptr;
return 1;
}
else if(*word_ptr == ' ')
{
if(word_length)
{
// tag on the white space onto the word length
word_length += white_space_width;
}
// other wise keep on tiking on
word_ptr++;
}
else
{
// yeah add a letter to the word length
int char_off = (char)(*word_ptr - offset);
word_length += CHAR_WIDTH(fontnum, char_off);
word_length ++; //for space between lettes
word_ptr++; //process next char
}
}
// okay we have the length of this word - check to see if
// it overruns the end of the line - if it is too long,
// break out of the line loop
if((word_length + *line_length) >= max_width)
{
*end_ch = start_ch;
return 1;
}
else
{
*line_length += word_length;
// set up the next word save the beginning of teh word in start_ch
start_ch = word_ptr;
}
}
}

262
3dc/AvP_Alien_Readme.txt Normal file
View file

@ -0,0 +1,262 @@
***********************************************************************
ALIENS VERSUS PREDATOR
Alien Demo
Version 1.2
Readme File
Jan 20th 1999
***********************************************************************
CONTENTS
***********************************************************************
1. MINIMUM REQUIREMENTS
2. DEMO OBJECTIVES
3. INSTALLATION
4. GAME CONTROLS
5. ALIEN ABILITIES
6. ALIEN WEAPONS
7. CONTACT & LEGAL INFORMATION
***********************************************************************
1. MINIMUM REQUIREMENTS
***********************************************************************
Intel Pentium 200 MMX PC (or 100% compatible CPU)
DirectX supported 3D Accelerator Card
DirectX v.6 (Included on Installation CD)
32Mb RAM (64Mb recommended)
64Mb free Hard Drive
Windows 95
The ALIENS VERSUS PREDATOR Demo is a work in-progress. Thus it is not
fully optimized and configured for lower spec machines. These issues
will be corrected for the full retail version, giving the end user
control over engine and special effect variables ensuring smooth
gameplay over a wide variety of CPUs, accelerator cards and RAM.
Due to the complexity of the ALIENS VERSUS PREDATOR models, users with
32Mb of RAM may experience some memory paging, especially when exiting
the game and returning to Windows. These problems will be fixed for the
release version of the game.
KNOWN ISSUE WITH SOUNDBLASTER LIVE! CARDS:
Currently with SoundBlaster Live! cards, the EAX environmental
extensions are applied to all the audio being played from the CD.
While this does not necessarily interfere with the game; to stop
it from happening, follow these steps:
1. Access your Creative AudioHQ, usually found in
Start Menu --> Programs --> Creative--> Soundblaster Live! --> AudioHQ
2. Access the 'Environmental Audio' control applet
3. Click on the 'Options' tab within the Environmental Audio window.
4. Check the 'Always Save Changes Automatically' preference box.
5. Click the 'Source' tab.
6. Select the CD Digital source and set the Reverb & Chorus amounts
to 0%. Leave the Original Sound source at 100%.
7. Do the same with the CD Audio source. (Reverb & Chorus at 0%)
8. Click on 'Close' and you will be prompted to input a name for your
new settings. We suggest 'No CD effects' or similar.
9. You are now ready to play ALIENS VERSUS PREDATOR with normal CD
music. This issue should be resolved for the full release of the game.
***********************************************************************
2. DEMO OBJECTIVES
***********************************************************************
Playing as an Alien, you start in an Atmosphere Processor secured
by Colonial Marines. You must escape to the planet's surface to alert
the Hive. You must proceed with speed and stealth, and use guile to
disable and destroy those forces which you cannot attack head-on.
***********************************************************************
3. INSTALLATION
***********************************************************************
ALIENS VERSUS PREDATOR requires DirectX 6. This can be found within the
game's installation directory and you will be prompted to install it if
it is not on your system when you install the Demo.
To install the ALIENS VERSUS PREDATOR Demo, double click on Setup.exe
Follow the onscreen instructions.
ALIENS VERSUS PREDATOR dynamically streams FMV from your machine's
local hard-drive. This playback is greatly enhanced if the FMV files
are installed on a defragmented directory. We STRONGLY recommend
de-fragging your hard drive before installing ALIENS VERSUS PREDATOR.
To de-fragment your drive, either use the Windows95 accessory
'Disk Defragmenter' or any other 3rd party defragmentation utility.
Although the ALIENS VERSUS PREDATOR Demo will work with other
applications running in the background, for the best results it is
recommended that you run the game as a stand-alone application
(with no other applications running).
As well as avoiding possible conflicts from other applications, this
will also help prevent Windows from accessing the hard drive Virtual
Memory swap file, and affecting the speed and sound effects of the
game.
***********************************************************************
4. GAME CONTROLS
***********************************************************************
ALIENS VERSUS PREDATOR supports all DirectX compatible controllers. You
must install and set up these controllers before entering the game.
Other keys and mouse configurations can be defined either from the main
menu screen or from the in-game menus.
The default keys are:
UPARROW Forward
DOWNARROW Backward
LEFTARROW Strafe Left
RIGHTARROW Strafe Right
NUMPAD 4 Turn Left
NUMPAD 6 Turn Right
RIGHT_ALT Strafe
A Look Up
Z Look Down
S Centre View
LEFTSHIFT Walk
RIGHTCTRL Crouch/Climb
RIGHTSHIFT Jump
SPACE Operate
I Toggle between HUNT and NAVIGATION vision modes
The default mouse settings are full MouseLook.
The default mouse buttons are "Claw Attack" and "Tail Attack".
F8 Take screenshot (currently only 16bit video modes)
***********************************************************************
5. ALIEN ABILITIES
***********************************************************************
HEALTH
Health is displayed as the numerals in the top right of your screen.
When you are damaged, your screen will flash yellow from the sides.
Your health can be replenished by feeding on other lifeforms - see
JAW ATTACK in the ALIEN WEAPONS section.
ARMOR
The strength of the Alien's exoskeleton is displayed as the numerals
directly under HEALTH. As with HEALTH, damage to the exoskeleton can
be repaired by feeding on other lifeforms.
VISION MODES
The Alien has the ability to 'see' the world through two modes:
HUNTING and NAVIGATION. In HUNTING mode the Alien's senses are
attuned to searching for prey, whereas in NAVIGATION mode the
senses are concentrated on defining the surrounding environment.
MOVEMENT & CLIMBING
The Alien has the ability to move on any surface. Simply hold down
the 'Crouch/Climb' key whilst moving. When climbing, releasing the
key will release the Alien's grip and drop it to the floor. Using
the 'Jump' key while climbing will cause the Alien to pounce in the
direction it is looking.
***********************************************************************
6. ALIEN WEAPONS
***********************************************************************
CLAWS
Tapping or holding the 'Claw Attack' button triggers a flurry of
swipes and slashes. In the right circumstances the 'Claw Attack'
button can also trigger the secondary jaws.
JAW
The secondary jaws can be used to feed on other lifeforms, thus
replenishing HEALTH and ARMOR. Jaw attacks require a certain amount
of skill to achieve. When a target's head is close enough and in the
centre of the screen (the 'sweet-spot') the Alien's inner jaws will
become visible to indicate that a jaw attack is possible. Pressing
the 'Claw Attack' key will then launch the jaw attack.
N.B. Jaw attacking corpses provides less of a health/armor bonus than
live prey - assuming that the corpse still has a head. Try practicing
on unarmed personnel!
TAIL
Tapping 'Tail Attack' causes a quick, low power, jab, whereas holding
down the 'Tail Attack' button readies the tail for a more powerful
strike. The tail will automatically target any prey in front of the
Alien.
***********************************************************************
7. CONTACT & LEGAL INFORMATION
***********************************************************************
CONTACT INFORMATION
For more information, or to communicate with us with regards to this or
any Fox Interactive product, please consult our Worldwide Web site at:
http://www.foxinteractive.com
...or for questions/technical issues send us an email at:
avp@fox.com
LEGAL INFORMATION
ALIENS VERSUS PREDATOR is published by Fox Interactive and developed
by Rebellion Developments, Ltd.
ALIENS TM & (c) 1986, 1998 Twentieth Century Fox Film Corporation.
PREDATOR TM & (c) 1987, 1998 Twentieth Century Fox Film Corporation.
ALIENS VERSUS PREDATOR TM & (c) 1998 Twentieth Century Fox Film
Corporation. All Rights Reserved. "Aliens," "Predator," "Fox," and
"Fox Interactive" and their associated logos are the property of
Twentieth Century Fox Film Corporation. All Rights Reserved.
***********************************************************************

284
3dc/AvP_Marine_Readme.txt Normal file
View file

@ -0,0 +1,284 @@
***********************************************************************
ALIENS VERSUS PREDATOR
Marine Demo
Version 1.0
Readme File
Nov 23rd 1998
***********************************************************************
CONTENTS
***********************************************************************
1. MINIMUM REQUIREMENTS
2. DEMO OBJECTIVES
3. INSTALLATION
4. GAME CONTROLS
5. MARINE EQUIPMENT
6. MARINE WEAPONRY
7. CONTACT & LEGAL INFORMATION
***********************************************************************
1. MINIMUM REQUIREMENTS
***********************************************************************
Intel Pentium 200 MMX PC (or 100% compatible CPU)
DirectX supported 3D Accelerator Card
DirectX v.6 (Included on Installation CD)
32Mb RAM (64Mb recommended)
64Mb free Hard Drive
Windows 95
The ALIENS VERSUS PREDATOR Demo is a work in-progress. Thus it is not
fully optimised and configured for lower spec machines. These issues
will be corrected for the full retail version, giving the end user
control over engine and special effect variables ensuring smooth
gameplay over a wide variety of CPUs, accelerator cards and RAM.
Due to the complexity of the ALIENS VERSUS PREDATOR models, users with
32Mb of RAM may experience some memory paging, especially when exiting
the game and returning to Windows. These problems will be fixed for the
release version of the game.
KNOWN ISSUE WITH SOUNDBLASTER LIVE! CARDS:
Currently with SoundBlaster Live! cards, the EAX environmental
extensions are applied to all the audio being played from the CD.
While this does not necessarily interfere with the game; to stop
it from happening, follow these steps:
1. Access your Creative AudioHQ, usually found in
Start Menu --> Programs --> Creative--> Soundblaster Live! --> AudioHQ
2. Access the 'Environmental Audio' control applet
3. Click on the 'Options' tab within the Environmental Audio window.
4. Check the 'Always Save Changes Automatically' preference box.
5. Click the 'Source' tab.
6. Select the CD Digital source and set the Reverb & Chorus amounts
to 0%. Leave the Original Sound source at 100%.
7. Do the same with the CD Audio source. (Reverb & Chorus at 0%)
8. Click on 'Close' and you will be prompted to input a name for your
new settings. We suggest 'No CD effects' or similar.
9. You are now ready to play ALIENS VERSUS PREDATOR with normal CD
music. This issue should be resolved for the full release of the game.
***********************************************************************
2. DEMO OBJECTIVES
***********************************************************************
As the Marine, you are the last surviving member of your squad. Your
mission was to explore and investigate the Atmosphere Processor, then
destroy it. You were to remain as guard inside the APC... until your
squad were brutally massacred by forces unknown. Your mission is now
to survive and follow the instructions beamed down to you from your
mission commander from his support ship in low orbit.
***********************************************************************
3. INSTALLATION
***********************************************************************
ALIENS VERSUS PREDATOR requires DirectX 6. This can be found within the
game's installation directory and you will be prompted to install it if
it is not on your system when you install the Demo.
To install the ALIENS VERSUS PREDATOR Demo, double click on Setup.exe
Follow the onscreen instructions.
ALIENS VERSUS PREDATOR dynamically streams FMV from your machine's
local hard-drive. This playback is greatly enhanced if the FMV files
are installed on a defragmented directory. We STRONGLY recommend
de-fragging your hard drive before installing ALIENS VERSUS PREDATOR.
To de-fragment your drive, either use the Windows95 accessory
'Disk Defragmenter' or any other 3rd party defragmentation utility.
Although the ALIENS VERSUS PREDATOR Demo will work with other
applications running in the background, for the best results it is
recommended that you run the game as a stand-alone application
(with no other applications running).
As well as avoiding possible conflicts from other applications, this
will also help prevent Windows from accessing the hard drive Virtual
Memory swap file, and affecting the speed and sound effects of the
game.
***********************************************************************
4. GAME CONTROLS
***********************************************************************
ALIENS VERSUS PREDATOR supports all DirectX compatible controllers. You
must install and set up these controllers before entering the game.
Other keys and mouse configurations can be defined either from the main
menu screen or from the in-game menus.
The default keys are:
UPARROW Forward
DOWNARROW Backward
LEFTARROW Strafe Left
RIGHTARROW Strafe Right
NUMPAD 4 Turn Left
NUMPAD 6 Turn Right
RIGHT_ALT Strafe
A Look Up
Z Look Down
S Centre View
LEFTSHIFT Walk
RIGHTSHIFT Jump
SPACE Operate
I Toggle Image Intensifier
Q Next Weapon
W Previous Weapon
L Throw Flare
BACKSPACE Flashback weapon (switches to previous held)
The default mouse settings are full MouseLook.
The default mouse buttons are fire primary and fire secondary.
***********************************************************************
5. MARINE EQUIPMENT
***********************************************************************
HEALTH
Health is displayed as green numerals in the top right of your screen.
When you are damaged, your screen will flash red from the sides. Your
health can be replenished from healthpacks your comrades have dropped
in various levels of the Atmosphere Processor.
ARMOR
Armor protects you from both acid blood and other forms of damage. It
is displayed beneath the health numerals as a percentage. You may don
extra armor if you find it.
IMAGE INTENSIFIER
All Colonial Marines are equipped with image intensification optics.
Once activated your vision is augmented for low light conditions, thus
allowing you to see even in pitch darkness. You may use the Intensifier
at will, although it does temporarily burn-out if you are near a strong
light source (such as your weapon firing).
FLARES
You come equipped with small phosphorus flares that you may throw to
light your way. These will stick to any surface and provide a strong
yet temporary light, as well as a deal of smoke. Flares and your
Image Intensifier naturally do not mix well.
***********************************************************************
6. MARINE WEAPONS
***********************************************************************
PULSERIFLE (slot 1)
A Colonial Marine's standard weapon, combining a powerful assault rifle
with an under and over grenade launcher. It carries 99 rounds in the
magazine - watch for reloads! The number of grenades it can carry are
limited - look for your companion's old pulserifles for reloads.
The PulseRifle is less accurate if you are moving whilst firing.
SMARTGUN (slot 2)
A mobile Colonial Marine's most powerful weapon, the SmartGun is a
masterpiece of technology. Mounted on a gyroscopic harness, it literally
aims itself, targeting the centre of mass. It is linked to the marine's
Head Up Display - once it has acquired a target the recticle turns red
and begins to track. To fully use a SmartGun, the operator must watch
where the gun wishes to move and lead it manually - this drastically
decreases aiming time. Smartguns are less useful against smaller, more
agile targets. The smartgun is belt-fed from a large magazine mounted
on the harness, so rarely runs out of ammunition. Care should be taken
as the armour piercing bullets from the SmartGun will deal with most
targets in an explosive manner - short bursts will be sufficient to
deal with almost any foe.
FLAMETHROWER (Slot 3)
The Flamethrower is specifically designed as a close-combat weapon for
the clearing of areas. It is somewhat inaccurate, but the jet of napalm
will eventually kill anything it ignites. Keep the jet trained on a
target to inflict more direct damage.
The flamethrower runs out of fuel in a very short space of time - short
controlled bursts are the most economical method of firing.
WARNING! The napalm fired from the flamethrower is dangerous - do NOT
run forwards whilst firing (walking is OK) else you will set yourself
on fire. Additionally, it is possible that the napalm will 'bounce' off
a surface and back onto the user. However, nothing is more effective
than the flamethrower when exterminating vermin.
***********************************************************************
7. CONTACT & LEGAL INFORMATION
***********************************************************************
CONTACT INFORMATION
For more information, or to communicate with us with regards to this or
any Fox Interactive product, please consult our Worldwide Web site at:
http://www.foxinteractive.com
...or for questions/technical issues send us an email at:
avp@fox.com
LEGAL INFORMATION
ALIENS VERSUS PREDATOR is published by Fox Interactive and developed
by Rebellion Developments, Ltd.
ALIENS TM & (c) 1986, 1998 Twentieth Century Fox Film Corporation.
PREDATOR TM & (c) 1987, 1998 Twentieth Century Fox Film Corporation.
ALIENS VERSUS PREDATOR TM & (c) 1998 Twentieth Century Fox Film
Corporation. All Rights Reserved. "Aliens," "Predator," "Fox," and
"Fox Interactive" and their associated logos are the property of
Twentieth Century Fox Film Corporation. All Rights Reserved.
***********************************************************************

264
3dc/AvP_Predator_Readme.txt Normal file
View file

@ -0,0 +1,264 @@
***********************************************************************
ALIENS VERSUS PREDATOR
Predator Demo
Version 1.3
Readme File
Oct 22nd 1998
***********************************************************************
CONTENTS
***********************************************************************
1. MINIMUM REQUIREMENTS
2. DEMO OBJECTIVES
3. INSTALLATION
4. GAME CONTROLS
5. PREDATOR EQUIPMENT
6. PREDATOR WEAPONRY
7. CONTACT & LEGAL INFORMATION
***********************************************************************
1. MINIMUM REQUIREMENTS
***********************************************************************
Intel Pentium 200 MMX PC (or 100% compatible CPU)
DirectX supported 3D Accelerator Card
DirectX v.6 (Included on Installation CD)
32Mb RAM (64Mb reccommended)
64Mb free Hard Drive
Windows 95
The ALIENS VERSUS PREDATOR Demo is a work in-progress. Thus it is not
fully optimised and configured for lower spec machines. These issues
will be corrected for the full retail version, giving the end user
control over engine and special effect variables ensuring smooth
gameplay over a wide variety of CPUs, accelerator cards and RAM.
Due to the complexity of the ALIENS VERSUS PREDATOR models, users with
32Mb of RAM may experience some memory paging, especially when exiting
the game and returning to Windows. These problems will be fixed for the
release version of the game.
***********************************************************************
2. DEMO OBJECTIVES
***********************************************************************
As the Predator, you must descend through an Alien-infested Atmosphere
Processor to eliminate the Marines who are defending an APC at the base
of the structure. Your weapons are Wrist-blades, Speargun and shoulder
mounted Plasmacaster. You also possess an emergency medical kit.
***********************************************************************
3. INSTALLATION
***********************************************************************
ALIENS VERSUS PREDATOR requires DirectX 6. This can be found within the
game's installation directory and you will be prompted to install it if
it is not on your system when you install the Demo.
To install the ALIENS VERSUS PREDATOR Demo, double click on Setup.exe
Follow the onscreen instructions.
ALIENS VERSUS PREDATOR dynamically streams FMV from your machine's
local hard-drive. This playback is greatly enhanced if the FMV files
are installed on a defragmented directory. We STRONGLY recommend
de-fragging your hard drive before installing ALIENS VERSUS PREDATOR.
To de-fragment your drive, either use the Windows95 accessory
'Disk Defragmenter' or any other 3rd party defragmentation utility.
Although the ALIENS VERSUS PREDATOR Demo will work with other
Applications running in the background, for the best results it is
recommended that you run the game as a stand-alone application
(with no other applications running).
As well as avoiding possible conflicts from other applications, this
will also help prevent Windows from accessing the hard drive Virtual
Memory swap file, and affecting the speed and sound effects of the
game.
***********************************************************************
4. GAME CONTROLS
***********************************************************************
ALIENS VERSUS PREDATOR supports all DirectX compatible controllers. You
must install and set up these controllers before entering the game.
Other keys and mouse configurations can be defined either from the main
menu screen or from the in-game menus.
The default keys are:
UPARROW Forward
DOWNARROW Backward
LEFTARROW Strafe Left
RIGHTARROW Strafe Right
NUMPAD 4 Turn Left
NUMPAD 6 Turn Right
RIGHT_ALT Strafe
A Look Up
Z Look Down
S Centre View
LEFTSHIFT Walk
RIGHTSHIFT Jump
SPACE Operate
I Toggle Cloaking
Q Next Weapon
W Previous Weapon
PAGEUP Zoom In
PAGEDOWN Zoom Out
L Cycle Vision Modes
The default mouse settings are full MouseLook.
The default mouse buttons are fire primary and fire secondary.
***********************************************************************
5. PREDATOR EQUIPMENT
***********************************************************************
HEALTH
Health is displayed as a vertical red bar on the left hand side of the
screen. As the Predator is wounded, these digits are removed from the
bottom up. When health is low, the Predator should use the MediComp.
The Predator has no Health pick-ups in ALIENS VERSUS PREDATOR.
FIELD CHARGE
All of the Predator's weapons and equipment run off the Predator's
Field Charge, a general measure of power. This is displayed as a
vertical blue bar on the right hand side of the screen. The Predator
can find extremely limited amounts of Field Charge in the Demo.
Field Charge is drained by a number of the Predator's abilities,
which are listed below:
Healing. The MediComp (q.v.) is expensive to run.
Plasmacaster. This can drain however much is required.
Cloaking. Both a chunk to enter cloak and a small permanent drain.
CLOAKING
The Predator has the ability to 'bend light' around itself. This can
render it almost invisible under most lighting conditions unless it
gives it's position away. Unfortunately, the Xenomorph species does
not use light to detect it's prey, so cloaking is not effective.
Whilst in cloak, the Predator sees the world differently as the
light is processed for his vision.
Entering cloak is costly for Field Charge.
VISION MODES
There are two vision modes available in this demo - Thermal and
Electro-magnetic. Thermal vision shows up Humans as bright red and
yellow heat sources, while the rest of the world is cold and blue.
Electro-magnetic vision displays the Aliens clearly, whilst failing
to pick up on the human targets. Some of the Predator's abilities
depend on picking the correct vision modes.
***********************************************************************
6. PREDATOR WEAPONS
***********************************************************************
WRISTBLADES (slot 1)
A set of lethal razor-sharp blades mounted on the Predator's right
wrist. Use Primary Fire to perform a quick jab. Use Secondary Fire to
pull back and charge up a high-powered swipe. The Predator may use the
wristblades while cloaked.
SPEARGUN (slot 3)
A high-velocity harpoon-style weapon, this fires a jagged bolt of metal
capable of ripping parts off the Predator's enemies. The extreme power
is tempered by the slow rate-of-fire and the fact that Aliens can easily
survive traumatic injuries. Ammunition is limited and the use of this
weapon de-activates the Predator's cloaking.
PLASMACASTER (slot 4)
The Predator's most effective weapon is computer-controlled from the
wrist console. It has it's own charge meter (found on the Wrist Console
as a small red bar) which displays how much power is contained within
the blast. This can be charged either by Primary Fire and upon release
the bolt is fired, or can have charge stored within it via the use of
Secondary Fire.
The Plasmacaster is fully auto-tracking, locking onto a target in
seconds as long as it remains within view. The Plasmacaster can only
target enemies if fired from the Predator's correct vision mode for
that species.
MEDICOMP (Slot 6)
Not really a weapon, the MediComp is the Predator's only hope of
regaining health while in combat. It is extremely expensive of
Field Charge and takes some time to use, during which the Predator
is effectively defenseless. It is therefore important to use it during
lulls in combat.
Primary fire begins the healing sequence.
Secondary fire activates the Predator's fire-damping abilities should
it unfortunately be caught by a flamethrower or incendiary. This is
far less expensive than a full heal.
***********************************************************************
7. CONTACT & LEGAL INFORMATION
***********************************************************************
CONTACT INFORMATION
For more information, or to communicate with us with regards to this or
any Fox Interactive product, please consult our Worldwide Web site at:
http://www.foxinteractive.com
LEGAL INFORMATION
ALIENS T & c 1986, 1998 Twentieth Century Fox Film Corporation.
PREDATOR T & c 1987, 1998 Twentieth Century Fox Film Corporation.
ALIENS VERSUS PREDATOR T & c 1998 Twentieth Century Fox Film
Corporation. All Rights Reserved. "Aliens," "Predator," "Fox," and
"Fox Interactive" and their associated logos are the property of
Twentieth Century Fox Film Corporation. All Rights Reserved.
***********************************************************************

278
3dc/AvP_Readme+Credits.txt Normal file
View file

@ -0,0 +1,278 @@
***********************************************************************
Fox Interactive presents
A Rebellion Game
***********************************************************************
Aliens Versus Predator
Predator Demo
Version 1.0
Readme File
10/16/98
***********************************************************************
CONTENTS
***********************************************************************
1. MINIMUM REQUIREMENTS
2. DEMO OBJECTIVES
3. INSTALLATION
4. GAME CONTROLS
5. PREDATOR EQUIPMENT
6. PREDATOR WEAPONRY
7. CREDITS
***********************************************************************
1. MINIMUM REQUIREMENTS
***********************************************************************
P200 MMX PC
Intel or 100% compatible CPU
DirectX supported 3D Accelerator Card
DirectX v.6 (Included on Installation CD)
32Mb RAM
Windows 95
The Aliens Versus Predator Demo is a work in-progress. Thus it is not
fully optimised and configured for lower spec machines. These issues
will be corrected for the full retail version, giving the end user
control over engine and special effect variables ensuring smooth
gameplay over a wide variety of CPUs, accelerator cards and RAM.
***********************************************************************
2. DEMO OBJECTIVES
***********************************************************************
As the Predator, you must descend through an Alien-infested Atmosphere
Processor to eliminate the Marines who are defending an APC at the base
of the structure. Your weapons are Wrist-blades, Speargun and shoulder
mounted Plasmacaster. You also possess an emergency medical kit.
***********************************************************************
3. INSTALLATION
***********************************************************************
To install the Aliens Versus Predator Demo, double click on Setup.exe
Follow the onscreen instructions.
Aliens Versus Predator dynamically streams FMV from your machine's
local hard-drive. This playback is greatly enhanced if the FMV files
are installed on a defragmented directory. We STRONGLY reccomend
de-fragging your hard drive before installing Aliens Versus Predator.
To de-fragment your drive, either use the Windows95 accessory
'Disk Defragmenter' or any other 3rd party defragmentation utility.
***********************************************************************
4. GAME CONTROLS
***********************************************************************
Aliens Versus Predator supports all DirectX compatible controllers. You
must install and set up these controllers before entering the game.
Other keys and mouse configurations can be defined either from the main
menu screen or from the in-game menus.
The default keys are:
UPARROW Forward
DOWNARROW Backward
LEFTARROW Strafe Left
RIGHTARROW Strafe Right
NUMPAD 4 Turn Reft
NUMPAD 6 Turn Right
RIGHT_ALT Strafe
A Look Up
Z Look Down
S Centre View
LEFTSHIFT Walk
RIGHTSHIFT Jump
SPACE Operate
I Toggle Cloaking
Q Next Weapon
W Previous Weapon
PAGEUP Zoom In
PAGEDOWN Zoon Out
L Cycle Vision Modes
The default mouse settings are full mouselook.
The default mouse buttons are fire primary and fire secondary.
***********************************************************************
5. PREDATOR EQUIPMENT
***********************************************************************
HEALTH
Health is displayed as a vertical red bar on the left hand side of the
screen. As the Predator is wounded, these digits are removed from the
bottom up. When health is low, the Predator should use the Medicomp.
The Predator has no Health pick-ups in Aliens Versus Predator.
FIELD CHARGE
All of the Predator's weapons and equipment run off the predator's
Field Charge, a general measure of power. This is displayed as a
vertical blue bar on the right hand side of the screen. The Predator
can find extremely limited amounts of Field Charge in the Demo.
Field Charge is drained by a number of the Predator's abilities,
which are listed below:
Healing. The Medicomp (qv) is expensive to run.
Plasmacaster. This can drain however much is required.
Cloaking. Both a chunk to enter cloak and a small permanent drain.
CLOAKING
The Predator has the ability to 'bend light' around itself. This can
render it almost invisible under most lighting conditions unless it
gives it's position away. Unfortunately, the Xenomorph species does
not use light to detect it's prey, so cloaking is not effective.
Whilst in cloak, the Predator sees the world differently as the
light is processed for his vision.
Entering cloak is costly for Field Charge.
VISION MODES
There are two vision modes available in this demo - Thermal and
Electro-magnetic. Thermal vision shows up Humans as bright red and
yellow heat sources, while the rest of the world is cold and blue.
Electro-magnetic vision displays the Aliens clearly, whilst failing
to pick up on the human targets. Some of the Predator's abilities
depend on picking the correct vision modes.
***********************************************************************
6. PREDATOR WEAPONS
***********************************************************************
WRISTBLADES (slot 1)
A set of lethal razor-sharp blades mounted on the Predator's right
wrist. Use Primary Fire to perform a quick jab. Use Secondary Fire to
pull back and charge up a high-powered swipe. The Predator may use the
wristblades while cloaked.
SPEARGUN (slot 3)
A high-velocity harpoon-style weapon, this fires a jagged bolt of metal
capable of ripping parts off the Predator's enemies. The extreme power
is tempered by the slow rate-of-fire and the fact that Aliens can easily
survive traumatic injuries. Ammunition is limited and the use of this
weapon de-activates the Predator's cloaking.
PLASMACASTER (slot 4)
The Predator's most effective weapon is computer-controlled from the
wrist console. It has it's own charge meter (found on the Wrist Console
as a small red bar) which displays how much power is contained within
the blast. This can be charged either by Primary Fire and upon release
the bolt is fired, or can have charge stored within it via the use of
Secondary Fire.
The Plasmacaster is fully auto-tracking, locking onto a target in
seconds as long as it remains within view. The Plasmacaster can only
target enemies if fired from the Predator's correct vision mode for
that species.
MEDICOMP (Slot 6)
Not really a weapon, the Medicomp is the Predator's only hope of
regaining health while in combat. It is extremely expensive of
Field Charge and takes some time to use, during which the Predator
is effectively defenseless. It is therefore important to use it during
lulls in combat.
Primary fire begins the healing sequence.
Secondary fire activates the Predator's fire-damping abilities should
it unfortunately be caught by a flamethrower or incendiary. This is
far less expensive than a full heal.
***********************************************************************
7. CREDITS
***********************************************************************
REBELLION CREDITS
Creative Director Jason Kingsley
Technical Director Chris Kingsley
Lead Programmer Kevin Lea
AI Programmer Chris Fox
Tools Programmer Richard Rice
Additional Programming Jake Hotson
Dave Wall
Producer Alastair Halsby
Level Design Julian Breddy
Ed Cookson
Adam Comiskey
Joe Gelder
Alastair Halsby
Tim Jones
Level Texturemaps Julian Breddy
Ed Cookson
Adam Comiskey
Joe Gelder
Alastair Halsby
Tim Jones
Matthew Riordan
Character Models
& Animation Ken Turner
Adam Comiskey
Character Texturemaps Alastair Halsby
Tim Jones
Ken Turner
Adam Comiskey
Sound Ed Cookson
Tim Jones
Alastair Halsby
Thanks To:
Patrick Dickinson, George Launchbury, Jake Hempson, John Bryden,
Andy Nixon, Will Davis, Shelagh Lewins, Luke Harman, Dan Mitchell,
Lee Brimmicombe-Wood, Sophie Mobbs, Bernard H. Wood and Paul Topping.
FOX INTERACTIVE CREDITS

226
3dc/AvP_Readme.txt Normal file
View file

@ -0,0 +1,226 @@
***********************************************************************
Fox Interactive presents
A Rebellion Game
***********************************************************************
Aliens Versus Predator
Predator Demo
Version 1.0
Readme File
10/16/98
***********************************************************************
CONTENTS
***********************************************************************
1. MINIMUM REQUIREMENTS
2. DEMO OBJECTIVES
3. INSTALLATION
4. GAME CONTROLS
5. PREDATOR EQUIPMENT
6. PREDATOR WEAPONRY
***********************************************************************
1. MINIMUM REQUIREMENTS
***********************************************************************
P200 MMX PC
Intel or 100% compatible CPU
DirectX supported 3D Accelerator Card
DirectX v.6 (Included on Installation CD)
32Mb RAM
Windows 95
The Aliens Versus Predator Demo is a work in-progress. Thus it is not
fully optimised and configured for lower spec machines. These issues
will be corrected for the full retail version, giving the end user
control over engine and special effect variables ensuring smooth
gameplay over a wide variety of CPUs, accelerator cards and RAM.
***********************************************************************
2. DEMO OBJECTIVES
***********************************************************************
As the Predator, you must descend through an Alien-infested Atmosphere
Processor to eliminate the Marines who are defending an APC at the base
of the structure. Your weapons are Wrist-blades, Speargun and shoulder
mounted Plasmacaster. You also possess an emergency medical kit.
***********************************************************************
3. INSTALLATION
***********************************************************************
To install the Aliens Versus Predator Demo, double click on Setup.exe
Follow the onscreen instructions.
Aliens Versus Predator dynamically streams FMV from your machine's
local hard-drive. This playback is greatly enhanced if the FMV files
are installed on a defragmented directory. We STRONGLY reccomend
de-fragging your hard drive before installing Aliens Versus Predator.
To de-fragment your drive, either use the Windows95 accessory
'Disk Defragmenter' or any other 3rd party defragmentation utility.
***********************************************************************
4. GAME CONTROLS
***********************************************************************
Aliens Versus Predator supports all DirectX compatible controllers. You
must install and set up these controllers before entering the game.
Other keys and mouse configurations can be defined either from the main
menu screen or from the in-game menus.
The default keys are:
UPARROW Forward
DOWNARROW Backward
LEFTARROW Strafe Left
RIGHTARROW Strafe Right
NUMPAD 4 Turn Reft
NUMPAD 6 Turn Right
RIGHT_ALT Strafe
A Look Up
Z Look Down
S Centre View
LEFTSHIFT Walk
RIGHTSHIFT Jump
SPACE Operate
I Toggle Cloaking
Q Next Weapon
W Previous Weapon
PAGEUP Zoom In
PAGEDOWN Zoon Out
L Cycle Vision Modes
The default mouse settings are full mouselook.
The default mouse buttons are fire primary and fire secondary.
***********************************************************************
5. PREDATOR EQUIPMENT
***********************************************************************
HEALTH
Health is displayed as a vertical red bar on the left hand side of the
screen. As the Predator is wounded, these digits are removed from the
bottom up. When health is low, the Predator should use the Medicomp.
The Predator has no Health pick-ups in Aliens Versus Predator.
FIELD CHARGE
All of the Predator's weapons and equipment run off the predator's
Field Charge, a general measure of power. This is displayed as a
vertical blue bar on the right hand side of the screen. The Predator
can find extremely limited amounts of Field Charge in the Demo.
Field Charge is drained by a number of the Predator's abilities,
which are listed below:
Healing. The Medicomp (qv) is expensive to run.
Plasmacaster. This can drain however much is required.
Cloaking. Both a chunk to enter cloak and a small permanent drain.
CLOAKING
The Predator has the ability to 'bend light' around itself. This can
render it almost invisible under most lighting conditions unless it
gives it's position away. Unfortunately, the Xenomorph species does
not use light to detect it's prey, so cloaking is not effective.
Whilst in cloak, the Predator sees the world differently as the
light is processed for his vision.
Entering cloak is costly for Field Charge.
VISION MODES
There are two vision modes available in this demo - Thermal and
Electro-magnetic. Thermal vision shows up Humans as bright red and
yellow heat sources, while the rest of the world is cold and blue.
Electro-magnetic vision displays the Aliens clearly, whilst failing
to pick up on the human targets. Some of the Predator's abilities
depend on picking the correct vision modes.
***********************************************************************
6. PREDATOR WEAPONS
***********************************************************************
WRISTBLADES (slot 1)
A set of lethal razor-sharp blades mounted on the Predator's right
wrist. Use Primary Fire to perform a quick jab. Use Secondary Fire to
pull back and charge up a high-powered swipe. The Predator may use the
wristblades while cloaked.
SPEARGUN (slot 3)
A high-velocity harpoon-style weapon, this fires a jagged bolt of metal
capable of ripping parts off the Predator's enemies. The extreme power
is tempered by the slow rate-of-fire and the fact that Aliens can easily
survive traumatic injuries. Ammunition is limited and the use of this
weapon de-activates the Predator's cloaking.
PLASMACASTER (slot 4)
The Predator's most effective weapon is computer-controlled from the
wrist console. It has it's own charge meter (found on the Wrist Console
as a small red bar) which displays how much power is contained within
the blast. This can be charged either by Primary Fire and upon release
the bolt is fired, or can have charge stored within it via the use of
Secondary Fire.
The Plasmacaster is fully auto-tracking, locking onto a target in
seconds as long as it remains within view. The Plasmacaster can only
target enemies if fired from the Predator's correct vision mode for
that species.
MEDICOMP (Slot 6)
Not really a weapon, the Medicomp is the Predator's only hope of
regaining health while in combat. It is extremely expensive of
Field Charge and takes some time to use, during which the Predator
is effectively defenseless. It is therefore important to use it during
lulls in combat.
Primary fire begins the healing sequence.
Secondary fire activates the Predator's fire-damping abilities should
it unfortunately be caught by a flamethrower or incendiary. This is
far less expensive than a full heal.
***********************************************************************

77
3dc/CD Tracks.txt Normal file
View file

@ -0,0 +1,77 @@
;CD track list
;Only lines starting with a # are looked at.
;After the # a list of cd track numbers should be provided
;All track numbers for a give level must appear on one line
;Any symbol can be used to seperate the numbers (Other than ;) , I'm using commas.
;Anything coming after a semicolon is ignored
;Default tracks for each character.
;Used in multiplayer games , or if no tracks have been assigned
;to a level
# 1,2,3,4,5 ;Marine
# 6,7,8,9,10 ;Predator
# 11,12,13,14,15 ;Alien
;Cd tracks assigned to each level
;Marine
# 2 ; AVP_ENVIRONMENT_DERELICT,
# 1 ; AVP_ENVIRONMENT_COLONY,
# 4 ; AVP_ENVIRONMENT_INVASION,
# 3 ; AVP_ENVIRONMENT_ORBITAL,
# 5 ; AVP_ENVIRONMENT_TYRARGO,
# 5 ; AVP_ENVIRONMENT_TYRARGOHANGAR,
;Predator
# 7 ; AVP_ENVIRONMENT_WATERFALL,
# 6 ; AVP_ENVIRONMENT_AREA52,
# 8 ; AVP_ENVIRONMENT_VAULTS,
# 10 ; AVP_ENVIRONMENT_FURY161,
# 9 ; AVP_ENVIRONMENT_CAVERNS,
# 9 ; AVP_ENVIRONMENT_CAVERNSEND,
;Alien
# 11 ; AVP_ENVIRONMENT_FERARCO,
# 12 ; AVP_ENVIRONMENT_TEMPLE,
# 13 ; AVP_ENVIRONMENT_GATEWAY,
# 14 ; AVP_ENVIRONMENT_ESCAPE,
# 15 ; AVP_ENVIRONMENT_EARTHBOUND,
;Multiplayer part 1(ignored , but leave the same number of #'s)
# ;
# ;
# ;
# ;
# ;
;Alien bonus
# ; AVP_ENVIRONMENT_INVASION_A,
# ; AVP_ENVIRONMENT_DERELICT_A,
# ; AVP_ENVIRONMENT_TYRARGO_A,
# ; AVP_ENVIRONMENT_FURY161_A,
# ; AVP_ENVIRONMENT_CAVERNS_A,
;Predator bonus
# ; AVP_ENVIRONMENT_INVASION_P,
# ; AVP_ENVIRONMENT_TYRARGO_P,
# ; AVP_ENVIRONMENT_TEMPLE_P,
# ; AVP_ENVIRONMENT_ESCAPE_P,
# ; AVP_ENVIRONMENT_EARTHBOUND_P,
;Marine bonus
# ; AVP_ENVIRONMENT_WATERFALL_M,
# ; AVP_ENVIRONMENT_VAULTS_M,
# ; AVP_ENVIRONMENT_FERARCO_M,
# ; AVP_ENVIRONMENT_TEMPLE_M,
# ; AVP_ENVIRONMENT_GATEWAY_M,
;Multiplayer part 2(ignored , but leave the same number of #'s)
# ;
# ;
# ;
# ;
# ;
# ;

340
3dc/CREDITS.txt Normal file
View file

@ -0,0 +1,340 @@
}Fox Interactive Presents
}Aliens Versus Predator
}Gold Edition
}Fox Interactive
}-------------
Producer|David Stalker
Senior Associate Producer|Chris Miller
Associate Producer|Aaron Blean
}Fox QA Department
QA Manager|David Ortiz
QA Lead|Igor Krinitsky
QA Co-Lead|Chris Wilson
Testers|Arabian
|Aron Ahles
|Ken Anderson
|Eric Asevo
|Sweet Billy
|Ben Borth
|Pete Cesario
|Francis Choi
|Kristian Davila
|Matt Dell
|Ryan Dowling
|Michael Dunn
|Tim Hall
|Tim Harrison
|Judd Hollander
|Kevin Huynh
|Cris Lee
|Jeremy Luyties
|Red Magpantay
|Kerry Marshall
|Young Park
|Kyle Peschel
|Harish Rao
|Don Sexton
|Gabe Slater
|Jeff Tatman
|Luke Thai
|Tim Tran
|Daan Wisehart
|Sung Yoo
|Brian Zenns
}Rebellion
}-------
Creative Director|Jason Kingsley
Technical Director|Chris Kingsley
Senior Producer|Mark Eyles
Production Manager|Graeme Williams
Technology Manager|Kevin Lea
Producer & Lead Artist|Tim Jones
Network Code & Tools Programmer|Richard Rice
Art|Julian Breddy
|Ed Cookson
|Dominic Jeffery
|Tim Jones
|Ken Turner
Sound|Ed Cookson
Additional Sound|Julian Breddy
|Dominic Jeffery
|Tim Jones
Thanks to|Al Halsby
|Chris Fox
|Jessica Sharp
|Nadia Cocklin
|Harry Harris
|April Chung
|Anna Floyer
|Siobhan Boughton
|Helen Szirtes
|Christian Russell
|Phil Moss
|Matt Black
|The Special K Massive (Big up stylee!)
}Gold Edition FMVs
Cast|Ed Cookson
|Aeron Guy
|Mike Healey
|Ben Jones
|Tim Jones
|Chris Kingsley
|Ed Niblett
|Ken Turner
Creative Director and Lighting|Jason Kingsley
Direction|Ed Cookson
|Tim Jones
|Ken Turner
Editing and Sound Effects|Ed Cookson
|Ken Turner
Special Effects|Ken, Ben, Ed C and Tim
Thanks to|Everyone at Rebellion who gave up their weekend
}Aliens Versus Predator
}Fox Interactive
}-------------
Producer|David Stalker
Associate Producer|Chris Miller
Music Composition|Rich Ragsdale
Sound Effects|Jered C. Miller
}Fox QA Department
QA Manager|Mike Schneider
QA Lead|Aaron Blean
Testers|Seth Roth
|Ken Anderson
|Eric Asevo
|Pete Cesario
|Ryan Dowling
|Michael Dunn
|Tim Hall
|Igor Krinitsky
|Red Magpantay
|Sweet Billy
|Paul Pawlicki
|Harish Rao
|Tim Ramage
|Nick Stecher
|Jeff Tatman
|Tim Tran
|Sung Yoo
|Kristian Davila
}Big Shouts out to:
The unsung folks at Fox|Paul Provenzano
|Mark Dawson
|Dave Shaw
|Alan Alder
|Brian Thomas
|Melissa Totten
|Ellen Gameral
|Jamie Samson
|Michele Birkner
|Priscilla Bourbonnais
|Mike Arkin
|Andrea Griffiths
|Simon Etchells
The folks who made the movies|Ridley Scott
|H.R. Giger
|James Cameron
|John McTiernan
|James Horner
|Jerry Goldsmith
|Elliot Goldenthal
|Stan Winston
|and many other talented individuals
}Rebellion
}-------
Creative Director|Jason Kingsley
Technical Director|Chris Kingsley
Producer & Lead Artist|Alastair Halsby
Engine Code & Lead Programmer|Kevin Lea
Network Code & Tools Programmer|Richard Rice
AI Programmer|Chris Fox
}Additional Programming
Sound|Dave Wall
Tools|Jake Hotson
AI|Alex Thomson
Art|Julian Breddy
|Ed Cookson
|Al Halsby
|Tim Jones
Additional Art|Ken Turner
|Matthew Riordan
|Adam Comiskey
|Kevin Lea
Lead Animator & Character Design|Ken Turner
Additional Animation|Adam Comiskey
Character Art|Al Halsby
|Tim Jones
|Julian Breddy
Sound|Ed Cookson
Additional Sound|Tim Jones
|Will Davies
|Al Halsby
Male Voice Talent|Julian Breddy
|Ken Turner
|Dominic Jeffrey
Female Voice Talent|Becky Kneubuhl
|April Chung
|Nadia Cocklin
Rebellion Thanks:|Jessica Sharp
|Patrick Dickinson
|George Launchbury
|Roxby Hartley
|Jake Hempson
|John Bryden
|Andy Nixon
|Shelagh Lewins
|Luke Harman
|Dan Mitchell
|Lee Brimmicombe-Wood
|Sophie Mobbs
|Bernard H. Wood
|Paul Topping
}Mondo Media
}-----------
Art Director|Marco Bertoldo
Producer|Liz Stuart
Senior Producer|Vivian Barad
3D Artists|Brittnal Anderson
|Robert Jeffery
|Kelley Lamsens
|Jeanne Littooy
|Manuel Marquez
|Art Matsuura
Storyboard Artist|Rhode Montijo
#

4252
3dc/ENGLISH.TXT Normal file

File diff suppressed because it is too large Load diff

140
3dc/GENPARAM.TXT Normal file
View file

@ -0,0 +1,140 @@
# AVP ALIEN GENERATOR DATA FILE
#
# This file contains level parameters for alien/marine generation.
# There are three parameters defined for each level:
# 1. Maximum number of aliens/marines in the level
# 2. Number of aliens/marines generated per minute
# 3. The increase in number generated per minute, per minute
#
# For an example of how these parameters work: if the initial
# number of aliens generated per minute is 3, and the increase
# in number per minute is 2, then during the first minute of
# play time 3 aliens will be generated, during the second minute
# 5 more will be generated, and during the third minute another
# 7 will be generated.
#
# The format of this file is: comment lines start with a hash,
# and each data item sits a new line. Each data item is preceeded
# with a comment, stating what it is
#
# CHANGING THIS FILE
# ------------------
# You may change any parameter for any level in this file. Save the
# file, and the next time you run the game the new parameter value
# will be used... however, you must follow these rules:
#
# 1. Stick to the format conventions described above
# 2. Do not insert comment lines longer than 80 characters
# 3. Do not change the order of the data items in this file
# 4. Do not save the file as anything other than a ASCII text file
# If you just edit the particular data item you are interested in,
# and then save the file, you shouldn't get any problems.
#
# Value Ranges
# ------------
# Maximum number of aliens should be between 0 and 255:
# 25 is a typical value.
# Aliens per minute should be between 0 and 255:
# 3 is a typical value
# Increase in aliens per minute should be between 0 and 255
# 2 is a typical value
#
# Patrick.
# -----------------------------------------------------------------
#
# GEN 1 (GENERAL ACCESS) : MAX ALIENS
25
# GEN 1 (GENERAL ACCESS) : ALIENS PER MINUTE
3
# GEN 1 (GENERAL ACCESS) : INCREASE IN ALIENS PER MINUTE
2
# GEN 2 (LIVING QUARTERS) : MAX ALIENS
25
# GEN 2 (LIVING QUARTERS) : ALIENS PER MINUTE
4
# GEN 2 (LIVING QUARTERS) : INCREASE IN ALIENS PER MINUTE
2
# GEN 3 (HANGER1) : MAX ALIENS
25
# GEN 3 (HANGER1) : ALIENS PER MINUTE
4
# GEN 3 (HANGER1) : INCREASE IN ALIENS PER MINUTE
2
# MEDLAB : MAX ALIENS
25
# MEDLAB : ALIENS PER MINUTE
3
# MEDLAB : INCREASE IN ALIENS PER MINUTE
2
# CMC 2 (HANGER 2) : MAX ALIENS
25
# CMC 2 (HANGER 2) : ALIENS PER MINUTE
3
# CMC 2 (HANGER 2) : INCREASE IN ALIENS PER MINUTE
2
# CMC 4 (MAIN ARMOURY) : MAX ALIENS
25
# CMC 4 (MAIN ARMOURY) : ALIENS PER MINUTE
3
# CMC 4 (MAIN ARMOURY) : INCREASE IN ALIENS PER MINUTE
2
# CMC 6 (MAIN CONTROL) : MAX ALIENS
25
# CMC 6 (MAIN CONTROL) : ALIENS PER MINUTE
3
# CMC 6 (MAIN CONTROL) : INCREASE IN ALIENS PER MINUTE
2
# SP2 (SECURITY POINT 2) : MAX ALIENS
10
# SP2 (SECURITY POINT 2) : ALIENS PER MINUTE
1
# SP2 (SECURITY POINT 2) : INCREASE IN ALIENS PER MINUTE
1
# SP3 (SECURITY POINT 3) : MAX ALIENS
10
# SP3 (SECURITY POINT 3) : ALIENS PER MINUTE
1
# SP3 (SECURITY POINT 3) : INCREASE IN ALIENS PER MINUTE
1
# R&D 2 (BIOWEAPONS RESEARCH) : MAX ALIENS
25
# R&D 2 (BIOWEAPONS RESEARCH) : ALIENS PER MINUTE
3
# R&D 2 (BIOWEAPONS RESEARCH) : INCREASE IN ALIENS PER MINUTE
2
# R&D 3 (CYBERNETIC AUGMENTATION) : MAX ALIENS
25
# R&D 3 (CYBERNETIC AUGMENTATION) : ALIENS PER MINUTE
3
# R&D 3 (CYBERNETIC AUGMENTATION) : INCREASE IN ALIENS PER MINUTE
2
# R&D 4 (NON-TERRESTRIAL TECH) : MAX ALIENS
25
# R&D 4 (NON-TERRESTRIAL TECH) : ALIENS PER MINUTE
3
# R&D 4 (NON-TERRESTRIAL TECH) : INCREASE IN ALIENS PER MINUTE
2
# MPS 2 (POWER SITE MAINTAINANCE) : MAX ALIENS
25
# MPS 2 (POWER SITE MAINTAINANCE) : ALIENS PER MINUTE
3
# MPS 2 (POWER SITE MAINTAINANCE) : INCREASE IN ALIENS PER MINUTE
2
# MPS 4 (MAIN REACTOR / NEST) : MAX ALIENS
10
# MPS 4 (MAIN REACTOR / NEST) : ALIENS PER MINUTE
1
# MPS 4 (MAIN REACTOR / NEST) : INCREASE IN ALIENS PER MINUTE
1
# SURFACE : MAX ALIENS
25
# SURFACE : ALIENS PER MINUTE
5
# SURFACE : INCREASE IN ALIENS PER MINUTE
4
# ENTRANCE : MAX ALIENS
10
# ENTRANCE : ALIENS PER MINUTE
2
# ENTRANCE : INCREASE IN ALIENS PER MINUTE
1

134
3dc/KSHAPE.H Normal file
View file

@ -0,0 +1,134 @@
#ifndef _kshape_h_ /* Is this your first time? */
#define _kshape_h_ 1
#include "particle.h"
#define SOFTWARE_RENDERER 0
#if SOFTWARE_RENDERER
#include "SoftwareRender.hpp"
#endif
typedef struct
{
/* base coords */
int X;
int Y;
int Z;
/* texels and intensity */
int U;
int V;
/* coloured components */
unsigned char R;
unsigned char G;
unsigned char B;
/* alpha component */
unsigned char A;
/* specular colour */
unsigned char SpecularR;
unsigned char SpecularG;
unsigned char SpecularB;
/* fog component */
unsigned char Fog;
} RENDERVERTEX;
typedef struct
{
/* stamp used for lazy evaluation */
int Stamp;
/* colour scalings */
unsigned char R;
unsigned char G;
unsigned char B;
/* specular colour */
unsigned char SpecularR;
unsigned char SpecularG;
unsigned char SpecularB;
/* fog component */
unsigned char Fog;
} COLOURINTENSITIES;
typedef struct
{
RENDERVERTEX Vertices[maxpolypts];
unsigned int NumberOfVertices;
unsigned int MinZ;
unsigned int MaxZ;
int ImageIndex;
unsigned char IsTextured :1;
unsigned char IsLit :1;
unsigned char IsSpecularLit :1;
enum TRANSLUCENCY_TYPE TranslucencyMode;
} RENDERPOLYGON;
extern RENDERVERTEX VerticesBuffer[9];
extern RENDERPOLYGON RenderPolygon;
enum LIGHTING_MODEL_ID
{
LIGHTING_MODEL_STANDARD,
LIGHTING_MODEL_HIERARCHICAL,
LIGHTING_MODEL_PRELIT,
};
extern void InitialiseLightIntensityStamps(void);
extern int FindHeatSourcesInHModel(DISPLAYBLOCK *dispPtr);
extern void TranslationSetup(void);
extern void TranslatePointIntoViewspace(VECTORCH *pointPtr);
extern void CheckRenderStatesForModule(MODULE *modulePtr);
extern void RenderDecal(DECAL *decalPtr);
extern void RenderParticle(PARTICLE *particlePtr);
/* KJL 10:25:44 7/23/97 - this offset is used to push back the normal game gfx,
so that the HUD can be drawn over the top without sinking into walls, etc. */
extern int HeadUpDisplayZOffset;
/* KJL 16:17:13 11/02/98 - heat source containment */
typedef struct
{
VECTORCH Position;
} HEATSOURCE;
#define MAX_NUMBER_OF_HEAT_SOURCES 10
extern HEATSOURCE HeatSourceList[];
extern int NumberOfHeatSources;
#define MIRRORING_ON 1
#if MIRRORING_ON
extern int MirroringActive;
extern int MirroringAxis;
#endif
#endif

8501
3dc/Kshape.bak Normal file

File diff suppressed because it is too large Load diff

8501
3dc/Kshape.c Normal file

File diff suppressed because it is too large Load diff

BIN
3dc/Language.txt Normal file

Binary file not shown.

246
3dc/MAP.C Normal file
View file

@ -0,0 +1,246 @@
#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "stratdef.h"
#define UseLocalAssert Yes
#include "ourasert.h"
/*
externs for commonly used global variables and arrays
*/
extern VIEWDESCRIPTORBLOCK *Global_VDB_Ptr;
/*
Global Variables
*/
DISPLAYBLOCK *dptr_last;
DISPLAYBLOCK *Player;
/*
Map Reading Functions
Read the map data passed and create the objects on the map
The map header contains an array of pointers to the different map data
structures
*/
DISPLAYBLOCK* ReadMap(MAPHEADER *mapheader)
{
MAPBLOCK8 *mapblock8ptr;
DISPLAYBLOCK *dblockptr = 0;
/* Set up pointers to the map arrays */
mapblock8ptr = mapheader->MapType8Objects;
/* Map Type #8 Structure */
if(mapblock8ptr) {
while(mapblock8ptr->MapType != MapType_Term) {
dblockptr = CreateActiveObject();
if(dblockptr)
{
dblockptr->ObShape = mapblock8ptr->MapShape;
CopyLocation(&mapblock8ptr->MapWorld, &dblockptr->ObWorld);
CopyEuler(&mapblock8ptr->MapEuler, &dblockptr->ObEuler);
dblockptr->ObFlags = mapblock8ptr->MapFlags;
dblockptr->ObFlags2 = mapblock8ptr->MapFlags2;
dblockptr->ObFlags3 = mapblock8ptr->MapFlags3;
if (mapblock8ptr->MapType == MapType_Player)
{
Player = dblockptr;
}
else
{
dblockptr->ObLightType = LightType_PerVertex;
dblockptr->ObFlags |= ObFlag_MultLSrc;
}
/* KJL 16:55:57 06/05/97 - removing camera stuff */
if(mapblock8ptr->MapVDBData)
MapSetVDB(dblockptr, mapblock8ptr->MapVDBData);
dblockptr->ObLightType = mapblock8ptr->MapLightType;
/* KJL 15:23:52 06/07/97 - removed */
// CopyVector(&mapblock8ptr->MapOrigin, &dblockptr->ObOrigin);
// dblockptr->ObSimShapes = mapblock8ptr->MapSimShapes;
// dblockptr->ObViewType = mapblock8ptr->MapViewType;
MapBlockInit(dblockptr);
CreateEulerMatrix(&dblockptr->ObEuler,&dblockptr->ObMat);
TransposeMatrixCH(&dblockptr->ObMat);
MapPostProcessing(dblockptr);
}
dptr_last = dblockptr;
mapblock8ptr++;
}
}
return dblockptr;
}
/*
Some objects might require a certain amount of general processing after
all the other map functions have been called
*/
void MapPostProcessing(DISPLAYBLOCK *dptr)
{
if(dptr)
{
/*
Make sure that objects requesting multiple light sources are at
least set to "LightType_PerObject"
*/
if(dptr->ObFlags & ObFlag_MultLSrc)
{
if(dptr->ObLightType == LightType_Infinite)
dptr->ObLightType = LightType_PerObject;
}
}
}
void MapSetVDB(DISPLAYBLOCK *dptr, MAPSETVDB *mapvdbdata)
{
VIEWDESCRIPTORBLOCK *vdb;
/* TEST */
/*LIGHTBLOCK *lptr;*/
/* Allocate a VDB */
vdb = CreateActiveVDB();
if(vdb) {
dptr->ObVDBPtr = vdb; /* Object Block ptr to VDB */
vdb->VDB_ViewObject = dptr; /* VDB ptr to Object Block */
/* VDB Setup */
SetVDB(
vdb,
mapvdbdata->SVDB_Flags,
mapvdbdata->SVDB_ViewType,
mapvdbdata->SVDB_Depth,
mapvdbdata->SVDB_CentreX,
mapvdbdata->SVDB_CentreY,
mapvdbdata->SVDB_ProjX,
mapvdbdata->SVDB_ProjY,
mapvdbdata->SVDB_MaxProj,
mapvdbdata->SVDB_ClipLeft,
mapvdbdata->SVDB_ClipRight,
mapvdbdata->SVDB_ClipUp,
mapvdbdata->SVDB_ClipDown,
mapvdbdata->SVDB_H1,
mapvdbdata->SVDB_H2,
mapvdbdata->SVDB_HColour,
mapvdbdata->SVDB_Ambience
);
PlatformSpecificVDBInit(vdb);
#if ProjectSpecificVDBs
ProjectSpecificVDBInit(vdb);
#endif
}
}
/*
Standard Initialisation for Map Objects
*/
void MapBlockInit(DISPLAYBLOCK *dptr)
{
SHAPEHEADER *sptr;
/* Get the shape header ptr */
sptr = GetShapeData(dptr->ObShape);
/* Augmented Z */
if(sptr->shapeflags & ShapeFlag_AugZ) dptr->ObFlags2 |= ObFlag2_AugZ;
/* Pass address of the shape data header back to the block for others */
dptr->ObShapeData = sptr;
/* Does this shape use a BSP tree or a Z Sort ? */
dptr->ObFlags |= ObFlag_TypeZ;
/* Copy shape radius to ODB */
dptr->ObRadius = sptr->shaperadius;
/* Copy shape xyz extents to ODB */
dptr->ObMaxX = sptr->shapemaxx;
dptr->ObMinX = sptr->shapeminx;
dptr->ObMaxY = sptr->shapemaxy;
dptr->ObMinY = sptr->shapeminy;
dptr->ObMaxZ = sptr->shapemaxz;
dptr->ObMinZ = sptr->shapeminz;
}

48
3dc/MEM3DCPP.CPP Normal file
View file

@ -0,0 +1,48 @@
#include "mem3dc.h"
#if DBGMALLOC
#if 1
// try and turn C++ new/delete tracking on such that
// we can do a malloc dump when the global objects
// with associated memory allocated is recored, the
// deallocation is recored, and then a malloc dump
// is done
// note that some global objects wont have their memory
// allocations/deallocations in the constructor/destructor
// tracked through record_malloc/record_free, but since
// global objects are deconstructed in the reverse order
// from construction, the deallocation type in the destructor
// will correspond to the allocation type in the constructor
int __cpp_new_recording = 0;
class DebugObject
{
public:
DebugObject();
~DebugObject();
};
DebugObject::DebugObject()
{
__cpp_new_recording = 1;
}
DebugObject::~DebugObject()
{
__cpp_new_recording = 0;
DumpMallocInfo(DUMPTOFILE);
}
static DebugObject dbo;
#else
int __cpp_new_recording = 1;
#endif
#endif

1131
3dc/MODULE.C Normal file

File diff suppressed because it is too large Load diff

322
3dc/MORPH.C Normal file
View file

@ -0,0 +1,322 @@
#include "3dc.h"
#include "inline.h"
/*
externs for commonly used global variables and arrays
*/
extern MORPHDISPLAY MorphDisplay;
extern int NormalFrameTime;
/*
Global Variables
*/
/*
Update Morphing Animation Control Block
*/
void UpdateMorphing(MORPHCTRL *mcptr)
{
MORPHHEADER *mhdr = mcptr->ObMorphHeader;
int UpdateRate;
/*textprint("UpdateMorphing\n");*/
if(mcptr->ObMorphFlags & mph_flag_play) {
/* How fast? */
if(mcptr->ObMorphSpeed == ONE_FIXED) {
UpdateRate = NormalFrameTime;
}
else {
UpdateRate = MUL_FIXED(NormalFrameTime, mcptr->ObMorphSpeed);
}
/* Update the current frame */
if(mcptr->ObMorphFlags & mph_flag_reverse) {
mcptr->ObMorphCurrFrame -= UpdateRate;
if(mcptr->ObMorphCurrFrame < 0) {
if(mcptr->ObMorphFlags & mph_flag_noloop) {
mcptr->ObMorphCurrFrame = 0;
/* The sequence has finished and we are at the start */
mcptr->ObMorphFlags |= (mph_flag_finished | mph_flag_start);
}
else {
mcptr->ObMorphCurrFrame += mhdr->mph_maxframes;
/* The sequence has looped and we are back at the end */
mcptr->ObMorphFlags |= (mph_flag_looped | mph_flag_end);
}
}
}
else {
mcptr->ObMorphCurrFrame += UpdateRate;
if(mcptr->ObMorphCurrFrame >= mhdr->mph_maxframes) {
if(mcptr->ObMorphFlags & mph_flag_noloop) {
/* The sequence has finished and we are at the end */
mcptr->ObMorphFlags |= (mph_flag_finished | mph_flag_end);
mcptr->ObMorphCurrFrame = mhdr->mph_maxframes - 1;
}
else {
mcptr->ObMorphCurrFrame -= mhdr->mph_maxframes;
/* The sequence has looped and we are back at the start */
mcptr->ObMorphFlags |= (mph_flag_looped | mph_flag_start);
}
}
}
}
}
/*
Update the Morphing Animation for this object
*/
void UpdateMorphingDptr(DISPLAYBLOCK *dptr)
{
SHAPEHEADER *sptr1;
SHAPEHEADER *sptr2;
/* Update object radius and extents */
GetMorphDisplay(&MorphDisplay, dptr);
sptr1 = MorphDisplay.md_sptr1;
sptr2 = MorphDisplay.md_sptr2;
#if 0
textprint("sptr1->shaperadius = %d\n", sptr1->shaperadius);
textprint("sptr2->shaperadius = %d\n", sptr2->shaperadius);
#endif
/* Radius */
if(sptr1->shaperadius == sptr2->shaperadius) {
dptr->ObRadius = sptr1->shaperadius;
}
else {
dptr->ObRadius = WideMul2NarrowDiv(sptr1->shaperadius,
MorphDisplay.md_one_minus_lerp,
sptr2->shaperadius,
MorphDisplay.md_lerp, ONE_FIXED);
}
/* X Extent */
if(sptr1->shapemaxx == sptr2->shapemaxx) {
dptr->ObMaxX = sptr1->shapemaxx;
}
else {
dptr->ObMaxX = WideMul2NarrowDiv(sptr1->shapemaxx,
MorphDisplay.md_one_minus_lerp,
sptr2->shapemaxx,
MorphDisplay.md_lerp, ONE_FIXED);
}
if(sptr1->shapeminx == sptr2->shapeminx) {
dptr->ObMinX = sptr1->shapeminx;
}
else {
dptr->ObMinX = WideMul2NarrowDiv(sptr1->shapeminx,
MorphDisplay.md_one_minus_lerp,
sptr2->shapeminx,
MorphDisplay.md_lerp, ONE_FIXED);
}
/* Y Extent */
if(sptr1->shapemaxy == sptr2->shapemaxy) {
dptr->ObMaxY = sptr1->shapemaxy;
}
else {
dptr->ObMaxY = WideMul2NarrowDiv(sptr1->shapemaxy,
MorphDisplay.md_one_minus_lerp,
sptr2->shapemaxy,
MorphDisplay.md_lerp, ONE_FIXED);
}
if(sptr1->shapeminy == sptr2->shapeminy) {
dptr->ObMinY = sptr1->shapeminy;
}
else {
dptr->ObMinY = WideMul2NarrowDiv(sptr1->shapeminy,
MorphDisplay.md_one_minus_lerp,
sptr2->shapeminy,
MorphDisplay.md_lerp, ONE_FIXED);
}
/* Z Extent */
if(sptr1->shapemaxz == sptr2->shapemaxz) {
dptr->ObMaxZ = sptr1->shapemaxz;
}
else {
dptr->ObMaxZ = WideMul2NarrowDiv(sptr1->shapemaxz,
MorphDisplay.md_one_minus_lerp,
sptr2->shapemaxz,
MorphDisplay.md_lerp, ONE_FIXED);
}
if(sptr1->shapeminz == sptr2->shapeminz) {
dptr->ObMinZ = sptr1->shapeminz;
}
else {
dptr->ObMinZ = WideMul2NarrowDiv(sptr1->shapeminz,
MorphDisplay.md_one_minus_lerp,
sptr2->shapeminz,
MorphDisplay.md_lerp, ONE_FIXED);
}
#if 0
textprint("dptr->ObRadius = %d\n", dptr->ObRadius);
#endif
}
/*
Using the current frame, calculate the lerp values and find out which two
shapes to interpolate between.
Write this information back to a MORPHDISPLAY structure.
*/
void GetMorphDisplay(MORPHDISPLAY *md, DISPLAYBLOCK *dptr)
{
MORPHFRAME *mdata;
MORPHCTRL *mc = dptr->ObMorphCtrl;
MORPHHEADER *mhdr = mc->ObMorphHeader;
md->md_lerp = mc->ObMorphCurrFrame & 0xffff;
md->md_one_minus_lerp = ONE_FIXED - md->md_lerp;
mdata = mhdr->mph_frames;
mdata = &mdata[mc->ObMorphCurrFrame >> 16];
md->md_shape1 = mdata->mf_shape1;
md->md_shape2 = mdata->mf_shape2;
md->md_sptr1 = GetShapeData(md->md_shape1);
md->md_sptr2 = GetShapeData(md->md_shape2);
}
void CopyMorphCtrl(MORPHCTRL *src, MORPHCTRL *dst)
{
dst->ObMorphCurrFrame = src->ObMorphCurrFrame;
dst->ObMorphFlags = src->ObMorphFlags;
dst->ObMorphSpeed = src->ObMorphSpeed;
dst->ObMorphHeader = src->ObMorphHeader;
}

187
3dc/MSLHAND.C Normal file
View file

@ -0,0 +1,187 @@
#include "3dc.h"
#include "mslhand.h"
#if PSX
#include "psx_inc.h"
#endif
#define UseLocalAssert 1
#include "ourasert.h"
extern SHAPEHEADER * mainshapelist[];
static int begins[ MSLS_MAXSECTIONS ];
static int ends[ MSLS_MAXSECTIONS ];
static int autodelete[ maxobjects ];
#define MSS_FREE (-1)
static void EnsureInitialized(void)
{
static int initialized = 0;
if (!initialized)
{
int i;
initialized = 1;
for (i=0; i<MSLS_MAXSECTIONS; ++i)
{
begins[i]=MSS_FREE;
ends[i]=MSS_FREE;
}
}
}
int GetNextMSLEntry(MSL_SECTION sect, unsigned int num_shapes, int auto_delete)
{
int i, blockstart, maxend = maxobjects;
/* I assume that the size of the global array 'mainshapelist' will be 'maxobjects' */
EnsureInitialized();
for (i=sect+1; i<MSLS_MAXSECTIONS; ++i)
{
if (MSS_FREE != begins[i])
{
maxend = begins[i];
break;
}
}
for (i=sect-1; MSS_FREE == begins[sect]; --i)
{
ends[sect] = begins[sect] = i>=0 ? ends[i] : 0;
}
blockstart = ends[sect];
/* can use a local assert here to fail on a mainshapelist overflow, otherwise return error code */
LOCALASSERT(ends[sect] + num_shapes <= maxend);
if (ends[sect] + num_shapes > maxend ) return MSL_OVERFLOW;
ends[sect] += num_shapes;
for (i=blockstart; i<ends[sect]; ++i)
{
mainshapelist[i] = 0;
autodelete[i] = auto_delete;
}
return blockstart;
}
void FlushMSLSection(MSL_SECTION sect)
{
#if StandardShapeLanguage
int i;
EnsureInitialized();
if (MSS_FREE == begins[sect] || MSS_FREE == ends[sect]) return;
for (i=begins[sect]; i<ends[sect]; ++i)
{
if (autodelete[i] && mainshapelist[i])
{
SHAPEHEADER * shp = mainshapelist[i];
int max_num_texs = 0;
int i;
if (shp->points)
{
if (*shp->points) free(*shp->points);
free(shp->points);
}
if (shp->sh_normals)
{
if (*shp->sh_normals) free(*shp->sh_normals);
free(shp->sh_normals);
}
if (shp->sh_vnormals)
{
if (*shp->sh_vnormals) free(*shp->sh_vnormals);
free(shp->sh_vnormals);
}
if (shp->sh_extraitemdata)
free(shp->sh_extraitemdata);
/* the items are allocated in one big bunch
// 9 int's per item (to make bsp simple)
// this should be changed if it is to be done
// a different way
*/
if (shp->items)
{
for (i=0; i<shp->numitems; i++)
{
if (shp->items[i][0] == 5 || shp->items[i][0] == 6)
{
int UVIndex = (shp->items[i][3] &0xffff0000) >> 16;
max_num_texs = max (max_num_texs, shp->items[i][3] &0x7fff);
if(shp->items[i][2]& iflag_txanim)
{
int j;
TXANIMHEADER** thlist=(TXANIMHEADER**)shp->sh_textures[UVIndex];
for(j=1;thlist[j]!=0;j++)
{
int k;
TXANIMHEADER* th=thlist[j];
for(k=0;k<th->txa_numframes;k++)
{
free(th->txa_framedata[k].txf_uvdata);
}
free (th->txa_framedata);
free (th);
}
free (thlist);
shp->sh_textures[UVIndex]=0;
}
else
{
free(shp->sh_textures[UVIndex]);
}
}
}
free (*shp->items);
free (shp->items);
}
if (shp->sh_textures)
{
free (shp->sh_textures);
}
if (shp->sh_localtextures)
{
for (i=0; i<(max_num_texs+1); i++)
{
free (shp->sh_localtextures[i]);
}
free (shp->sh_localtextures);
}
if (shp->sh_instruction)
free(shp->sh_instruction);
free(shp);
}
mainshapelist[i]=0;
autodelete[i]=0;
}
begins[sect]=MSS_FREE;
ends[sect]=MSS_FREE;
#else
printf("\nDo NOT call this function!\n");
//GLOBALASSERT(1==0);
#endif
}

28
3dc/MSLHAND.H Normal file
View file

@ -0,0 +1,28 @@
#ifndef _included_mslhand_h_
#define _included_mslhand_h_
#ifdef __cplusplus
extern "C" {
#endif
typedef enum MSL_Section
{
MSLS_COMPILEDIN,
MSLS_CHARACTER,
MSLS_ENVIRONMENT,
MSLS_MAXSECTIONS
} MSL_SECTION;
#define MSL_OVERFLOW (-1)
int GetNextMSLEntry(MSL_SECTION, unsigned int num_shapes, int auto_delete);
void FlushMSLSection(MSL_SECTION);
#ifdef __cplusplus
}
#endif
#endif /* !_included_mslhand_h_ */

2944
3dc/Maths.c Normal file

File diff suppressed because it is too large Load diff

613
3dc/OBJECT.C Normal file
View file

@ -0,0 +1,613 @@
#include "3dc.h"
#include "module.h"
#include "stratdef.h"
#include "sfx.h"
#define UseLocalAssert Yes
#include "ourasert.h"
/* globals for export */
int NumActiveBlocks;
DISPLAYBLOCK *ActiveBlockList[maxobjects];
/*
Object Block Lists et al
*/
static int NumFreeBlocks;
static DISPLAYBLOCK *FreeBlockList[maxobjects];
static DISPLAYBLOCK **FreeBlockListPtr = &FreeBlockList[maxobjects-1];
static DISPLAYBLOCK FreeBlockData[maxobjects];
static DISPLAYBLOCK **ActiveBlockListPtr = &ActiveBlockList[0];
/*
Texture Animation Block Extensions
*/
static int NumFreeTxAnimBlocks;
static TXACTRLBLK *FreeTxAnimBlockList[maxTxAnimblocks];
static TXACTRLBLK **FreeTxAnimBlockListPtr = &FreeTxAnimBlockList[maxTxAnimblocks-1];
static TXACTRLBLK FreeTxAnimBlockData[maxTxAnimblocks];
/*
Light Block Extensions
*/
static int NumFreeLightBlocks;
static LIGHTBLOCK *FreeLightBlockList[maxlightblocks];
static LIGHTBLOCK **FreeLightBlockListPtr = &FreeLightBlockList[maxlightblocks-1];
static LIGHTBLOCK FreeLightBlockData[maxlightblocks];
/*
To create the free block list, pointers to "FreeBlockData[]" must be copied
to "FreeBlockList[]".
Also:
"NumFreeBlocks" must be updated as "FreeBlockList[]" is created.
"NumActiveBlocks" must be initialised to zero.
*/
void InitialiseObjectBlocks(void)
{
DISPLAYBLOCK *FreeBlkPtr = &FreeBlockData[0];
NumActiveBlocks = 0;
FreeBlockListPtr = &FreeBlockList[maxobjects-1];
ActiveBlockListPtr = &ActiveBlockList[0];
for(NumFreeBlocks = 0; NumFreeBlocks<maxobjects; NumFreeBlocks++) {
FreeBlockList[NumFreeBlocks] = FreeBlkPtr;
FreeBlkPtr++;
}
}
/*
"AllocateObjectBlock()" is identical to the routine "GetBlock"
*/
DISPLAYBLOCK* AllocateObjectBlock(void)
{
DISPLAYBLOCK *FreeBlkPtr = 0; /* Default to null ptr */
int *sptr;
int i;
if(NumFreeBlocks) {
FreeBlkPtr = *FreeBlockListPtr--;
NumFreeBlocks--; /* One less free block */
/* Clear the block */
sptr = (int *)FreeBlkPtr;
for(i = sizeof(DISPLAYBLOCK)/4; i!=0; i--)
*sptr++ = 0;
}
return(FreeBlkPtr);
}
/*
"DeallocateObjectBlock()" is identical to the routine "ReturnBlock"
*/
void DeallocateObjectBlock(DISPLAYBLOCK *dblockptr)
{
/* Deallocate the Display Block */
FreeBlockListPtr++;
*FreeBlockListPtr = dblockptr;
NumFreeBlocks++; /* One more free block */
}
/*
"CreateActiveObject()" calls "AllocateObjectBlock()". An active object is
passed into the view and strategy routines unless flagged otherwise
WARNING!
An active object must ALWAYS be deallocated by "DestroyActiveObject()".
*/
DISPLAYBLOCK* CreateActiveObject(void)
{
DISPLAYBLOCK *dblockptr;
dblockptr = AllocateObjectBlock();
if(dblockptr) {
*ActiveBlockListPtr++ = dblockptr;
NumActiveBlocks++;
}
return dblockptr;
}
/*
DestroyActiveObject()
Remove the block from "ActiveBlockList".
Use the array model because it's clearer.
This function returns 0 if successful, -1 if not
*/
int DestroyActiveObject(DISPLAYBLOCK *dblockptr)
{
int i, light;
TXACTRLBLK *taptr;
/* If the block ptr is OK, search the Active Blocks List */
if(dblockptr) {
for(i = 0; i < NumActiveBlocks; i++) {
if(ActiveBlockList[i] == dblockptr) {
ActiveBlockList[i] = ActiveBlockList[NumActiveBlocks-1];
NumActiveBlocks--;
ActiveBlockListPtr--;
DestroyActiveVDB(dblockptr->ObVDBPtr); /* Checks for null */
if(dblockptr->ObNumLights) {
for(light = dblockptr->ObNumLights - 1; light != -1; light--)
DeleteLightBlock(dblockptr->ObLights[light], dblockptr);
}
/* If no SB, deallocate any Texture Animation Blocks */
if(dblockptr->ObStrategyBlock == 0) {
if(dblockptr->ObTxAnimCtrlBlks) {
taptr = dblockptr->ObTxAnimCtrlBlks;
while(taptr) {
DeallocateTxAnimBlock(taptr);
taptr = taptr->tac_next;
}
}
}
/* Deallocate the Lazy Morphed Points Array Pointer */
#if (SupportMorphing && LazyEvaluationForMorphing)
if(dblockptr->ObMorphedPts) {
DeallocateMem(dblockptr->ObMorphedPts);
dblockptr->ObMorphedPts = 0;
}
#endif
/* KJL 16:52:43 06/01/98 - dealloc sfx block if one exists */
if(dblockptr->SfxPtr)
{
DeallocateSfxBlock(dblockptr->SfxPtr);
}
DeallocateObjectBlock(dblockptr); /* Back to Free List */
/* If this is the current landscape, clear the pointer */
return 0;
}
}
}
return -1;
}
/*
Support Functions for Texture Animation Blocks
*/
void InitialiseTxAnimBlocks(void)
{
TXACTRLBLK *FreeBlkPtr = &FreeTxAnimBlockData[0];
FreeTxAnimBlockListPtr = &FreeTxAnimBlockList[maxTxAnimblocks-1];
for(NumFreeTxAnimBlocks=0; NumFreeTxAnimBlocks < maxTxAnimblocks; NumFreeTxAnimBlocks++) {
FreeTxAnimBlockList[NumFreeTxAnimBlocks] = FreeBlkPtr;
FreeBlkPtr++;
}
}
/*
Allocate a Texture Animation Block
*/
TXACTRLBLK* AllocateTxAnimBlock(void)
{
TXACTRLBLK *FreeBlkPtr = 0; /* Default to null ptr */
int *sptr;
int i;
if(NumFreeTxAnimBlocks) {
FreeBlkPtr = *FreeTxAnimBlockListPtr--;
NumFreeTxAnimBlocks--; /* One less free block */
/* Clear the block */
sptr = (int *)FreeBlkPtr;
for(i = sizeof(TXACTRLBLK)/4; i!=0; i--)
*sptr++ = 0;
}
return FreeBlkPtr;
}
/*
Deallocate a Texture Animation Block
*/
void DeallocateTxAnimBlock(TXACTRLBLK *TxAnimblockptr)
{
FreeTxAnimBlockListPtr++;
*FreeTxAnimBlockListPtr = TxAnimblockptr;
NumFreeTxAnimBlocks++; /* One more free block */
}
/*
Add a Texture Animation Block to a Display Block
*/
void AddTxAnimBlock(DISPLAYBLOCK *dptr, TXACTRLBLK *taptr)
{
TXACTRLBLK *taptr_tmp;
if(dptr->ObTxAnimCtrlBlks) {
taptr_tmp = dptr->ObTxAnimCtrlBlks;
while(taptr_tmp->tac_next)
taptr_tmp = taptr_tmp->tac_next;
taptr_tmp->tac_next = taptr;
}
else dptr->ObTxAnimCtrlBlks = taptr;
}
/*
Support functions for Light Blocks
*/
void InitialiseLightBlocks(void)
{
LIGHTBLOCK *FreeBlkPtr = &FreeLightBlockData[0];
FreeLightBlockListPtr = &FreeLightBlockList[maxlightblocks-1];
for(NumFreeLightBlocks=0; NumFreeLightBlocks < maxlightblocks; NumFreeLightBlocks++) {
FreeLightBlockList[NumFreeLightBlocks] = FreeBlkPtr;
FreeBlkPtr++;
}
}
LIGHTBLOCK* AllocateLightBlock(void)
{
LIGHTBLOCK *FreeBlkPtr = 0; /* Default to null ptr */
int *lptr;
int i;
if(NumFreeLightBlocks) {
FreeBlkPtr = *FreeLightBlockListPtr--;
NumFreeLightBlocks--; /* One less free block */
/* Clear the block */
lptr = (int *)FreeBlkPtr;
for(i = sizeof(LIGHTBLOCK)/4; i!=0; i--)
*lptr++ = 0;
}
return(FreeBlkPtr);
}
void DeallocateLightBlock(LIGHTBLOCK *lptr)
{
/* Not all lights come from the free light list */
if(lptr->LightFlags & LFlag_WasNotAllocated) return;
/* Make sure that this light IS from the free light list */
GLOBALASSERT(
(lptr >= FreeLightBlockData) &&
(lptr < &FreeLightBlockData[maxlightblocks])
);
/* Ok to return the light */
FreeLightBlockListPtr++;
*FreeLightBlockListPtr = lptr;
NumFreeLightBlocks++; /* One more free block */
}
/*
See if there are any free slots in the dptr light block array.
If there are, allocate a light block, place it in the list and return
the pointer to the caller.
A late addition is the passing of a light block (from somewhere, it does
not matter where). This light block is then added rather than one being
allocated from the free light block list.
*/
LIGHTBLOCK* AddLightBlock(DISPLAYBLOCK *dptr, LIGHTBLOCK *lptr_to_add)
{
LIGHTBLOCK **larrayptr;
LIGHTBLOCK **freelarrayptr;
LIGHTBLOCK *lptr = 0;
int i, lfree;
/* Are there any free slots? */
lfree = No;
larrayptr = &dptr->ObLights[0];
for(i = MaxObjectLights; i!=0 && lfree == No; i--) {
if(*larrayptr == 0) {
freelarrayptr = larrayptr;
lfree = Yes;
}
larrayptr++;
}
if(lfree) {
if(lptr_to_add) {
lptr = lptr_to_add;
}
else {
lptr = AllocateLightBlock();
}
if(lptr)
{
*freelarrayptr = lptr;
dptr->ObNumLights++;
}
}
return lptr;
}
/*
To delete a light block, copy the end block to the new free slot and
reduce the count by one. Make sure the end block array entry is cleared.
*/
void DeleteLightBlock(LIGHTBLOCK *lptr, DISPLAYBLOCK *dptr)
{
int i, larrayi;
DeallocateLightBlock(lptr);
/* What is lptr's array index? */
larrayi = -1; /* null value */
for(i = 0; i < dptr->ObNumLights; i++)
if(dptr->ObLights[i] == lptr) larrayi = i;
/* Proceed only if lptr has been found in the array */
if(larrayi != -1) {
/* Copy the end block to that of lptr */
dptr->ObLights[larrayi] = dptr->ObLights[dptr->ObNumLights - 1];
/* Clear the end block array entry */
dptr->ObLights[dptr->ObNumLights - 1] = 0;
/* One less light in the dptr list */
dptr->ObNumLights--;
}
}
/*
When running the parallel strategies, display and light block deallocation
must only be done at the end of the frame, AFTER processor synchronisation
and BEFORE the shadow copy.
*/
int DisplayAndLightBlockDeallocation(void)
{
DISPLAYBLOCK **activeblocksptr;
DISPLAYBLOCK *dptr;
int i, j;
LIGHTBLOCK *lptr;
if(NumActiveBlocks) {
activeblocksptr = &ActiveBlockList[NumActiveBlocks - 1];
for(i = NumActiveBlocks; i!=0; i--) {
dptr = *activeblocksptr--;
/* Deallocate Object? */
if(dptr->ObFlags2 & ObFlag2_Deallocate) {
DestroyActiveObject(dptr);
}
/* Deallocate any Lights? */
else {
if(dptr->ObNumLights) {
for(j = dptr->ObNumLights - 1; j > -1; j--) {
lptr = dptr->ObLights[j];
if(lptr->LightFlags & LFlag_Deallocate) {
DeleteLightBlock(dptr->ObLights[j], dptr);
}
}
}
}
}
}
return 0;
}

BIN
3dc/SMACKW32.DLL Normal file

Binary file not shown.

BIN
3dc/SMACKW32.LIB Normal file

Binary file not shown.

16460
3dc/TABLES.C Normal file

File diff suppressed because it is too large Load diff

779
3dc/VDB.C Normal file
View file

@ -0,0 +1,779 @@
#include "3dc.h"
#include "inline.h"
/*
externs for commonly used global variables and arrays
*/
#if platform_pc
extern int sine[];
extern int cosine[];
#endif
#if SupportWindows95
extern int ScanDrawMode;
#endif
/*
General System Globals
*/
SCENE Global_Scene = 0;
/*
Screen Descriptor Block
*/
SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
/*
View Descriptor Blocks
*/
int NumFreeVDBs;
VIEWDESCRIPTORBLOCK *FreeVDBList[maxvdbs];
static VIEWDESCRIPTORBLOCK **FreeVDBListPtr = &FreeVDBList[maxvdbs-1];
int NumActiveVDBs;
VIEWDESCRIPTORBLOCK *ActiveVDBList[maxvdbs];
static VIEWDESCRIPTORBLOCK **ActiveVDBListPtr = &ActiveVDBList[0];
static VIEWDESCRIPTORBLOCK FreeVDBData[maxvdbs];
/* Clip Plane Block */
static CLIPPLANEPOINTS ClipPlanePoints;
extern int GlobalAmbience;
/*
Support Functions
*/
/*
Calculate View Volume Planes from the Clip Boundaries for a VDB
Before doing this, check that the requested boundaries are within those of
the physical sceen. If any boundary transgresses, truncate it and set the
appropriate flag bit.
*/
void VDBClipPlanes(VIEWDESCRIPTORBLOCK *vdb)
{
/* Check Clip Boundaries against the Physical Screen */
/* Check Left Boundary */
if(vdb->VDB_ClipLeft < ScreenDescriptorBlock.SDB_ClipLeft) {
vdb->VDB_ClipLeft = ScreenDescriptorBlock.SDB_ClipLeft;
vdb->VDB_Flags |= ViewDB_Flag_LTrunc;
}
/* Check Right Boundary */
if(vdb->VDB_ClipRight > ScreenDescriptorBlock.SDB_ClipRight) {
vdb->VDB_ClipRight = ScreenDescriptorBlock.SDB_ClipRight;
vdb->VDB_Flags |= ViewDB_Flag_RTrunc;
}
/* Check Up boundary */
if(vdb->VDB_ClipUp < ScreenDescriptorBlock.SDB_ClipUp) {
vdb->VDB_ClipUp = ScreenDescriptorBlock.SDB_ClipUp;
vdb->VDB_Flags |= ViewDB_Flag_UTrunc;
}
/* Check Down boundary */
if(vdb->VDB_ClipDown > ScreenDescriptorBlock.SDB_ClipDown) {
vdb->VDB_ClipDown = ScreenDescriptorBlock.SDB_ClipDown;
vdb->VDB_Flags |= ViewDB_Flag_DTrunc;
}
/* Calculate Width and Height */
/* textprint("current wh = %d, %d\n", vdb->VDB_Width, vdb->VDB_Height); */
/* Width */
vdb->VDB_Width = vdb->VDB_ClipRight - vdb->VDB_ClipLeft;
/* Height */
vdb->VDB_Height = vdb->VDB_ClipDown - vdb->VDB_ClipUp;
#if 0
textprint("new wh = %d, %d\n", vdb->VDB_Width, vdb->VDB_Height);
WaitForReturn();
#endif
/* Set up the Clip Planes */
/* Clip Left */
ClipPlanePoints.cpp1.vx = vdb->VDB_ClipLeft;
ClipPlanePoints.cpp1.vy = vdb->VDB_ClipUp;
ClipPlanePoints.cpp1.vz = NearZ;
ClipPlanePoints.cpp2.vx = vdb->VDB_ClipLeft;
ClipPlanePoints.cpp2.vy = (vdb->VDB_ClipUp + vdb->VDB_ClipDown) / 2;
ClipPlanePoints.cpp2.vz = FarZ;
ClipPlanePoints.cpp3.vx = vdb->VDB_ClipLeft;
ClipPlanePoints.cpp3.vy = vdb->VDB_ClipDown;
ClipPlanePoints.cpp3.vz = NearZ;
MakeClipPlane(vdb, &vdb->VDB_ClipLeftPlane, &ClipPlanePoints);
/* Clip Right */
ClipPlanePoints.cpp1.vx = vdb->VDB_ClipRight;
ClipPlanePoints.cpp1.vy = vdb->VDB_ClipUp;
ClipPlanePoints.cpp1.vz = NearZ;
ClipPlanePoints.cpp2.vx = vdb->VDB_ClipRight;
ClipPlanePoints.cpp2.vy = vdb->VDB_ClipDown;
ClipPlanePoints.cpp2.vz = NearZ;
ClipPlanePoints.cpp3.vx = vdb->VDB_ClipRight;
ClipPlanePoints.cpp3.vy = (vdb->VDB_ClipUp + vdb->VDB_ClipDown) / 2;
ClipPlanePoints.cpp3.vz = FarZ;
MakeClipPlane(vdb, &vdb->VDB_ClipRightPlane, &ClipPlanePoints);
/* Clip Up */
ClipPlanePoints.cpp1.vx = vdb->VDB_ClipLeft;
ClipPlanePoints.cpp1.vy = vdb->VDB_ClipUp;
ClipPlanePoints.cpp1.vz = NearZ;
ClipPlanePoints.cpp2.vx = vdb->VDB_ClipRight;
ClipPlanePoints.cpp2.vy = vdb->VDB_ClipUp;
ClipPlanePoints.cpp2.vz = NearZ;
ClipPlanePoints.cpp3.vx = (vdb->VDB_ClipLeft + vdb->VDB_ClipRight) / 2;
ClipPlanePoints.cpp3.vy = vdb->VDB_ClipUp;
ClipPlanePoints.cpp3.vz = FarZ;
MakeClipPlane(vdb, &vdb->VDB_ClipUpPlane, &ClipPlanePoints);
/* Clip Down */
ClipPlanePoints.cpp1.vx = vdb->VDB_ClipLeft;
ClipPlanePoints.cpp1.vy = vdb->VDB_ClipDown;
ClipPlanePoints.cpp1.vz = NearZ;
ClipPlanePoints.cpp2.vx = (vdb->VDB_ClipLeft + vdb->VDB_ClipRight) / 2;
ClipPlanePoints.cpp2.vy = vdb->VDB_ClipDown;
ClipPlanePoints.cpp2.vz = FarZ;
ClipPlanePoints.cpp3.vx = vdb->VDB_ClipRight;
ClipPlanePoints.cpp3.vy = vdb->VDB_ClipDown;
ClipPlanePoints.cpp3.vz = NearZ;
MakeClipPlane(vdb, &vdb->VDB_ClipDownPlane, &ClipPlanePoints);
/* Clip Z */
vdb->VDB_ClipZPlane.CPB_Normal.vx = 0;
vdb->VDB_ClipZPlane.CPB_Normal.vy = 0;
vdb->VDB_ClipZPlane.CPB_Normal.vz = -ONE_FIXED;
vdb->VDB_ClipZPlane.CPB_POP.vx = 0;
vdb->VDB_ClipZPlane.CPB_POP.vy = 0;
vdb->VDB_ClipZPlane.CPB_POP.vz = vdb->VDB_ClipZ;
}
/*
Make a Clip Plane.
Reverse Project the three Clip Points (overwrite their struct).
Use the first Clip Point as the POP, writing this to the CPB.
Pass the three Clip Points to MakeNormal() specifying the CPB Normal as
the destination.
NOTES
The vdb is passed for the reverse projection.
*/
void MakeClipPlane(
VIEWDESCRIPTORBLOCK *vdb,
CLIPPLANEBLOCK *cpb,
CLIPPLANEPOINTS *cpp)
{
int x, y;
/* Reverse Project the Clip Points */
/* cpp1 */
/* x */
x=cpp->cpp1.vx;
x-=vdb->VDB_CentreX;
x*=cpp->cpp1.vz;
x/=vdb->VDB_ProjX;
cpp->cpp1.vx=x;
/* y */
y=cpp->cpp1.vy;
y-=vdb->VDB_CentreY;
y*=cpp->cpp1.vz;
y/=vdb->VDB_ProjY;
cpp->cpp1.vy=y;
/* cpp2 */
/* x */
x=cpp->cpp2.vx;
x-=vdb->VDB_CentreX;
x*=cpp->cpp2.vz;
x/=vdb->VDB_ProjX;
cpp->cpp2.vx=x;
/* y */
y=cpp->cpp2.vy;
y-=vdb->VDB_CentreY;
y*=cpp->cpp2.vz;
y/=vdb->VDB_ProjY;
cpp->cpp2.vy=y;
/* cpp3 */
/* x */
x=cpp->cpp3.vx;
x-=vdb->VDB_CentreX;
x*=cpp->cpp3.vz;
x/=vdb->VDB_ProjX;
cpp->cpp3.vx=x;
/* y */
y=cpp->cpp3.vy;
y-=vdb->VDB_CentreY;
y*=cpp->cpp3.vz;
y/=vdb->VDB_ProjY;
cpp->cpp3.vy=y;
/* The 1st Clip Point can be the POP */
cpb->CPB_POP.vx=cpp->cpp1.vx;
cpb->CPB_POP.vy=cpp->cpp1.vy;
cpb->CPB_POP.vz=cpp->cpp1.vz;
/* Make CPB_Normal */
MakeNormal(&cpp->cpp1, &cpp->cpp2, &cpp->cpp3, &cpb->CPB_Normal);
}
#if pc_backdrops
/*
Create the projector array used for cylindrically projected backdrops
The array looks like this
unsigned short VDB_ProjectorXOffsets[MaxScreenWidth];
For each centre relative x there is a projector. Using just the x and z
components of the projector an angular offset from the centre (0) can be
calculated using ArcTan().
To calculate a projector one must reverse project each x value at a given
z value. Rather than go on to create the normalised projector vector we can
go straight to the ArcTan() to find the angular offset.
*/
static void CreateProjectorArray(VIEWDESCRIPTORBLOCK *vdb)
{
int sx, x, vx, vz, i, ao;
vz = ONE_FIXED;
sx = vdb->VDB_ClipLeft;
i = 0;
while(sx < vdb->VDB_ClipRight) {
x = sx - vdb->VDB_CentreX;
vx = (x * vz) / vdb->VDB_ProjX;
ao = ArcTan(vx, vz);
vdb->VDB_ProjectorXOffsets[i] = ao;
#if 0
textprint("Pr. Offset %d = %u\n", i, vdb->VDB_ProjectorXOffsets[i]);
WaitForReturn();
#endif
sx++; i++;
}
}
#endif
/*
SetVDB requires a VIEWDESCRIPTORBLOCK
See the actual function code for what each parameter is
*/
void SetVDB(vdb, fl, ty, d, cx,cy, prx,pry, mxp, cl,cr,cu,cd, h1,h2,hc, amb)
VIEWDESCRIPTORBLOCK *vdb;
int fl;
int ty;
int d;
int cx;
int cy;
int prx;
int pry;
int mxp;
int cl;
int cr;
int cu;
int cd;
int h1;
int h2;
int hc;
int amb;
{
/* Initial setup */
vdb->VDB_Flags = fl;
vdb->VDB_ViewType = ty;
/* Ambience */
vdb->VDB_Ambience = amb;
/* KJL 14:30:57 05/14/97 - set globalAmbience here as well */
GlobalAmbience = amb;
/* Width and Height are set by the Clip Boundaries */
if(vdb->VDB_Flags & ViewDB_Flag_FullSize) {
vdb->VDB_Depth = ScreenDescriptorBlock.SDB_Depth;
#if SupportWindows95
vdb->VDB_ScreenDepth = ScreenDescriptorBlock.SDB_ScreenDepth;
#endif
vdb->VDB_CentreX = ScreenDescriptorBlock.SDB_CentreX;
vdb->VDB_CentreY = ScreenDescriptorBlock.SDB_CentreY;
vdb->VDB_ProjX = ScreenDescriptorBlock.SDB_ProjX;
vdb->VDB_ProjY = ScreenDescriptorBlock.SDB_ProjY;
vdb->VDB_MaxProj = ScreenDescriptorBlock.SDB_MaxProj;
vdb->VDB_ClipLeft = ScreenDescriptorBlock.SDB_ClipLeft;
vdb->VDB_ClipRight = ScreenDescriptorBlock.SDB_ClipRight;
vdb->VDB_ClipUp = ScreenDescriptorBlock.SDB_ClipUp;
vdb->VDB_ClipDown = ScreenDescriptorBlock.SDB_ClipDown;
}
else {
#if SupportWindows95
if (ScanDrawMode == ScanDrawDirectDraw)
vdb->VDB_Depth = d;
else
vdb->VDB_Depth = VideoModeType_24;
vdb->VDB_ScreenDepth = ScreenDescriptorBlock.SDB_ScreenDepth;
#else
vdb->VDB_Depth = d;
#endif
vdb->VDB_CentreX = cx;
vdb->VDB_CentreY = cy;
vdb->VDB_ProjX = prx;
vdb->VDB_ProjY = pry;
vdb->VDB_MaxProj = mxp;
vdb->VDB_ClipLeft = cl;
vdb->VDB_ClipRight = cr;
vdb->VDB_ClipUp = cu;
vdb->VDB_ClipDown = cd;
if(vdb->VDB_Flags & ViewDB_Flag_AdjustScale) {
vdb->VDB_CentreX =
WideMulNarrowDiv(
vdb->VDB_CentreX,
ScreenDescriptorBlock.SDB_Width,
320);
vdb->VDB_CentreY =
WideMulNarrowDiv(
vdb->VDB_CentreY,
ScreenDescriptorBlock.SDB_Height,
200);
vdb->VDB_ProjX =
WideMulNarrowDiv(
vdb->VDB_ProjX,
ScreenDescriptorBlock.SDB_Width,
320);
vdb->VDB_ProjY =
WideMulNarrowDiv(
vdb->VDB_ProjY,
ScreenDescriptorBlock.SDB_Height,
200);
vdb->VDB_MaxProj =
WideMulNarrowDiv(
vdb->VDB_MaxProj,
ScreenDescriptorBlock.SDB_Width,
320);
vdb->VDB_ClipLeft =
WideMulNarrowDiv(
vdb->VDB_ClipLeft,
ScreenDescriptorBlock.SDB_Width,
320);
vdb->VDB_ClipRight =
WideMulNarrowDiv(
vdb->VDB_ClipRight,
ScreenDescriptorBlock.SDB_Width,
320);
vdb->VDB_ClipUp =
WideMulNarrowDiv(
vdb->VDB_ClipUp,
ScreenDescriptorBlock.SDB_Height,
200);
vdb->VDB_ClipDown =
WideMulNarrowDiv(
vdb->VDB_ClipDown,
ScreenDescriptorBlock.SDB_Height,
200);
}
}
/* Create the clip planes */
/* KJL 10:41:13 04/09/97 - set to constant so the same for all screen sizes! */
vdb->VDB_ClipZ = 64;//vdb->VDB_MaxProj; /* Safe */
VDBClipPlanes(vdb);
#if 0
/* View Angle */
if(vdb->VDB_CentreX > vdb->VDB_CentreY) s = vdb->VDB_CentreX;
else s = vdb->VDB_CentreY;
z = vdb->VDB_MaxProj * 100;
x = (s * z) / vdb->VDB_MaxProj;
vdb->VDB_ViewAngle = ArcTan(x, z);
vdb->VDB_ViewAngleCos = GetCos(vdb->VDB_ViewAngle);
#if 0
textprint("View Angle = %d\n", vdb->VDB_ViewAngle);
WaitForReturn();
#endif
#if pc_backdrops
/* Projector Array */
CreateProjectorArray(vdb);
#endif
/* Hazing & Background Colour */
vdb->VDB_H1 = h1;
vdb->VDB_H2 = h2;
vdb->VDB_HInterval = h2 - h1;
vdb->VDB_HColour = hc;
#endif
}
/*
Initialise the Free VDB List
*/
void InitialiseVDBs(void)
{
VIEWDESCRIPTORBLOCK *FreeVDBPtr = &FreeVDBData[0];
NumActiveVDBs = 0;
for(NumFreeVDBs = 0; NumFreeVDBs < maxvdbs; NumFreeVDBs++) {
FreeVDBList[NumFreeVDBs] = FreeVDBPtr;
FreeVDBPtr++;
}
FreeVDBListPtr = &FreeVDBList[maxvdbs-1];
ActiveVDBListPtr = &ActiveVDBList[0];
}
/*
Get a VDB from the Free VDB list
*/
VIEWDESCRIPTORBLOCK* AllocateVDB(void)
{
VIEWDESCRIPTORBLOCK *FreeVDBPtr = 0; /* Default to null ptr */
int *i_src;
int i;
if(NumFreeVDBs) {
FreeVDBPtr = *FreeVDBListPtr--;
NumFreeVDBs -= 1; /* One less free block */
/* Clear the block */
i_src = (int *) FreeVDBPtr;
for(i = sizeof(VIEWDESCRIPTORBLOCK)/4; i!=0; i--)
*i_src++ = 0;
}
return(FreeVDBPtr);
}
/*
Return a VDB to the Free VDB list
*/
void DeallocateVDB(VIEWDESCRIPTORBLOCK *vdb)
{
FreeVDBListPtr++;
*FreeVDBListPtr = vdb;
NumFreeVDBs++; /* One more free block */
}
/*
Allocate a VDB and make it active
*/
VIEWDESCRIPTORBLOCK* CreateActiveVDB(void)
{
VIEWDESCRIPTORBLOCK *vdb;
VIEWDESCRIPTORBLOCK *vdb_tmp;
VIEWDESCRIPTORBLOCK **v_src;
int v;
int p = -1;
vdb = AllocateVDB();
if(vdb) {
/* Find the next "VDB_Priority" */
if(NumActiveVDBs) {
v_src = &ActiveVDBList[0];
for(v = NumActiveVDBs; v!=0; v--) {
vdb_tmp = *v_src++;
if(vdb_tmp->VDB_Priority > p) p = vdb_tmp->VDB_Priority;
}
}
/* Set the VDB priority */
vdb->VDB_Priority = (p + 1);
/* Update the active VDB list */
*ActiveVDBListPtr++ = vdb;
NumActiveVDBs++;
}
return vdb;
}
/*
Deallocate an active VDB
*/
int DestroyActiveVDB(dblockptr)
VIEWDESCRIPTORBLOCK *dblockptr;
{
int j = -1;
int i;
/* If the VDB ptr is OK, search the Active VDB List */
if(dblockptr) {
for(i = 0; i < NumActiveVDBs && j!=0; i++) {
if(ActiveVDBList[i] == dblockptr) {
#if ProjectSpecificVDBs
ProjectSpecificVDBDestroy(dblockptr);
#endif
ActiveVDBList[i] = ActiveVDBList[NumActiveVDBs - 1];
NumActiveVDBs--;
ActiveVDBListPtr--;
DeallocateVDB(dblockptr); /* Return VDB to Free List */
j = 0; /* Flag OK */
}
}
}
return(j);
}

BIN
3dc/avp.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

1
3dc/avp.rc Normal file
View file

@ -0,0 +1 @@
AVPICON ICON AvP.ICO

198
3dc/avp/AI_Sight.c Normal file
View file

@ -0,0 +1,198 @@
/*KJL*****************************************
* AI_Sight.c handles the NPC's visual senses *
*****************************************KJL*/
#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "stratdef.h"
#include "gamedef.h"
#include "dynblock.h"
#include "dynamics.h"
#include "los.h"
#include "ShowCmds.h"
#include "equipmnt.h"
#include "bh_marin.h"
#include "bh_xeno.h"
#include "targeting.h"
#include "bh_weap.h"
#include "AI_Sight.h"
#define UseLocalAssert Yes
#include "ourasert.h"
extern int MarineSight_FrustrumReject(STRATEGYBLOCK *sbPtr,VECTORCH *localOffset,STRATEGYBLOCK *target);
extern int FrisbeeSight_FrustrumReject(STRATEGYBLOCK *sbPtr,VECTORCH *localOffset,STRATEGYBLOCK *target);
int NPCCanSeeTarget(STRATEGYBLOCK *sbPtr, STRATEGYBLOCK *target, int viewRange)
{
int frustrum_test;
/* connect eyeposition to head */
VECTORCH eyePosition = {0,-1500,0};
LOCALASSERT(target);
LOCALASSERT(sbPtr);
if (target->containingModule==NULL) {
return(0);
}
if (sbPtr->containingModule==NULL) {
return(0);
}
if ((target->SBdptr==NULL)||(sbPtr->SBdptr==NULL)) {
if ((IsModuleVisibleFromModule(target->containingModule,sbPtr->containingModule))) {
return(1);
} else {
return(0);
}
} else {
switch (sbPtr->I_SBtype) {
case I_BehaviourFrisbee:
{
MATRIXCH WtoL;
VECTORCH offset, sourcepos, targetpos;
FRISBEE_BEHAV_BLOCK *frisbeeStatusPointer;
SECTION_DATA *disc_sec;
LOCALASSERT(sbPtr);
LOCALASSERT(sbPtr->containingModule);
frisbeeStatusPointer = (FRISBEE_BEHAV_BLOCK *)(sbPtr->SBdataptr);
LOCALASSERT(frisbeeStatusPointer);
/* Arc reject. */
disc_sec=GetThisSectionData(frisbeeStatusPointer->HModelController.section_data,"Mdisk");
if (disc_sec) {
WtoL=disc_sec->SecMat;
sourcepos=disc_sec->World_Offset;
} else {
WtoL=sbPtr->DynPtr->OrientMat;
GetTargetingPointOfObject_Far(sbPtr,&sourcepos);
}
GetTargetingPointOfObject_Far(target,&targetpos);
offset.vx=sourcepos.vx-targetpos.vx;
offset.vy=sourcepos.vy-targetpos.vy;
offset.vz=sourcepos.vz-targetpos.vz;
TransposeMatrixCH(&WtoL);
RotateVector(&offset,&WtoL);
frustrum_test=FrisbeeSight_FrustrumReject(sbPtr,&offset,target);
}
break;
case I_BehaviourMarine:
case I_BehaviourSeal:
{
MATRIXCH WtoL;
VECTORCH offset, sourcepos, targetpos;
MARINE_STATUS_BLOCK *marineStatusPointer;
SECTION_DATA *head_sec;
LOCALASSERT(sbPtr);
LOCALASSERT(sbPtr->containingModule);
marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbPtr->SBdataptr);
LOCALASSERT(marineStatusPointer);
/* Arc reject. */
head_sec=GetThisSectionData(marineStatusPointer->HModelController.section_data,"head");
if (head_sec) {
WtoL=head_sec->SecMat;
sourcepos=head_sec->World_Offset;
} else {
WtoL=sbPtr->DynPtr->OrientMat;
GetTargetingPointOfObject_Far(sbPtr,&sourcepos);
}
GetTargetingPointOfObject_Far(target,&targetpos);
offset.vx=sourcepos.vx-targetpos.vx;
offset.vy=sourcepos.vy-targetpos.vy;
offset.vz=sourcepos.vz-targetpos.vz;
TransposeMatrixCH(&WtoL);
RotateVector(&offset,&WtoL);
frustrum_test=MarineSight_FrustrumReject(sbPtr,&offset,target);
}
break;
case I_BehaviourXenoborg:
{
MATRIXCH WtoL;
VECTORCH offset, sourcepos, targetpos;
XENO_STATUS_BLOCK *xenoStatusPointer;
SECTION_DATA *head_sec;
LOCALASSERT(sbPtr);
LOCALASSERT(sbPtr->containingModule);
xenoStatusPointer = (XENO_STATUS_BLOCK *)(sbPtr->SBdataptr);
LOCALASSERT(xenoStatusPointer);
/* Arc reject. */
head_sec=GetThisSectionData(xenoStatusPointer->HModelController.section_data,"head");
if (head_sec) {
WtoL=head_sec->SecMat;
sourcepos=head_sec->World_Offset;
} else {
WtoL=sbPtr->DynPtr->OrientMat;
GetTargetingPointOfObject_Far(sbPtr,&sourcepos);
}
GetTargetingPointOfObject_Far(target,&targetpos);
offset.vx=sourcepos.vx-targetpos.vx;
offset.vy=sourcepos.vy-targetpos.vy;
offset.vz=sourcepos.vz-targetpos.vz;
TransposeMatrixCH(&WtoL);
RotateVector(&offset,&WtoL);
frustrum_test=XenoSight_FrustrumReject(sbPtr,&offset);
}
break;
case I_BehaviourAutoGun:
{
/* Less pretentious, based on the SB. */
MATRIXCH WtoL;
VECTORCH offset, sourcepos, targetpos;
/* Arc reject. */
WtoL=sbPtr->DynPtr->OrientMat;
GetTargetingPointOfObject_Far(sbPtr,&sourcepos);
GetTargetingPointOfObject_Far(target,&targetpos);
offset.vx=sourcepos.vx-targetpos.vx;
offset.vy=sourcepos.vy-targetpos.vy;
offset.vz=sourcepos.vz-targetpos.vz;
TransposeMatrixCH(&WtoL);
RotateVector(&offset,&WtoL);
frustrum_test=AGunSight_FrustrumReject(&offset);
}
break;
default:
frustrum_test=1;
break;
}
if (frustrum_test) {
RotateVector(&eyePosition,&(sbPtr->DynPtr->OrientMat));
eyePosition.vx += sbPtr->DynPtr->Position.vx;
eyePosition.vy += sbPtr->DynPtr->Position.vy;
eyePosition.vz += sbPtr->DynPtr->Position.vz;
return IsThisObjectVisibleFromThisPosition_WithIgnore(target->SBdptr,sbPtr->SBdptr,&eyePosition,NPC_MAX_VIEWRANGE);
}
}
return(0);
}

3
3dc/avp/AI_Sight.h Normal file
View file

@ -0,0 +1,3 @@
#define NPC_MAX_VIEWRANGE (50000)
extern int NPCCanSeeTarget(STRATEGYBLOCK *sbptr, STRATEGYBLOCK *target, int viewRange);

7
3dc/avp/AVPVIEW.H Normal file
View file

@ -0,0 +1,7 @@
/* KJL 10:49:41 04/21/97 - avpview.h */
extern void AvpShowViews(void);
extern void InitCameraValues(void);
extern void LightSourcesInRangeOfObject(DISPLAYBLOCK *dptr);
extern VIEWDESCRIPTORBLOCK *Global_VDB_Ptr;

1019
3dc/avp/Avpview.c Normal file

File diff suppressed because it is too large Load diff

2496
3dc/avp/BH_ALIEN.C Normal file

File diff suppressed because it is too large Load diff

260
3dc/avp/BH_ALIEN.H Normal file
View file

@ -0,0 +1,260 @@
/*--------------Patrick 7/11/96----------------
Header file for Alien AI support functions
---------------------------------------------*/
#ifndef _bhalien_h_
#define _bhalien_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_pred.h"
/*--------------------------------------------
Enum of alien behaviour states
--------------------------------------------*/
typedef enum AlienBhState
{
ABS_Wait,
ABS_Approach,
ABS_Hunt,
ABS_Wander,
ABS_Retreat,
ABS_Attack,
ABS_Avoidance,
ABS_Dying,
ABS_Pounce,
ABS_Jump,
ABS_Dormant,
ABS_Awakening,
ABS_Taunting,
}ALIEN_BHSTATE;
/*--------------------------------------------
Enum of alien animation sequences
--------------------------------------------*/
typedef enum AlienSequence
{
ASQ_Run,
ASQ_StandingAttack_Claw,
ASQ_Crawl,
ASQ_Stand,
ASQ_Crouch,
ASQ_CrouchedAttack_Claw,
ASQ_CrawlingAttack_Claw,
ASQ_RunningAttack_Claw,
ASQ_Pain,
ASQ_Jump,
/* Additions by ChrisF, 20/4/98 */
ASQ_StandingTailPoise,
ASQ_StandingTailStrike,
ASQ_CrouchedTailPoise,
ASQ_CrouchedTailStrike,
ASQ_RunningTailPoise,
ASQ_RunningTailStrike,
ASQ_CrawlingTailPoise,
ASQ_CrawlingTailStrike,
ASQ_Eat,
ASQ_Pounce,
ASQ_JumpingTailPoise,
ASQ_JumpingTailStrike,
ASQ_Taunt,
ASQ_CrouchEat,
ASQ_Scamper,
/* More additions for reversing, 8/5/98 */
ASQ_Run_Backwards,
ASQ_Crawl_Backwards,
ASQ_RunningAttack_Claw_Backwards,
ASQ_RunningTailPoise_Backwards,
ASQ_RunningTailStrike_Backwards,
ASQ_CrawlingTailPoise_Backwards,
ASQ_CrawlingTailStrike_Backwards,
ASQ_CrawlingAttack_Claw_Backwards,
ASQ_Scamper_Backwards,
}ALIEN_SEQUENCE;
#include "sequnces.h"
typedef enum AlienMissions {
AM_UndefinedBehaviour, // Should do nothing.
AM_Hunt,
AM_GlobalHunt,
} ALIEN_MISSION;
typedef enum AlienType {
AT_Standard=0,
AT_Predalien,
AT_Praetorian,
} ALIEN_TYPE;
/*--------------------------------------------
Alien behaviour data block
--------------------------------------------*/
typedef struct alienStatusBlock
{
ALIEN_TYPE Type;
signed char Health;
int GibbFactor;
int MaxSpeed;
int Wounds;
int last_anim_length;
ALIEN_BHSTATE BehaviourState;
ATTACK_DATA *current_attack;
int PounceDetected;
int JumpDetected;
int EnablePounce;
int EnableWaypoints;
int PreferToCrouch;
MODULE *my_containing_module;
AIMODULE *huntingModule;
int incidentFlag;
int incidentTimer;
STRATEGYBLOCK *Target;
char Target_SBname[SB_NAME_LENGTH];
ALIEN_MISSION Mission;
int CurveRadius;
int CurveLength;
int CurveTimeOut;
int FarStateTimer;
int NearStateTimer;
int IAmCrouched;
NPC_MOVEMENTDATA moveData;
NPC_WANDERDATA wanderData;
NPC_AVOIDANCEMANAGER avoidanceManager;
WAYPOINT_MANAGER waypointManager;
HMODELCONTROLLER HModelController;
char death_target_ID[SB_NAME_LENGTH]; //another strategy can be notified of the alien's death
STRATEGYBLOCK* death_target_sbptr;
STRATEGYBLOCK* generator_sbptr;//0 unless created by a generator
DPID aliensIgniterId;//Which player in a multiplayer game toasted this poor beast?
int soundHandle;
int soundHandle2;
/*The following three values are used by the extrapolation code for network games.
It doesn't particularly matter if they aren't initialised*/
int timeOfLastSend;
VECTORCH lastFacingSent;
VECTORCH lastVelocitySent;
}ALIEN_STATUS_BLOCK;
/*--------------------------------------------
Tools data template
--------------------------------------------*/
typedef struct tools_data_alien
{
struct vectorch position;
int shapeIndex;
char nameID[SB_NAME_LENGTH];
char death_target_ID[SB_NAME_LENGTH];
ALIEN_TYPE type;
int start_inactive;
struct euler starteuler;
}TOOLS_DATA_ALIEN;
/*--------------------------------------------
Defines
--------------------------------------------*/
#define ULTRAVIOLENCE 0
#define ALIEN_STATE_PRINT 0
#define WOUNDING_SPEED_EFFECTS 1
#define ALIEN_STARTING_HEALTH (30)
#if PSX||Saturn
#define NO_OF_FRAGMENTS_FROM_DEAD_ALIEN (5)
#else
#define NO_OF_FRAGMENTS_FROM_DEAD_ALIEN (10)
#endif
/* random time between 1.5 and 2 seconds,in fixed point, with granularity 1/32th second */
#if ULTRAVIOLENCE
#define ALIEN_FAR_MOVE_TIME ((48+(FastRandom()&0xF))*(ONE_FIXED>>7))
#else
#define ALIEN_FAR_MOVE_TIME ((48+(FastRandom()&0xF))*(ONE_FIXED>>5))
#endif
/* random time between 1.5 and 2 seconds,in fixed point, with granularity 1/32th second */
#define ALIEN_FAR_RETREAT_TIME ((48+(FastRandom()&0xF))*(ONE_FIXED>>5))
#define ALIEN_JUMPVELOCITY (8000)
#define ALIEN_FORWARDVELOCITY (12000)
#define ALIEN_CURVEDISTANCE (8000)
#define ALIEN_ATTACKDISTANCE_MIN (2000)
/* Above (1500) for Ken: reduced from 2000 */
/* 1/6/98, changed back to 2000. It was well bust. */
#define ALIEN_ATTACKDISTANCE_MAX (4000)
#define ALIEN_ATTACKRANGE (3000)
/* Range check for damage validity. */
#define ALIEN_ATTACKTIME (ONE_FIXED>>1)
/* random time between 1 and 2 seconds,in fixed point,with granularity 1/8th second */
#define ALIEN_NEARWAITTIME (ONE_FIXED+((FastRandom()&0x7)*(ONE_FIXED>>3)))
#define PREDALIEN_SPEED_FACTOR ((ONE_FIXED*8)/10)
#define PRAETORIAN_SPEED_FACTOR ((ONE_FIXED*8)/10)
#define PRAETORIAN_WALKSPEED_FACTOR ((ONE_FIXED*6)/5)
#define PRAETORIAN_CRAWLSPEED_FACTOR (ONE_FIXED*2)
#define ALIEN_POUNCE_MAXRANGE (12000)
#define ALIEN_POUNCE_STARTMAXRANGE (8000)
#define ALIEN_POUNCE_MINRANGE (3000)
#define ALIEN_JUMP_SPEED (25000)
#define PREDALIEN_JUMP_SPEED (25000)
#define PRAETORIAN_JUMP_SPEED (25000)
#define ALIEN_JUMPINESS (13106)
#define PREDALIEN_JUMPINESS (13106)
#define PRAETORIAN_JUMPINESS (13106)
#define ALIEN_MASS (160)
#define PREDALIEN_MASS (200)
#define PRAETORIAN_MASS (250)
#define ALL_NEW_AVOIDANCE_ALIEN 0
/*--------------------------------------------
Prototypes
--------------------------------------------*/
void CreateAlienDynamic(STRATEGYBLOCK *Generator , ALIEN_TYPE type_of_alien);
void InitAlienBehaviour(void* bhdata, STRATEGYBLOCK *sbPtr);
void AlienBehaviour(STRATEGYBLOCK *sbPtr);
void AlienIsDamaged(STRATEGYBLOCK *sbPtr, DAMAGE_PROFILE *damage, int multiple, int wounds,SECTION_DATA *Section,VECTORCH *incoming,DISPLAYBLOCK *frag);
void MakeAlienNear(STRATEGYBLOCK *sbPtr);
void MakeAlienFar(STRATEGYBLOCK *sbPtr);
int AlienShouldBeCrawling(STRATEGYBLOCK *sbPtr);
void SetAlienShapeAnimSequence(STRATEGYBLOCK *sbPtr,HMODEL_SEQUENCE_TYPES type, int subtype, int length);
void SetAlienShapeAnimSequence_Core(STRATEGYBLOCK *sbPtr,HMODEL_SEQUENCE_TYPES type, int subtype, int length, int tweeningtime);
int AlienIsAwareOfTarget(STRATEGYBLOCK *sbPtr);
int AlienHasPathToOfTarget(STRATEGYBLOCK *sbPtr);
int GetAlienSpeedFactor(STRATEGYBLOCK *sbPtr);
int GetAlienSpeedFactor_ForSequence(STRATEGYBLOCK *sbPtr, HMODEL_SEQUENCE_TYPES sequence_type,int subsequence);
void RecomputeAlienSpeed(STRATEGYBLOCK *sbPtr);
void Alien_GoToApproach(STRATEGYBLOCK *sbPtr);
void Alien_Awaken(STRATEGYBLOCK *sbPtr);
int AlienIsCrawling(STRATEGYBLOCK *sbPtr);
#ifdef __cplusplus
}
#endif
#endif

932
3dc/avp/BH_BINSW.C Normal file
View file

@ -0,0 +1,932 @@
#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "stratdef.h"
#include "gamedef.h"
#include "bh_types.h"
#include "bh_binsw.h"
#include "dynblock.h"
#include "dynamics.h"
#include "pldghost.h"
#define UseLocalAssert Yes
#include "ourasert.h"
#include "pmove.h"
#include "pvisible.h"
#include "plat_shp.h"
#include "psnd.h"
extern int NormalFrameTime;
extern int RealFrameTime;
extern int ReturnPlayerSecurityClearance(STRATEGYBLOCK *sbPtr, unsigned int securityLevel);
/*********************** SWITCH INIT *****************************/
void* BinarySwitchBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr)
{
BINARY_SWITCH_BEHAV_BLOCK *bs_bhv;
BIN_SWITCH_TOOLS_TEMPLATE *bs_tt;
int i;
GLOBALASSERT(sbptr);
bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)AllocateMem(sizeof(BINARY_SWITCH_BEHAV_BLOCK));
if (!bs_bhv)
{
memoryInitialisationFailure = 1;
return ((void *)NULL);
}
bs_bhv->bhvr_type = I_BehaviourBinarySwitch;
// from loaders
// 1 rest_state - on or off
// 2 mode
// 3 timer switch - time for reset
// 4 security clerance to operate
// 5 copy the target name
bs_tt = (BIN_SWITCH_TOOLS_TEMPLATE*)bhdata;
sbptr->shapeIndex = bs_tt->shape_num;
COPY_NAME(sbptr->SBname, bs_tt->nameID);
bs_bhv->bs_mode = bs_tt->mode;
bs_bhv->time_for_reset = bs_tt->time_for_reset;
bs_bhv->security_clerance = bs_tt->security_clearance;
bs_bhv->trigger_volume_min=bs_tt->trigger_volume_min;
bs_bhv->trigger_volume_max=bs_tt->trigger_volume_max;
bs_bhv->switch_flags=bs_tt->switch_flags;
bs_bhv->num_targets = bs_tt->num_targets;
if(bs_tt->num_targets)
{
bs_bhv->target_names = (SBNAMEBLOCK *)AllocateMem(sizeof(SBNAMEBLOCK) * bs_tt->num_targets);
if (!bs_bhv->target_names)
{
memoryInitialisationFailure = 1;
return ((void *)NULL);
}
bs_bhv->request_messages = (int *)AllocateMem(sizeof(int) * bs_tt->num_targets);
if (!bs_bhv->request_messages)
{
memoryInitialisationFailure = 1;
return ((void *)NULL);
}
bs_bhv->bs_targets = (STRATEGYBLOCK **)AllocateMem(sizeof(STRATEGYBLOCK *) * bs_tt->num_targets);
if (!bs_bhv->bs_targets)
{
memoryInitialisationFailure = 1;
return ((void *)NULL);
}
}
else
{
bs_bhv->target_names=0;
bs_bhv->request_messages=0;
bs_bhv->bs_targets=0;
}
for (i=0; i<bs_tt->num_targets; i++)
{
COPY_NAME(bs_bhv->target_names[i].name, bs_tt->target_names[i].name);
bs_bhv->request_messages[i]=bs_tt->request_messages[i];
bs_bhv->bs_targets[i] = 0;
}
if(sbptr->DynPtr) //there may be no shape
{
sbptr->DynPtr->Position = sbptr->DynPtr->PrevPosition = bs_tt->position;
sbptr->DynPtr->OrientEuler = bs_tt->orientation;
CreateEulerMatrix(&sbptr->DynPtr->OrientEuler, &sbptr->DynPtr->OrientMat);
TransposeMatrixCH(&sbptr->DynPtr->OrientMat);
}
// set up the animation control
if(sbptr->shapeIndex!=-1)
{
int item_num;
TXACTRLBLK **pptxactrlblk;
int shape_num = bs_tt->shape_num;
SHAPEHEADER *shptr = GetShapeData(shape_num);
SetupPolygonFlagAccessForShape(shptr);
pptxactrlblk = &bs_bhv->bs_tac;
for(item_num = 0; item_num < shptr->numitems; item_num ++)
{
POLYHEADER *poly = (POLYHEADER*)(shptr->items[item_num]);
LOCALASSERT(poly);
if((Request_PolyFlags((void *)poly)) & iflag_txanim)
{
TXACTRLBLK *pnew_txactrlblk;
int num_seq = 0;
pnew_txactrlblk = AllocateMem(sizeof(TXACTRLBLK));
if (pnew_txactrlblk)
{
pnew_txactrlblk->tac_flags = 0;
pnew_txactrlblk->tac_item = item_num;
pnew_txactrlblk->tac_sequence = bs_tt->starts_on;
pnew_txactrlblk->tac_node = 0;
pnew_txactrlblk->tac_txarray = GetTxAnimArrayZ(shape_num, item_num);
pnew_txactrlblk->tac_txah_s = GetTxAnimHeaderFromShape(pnew_txactrlblk, shape_num);
while(pnew_txactrlblk->tac_txarray[num_seq+1])num_seq++;
// Assert does not work at this point so
GLOBALASSERT(num_seq==2);
/* set the flags in the animation header */
// we only ever have one frame of animation per sequence -
// nb this can change talk to richard - one sequence with two frames
// or mutliple sequences???
pnew_txactrlblk->tac_txah.txa_flags |= txa_flag_play;
/* change the value held in pptxactrlblk
which point to the previous structures "next"
pointer*/
*pptxactrlblk = pnew_txactrlblk;
pptxactrlblk = &pnew_txactrlblk->tac_next;
}
else
{
memoryInitialisationFailure = 1;
}
}
}
*pptxactrlblk=0;
}
else
{
//no shape - so there won't be any animation
bs_bhv->bs_tac=0;
}
bs_bhv->bs_dtype = binswitch_no_display;
if (bs_bhv->bs_tac)
{
bs_bhv->bs_dtype = binswitch_animate_me;
}
bs_bhv->bs_track=bs_tt->track;
if (bs_bhv->bs_track)
{
bs_bhv->bs_track->sbptr=sbptr;
if (bs_bhv->bs_dtype == binswitch_animate_me)
{
bs_bhv->bs_dtype = binswitch_animate_and_move_me;
}
else
{
bs_bhv->bs_dtype = binswitch_move_me;
}
}
#if !Saturn
// GLOBALASSERT(bs_bhv->bs_dtype != binswitch_no_display);
#endif
// fill in the rest ourselves
bs_bhv->request = 0;
bs_bhv->state = bs_tt->starts_on;
bs_bhv->timer = 0;
bs_bhv->switch_off_message_same=bs_tt->switch_off_message_same;
bs_bhv->switch_off_message_none=bs_tt->switch_off_message_none;
bs_bhv->soundHandle = SOUND_NOACTIVEINDEX;
bs_bhv->triggered_last = No;
if(bs_bhv->bs_mode==I_bswitch_time_delay_autoexec)
{
//set request and then treat as normal time delay switch
bs_bhv->bs_mode=I_bswitch_time_delay;
bs_bhv->request=I_request_on;
}
if(bs_bhv->state)
{
bs_bhv->timer=bs_bhv->time_for_reset;
if(bs_bhv->bs_track)
{
//set the track to the end position
bs_bhv->bs_track->current_section=(bs_bhv->bs_track->num_sections-1);
bs_bhv->bs_track->timer=bs_bhv->bs_track->sections[bs_bhv->bs_track->current_section].time_for_section;
bs_bhv->bs_track->playing=1;
Update_Track_Position(bs_bhv->bs_track);
}
}
bs_bhv->TimeUntilNetSynchAllowed=0;
return((void*)bs_bhv);
}
void BinarySwitchBehaveFun(STRATEGYBLOCK* sbptr)
{
BINARY_SWITCH_BEHAV_BLOCK *bs_bhv;
DISPLAYBLOCK* dptr;
int oldState;
GLOBALASSERT(sbptr);
bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)sbptr->SBdataptr;
GLOBALASSERT((bs_bhv->bhvr_type == I_BehaviourBinarySwitch));
dptr = sbptr->SBdptr;
/*
if(AvP.Network!=I_No_Network) return;
*/
/******
What I need to do - check to see if we have
a request - requests have different effects depending on
the mode - so we have to switch on the mode
*****/
if (bs_bhv->bs_dtype == binswitch_animate_me || bs_bhv->bs_dtype == binswitch_animate_and_move_me)
{
if(dptr)
dptr->ObTxAnimCtrlBlks = bs_bhv->bs_tac;
}
if (!ReturnPlayerSecurityClearance(0,bs_bhv->security_clerance) && bs_bhv->security_clerance)
{
bs_bhv->request = I_no_request;
return;
}
if(AvP.Network != I_No_Network)
{
/*
Every time a switch is updated there is a time delay of 5 seconds before the
switch can next be changed by the host sending synch messages.
This prevents the host machine from resetting a switch before it learns that
it has been pressed
*/
if(bs_bhv->request == I_no_request)
{
bs_bhv->TimeUntilNetSynchAllowed-=RealFrameTime;
if(bs_bhv->TimeUntilNetSynchAllowed<0)
{
bs_bhv->TimeUntilNetSynchAllowed=0;
}
}
else
{
bs_bhv->TimeUntilNetSynchAllowed=5*ONE_FIXED;
}
}
if(bs_bhv->switch_flags && SwitchFlag_UseTriggerVolume)
{
/*See if switch has been set off*/
int i;
for (i=0; i<NumActiveStBlocks; i++)
{
int needToTest = 0;
STRATEGYBLOCK *sbPtr = ActiveStBlockList[i];
if (sbPtr->DynPtr)
{
if (sbPtr->SBdptr == Player)
{
needToTest = 1;
}
else if (sbPtr->I_SBtype == I_BehaviourNetGhost)
{
NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->SBdataptr;
if ((ghostData->type == I_BehaviourMarinePlayer)
||(ghostData->type == I_BehaviourAlienPlayer)
||(ghostData->type == I_BehaviourPredatorPlayer))
needToTest = 1;
}
}
if(needToTest&&
sbPtr->DynPtr->Position.vx > bs_bhv->trigger_volume_min.vx &&
sbPtr->DynPtr->Position.vx < bs_bhv->trigger_volume_max.vx &&
sbPtr->DynPtr->Position.vy > bs_bhv->trigger_volume_min.vy &&
sbPtr->DynPtr->Position.vy < bs_bhv->trigger_volume_max.vy &&
sbPtr->DynPtr->Position.vz > bs_bhv->trigger_volume_min.vz &&
sbPtr->DynPtr->Position.vz < bs_bhv->trigger_volume_max.vz)
{
bs_bhv->request=I_request_on;
break;
}
}
}
if (bs_bhv->request == I_request_on)
{
if (bs_bhv->triggered_last)
{
bs_bhv->request = I_no_request;
}
else
{
bs_bhv->triggered_last = Yes;
}
}
else
{
bs_bhv->triggered_last = No;
}
switch(bs_bhv->bs_mode)
{
case I_bswitch_timer:
{
if(bs_bhv->request == I_request_on && !bs_bhv->state)
{
bs_bhv->timer = bs_bhv->time_for_reset;
if(sbptr->shapeIndex!=-1)//don't play a sound if there is no shape
{
if(!bs_bhv->bs_track || !bs_bhv->bs_track->sound)
{
if (bs_bhv->soundHandle == SOUND_NOACTIVEINDEX)
{
Sound_Play(SID_SWITCH1,"eh",&bs_bhv->soundHandle);
}
}
}
if (bs_bhv->bs_dtype == binswitch_move_me || bs_bhv->bs_dtype == binswitch_animate_and_move_me)
{
// moving switch
bs_bhv->new_state = 1;
bs_bhv->new_request = 1;
bs_bhv->bs_track->reverse=0;
Start_Track_Playing(bs_bhv->bs_track);
bs_bhv->mode_store = bs_bhv->bs_mode;
bs_bhv->bs_mode = I_bswitch_moving;
}
else
{
int i;
for (i=0; i<bs_bhv->num_targets; i++)
{
if (bs_bhv->bs_targets[i])
{
RequestState(bs_bhv->bs_targets[i],bs_bhv->request_messages[i], sbptr);
}
}
bs_bhv->state = 1;
}
// swap sequence
if(bs_bhv->bs_tac)
{
bs_bhv->bs_tac->tac_sequence = 1;
bs_bhv->bs_tac->tac_txah_s = GetTxAnimHeaderFromShape(bs_bhv->bs_tac, (sbptr->shapeIndex));
}
}
else if(bs_bhv->timer > 0)
{
bs_bhv->timer -= NormalFrameTime;
if(bs_bhv->timer <= 0)
{
if(AvP.Network != I_No_Network)
{
bs_bhv->TimeUntilNetSynchAllowed=5*ONE_FIXED;
}
if(sbptr->shapeIndex!=-1)//don't play a sound if there is no shape
{
if (bs_bhv->soundHandle == SOUND_NOACTIVEINDEX)
{
if(!bs_bhv->bs_track || !bs_bhv->bs_track->sound)
{
Sound_Play(SID_SWITCH2,"eh",&bs_bhv->soundHandle);
}
}
}
bs_bhv->state = 0;
if (bs_bhv->bs_dtype == binswitch_move_me || bs_bhv->bs_dtype == binswitch_animate_and_move_me)
{
// moving switch
bs_bhv->new_state = 0;
bs_bhv->new_request = -1; //the 'off' message will be sent as soon as the timer finishes
bs_bhv->bs_track->reverse=1;
Start_Track_Playing(bs_bhv->bs_track);
bs_bhv->mode_store = bs_bhv->bs_mode;
bs_bhv->bs_mode = I_bswitch_moving;
}
if(!bs_bhv->switch_off_message_none)
{
//send the 'off' message
int i;
for (i=0; i<bs_bhv->num_targets; i++)
{
if (bs_bhv->bs_targets[i])
{
RequestState(bs_bhv->bs_targets[i],bs_bhv->request_messages[i]^(!bs_bhv->switch_off_message_same), sbptr);
}
}
}
if(bs_bhv->bs_tac)
{
bs_bhv->bs_tac->tac_sequence = 0;
bs_bhv->bs_tac->tac_txah_s = GetTxAnimHeaderFromShape(bs_bhv->bs_tac, (sbptr->shapeIndex));
}
}
}
break;
}
case I_bswitch_toggle:
{
if(bs_bhv->request == I_no_request)
return;
/* change the state and request the new state in
the target */
if(sbptr->shapeIndex!=-1)//don't play a sound if there is no shape
{
if (bs_bhv->soundHandle == SOUND_NOACTIVEINDEX)
{
if(!bs_bhv->bs_track || !bs_bhv->bs_track->sound)
{
Sound_Play(SID_SWITCH1,"eh",&bs_bhv->soundHandle);
}
}
}
if(bs_bhv->bs_dtype == binswitch_move_me || bs_bhv->bs_dtype == binswitch_animate_and_move_me)
{
// moving switch
bs_bhv->new_state = !bs_bhv->state;
if(bs_bhv->new_state)
{
bs_bhv->new_request = 1;
}
else
{
//check to see what the switch off request is
if(bs_bhv->switch_off_message_same)
bs_bhv->new_request=1;
else if(bs_bhv->switch_off_message_none)
bs_bhv->new_request=-1;
else
bs_bhv->new_request=0;
}
bs_bhv->mode_store = bs_bhv->bs_mode;
bs_bhv->bs_mode = I_bswitch_moving;
bs_bhv->bs_track->reverse=bs_bhv->state;
Start_Track_Playing(bs_bhv->bs_track);
}
else
{
bs_bhv->state = !bs_bhv->state;
{
int i;
for (i=0; i<bs_bhv->num_targets; i++)
{
if (bs_bhv->bs_targets[i])
{
if(bs_bhv->state)
{
RequestState(bs_bhv->bs_targets[i], bs_bhv->request_messages[i], sbptr);
}
else
{
if(!bs_bhv->switch_off_message_none)
{
RequestState(bs_bhv->bs_targets[i], bs_bhv->request_messages[i]^(!bs_bhv->switch_off_message_same), sbptr);
}
}
}
}
}
}
if(bs_bhv->bs_tac)
{
bs_bhv->bs_tac->tac_sequence = bs_bhv->state ;
bs_bhv->bs_tac->tac_txah_s = GetTxAnimHeaderFromShape(bs_bhv->bs_tac, (sbptr->shapeIndex));
}
break;
}
case I_bswitch_wait:
{
if(bs_bhv->request == I_no_request)
return;
oldState = bs_bhv->state;
if(bs_bhv->request == I_request_on)
{
if(bs_bhv->state)
break;//switch cannot be activated again until it is reset
if(bs_bhv->bs_dtype == binswitch_move_me || bs_bhv->bs_dtype == binswitch_animate_and_move_me)
{
// moving switch
bs_bhv->new_state = 1;
bs_bhv->new_request = 1;
bs_bhv->mode_store = bs_bhv->bs_mode;
bs_bhv->bs_mode = I_bswitch_moving;
bs_bhv->bs_track->reverse=0;
Start_Track_Playing(bs_bhv->bs_track);
}
else
{
int i;
bs_bhv->state = 1;
for (i=0; i<bs_bhv->num_targets; i++)
{
if (bs_bhv->bs_targets[i])
{
RequestState(bs_bhv->bs_targets[i],bs_bhv->request_messages[i] , sbptr);
}
}
}
}
else
{
if(!bs_bhv->state) break; //can only be deactivated if currently on
if(bs_bhv->bs_dtype == binswitch_move_me || bs_bhv->bs_dtype == binswitch_animate_and_move_me)
{
// moving switch
bs_bhv->new_state = 0;
//check to see what the switch off request is
if(bs_bhv->switch_off_message_same)
bs_bhv->new_request=1;
else if(bs_bhv->switch_off_message_none)
bs_bhv->new_request=-1;
else
bs_bhv->new_request=0;
bs_bhv->mode_store = bs_bhv->bs_mode;
bs_bhv->bs_mode = I_bswitch_moving;
bs_bhv->bs_track->reverse=1;
Start_Track_Playing(bs_bhv->bs_track);
}
else
{
int i;
bs_bhv->state = 0;
if(!bs_bhv->switch_off_message_none)
{
for (i=0; i<bs_bhv->num_targets; i++)
{
if (bs_bhv->bs_targets[i])
{
RequestState(bs_bhv->bs_targets[i],bs_bhv->request_messages[i]^(!bs_bhv->switch_off_message_same), sbptr);
}
}
}
}
}
if(sbptr->shapeIndex!=-1)//don't play a sound if there is no shape
{
if (oldState == bs_bhv->state)
{
if (bs_bhv->soundHandle == SOUND_NOACTIVEINDEX)
{
if(!bs_bhv->bs_track || !bs_bhv->bs_track->sound)
{
Sound_Play(SID_SWITCH2,"eh",&bs_bhv->soundHandle);
}
}
}
else
{
if (bs_bhv->soundHandle == SOUND_NOACTIVEINDEX)
{
if(!bs_bhv->bs_track || !bs_bhv->bs_track->sound)
{
Sound_Play(SID_SWITCH1,"eh",&bs_bhv->soundHandle);
}
}
}
}
if(bs_bhv->bs_tac)
{
bs_bhv->bs_tac->tac_sequence = bs_bhv->state ? 1 : 0;
bs_bhv->bs_tac->tac_txah_s = GetTxAnimHeaderFromShape(bs_bhv->bs_tac, (sbptr->shapeIndex));
}
break;
}
case I_bswitch_moving:
{
Update_Track_Position(bs_bhv->bs_track);
if(!bs_bhv->bs_track->playing)
{
bs_bhv->bs_mode = bs_bhv->mode_store;
bs_bhv->state = bs_bhv->new_state;
if(bs_bhv->bs_tac)
{
bs_bhv->bs_tac->tac_sequence = bs_bhv->state ? 1 : 0;
bs_bhv->bs_tac->tac_txah_s = GetTxAnimHeaderFromShape(bs_bhv->bs_tac, (sbptr->shapeIndex));
}
if (bs_bhv->new_request != -1)
{
int i;
for (i=0; i<bs_bhv->num_targets; i++)
{
if (bs_bhv->bs_targets[i])
{
if(bs_bhv->new_request)
RequestState(bs_bhv->bs_targets[i],bs_bhv->request_messages[i] , sbptr);
else
RequestState(bs_bhv->bs_targets[i],bs_bhv->request_messages[i]^1, sbptr);
}
}
}
}
}
break;
case I_bswitch_time_delay :
{
if(bs_bhv->timer>0)
{
bs_bhv->timer-=NormalFrameTime;
if(bs_bhv->timer<=0 || bs_bhv->request == I_request_off)
{
//time to send the request
int i;
bs_bhv->timer=0;
//only send message if we got here through the time running out
if(bs_bhv->request != I_request_off)
{
for (i=0; i<bs_bhv->num_targets; i++)
{
if (bs_bhv->bs_targets[i])
{
RequestState(bs_bhv->bs_targets[i],bs_bhv->request_messages[i] , sbptr);
}
}
}
bs_bhv->state = 0;
// swap sequence
if(bs_bhv->bs_tac)
{
bs_bhv->bs_tac->tac_sequence = 0;
bs_bhv->bs_tac->tac_txah_s = GetTxAnimHeaderFromShape(bs_bhv->bs_tac, (sbptr->shapeIndex));
}
if(AvP.Network != I_No_Network)
{
bs_bhv->TimeUntilNetSynchAllowed=5*ONE_FIXED;
}
}
}
else
{
if(bs_bhv->request == I_request_on && bs_bhv->state == 0)
{
bs_bhv->timer = bs_bhv->time_for_reset;
if(sbptr->shapeIndex!=-1)//don't play a sound if there is no shape
{
if (bs_bhv->soundHandle == SOUND_NOACTIVEINDEX)
{
if(!bs_bhv->bs_track || !bs_bhv->bs_track->sound)
{
Sound_Play(SID_SWITCH1,"eh",&bs_bhv->soundHandle);
}
}
}
bs_bhv->state = 1;
// swap sequence
if(bs_bhv->bs_tac)
{
bs_bhv->bs_tac->tac_sequence = 1;
bs_bhv->bs_tac->tac_txah_s = GetTxAnimHeaderFromShape(bs_bhv->bs_tac, (sbptr->shapeIndex));
}
}
}
}
break;
default:
GLOBALASSERT(2<1);
}
bs_bhv->request = I_no_request;
}
#define BINARYSWITCHSYNCH_ON 0
#define BINARYSWITCHSYNCH_OFF 1
#define BINARYSWITCHSYNCH_IGNORE 2
int BinarySwitchGetSynchData(STRATEGYBLOCK* sbPtr)
{
BINARY_SWITCH_BEHAV_BLOCK *bs_bhv;
GLOBALASSERT(sbPtr);
bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)sbPtr->SBdataptr;
GLOBALASSERT((bs_bhv->bhvr_type == I_BehaviourBinarySwitch));
//don't try to synch moving switches
if(bs_bhv->bs_mode==I_bswitch_moving)
{
return BINARYSWITCHSYNCH_IGNORE;
}
if(bs_bhv->state)
return BINARYSWITCHSYNCH_ON;
else
return BINARYSWITCHSYNCH_OFF;
}
void BinarySwitchSetSynchData(STRATEGYBLOCK* sbPtr,int status)
{
BINARY_SWITCH_BEHAV_BLOCK *bs_bhv;
GLOBALASSERT(sbPtr);
bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)sbPtr->SBdataptr;
GLOBALASSERT((bs_bhv->bhvr_type == I_BehaviourBinarySwitch));
if(bs_bhv->TimeUntilNetSynchAllowed>0)
{
//ignore this attempt to synch the switch
return;
}
//don't try to synch moving switches
if(bs_bhv->bs_mode==I_bswitch_moving)
{
return;
}
switch(status)
{
case BINARYSWITCHSYNCH_ON :
if(!bs_bhv->state)
{
//this switch should be on
RequestState(sbPtr,1,0);
}
break;
case BINARYSWITCHSYNCH_OFF :
if(bs_bhv->state)
{
//this switch should be off
RequestState(sbPtr,0,0);
}
break;
}
}
/*--------------------**
** Loading and Saving **
**--------------------*/
#include "savegame.h"
typedef struct binary_switch_save_block
{
SAVE_BLOCK_STRATEGY_HEADER header;
BINARY_SWITCH_REQUEST_STATE request;
BOOL state;
BSWITCH_MODE bs_mode;
int timer;
BSWITCH_MODE mode_store;
BOOL new_state;
int new_request;
BOOL triggered_last;
int txanim_sequence;
}BINARY_SWITCH_SAVE_BLOCK;
//defines for load/save macros
#define SAVELOAD_BLOCK block
#define SAVELOAD_BEHAV bs_bhv
void LoadStrategy_BinarySwitch(SAVE_BLOCK_STRATEGY_HEADER* header)
{
STRATEGYBLOCK* sbPtr;
BINARY_SWITCH_BEHAV_BLOCK *bs_bhv;
BINARY_SWITCH_SAVE_BLOCK* block = (BINARY_SWITCH_SAVE_BLOCK*) header;
//check the size of the save block
if(header->size!=sizeof(*block)) return;
//find the existing strategy block
sbPtr = FindSBWithName(header->SBname);
if(!sbPtr) return;
//make sure the strategy found is of the right type
if(sbPtr->I_SBtype != I_BehaviourBinarySwitch) return;
bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)sbPtr->SBdataptr;
//start copying stuff
COPYELEMENT_LOAD(request)
COPYELEMENT_LOAD(state)
COPYELEMENT_LOAD(bs_mode)
COPYELEMENT_LOAD(timer)
COPYELEMENT_LOAD(mode_store)
COPYELEMENT_LOAD(new_state)
COPYELEMENT_LOAD(new_request)
COPYELEMENT_LOAD(triggered_last)
//set the texture animation sequence
if(bs_bhv->bs_tac)
{
bs_bhv->bs_tac->tac_sequence = block->txanim_sequence;
bs_bhv->bs_tac->tac_txah_s = GetTxAnimHeaderFromShape(bs_bhv->bs_tac, (sbPtr->shapeIndex));
}
//load the track position , if the switch has one
if(bs_bhv->bs_track)
{
SAVE_BLOCK_HEADER* track_header = GetNextBlockIfOfType(SaveBlock_Track);
if(track_header)
{
LoadTrackPosition(track_header,bs_bhv->bs_track);
}
}
}
void SaveStrategy_BinarySwitch(STRATEGYBLOCK* sbPtr)
{
BINARY_SWITCH_SAVE_BLOCK *block;
BINARY_SWITCH_BEHAV_BLOCK *bs_bhv;
bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)sbPtr->SBdataptr;
GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
//start copying stuff
COPYELEMENT_SAVE(request)
COPYELEMENT_SAVE(state)
COPYELEMENT_SAVE(bs_mode)
COPYELEMENT_SAVE(timer)
COPYELEMENT_SAVE(mode_store)
COPYELEMENT_SAVE(new_state)
COPYELEMENT_SAVE(new_request)
COPYELEMENT_SAVE(triggered_last)
//get the animation sequence
if(bs_bhv->bs_tac)
{
block->txanim_sequence = bs_bhv->bs_tac->tac_sequence;
}
else
{
block->txanim_sequence = 0;
}
//save the track position , if the switch has one
if(bs_bhv->bs_track)
{
SaveTrackPosition(bs_bhv->bs_track);
}
}

152
3dc/avp/BH_BINSW.H Normal file
View file

@ -0,0 +1,152 @@
#ifndef _bh_binsw_h_
#define _bh_binsw_h_ 1
#include "3dc.h"
#include "track.h"
#ifdef __cplusplus
extern "C" {
#endif
extern void* BinarySwitchBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr);
extern void BinarySwitchBehaveFun(STRATEGYBLOCK* sbptr);
extern int BinarySwitchGetSynchData(STRATEGYBLOCK* sbptr);
extern void BinarySwitchSetSynchData(STRATEGYBLOCK* sbptr,int status);
/******************** BinarySwitch ***********************/
// enum to decxribe how the switch works
// action is always dependent on the SB block of the target
typedef enum binary_switch_mode
{
I_bswitch_timer,
I_bswitch_wait,
I_bswitch_toggle,
I_bswitch_moving,
I_bswitch_time_delay,
I_bswitch_time_delay_autoexec,//timer starts as soon as game starts
} BSWITCH_MODE;
typedef enum binary_switch_req_states
{
I_no_request,
I_request_on,
I_request_off,
}BINARY_SWITCH_REQUEST_STATE;
typedef enum bswitch_display_types
{
binswitch_no_display,
binswitch_animate_me,
binswitch_move_me,
binswitch_animate_and_move_me,
} BSWITCH_DISPLAY_TYPES;
typedef enum bs_move_dir
{
bs_start_to_end,
bs_end_to_start,
} BS_MOVE_DIR;
// require three states for rest fso we can ignore
#define SwitchFlag_UseTriggerVolume 0x00000001 //switch triggered by walking into trigger volume
typedef struct binary_switch
{
AVP_BEHAVIOUR_TYPE bhvr_type;
BINARY_SWITCH_REQUEST_STATE request;
BOOL state;
BSWITCH_MODE bs_mode;
int num_targets;
SBNAMEBLOCK * target_names;
int * request_messages;
STRATEGYBLOCK ** bs_targets;
int time_for_reset; // constant
int timer;
// stuff for showing how the switch displays its state
BSWITCH_DISPLAY_TYPES bs_dtype;
TXACTRLBLK *bs_tac; // animations
TRACK_CONTROLLER* bs_track;
// or positions
BSWITCH_MODE mode_store;
BOOL new_state;
int new_request;
int security_clerance; // what the plyer has to be to use this switch
int switch_flags;
VECTORCH trigger_volume_min;//for switches that can be set off by walking
VECTORCH trigger_volume_max;//into a given area
int soundHandle;
BOOL triggered_last;
unsigned int switch_off_message_same:1;
unsigned int switch_off_message_none:1;
int TimeUntilNetSynchAllowed;
}BINARY_SWITCH_BEHAV_BLOCK;
typedef struct bin_switch_tools_template
{
VECTORCH position;
EULER orientation;
int mode;
int time_for_reset;
int security_clearance;
int num_targets;
SBNAMEBLOCK * target_names;
int* request_messages;
int shape_num;
char nameID[SB_NAME_LENGTH];
TRACK_CONTROLLER* track;
int switch_flags;
VECTORCH trigger_volume_min;//for switches that can be set off by walking
VECTORCH trigger_volume_max;//into a given area
unsigned int starts_on:1;
unsigned int switch_off_message_same:1;
unsigned int switch_off_message_none:1;
} BIN_SWITCH_TOOLS_TEMPLATE;
#ifdef __cplusplus
};
#endif
#endif

63
3dc/avp/BH_FAR.H Normal file
View file

@ -0,0 +1,63 @@
/*------------------------Patrick 26/11/96-----------------------------
Header file for FAR AI alien behaviour
--------------------------------------------------------------------*/
#ifndef _bhfar_h_
#define _bhfar_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/* enum for far alien target module status */
typedef enum fnpc_targetmodulestatus
{
NPCTM_NoEntryPoint,
NPCTM_NormalRoom,
NPCTM_AirDuct,
NPCTM_LiftTeleport,
NPCTM_ProxDoorOpen,
NPCTM_ProxDoorNotOpen,
NPCTM_LiftDoorOpen,
NPCTM_LiftDoorNotOpen,
NPCTM_SecurityDoorOpen,
NPCTM_SecurityDoorNotOpen,
} NPC_TARGETMODULESTATUS;
/* prototypes */
extern void FarAlienBehaviour(STRATEGYBLOCK *sbPtr);
extern void BuildFarModuleLocs(void);
extern void KillFarModuleLocs(void);
extern void LocateFarNPCInModule(STRATEGYBLOCK *sbPtr, MODULE *targetModule);
extern void LocateFarNPCInAIModule(STRATEGYBLOCK *sbPtr, AIMODULE *targetModule);
extern NPC_TARGETMODULESTATUS GetTargetAIModuleStatus(STRATEGYBLOCK *sbPtr, AIMODULE *targetModule, int alien);
extern AIMODULE *FarNPC_GetTargetAIModuleForHunt(STRATEGYBLOCK *sbPtr,int alien);
extern AIMODULE *FarNPC_GetTargetAIModuleForGlobalHunt(STRATEGYBLOCK *sbPtr);
extern AIMODULE *FarNPC_GetTargetAIModuleForWander(STRATEGYBLOCK *sbPtr, AIMODULE *exception, int alien);
extern AIMODULE *FarNPC_GetTargetAIModuleForRetreat(STRATEGYBLOCK *sbPtr);
extern AIMODULE *FarNPC_GetTargetAIModuleForMarineRespond(STRATEGYBLOCK *sbPtr);
extern void FarNpc_FlipAround(STRATEGYBLOCK *sbPtr);
/* this define to help stop aliens coagulating in the environment */
#if SupportWindows95
#define MAX_GENERATORNPCSPERMODULE 5
#define MAX_VISIBLEGENERATORNPCS 8 //12
#else
/* PSX & Saturn*/
#define MAX_GENERATORNPCSPERMODULE 5
#define MAX_VISIBLEGENERATORNPCS 6
#endif
#ifdef __cplusplus
}
#endif
#endif

1335
3dc/avp/BH_FHUG.C Normal file

File diff suppressed because it is too large Load diff

112
3dc/avp/BH_FHUG.H Normal file
View file

@ -0,0 +1,112 @@
/* Patrick 27/2/97 --------------------------------------------
Header file for facehugger support functions
-------------------------------------------------------------*/
#ifndef _bhfhug_h_
#define _bhfhug_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_pred.h"
/* ------------------------------------------------------------
Some enums
-------------------------------------------------------------*/
typedef enum FhugSequence
{
FhSQ_Run,
FhSQ_Attack,
FhSQ_Stand,
FhSQ_Jump,
}FHUG_SEQUENCE;
typedef enum FhugHModelSequence {
FhSSQ_Stand = 0,
FhSSQ_Run,
FhSSQ_Dies,
FhSSQ_Jump,
FhSSQ_Attack,
} FHUG_HMODEL_SEQUENCE;
#include "sequnces.h"
typedef enum facehugger_near_bhstate
{
FHNS_Approach,
FHNS_Attack,
FHNS_Wait,
FHNS_Avoidance,
FHNS_Dying,
FHNS_Floating,
FHNS_Jumping,
FHNS_AboutToJump,
}FACEHUGGER_NEAR_BHSTATE;
/* ------------------------------------------------------------
Some structures
-------------------------------------------------------------*/
typedef struct facehuggerStatusBlock
{
signed int health;
FACEHUGGER_NEAR_BHSTATE nearBehaviourState;
int stateTimer;
int DoomTimer;
int CurveRadius;
int CurveLength;
int CurveTimeOut;
unsigned int jumping :1;
NPC_MOVEMENTDATA moveData;
HMODELCONTROLLER HModelController;
int soundHandle;
int soundHandle2;
char death_target_ID[SB_NAME_LENGTH];
STRATEGYBLOCK* death_target_sbptr;
int death_target_request;
}FACEHUGGER_STATUS_BLOCK;
typedef struct tools_data_facehugger
{
struct vectorch position;
int shapeIndex;
char nameID[SB_NAME_LENGTH];
int startInactive;
char death_target_ID[SB_NAME_LENGTH];
int death_target_request;
}TOOLS_DATA_FACEHUGGER;
/* ------------------------------------------------------------
Some structures
-------------------------------------------------------------*/
#define FACEHUGGER_STARTING_HEALTH 5
#define NO_OF_FRAGMENTS_FROM_DEAD_FHUGA 10
#define FACEHUGGER_NEAR_SPEED 4000/* 8000 */
#define FACEHUGGER_JUMPSPEED 6000/* 10000 */
#define FACEHUGGER_JUMPDISTANCE 3000
#define FACEHUGGER_ATTACKYOFFSET (-300)/*300*/
#define FACEHUGGER_ATTACKZOFFSET (325)/*2000*/
#define FACEHUGGER_NEARATTACKTIME (ONE_FIXED>>2)
#define FACEHUGGER_NEARATTACKDAMAGE 10
#define FACEHUGGER_DYINGTIME (ONE_FIXED<<2)
#define FACEHUGGER_EXPIRY_TIME 5
#define FACEHUGGER_JUMP_SPEED (15000)
/* ------------------------------------------------------------
Some prototypes
-------------------------------------------------------------*/
void InitFacehuggerBehaviour(void* bhdata, STRATEGYBLOCK *sbPtr);
void FacehuggerBehaviour(STRATEGYBLOCK *sbPtr);
void MakeFacehuggerNear(STRATEGYBLOCK *sbPtr);
void MakeFacehuggerFar(STRATEGYBLOCK *sbPtr);
void FacehuggerIsDamaged(STRATEGYBLOCK *sbPtr, DAMAGE_PROFILE *damage, int multiple);
void Wake_Hugger(STRATEGYBLOCK *sbPtr);
#ifdef __cplusplus
}
#endif
#endif

1372
3dc/avp/BH_GENER.C Normal file

File diff suppressed because it is too large Load diff

131
3dc/avp/BH_GENER.H Normal file
View file

@ -0,0 +1,131 @@
/*----------------Patrick 15/11/96-------------------
Header for NPC generators
----------------------------------------------------*/
#ifndef _bhgenerator_h_
#define _bhgenerator_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*----------------Patrick 15/11/96-------------------
Generator behaviour data block. NB generators
have their own module ptr, as they are not included
in the visibility system.
----------------------------------------------------*/
typedef struct generatorblock
{
int PulseMarine_Wt;
int FlameMarine_Wt;
int SmartMarine_Wt;
int SadarMarine_Wt;
int GrenadeMarine_Wt;
int MinigunMarine_Wt;
int ShotgunCiv_Wt;
int PistolCiv_Wt;
int FlameCiv_Wt;
int UnarmedCiv_Wt;
int MolotovCiv_Wt;
int Alien_Wt;
int PredAlien_Wt;
int Praetorian_Wt;
int PistolMarine_Wt;
int WeightingTotal;
/* Pathfinder parameters */
/* If these values aren't -1 , then the generator produces path following creatures*/
int path;
int stepnumber;
struct vectorch Position;
int Timer;
/* generator can be switched on and off via the request state function */
int Active;
int GenerationRate; //scaled up by 100
int GenerationRateIncrease; //scaled up by 100
int RateIncreaseTimer;
int MaxGenNPCs;//limit for this generator
/*if use_own_rate_values is false then the generator will use the global
generation rates*/
unsigned int use_own_rate_values :1;
unsigned int use_own_max_npc :1;
} GENERATOR_BLOCK;
/*----------------Patrick 22/1/97-------------------
Hive enums and data structure.
Note that only one hive exists in the game.
----------------------------------------------------*/
typedef enum hive_state
{
HS_Attack,
HS_Regroup,
}HIVE_STATE;
typedef struct hive_data
{
HIVE_STATE currentState;
int numGenerators;
int hiveStateTimer;
int genRateTimer;
int maxGeneratorNPCs;
int generatorNPCsPerMinute;
int deltaGeneratorNPCsPerMinute;
BOOL AliensCanBeGenerated;
BOOL PredAliensCanBeGenerated;
BOOL PraetoriansCanBeGenerated;
} HIVE_DATA;
typedef struct hivelevelparams
{
int maxGeneratorNPCs;
int generatorNPCsPerMinute;
int deltaGeneratorNPCsPerMinute;
int hiveStateBaseTime;
} HIVELEVELPARAMS;
extern int ShowSlack;
/* prototypes */
extern void InitGenerator(void *posn, STRATEGYBLOCK *sbPtr);
extern void GeneratorBehaviour(STRATEGYBLOCK *sbPtr);
extern void InitHive(void);
extern void DoHive(void);
extern int NumGeneratorNPCsInEnv(void);
extern int NumGeneratorNPCsVisible(void);
extern void ForceAGenerator(void);
extern void ActivateHive(void);
/* defines */
#define DEFAULTHIVESTATETIME (60*ONE_FIXED)
#define MAXGENNPCS_MAX (255)
#define MAXGENNPCS_MIN (0)
#define GENSPERMINUTE_MAX (255)
#define GENSPERMINUTE_MIN (0)
#define INCREASEGENSPERMINUTE_MAX (255)
#define INCREASEGENSPERMINUTE_MIN (0)
#define GENERATORTIME_MAX (120*ONE_FIXED)
#define GENERATORTIME_MIN (3*ONE_FIXED)
/* globals */
extern HIVE_DATA NPCHive;
#ifdef __cplusplus
}
#endif
extern void GeneratorBalance_NoteAIDeath();
extern void GeneratorBalance_NotePlayerDeath();
#endif

863
3dc/avp/BH_LNKSW.C Normal file
View file

@ -0,0 +1,863 @@
#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "stratdef.h"
#include "gamedef.h"
#include "bh_types.h"
#include "bh_lnksw.h"
#include "dynblock.h"
#include "dynamics.h"
#include "pldghost.h"
#define UseLocalAssert Yes
#include "ourasert.h"
#include "pmove.h"
#include "pvisible.h"
#include "bh_binsw.h"
#include "plat_shp.h"
#include "psnd.h"
#include "inventry.h"
extern int NormalFrameTime;
extern int RealFrameTime;
static BOOL check_link_switch_states (LINK_SWITCH_BEHAV_BLOCK * lsbb)
{
int i=0;
LSWITCH_ITEM * lsi = lsbb->lswitch_list;
// textprint ("Checking link states\n");
if (!lsbb->state)
return(No);
// textprint ("Link switch OK\n");
while (i < lsbb->num_linked_switches)
{
if(lsi[i].bswitch->I_SBtype==I_BehaviourBinarySwitch)
{
BINARY_SWITCH_BEHAV_BLOCK * bsbb = ((BINARY_SWITCH_BEHAV_BLOCK *)lsi[i].bswitch->SBdataptr);
// if it's off return No
if (!bsbb->state)
return(No);
// textprint ("Switch %d OK\n", i);
}
else if(lsi[i].bswitch->I_SBtype==I_BehaviourLinkSwitch)
{
LINK_SWITCH_BEHAV_BLOCK * linked_lsbb = ((LINK_SWITCH_BEHAV_BLOCK *)lsi[i].bswitch->SBdataptr);
// if the system state is off return No
if (!linked_lsbb->system_state)
return(No);
}
else
{
GLOBALASSERT(0=="Switch should only have links to link switches and binary switches");
}
i++;
}
// textprint ("Link switchs activated\n");
return(Yes);
}
#if 0
static void set_link_switch_states_off (LINK_SWITCH_BEHAV_BLOCK * lsbb)
{
int i=0;
LSWITCH_ITEM * lsi = lsbb->lswitch_list;
while (lsi[i].bswitch && i < MAX_SWITCHES_FOR_LINK)
{
BINARY_SWITCH_BEHAV_BLOCK * bsbb = ((BINARY_SWITCH_BEHAV_BLOCK *)lsi[i].bswitch->SBdataptr);
// if it's on, tell it to go off
if (! ((bsbb->state && bsbb->rest_state) || (!bsbb->state && !bsbb->rest_state)) )
RequestState (lsi->bswitch, 0, 0);
i++;
}
}
#endif
void* LinkSwitchBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr)
{
LINK_SWITCH_BEHAV_BLOCK *ls_bhv;
LINK_SWITCH_TOOLS_TEMPLATE *ls_tt;
int i;
GLOBALASSERT(sbptr);
ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)AllocateMem(sizeof(LINK_SWITCH_BEHAV_BLOCK));
if(!ls_bhv)
{
memoryInitialisationFailure = 1;
return ((void *)NULL);
}
ls_bhv->bhvr_type = I_BehaviourLinkSwitch;
// from loaders
// 1 rest_state - on or off
// 2 mode
// 3 timer switch - time for reset
// 4 security clerance to operate
// 5 copy the target name
ls_tt = (LINK_SWITCH_TOOLS_TEMPLATE*)bhdata;
sbptr->shapeIndex = ls_tt->shape_num;
COPY_NAME(sbptr->SBname, ls_tt->nameID);
if (ls_tt->mode == I_lswitch_SELFDESTRUCT)
{
ls_bhv->ls_mode = I_lswitch_timer;
ls_bhv->IS_SELF_DESTRUCT = Yes;
}
else
{
ls_bhv->ls_mode = ls_tt->mode;
ls_bhv->IS_SELF_DESTRUCT = No;
}
ls_bhv->num_targets=ls_tt->num_targets;
if(ls_bhv->num_targets)
{
ls_bhv->ls_targets = (LINK_SWITCH_TARGET*)AllocateMem(sizeof(LINK_SWITCH_TARGET) * ls_tt->num_targets);
if (!ls_bhv->ls_targets)
{
memoryInitialisationFailure = 1;
return ((void *)NULL);
}
}
else
{
ls_bhv->ls_targets=0;
}
for (i=0; i<ls_tt->num_targets; i++)
{
ls_bhv->ls_targets[i]=ls_tt->targets[i];
ls_bhv->ls_targets[i].sbptr = 0;
}
ls_bhv->time_for_reset = ls_tt->time_for_reset;
ls_bhv->security_clerance = ls_tt->security_clearance;
ls_bhv->switch_flags=ls_tt->switch_flags;
ls_bhv->trigger_volume_min=ls_tt->trigger_volume_min;
ls_bhv->trigger_volume_max=ls_tt->trigger_volume_max;
ls_bhv->switch_always_on = ls_tt->switch_always_on;
ls_bhv->switch_off_message_same=ls_tt->switch_off_message_same;
ls_bhv->switch_off_message_none=ls_tt->switch_off_message_none;
if(sbptr->DynPtr) //there may be no shape
{
sbptr->DynPtr->Position = sbptr->DynPtr->PrevPosition = ls_tt->position;
sbptr->DynPtr->OrientEuler = ls_tt->orientation;
CreateEulerMatrix(&sbptr->DynPtr->OrientEuler, &sbptr->DynPtr->OrientMat);
TransposeMatrixCH(&sbptr->DynPtr->OrientMat);
}
// set up the animation control
if(sbptr->shapeIndex!=-1)
{
int item_num;
TXACTRLBLK **pptxactrlblk;
int shape_num = ls_tt->shape_num;
SHAPEHEADER *shptr = GetShapeData(shape_num);
SetupPolygonFlagAccessForShape(shptr);
pptxactrlblk = &ls_bhv->ls_tac;
for(item_num = 0; item_num < shptr->numitems; item_num ++)
{
POLYHEADER *poly = (POLYHEADER*)(shptr->items[item_num]);
LOCALASSERT(poly);
if((Request_PolyFlags((void *)poly)) & iflag_txanim)
{
TXACTRLBLK *pnew_txactrlblk;
int num_seq = 0;
pnew_txactrlblk = AllocateMem(sizeof(TXACTRLBLK));
if (pnew_txactrlblk)
{
pnew_txactrlblk->tac_flags = 0;
pnew_txactrlblk->tac_item = item_num;
pnew_txactrlblk->tac_sequence = ls_tt->rest_state;
pnew_txactrlblk->tac_node = 0;
pnew_txactrlblk->tac_txarray = GetTxAnimArrayZ(shape_num, item_num);
pnew_txactrlblk->tac_txah_s = GetTxAnimHeaderFromShape(pnew_txactrlblk, shape_num);
while(pnew_txactrlblk->tac_txarray[num_seq+1])num_seq++;
// Assert does not work at this point so
GLOBALASSERT(num_seq==2);
/* set the flags in the animation header */
// we only ever have one frame of animation per sequence -
// nb this can change talk to richard - one sequence with two frames
// or mutliple sequences???
//Now two sequences with an arbitrary number of frames - Richard
pnew_txactrlblk->tac_txah.txa_flags |= txa_flag_play;
/* change the value held in pptxactrlblk
which point to the previous structures "next"
pointer*/
*pptxactrlblk = pnew_txactrlblk;
pptxactrlblk = &pnew_txactrlblk->tac_next;
}
else
{
memoryInitialisationFailure = 1;
}
}
}
*pptxactrlblk=0;
}
else
{
//no shape - so there won't be any animation
ls_bhv->ls_tac=0;
}
ls_bhv->ls_dtype = linkswitch_no_display;
if (ls_bhv->ls_tac)
{
ls_bhv->ls_dtype = linkswitch_animate_me;
}
ls_bhv->ls_track=ls_tt->track;
if (ls_bhv->ls_track)
{
ls_bhv->ls_track->sbptr=sbptr;
if (ls_bhv->ls_dtype == linkswitch_animate_me)
{
ls_bhv->ls_dtype = linkswitch_animate_and_move_me;
}
else
{
ls_bhv->ls_dtype = linkswitch_move_me;
}
}
// fill in the rest ourselves
ls_bhv->request = 0;
ls_bhv->state = ls_tt->rest_state;
ls_bhv->timer = 0;
ls_bhv->system_state = 0;
ls_bhv->soundHandle = SOUND_NOACTIVEINDEX;
ls_bhv->num_linked_switches=ls_tt->num_linked_switches;
if(ls_tt->num_linked_switches)
ls_bhv->lswitch_list=(LSWITCH_ITEM*)AllocateMem(sizeof(LSWITCH_ITEM)*ls_bhv->num_linked_switches);
else
ls_bhv->lswitch_list=0;
for (i=0; i<ls_tt->num_linked_switches; i++)
{
COPY_NAME (ls_bhv->lswitch_list[i].bs_name, ls_tt->switchIDs[i].name);
}
if(ls_bhv->state)
{
ls_bhv->timer=ls_bhv->time_for_reset;
if(ls_bhv->ls_track)
{
//set the track to the end position
ls_bhv->ls_track->current_section=(ls_bhv->ls_track->num_sections-1);
ls_bhv->ls_track->timer=ls_bhv->ls_track->sections[ls_bhv->ls_track->current_section].time_for_section;
ls_bhv->ls_track->playing=1;
Update_Track_Position(ls_bhv->ls_track);
}
}
ls_bhv->TimeUntilNetSynchAllowed=0;
return((void*)ls_bhv);
}
void LinkSwitchBehaveFun(STRATEGYBLOCK* sbptr)
{
LINK_SWITCH_BEHAV_BLOCK *ls_bhv;
DISPLAYBLOCK* dptr;
int i;
GLOBALASSERT(sbptr);
ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbptr->SBdataptr;
GLOBALASSERT((ls_bhv->bhvr_type == I_BehaviourLinkSwitch));
dptr = sbptr->SBdptr;
// if(AvP.Network!=I_No_Network) return; /* disable for network game */
/******
What I need to do - check to see if we have
a request - requests have different effects depending on
the mode - so we have to switch on the mode
*****/
if (ls_bhv->ls_dtype == linkswitch_animate_me || ls_bhv->ls_dtype == linkswitch_animate_and_move_me)
{
if(dptr)
dptr->ObTxAnimCtrlBlks = ls_bhv->ls_tac;
}
if (!ReturnPlayerSecurityClearance(0,ls_bhv->security_clerance) && ls_bhv->security_clerance)
{
ls_bhv->request = I_no_request;
return;
}
if(ls_bhv->switch_flags && SwitchFlag_UseTriggerVolume)
{
/*See if switch has been set off*/
int i;
for (i=0; i<NumActiveStBlocks; i++)
{
int needToTest = 0;
STRATEGYBLOCK *sbPtr = ActiveStBlockList[i];
if (sbPtr->DynPtr)
{
if (sbPtr->SBdptr == Player)
{
needToTest = 1;
}
else if (sbPtr->I_SBtype == I_BehaviourNetGhost)
{
NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->SBdataptr;
if ((ghostData->type == I_BehaviourMarinePlayer)
||(ghostData->type == I_BehaviourAlienPlayer)
||(ghostData->type == I_BehaviourPredatorPlayer))
needToTest = 1;
}
}
if(needToTest&&
sbPtr->DynPtr->Position.vx > ls_bhv->trigger_volume_min.vx &&
sbPtr->DynPtr->Position.vx < ls_bhv->trigger_volume_max.vx &&
sbPtr->DynPtr->Position.vy > ls_bhv->trigger_volume_min.vy &&
sbPtr->DynPtr->Position.vy < ls_bhv->trigger_volume_max.vy &&
sbPtr->DynPtr->Position.vz > ls_bhv->trigger_volume_min.vz &&
sbPtr->DynPtr->Position.vz < ls_bhv->trigger_volume_max.vz)
{
ls_bhv->request=I_request_on;
break;
}
}
}
if (ls_bhv->request == I_request_on)
{
if (ls_bhv->triggered_last)
{
ls_bhv->request = I_no_request;
}
else
{
ls_bhv->triggered_last = Yes;
}
}
else
{
ls_bhv->triggered_last = No;
}
if(ls_bhv->switch_always_on)
{
ls_bhv->request=I_no_request;
ls_bhv->state=1;
}
if(AvP.Network != I_No_Network)
{
/*
Every time a switch is updated there is a time delay of 5 seconds before the
switch can next be changed by the host sending synch messages.
This prevents the host machine from resetting a switch before it learns that
it has been pressed
*/
if(ls_bhv->request == I_no_request)
{
ls_bhv->TimeUntilNetSynchAllowed-=RealFrameTime;
if(ls_bhv->TimeUntilNetSynchAllowed<0)
{
ls_bhv->TimeUntilNetSynchAllowed=0;
}
}
else
{
ls_bhv->TimeUntilNetSynchAllowed=5*ONE_FIXED;
}
}
switch(ls_bhv->ls_mode)
{
case I_lswitch_timer:
{
if(ls_bhv->request == I_request_on && !ls_bhv->state)
{
if(sbptr->shapeIndex!=-1)//don't play a sound if there is no shape
{
if(!ls_bhv->ls_track || !ls_bhv->ls_track->sound)
{
if (ls_bhv->soundHandle == SOUND_NOACTIVEINDEX)
{
Sound_Play(SID_SWITCH1,"eh",&ls_bhv->soundHandle);
}
}
}
ls_bhv->timer = ls_bhv->time_for_reset;
if (ls_bhv->ls_dtype == binswitch_move_me || ls_bhv->ls_dtype == binswitch_animate_and_move_me)
{
// moving switch
ls_bhv->new_state = 1;
ls_bhv->new_request = -1;
ls_bhv->ls_track->reverse=0;
Start_Track_Playing(ls_bhv->ls_track);
ls_bhv->mode_store = ls_bhv->ls_mode;
ls_bhv->ls_mode = I_lswitch_moving;
}
else
{
ls_bhv->state = 1;
}
if(ls_bhv->ls_tac)
{
ls_bhv->ls_tac->tac_sequence = 1;
ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbptr->shapeIndex));
}
}
else if(ls_bhv->timer > 0)
{
ls_bhv->timer -= NormalFrameTime;
if(ls_bhv->timer <= 0)
{
if(sbptr->shapeIndex!=-1)//don't play a sound if there is no shape
{
if(!ls_bhv->ls_track || !ls_bhv->ls_track->sound)
{
if (ls_bhv->soundHandle == SOUND_NOACTIVEINDEX)
{
Sound_Play(SID_SWITCH2,"eh",&ls_bhv->soundHandle);
}
}
}
ls_bhv->state = 0;
if (ls_bhv->ls_dtype == binswitch_move_me || ls_bhv->ls_dtype == binswitch_animate_and_move_me)
{
// moving switch
ls_bhv->new_state = 0;
ls_bhv->new_request = -1;
ls_bhv->ls_track->reverse=1;
Start_Track_Playing(ls_bhv->ls_track);
ls_bhv->mode_store = ls_bhv->ls_mode;
ls_bhv->ls_mode = I_lswitch_moving;
}
if(ls_bhv->ls_tac)
{
ls_bhv->ls_tac->tac_sequence = 0;
ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbptr->shapeIndex));
}
}
}
break;
}
case I_lswitch_toggle:
{
// if it's off and no request then we can return
if (!ls_bhv->state)
if(ls_bhv->request == I_no_request)
return;
/* change the state and request the new state in
the target */
if(ls_bhv->request != I_no_request)
{
if(ls_bhv->ls_dtype == binswitch_move_me || ls_bhv->ls_dtype == binswitch_animate_and_move_me)
{
// moving switch
ls_bhv->new_state = !ls_bhv->state;
ls_bhv->new_request = -1;
ls_bhv->mode_store = ls_bhv->ls_mode;
ls_bhv->ls_mode = I_lswitch_moving;
ls_bhv->ls_track->reverse=ls_bhv->state;
Start_Track_Playing(ls_bhv->ls_track);
}
else
{
ls_bhv->state = !ls_bhv->state;
}
if(sbptr->shapeIndex!=-1)//don't play a sound if there is no shape
{
if(!ls_bhv->ls_track || !ls_bhv->ls_track->sound)
{
if (ls_bhv->soundHandle == SOUND_NOACTIVEINDEX)
{
Sound_Play(SID_SWITCH1,"eh",&ls_bhv->soundHandle);
}
}
}
if(ls_bhv->ls_tac)
{
ls_bhv->ls_tac->tac_sequence = ls_bhv->state ? 1 : 0;
ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbptr->shapeIndex));
}
}
break;
}
case I_lswitch_wait:
{
// if it's off and no request then we can return
if (!ls_bhv->state)
if(ls_bhv->request == I_no_request)
return;
if(ls_bhv->request == I_request_on)
{
if(!ls_bhv->state)//can only be switched on if currently off
{
if(!ls_bhv->ls_track || !ls_bhv->ls_track->sound)
{
Sound_Play(SID_SWITCH2,"eh",&ls_bhv->soundHandle);
}
if(ls_bhv->ls_dtype == binswitch_move_me || ls_bhv->ls_dtype == binswitch_animate_and_move_me)
{
// moving switch
ls_bhv->new_state = 1;
ls_bhv->new_request = -1;
ls_bhv->ls_track->reverse=0;
Start_Track_Playing(ls_bhv->ls_track);
ls_bhv->mode_store = ls_bhv->ls_mode;
ls_bhv->ls_mode = I_lswitch_moving;
}
else
{
ls_bhv->state = 1;
}
}
}
else if (ls_bhv->request == I_request_off)
{
if(ls_bhv->state)//can only be switched off if currently on
{
if(!ls_bhv->ls_track || !ls_bhv->ls_track->sound)
{
Sound_Play(SID_SWITCH1,"eh",&ls_bhv->soundHandle);
}
if(ls_bhv->ls_dtype == binswitch_move_me || ls_bhv->ls_dtype == binswitch_animate_and_move_me)
{
// moving switch
ls_bhv->new_state = 0;
ls_bhv->new_request = -1;
ls_bhv->ls_track->reverse=1;
Start_Track_Playing(ls_bhv->ls_track);
ls_bhv->mode_store = ls_bhv->ls_mode;
ls_bhv->ls_mode = I_lswitch_moving;
}
else
{
ls_bhv->state = 0;
}
}
}
if(ls_bhv->ls_tac)
{
ls_bhv->ls_tac->tac_sequence = ls_bhv->state ? 1 : 0;
ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbptr->shapeIndex));
}
break;
}
case I_lswitch_moving:
{
textprint ("moving\n");
Update_Track_Position(ls_bhv->ls_track);
if (!ls_bhv->ls_track->playing)
{
ls_bhv->ls_mode = ls_bhv->mode_store;
ls_bhv->state = ls_bhv->new_state;
if(ls_bhv->ls_tac)
{
ls_bhv->ls_tac->tac_sequence = ls_bhv->state ? 1 : 0;
ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbptr->shapeIndex));
}
}
}
break;
default:
GLOBALASSERT(2<1);
}
ls_bhv->request = I_no_request;
//check to see if the system state has changed
if (ls_bhv->system_state)
{
if (!check_link_switch_states(ls_bhv))
{
ls_bhv->system_state = No;
//link switch system state is turning off
if(!ls_bhv->switch_off_message_none)
{
for(i=0;i<ls_bhv->num_targets;i++)
{
RequestState(ls_bhv->ls_targets[i].sbptr,ls_bhv->ls_targets[i].request_message^(!ls_bhv->switch_off_message_same), sbptr);
}
}
}
}
else
{
if (check_link_switch_states(ls_bhv))
{
ls_bhv->system_state = Yes;
//link switch system state is turning on
for(i=0;i<ls_bhv->num_targets;i++)
{
RequestState(ls_bhv->ls_targets[i].sbptr,ls_bhv->ls_targets[i].request_message, sbptr);
}
}
}
}
#define LINKSWITCHSYNCH_ON 0
#define LINKSWITCHSYNCH_OFF 1
#define LINKSWITCHSYNCH_IGNORE 2
int LinkSwitchGetSynchData(STRATEGYBLOCK* sbPtr)
{
LINK_SWITCH_BEHAV_BLOCK *ls_bhv;
GLOBALASSERT(sbPtr);
ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbPtr->SBdataptr;
GLOBALASSERT((ls_bhv->bhvr_type == I_BehaviourLinkSwitch));
//don't try to synch moving switches
if(ls_bhv->ls_mode==I_lswitch_moving)
{
return LINKSWITCHSYNCH_IGNORE;
}
if(ls_bhv->state)
return LINKSWITCHSYNCH_ON;
else
return LINKSWITCHSYNCH_OFF;
}
void LinkSwitchSetSynchData(STRATEGYBLOCK* sbPtr,int status)
{
LINK_SWITCH_BEHAV_BLOCK *ls_bhv;
GLOBALASSERT(sbPtr);
ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbPtr->SBdataptr;
GLOBALASSERT((ls_bhv->bhvr_type == I_BehaviourLinkSwitch));
if(ls_bhv->TimeUntilNetSynchAllowed>0)
{
//ignore this attempt to synch the switch
return;
}
//don't try to synch moving switches
if(ls_bhv->ls_mode==I_lswitch_moving)
{
return;
}
switch(status)
{
case LINKSWITCHSYNCH_ON :
if(!ls_bhv->state)
{
//this switch should be on
RequestState(sbPtr,1,0);
}
break;
case LINKSWITCHSYNCH_OFF :
if(ls_bhv->state)
{
//this switch should be off
RequestState(sbPtr,0,0);
}
break;
}
}
/*--------------------**
** Loading and Saving **
**--------------------*/
#include "savegame.h"
typedef struct link_switch_save_block
{
SAVE_BLOCK_STRATEGY_HEADER header;
BINARY_SWITCH_REQUEST_STATE request;
BOOL system_state;
BOOL state;
LSWITCH_MODE ls_mode;
int timer;
BOOL new_state;
int new_request;
LSWITCH_MODE mode_store;
BOOL triggered_last;
int txanim_sequence;
}LINK_SWITCH_SAVE_BLOCK;
//defines for load/save macros
#define SAVELOAD_BLOCK block
#define SAVELOAD_BEHAV ls_bhv
void LoadStrategy_LinkSwitch(SAVE_BLOCK_STRATEGY_HEADER* header)
{
STRATEGYBLOCK* sbPtr;
LINK_SWITCH_BEHAV_BLOCK *ls_bhv;
LINK_SWITCH_SAVE_BLOCK* block = (LINK_SWITCH_SAVE_BLOCK*) header;
//check the size of the save block
if(header->size!=sizeof(*block)) return;
//find the existing strategy block
sbPtr = FindSBWithName(header->SBname);
if(!sbPtr) return;
//make sure the strategy found is of the right type
if(sbPtr->I_SBtype != I_BehaviourLinkSwitch) return;
ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbPtr->SBdataptr;
//start copying stuff
COPYELEMENT_LOAD(request)
COPYELEMENT_LOAD(system_state)
COPYELEMENT_LOAD(state)
COPYELEMENT_LOAD(ls_mode)
COPYELEMENT_LOAD(timer)
COPYELEMENT_LOAD(new_state)
COPYELEMENT_LOAD(new_request)
COPYELEMENT_LOAD(mode_store)
COPYELEMENT_LOAD(triggered_last)
//set the texture animation sequence
if(ls_bhv->ls_tac)
{
ls_bhv->ls_tac->tac_sequence = block->txanim_sequence;
ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbPtr->shapeIndex));
}
//load the track position , if the switch has one
if(ls_bhv->ls_track)
{
SAVE_BLOCK_HEADER* track_header = GetNextBlockIfOfType(SaveBlock_Track);
if(track_header)
{
LoadTrackPosition(track_header,ls_bhv->ls_track);
}
}
}
void SaveStrategy_LinkSwitch(STRATEGYBLOCK* sbPtr)
{
LINK_SWITCH_SAVE_BLOCK *block;
LINK_SWITCH_BEHAV_BLOCK *ls_bhv;
ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbPtr->SBdataptr;
GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
//start copying stuff
COPYELEMENT_SAVE(request)
COPYELEMENT_SAVE(system_state)
COPYELEMENT_SAVE(state)
COPYELEMENT_SAVE(ls_mode)
COPYELEMENT_SAVE(timer)
COPYELEMENT_SAVE(new_state)
COPYELEMENT_SAVE(new_request)
COPYELEMENT_SAVE(mode_store)
COPYELEMENT_SAVE(triggered_last)
//get the animation sequence
if(ls_bhv->ls_tac)
{
block->txanim_sequence = ls_bhv->ls_tac->tac_sequence;
}
else
{
block->txanim_sequence = 0;
}
//save the track position , if the switch has one
if(ls_bhv->ls_track)
{
SaveTrackPosition(ls_bhv->ls_track);
}
}

163
3dc/avp/BH_LNKSW.H Normal file
View file

@ -0,0 +1,163 @@
#ifndef _bhlnksw_h_
#define _bhlnksw_h_ 1
#include "track.h"
#ifdef __cplusplus
extern "C" {
#endif
void* LinkSwitchBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr);
void LinkSwitchBehaveFun(STRATEGYBLOCK* sbptr);
extern int LinkSwitchGetSynchData(STRATEGYBLOCK* sbptr);
extern void LinkSwitchSetSynchData(STRATEGYBLOCK* sbptr,int status);
typedef enum link_switch_mode
{
I_lswitch_timer,
I_lswitch_wait,
I_lswitch_toggle,
I_lswitch_moving,
I_lswitch_SELFDESTRUCT,
} LSWITCH_MODE;
typedef enum link_switch_req_states
{
linkswitch_no_request,
linkswitch_request_on,
linkswitch_request_off,
}LINK_SWITCH_REQUEST_STATE;
typedef enum lswitch_display_types
{
linkswitch_no_display,
linkswitch_animate_me,
linkswitch_move_me,
linkswitch_animate_and_move_me,
} LSWITCH_DISPLAY_TYPES;
typedef enum ls_move_dir
{
ls_start_to_end,
ls_end_to_start,
} LS_MOVE_DIR;
typedef struct lswitch_item
{
STRATEGYBLOCK * bswitch;
char bs_name [SB_NAME_LENGTH];
} LSWITCH_ITEM;
typedef struct link_switch_target
{
char name[SB_NAME_LENGTH];
int request_message;
STRATEGYBLOCK* sbptr;
}LINK_SWITCH_TARGET;
typedef struct link_switch
{
AVP_BEHAVIOUR_TYPE bhvr_type;
LINK_SWITCH_REQUEST_STATE request;
BOOL system_state;
BOOL state;
LSWITCH_MODE ls_mode;
int num_targets;
LINK_SWITCH_TARGET* ls_targets;
int time_for_reset; // constant
int timer;
int security_clerance; // what the plyer has to be to use this switch
int num_linked_switches;
LSWITCH_ITEM* lswitch_list ;
// stuff for showing how the switch displays its state
LSWITCH_DISPLAY_TYPES ls_dtype;
TXACTRLBLK *ls_tac; // animations
// or track
TRACK_CONTROLLER* ls_track;
BOOL new_state;
int new_request;
LSWITCH_MODE mode_store;
// SELF DESTRUCT SEQUENCE STUFF
BOOL IS_SELF_DESTRUCT;
int soundHandle;
BOOL triggered_last;
int switch_flags;
VECTORCH trigger_volume_min;//for switches that can be set off by walking
VECTORCH trigger_volume_max;//into a given area
unsigned int switch_always_on:1;
unsigned int switch_off_message_same:1;
unsigned int switch_off_message_none:1;
int TimeUntilNetSynchAllowed;
}LINK_SWITCH_BEHAV_BLOCK;
typedef struct link_switch_tools_template
{
VECTORCH position;
EULER orientation;
BOOL rest_state;
int mode;
int time_for_reset;
int security_clearance;
int num_targets;
LINK_SWITCH_TARGET * targets;
int shape_num;
TRACK_CONTROLLER* track;
char nameID[SB_NAME_LENGTH];
int num_linked_switches;
SBNAMEBLOCK* switchIDs;
int switch_flags;
VECTORCH trigger_volume_min;//for switches that can be set off by walking
VECTORCH trigger_volume_max;//into a given area
unsigned int switch_always_on:1;
unsigned int switch_off_message_same:1;
unsigned int switch_off_message_none:1;
} LINK_SWITCH_TOOLS_TEMPLATE;
#ifdef __cplusplus
};
#endif
#endif

412
3dc/avp/BH_MARIN.H Normal file
View file

@ -0,0 +1,412 @@
/*--------------Patrick 14/2/97----------------
Header file for marine support functions
---------------------------------------------*/
#ifndef _bhmarin_h_
#define _bhmarin_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_pred.h"
#include "psndproj.h"
#include "sfx.h"
/*--------------------------------------------
enums of marine far and near behaviour states
--------------------------------------------*/
typedef enum marine_bhstate
{
MBS_Waiting,
/* Waiting - stand and do nothing,
until you get a call, see an enemy,
or begin to fidget. */
MBS_Wandering,
/* Go from module to module around the environment. */
MBS_Retreating,
MBS_Sentry,
MBS_Approaching,
MBS_Firing,
MBS_Avoidance,
MBS_Dying,
MBS_Responding,
MBS_Returning,
MBS_Pathfinding,
MBS_Taunting,
MBS_PanicFire,
MBS_Reloading,
MBS_PumpAction,
MBS_GetWeapon,
MBS_PanicReloading,
MBS_AcidAvoidance,
} MARINE_BHSTATE;
typedef enum marine_movement_style {
MMS_Stationary=0,
MMS_Bored,
MMS_Alert,
MMS_Combat,
MMS_Sprint,
} MARINE_MOVEMENT_STYLE;
typedef enum state_return_condition {
SRC_No_Change,
SRC_Request_Approach,
SRC_Request_Fire,
SRC_Request_Wander,
SRC_Request_Avoidance,
SRC_Request_Wait,
SRC_Request_Retreat,
SRC_Request_Respond,
SRC_Request_Return,
SRC_Request_Taunt,
SRC_Request_PanicFire,
SRC_Request_Reload,
SRC_Request_PumpAction,
SRC_Request_PullPistol,
SRC_Request_PanicReload,
} STATE_RETURN_CONDITION;
/*--------------------------------------------
Enum of marine animation sequences
--------------------------------------------*/
typedef enum MarineSequence
{
MSQ_Walk,
MSQ_StandDieFront,
MSQ_StandDieBack,
MSQ_StartStandingFire,
MSQ_StandingFire,
MSQ_StandDeadFront,
MSQ_StandDeadBack,
MSQ_Crawl,
MSQ_CrouchDie,
MSQ_CrouchDead,
MSQ_RunningFire,
MSQ_Crouch,
MSQ_Stand,
MSQ_Jump,
MSQ_Taunt,
MSQ_Walk_Backwards,
MSQ_Crawl_Backwards,
MSQ_RunningFire_Backwards,
MSQ_StandingFireSecondary,
MSQ_RunningFireSecondary,
MSQ_RunningFireSecondary_Backwards,
MSQ_BaseOfCudgelAttacks=40,
}MARINE_SEQUENCE;
typedef enum MarineMissions {
MM_Wait_Then_Wander, // Should do nothing until visible.
MM_Wander,
MM_Guard,
MM_LocalGuard,
MM_NonCom,
MM_Pathfinder,
MM_RunAroundOnFire,
}MARINE_MISSION;
/***** Marine squad command state *****/
typedef struct squadcommand {
int alertStatus;
int responseLevel;
AIMODULE *alertZone;
int alertPriority;
int Squad_Suspicion;
VECTORCH squad_suspect_point;
/* Now some stats. */
int RespondingMarines;
int Alt_RespondingMarines;
int NearUnpanickedMarines;
int Alt_NearUnpanickedMarines;
int NearPanickedMarines;
int Alt_NearPanickedMarines;
int NearBurningMarines;
int Alt_NearBurningMarines;
int Squad_Delta_Morale;
int Nextframe_Squad_Delta_Morale;
} SQUAD_COMMAND_STATE;
/*--------------------------------------------
Data for civilian accoutement stuff
--------------------------------------------*/
struct hierarchy_shape_replacement;
typedef struct hierarchy_variant_data
{
struct hierarchy_shape_replacement * replacements;
int voice;
unsigned int female :1;
} HIERARCHY_VARIANT_DATA;
/*--------------------------------------------
Marine behaviour data block
--------------------------------------------*/
typedef struct marineStatusBlock
{
signed int health;
signed int volleySize;
signed int primaryWeaponDamage;
MARINE_BHSTATE behaviourState;
MARINE_BHSTATE lastState;
STRATEGYBLOCK *Target;
MARINE_MISSION Mission;
char Target_SBname[SB_NAME_LENGTH];
char death_target_ID[SB_NAME_LENGTH]; //another strategy can be notified of the marine's death
STRATEGYBLOCK* death_target_sbptr;
int death_target_request;
STRATEGYBLOCK* generator_sbptr;//0 unless created by a generator
AIMODULE *lastmodule;
AIMODULE *destinationmodule;
AIMODULE *missionmodule;
AIMODULE *fearmodule;
VECTORCH my_spot;
VECTORCH my_facing_point;
/* Movement data. */
signed int nearSpeed;
int acceleration;
int speedConstant;
int accelerationConstant;
/* Sense data */
int mtracker_timer;
VECTORCH suspect_point;
int suspicious;
int previous_suspicion;
int using_squad_suspicion;
int sawlastframe;
int gotapoint;
int lastframe_fallingspeed;
/* Pathfinder parameters */
int path;
int stepnumber;
/* Pathfinder parameters */
int stateTimer;
int internalState;
HMODELCONTROLLER HModelController;
VECTORCH weaponTarget; /* position for firing weapon at */
DISPLAYBLOCK *myGunFlash;
int soundHandle;
int soundHandle2;
NPC_OBSTRUCTIONREPORT obstruction;
NPC_MOVEMENTDATA moveData;
NPC_WANDERDATA wanderData;
int IAmCrouched;
/* CDF 15/12/97 */
struct marine_weapon_data *My_Weapon;
SECTION_DATA *My_Gunflash_Section;
SECTION_DATA *My_Elevation_Section; /* For elevation computation. */
int lastroundhit;
SECTION_DATA *lasthitsection;
int GibbFactor;
int Wounds;
int incidentFlag;
int incidentTimer;
int weapon_variable;
int weapon_variable2;
int clipammo;
int roundsForThisTarget;
int Female;
int Android;
int Skill;
int Courage;
int Voice;
int VoicePitch;
int FiringAnim;
int Expression;
int Target_Expression;
int Blink;
int SpotFlag;
NPC_AVOIDANCEMANAGER avoidanceManager;
WAYPOINT_MANAGER waypointManager;
}MARINE_STATUS_BLOCK;
typedef enum marine_npc_weapons {
MNPCW_PulseRifle,
MNPCW_Flamethrower,
MNPCW_Smartgun,
MNPCW_SADAR,
MNPCW_GrenadeLauncher,
MNPCW_Minigun,
MNPCW_MShotgun,
MNPCW_MPistol,
MNPCW_MFlamer,
MNPCW_MUnarmed,
MNPCW_MMolotov,
MNPCW_PistolMarine,
MNPCW_Android,
MNPCW_AndroidSpecial,
MNPCW_Android_Pistol_Special,
MNPCW_Scientist_A,
MNPCW_Scientist_B,
MNPCW_TwoPistols,
MNPCW_Skeeter,
MNPCW_End,
} MARINE_NPC_WEAPONS;
/*--------------------------------------------
Tools data template
--------------------------------------------*/
typedef struct tools_data_marine
{
struct vectorch position;
struct vectorch facing_point;
int shapeIndex;
char nameID[SB_NAME_LENGTH];
MARINE_MISSION Mission;
char death_target_ID[SB_NAME_LENGTH];
int death_target_request;
enum marine_npc_weapons marine_type;
int path;
int stepnumber;
int textureID;
}TOOLS_DATA_MARINE;
/*--------------------------------------------
Weapon Behaviour Type.
--------------------------------------------*/
typedef struct marine_weapon_data {
MARINE_NPC_WEAPONS id;
enum SFX_ID SfxID;
STATE_RETURN_CONDITION (*WeaponFireFunction)(STRATEGYBLOCK *);
void (*WeaponMisfireFunction)(SECTION_DATA *, int *);
STATE_RETURN_CONDITION (*WeaponPanicFireFunction)(STRATEGYBLOCK *);
char *Riffname;
char *HierarchyName;
char *GunflashName;
char *ElevationSection;
char *HitLocationTableName;
char *TemplateName;
char *ClipName;
int MinRange;
int ForceFireRange;
int MaxRange;
int Accuracy;
int FiringRate;
int FiringTime;
int MinimumBurstSize;
enum AMMO_ID Ammo_Type;
int clip_size;
int Reload_Sequence;
int TargetCallibrationShift;
SOUNDINDEX StartSound;
SOUNDINDEX LoopSound;
SOUNDINDEX EndSound;
unsigned int EnableGrenades :1;
unsigned int UseElevation :1;
unsigned int EnableTracker :1;
unsigned int ARealMarine :1;
unsigned int Android :1;
}MARINE_WEAPON_DATA;
/*--------------------------------------------
Some defines....
--------------------------------------------*/
#define MARINE_STATE_PRINT 0
#define MARINE_STARTING_HEALTH 30
#define NO_OF_FRAGMENTS_FROM_DEAD_MARINE 10
// #define MARINE_NEAR_SPEED 6000 /* mm/s */
/* Experiment. Can they take the ramps? */
#define MARINE_NEAR_SPEED 6000 /* mm/s */
#define MARINE_NEAR_VIEW_WIDTH 500 /* mm */
#define MARINE_WEAPON_DAMAGE 5
#define MARINE_CLOSE_APPROACH_DISTANCE 3000 /* mm */
#define MARINE_FIRINGPOINT_INFRONT 3000 /* 900 mm */
#define MARINE_FIRINGPOINT_ACROSS 300 /* 300 mm */
#define MARINE_FIRINGPOINT_UP 200 /* 200 mm */
#define MARINE_FIRINGPOINT_INFRONT_CROUCHED 900 /* mm */
#define MARINE_FIRINGPOINT_ACROSS_CROUCHED 200 /* mm */
#define MARINE_FIRINGPOINT_UP_CROUCHED 100 /* mm */
#define MARINE_WEAPON_VOLLEYSIZE (1+(FastRandom()&0x02)) /* 1,2 or 3 1/4 second bursts */
#define MARINE_CHANCEOFGRENADE (3)
#define MARINE_TOO_CLOSE_TO_GRENADE_FOOL 3000
#define MARINE_PARANOIA_TIME (ONE_FIXED*10)
#define MARINE_PANIC_TIME (ONE_FIXED*120)
#define SQUAD_PARANOIA_TIME (ONE_FIXED)
/* 1.5-2 seconds in 1/16 second. NB DO NOT INCREASE THIS */
#define MARINE_FAR_MOVE_TIME ((24+(FastRandom()&0x07))*(ONE_FIXED>>4))
/* 1-2 seconds in 1/8ths of a second */
#define MARINE_NEAR_TIMEBETWEENFIRING ((8+(FastRandom()&0x07))*(ONE_FIXED>>3))
// #define MARINE_NEAR_FIRE_TIME (ONE_FIXED>>2) /* 1/4 second */
#define MARINE_NEAR_FIRE_TIME (ONE_FIXED) /* 1 second */
/* random time between 1 and 2 seconds,in fixed point,with granularity 1/8th second */
#define MARINE_NEARWAITTIME (ONE_FIXED+((FastRandom()&0x7)*(ONE_FIXED>>3)))
#define SEAL_NEAR_SPEED 7000
#define SEAL_WEAPON_DAMAGE 15
#define SEAL_STARTING_HEALTH 150
//#define MINIGUN_IDLE_SPEED (ONE_FIXED>>2)
#define MINIGUN_IDLE_SPEED (0)
#define MINIGUN_MAX_SPEED (ONE_FIXED*20)
#define MINIGUN_MINIMUM_BURST (25)
/*--------------------------------------------
Some prototypes...
--------------------------------------------*/
void InitMarineBehaviour(void* bhdata, STRATEGYBLOCK *sbPtr);
void InitSealBehaviour(void* bhdata, STRATEGYBLOCK *sbPtr);
void SendRequestToMarine(STRATEGYBLOCK* sbPtr,BOOL state,int extended_data);
void MarineBehaviour(STRATEGYBLOCK *sbPtr);
void MakeMarineNear(STRATEGYBLOCK *sbPtr);
void MakeMarineFar(STRATEGYBLOCK *sbPtr);
void MarineIsDamaged(STRATEGYBLOCK *sbPtr, DAMAGE_PROFILE *damage, int multiple, int wounds,SECTION_DATA *Section, VECTORCH *incoming);
void WarnMarineOfAttack(STRATEGYBLOCK *marine,STRATEGYBLOCK *attacker);
DISPLAYBLOCK* AddNPCGunFlashEffect(VECTORCH *position, MATRIXCH* orientation, enum SFX_ID sfxID);
void RemoveNPCGunFlashEffect(DISPLAYBLOCK* dPtr);
void MaintainNPCGunFlashEffect(DISPLAYBLOCK* dPtr, VECTORCH *position, MATRIXCH* orientation);
int Validate_Target(STRATEGYBLOCK *target,char *SBname);
int Validate_Strategy(STRATEGYBLOCK *target,char *SBname);
AIMODULE *NearNPC_GetTargetAIModuleForRetreat(STRATEGYBLOCK *sbPtr, NPC_MOVEMENTDATA *moveData);
extern void InitSquad(void);
extern void DoSquad(void);
extern void ZoneAlert(int level,AIMODULE *targetModule);
extern void Marine_CorpseSightingTest(STRATEGYBLOCK *corpse);
#ifdef __cplusplus
}
#endif
#endif

2
3dc/avp/BH_NEAR.H Normal file
View file

@ -0,0 +1,2 @@
extern void NearAlienBehaviour(STRATEGYBLOCK *sbPtr);

1196
3dc/avp/BH_PAQ.C Normal file

File diff suppressed because it is too large Load diff

103
3dc/avp/BH_PAQ.H Normal file
View file

@ -0,0 +1,103 @@
/* Patrick 18/2/97 ------------------------------------------------
Header file for alien queen and predator-alien support functions
-----------------------------------------------------------------*/
#ifndef _bhpaq_h_
#define _bhpaq_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_pred.h"
/* Patrick 18/2/97 ------------------------------------------------
Some enumerations
-----------------------------------------------------------------*/
typedef enum PaqSequence
{
PaqSQ_Run,
PaqSQ_Attack,
PaqSQ_Stand,
PaqSQ_Dying,
PaqSQ_Dead,
PaqSQ_Attack2,
}PAQ_SEQUENCE;
typedef enum paq_far_bhstate
{
PAQFS_Wait,
PAQFS_Hunt,
PAQFS_Wander,
PAQFS_Dying,
}PAQ_FAR_BHSTATE;
typedef enum paq_near_bhstate
{
PAQNS_Wait,
PAQNS_Approach,
PAQNS_Attack,
PAQNS_Wander,
PAQNS_Avoidance,
PAQNS_Dying,
}PAQ_NEAR_BHSTATE;
/* Patrick 18/2/97 ------------------------------------------------
Some structures
-----------------------------------------------------------------*/
typedef struct paqStatusBlock
{
signed int health;
signed int nearSpeed;
signed int damageInflicted;
PAQ_FAR_BHSTATE FarBehaviourState;
PAQ_NEAR_BHSTATE NearBehaviourState;
int stateTimer;
SHAPEANIMATIONCONTROLLER ShpAnimCtrl;
HMODELCONTROLLER HModelController;
NPC_MOVEMENTDATA moveData;
NPC_WANDERDATA wanderData;
}PAQ_STATUS_BLOCK;
typedef struct tools_data_paq
{
struct vectorch position;
int shapeIndex;
char nameID[SB_NAME_LENGTH];
}TOOLS_DATA_PAQ;
/* Patrick 18/2/97 ------------------------------------------------
Some defines
-----------------------------------------------------------------*/
#define PRAL_STARTING_HEALTH 700
#define QUEEN_STARTING_HEALTH 1400
#define NO_OF_FRAGMENTS_FROM_DEAD_PAQ 10
#define PRAL_NEAR_SPEED 10000 /* mm/s */
#define QUEEN_NEAR_SPEED 12000 /* mm/s */
#define PRAL_NEAR_DAMAGE 20 /* mm/s */
#define QUEEN_NEAR_DAMAGE 40 /* mm/s */
#define PAQ_CLOSE_ATTACK_RANGE 1500 /* mm */
#define PAQ_NEAR_VIEW_WIDTH 500 /* mm */
/* 1-1.5 seconds in 16ths of a second */
#define PAQ_FAR_MOVE_TIME ((16+(FastRandom()&0x07))*(ONE_FIXED>>4))
#define PAQ_NEAR_CLOSEATTACK_TIME (ONE_FIXED>>1) /* 1/2 second */
/* random time between 1 and 2 seconds,in fixed point,with granularity 1/8th second */
#define PAQ_NEARWAITTIME (ONE_FIXED+((FastRandom()&0x7)*(ONE_FIXED>>3)))
#define PAQ_DIETIME (ONE_FIXED<<4)
/* Patrick 18/2/97 ------------------------------------------------
Some prototypes
-----------------------------------------------------------------*/
void InitPredAlBehaviour(void* bhdata, STRATEGYBLOCK *sbPtr);
void InitQueenBehaviour(void* bhdata, STRATEGYBLOCK *sbPtr);
void PAQBehaviour(STRATEGYBLOCK *sbPtr);
void MakePAQNear(STRATEGYBLOCK *sbPtr);
void MakePAQFar(STRATEGYBLOCK *sbPtr);
void PAQIsDamaged(STRATEGYBLOCK *sbPtr, DAMAGE_PROFILE *damage, int multiple);
#ifdef __cplusplus
}
#endif
#endif

261
3dc/avp/BH_PRED.H Normal file
View file

@ -0,0 +1,261 @@
/*--------------Patrick 21/1/97-----------------------
Header file for predator AI & NPC support functions
---------------------------------------------------*/
#ifndef _bhpred_h_
#define _bhpred_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_ais.h"
#include "decal.h"
/*-----------------------------
Predator Specific Support
-------------------------------*/
/* predator animation sequences */
typedef enum predatorsequence
{
PredSQ_Run=0,
PredSQ_Crawl,
PredSQ_Stand,
PredSQ_Crouch,
PredSQ_StandDie,
PredSQ_StandDead,
PredSQ_CrouchDie,
PredSQ_CrouchDead,
PredSQ_StandingSwipe,
PredSQ_CrouchedSwipe,
PredSQ_RunningSwipe,
PredSQ_CrawlingSwipe,
PredSQ_Jump,
PredSQ_Taunt,
PredSQ_Run_Backwards,
PredSQ_Crawl_Backwards,
PredSQ_RunningSwipe_Backwards,
PredSQ_CrawlingSwipe_Backwards,
PredSQ_BaseOfStaffAttacks=20,
PredSQ_BaseOfWristbladeAttacks=40,
}PREDATOR_SEQUENCE;
typedef enum pred_bhstate {
PBS_Wandering,
PBS_Hunting,
PBS_Avoidance,
PBS_Withdrawing,
PBS_Dying,
PBS_Recovering,
PBS_SwapWeapon,
PBS_Engaging,
PBS_Attacking,
PBS_Pathfinding,
PBS_Returning,
PBS_Taunting,
PBS_SelfDestruct,
} PRED_BHSTATE;
typedef enum pred_return_condition {
PRC_No_Change,
PRC_Request_Engage,
PRC_Request_Attack,
PRC_Request_Wander,
PRC_Request_Avoidance,
PRC_Request_Hunt,
PRC_Request_Withdraw,
PRC_Request_Recover,
PRC_Request_Swap,
PRC_Request_Return,
PRC_Request_Pathfind,
PRC_Request_Taunt,
PRC_Request_SelfDestruct,
} PRED_RETURN_CONDITION;
/* cloaking states */
typedef enum pred_cloakstate
{
PCLOAK_Off,
PCLOAK_Activating,
PCLOAK_On,
PCLOAK_Deactivating,
}PRED_CLOAKSTATE;
typedef struct predatorPersonalParameters
{
int startingHealth; /* initial health */
int speed; /* running speed */
int defenceHealth; /* health level below which defensive behaviour is used */
int useShoulderCannon; /* 1 = shouldercannon, 0 = disc */
int timeBetweenRangedAttacks;
int maxShotsPerRangedAttack;
int timeBetweenShots;
int closeAttackDamage;
int regenerationUnit; /* health recovered when made visible */
int chanceOfCloaking; /* 0-8, chance in 8 */
} PREDATOR_PERSONALPARAMETERS;
typedef enum predator_npc_weapons {
PNPCW_Pistol,
PNPCW_Wristblade,
PNPCW_PlasmaCaster,
PNPCW_Staff,
PNPCW_Medicomp,
PNPCW_Speargun,
PNPCW_SeriousPlasmaCaster,
PNPCW_End,
} PREDATOR_NPC_WEAPONS;
typedef struct predator_weapon_data {
PREDATOR_NPC_WEAPONS id;
PRED_RETURN_CONDITION (*WeaponFireFunction)(STRATEGYBLOCK *);
PRED_RETURN_CONDITION (*WeaponEngageFunction)(STRATEGYBLOCK *);
char *Riffname;
char *HierarchyName;
char *GunName;
char *ElevationName;
char *HitLocationTableName;
int MinRange;
int ForceFireRange;
int MaxRange;
int FiringRate;
int VolleySize;
int SwappingTime;
int UseElevation :1;
}PREDATOR_WEAPON_DATA;
typedef struct predatorStatusBlock
{
signed int health;
PRED_BHSTATE behaviourState;
PRED_BHSTATE lastState;
int stateTimer;
int internalState;
int patience;
int enableSwap;
int enableTaunt;
VECTORCH weaponTarget; /* target position for firing weapon at */
int volleySize; /* used for weapon control */
NPC_OBSTRUCTIONREPORT obstruction;
NPC_MOVEMENTDATA moveData;
NPC_WANDERDATA wanderData;
NPC_AVOIDANCEMANAGER avoidanceManager;
WAYPOINT_MANAGER waypointManager;
int IAmCrouched;
int personalNumber; /* for predator personalisation */
int nearSpeed;
int GibbFactor;
int incidentFlag;
int incidentTimer;
PREDATOR_WEAPON_DATA *Selected_Weapon;
PREDATOR_NPC_WEAPONS PrimaryWeapon;
PREDATOR_NPC_WEAPONS SecondaryWeapon;
PREDATOR_NPC_WEAPONS ChangeToWeapon;
ATTACK_DATA *current_attack;
STRATEGYBLOCK *Target;
char Target_SBname[SB_NAME_LENGTH];
int soundHandle;
HMODELCONTROLLER HModelController;
SECTION_DATA *My_Gun_Section; /* For template computation. */
SECTION_DATA *My_Elevation_Section; /* For elevation computation. */
/* these are for cloaking... */
PRED_CLOAKSTATE CloakStatus;
int CloakingEffectiveness;
int CloakTimer;
/* And these for the laser dots. */
THREE_LASER_DOT_DESC Pred_Laser_Sight;
int Pred_Laser_On :1;
int Explode :1;
/* Pathfinder parameters */
int path;
int stepnumber;
AIMODULE *missionmodule;
AIMODULE *fearmodule;
/* Pathfinder parameters */
char death_target_ID[SB_NAME_LENGTH]; //another strategy can be notified of the marine's death
STRATEGYBLOCK* death_target_sbptr;
int death_target_request;
}PREDATOR_STATUS_BLOCK;
typedef struct dormantPredatorStatusBlock
{
AVP_BEHAVIOUR_TYPE bhvr_type;
void* toolsData;
}DORMANT_PREDATOR_STATUS_BLOCK;
/* Tools data template */
typedef struct tools_data_predator
{
struct vectorch position;
int shapeIndex;
int predator_number;
char nameID[SB_NAME_LENGTH];
PREDATOR_NPC_WEAPONS primary;
PREDATOR_NPC_WEAPONS secondary;
int path;
int stepnumber;
char death_target_ID[SB_NAME_LENGTH];
int death_target_request;
}TOOLS_DATA_PREDATOR;
#define PRED_SELF_DESTRUCT_TIMER (ONE_FIXED*3)
#define PRED_WALKING_SPEED_MAX (5000)
#define PRED_WALKING_SPEED_MIN (3000)
#define PRED_PATIENCE_TIME (6*ONE_FIXED)
#define PRED_REGEN_TIME (10*ONE_FIXED)
#define PRED_MAXIDENTITY (4)
#define NO_OF_FRAGMENTS_FROM_DEAD_PREDATOR (10)
#define PRED_CLOSE_ATTACK_RANGE (1500) /* mm */
#define PRED_STAFF_ATTACK_RANGE (2000) /* mm */
#define PRED_NEAR_VIEW_WIDTH (500) /* mm */
#define PRED_FPPLASMA_INFRONT (600) /* mm */
#define PRED_FPPLASMA_ACROSS (-500) /* mm */
#define PRED_FPPLASMA_UP (900) /* mm */
#define PRED_FPPLASMA_INFRONTCROUCH (600) /* mm */
#define PRED_FPPLASMA_ACROSSCROUCH (-500) /* mm */
#define PRED_FPPLASMA_UPCROUCH (400) /* mm */
#define PRED_FPDISC_INFRONT (600) /* mm */
#define PRED_FPDISC_ACROSS (500) /* mm */
#define PRED_FPDISC_UP (500) /* mm */
#define PRED_FPDISC_INFRONTCROUCH (600) /* mm */
#define PRED_FPDISC_ACROSSCROUCH (500) /* mm */
#define PRED_FPDISC_UPCROUCH (200) /* mm */
#define PRED_PLASBOLTSPEED (22000) /* mm/s */
#define PRED_PLASBOLTDAMAGE (50)
/* 1.5-2 seconds in 1/16 second. NB DO NOT INCREASE THIS */
#define PRED_FAR_MOVE_TIME ((24+(FastRandom()&0x07))*(ONE_FIXED>>4))
#define PRED_NEAR_CLOSEATTACK_TIME ONE_FIXED /* 1 second */
extern void InitPredatorBehaviour(void* bhdata, STRATEGYBLOCK *sbPtr);
extern void InitDormantPredatorBehaviour(void* bhdata, STRATEGYBLOCK *sbPtr);
extern void PredatorBehaviour(STRATEGYBLOCK *sbPtr);
extern void MakePredatorNear(STRATEGYBLOCK *sbPtr);
extern void MakePredatorFar(STRATEGYBLOCK *sbPtr);
extern void PredatorIsDamaged(STRATEGYBLOCK *sbPtr, DAMAGE_PROFILE *damage, int multiple,SECTION_DATA *Section, VECTORCH *incoming);
extern void ActivateDormantPredator(STRATEGYBLOCK *sbPtr);
extern int NPCPredatorIsCloaked(STRATEGYBLOCK *sbPtr);
extern void StartPredatorSelfDestructExplosion(STRATEGYBLOCK *sbPtr);
#ifdef __cplusplus
}
#endif
#endif

350
3dc/avp/BH_SWDOR.C Normal file
View file

@ -0,0 +1,350 @@
/*------------------------------Patrick 12/3/97-----------------------------------
Source for Switch Operated Doors
--------------------------------------------------------------------------------*/
#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "stratdef.h"
#include "gamedef.h"
#include "bh_types.h"
#include "triggers.h"
#include "mslhand.h"
#include "psnd.h"
#define UseLocalAssert Yes
#include "ourasert.h"
#include "pvisible.h"
#include "bh_swdor.h"
#include "savegame.h"
/* external stuff */
extern int NormalFrameTime;
/*---------------------Patrick 12/3/97-------------------------
Initialisation of a switch door....
NB asumes that all switch doors start in a 'closed' state
-------------------------------------------------------------*/
void InitialiseSwitchDoor(void* bhdata, STRATEGYBLOCK* sbPtr)
{
SWITCH_DOOR_BEHAV_BLOCK *switchDoorBehaviourPtr;
SWITCH_DOOR_TOOLS_TEMPLATE *switchDoorToolsData;
MORPHCTRL *morphCtrl;
MORPHHEADER *morphHeader;
MORPHFRAME *morphFrame;
/* create a switch door data block */
switchDoorBehaviourPtr = (SWITCH_DOOR_BEHAV_BLOCK*)AllocateMem(sizeof(SWITCH_DOOR_BEHAV_BLOCK));
if (!switchDoorBehaviourPtr)
{
memoryInitialisationFailure = 1;
return;
}
switchDoorBehaviourPtr->myBehaviourType = I_BehaviourSwitchDoor;
sbPtr->SBdataptr = (void *)switchDoorBehaviourPtr;
/* cast the tools data for access */
switchDoorToolsData = (SWITCH_DOOR_TOOLS_TEMPLATE *)bhdata;
/* Set up a new Morph Control */
morphFrame = (MORPHFRAME*)AllocateMem(sizeof(MORPHFRAME));
if (!morphFrame)
{
memoryInitialisationFailure = 1;
return;
}
morphFrame->mf_shape1 = switchDoorToolsData->shapeOpen;
morphFrame->mf_shape2 = switchDoorToolsData->shapeClosed;
morphHeader = (MORPHHEADER*)AllocateMem(sizeof(MORPHHEADER));
if (!morphHeader)
{
memoryInitialisationFailure = 1;
return;
}
morphHeader->mph_numframes = 1;
morphHeader->mph_maxframes = ONE_FIXED;
morphHeader->mph_frames = morphFrame;
morphCtrl = (MORPHCTRL*)AllocateMem(sizeof(MORPHCTRL));
if (!morphCtrl)
{
memoryInitialisationFailure = 1;
return;
}
morphCtrl->ObMorphCurrFrame = 0;
morphCtrl->ObMorphFlags = 0;
morphCtrl->ObMorphSpeed = 0;
morphCtrl->ObMorphHeader = morphHeader;
switchDoorBehaviourPtr->morfControl = sbPtr->SBmorphctrl = morphCtrl;
/* set up my module, and it's morph controls */
COPY_NAME(sbPtr->SBname, switchDoorToolsData->nameID);
{
MREF mref=switchDoorToolsData->myModule;
ConvertModuleNameToPointer(&mref, MainSceneArray[0]->sm_marray);
GLOBALASSERT(mref.mref_ptr);
GLOBALASSERT(mref.mref_ptr->m_mapptr);
mref.mref_ptr->m_sbptr = sbPtr;
sbPtr->SBmoptr = mref.mref_ptr;
}
sbPtr->SBmomptr = sbPtr->SBmoptr->m_mapptr;
sbPtr->SBmomptr->MapMorphHeader = sbPtr->SBmorphctrl->ObMorphHeader;
sbPtr->SBmoptr->m_flags &= ~m_flag_open;
/* set up some other behaviour block stuff */
COPY_NAME(switchDoorBehaviourPtr->linkedDoorName, switchDoorToolsData->linkedDoorName);
switchDoorBehaviourPtr->doorState = I_door_closed;
switchDoorBehaviourPtr->linkedDoorPtr = (STRATEGYBLOCK *)0;
switchDoorBehaviourPtr->requestOpen = 0;
switchDoorBehaviourPtr->requestClose = 0;
switchDoorBehaviourPtr->openTimer = 0;
switchDoorBehaviourPtr->SoundHandle = SOUND_NOACTIVEINDEX;
CloseDoor(sbPtr->SBmorphctrl, DOOR_CLOSEFASTSPEED);
{
// Work out the door sound pitch
int maxX,maxY,maxZ,doorSize;
maxX=mainshapelist[morphFrame->mf_shape2]->shapemaxx;
maxY=mainshapelist[morphFrame->mf_shape2]->shapemaxy;
maxZ=mainshapelist[morphFrame->mf_shape2]->shapemaxz;
doorSize = maxX + maxY + maxZ;
if (doorSize < 3000) doorSize = 3000;
else if (doorSize > 8000) doorSize = 8000;
doorSize = (3000 - doorSize) >> 4;
switchDoorBehaviourPtr->doorType = doorSize;
}
}
/*---------------------Patrick 13/3/97-------------------------
Switch door behaviour function.
-------------------------------------------------------------*/
void SwitchDoorBehaviour(STRATEGYBLOCK* sbPtr)
{
SWITCH_DOOR_BEHAV_BLOCK *doorBehaviour;
MORPHCTRL *mCtrl;
MODULE *mPtr;
int linkedDoorIsClosed = 1;
GLOBALASSERT(sbPtr);
doorBehaviour = (SWITCH_DOOR_BEHAV_BLOCK*)sbPtr->SBdataptr;
GLOBALASSERT(doorBehaviour);
mCtrl = doorBehaviour->morfControl;
GLOBALASSERT(mCtrl);
mPtr = sbPtr->SBmoptr;
GLOBALASSERT(mPtr);
/* update morphing.... */
UpdateMorphing(mCtrl);
/* get state of linked door: if there isn't a linked door, 'linkeddoorisclosed'
remains true so that there is no obstruction to operation of this door.
NB can't use 'GetState' here, as it returns true only if the door is fully open
(used by the NPC's). Here, we need to determine if the door is closed (which is
not the same as !open) */
if(doorBehaviour->linkedDoorPtr)
{
if(((SWITCH_DOOR_BEHAV_BLOCK *)doorBehaviour->linkedDoorPtr->SBdataptr)->doorState != I_door_closed) linkedDoorIsClosed = 0;
}
switch(doorBehaviour->doorState)
{
case I_door_opening:
{
/* LOCALASSERT(linkedDoorIsClosed); */
/* check if we've got a close request */
if(doorBehaviour->requestClose && !AnythingInMyModule(sbPtr->SBmoptr))
{
if(sbPtr->SBdptr) CloseDoor(mCtrl, DOOR_CLOSESLOWSPEED);
else CloseDoor(mCtrl, DOOR_CLOSEFASTSPEED);
doorBehaviour->doorState = I_door_closing;
}
/* already opening, so just allow the door to continue... */
else if(mCtrl->ObMorphFlags & mph_flag_finished)
{
//door has finished opening
doorBehaviour->doorState = I_door_open;
doorBehaviour->openTimer = DOOR_FAROPENTIME;
if (doorBehaviour->SoundHandle!=SOUND_NOACTIVEINDEX)
{
Sound_Play(SID_DOOREND,"dp",&mPtr->m_world,doorBehaviour->doorType);
Sound_Stop(doorBehaviour->SoundHandle);
}
}
break;
}
case I_door_closing:
{
/* LOCALASSERT(linkedDoorIsClosed); */
/* check if we've got an open request, or anything has jumped in */
if((doorBehaviour->requestOpen)||(AnythingInMyModule(sbPtr->SBmoptr)))
{
//have to start opening again
if(sbPtr->SBdptr) OpenDoor(mCtrl, DOOR_OPENSLOWSPEED);
else OpenDoor(mCtrl, DOOR_OPENFASTSPEED);
doorBehaviour->doorState = I_door_opening;
Sound_Play(SID_DOORSTART,"dp",&mPtr->m_world,doorBehaviour->doorType);
Sound_Play(SID_DOORMID,"delp",&mPtr->m_world,&doorBehaviour->SoundHandle,doorBehaviour->doorType);
}
/* check if we've finished closing */
else if(mCtrl->ObMorphFlags & mph_flag_finished)
{
doorBehaviour->doorState = I_door_closed;
mPtr->m_flags &= ~m_flag_open;
if (doorBehaviour->SoundHandle!=SOUND_NOACTIVEINDEX)
{
Sound_Play(SID_DOOREND,"dp",&mPtr->m_world,doorBehaviour->doorType);
Sound_Stop(doorBehaviour->SoundHandle);
}
}
break;
}
case I_door_open:
{
/* LOCALASSERT(linkedDoorIsClosed); */
/*if we've got a close request , set the open timer to 0
so the door will start closing*/
if(doorBehaviour->requestClose)
{
doorBehaviour->openTimer=0;
}
/* check our timer to see if it's time to close*/
if(doorBehaviour->openTimer <= 0)
{
/* make sure there's nothing inside the door module before closing */
if(AnythingInMyModule(sbPtr->SBmoptr)==0)
{
if(sbPtr->SBdptr) CloseDoor(mCtrl, DOOR_CLOSESLOWSPEED);
else CloseDoor(mCtrl, DOOR_CLOSEFASTSPEED);
doorBehaviour->doorState = I_door_closing;
doorBehaviour->openTimer = 0;
Sound_Play(SID_DOORSTART,"dp",&mPtr->m_world,doorBehaviour->doorType);
Sound_Play(SID_DOORMID,"delp",&mPtr->m_world,&doorBehaviour->SoundHandle,doorBehaviour->doorType);
}
}
else doorBehaviour->openTimer -= NormalFrameTime;
break;
}
case I_door_closed:
{
if((doorBehaviour->requestOpen)&&(linkedDoorIsClosed))
{
/* just open the door */
if(sbPtr->SBdptr) OpenDoor(mCtrl, DOOR_OPENSLOWSPEED);
else OpenDoor(mCtrl, DOOR_OPENFASTSPEED);
doorBehaviour->doorState = I_door_opening;
mPtr->m_flags |= m_flag_open;
Sound_Play(SID_DOORSTART,"dp",&mPtr->m_world,doorBehaviour->doorType);
Sound_Play(SID_DOORMID,"delp",&mPtr->m_world,&doorBehaviour->SoundHandle,doorBehaviour->doorType);
}
}
}
/* must reset this every frame */
doorBehaviour->requestOpen = 0;
doorBehaviour->requestClose = 0;
}
/*--------------------**
** Loading and Saving **
**--------------------*/
typedef struct switch_door_save_block
{
SAVE_BLOCK_STRATEGY_HEADER header;
DOOR_STATES doorState;
int openTimer;
unsigned int requestOpen :1;
unsigned int requestClose :1;
//from the morph control
int ObMorphCurrFrame;
int ObMorphFlags;
int ObMorphSpeed;
}SWITCH_DOOR_SAVE_BLOCK;
//defines for load/save macros
#define SAVELOAD_BLOCK block
#define SAVELOAD_BEHAV doorbhv
void LoadStrategy_SwitchDoor(SAVE_BLOCK_STRATEGY_HEADER* header)
{
STRATEGYBLOCK* sbPtr;
SWITCH_DOOR_BEHAV_BLOCK *doorbhv;
SWITCH_DOOR_SAVE_BLOCK* block = (SWITCH_DOOR_SAVE_BLOCK*) header;
if(header->size!=sizeof(*block)) return;
//find the existing strategy block
sbPtr = FindSBWithName(header->SBname);
if(!sbPtr) return;
//make sure the strategy found is of the right type
if(sbPtr->I_SBtype != I_BehaviourSwitchDoor) return;
doorbhv = (SWITCH_DOOR_BEHAV_BLOCK*)sbPtr->SBdataptr;
COPYELEMENT_LOAD(doorState)
COPYELEMENT_LOAD(openTimer)
COPYELEMENT_LOAD(requestOpen)
COPYELEMENT_LOAD(requestClose)
COPYELEMENT_LOAD_EXT(block->ObMorphCurrFrame,doorbhv->morfControl->ObMorphCurrFrame)
COPYELEMENT_LOAD_EXT(block->ObMorphFlags , doorbhv->morfControl->ObMorphFlags)
COPYELEMENT_LOAD_EXT(block->ObMorphSpeed , doorbhv->morfControl->ObMorphSpeed)
Load_SoundState(&doorbhv->SoundHandle);
}
void SaveStrategy_SwitchDoor(STRATEGYBLOCK* sbPtr)
{
SWITCH_DOOR_SAVE_BLOCK *block;
SWITCH_DOOR_BEHAV_BLOCK *doorbhv ;
doorbhv = (SWITCH_DOOR_BEHAV_BLOCK*)sbPtr->SBdataptr;
GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
COPYELEMENT_SAVE(doorState)
COPYELEMENT_SAVE(openTimer)
COPYELEMENT_SAVE(requestOpen)
COPYELEMENT_SAVE(requestClose)
COPYELEMENT_SAVE_EXT(block->ObMorphCurrFrame,doorbhv->morfControl->ObMorphCurrFrame)
COPYELEMENT_SAVE_EXT(block->ObMorphFlags , doorbhv->morfControl->ObMorphFlags)
COPYELEMENT_SAVE_EXT(block->ObMorphSpeed , doorbhv->morfControl->ObMorphSpeed)
Save_SoundState(&doorbhv->SoundHandle);
}

40
3dc/avp/BH_SWDOR.H Normal file
View file

@ -0,0 +1,40 @@
/*------------------------------Patrick 12/3/97-----------------------------------
Header for Switch Operated Doors
--------------------------------------------------------------------------------*/
typedef struct switch_door_behaviour_type
{
AVP_BEHAVIOUR_TYPE myBehaviourType; /* just for testing system integrity */
DOOR_STATES doorState;
MORPHCTRL *morfControl;
char linkedDoorName[SB_NAME_LENGTH];
STRATEGYBLOCK* linkedDoorPtr;
int openTimer;
unsigned int requestOpen :1;
unsigned int requestClose :1;
int SoundHandle;
int doorType; // Used to determine door sound type
} SWITCH_DOOR_BEHAV_BLOCK;
typedef struct switch_door_tools_template
{
BOOL state;
MREF myModule;
int shapeOpen;
int shapeClosed;
char linkedDoorName[SB_NAME_LENGTH];
char nameID[SB_NAME_LENGTH];
} SWITCH_DOOR_TOOLS_TEMPLATE;
#define DOOR_OPENSLOWSPEED (1<<16)
#define DOOR_OPENFASTSPEED (1<<20)
#define DOOR_CLOSESLOWSPEED (1<<17)
#define DOOR_CLOSEFASTSPEED (1<<20)
#define DOOR_FAROPENTIME (ONE_FIXED<<2) /* 4 seconds: DO NOT CHANGE THIS OR AI MAY NOT WORK*/
#define DOOR_OPENDISTANCE (5000) /* mm */
extern void InitialiseSwitchDoor(void* bhdata, STRATEGYBLOCK* sbptr);
extern void SwitchDoorBehaviour(STRATEGYBLOCK* sbptr);
extern void OpenDoor(MORPHCTRL *mctrl, int speed);
extern void CloseDoor(MORPHCTRL *mctrl, int speed);

3723
3dc/avp/BH_TYPES.C Normal file

File diff suppressed because it is too large Load diff

516
3dc/avp/BH_TYPES.H Normal file
View file

@ -0,0 +1,516 @@
#ifndef _bhtypes_h_
#define _bhtypes_h_ 1
#ifndef _equipmnt_h_
#include "equipmnt.h"
#endif
#include "gameflow.h"
#include "pmove.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
I think I am going to devide the behaviour of objects into two different forms
In terms of emulating 3d we need to think of multiple cluster of sprite sequences to
descibe any one motion. In this respect I am going to have a list of capabilities for
objects. If you supply One animation sequence that allows a capabiltity the animation capability
language will allow that capabiltiy. If it is a front walk, the object will walk
but it will always display the one type of sequence even if it is walking away from
you. When we load up a sprite sequence we include an enum that tells us what capabiltiy_type
these sequence is part of. The animation capabiltity language and capabiltiy_type can refer
to morphing equally as to sprites (morphing is some what easier as the object will always look
right
Other objects are rather dull and the above capability system is too complex. A module
playing a TV does not need such a comple behaviour. These objects have much simpler
strategies and we will have specfifc low level functions to deal with them.
*/
typedef enum actor_capability_types
{
BHTypeWalk, /* gen movement */
BHTypeCrawl, /* gen movement */
BHTypeRun, /* gen movement */
BHTypeFly, /* gen movement */
BHTypeStandUp,
BHTypeSitDown,
BHTypeKneelDown,
BHTypeCroach,
BHTypeAttack1,
BHTypeAttack2,
BHTypeAttack3,
BHTypeRangedAttack1,
BHTypeRangedAttack2,
BHTypeRangedAttack3,
BHTypeHit,
BHTypeDying,
BHTypeDead,
BHTypeJump
} ACTOR_CAPABILITY_TYPES;
/* ****************** STRATEGY BLOCK Behaviour DESCRIPTION ************ */
typedef struct CapabilityDescription
{
int num_animating_items;
int **item_animations;
} CAPABILITY_DESCRIPTION;
/* the item_animations are specific to each animating
item the have no formal description interms of a type
the theyare listed as.
int item_num
seq_des1
seq_des2
seq_des3
seq_des4
term
the list of void* pointers points to the initial
item_num for the following sequences
*/
typedef struct sequence_descriptor
{
ACTOR_CAPABILITY_TYPES cap_type;
TXANIMHEADER* txanim_header;
int view_angle;
int view_azimuth;
} SEQUENCE_DESCRIPTOR;
typedef struct SuicideTimer
{
int time_left; /*agrgggghhh*****/
}SUICIDE_TIMER;
/**************************** SPECIFIC BEHAVIOUR TYPES ************************/
// ENUM now in Stratdef.h
/*-------------Patrick 21/10/96 --------------------
This structure is used in Player Status to represent
the various player input requests. It consists
of single bit fields, which are used as a bit-mask
for recording key-combo sequences for special moves.
for the purposes of bit-masking, it is implemented as
a union with an unsigned int...
NB it is easier to add new fields towards the end,
as otherwise you may have to change the special
move input bitmasks
--------------------------------------------------*/
typedef struct player_input_requests
{
unsigned int Rqst_Forward :1;
unsigned int Rqst_Backward :1;
unsigned int Rqst_TurnLeft :1;
unsigned int Rqst_TurnRight :1;
unsigned int Rqst_LookUp :1;
unsigned int Rqst_LookDown :1;
unsigned int Rqst_FirePrimaryWeapon :1;
unsigned int Rqst_Faster :1;
unsigned int Rqst_SideStepLeft :1;
unsigned int Rqst_SideStepRight :1;
unsigned int Rqst_Strafe :1;
unsigned int Rqst_Crouch :1;
unsigned int Rqst_Jump :1;
/* NB Lie Down is set by special moves only (ie doesn't require a user input, configuration entry, etc) */
unsigned int Rqst_Operate :1;
unsigned int Rqst_CentreView :1;
unsigned int Rqst_NextWeapon :1;
unsigned int Rqst_PreviousWeapon :1;
unsigned int Rqst_WeaponNo :4;
unsigned int Rqst_QuitGame :1;
unsigned int Rqst_PauseGame :1;
/* KJL 16:58:37 04/11/98 - Change vision does a variety of things, dependent on the player's
character. */
unsigned int Rqst_ChangeVision :1;
unsigned int Rqst_FireSecondaryWeapon :1;
/* Predator Specific */
unsigned int Rqst_CycleVisionMode :1;
unsigned int Rqst_ZoomIn :1;
unsigned int Rqst_ZoomOut :1;
unsigned int Rqst_GrapplingHook :1;
/* Alien Specific */
unsigned int Rqst_Spit :1;
/* Marine Specific */
unsigned int Rqst_ThrowFlare :1;
unsigned int Rqst_Jetpack :1;
unsigned int :0;
}PLAYER_INPUT_REQUESTS;
/*-------------Patrick 23/10/96 --------------------
Some defines for key combo bit masks
these should correspond to the above request flags.
--------------------------------------------------*/
#define INPUT_BITMASK_FORWARD 0x00000001
#define INPUT_BITMASK_BACKWARD 0x00000002
#define INPUT_BITMASK_LEFT 0x00000004
#define INPUT_BITMASK_RIGHT 0x00000008
#define INPUT_BITMASK_FIRE 0x00000040
#define INPUT_BITMASK_FASTER 0x00000080
#define INPUT_BITMASK_STRAFE 0x00000100
#define INPUT_BITMASK_CROUCH 0x00000200
#define INPUT_BITMASK_JUMP 0x00000400
/* KJL 14:16:52 09/20/96 - the new player status type
modified by patrick */
typedef struct player_status
{
AVP_BEHAVIOUR_TYPE bhvr_type;
/* player's weapons */
PLAYER_WEAPON_DATA WeaponSlot[MAX_NO_OF_WEAPON_SLOTS];
enum WEAPON_SLOT SelectedWeaponSlot;
enum WEAPON_SLOT SwapToWeaponSlot;
enum WEAPON_SLOT PreviouslySelectedWeaponSlot;
int Health; /* in 16.16 */
int Energy; /* in 16.16 */
int Armour; /* in 16.16 */
/* general info */
/* KJL 17:28:20 09/19/96 - not yet used
int ArmourType;
int HealingRate;
int CloakingType;
int VisionType;
*/
/*-----Patrick 15/10/96---------
Player movement bits...
------------------------------*/
enum player_morph_state ShapeState; /* for controlling morphing */
/* and these are for free (ie normal) movement,
and should be set by the (platform dependant) input
device reading function */
unsigned char Mvt_DeviceType;
signed int Mvt_MotionIncrement; /* 65536 (Forward) to -65536 (Backward) */
signed int Mvt_TurnIncrement; /* 65536 (Right) to -65536 (Left)*/
signed int Mvt_PitchIncrement; /* 65536 to -65536 */
signed int Mvt_SideStepIncrement; /* 65536 to -65536 */
/* KJL 10:48:33 03/26/97 - inertia data */
signed int ForwardInertia;
signed int StrafeInertia;
signed int TurnInertia;
int ViewPanX; /* the looking up/down value that used to be in displayblock */
union Mvt_InputRequests
{
unsigned int Mask;
unsigned int Mask2;
PLAYER_INPUT_REQUESTS Flags;
}Mvt_InputRequests;
/* security clearances */
unsigned int securityClearances;
/* useful flags */
unsigned int IsAlive :1;
unsigned int IsImmortal :1;
unsigned int Mvt_AnalogueTurning :1;
unsigned int Mvt_AnaloguePitching :1;
unsigned int Absolute_Pitching :1;
unsigned int SwappingIsDebounced :1;
unsigned int DemoMode :1;
unsigned int IHaveAPlacedAutogun :1;
unsigned int IsMovingInWater :1;
unsigned int JetpackEnabled :1;
unsigned int GrapplingHookEnabled :1;
unsigned int MTrackerType;
/* Patrick: 1/7/97 : for predator-type cloaking stuff */
unsigned int cloakOn :1;
unsigned int cloakPositionGivenAway :1;
int FieldCharge;
int cloakPositionGivenAwayTimer;
int PlasmaCasterCharge;
/* KJL 99/2/3 - Cloaking Effectiveness
ranges from 0 (useless) to ONE_FIXED (practically invisible) */
int CloakingEffectiveness;
// John 28/7/97 Game Flow stuff
PLAYERMISSION CurrentMission;
unsigned long StateChangeObjectFlags;
/* Encumberance */
ENCUMBERANCE_STATE Encumberance;
STRATEGYBLOCK *MyFaceHugger;
STRATEGYBLOCK *MyCorpse;
int tauntTimer;
int soundHandle;
/* Why no 2, you ask? */
int soundHandle3;
/* Because '3' is always crackling fire, for *
* netghosts and corpses. Really, 2 should be*
* the voice and 1 should be weapon use. */
int soundHandle4;
/* For the splash. */
int soundHandle5;
/* For the jetpack. */
int soundHandleForPredatorCloakDamaged;
/* the above seemed better than soundHandle5 :) */
HMODELCONTROLLER HModelController;
int incidentFlag;
int incidentTimer;
int fireTimer;
int invulnerabilityTimer;
} PLAYER_STATUS;
#define TAUNT_LENGTH (ONE_FIXED<<1)
#define PLAYER_ON_FIRE_TIME (ONE_FIXED*20)
#define STARTOFGAME_MARINE_HEALTH (100*65536) /* ie. 100 in 16.16 notation */
#define STARTOFGAME_MARINE_ENERGY (100*65536) /* ie. 100 in 16.16 notation */
#define STARTOFGAME_MARINE_ARMOUR (100*65536) /* ie. 100 in 16.16 notation */
/* Patrick 22/8/97------------------------------------------------
Cloaking stuff
------------------------------------------------------------------*/
#define PLAYERCLOAK_MAXENERGY (30*ONE_FIXED) /* fixed point seconds */
#define PLAYERCLOAK_RECHARGEFACTOR (4) /* ... times slower than discharge */
#define PLAYERCLOAK_POSTIONGIVENAWAYTIME (ONE_FIXED>>2) /*(2*ONE_FIXED) fixed point seconds */
#define PLAYERCLOAK_THRESHOLD (5*ONE_FIXED)
#define PLAYERCLOAK_POWERON_DRAIN (2*ONE_FIXED)
#define PLAYERCLOAK_DRAIN_FACTOR (4)
/* Moved mere from player.c, CDF 23/4/98 */
extern PLAYER_STATUS* PlayerStatusPtr;
/******************** SIMPLE ANIMATIONS ********************/
typedef struct simpleanimbehaviour
{
AVP_BEHAVIOUR_TYPE bhvr_type;
TXACTRLBLK *tacbSimple;
}SIMPLE_ANIM_BEHAV_BLOCK;
typedef struct simple_anim_tools_template
{
int shape_num;
MREF my_module;
char nameID[SB_NAME_LENGTH];
} SIMPLE_ANIM_TOOLS_TEMPLATE;
/**********************************************************/
/**********************DOORS*******************************/
typedef enum{ /* this may be flags*/
I_door_opening,
I_door_closing,
I_door_open,
I_door_closed,
} DOOR_STATES;
/******************** PROXIMITY DOORS ********************/
typedef struct ProxDoorBehaviourType
{
AVP_BEHAVIOUR_TYPE bhvr_type;
int door_state;
MORPHCTRL *PDmctrl;
/*---- Patrick 1/1/97 -----
added for far ai stratgies
--------------------------*/
int alienTimer;
unsigned int alienTrigger :1;
unsigned int marineTrigger :1;
unsigned int triggeredByMarine :1;
/*---- Roxby 1/1/97 -----
Added so that another door can lock
this door closed
--------------------------*/
BOOL lockable_door;
BOOL door_locked;
char target_name[SB_NAME_LENGTH];
STRATEGYBLOCK* door_lock_target;
int SoundHandle;
int doorType; // Used to determine door sound type
int door_opening_speed;
int door_closing_speed;
} PROXDOOR_BEHAV_BLOCK;
typedef struct prox_door_tools_template
{
BOOL has_lock_target;
char target_name [SB_NAME_LENGTH];
MREF my_module;
int shape_open;
int shape_closed;
char nameID[SB_NAME_LENGTH];
BOOL door_is_locked;
int door_opening_speed;
int door_closing_speed;
} PROX_DOOR_TOOLS_TEMPLATE;
/* Structures for Stat Initialisation */
typedef enum {
I_NPC_Civilian=0,
I_NPC_FaceHugger,
I_NPC_ChestBurster,
I_NPC_Alien,
I_NPC_Xenoborg,
I_NPC_Marine,
I_NPC_PredatorAlien,
I_NPC_SFMarine,
I_NPC_Predator,
I_NPC_PraetorianGuard,
I_NPC_AlienQueen,
I_NPC_DefaultInanimate,
I_PC_Alien_Easy,
I_PC_Marine_Easy,
I_PC_Predator_Easy,
I_PC_Alien_Medium,
I_PC_Marine_Medium,
I_PC_Predator_Medium,
I_PC_Alien_Hard,
I_PC_Marine_Hard,
I_PC_Predator_Hard,
I_PC_Alien_Impossible,
I_PC_Marine_Impossible,
I_PC_Predator_Impossible,
I_PC_Alien_MaxStats,
I_NPC_SentryGun,
I_NPC_Android,
I_NPC_End,
} NPC_TYPES;
typedef struct {
NPC_TYPES Type;
//int StartingHealth;
//int StartingArmour;
//SBHEALTHFLAGS SB_H_flags;
DAMAGEBLOCK StartingStats;
} NPC_DATA;
/* Interface function! */
extern NPC_DATA *GetThisNpcData(NPC_TYPES NpcType);
/********************************************************/
/******************* Database behaviour************/
/*
we will need to include an enum into another menu
graphic which contains the text to overlay onto
the menugraphics
*/
typedef struct database
{
AVP_BEHAVIOUR_TYPE bhvr_type;
int num;
}DATABASE_BLOCK;
typedef struct database_template
{
int num;
VECTORCH position;
EULER orientation;
int shape_num;
} DATABASE_TOOLS_TEMPLATE;
extern void DatabaseMenus(DATABASE_BLOCK* db);
/***********************************************************/
/****************** externs for bh_types.c ******************/
/* functions*/
extern void AssignAllSBNames();
extern void AssignRunTimeBehaviours(STRATEGYBLOCK* sbptr);
extern void EnableBehaviourType(STRATEGYBLOCK* sbptr, AVP_BEHAVIOUR_TYPE sb_type, void *bhdata);
extern void ExecuteBehaviour(STRATEGYBLOCK* sbptr);
extern void ObjectBehaviours(void);
extern void RequestState(STRATEGYBLOCK* sb, int message, STRATEGYBLOCK * SBRequester);
extern BOOL GetState(STRATEGYBLOCK* sb);
extern void RemoveBehaviourStrategy(STRATEGYBLOCK* sbptr);
extern void UnlockThisProxdoor(STRATEGYBLOCK* sbptr);
extern void FindMaxZXandYAverages(VECTORCH* vect, SHAPEHEADER* shapeptr);
extern DISPLAYBLOCK *MakeObject(AVP_BEHAVIOUR_TYPE bhvr, VECTORCH *positionPtr);
extern void SetupPlayerAutoGun();
#ifdef __cplusplus
};
#endif
#endif

234
3dc/avp/BH_XENO.H Normal file
View file

@ -0,0 +1,234 @@
/* Patrick 4/7/97------------------------------
Header file for xenoborg support functions
ChrisF 6/7/98 Well, sort of.
---------------------------------------------*/
#ifndef _bhxeno_h_
#define _bhxeno_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/* KJL 16:57:28 16/07/98 - particle.h is needed for LASER_BEAM_DESC */
#include "particle.h"
#include "bh_ais.h"
/* Patrick 4/7/97------------------------------
Enumerations of sequences and states
---------------------------------------------*/
typedef enum xeno_bhstate
{
XS_ActiveWait,
XS_TurnToFace,
XS_Following,
XS_Returning,
XS_Inactive,
XS_Activating,
XS_Deactivating,
XS_Avoidance,
XS_Regenerating,
XS_Dying,
XS_ShootingTheRoof,
}XENO_BHSTATE;
/* Patrick 4/7/97------------------------------
Structures for behaviour data & tools data
---------------------------------------------*/
typedef struct xenoStatusBlock
{
signed int health;
XENO_BHSTATE behaviourState;
XENO_BHSTATE lastState;
int stateTimer;
NPC_MOVEMENTDATA moveData;
NPC_WANDERDATA wanderData;
NPC_OBSTRUCTIONREPORT obstruction;
AIMODULE *my_module;
VECTORCH my_spot_therin;
VECTORCH my_orientdir_therin;
int module_range;
int UpTime;
int GibbFactor;
int Wounds;
HMODELCONTROLLER HModelController;
DELTA_CONTROLLER *head_pan;
DELTA_CONTROLLER *head_tilt;
DELTA_CONTROLLER *left_arm_pan;
DELTA_CONTROLLER *left_arm_tilt;
DELTA_CONTROLLER *right_arm_pan;
DELTA_CONTROLLER *right_arm_tilt;
DELTA_CONTROLLER *torso_twist;
STRATEGYBLOCK *Target;
char Target_SBname[SB_NAME_LENGTH];
VECTORCH targetTrackPos;
int Head_Pan;
int Head_Tilt;
int Left_Arm_Pan;
int Left_Arm_Tilt;
int Right_Arm_Pan;
int Right_Arm_Tilt;
int Torso_Twist;
int Old_Head_Pan;
int Old_Head_Tilt;
int Old_Left_Arm_Pan;
int Old_Left_Arm_Tilt;
int Old_Right_Arm_Pan;
int Old_Right_Arm_Tilt;
int Old_Torso_Twist;
/* KJL 12:23:24 09/12/98 - muzzleflashes replaced by
beam weapon thingies */
LASER_BEAM_DESC LeftMainBeam;
LASER_BEAM_DESC RightMainBeam;
/* KJL 16:56:38 16/07/98 */
LASER_BEAM_DESC TargetingLaser[3];
unsigned int headpandir :1;
unsigned int headtiltdir :1;
unsigned int leftarmpandir :1;
unsigned int leftarmtiltdir :1;
unsigned int rightarmpandir :1;
unsigned int rightarmtiltdir :1;
unsigned int torsotwistdir :1;
unsigned int headLock :1;
unsigned int leftArmLock :1;
unsigned int rightArmLock :1;
unsigned int targetSightTest :1;
unsigned int IAmFar :1;
unsigned int ShotThisFrame :1;
unsigned int FiringLeft :1;
unsigned int FiringRight :1;
unsigned int UseHeadLaser :1;
unsigned int UseLALaser :1;
unsigned int UseRALaser :1;
unsigned int HeadLaserOnTarget :1;
unsigned int LALaserOnTarget :1;
unsigned int RALaserOnTarget :1;
unsigned int head_moving :1;
unsigned int la_moving :1;
unsigned int ra_moving :1;
unsigned int torso_moving :1;
int soundHandle1;
int soundHandle2;
int incidentFlag;
int incidentTimer;
int head_whirr;
int left_arm_whirr;
int right_arm_whirr;
int torso_whirr;
char death_target_ID[SB_NAME_LENGTH];
STRATEGYBLOCK* death_target_sbptr;
int death_target_request;
WAYPOINT_MANAGER waypointManager;
}XENO_STATUS_BLOCK;
typedef struct tools_data_xeno
{
struct vectorch position;
int shapeIndex;
char nameID[SB_NAME_LENGTH];
char death_target_ID[SB_NAME_LENGTH];
int death_target_request;
struct euler starteuler;
int UpTime; /* Default to '20' */
int ModuleRange; /* Default to '7' */
}TOOLS_DATA_XENO;
/* Patrick 4/7/97------------------------------
Some defines
---------------------------------------------*/
#define XENO_STARTING_HEALTH 600
#define XENO_NEAR_SPEED 1000 /* mm/s */
#define XENO_NEAR_ACCURACY 5 /* mm per m max deviation */
#define XENO_NEAR_VIEW_WIDTH 500 /* mm */
#define XENO_CLOSE_APPROACH_DISTANCE 3000 /* mm */
#define XENO_FIRINGPOINT_INFRONT 1000 /* mm */
#define XENO_FIRINGPOINT_ACROSS 300 /* mm */
#define XENO_FIRINGPOINT_UP 100 /* mm */
#define XENO_PROJECTILESPEED 20000 /* mm/s */
#define XENO_PROJECTILEDAMAGE 10
#define XENO_SENTRY_SENSITIVITY 1500
#define XENO_FAR_MOVE_TIME ((24+(FastRandom()&0x07))*(ONE_FIXED>>4))
/* 1-2 seconds in 1/8ths of a second */
#define XENO_NEAR_TIMEBETWEENFIRING ((8+(FastRandom()&0x07))*(ONE_FIXED>>3))
#define XENO_RECOILTIME (ONE_FIXED>>1) /* 1/2 seconds */
#define XENO_ACTIVATION_TIME (ONE_FIXED) /* 1 second */
#define XENO_DEACTIVATION_TIME (ONE_FIXED) /* 1 second */
#define XENO_REGEN_TIME (ONE_FIXED*5)
#define XENO_POWERDOWN_TIME (ONE_FIXED*5)
/* 2,3 or 4*/
#define XENO_VOLLEYSIZE (2+(FastRandom()%3))
#define XENO_HEADPAN_GIMBALL (1024)
#define XENO_HEADTILT_GIMBALL (512)
#define XENO_TORSO_GIMBALL (1195)
#define XENO_LEFTARM_CW_GIMBALL (626)
#define XENO_LEFTARM_ACW_GIMBALL (910)
#define XENO_RIGHTARM_CW_GIMBALL (910)
#define XENO_RIGHTARM_ACW_GIMBALL (626)
#define XENO_ARM_PITCH_GIMBALL (1024)
#if 0
/* Original values. */
#define XENO_HEAD_LOCK_RATE (2) /* Was 0 */
#define XENO_HEAD_SCAN_RATE (3)
#define XENO_TORSO_TWIST_RATE (3)
#define XENO_ARM_LOCK_RATE (4)
#define XENO_FOOT_TURN_RATE (3)
#else
/* Let's slow everything down a wee bit. */
#define XENO_HEAD_LOCK_RATE (2) /* Was 0 */
#define XENO_HEAD_SCAN_RATE (4)
#define XENO_TORSO_TWIST_RATE (5)
#define XENO_ARM_LOCK_RATE (5)
#define XENO_FOOT_TURN_RATE (5)
#endif
/* Patrick 4/7/97------------------------------
Some prototypes
---------------------------------------------*/
void InitXenoborgBehaviour(void* bhdata, STRATEGYBLOCK *sbPtr);
void XenoborgBehaviour(STRATEGYBLOCK *sbPtr);
void MakeXenoborgNear(STRATEGYBLOCK *sbPtr);
void MakeXenoborgFar(STRATEGYBLOCK *sbPtr);
void XenoborgIsDamaged(STRATEGYBLOCK *sbPtr, DAMAGE_PROFILE *damage, int multiple, int wounds,VECTORCH *incoming);
int XenoSight_FrustrumReject(STRATEGYBLOCK *sbtr,VECTORCH *localOffset);
#ifdef __cplusplus
}
#endif
#endif

1867
3dc/avp/Bh_debri.c Normal file

File diff suppressed because it is too large Load diff

19113
3dc/avp/Bh_marin.c Normal file

File diff suppressed because it is too large Load diff

3049
3dc/avp/Bh_near.c Normal file

File diff suppressed because it is too large Load diff

7208
3dc/avp/Bh_pred.c Normal file

File diff suppressed because it is too large Load diff

5308
3dc/avp/Bh_xeno.c Normal file

File diff suppressed because it is too large Load diff

448
3dc/avp/BonusAbilities.c Normal file
View file

@ -0,0 +1,448 @@
/* KJL 16:14:35 09/09/98 - BonusAbilities.c */
#include "3dc.h"
#include "module.h"
#include "inline.h"
#include "stratdef.h"
#include "gamedef.h"
#include "bh_types.h"
#include "weapons.h"
#include "dynblock.h"
#include "avpview.h"
#include "load_shp.h"
#include "kzsort.h"
#include "kshape.h"
#include "pfarlocs.h"
#include "pvisible.h"
#define UseLocalAssert Yes
#include "ourasert.h"
extern int NormalFrameTime;
/* KJL 16:18:20 09/09/98 - Predator Grappling Hook */
struct GrapplingHookData
{
int IsEmbedded;
int IsEngaged;
int Tightness;
VECTORCH Position;
MATRIXCH Orientation;
int ShapeIndex;
DISPLAYBLOCK *DispPtr;
};
static struct GrapplingHookData GrapplingHook;
static DISPLAYBLOCK* CreateGrapplingHook(void);
extern void InitialiseGrapplingHook(void)
{
GrapplingHook.IsEngaged = 0;
GrapplingHook.IsEmbedded = 0;
GrapplingHook.ShapeIndex = GetLoadedShapeMSL("spear");
GrapplingHook.DispPtr = 0;
}
static void FireGrapplingHook(void);
void DisengageGrapplingHook(void);
extern void ActivateGrapplingHook(void)
{
if (GrapplingHook.IsEngaged)
{
DisengageGrapplingHook();
}
else
{
FireGrapplingHook();
}
}
static void FireGrapplingHook(void)
{
GrapplingHook.DispPtr = CreateGrapplingHook();
if (GrapplingHook.DispPtr)
{
GrapplingHook.IsEngaged = 1;
GrapplingHook.IsEmbedded = 0;
GrapplingHook.Tightness = ONE_FIXED;
/* CDF 14/4/99 Make a sound... */
Sound_Play(SID_GRAPPLE_THROW,"h");
#if 0
/* los */
GrapplingHook.Position = PlayersTarget.Position;
GrapplingHook.Orientation = Global_VDB_Ptr->VDB_Mat;
TransposeMatrixCH(&GrapplingHook.Orientation);
#endif
}
}
static DISPLAYBLOCK* CreateGrapplingHook(void)
{
STRATEGYBLOCK* sbPtr;
/* create and initialise a strategy block */
sbPtr = CreateActiveStrategyBlock();
if(!sbPtr) return NULL; /* failure */
InitialiseSBValues(sbPtr);
sbPtr->I_SBtype = I_BehaviourGrapplingHook;
AssignNewSBName(sbPtr);
/* create, initialise and attach a dynamics block */
sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_ROCKET);
if(sbPtr->DynPtr)
{
DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
dynPtr->PrevPosition = dynPtr->Position = Global_VDB_Ptr->VDB_World;
GrapplingHook.Orientation = Global_VDB_Ptr->VDB_Mat;
TransposeMatrixCH(&GrapplingHook.Orientation);
dynPtr->OrientMat = GrapplingHook.Orientation;
dynPtr->LinVelocity.vx = dynPtr->OrientMat.mat31;
dynPtr->LinVelocity.vy = dynPtr->OrientMat.mat32;
dynPtr->LinVelocity.vz = dynPtr->OrientMat.mat33;
}
else
{
/* dynamics block allocation failed... */
RemoveBehaviourStrategy(sbPtr);
return NULL;
}
sbPtr->shapeIndex = GetLoadedShapeMSL("spear");
sbPtr->maintainVisibility = 0;
sbPtr->containingModule = ModuleFromPosition(&(sbPtr->DynPtr->Position), 0);
LOCALASSERT(sbPtr->containingModule);
if(!(sbPtr->containingModule))
{
/* no containing module can be found... abort*/
RemoveBehaviourStrategy(sbPtr);
return NULL;
}
{
MODULE tempModule;
DISPLAYBLOCK *dPtr;
DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
VisibilityDefaultObjectMap.MapShape = sbPtr->shapeIndex;
tempModule.m_mapptr = &VisibilityDefaultObjectMap;
tempModule.m_sbptr = (STRATEGYBLOCK*)NULL;
tempModule.m_numlights = 0;
tempModule.m_lightarray = (struct lightblock *)0;
tempModule.m_extraitemdata = (struct extraitemdata *)0;
tempModule.m_dptr = NULL; /* this is important */
#if SupportWIndows95
tempModule.name = NULL; /* this is important */
#endif
AllocateModuleObject(&tempModule);
dPtr = tempModule.m_dptr;
if(dPtr==NULL)
{
RemoveBehaviourStrategy(sbPtr);
return NULL;
}
sbPtr->SBdptr = dPtr;
dPtr->ObStrategyBlock = sbPtr;
dPtr->ObMyModule = NULL;
dPtr->ObWorld = dynPtr->Position;
dPtr->ObEuler = dynPtr->OrientEuler;
dPtr->ObMat = dynPtr->OrientMat;
dPtr->ObRadius=10;
dPtr->ObMaxX=10;
dPtr->ObMinX=-10;
dPtr->ObMaxY=10;
dPtr->ObMinY=-10;
dPtr->ObMaxZ=10;
dPtr->ObMinZ=-10;
/* make displayblock a dynamic module object */
dPtr->ObFlags3 |= ObFlag3_DynamicModuleObject;
// sbPtr->SBDamageBlock.IsOnFire=1;
return dPtr;
}
}
extern void GrapplingHookBehaviour(STRATEGYBLOCK *sbPtr)
{
DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
if (!GrapplingHook.IsEmbedded)
{
COLLISIONREPORT *reportPtr = dynPtr->CollisionReportPtr;
if(reportPtr)
{
char stickWhereYouAre = 0;
if (reportPtr->ObstacleSBPtr)
{
DISPLAYBLOCK *dispPtr = reportPtr->ObstacleSBPtr->SBdptr;
if (dispPtr)
if (dispPtr->ObMyModule && (!dispPtr->ObMorphCtrl))
{
stickWhereYouAre=1;
}
}
else
{
stickWhereYouAre = 1;
}
if(stickWhereYouAre)
{
dynPtr->IsStatic=1;
dynPtr->PrevPosition=dynPtr->Position;
GrapplingHook.Position=dynPtr->Position;
GrapplingHook.IsEmbedded=1;
/* CDF 14/4/99 Make a sound. */
Sound_Play(SID_GRAPPLE_HIT_WALL,"d",&dynPtr->Position);
return;
}
else
{
DisengageGrapplingHook();
return;
}
}
}
else
{
GrapplingHook.Tightness -= NormalFrameTime*4;
if (GrapplingHook.Tightness<0) GrapplingHook.Tightness=0;
}
}
extern void DisengageGrapplingHook(void)
{
GrapplingHook.IsEngaged = 0;
GrapplingHook.IsEmbedded = 0;
if (GrapplingHook.DispPtr)
{
RemoveBehaviourStrategy(GrapplingHook.DispPtr->ObStrategyBlock);
GrapplingHook.DispPtr=NULL;
}
}
extern void HandleGrapplingHookForces(void)
{
if (GrapplingHook.IsEmbedded)
{
DYNAMICSBLOCK *dynPtr = Player->ObStrategyBlock->DynPtr;
VECTORCH direction = GrapplingHook.Position;
int distance;
direction.vx -= dynPtr->Position.vx;
direction.vy -= dynPtr->Position.vy-1000;
direction.vz -= dynPtr->Position.vz;
distance = Approximate3dMagnitude(&direction);
if (distance>4096+1024)
{
Normalise(&direction);
dynPtr->LinImpulse.vx += MUL_FIXED(direction.vx,NormalFrameTime);
dynPtr->LinImpulse.vy += MUL_FIXED(direction.vy,NormalFrameTime);
dynPtr->LinImpulse.vz += MUL_FIXED(direction.vz,NormalFrameTime);
}
else if (distance>1024)
{
int s = MUL_FIXED((distance-1024)*16,NormalFrameTime);
Normalise(&direction);
dynPtr->LinImpulse.vx += MUL_FIXED(direction.vx,s);
dynPtr->LinImpulse.vy += MUL_FIXED(direction.vy,s);
dynPtr->LinImpulse.vz += MUL_FIXED(direction.vz,s);
dynPtr->LinImpulse.vx -= MUL_FIXED(dynPtr->LinImpulse.vx,NormalFrameTime/2);
dynPtr->LinImpulse.vy -= MUL_FIXED(dynPtr->LinImpulse.vy,NormalFrameTime/2);
dynPtr->LinImpulse.vz -= MUL_FIXED(dynPtr->LinImpulse.vz,NormalFrameTime/2);
}
if (Approximate3dMagnitude(&dynPtr->LinImpulse)>ONE_FIXED)
{
Normalise(&dynPtr->LinImpulse);
}
}
}
extern void RenderGrapplingHook(void)
{
if (GrapplingHook.IsEngaged && GrapplingHook.DispPtr)
{
extern void D3D_DrawCable(VECTORCH *centrePtr, MATRIXCH *orientationPtr);
extern int CloakingPhase;
VECTORCH cable[46];
int i;
{
MATRIXCH mat = Global_VDB_Ptr->VDB_Mat;
TransposeMatrixCH(&mat);
cable[0].vx = Global_VDB_Ptr->VDB_World.vx-mat.mat31/128;
cable[0].vy = Global_VDB_Ptr->VDB_World.vy-mat.mat32/128+500;
cable[0].vz = Global_VDB_Ptr->VDB_World.vz-mat.mat33/128;
}
// cable[0].vx = Global_VDB_Ptr->VDB_World.vx;
// cable[0].vy = Global_VDB_Ptr->VDB_World.vy+500;
// cable[0].vz = Global_VDB_Ptr->VDB_World.vz;
for (i=1; i<46; i++)
{
cable[i].vx = ((45-i)*cable[0].vx + (i)*GrapplingHook.DispPtr->ObStrategyBlock->DynPtr->Position.vx)/45;
cable[i].vy = ((45-i)*cable[0].vy + (i)*GrapplingHook.DispPtr->ObStrategyBlock->DynPtr->Position.vy)/45;
cable[i].vz = ((45-i)*cable[0].vz + (i)*GrapplingHook.DispPtr->ObStrategyBlock->DynPtr->Position.vz)/45;
if (GrapplingHook.Tightness!=0)
{
int x = GetSin((302*i+CloakingPhase)&4095)/256;
int y = GetSin((502*i+200+CloakingPhase)&4095)/256;
int z = GetCos((302*i+100+CloakingPhase)&4095)/256;
int u = GetSin( ((4096*i)/45)&4095 );
u = MUL_FIXED(MUL_FIXED(u,u),GrapplingHook.Tightness);
cable[i].vx += MUL_FIXED(u,x);
cable[i].vy += MUL_FIXED(u,y);
cable[i].vz += MUL_FIXED(u,z);
}
}
{
MATRIXCH mat;
VECTORCH dir = cable[45];
dir.vx -= cable[0].vx;
dir.vy -= cable[0].vy;
dir.vz -= cable[0].vz;
Normalise(&dir);
MakeMatrixFromDirection(&dir,&mat);
D3D_DrawCable(cable, &mat);
}
#if 0
DISPLAYBLOCK displayblock;
displayblock.ObWorld=GrapplingHook.Position;
displayblock.ObMat=GrapplingHook.Orientation;
displayblock.ObShape=GrapplingHook.ShapeIndex;
displayblock.ObShapeData=GetShapeData(GrapplingHook.ShapeIndex);
displayblock.name=NULL;
displayblock.ObEuler.EulerX=0;
displayblock.ObEuler.EulerY=0;
displayblock.ObEuler.EulerZ=0;
displayblock.ObFlags=0;
displayblock.ObFlags2=0;
displayblock.ObFlags3=0;
displayblock.ObNumLights=0;
displayblock.ObRadius=0;
displayblock.ObMaxX=0;
displayblock.ObMinX=0;
displayblock.ObMaxY=0;
displayblock.ObMinY=0;
displayblock.ObMaxZ=0;
displayblock.ObMinZ=0;
displayblock.ObTxAnimCtrlBlks=NULL;
displayblock.ObEIDPtr=NULL;
displayblock.ObMorphCtrl=NULL;
displayblock.ObStrategyBlock=NULL;
displayblock.ShapeAnimControlBlock=NULL;
displayblock.HModelControlBlock=NULL;
displayblock.ObMyModule=NULL;
displayblock.SpecialFXFlags = 0;
displayblock.SfxPtr=0;
MakeVector(&displayblock.ObWorld, &Global_VDB_Ptr->VDB_World, &displayblock.ObView);
RotateVector(&displayblock.ObView, &Global_VDB_Ptr->VDB_Mat);
RenderThisDisplayblock(&displayblock);
{
PARTICLE particle;
particle.Colour = 0xffffffff;
particle.ParticleID = PARTICLE_LASERBEAM;
particle.Position = Player->ObStrategyBlock->DynPtr->Position;
particle.Position.vy-=1000;
particle.Offset = GrapplingHook.DispPtr->ObStrategyBlock->DynPtr->Position;
particle.Size = 20;
RenderParticle(&particle);
}
#endif
}
}
/*--------------------**
** Loading and Saving **
**--------------------*/
#include "savegame.h"
typedef struct grapple_save_block
{
SAVE_BLOCK_STRATEGY_HEADER header;
int IsEmbedded;
int IsEngaged;
int Tightness;
VECTORCH Position;
MATRIXCH Orientation;
//strategy block stuff
DYNAMICSBLOCK dynamics;
}GRAPPLE_SAVE_BLOCK;
//defines for load/save macros
#define SAVELOAD_BLOCK block
#define SAVELOAD_BEHAV (&GrapplingHook)
void LoadStrategy_Grapple(SAVE_BLOCK_STRATEGY_HEADER* header)
{
GRAPPLE_SAVE_BLOCK* block = (GRAPPLE_SAVE_BLOCK*) header;
//check the size of the save block
if(header->size!=sizeof(*block)) return;
//create the grappling hook
GrapplingHook.DispPtr = CreateGrapplingHook();
if(!GrapplingHook.DispPtr) return;
//copy suff from the save block
COPYELEMENT_LOAD(IsEmbedded)
COPYELEMENT_LOAD(IsEngaged)
COPYELEMENT_LOAD(Tightness)
COPYELEMENT_LOAD(Position)
COPYELEMENT_LOAD(Orientation)
*GrapplingHook.DispPtr->ObStrategyBlock->DynPtr = block->dynamics;
}
void SaveStrategy_Grapple(STRATEGYBLOCK* sbPtr)
{
GRAPPLE_SAVE_BLOCK* block;
GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
//copy stuff to the save block
COPYELEMENT_SAVE(IsEmbedded)
COPYELEMENT_SAVE(IsEngaged)
COPYELEMENT_SAVE(Tightness)
COPYELEMENT_SAVE(Position)
COPYELEMENT_SAVE(Orientation)
block->dynamics = *sbPtr->DynPtr;
block->dynamics.CollisionReportPtr=0;
}

8
3dc/avp/BonusAbilities.h Normal file
View file

@ -0,0 +1,8 @@
/* KJL 12:09:35 10/09/98 - BonusAbilities.h */
/* KJL 12:09:43 10/09/98 - Grappling Hook */
extern void InitialiseGrapplingHook(void);
extern void ActivateGrapplingHook(void);
extern void HandleGrapplingHookForces(void);
extern void RenderGrapplingHook(void);
extern void DisengageGrapplingHook(void);

View file

@ -0,0 +1,225 @@
extern "C"
{
#include "3dc.h"
#include "ourasert.h"
#include "psndplat.h"
#include "dxlog.h"
#include "CD_player.h"
#include "avp_menus.h"
#include "gamedef.h"
#include "AvP_EnvInfo.h"
#include "dxlog.h"
};
#include "list_tem.hpp"
//lists of tracks for each level
List<int> LevelCDTracks[AVP_ENVIRONMENT_END_OF_LIST];
//lists of tracks for each species in multiplayer games
List<int> MultiplayerCDTracks[3];
static int LastTrackChosen=-1;
extern "C"
{
void EmptyCDTrackList()
{
for(int i=0;i<AVP_ENVIRONMENT_END_OF_LIST;i++)
{
while(LevelCDTracks[i].size()) LevelCDTracks[i].delete_first_entry();
}
for(i=0;i<3;i++)
{
while(MultiplayerCDTracks[i].size()) MultiplayerCDTracks[i].delete_first_entry();
}
}
#define CDTrackFileName "CD Tracks.txt"
static void ExtractTracksForLevel(char* & buffer,List<int> & track_list)
{
//search for a line starting with a #
while(*buffer)
{
if(*buffer=='#') break;
//search for next line
while(*buffer)
{
if(*buffer=='\n')
{
buffer++;
if(*buffer=='\r') buffer++;
break;
}
buffer++;
}
}
while(*buffer)
{
//search for a track number or comment
if(*buffer==';')
{
//comment , so no further info on this line
break;
}
else if(*buffer=='\n' || *buffer=='\r')
{
//reached end of line
break;
}
else if(*buffer>='0' && *buffer<='9')
{
int track=-1;
//find a number , add it to the list
sscanf(buffer,"%d",&track);
if(track>=0)
{
track_list.add_entry(track);
}
//skip to the next non numerical character
while(*buffer>='0' && *buffer<='9') buffer++;
}
else
{
*buffer++;
}
}
//go to the next line
while(*buffer)
{
if(*buffer=='\n')
{
buffer++;
if(*buffer=='\r') buffer++;
break;
}
buffer++;
}
}
void LoadCDTrackList()
{
//clear out the old list first
EmptyCDTrackList();
HANDLE file=CreateFile(CDTrackFileName,GENERIC_READ, 0, 0, OPEN_EXISTING,FILE_FLAG_RANDOM_ACCESS, 0);
if(file==INVALID_HANDLE_VALUE)
{
LOGDXFMT(("Failed to open %s",CDTrackFileName));
return;
}
char* buffer;
int file_size;
unsigned long bytes_read;
//copy the file contents into a buffer
file_size= GetFileSize(file,0);
buffer=new char[file_size+1];
ReadFile(file,buffer,file_size,&bytes_read,0);
CloseHandle(file);
char* bufferptr=buffer;
//first extract the multiplayer tracks
for(int i=0;i<3;i++)
{
ExtractTracksForLevel(bufferptr,MultiplayerCDTracks[i]);
}
//now the level tracks
for(i=0 ;i<AVP_ENVIRONMENT_END_OF_LIST;i++)
{
ExtractTracksForLevel(bufferptr,LevelCDTracks[i]);
}
delete [] buffer;
}
static unsigned int TrackSelectCounter=0;
static BOOL PickCDTrack(List<int>& track_list)
{
//make sure we have some tracks in the list
if(!track_list.size()) return FALSE;
//pick the next track in the list
unsigned int index=TrackSelectCounter % track_list.size();
TrackSelectCounter++;
//play it
CDDA_Stop();
CDDA_Play(track_list[index]);
LastTrackChosen = track_list[index];
return TRUE;
}
void CheckCDAndChooseTrackIfNeeded()
{
static enum playertypes lastPlayerType;
//are we bothering with cd tracks
if(!CDDA_IsOn()) return;
//is our current track still playing
if(CDDA_IsPlaying())
{
//if in a multiplayer game see if we have changed character type
if(AvP.Network == I_No_Network || AvP.PlayerType==lastPlayerType)
return;
//have changed character type , is the current track in the list for this character type
if(MultiplayerCDTracks[AvP.PlayerType].contains(LastTrackChosen))
return;
//Lets choose a new track then
}
if(AvP.Network == I_No_Network)
{
int level=NumberForCurrentLevel();
if(level>=0 && level<AVP_ENVIRONMENT_END_OF_LIST)
{
//pick track based on level
if(PickCDTrack(LevelCDTracks[level]))
{
return;
}
}
}
//multiplayer (or their weren't ant level specific tracks)
lastPlayerType=AvP.PlayerType;
PickCDTrack(MultiplayerCDTracks[AvP.PlayerType]);
}
void ResetCDPlayForLevel()
{
//check the number of tracks available while we're at it
CDDA_CheckNumberOfTracks();
TrackSelectCounter=0;
CDDA_Stop();
}
};

View file

@ -0,0 +1,3 @@
extern void LoadCDTrackList();
extern void CheckCDAndChooseTrackIfNeeded();
extern void ResetCDPlayForLevel();

181
3dc/avp/COMP_SHP.C Normal file
View file

@ -0,0 +1,181 @@
#include "3dc.h"
#include "module.h"
#include "stratdef.h"
#include "gamedef.h"
#include "comp_shp.h"
#include "mslhand.h"
#define UseLocalAssert Yes
#include "ourasert.h"
/*
There is a small problem in the destiction between
compiled in shapes and binary loaded ones. I am
changing chnkmaps.c maps.c and shapes.c into comp_shp.c
comp_shp.h, comp_map.c and comp_map.h.
We need to generate data for the game by
1. Setting up the initial Environment
2. Placing the player in the environment
3. Generateing Activer blocks at runtime.
To deal with these problems we can now do the following
1 Binary Load Shapes. Link these to MAPs and SBs
2 Have functions to modify a mapblock that describes
the player depending on how he entered a level
3 Have a list of shapes that is either Compiled in
or loaded at game init to represent the shapes that
can be generated at run time. Have a set of functions
to gnertae MAPBLOCKS for the above.
this is the compiled in shape list for AVP. For the
Saturn and the Playstation, these shapes may end up
being loaded during game init, (not level init) to
reduce the overall memory load
compiled in shapes are descriptons and strategies of
shapes AND functions to spawn mapblocks and attach
strategy blocks
To generate stuff we have a list of compiled in shapes
that are appended to the start of the mainshapelist.
We then have functions that cen generate the maps and
strategyblocks for each. Texture maps for the shapes
are read in at level init along with the rest of the
texture maps for each env.
procedure:
Generate map block using reference into
*/
#define NUM_MAR_SHAPES 14
int maxshapes=0;
SHAPEHEADER ** mainshapelist=0;
/* compiled in shapes that do not exist as yet*/
#if 0
SHAPEHEADER PULSE_header; /*Marine Weapons*/
SHAPEHEADER AASHOTGUN_header;
SHAPEHEADER CANNISTERGUN_header;
SHAPEHEADER FTHROWER_header;
SHAPEHEADER SMARTGUN_header;
SHAPEHEADER PIG_header;
SHAPEHEADER LATW_header;
SHAPEHEADER PARTICLE_header;
SHAPEHEADER ROCKET_header;
SHAPEHEADER* MarineCompiledShapes[] = {
&BOB_header,
&BOB_header,
&BOB_header, /*MarinePlayer*/
&BOB_header, /*PredatorPlayer*/
&BOB_header, /*AlienPlayer*/
&BOB_header, /* was &ALIEN_header, but the textures are no longer there. The old alien should be fully purged. << keywords: BUG FIXME OPTIMIZEME OPTIMISEME ERROR MISTAKE HACK >> */
&BOB_header,
&BOB_header,
&BOB_header,
&BOBCROUCH_header, /* player crouch shape */
&BOBLIE_header, /* player lying down shape */
&BOB_header, /* Flamethrower shot - frame 1 */
&BOB_header, /* Flamethrower shot - frame 2 */
&BOB_header,
&BOB_header, /*Marine Weapons*/
&AASHOTGUN_header,
&CANNISTERGUN_header,
&FTHROWER_header,
&SMARTGUN_header,
&PIG_header,
&LATW_header,
&PARTICLE_header,
&ROCKET_header,
&BOB_header, /* alien generator */
};
#else
// changed by John to get rid of all compiled in shapes
SHAPEHEADER* MarineCompiledShapes[] = {
&CUBE_header,
&CUBE_header,
&CUBE_header, /*MarinePlayer*/
&CUBE_header, /*PredatorPlayer*/
&CUBE_header, /*AlienPlayer*/
&CUBE_header, /* was &ALIEN_header, but the textures are no longer there. The old alien should be fully purged. << keywords: BUG FIXME OPTIMIZEME OPTIMISEME ERROR MISTAKE HACK >> */
&CUBE_header,
&CUBE_header,
&CUBE_header,
&CUBE_header, /* player crouch shape */
&CUBE_header, /* player lying down shape */
&CUBE_header,
&CUBE_header,
&CUBE_header,
&CUBE_header,
&CUBE_header,
&CUBE_header,
&CUBE_header,
&CUBE_header,
&CUBE_header,
&CUBE_header,
&CUBE_header,
&CUBE_header, /* alien generator */
};
#endif
#define STARTOF_PRECOMPILEDSHAPES 0
int load_precompiled_shapes(void)
{
static int done = 0;
int i,j = 0;
if(!mainshapelist)
{
maxshapes=750;
/*I'm not using AllocateMem because I'll have to realloc this later*/
mainshapelist=(SHAPEHEADER**)malloc(sizeof(SHAPEHEADER*)*maxshapes);
LOCALASSERT(mainshapelist);
if(!mainshapelist)
{
ReleaseDirect3D();
exit(0x74363);
}
for(i=0;i<maxshapes;i++)
{
mainshapelist[i]=0;
}
}
i=STARTOF_PRECOMPILEDSHAPES;
if (done) return i+NUM_MAR_SHAPES;
/* KJL 11:43:36 09/24/96 - load some marine stuff hacked in 'cos the old way was even worse */
while(j < NUM_MAR_SHAPES)
{
mainshapelist[i] = MarineCompiledShapes[j];
i++;
j++;
}
done = 1;
return i;
}

49
3dc/avp/COMP_SHP.H Normal file
View file

@ -0,0 +1,49 @@
extern SHAPEHEADER** mainshapelist;
extern int start_of_loaded_shapes;
extern SHAPEHEADER CUBE_header;
extern SHAPEHEADER PRISM_header;
extern SHAPEHEADER BOB_header;
extern SHAPEHEADER ALIEN_header;
extern SHAPEHEADER BLOODSPLASH_header;
extern SHAPEHEADER BULLETRICOCHET_header;
extern SHAPEHEADER EXPLOSION_header;
extern SHAPEHEADER BOBCROUCH_header;
extern SHAPEHEADER BOBLIE_header;
extern SHAPEHEADER FLAME1_header;
extern SHAPEHEADER FLAME2_header;
extern SHAPEHEADER LGRENADE_header;
typedef enum marineshapesenum
{
I_ShapeCube,
I_ShapePrism,
I_ShapeMarinePlayer,
I_ShapePredatorPlayer,
I_ShapeAlienPlayer,
I_ShapeAlien,
I_ShapeBloodSplash,
I_ShapeBulletRicochet,
I_ShapeExplosion,
I_ShapeMarinePlayerCrouch,
I_ShapeMarinePlayerLieDown,
I_ShapeFlame1,
I_ShapeFlame2,
I_ShapeLGrenade,
I_ShapePulseRifle,
I_ShapeAAShotgun,
I_ShapeCanisterGun,
I_ShapeFThrower,
I_ShapeSmartGun,
I_ShapePig,
I_ShapeLATW,
I_ShapeParticle,
I_ShapeRocket,
I_ShapeGenerator,
} MARINE_SHAPES_ENUM;
extern int load_precompiled_shapes(void);

1143
3dc/avp/CheatModes.c Normal file

File diff suppressed because it is too large Load diff

100
3dc/avp/ConsoleLog.cpp Normal file
View file

@ -0,0 +1,100 @@
/* KJL 10:19:41 30/03/98 - ConsoleLog.cpp
This file handles the mirroring of the console text
to a log file.
*/
#include <stdlib.h>
#include <string.h>
#include "3dc.h"
#include "module.h"
#include "inline.h"
#include "stratdef.h"
#include "gamedef.h"
#include "gameplat.h"
#include "debuglog.hpp"
#include "ConsoleLog.hpp"
#include "bh_types.h"
#include "inventry.h"
#include "bh_alien.h"
#include "bh_pred.h"
#include "bh_xeno.h"
#include "bh_paq.h"
#include "bh_queen.h"
#include "bh_fhug.h"
#include "bh_marin.h"
#include "bh_debri.h"
#include "bh_weap.h"
#include "bh_agun.h"
#include "weapons.h"
LogFile ConsoleLogFile("ConsoleLog.txt");
extern "C"
{
int LogConsoleTextToFile;
extern void OutputBugReportToConsoleLogfile(char *messagePtr)
{
extern MODULE *playerPherModule;
extern struct Target PlayersTarget;
ConsoleLogFile.lprintf("\n*** AvP Automated Bug Report ****\n\n");
ConsoleLogFile.lprintf("Comment: %s\n\n", (char const*)messagePtr);
ConsoleLogFile.lprintf("Environment: %s\n", (char const*)Env_List[AvP.CurrentEnv]->main );
ConsoleLogFile.lprintf("Game type: ");
if (AvP.Network != I_No_Network)
{
ConsoleLogFile.lprintf("Multiplayer\n");
}
else
{
ConsoleLogFile.lprintf("Single player\n");
}
ConsoleLogFile.lprintf("Player's Species: ");
switch(AvP.PlayerType)
{
case I_Marine:
ConsoleLogFile.lprintf("Marine\n");
break;
case I_Alien:
ConsoleLogFile.lprintf("Alien\n");
break;
case I_Predator:
ConsoleLogFile.lprintf("Predator\n");
break;
}
ConsoleLogFile.lprintf("\nPlayer's Coords: %d,%d,%d\n",Player->ObWorld.vx,Player->ObWorld.vy,Player->ObWorld.vz);
ConsoleLogFile.lprintf("Player's Module: %d '%s'\n", playerPherModule->m_index,playerPherModule->name);
ConsoleLogFile.lprintf("Player's Module Coords: %d %d %d\n",playerPherModule->m_world.vx,playerPherModule->m_world.vy,playerPherModule->m_world.vz);
ConsoleLogFile.lprintf("Player's Target: %d %d %d\n",PlayersTarget.Position.vx,PlayersTarget.Position.vy,PlayersTarget.Position.vz);
ConsoleLogFile.lprintf("\n");
}
};
extern void OutputToConsoleLogfile(char *messagePtr)
{
if(LogConsoleTextToFile)
{
ConsoleLogFile.lprintf("%s\n", (char const*)messagePtr);
}
}

23
3dc/avp/ConsoleLog.hpp Normal file
View file

@ -0,0 +1,23 @@
/* KJL 10:19:41 30/03/98 - ConsoleLog.hpp
This file handles the mirroring of the console text
to a log file.
*/
#ifndef ConsoleLog_h_included
#define ConsoleLog_h_included
extern void OutputToConsoleLogfile(char *messagePtr);
#ifdef __cplusplus
extern "C"
{
#endif
extern void OutputBugReportToConsoleLogfile(char *messagePtr);
#ifdef __cplusplus
};
#endif
#endif

602
3dc/avp/DATABASE.C Normal file
View file

@ -0,0 +1,602 @@
#include "3dc.h"
#include "module.h"
#include "stratdef.h"
#include "gamedef.h"
#include "equipmnt.h"
#include "saveload.h"
#include "font.h"
#include "database.h"
#include "svldplat.h"
#define UseLocalAssert Yes
#include "ourasert.h"
// extern old movement functions
extern int IDemandGoForward();
extern int IDemandSelect();
extern int IDemandGoBackward();
extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
extern void LoadDatabaseMessage(void);
extern void UnloadDatabaseMessage(void);
extern void WriteDatabaseMessage(void);
unsigned char *GetTextForMenuOption(enum DB_MENUOPTION_ID optionID);
#if 0
struct MenuOptionDescriptor MenuOptionData[MAX_NO_OF_DB_MENUOPTIONS] =
{
{145,40,FJ_CENTRED}, /* DB_MENUOPTION_RESUME*/
{145,60,FJ_CENTRED}, /* DB_MENUOPTION_OPTIONS*/
{145,80,FJ_CENTRED}, /*DB_MENUOPTION_MISSION*/
{145,100,FJ_CENTRED},/* DB_MENUOPTION_LOAD, */
{145,120,FJ_CENTRED},/* DB_MENUOPTION_SAVE, */
{145,140,FJ_CENTRED},/* DB_MENUOPTION_QUIT, */
{145,80,FJ_CENTRED}, /*DB_MENUOPTION_YESQUIT*/
{145,100,FJ_CENTRED},/*DB_MENUOPTION_NO*/
{237,150,FJ_CENTRED},/* DB_MENUOPTION_GOBACK, */
{125,90,FJ_CENTRED},/* DB_MENUOPTION_ACCESSDENIED */
{30,30,FJ_LEFT_JUST},/*SLOT0*/
{30,45,FJ_LEFT_JUST},/*SLOT1*/
{30,60,FJ_LEFT_JUST},/*SLOT2*/
{30,75,FJ_LEFT_JUST},/*SLOT3*/
{30,90,FJ_LEFT_JUST},/*SLOT4*/
{30,105,FJ_LEFT_JUST},/*SLOT5*/
{30,120,FJ_LEFT_JUST},/*SLOT6*/
{30,135,FJ_LEFT_JUST},/*SLOT7*/
};
#else
struct MenuOptionDescriptor MenuOptionData[MAX_NO_OF_DB_MENUOPTIONS] =
{
{0,(ONE_FIXED*4)/32,FJ_CENTRED}, /* DB_MENUOPTION_RESUME*/
{0,(ONE_FIXED*7)/32,FJ_CENTRED}, /* DB_MENUOPTION_OPTIONS*/
{0,(ONE_FIXED*10)/32,FJ_CENTRED}, /* DB_MENUOPTION_MISSION*/
{0,(ONE_FIXED*13)/32,FJ_CENTRED}, /* DB_MENUOPTION_LOAD, */
{0,(ONE_FIXED*16)/32,FJ_CENTRED}, /* DB_MENUOPTION_SAVE, */
{0,(ONE_FIXED*19)/32,FJ_CENTRED}, /* DB_MENUOPTION_QUIT, */
{0,(ONE_FIXED*10)/32,FJ_CENTRED}, /* DB_MENUOPTION_YESQUIT*/
{0,(ONE_FIXED*13)/32,FJ_CENTRED}, /* DB_MENUOPTION_NO*/
{0,(ONE_FIXED*16)/32,FJ_CENTRED}, /* DB_MENUOPTION_STARTMENU*/
{0,(ONE_FIXED*29)/32,FJ_CENTRED}, /* DB_MENUOPTION_GOBACK, */
{0,(ONE_FIXED*16)/32,FJ_CENTRED}, /* DB_MENUOPTION_ACCESSDENIED */
{(ONE_FIXED*1)/32,(ONE_FIXED*4)/32,FJ_LEFT_JUST}, /*SLOT0*/
{(ONE_FIXED*1)/32,(ONE_FIXED*7)/32,FJ_LEFT_JUST}, /*SLOT1*/
{(ONE_FIXED*1)/32,(ONE_FIXED*10)/32,FJ_LEFT_JUST}, /*SLOT2*/
{(ONE_FIXED*1)/32,(ONE_FIXED*13)/32,FJ_LEFT_JUST}, /*SLOT3*/
{(ONE_FIXED*1)/32,(ONE_FIXED*16)/32,FJ_LEFT_JUST}, /*SLOT4*/
{(ONE_FIXED*1)/32,(ONE_FIXED*19)/32,FJ_LEFT_JUST}, /*SLOT5*/
{(ONE_FIXED*1)/32,(ONE_FIXED*22)/32,FJ_LEFT_JUST}, /*SLOT6*/
{(ONE_FIXED*1)/32,(ONE_FIXED*25)/32,FJ_LEFT_JUST}, /*SLOT7*/
};
#endif
/* KJL 13:09:25 03/17/97 - to be rewritten after alpha */
unsigned char *TestMenuOptionText[] =
{
"RESUME",
"OPTIONS",
"MISSION",
"LOAD",
"SAVE",
"QUIT",
"QUIT TO WINDOWS",
"RESUME",
"QUIT TO START MENU",
"BACK",
"ACCESS DENIED",
"1:",
"2:",
"3:",
"4:",
"5:",
"6:",
"7:",
"8:",
};
static int NumberOfCurrentDbOptions;
static enum DB_MENUOPTION_ID CurrentDbOptions[MAX_NO_OF_DB_MENUOPTIONS];
static struct DatabaseInput DatabaseInput={0,0,0};
static enum DB_STATE_ID CurrentState;
static int DBStateHasChanged;
void SetupDatabaseState(enum DB_STATE_ID stateID);
void ClearMenuOptions(void);
void AddMenuOption(enum DB_MENUOPTION_ID optionID);
void ActUponChosenOption(enum DB_MENUOPTION_ID optionID);
enum DB_MENUOPTION_ID DisplayCurrentDatabaseState(enum DB_STATE_ID stateID);
void LoadGraphicsForDatabaseState(enum DB_STATE_ID stateID);
void UnloadGraphicsForDatabaseState(enum DB_STATE_ID stateID);
void DrawSpecialGraphicsForState(enum DB_STATE_ID stateID);
/* fns that should be platform specific but aren't yet */
void GetDatabaseInput(void);
void DrawDatabaseMenuOption(enum DB_MENUOPTION_ID optionID, int highlighted);
void DrawDatabaseTextString(unsigned char *textPtr, int x, int y, FONT_JUST justification, int highlighted);
unsigned char *GetTextForMenuOption(enum DB_MENUOPTION_ID optionID);
void AccessDatabase(int databaseID)
{
CurrentState = DB_STATE_MAINMENU;
PlatformSpecificEnteringDatabase();
/* database main loop */
while(CurrentState != DB_STATE_RESUME)
{
enum DB_MENUOPTION_ID chosenOption;
/* load gfx and setup menu options for current state */
SetupDatabaseState(CurrentState);
/* display state and let user select option */
chosenOption = DisplayCurrentDatabaseState(CurrentState);
/* kill gfx for current state */
UnloadGraphicsForDatabaseState(CurrentState);
/* act upon chosen option, which usually changes state */
ActUponChosenOption(chosenOption);
}
PlatformSpecificExitingDatabase();
}
void SetupDatabaseState(enum DB_STATE_ID stateID)
{
LoadGraphicsForDatabaseState(stateID);
ClearMenuOptions();
switch (stateID)
{
case DB_STATE_MAINMENU:
{
AddMenuOption(DB_MENUOPTION_RESUME);
AddMenuOption(DB_MENUOPTION_OPTIONS);
AddMenuOption(DB_MENUOPTION_MISSION);
AddMenuOption(DB_MENUOPTION_LOAD);
AddMenuOption(DB_MENUOPTION_SAVE);
AddMenuOption(DB_MENUOPTION_QUIT);
break;
}
case DB_STATE_OPTIONS:
{
AddMenuOption(DB_MENUOPTION_GOBACK);
break;
}
case DB_STATE_QUIT:
{
AddMenuOption(DB_MENUOPTION_MAINMENU);
AddMenuOption(DB_MENUOPTION_YESQUIT);
AddMenuOption(DB_MENUOPTION_NO);
break;
}
case DB_STATE_MISSION:
{
AddMenuOption(DB_MENUOPTION_GOBACK);
break;
}
case DB_STATE_LOAD:
{
AddMenuOption(DB_MENUOPTION_SAVESLOT0);
AddMenuOption(DB_MENUOPTION_SAVESLOT1);
AddMenuOption(DB_MENUOPTION_SAVESLOT2);
AddMenuOption(DB_MENUOPTION_SAVESLOT3);
AddMenuOption(DB_MENUOPTION_SAVESLOT4);
AddMenuOption(DB_MENUOPTION_SAVESLOT5);
AddMenuOption(DB_MENUOPTION_SAVESLOT6);
AddMenuOption(DB_MENUOPTION_SAVESLOT7);
AddMenuOption(DB_MENUOPTION_GOBACK);
break;
}
case DB_STATE_SAVE:
{
AddMenuOption(DB_MENUOPTION_SAVESLOT0);
AddMenuOption(DB_MENUOPTION_SAVESLOT1);
AddMenuOption(DB_MENUOPTION_SAVESLOT2);
AddMenuOption(DB_MENUOPTION_SAVESLOT3);
AddMenuOption(DB_MENUOPTION_SAVESLOT4);
AddMenuOption(DB_MENUOPTION_SAVESLOT5);
AddMenuOption(DB_MENUOPTION_SAVESLOT6);
AddMenuOption(DB_MENUOPTION_SAVESLOT7);
AddMenuOption(DB_MENUOPTION_GOBACK);
break;
}
case DB_STATE_ACCESSDENIED:
{
AddMenuOption(DB_MENUOPTION_ACCESSDENIED);
break;
}
default:
{
/* not a valid state, assert */
LOCALASSERT(0);
break;
}
}
}
void ClearMenuOptions(void)
{
NumberOfCurrentDbOptions=0;
}
void AddMenuOption(enum DB_MENUOPTION_ID optionID)
{
CurrentDbOptions[NumberOfCurrentDbOptions] = optionID;
NumberOfCurrentDbOptions++;
}
void ActUponChosenOption(enum DB_MENUOPTION_ID optionID)
{
switch (optionID)
{
case DB_MENUOPTION_RESUME:
{
CurrentState = DB_STATE_RESUME;
DBStateHasChanged = 1;
break;
}
case DB_MENUOPTION_OPTIONS:
{
CurrentState = DB_STATE_ACCESSDENIED;
DBStateHasChanged = 1;
break;
}
case DB_MENUOPTION_MISSION:
{
CurrentState = DB_STATE_MISSION;
DBStateHasChanged = 1;
break;
}
case DB_MENUOPTION_LOAD:
{
CurrentState = DB_STATE_LOAD;
// LoadGameFromFile();
break;
}
case DB_MENUOPTION_SAVE:
{
CurrentState = DB_STATE_SAVE;
// SaveGameToFile();
break;
}
case DB_MENUOPTION_NO:
case DB_MENUOPTION_GOBACK:
case DB_MENUOPTION_ACCESSDENIED:
{
/* return to main menu */
CurrentState = DB_STATE_MAINMENU;
DBStateHasChanged = 1;
break;
}
case DB_MENUOPTION_SAVESLOT0:
case DB_MENUOPTION_SAVESLOT1:
case DB_MENUOPTION_SAVESLOT2:
case DB_MENUOPTION_SAVESLOT3:
case DB_MENUOPTION_SAVESLOT4:
case DB_MENUOPTION_SAVESLOT5:
case DB_MENUOPTION_SAVESLOT6:
case DB_MENUOPTION_SAVESLOT7:
{
if(DB_STATE_LOAD == CurrentState)
{
LoadSaveSlot(optionID - DB_MENUOPTION_SAVESLOT0);
}
if(DB_STATE_SAVE == CurrentState)
{
SaveSaveSlot(optionID - DB_MENUOPTION_SAVESLOT0);
}
CurrentState = DB_STATE_RESUME;
break;
}
case DB_MENUOPTION_QUIT:
{
CurrentState = DB_STATE_QUIT;
DBStateHasChanged = 1;
break;
}
case DB_MENUOPTION_YESQUIT:
{
ExitSystem();
exit(0);
}
case DB_MENUOPTION_MAINMENU:
{
AvP.MainLoopRunning = 0;
CurrentState = DB_STATE_RESUME;
break;
}
default:
{
/* invalid option */
LOCALASSERT(0);
break;
}
}
}
static int selectedOption;
enum DB_MENUOPTION_ID DisplayCurrentDatabaseState(enum DB_STATE_ID stateID)
{
int selectionNotMade = 1;
selectedOption = 0;
LOCALASSERT(NumberOfCurrentDbOptions != 0);
do
{
// JCWH 18/02/98: allow ALT+TAB
CheckForWindowsMessages();
/* draw background */
DrawDatabaseBackground();
/* draw weapons, maps etc. as required */
DrawSpecialGraphicsForState(stateID);
/* draw all menu options */
{
int o;
for (o=0; o<NumberOfCurrentDbOptions; o++)
{
if (o == selectedOption)
DrawDatabaseMenuOption(CurrentDbOptions[o],1);
else
DrawDatabaseMenuOption(CurrentDbOptions[o],0);
}
}
/* update screen */
UpdateDatabaseScreen();
/* allow user to select an option */
GetDatabaseInput();
if (DatabaseInput.RequestSelectItem)
{
selectionNotMade=0;
}
else if (DatabaseInput.RequestPreviousItem)
{
if (selectedOption == 0)
{
selectedOption = NumberOfCurrentDbOptions;
}
selectedOption--;
}
else if (DatabaseInput.RequestNextItem)
{
selectedOption++;
if (selectedOption == NumberOfCurrentDbOptions)
{
selectedOption = 0;
}
}
}
while(selectionNotMade);
return(CurrentDbOptions[selectedOption]);
}
void LoadGraphicsForDatabaseState(enum DB_STATE_ID stateID)
{
switch (stateID)
{
case DB_STATE_MISSION:
{
LoadDatabaseMessage();
break;
}
default:
break;
}
}
void UnloadGraphicsForDatabaseState(enum DB_STATE_ID stateID)
{
switch (stateID)
{
case DB_STATE_MISSION:
{
UnloadDatabaseMessage();
break;
}
default:
break;
}
}
void DrawSpecialGraphicsForState(enum DB_STATE_ID stateID)
{
if(stateID == DB_STATE_MISSION)
{
WriteDatabaseMessage();
}
if((stateID == DB_STATE_LOAD) || (stateID == DB_STATE_SAVE))
{
char game_name[GAME_NAME_LENGTH];
int i = GAME_NAME_LENGTH, j;
while(i-- > 0)
{
*(game_name + i) = 0;
}
i = NUM_SAVE_SLOTS;
while(i-- >0)
{
FONT_DESC packet;
int posx, posy;
AVP_FONTS font_num = DATABASE_FONT_DARK;
j = GAME_NAME_LENGTH;
while(j-- > 0)
{
*(game_name + j) = 0;
}
ReadSaveSlotGameName(i, game_name);
posx = ((MenuOptionData[i + DB_MENUOPTION_SAVESLOT0].X*ScreenDescriptorBlock.SDB_Width) >> 16) + 20;
posy = ((MenuOptionData[i + DB_MENUOPTION_SAVESLOT0].Y*ScreenDescriptorBlock.SDB_Height) >> 16);
if(selectedOption == i)
{
font_num = DATABASE_FONT_LITE;
}
packet.fontnum = font_num;
packet.string = game_name;
packet.destx = posx;
packet.desty = posy;
packet.just = FJ_LEFT_JUST;
packet.width = ScreenDescriptorBlock.SDB_Width;
BLTString(packet);
}
}
}
/* platform specific fns */
static int debounced = 0;
void GetDatabaseInput(void)
{
ReadUserInput();
DatabaseInput.RequestSelectItem = 0;
DatabaseInput.RequestPreviousItem = 0;
DatabaseInput.RequestNextItem = 0;
if (IDemandSelect())
{
if (debounced)
{
DatabaseInput.RequestSelectItem =1;
debounced = 0;
}
}
else if (IDemandGoBackward())
{
if (debounced)
{
DatabaseInput.RequestNextItem =1;
debounced = 0;
}
}
else if (IDemandGoForward())
{
if (debounced)
{
DatabaseInput.RequestPreviousItem =1;
debounced = 0;
}
}
else
{
debounced=1;
}
}
void DrawDatabaseMenuOption(enum DB_MENUOPTION_ID optionID, int highlighted)
{
unsigned char *textPtr = GetTextForMenuOption(optionID);
DrawDatabaseTextString
(
textPtr,
MenuOptionData[optionID].X,
MenuOptionData[optionID].Y,
MenuOptionData[optionID].justification,
highlighted
);
}
void DrawDatabaseTextString
(
unsigned char *textPtr,
int x,
int y,
FONT_JUST justification,
int highlighted)
{
FONT_DESC packet;
if (highlighted) packet.fontnum = DATABASE_FONT_LITE;
else packet.fontnum = DATABASE_FONT_DARK;
packet.string = textPtr;
packet.destx = (x*ScreenDescriptorBlock.SDB_Width) >>16;
packet.desty = (y*ScreenDescriptorBlock.SDB_Height) >>16;
packet.just = justification;
packet.width = ScreenDescriptorBlock.SDB_Width;
BLTString(packet);
}
unsigned char *GetTextForMenuOption(enum DB_MENUOPTION_ID optionID)
{
return TestMenuOptionText[optionID];
}
int DatabaseStateChange()
{
if(DBStateHasChanged)
{
DBStateHasChanged = 0;
return 1;
}
return 0;
}

72
3dc/avp/DATABASE.H Normal file
View file

@ -0,0 +1,72 @@
#define NUM_SAVE_SLOTS 10
enum DB_STATE_ID
{
DB_STATE_MAINMENU,
DB_STATE_QUIT,
DB_STATE_OPTIONS,
DB_STATE_MISSION,
DB_STATE_LOAD,
DB_STATE_SAVE,
DB_STATE_RESUME,
DB_STATE_ACCESSDENIED,
MAX_NO_OF_DB_STATES
};
enum DB_MENUOPTION_ID
{
DB_MENUOPTION_RESUME,
DB_MENUOPTION_OPTIONS,
DB_MENUOPTION_MISSION,
DB_MENUOPTION_LOAD,
DB_MENUOPTION_SAVE,
DB_MENUOPTION_QUIT,
DB_MENUOPTION_YESQUIT,
DB_MENUOPTION_NO,
DB_MENUOPTION_MAINMENU,
DB_MENUOPTION_GOBACK,
DB_MENUOPTION_ACCESSDENIED,
DB_MENUOPTION_SAVESLOT0,
DB_MENUOPTION_SAVESLOT1,
DB_MENUOPTION_SAVESLOT2,
DB_MENUOPTION_SAVESLOT3,
DB_MENUOPTION_SAVESLOT4,
DB_MENUOPTION_SAVESLOT5,
DB_MENUOPTION_SAVESLOT6,
DB_MENUOPTION_SAVESLOT7,
MAX_NO_OF_DB_MENUOPTIONS
};
struct DatabaseInput
{
unsigned char RequestSelectItem :1;
unsigned char RequestPreviousItem :1;
unsigned char RequestNextItem :1;
};
struct MenuOptionDescriptor
{
/* top-left coords */
int X;
int Y;
FONT_JUST justification;
};
extern void AccessDatabase(int databaseID);
/* KJL 15:43:16 04/11/97 - platform specific */
extern void PlatformSpecificEnteringDatabase(void);
extern void PlatformSpecificExitingDatabase(void);
extern void DrawDatabaseBackground(void);
extern void UpdateDatabaseScreen(void);
extern int DatabaseStateChange();

57
3dc/avp/DYNAMICS.H Normal file
View file

@ -0,0 +1,57 @@
#ifndef _dynamics_h_ /* KJL 17:23:01 11/05/96 - is this your first time? */
#define _dynamics_h_ 1
#include "particle.h"
/*KJL************************************************************************
* DYNAMICS.H *
* - this file contains prototypes for the functions in dynamics.c *
* which can be called externally. *
************************************************************************KJL*/
/*KJL****************************************************************************************
* S T R U C T U R E S *
****************************************************************************************KJL*/
struct ColPolyTag
{
int NumberOfVertices;
VECTORCH PolyPoint[4];
VECTORCH PolyNormal;
DISPLAYBLOCK *ParentObject;
};
/*KJL****************************************************************************************
* P H Y S I C A L C O N S T A N T S *
****************************************************************************************KJL*/
#define GRAVITY_STRENGTH 25000
#define TIME_BEFORE_GRAVITY_KICKS_IN 16384
#define MAXIMUM_STEP_HEIGHT 450
#define MAX_ANG_VELOCITY 8192
#define MAX_MOVES 4
//16384
/*KJL****************************************************************************************
* P R O T O T Y P E S *
****************************************************************************************KJL*/
extern void ObjectDynamics(void);
extern void DynamicallyRotateObject(DYNAMICSBLOCK *dynPtr);
/* externs to shape access fns (platform specific) */
extern int SetupPolygonAccess(DISPLAYBLOCK *objectPtr);
extern void AccessNextPolygon(void);
extern void GetPolygonVertices(struct ColPolyTag *polyPtr);
extern void GetPolygonNormal(struct ColPolyTag *polyPtr);
/* extra camera movement */
extern EULER HeadOrientation;
extern int ParticleDynamics(PARTICLE *particlePtr, VECTORCH *obstacleNormalPtr, int *moduleIndexPtr);
#endif /* end of preprocessor condition for file wrapping */

801
3dc/avp/DYNBLOCK.C Normal file
View file

@ -0,0 +1,801 @@
#include "3dc.h"
#include "dynblock.h"
#define UseLocalAssert No
#include "ourasert.h"
/*KJL****************************************************************************************
* P R O T O T Y P E S *
****************************************************************************************KJL*/
void InitialiseDynamicsBlocks(void);
DYNAMICSBLOCK* AllocateDynamicsBlock(enum DYNAMICS_TEMPLATE_ID templateID);
void DeallocateDynamicsBlock(DYNAMICSBLOCK *dynPtr);
void InitialiseCollisionReports(void);
COLLISIONREPORT* AllocateCollisionReport(DYNAMICSBLOCK* dynPtr);
static DYNAMICSBLOCK DynBlockStorage[MAX_NO_OF_DYNAMICS_BLOCKS];
static int NumFreeDynBlocks;
static DYNAMICSBLOCK *FreeDynBlockList[MAX_NO_OF_DYNAMICS_BLOCKS];
static DYNAMICSBLOCK **FreeDynBlockListPtr;
static COLLISIONREPORT CollisionReportStorage[MAX_NO_OF_COLLISION_REPORTS];
int NumFreeCollisionReports;
static DYNAMICSBLOCK DynamicsTemplate[]=
{
/* DYNAMICS_TEMPLATE_MARINE_PLAYER */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{0,0,0,0,0,0,0,0,0},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,65536,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
0,/* int Friction; */
0,/* int Elasticity; */
80*2, /* int Mass */
DYN_TYPE_NRBB_COLLISIONS,
TOPPLE_FORCE_NONE,
1,/* GravityOn :1; */
1,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
1,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_ALIEN_NPC */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{0,0,0,0,0,0,0,0,0},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,65536,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
1,/* int Friction; */
0,/* int Elasticity; */
100, /* int Mass */
DYN_TYPE_NRBB_COLLISIONS,
TOPPLE_FORCE_ALIEN,
1,/* GravityOn :1; */
0,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
1,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_GRENADE */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{0,0,0,0,0,0,0,0,0},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,0,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
0,/* int Friction; */
32768/2,/* int Elasticity; */
20, /* int Mass */
DYN_TYPE_NRBB_COLLISIONS,
TOPPLE_FORCE_FULL,
1,/* GravityOn :1; */
1,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
0,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
1,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_ROCKET & predator disc weapon */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{0,0,0,0,0,0,0,0,0},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,0,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
0,/* int Friction; */
65536,/* int Elasticity; */
40, /* int Mass */
DYN_TYPE_NRBB_COLLISIONS,
TOPPLE_FORCE_NONE,
0,/* GravityOn :1; */
0,/* UseStandardGravity :1 - ie. in direction of increasing Y */
1,/* StopOnCollision :1; */
0,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
1,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_DEBRIS */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,0,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
0,/* int Friction; */
0,/* int Elasticity; */
30, /* int Mass */
DYN_TYPE_NO_COLLISIONS,
TOPPLE_FORCE_NONE,
1,/* GravityOn :1; */
1,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
0,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
1,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_STATIC */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,0,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
0,/* int Friction; */
0,/* int Elasticity; */
100, /* int Mass */
DYN_TYPE_NRBB_COLLISIONS,
TOPPLE_FORCE_NONE,
1,/* GravityOn :1; */
1,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
0,/* CanClimbStairs :1; */
1,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_INANIMATE */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,0,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
1,/* int Friction; */
16384,/* int Elasticity; */
65536, /* int Mass */
DYN_TYPE_NRBB_COLLISIONS,
TOPPLE_FORCE_FULL,
1,/* GravityOn :1; */
1,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
0,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
1,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_PICKUPOBJECT */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,0,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
0,/* int Friction; */
16384,/* int Elasticity; */
20, /* int Mass */
DYN_TYPE_NRBB_COLLISIONS,
TOPPLE_FORCE_FULL,
0,/* GravityOn :1; */
1,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
0,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
1,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_SPRITE_NPC */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{0,0,0,0,0,0,0,0,0},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,65536,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
1,/* int Friction; */
0,/* int Elasticity; */
80*2, /* int Mass */
DYN_TYPE_NRBB_COLLISIONS,
TOPPLE_FORCE_NONE,
1,/* GravityOn :1; */
1,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
1,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_STATIC_SPRITE */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{0,0,0,0,0,0,0,0,0},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,65536,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
1,/* int Friction; */
0,/* int Elasticity; */
80*2, /* int Mass */
DYN_TYPE_SPRITE_COLLISIONS,
TOPPLE_FORCE_NONE,
1,/* GravityOn :1; */
1,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
1,/* CanClimbStairs :1; */
1,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_PLATFORM_LIFT */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,0,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
0,/* int Friction; */
0,/* int Elasticity; */
1, /* int Mass */
DYN_TYPE_NRBB_COLLISIONS,
TOPPLE_FORCE_NONE,
0,/* GravityOn :1; */
1,/* UseStandardGravity :1 - ie. in direction of increasing Y */
1,/* StopOnCollision :1; */
0,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
1,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
1,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_ALIEN_DEBRIS */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,0,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
0,/* int Friction; */
0,/* int Elasticity; */
1, /* int Mass */
DYN_TYPE_NRBB_COLLISIONS,
TOPPLE_FORCE_NONE,
1,/* GravityOn :1; */
1,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
0,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
1,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
1,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_ACID_SMOKE */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,-ONE_FIXED,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
0,/* int Friction; */
0,/* int Elasticity; */
1, /* int Mass */
DYN_TYPE_NO_COLLISIONS,
TOPPLE_FORCE_NONE,
1,/* GravityOn :1; */
0,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
0,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
0,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
/* DYNAMICS_TEMPLATE_NET_GHOST */
{
{0,0,0},/* EULER OrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH OrientMat - Local -> World Orientation Matrix */
{0,0,0},/* EULER PrevOrientEuler - Euler Orientation */
{65536,0,0,0,65536,0,0,0,65536},/* MATRIXCH PrevOrientMat - Local -> World Orientation Matrix */
{0,0,0},/* VECTORCH Position */
{0,0,0},/* VECTORCH PrevPosition */
{0,0,0},/* VECTORCH LinVelocity */
{0,0,0},/* VECTORCH LinImpulse */
{0,0,0},/* EULER AngVelocity */
{0,0,0},/* EULER AngImpulse */
NULL, /* struct collisionreport *CollisionReportPtr; */
{0,0,0},/* VECTORCH GravityDirection */
0, /* int TimeNotInContactWithFloor */
0,/* int Friction; */
0,/* int Elasticity; */
100, /* int Mass */
DYN_TYPE_NRBB_COLLISIONS,
TOPPLE_FORCE_NONE,
1,/* GravityOn :1; */
1,/* UseStandardGravity :1 - ie. in direction of increasing Y */
0,/* StopOnCollision :1; */
0,/* CanClimbStairs :1; */
0,/* IsStatic :1; */
0,/* OnlyCollideWithObjects :1; */
1,/* IsNetGhost :1; */
0,/* IgnoreSameObjectsAsYou :1; */
0,/* IgnoreThePlayer :1; */
0,/* UseDisplacement :1; */
0,/* OnlyCollideWithEnvironment :1; */
0,/* IsInContactWithFloor :1 */
0,/* IsInContactWithNearlyFlatFloor */
0,/* RequestsToStandUp :1 */
0,/* IsFloating :1 */
0,/* IsPickupObject :1 */
0,/* IsInanimate :1; */
0,/* IgnoresNotVisPolys :1; */
},
};
/*KJL***************************************************************************
* FUNCTIONS TO ALLOCATE AND DEALLOCATE DYNAMICS BLOCKS - KJL 12:02:14 11/13/96 *
***************************************************************************KJL*/
void InitialiseDynamicsBlocks(void)
{
DYNAMICSBLOCK *freeBlockPtr = DynBlockStorage;
int blk;
for(blk=0; blk < MAX_NO_OF_DYNAMICS_BLOCKS; blk++)
{
FreeDynBlockList[blk] = freeBlockPtr++;
}
FreeDynBlockListPtr = &FreeDynBlockList[MAX_NO_OF_DYNAMICS_BLOCKS-1];
NumFreeDynBlocks = MAX_NO_OF_DYNAMICS_BLOCKS;
}
DYNAMICSBLOCK* AllocateDynamicsBlock(enum DYNAMICS_TEMPLATE_ID templateID)
{
DYNAMICSBLOCK *dynPtr = 0; /* Default to null ptr */
if (NumFreeDynBlocks)
{
dynPtr = *FreeDynBlockListPtr--;
NumFreeDynBlocks--;
GLOBALASSERT(templateID>=0);
GLOBALASSERT(templateID<MAX_NO_OF_DYNAMICS_TEMPLATES);
*dynPtr = DynamicsTemplate[templateID];
}
else
{
/* unable to allocate a dynamics block I'm afraid;
MAX_NO_OF_DYNAMICS_BLOCKS is too low */
LOCALASSERT(NumFreeDynBlocks);
}
return dynPtr;
}
void DeallocateDynamicsBlock(DYNAMICSBLOCK *dynPtr)
{
GLOBALASSERT(dynPtr);
*(++FreeDynBlockListPtr) = dynPtr;
NumFreeDynBlocks++;
}
/*KJL***************************************************************************
* FUNCTIONS TO INITIALISE & ALLOCATE COLLISION REPORTS - KJL 12:17:13 11/19/96 *
***************************************************************************KJL*/
void InitialiseCollisionReports(void)
{
NumFreeCollisionReports = MAX_NO_OF_COLLISION_REPORTS;
}
COLLISIONREPORT* AllocateCollisionReport(DYNAMICSBLOCK* dynPtr)
{
COLLISIONREPORT *newReportPtr = 0; /* Default to null ptr */
GLOBALASSERT(dynPtr);
if (NumFreeCollisionReports)
{
NumFreeCollisionReports--;
newReportPtr = &CollisionReportStorage[NumFreeCollisionReports];
if (dynPtr->CollisionReportPtr) /* already some reports */
{
COLLISIONREPORT *reportPtr = dynPtr->CollisionReportPtr;
/* search for the last report */
while(reportPtr->NextCollisionReportPtr)
reportPtr = reportPtr->NextCollisionReportPtr;
reportPtr->NextCollisionReportPtr = newReportPtr;
}
else /* object's first report */
{
dynPtr->CollisionReportPtr = newReportPtr;
}
/* make report the end of the list */
newReportPtr->NextCollisionReportPtr=0;
}
else
{
/* unable to allocate a collision block I'm afraid */
LOCALASSERT(1==0);
}
return newReportPtr;
}

142
3dc/avp/DYNBLOCK.H Normal file
View file

@ -0,0 +1,142 @@
#ifndef _dynblock_h_ /* Is this your first time? */
#define _dynblock_h_ 1
/*KJL****************************************************************************************
* S T R U C T U R E S *
****************************************************************************************KJL*/
enum DYN_TYPE
{
DYN_TYPE_NO_COLLISIONS,
DYN_TYPE_SPRITE_COLLISIONS,
DYN_TYPE_SPHERE_COLLISIONS,
DYN_TYPE_NRBB_COLLISIONS,
DYN_TYPE_CUBOID_COLLISIONS,
};
enum TOPPLE_FORCE
{
TOPPLE_FORCE_NONE,
TOPPLE_FORCE_ALIEN,
TOPPLE_FORCE_FULL
};
/* KJL 17:19:14 11/05/96 - my 'dynamicsblock'. I'll use the enginesque lower/upper case naming convention */
typedef struct dynamicsblock
{
/* representations of orientation of object */
EULER OrientEuler; /* Euler Orientation */
MATRIXCH OrientMat; /* Local -> World Orientation Matrix */
EULER PrevOrientEuler; /* Euler Orientation */
MATRIXCH PrevOrientMat; /* Local -> World Orientation Matrix */
/* position in World Space (units mm) */
VECTORCH Position;
VECTORCH PrevPosition;
/* component of velocity (in World Space, units mm per sec) due to internal forces
eg. a player walking forward, a rocket's thrust - set by strategies */
VECTORCH LinVelocity;
/* component of velocity (in World Space, units mm per sec) due to external forces
eg. gravity, explosions, jumping - set by dynamics system & strategies */
VECTORCH LinImpulse;
/* angular velocity in World Space */
EULER AngVelocity;
/* rotational effects due to external forces */
EULER AngImpulse;
/* pointer to report(s) on last frame's collisions (singly-linked list) */
struct collisionreport *CollisionReportPtr;
/* object's normalised gravity vector - used if UseStandardGravity is set to false */
VECTORCH GravityDirection;
int TimeNotInContactWithFloor;
/* physical constants */
int Friction; /* difficult to set a scale as yet */
int Elasticity; /* 0 = perfectly inelastic, 65536 = perfectly elastic */
int Mass; /* integer in kg */
/* collision flags */
/* eg. can go up steps, cuboid model etc */
enum DYN_TYPE DynamicsType;
enum TOPPLE_FORCE ToppleForce;
unsigned int GravityOn :1;
unsigned int UseStandardGravity :1; /* ie. in direction of increasing Y */
unsigned int StopOnCollision :1; /* eg. missiles stop as soon as bthey hit something; players don't */
unsigned int CanClimbStairs :1;
unsigned int IsStatic :1;
unsigned int OnlyCollideWithObjects :1;
unsigned int IsNetGhost :1;
unsigned int IgnoreSameObjectsAsYou :1; /* don't collide with objects which have the same behaviour type */
unsigned int IgnoreThePlayer :1;
unsigned int UseDisplacement :1;
unsigned int OnlyCollideWithEnvironment :1;
unsigned int IsInContactWithFloor :1;
unsigned int IsInContactWithNearlyFlatFloor :1;
unsigned int RequestsToStandUp :1;
unsigned int IsFloating :1;
unsigned int IsPickupObject :1;
unsigned int IsInanimate :1;
unsigned int IgnoresNotVisPolys :1;
/* FOR INTERNAL USE ONLY */
int CollisionRadius;
int DistanceLeftToMove;
VECTORCH Displacement;
VECTORCH ObjectVertices[8]; /* vertices of the cuboid which describes the object */
} DYNAMICSBLOCK;
enum DYNAMICS_TEMPLATE_ID
{
DYNAMICS_TEMPLATE_MARINE_PLAYER,
DYNAMICS_TEMPLATE_ALIEN_NPC,
DYNAMICS_TEMPLATE_GRENADE,
DYNAMICS_TEMPLATE_ROCKET,
DYNAMICS_TEMPLATE_DEBRIS,
DYNAMICS_TEMPLATE_STATIC,
DYNAMICS_TEMPLATE_INANIMATE,
DYNAMICS_TEMPLATE_PICKUPOBJECT,
DYNAMICS_TEMPLATE_SPRITE_NPC,
DYNAMICS_TEMPLATE_STATIC_SPRITE,
DYNAMICS_TEMPLATE_PLATFORM_LIFT,
DYNAMICS_TEMPLATE_ALIEN_DEBRIS,
DYNAMICS_TEMPLATE_ACID_SMOKE,
DYNAMICS_TEMPLATE_NET_GHOST,
MAX_NO_OF_DYNAMICS_TEMPLATES
};
typedef struct collisionreport
{
/* strategy block of whatever you've hit - this is null if you've hit the landscape */
struct strategyblock *ObstacleSBPtr;
/* the normal of the obstacle's face which you've hit */
VECTORCH ObstacleNormal;
VECTORCH ObstaclePoint;
/* ptr to the next report, null if there isn't one */
struct collisionreport *NextCollisionReportPtr;
} COLLISIONREPORT;
#define MAX_NO_OF_DYNAMICS_BLOCKS maxstblocks
#define MAX_NO_OF_COLLISION_REPORTS 400
/*KJL****************************************************************************************
* P R O T O T Y P E S *
****************************************************************************************KJL*/
extern void InitialiseDynamicsBlocks(void);
extern DYNAMICSBLOCK* AllocateDynamicsBlock(enum DYNAMICS_TEMPLATE_ID templateID);
extern void DeallocateDynamicsBlock(DYNAMICSBLOCK *dynPtr);
extern void InitialiseCollisionReports(void);
extern COLLISIONREPORT* AllocateCollisionReport(DYNAMICSBLOCK* dynPtr);
#endif /* end of preprocessor condition for file wrapping */

162
3dc/avp/DetailLevels.c Normal file
View file

@ -0,0 +1,162 @@
#include "DetailLevels.h"
DETAIL_LEVELS LocalDetailLevels;
MENU_DETAIL_LEVEL_OPTIONS MenuDetailLevelOptions;
extern int GlobalLevelOfDetail_Hierarchical;
extern void SetToDefaultDetailLevels(void)
{
#if 0
LocalDetailLevels.BloodCollidesWithEnvironment=1;
LocalDetailLevels.DrawLightCoronas=1;
LocalDetailLevels.DrawHierarchicalDecals=1;
LocalDetailLevels.ExplosionsDeformToEnvironment=1;
LocalDetailLevels.GhostFlameThrowerCollisions=0;
LocalDetailLevels.MaximumAllowedNumberOfDecals = 1024;
LocalDetailLevels.AlienEnergyViewThreshold = 0;
LocalDetailLevels.NumberOfSmokeParticlesFromLargeExplosion=10;
LocalDetailLevels.NumberOfSmokeParticlesFromSmallExplosion=5;
GlobalLevelOfDetail_Hierarchical = 65536;
#endif
MenuDetailLevelOptions.DecalNumber = 3;
MenuDetailLevelOptions.LightCoronas = 1;
MenuDetailLevelOptions.DecalsOnCharacters = 1;
MenuDetailLevelOptions.DeformableExplosions = 1;
MenuDetailLevelOptions.CharacterComplexity = 3;
MenuDetailLevelOptions.ParticleComplexity = 1;
SetDetailLevelsFromMenu();
}
extern void SetToMinimalDetailLevels(void)
{
#if 0
LocalDetailLevels.BloodCollidesWithEnvironment=0;
LocalDetailLevels.DrawLightCoronas=0;
LocalDetailLevels.DrawHierarchicalDecals=0;
LocalDetailLevels.ExplosionsDeformToEnvironment=0;
LocalDetailLevels.GhostFlameThrowerCollisions=0;
LocalDetailLevels.MaximumAllowedNumberOfDecals = 16;
LocalDetailLevels.AlienEnergyViewThreshold = 450;
LocalDetailLevels.NumberOfSmokeParticlesFromLargeExplosion=5;
LocalDetailLevels.NumberOfSmokeParticlesFromSmallExplosion=2;
GlobalLevelOfDetail_Hierarchical = 128*65536;
#endif
MenuDetailLevelOptions.DecalNumber = 0;
MenuDetailLevelOptions.LightCoronas = 0;
MenuDetailLevelOptions.DecalsOnCharacters = 0;
MenuDetailLevelOptions.DeformableExplosions = 0;
MenuDetailLevelOptions.CharacterComplexity = 0;
MenuDetailLevelOptions.ParticleComplexity = 0;
SetDetailLevelsFromMenu();
}
extern void SetDetailLevelsFromMenu(void)
{
switch (MenuDetailLevelOptions.DecalNumber)
{
default:
case 0:
{
LocalDetailLevels.MaximumAllowedNumberOfDecals = 16;
break;
}
case 1:
{
LocalDetailLevels.MaximumAllowedNumberOfDecals = 128;
break;
}
case 2:
{
LocalDetailLevels.MaximumAllowedNumberOfDecals = 512;
break;
}
case 3:
{
LocalDetailLevels.MaximumAllowedNumberOfDecals = 1024;
break;
}
}
LocalDetailLevels.DrawLightCoronas = MenuDetailLevelOptions.LightCoronas;
LocalDetailLevels.DrawHierarchicalDecals = MenuDetailLevelOptions.DecalsOnCharacters;
LocalDetailLevels.ExplosionsDeformToEnvironment = MenuDetailLevelOptions.DeformableExplosions;
switch (MenuDetailLevelOptions.CharacterComplexity)
{
default:
case 0:
{
GlobalLevelOfDetail_Hierarchical = 65536*128;
break;
}
case 1:
{
GlobalLevelOfDetail_Hierarchical = 65536*4;
break;
}
case 2:
{
GlobalLevelOfDetail_Hierarchical = 65536*2;
break;
}
case 3:
{
GlobalLevelOfDetail_Hierarchical = 65536;
break;
}
}
switch (MenuDetailLevelOptions.ParticleComplexity)
{
default:
case 0:
{
LocalDetailLevels.BloodCollidesWithEnvironment=0;
LocalDetailLevels.AlienEnergyViewThreshold = 300;
LocalDetailLevels.NumberOfSmokeParticlesFromLargeExplosion=5;
LocalDetailLevels.NumberOfSmokeParticlesFromSmallExplosion=2;
LocalDetailLevels.GhostFlameThrowerCollisions=0;
break;
}
case 1:
{
LocalDetailLevels.BloodCollidesWithEnvironment=1;
LocalDetailLevels.AlienEnergyViewThreshold = 0;
LocalDetailLevels.NumberOfSmokeParticlesFromLargeExplosion=10;
LocalDetailLevels.NumberOfSmokeParticlesFromSmallExplosion=5;
LocalDetailLevels.GhostFlameThrowerCollisions=1;
break;
}
}
}

38
3dc/avp/DetailLevels.h Normal file
View file

@ -0,0 +1,38 @@
#ifndef _detaillevels_h_
#define _detaillevels_h_ 1
typedef struct
{
unsigned int MaximumAllowedNumberOfDecals;
unsigned int AlienEnergyViewThreshold;
unsigned int NumberOfSmokeParticlesFromLargeExplosion;
unsigned int NumberOfSmokeParticlesFromSmallExplosion;
unsigned int BloodCollidesWithEnvironment :1;
unsigned int DrawLightCoronas :1;
unsigned int DrawHierarchicalDecals :1;
unsigned int ExplosionsDeformToEnvironment :1;
unsigned int GhostFlameThrowerCollisions :1;
} DETAIL_LEVELS;
extern DETAIL_LEVELS LocalDetailLevels;
typedef struct
{
int DecalNumber;
int LightCoronas;
int DecalsOnCharacters;
int DeformableExplosions;
int CharacterComplexity;
int ParticleComplexity;
} MENU_DETAIL_LEVEL_OPTIONS;
extern MENU_DETAIL_LEVEL_OPTIONS MenuDetailLevelOptions;
extern void SetToDefaultDetailLevels(void);
extern void SetToMinimalDetailLevels(void);
extern void SetDetailLevelsFromMenu(void);
#endif

6444
3dc/avp/Dynamics.c Normal file

File diff suppressed because it is too large Load diff

228
3dc/avp/EQUATES.H Normal file
View file

@ -0,0 +1,228 @@
#ifndef EQUATES_INCLUDED
/*
Equates & Enums for AVP
*/
#ifdef __cplusplus
extern "C" {
#endif
#define default_global_h1 5000000
#define default_global_h2 (5000000 + (ONE_FIXED << 5))
#define default_global_hs 5
#define default_zratio_threshold 320 /* 1.25 */
#define MaxObjectLights 50 /* Sources attached to the object */
#define maxlightblocks 100 /* This ought to be MORE than enough */
#if PSX
#define MaxLightsPerObject 10 /* Sources lighting the object */
#else
#define MaxLightsPerObject 100 /* Sources lighting the object */
#endif
/*
3d Texture Scan Subdivision limits
*/
#define lin_s_max 5
#if 0
#define lin_s_zthr 320 /* 1.25 */
#else
#if 1
#define lin_s_zthr 281 /* 1.1 */
#else
#define lin_s_zthr 260 /* 1.01 */
#endif
#endif
/* AH Table */
#define RScale 2
#define VScale (6 + 3)
#define Wibble Yes
#define GlobalScale 1
/*
Scenes and View Types
*/
typedef enum {
AVP_Scene0, /* environments*/
AVP_Scene1,
AVP_Scene2,
AVP_Scene3,
AVP_Scene4,
AVP_Scene5,
AVP_Scene6,
AVP_Scene7,
AVP_Scene8,
AVP_Scene9,
AVP_Scene10
} SCENE;
typedef enum {
AVP_ViewType0, /* worlds within env*/
} VIEWTYPE;
/*
View Handler Function Array Indices
*/
typedef enum {
VState_Inside,
VState_RelativeRemote,
VState_RelativeYRemote,
VState_FixedRemote,
VState_FlyBy,
VState_LagRelRemote,
VState_TrackingRemote,
VState_LagRelYRemote,
VState_Last
} VIEWSTATES;
#define CameraTrackingNormal 0x00000000
#define CameraTrackingSlew 0x00000001
#define CameraTrackingFollow 0x00000002
#define CameraTrackingTrakBak 0x00000004
#define PanChange 128
/*
View Interior Types
*/
typedef enum {
IType_Default,
IType_Body,
IType_Car,
IType_Aircraft,
IType_Last
} ITYPES;
/*
Shape enum for mainshapelist[]
We don't need this except for compiled in
shapes. For pc riff loading the comipled in
shape enum is in cnkhmaps.c in avp\win95
*/
#if PSX
#if BinaryLoading
#else
typedef enum {
Shape_bob,
Shape_Default,
Shape_Alien,
Shape_weapon,
Shape_terminal,
Shape_mmseg1,
Shape_Cube,
} AVP_SHAPES;
#endif
#endif
/* Map Types */
typedef enum {
MapType_Default,
MapType_Player,
MapType_PlayerShipCamera,
MapType_Sprite,
MapType_Term
} AVP_MAP_TYPES;
/* Strategies */
typedef enum {
StrategyI_Null,
StrategyI_Camera,
StrategyI_Player,
StrategyI_Test,
StrategyI_NewtonTest,
StrategyI_HomingTest,
StrategyI_MissileTest,
StrategyI_GravityOnly,
StrategyI_Database,
StrategyI_DoorPROX,
StrategyI_Terminal,
StrategyI_Last /* Always the last */
} AVP_STRATEGIES;
#define MaxSint5SortArraySize 50 /* was 100, must be at least ml_shm_maxheights */
/***********end for C++************/
#ifdef __cplusplus
};
#endif
#define EQUATES_INCLUDED
#endif

8238
3dc/avp/EQUIPMNT.C Normal file

File diff suppressed because it is too large Load diff

579
3dc/avp/EQUIPMNT.H Normal file
View file

@ -0,0 +1,579 @@
#ifndef _equipmnt_h_
#define _equipmnt_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
#include "language.h"
/* has to come after gameplat.h in the setup*/
#include "gamedef.h"
/* KJL 12:34:46 09/18/96 - new stuff under development */
/* KJL 12:39:41 09/18/96 -
Okay, I think we should have two weapon structures:
TEMPLATE_WEAPON_DATA: First the basic template for each weapon, which remains constant
during the game & contains the base description of a weapon eg.
ammo type, weight, graphics, etc.
PLAYER_WEAPON_DATA: Second is the structure which describes a player's weapon
eg. a pointer to a TEMPLATE_WEAPON_DATA, ammo remaining, jam
status, and so on.
eg. PLAYER_WEAPON_DATA PlayerWeapons[];
*/
/* KJL 16:09:51 09/20/96 - Weapon States */
enum WEAPON_STATE
{
WEAPONSTATE_IDLE=0,
WEAPONSTATE_FIRING_PRIMARY,
WEAPONSTATE_RECOIL_PRIMARY,
WEAPONSTATE_RELOAD_PRIMARY,
WEAPONSTATE_FIRING_SECONDARY,
WEAPONSTATE_RECOIL_SECONDARY,
WEAPONSTATE_RELOAD_SECONDARY,
WEAPONSTATE_SWAPPING_IN,
WEAPONSTATE_SWAPPING_OUT,
WEAPONSTATE_JAMMED,
WEAPONSTATE_WAITING,
WEAPONSTATE_READYING,
WEAPONSTATE_UNREADYING,
MAX_NO_OF_WEAPON_STATES
};
#define WEAPONSTATE_INITIALTIMEOUTCOUNT 65536
#define WEAPONSTATE_INSTANTTIMEOUT 0
/* KJL 10:42:38 09/19/96 - Weapon Enumerations */
enum WEAPON_ID
{
/* USED TO DENOTE AN EMPTY SLOT */
NULL_WEAPON=-1,
/* MARINE WEAPONS */
WEAPON_PULSERIFLE,
WEAPON_AUTOSHOTGUN,
WEAPON_SMARTGUN,
WEAPON_FLAMETHROWER,
WEAPON_PLASMAGUN,
WEAPON_SADAR,
WEAPON_GRENADELAUNCHER,
WEAPON_MINIGUN,
WEAPON_SONICCANNON,
WEAPON_BEAMCANNON,
WEAPON_MYSTERYGUN,
/* PREDATOR WEAPONS */
WEAPON_PRED_WRISTBLADE,
WEAPON_PRED_PISTOL,
WEAPON_PRED_RIFLE,
WEAPON_PRED_SHOULDERCANNON,
WEAPON_PRED_DISC,
WEAPON_PRED_MEDICOMP,
WEAPON_PRED_STAFF,
/* ALIEN WEAPONS */
WEAPON_ALIEN_CLAW,
WEAPON_ALIEN_GRAB,
WEAPON_ALIEN_SPIT,
WEAPON_CUDGEL,
WEAPON_MARINE_PISTOL,
WEAPON_FRISBEE_LAUNCHER,
WEAPON_TWO_PISTOLS,
MAX_NO_OF_WEAPON_TEMPLATES
};
enum WEAPON_SLOT
{
WEAPON_SLOT_1=0,
WEAPON_SLOT_2,
WEAPON_SLOT_3,
WEAPON_SLOT_4,
WEAPON_SLOT_5,
WEAPON_SLOT_6,
WEAPON_SLOT_7,
WEAPON_SLOT_8,
WEAPON_SLOT_9,
WEAPON_SLOT_10,
WEAPON_SLOT_11,
MAX_NO_OF_WEAPON_SLOTS,
WEAPON_FINISHED_SWAPPING
};
enum AMMO_ID
{
AMMO_NONE=-1,
AMMO_10MM_CULW=0,
AMMO_SHOTGUN,
AMMO_SMARTGUN,
AMMO_FLAMETHROWER,
AMMO_PLASMA,
AMMO_SADAR_TOW,
AMMO_GRENADE,
AMMO_MINIGUN,
AMMO_PULSE_GRENADE,
AMMO_FLARE_GRENADE,
AMMO_FRAGMENTATION_GRENADE,
AMMO_PROXIMITY_GRENADE,
AMMO_PARTICLE_BEAM,
AMMO_SONIC_PULSE,
AMMO_PRED_WRISTBLADE,
AMMO_PRED_PISTOL,
AMMO_PRED_RIFLE,
AMMO_PRED_ENERGY_BOLT,
AMMO_PRED_DISC,
AMMO_ALIEN_CLAW,
AMMO_ALIEN_TAIL,
AMMO_ALIEN_SPIT,
AMMO_AUTOGUN,
AMMO_XENOBORG,
AMMO_FACEHUGGER,
AMMO_NPC_OBSTACLE_CLEAR,
AMMO_ALIEN_FRAG,
AMMO_ALIEN_DEATH,
AMMO_SHOTGUN_BLAST,
AMMO_SADAR_BLAST,
AMMO_ALIEN_BITE_KILLSECTION,
AMMO_PRED_DISC_PM,
AMMO_NPC_ALIEN_CLAW,
AMMO_NPC_PAQ_CLAW,
AMMO_PULSE_GRENADE_STRIKE,
AMMO_NPC_ALIEN_TAIL,
AMMO_NPC_ALIEN_BITE,
AMMO_NPC_PREDALIEN_CLAW,
AMMO_NPC_PREDALIEN_BITE,
AMMO_NPC_PREDALIEN_TAIL,
AMMO_NPC_PRAETORIAN_CLAW,
AMMO_NPC_PRAETORIAN_BITE,
AMMO_NPC_PRAETORIAN_TAIL,
AMMO_PRED_STAFF,
AMMO_NPC_PRED_STAFF,
AMMO_PC_ALIEN_BITE,
AMMO_HEAVY_PRED_WRISTBLADE,
AMMO_MARINE_PISTOL,
AMMO_PREDPISTOL_STRIKE,
AMMO_PLASMACASTER_NPCKILL,
AMMO_PLASMACASTER_PCKILL,
AMMO_10MM_CULW_NPC,
AMMO_SMARTGUN_NPC,
AMMO_MINIGUN_NPC,
AMMO_MOLOTOV,
AMMO_ALIEN_OBSTACLE_CLEAR,
AMMO_PRED_TROPHY_KILLSECTION,
AMMO_CUDGEL,
AMMO_ALIEN_BITE_KILLSECTION_SUPER,
AMMO_MARINE_PISTOL_PC,
AMMO_FRISBEE,
AMMO_FRISBEE_BLAST,
AMMO_FRISBEE_FIRE,
MAX_NO_OF_AMMO_TEMPLATES,
AMMO_FLECHETTE_POSTMAX,
AMMO_FALLING_POSTMAX,
AMMO_FIREDAMAGE_POSTMAX
};
/* CDF - 15/9/97 New Damage System */
typedef struct {
short Impact;
short Cutting;
short Penetrative;
short Fire;
short Electrical;
short Acid;
/* New additions, 4/8/98 */
unsigned int ExplosivePower :3;
/* XP: 0 is nothing, 1 is little, 2 is big (SADAR),
3 is pred pistol, 4 is plasmacaster, 5 is molotov, 6 is big with no collisions,
7+ unused. */
unsigned int Slicing :2;
unsigned int ProduceBlood :1;
unsigned int ForceBoom :2;
unsigned int BlowUpSections :1;
unsigned int Special :1;
unsigned int MakeExitWounds :1;
enum AMMO_ID Id;
} DAMAGE_PROFILE;
/* CDF - 15/9/97 New Damage System */
typedef struct {
unsigned int MovementMultiple;
unsigned int TurningMultiple;
unsigned int JumpingMultiple;
unsigned int CanCrouch:1;
unsigned int CanRun:1;
} ENCUMBERANCE_STATE;
typedef struct
{
int AmmoPerMagazine;
DAMAGE_PROFILE MaxDamage[I_MaxDifficulties];
int MaxRange;
enum TEXTSTRING_ID ShortName;
/* Added 20/11/97 by DHM: Abberviated name for ammo, to appear in HUD status panel */
/* ammo flags */
unsigned int CreatesProjectile :1;
unsigned int ExplosionIsFlat:1;
} TEMPLATE_AMMO_DATA;
typedef struct
{
enum WEAPON_ID WeaponIDNumber;
/* eg.==MARINE_WEAPON_PULSE. This can be used to access the TemplateWeapon[] data, graphics, etc. */
enum WEAPON_STATE CurrentState;
int StateTimeOutCounter; /* in 16.16 */
unsigned int PrimaryRoundsRemaining; /* in 'current' magazine */
unsigned int SecondaryRoundsRemaining; /* in 'current' magazine */
unsigned char PrimaryMagazinesRemaining;
unsigned char SecondaryMagazinesRemaining;
VECTORCH PositionOffset;
EULER DirectionOffset;
SHAPEANIMATIONCONTROLLER ShpAnimCtrl;
TXACTRLBLK *TxAnimCtrl;
/* general flags */
signed int Possessed :2; /* meaning you are carrying the weapon, not that an evil spirit etc etc. */
} PLAYER_WEAPON_DATA;
typedef struct
{
enum AMMO_ID PrimaryAmmoID;
enum AMMO_ID SecondaryAmmoID;
int (*FirePrimaryFunction)(PLAYER_WEAPON_DATA *);
int (*FireSecondaryFunction)(PLAYER_WEAPON_DATA *);
void (*WeaponInitFunction)(PLAYER_WEAPON_DATA *);
int TimeOutRateForState[MAX_NO_OF_WEAPON_STATES]; /* in 16.16 */
void (*WeaponStateFunction[MAX_NO_OF_WEAPON_STATES])(void *, PLAYER_WEAPON_DATA *); // void * is for PLAYER_STATUS
int ProbabilityOfJamming;
int FiringRate;
/* display stuff */
signed int SmartTargetSpeed; /* how fast crosshair moves */
unsigned int GunCrosshairSpeed; /* how fast the gun moves to catch up */
unsigned int SmartTargetRadius;
VECTORCH RestPosition;
int RecoilMaxZ;
int RecoilMaxRandomZ;
int RecoilMaxXTilt;
int RecoilMaxYTilt;
VECTORCH StrikePosition;
enum TEXTSTRING_ID Name;
/* shape reference */
char * WeaponShapeName;
char * MuzzleFlashShapeName;
char * RiffName;
char * HierarchyName;
int InitialSequenceType;
int InitialSubSequence;
/* Encumberance */
ENCUMBERANCE_STATE Encum_Idle;
ENCUMBERANCE_STATE Encum_FirePrime;
ENCUMBERANCE_STATE Encum_FireSec;
/* flags */
unsigned int UseStateMovement :1;
unsigned int IsSmartTarget :1;
unsigned int PrimaryIsRapidFire :1;
unsigned int PrimaryIsAutomatic :1;
unsigned int PrimaryIsMeleeWeapon :1;
unsigned int SecondaryIsRapidFire :1;
unsigned int SecondaryIsAutomatic :1;
unsigned int SecondaryIsMeleeWeapon :1;
unsigned int HasShapeAnimation: 1;
unsigned int HasTextureAnimation: 1;
unsigned int FireWhenCloaked: 1;
unsigned int FireInChangeVision: 1;
unsigned int FirePrimaryLate: 1;
unsigned int FireSecondaryLate: 1;
unsigned int PrimaryMuzzleFlash: 1;
unsigned int SecondaryMuzzleFlash: 1;
unsigned int LogAccuracy: 1;
unsigned int LogShots: 1;
} TEMPLATE_WEAPON_DATA;
typedef struct
{
enum AMMO_ID SelectedAmmo;
unsigned int StandardRoundsRemaining;
unsigned char StandardMagazinesRemaining;
unsigned int FlareRoundsRemaining;
unsigned char FlareMagazinesRemaining;
unsigned int ProximityRoundsRemaining;
unsigned char ProximityMagazinesRemaining;
unsigned int FragmentationRoundsRemaining;
unsigned char FragmentationMagazinesRemaining;
} GRENADE_LAUNCHER_DATA;
typedef enum Pred_Disc_Modes {
I_Seek_Track,
I_Search_Destroy,
I_Proximity_Mine,
} PRED_DISC_MODES;
typedef enum Smartgun_Modes {
I_Track,
I_Free,
} SMARTGUN_MODES;
extern PRED_DISC_MODES ThisDiscMode;
extern SMARTGUN_MODES SmartgunMode;
extern TEMPLATE_WEAPON_DATA TemplateWeapon[];
extern TEMPLATE_AMMO_DATA TemplateAmmo[];
extern GRENADE_LAUNCHER_DATA GrenadeLauncherData;
extern enum WEAPON_ID MarineWeaponKey[MAX_NO_OF_WEAPON_SLOTS];
extern enum WEAPON_ID PredatorWeaponKey[MAX_NO_OF_WEAPON_SLOTS];
extern enum WEAPON_ID AlienWeaponKey[MAX_NO_OF_WEAPON_SLOTS];
extern DAMAGE_PROFILE certainDeath;
extern DAMAGE_PROFILE console_nuke;
extern DAMAGE_PROFILE firedamage;
extern DAMAGE_PROFILE SmallExplosionDamage;
extern DAMAGE_PROFILE BigExplosionDamage;
extern void InitialiseEquipment(void);
/*compare two damage profiles to see if they are the same*/
extern BOOL AreDamageProfilesEqual(DAMAGE_PROFILE* profile1,DAMAGE_PROFILE* profile2);
#ifdef __cplusplus
};
#endif
#endif
/*KJL*****************************************************************************************
* Roxby's old stuff follows. I'm keeping it here 'cos it's very useful as reference material *
*****************************************************************************************KJL*/
#if 0
/*
Hmmm. Weapons need to be treated differnetly to Other Objects
Such as AMMO and Tools. They have things like Info Screen data
(Text and schematics) range, damage, weight, incumberance, DM
status, Jam status, reliabilty, Vulnerablity.
This contains the data sturcture and the weapons information
for the marine weapons - It may be extended to cover all
the predator weapons as well
*/
/*
The player can carry up to 100 kg.. Strong huh.
encumberance - a measure of how `encumbering' the weapon may
actually be. It is an abstrcted measure of how much it slows
the player down - It shouldnt effect the players fatigue - and
how difficult it is to change to another weapon.
To use a weapon it the players total `USING' encumberance has to
less than 50 in a normal corridor and less the 30 in an airduct
*/
/* Ammo
Ammo - this is where the weight is....
All this rounding... lets play
with integers only
These are only the initial specs, I imagine dramatic alterations.
Partic if we want to swap to weights to use shifts rather than divs
10 mm culw rounds (Ceramic - Ultra Light Weight) 0.05 Kg each. (1.5 oz!!)
20 mm culw rounds (Ceramic - Ultra Light Weight) 0.08 Kg each. (1.5 oz!!)
standard grenades 0.2 Kg each .
Heavy grenades 0.4 Kg each.
shotgun rounds 0.1 each
0 standard grenade 1 Kg
1 99x10 mm magizines of culw rounds. 5 Kg
2 500x10 mm magazines of culw rounds. 25 Kg
3 5xstandard grenades 1 Kg
4 5 Heavy grenades HE 2 Kg
5 5 Heavy grenades Napalm 2 Kg
6 5 HEavy grenades Canister 2 Kg
7 5 Heavy Grenades Cluster 2 Kg
8 5 Heavy Grenades WP 2 Kg
9 20x shotgun rounds 2 Kg
10 20 litres of fuel 18 Kg
11 500x20 mm magizines of culw rounds 40 Kg
12 Sonic Gun Power Packs 5 Kg
*/
/*
Weapons Information
Weight Kilos
Incumberance - Abstract use difficulty.
*/
#define MAX_PLAYER_WEAPONS 10
#define MAX_AMMO_TYPES 20
typedef struct ammo_data{
unsigned char weight; /*in 10ths of KG*/
unsigned char num_magazines;
unsigned short magazine_size;
unsigned short spread_radius;
unsigned short damage;
unsigned char damage_flags;
unsigned char flight_flags;
} AMMO_DATA;
/*damage flags*/
#define DAMAGE_POINT 0x01 /*point pixel damage*/
#define DAMAGE_SPREAD 0x02 /*Equal damage along radius*/
#define DAMAGE_TAPER 0x04 /*Decreasing damge on radius*/
#define DAMAGE_EXPLOSIVE1 0x08 /*explodes*/
#define DAMAGE_EXPLOSIVE2 0x10 /*big explodes*/
#define DAMAGE_DELAY 0x20 /*limpet*/
#define DAMAGE_FLAME 0x40 /*sets things on fire*/
/*Flight Flags*/
#define FLIGHT_HAND_GRENADE 0x01
#define FLIGHT_BULLET 0x02
#define FLIGHT_GRENADE_LNCH 0x04
typedef struct weapon_ammo_attributes{
unsigned char ammotype;
unsigned char remaining_ammo;
unsigned char targeting_flags;
unsigned char rate_of_fire; /*frames Between rounds */
unsigned char magazine_reload_time; /*frames to reload magazine*/
unsigned short failure_risk; /*0 - 2**16*/
unsigned char failure_flags;
} WEAP_AMMO_ATTR;
/* WEapon data contains the data to maintain, draw weapons
generation of these objects comes via the entity*/
/*
*schematic --- for the data retrival
*hudata - for drawing the HUD graphic . Note that this is PLATFORM dependent
*descriptive text --- to print up in the data retrival
*/
typedef struct weapon_data{
char weapon_flags;
char name[8]; /* can be made into something else if ness*/
/* YES the address of the platform spec data
structure*/
void *schematic; /* these contain the file name before the */
HUDGRAPHIC *huddata; /* graphic is loaded into here -- LPDDS*/
char *descriptivetext;
unsigned char weight; /*in 10ths of KG*/
unsigned char encumbrance; /*time it takes to swap the
weapon in pixels per sec*/
WEAP_AMMO_ATTR primary;
WEAP_AMMO_ATTR secondary;
#if Saturn
char* WDroxptr;
#endif
} WEAPON_DATA;
/*weapon_flags */
/*targeting flags*/
#define TARGETING_MANUAL 0x01
#define TARGETING_XHAIR 0x02
#define TARGETING_SMART 0x04
#define TARGETING_XTOS 0x08 /*targeting depends on equip*/
#define TARGETING_FAF_TRACK 0x10 /*Fire and forget....!*/
#define TARGETING_THROWN 0x20
/* failure flags */
#endif

342
3dc/avp/GAMEDEF.H Normal file
View file

@ -0,0 +1,342 @@
#ifndef GAMEDEF_INCLUDED
/*
Contains game specific defininitions of structures
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "module.h"
/***********************************************
AVP game description stuff
***********************************************/
/* game modes*/
typedef enum gamemode
{
I_GM_Playing,
I_GM_DataBase,
I_GM_Menus,
I_GM_Paused,
} I_GAME_MODE;
typedef enum gamedrawmode
{
I_GDM_GameOperations,
I_GDM_DrawWorld,
I_GDM_DrawHud,
I_GDM_Flippin,
} I_GAMEDRAW_MODE;
/* Languages*/
typedef enum languages
{
I_English,
I_French,
I_Spanish,
I_German,
I_Italian,
I_Swedish,
I_MAX_NO_OF_LANGUAGES
}I_LANGUAGE;
extern char* LanguageDirNames[];
typedef enum playertypes
{
I_Marine,
I_Predator,
I_Alien,
}I_PLAYER_TYPE;
extern char* PlayerNames[];
typedef enum networktype
{
I_No_Network,
I_Host,
I_Peer,
I_DedicatedServer,
}I_NETWORK;
typedef enum gamedifficulty
{
I_Easy = 0,
I_Medium,
I_Hard,
I_Impossible,
I_MaxDifficulties
}I_HARDANUFF;
typedef enum environments
{
//#ifndef MPLAYER_DEMO
I_Gen1 = 0,
I_Gen2,
I_Gen3,
I_Gen4,
I_Medlab, // 5
I_Cmc1,
I_Cmc2,
I_Cmc3,
I_Cmc4,
I_Cmc5, // 10
I_Cmc6,
I_Sp1,
I_Sp2,
I_Sp3,
I_Rnd1, // 15
I_Rnd2,
I_Rnd3,
I_Rnd4,
I_Mps1,
I_Mps2, // 20
I_Mps3,
I_Mps4,
I_Surface,
I_Entrance,
#if PSX || Saturn
#else
I_Dml1, // 25- Vertigo.rif for Al
// #ifndef MPLAYER_DEMO
I_Dml2, // KJL 16:59:58 05/1/97 - fruitbat.rif for Al
I_Dml3, // KJL 16:59:58 05/19/97 - kipper.rif for George
I_Dml4, // KJL 16:59:58 05/19/97 - mu.rif for Jake
I_Dml5, // KJL 16:59:58 05/19/97 - mu.rif for Jake
I_Dml6, // 30- KJL 16:59:58 05/19/97 - mu.rif for Jake
I_Dml7, // KJL 16:59:58 05/19/97 - mu.rif for Jake
I_Dml8, // KJL 16:59:58 05/19/97 - mu.rif for Jake
I_Dml9, // KJL 16:59:58 05/19/97 - mu.rif for Jake
I_Dml10, // KJL 16:59:58 05/19/97 - mu.rif for Jake
// #endif
#endif
I_Num_Environments // 34
}I_AVP_ENVIRONMENTS;
extern char* LevelNames[];
#if SupportWindows95
#define GAME_NAME_LENGTH 30
#else
#define GAME_NAME_LENGTH 12
#endif
typedef struct avpgamedesc{
I_LANGUAGE Language;
I_GAME_MODE GameMode;
I_GAMEDRAW_MODE GameDrawMode;
int DatabaseAccessNum; // to make it easier to pass this around
I_PLAYER_TYPE PlayerType;
I_NETWORK Network;
I_HARDANUFF Difficulty;
I_AVP_ENVIRONMENTS CurrentEnv;
I_AVP_ENVIRONMENTS StartingEnv;
char GameName[GAME_NAME_LENGTH];
int GameVideoRequestMode;
int MenuVideoRequestMode;
int DestructTimer;
unsigned int ElapsedMinutes;
unsigned int ElapsedSeconds;
unsigned int ElapsedHours;
/* KJL 15:36:53 03/11/97 - set to zero
on death, pressing quit, etc. */
unsigned char MainLoopRunning :1;
/* set to 1 when player dies*/
unsigned char RestartLevel :1;
/* set to 1 if you manage to complete the level */
unsigned char LevelCompleted :1;
/* If network game, disable generators if unset */
unsigned char NetworkAIServer :1;
}AVP_GAME_DESC;
extern AVP_GAME_DESC AvP; /*game.c*/
extern DISPLAYBLOCK *Player;
/***************************************************************/
/************************ AVP high level control **************/
extern RECT_AVP screenRect;
/* KJL 15:42:23 10/02/96 - These two are mine. */
extern void MaintainPlayer(void);
extern void MaintainHUD(void);
/*********************************************************/
/*********************** PLAYER CONTROL STUFF ************/
extern int AnyUserInput();
extern int IDemandGoBackward();
extern int IDemandGoForward();
extern int IDemandTurnRight();
extern int IDemandTurnLeft();
//extern int IDemandLookUp(void);
//extern int IDemandLookDown(void);
//extern int IDemandTurnLeft(void);
//extern int IDemandTurnRight(void);
//extern int IDemandGoForward(void);
//extern int IDemandGoBackward(void);
//extern int IDemandFaster(void);
//extern int IDemandSideStep(void);
//extern int IDemandStop(void);
//extern int IDemandNextWeapon(void); /* KJL 11:45:40 10/07/96 */
//extern int IDemandPreviousWeapon(void); /* KJL 11:45:44 10/07/96 */
//extern int IDemandPickupItem(void);
//extern int IDemandDropItem(void);
//extern int IDemandOperate(void);
//extern int IDemandMenu(void);
//extern int IDemandChangeEnvironment(void);
/*************************************************
************* ENVIRONMENT STUFF
**************************************************/
/* some old funnier stuff*/
// kept as this struct so we can compile in environmnet
// changes
typedef struct environment_list_object{
char* main;
}ELO;
extern ELO* Env_List[];
extern int EnvToLoad;
extern void ChnageEnvironment();
extern void ChangeEnvironmentToEnv(I_AVP_ENVIRONMENTS);
extern int Destroy_CurrentEnvironment();
extern void LoadGameFromFile();
extern void SaveGameToFile();
extern void InitCharacter();
/*************************************************************/
/* KJL 15:42:46 10/02/96 - Okay, I don't use HUDGRAPHIC on the PC anymore and I suggest
you don't use it on your platform either 'cos it's a mess. (Sorry Roxby, no offense...) */
/************ HUD GRAPHIC STUFF *********************/
typedef struct
{
void* data; /* just about anything you feel like points to the file name*/
char* filename;
int xdest, ydest; /*screen x y*/
int width, height; /*depth and height of dest incase of shrink*/
RECT_AVP *srcRect;
int hg_flags;
}HUDGRAPHIC;
/* where to put the grahic*/
#define HGflag_NotInVRAM 0x0000001 /*saturn only*/
#define HGflag_LoadIntoVDP2 0x0000002 /*saturn only*/
#define HGflag_LoadIntoVDP1 0x0000004 /*saturn only*/
/* how to get the graphic */
#define HGflag_AlwaysLoadOffDisk 0x00000200 /*cd or HD*/
#define HGflag_LoadedIntoMemory 0x00000400 /*loaded into memory*/
/* source directory for the graphic */
#define HGflag_MenuDir 0x00010000
/********************************************************/
/************************ Menu Code ***************/
extern void ChooseLanguage(void);
extern void CharacterChoice(void);
extern void InitDataBaseMenus(void);
extern void DoMainMenu(void);
extern int UsingDataBase;
/* How many info screens will there be? */
#define MAXINFOSCREENS 10
/* How many different info screen backgrounds there may be*/
#define MAXBACKGROUNDS 10
/* How many overlay items can be in existence at a time */
#define MAXSCREENITEMS 10
#define NUM_CREDIT_SCREENS 2
extern HUDGRAPHIC Menu[];
extern HUDGRAPHIC CreditScreen[];
typedef enum
{
UNLIT,
LITUP,
} LIGHTSTATE;
/****************** MISC Game Externs ****/
extern MODULEMAPBLOCK TempModuleMap;
extern SHAPEHEADER** mainshapelist;
extern int memoryInitialisationFailure;
/*******************MISC extern functions ***/
extern void DealWithElapsedTime();
extern void FadeScreen(int colour, int screen, int rate);
extern volatile char StillFading;
#ifdef __cplusplus
};
#endif
#define GAMEDEF_INCLUDED
#endif

870
3dc/avp/Game.c Normal file
View file

@ -0,0 +1,870 @@
#include "3dc.h"
#include <math.h>
#include "inline.h"
#include "module.h"
#include "stratdef.h"
#include "gamedef.h"
#include "dynblock.h"
#include "dynamics.h"
#include "bh_types.h"
#include "bh_alien.h"
#include "pheromon.h"
#include "pfarlocs.h"
#include "bh_gener.h"
#include "pvisible.h"
#include "lighting.h"
#include "bh_pred.h"
#include "bh_lift.h"
#include "avpview.h"
#include "psnd.h"
#include "psndplat.h"
#include "particle.h"
#include "sfx.h"
#include "version.h"
#include "bh_RubberDuck.h"
#include "bh_marin.h"
#include "dxlog.h"
#include "avp_menus.h"
#include "avp_userprofile.h"
#include "davehook.h"
#include "CDTrackSelection.h"
#include "savegame.h"
// Added 18/11/97 by DHM: all hooks for my code
#define UseLocalAssert Yes
#include "ourasert.h"
/* KJL 09:47:33 03/19/97 - vision stuff for marine and predator.
Currently PC only because it will probably be implemented in a completely
different way on the consoles, so I won't worry the PSX guys for now.
*/
#if SupportWindows95
#include "vision.h"
#include "cheat.h"
#include "pldnet.h"
#endif
#if SupportWindows95 || Saturn
#include "kshape.h"
#include "krender.h"
#endif
/* KJL 16:00:13 11/22/96 - One of my evil experiments.... */
#define PENTIUM_PROFILING_ON 0
#define PROFILING_ON 0
#if PENTIUM_PROFILING_ON
#include "pentime.h"
#else
#if SupportWindows95
#define gProfileStart();
#define ProfileStop(x);
#endif
#endif
#define VERSION_DisableStartupMenus Yes
#define VERSION_DisableStartupCredits Yes
#include "avp_menus.h"
/******************
Extern Engine Varibles
******************/
extern void (*UpdateScreen[]) (void);
extern int VideoMode;
#if PSX
#else
extern void (*SetVideoMode[]) (void);
#endif
extern int FrameRate;
extern int NormalFrameTime;
extern int FrameRate;
extern int HWAccel;
extern int Resolution;
unsigned char Null_Name[8];
extern int PlaySounds;
/*******************************
EXPORTED GLOBALS
*******************************/
AVP_GAME_DESC AvP; /* game description */
char projectsubdirectory[] = {"avp/"};
int SavedFrameRate;
int SavedNormalFrameTime;
/* Andy 13/10/97
This global is set by any initialisation routine if a call to AllocateMem fails.
It can be checked during debugging after all game and level initialisation to see
if we have run out of memory.
*/
int memoryInitialisationFailure = 0;
/* start inits for the game*/
void ProcessSystemObjects();
void LevelSpecificChecks(void);
/*runtime maintainance*/
void FindObjectOfFocus();
void MaintainPlayer(void);
extern void CheckCDStatus(void);
/*********************************************
Init Game and Start Game
*********************************************/
void InitGame(void)
{
/*
RWH
InitGame is to be used only to set platform independent
varibles. It will be called ONCE only by the game
*/
/***** Set up default game settings*/
AvP.Language = I_English;
AvP.GameMode = I_GM_Playing;
AvP.Network = I_No_Network;
AvP.Difficulty = I_Medium;
// Modified by Edmond for Mplayer demo
#ifdef MPLAYER_DEMO
AvP.StartingEnv = I_Dml1;
#else
AvP.StartingEnv = I_Entrance;
#endif
AvP.CurrentEnv = AvP.StartingEnv;
AvP.PlayerType = I_Marine;
#if SupportWindows95
AvP.GameVideoRequestMode = VideoMode_DX_320x200x8; /* ignored */
if(HWAccel)
AvP.MenuVideoRequestMode = VideoMode_DX_640x480x15;
else
AvP.MenuVideoRequestMode = VideoMode_DX_640x480x8;
#endif
AvP.ElapsedSeconds = 0;
AvP.ElapsedMinutes = 0;
AvP.ElapsedHours = 0;
AvP.NetworkAIServer = 0;
// Added by DHM 18/11/97: Hook for my initialisation code:
DAVEHOOK_Init();
/* KJL 15:17:35 28/01/98 - Initialise console variables */
{
extern void CreateGameSpecificConsoleVariables(void);
extern void CreateGameSpecificConsoleCommands(void);
extern void CreateMoreGameSpecificConsoleVariables(void);
/* KJL 12:03:18 30/01/98 - Init console variables and commands */
CreateGameSpecificConsoleVariables();
CreateGameSpecificConsoleCommands();
/* Next one is CDF's */
CreateMoreGameSpecificConsoleVariables();
}
#if DEATHMATCH_DEMO
SetToMinimalDetailLevels();
#else
SetToDefaultDetailLevels();
#endif
}
extern void create_strategies_from_list ();
extern void AssignAllSBNames();
extern BOOL Current_Level_Requires_Mirror_Image();
void StartGame(void)
{
/* called whenever we start a game (NOT when we change */
/* environments - destroy anything from a previous game*/
/*
Temporarily disable sounds while loading. Largely to avoid
some irritating teletext sounds starting up
*/
int playSoundsStore=PlaySounds;
PlaySounds=0;
//get the cd to start again at the beginning of the play list.
ResetCDPlayForLevel();
ProcessSystemObjects();
create_strategies_from_list ();
AssignAllSBNames();
SetupVision();
/*-------------- Patrick 11/1/97 ----------------
Initialise visibility system and NPC behaviour
systems for new level.
-----------------------------------------------*/
InitObjectVisibilities();
InitPheromoneSystem();
BuildFarModuleLocs();
InitHive();
InitSquad();
InitialiseParticleSystem();
InitialiseSfxBlocks();
InitialiseLightElementSystem();
#if PSX
{
extern int RedOut;
RedOut=0;
}
#endif
AvP.DestructTimer=-1;
// DHM 18/11/97: I've put hooks for screen mode changes here for the moment:
DAVEHOOK_ScreenModeChange_Setup();
DAVEHOOK_ScreenModeChange_Cleanup();
/* KJL 11:46:42 30/03/98 - I thought it'd be nice to display the version details
when you start a game */
#if PREDATOR_DEMO||MARINE_DEMO||ALIEN_DEMO
#else
// GiveVersionDetails();
#endif
#if MIRRORING_ON
if(Current_Level_Requires_Mirror_Image())
{
CreatePlayersImageInMirror();
}
#endif
/* KJL 16:13:30 01/05/98 - rubber ducks! */
CreateRubberDucks();
CheckCDStatus();
{
extern int LeanScale;
if (AvP.PlayerType==I_Alien)
{
LeanScale=ONE_FIXED*3;
}
else
{
LeanScale=ONE_FIXED;
}
}
{
extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
extern int MotionTrackerScale;
MotionTrackerScale = DIV_FIXED(ScreenDescriptorBlock.SDB_Width,640);
}
// BuildInvSqrtTable();
InitialiseTriggeredFMVs();
CreateStarArray();
{
//check the containing modules for preplaced decals
void check_preplaced_decal_modules();
check_preplaced_decal_modules();
}
CurrentGameStats_Initialise();
MessageHistory_Initialise();
if (DISCOINFERNO_CHEATMODE || TRIPTASTIC_CHEATMODE)
{
MakeLightElement(&Player->ObWorld,LIGHTELEMENT_ROTATING);
}
//restore the play sounds setting
PlaySounds=playSoundsStore;
//make sure the visibilities are up to date
Global_VDB_Ptr->VDB_World = Player->ObWorld;
AllNewModuleHandler();
DoObjectVisibilities();
}
#define FIXED_MINUTE ONE_FIXED*60
void DealWithElapsedTime()
{
AvP.ElapsedSeconds += NormalFrameTime;
if(AvP.ElapsedSeconds >= FIXED_MINUTE)
{
AvP.ElapsedSeconds -= FIXED_MINUTE;
AvP.ElapsedMinutes ++;
}
if(AvP.ElapsedMinutes >= 60)
{
AvP.ElapsedMinutes -= 60;
AvP.ElapsedHours ++;
}
}
/**********************************************
Main Loop Game Functions
**********************************************/
void UpdateGame(void)
{
/* Read Keyboard, Keypad, Joystick etc. */
ReadUserInput();
/* DHM 18/11/97: hook for my code */
#if PENTIUM_PROFILING_ON
ProfileStart();
#endif
DAVEHOOK_Maintain();
#if PENTIUM_PROFILING_ON
ProfileStop("DAEMON");
#endif
/*-------------- Patrick 14/11/96 ----------------
call the pheronome system maintainence functions
-------------------------------------------------*/
#if PENTIUM_PROFILING_ON
ProfileStart();
#endif
PlayerPheromoneSystem();
AiPheromoneSystem();
#if PENTIUM_PROFILING_ON
ProfileStop("PHEROMONE");
#endif
/*-------------- Patrick 11/1/97 ----------------
Call the alien hive management function
-------------------------------------------------*/
DoHive();
DoSquad();
#if PROFILING_ON
ProfileStart();
#endif
ObjectBehaviours();
#if PROFILING_ON
ProfileStop("BEHAVS");
#endif
/* KJL 10:32:55 09/24/96 - update player */
#if PENTIUM_PROFILING_ON
ProfileStart();
#endif
MaintainPlayer();
#if PENTIUM_PROFILING_ON
ProfileStop("MNT PLYR");
#endif
/* KJL 12:54:08 21/04/98 - make sure the player's matrix is always normalised */
#if PENTIUM_PROFILING_ON
ProfileStart();
#endif
MNormalise(&(Player->ObStrategyBlock->DynPtr->OrientMat));
#if PENTIUM_PROFILING_ON
ProfileStop("MNorm");
#endif
/* netgame support: it seems necessary to collect all our messages here, as some
things depend on the player's behaviour running before anything else...
including firing the player's weapon */
#if SupportWindows95
if(AvP.Network != I_No_Network) NetCollectMessages();
#endif
RemoveDestroyedStrategyBlocks();
{
if(SaveGameRequest != SAVELOAD_REQUEST_NONE)
{
SaveGame();
}
else if(LoadGameRequest != SAVELOAD_REQUEST_NONE)
{
LoadSavedGame();
}
}
#if PENTIUM_PROFILING_ON
ProfileStart();
#endif
ObjectDynamics();
#if PENTIUM_PROFILING_ON
ProfileStop("DYNAMICS");
#endif
// now for the env teleports
if(RequestEnvChangeViaLift)
{
CleanUpLiftControl();
}
#if 0
Player->ObStrategyBlock->DynPtr->Position.vx = -71893;
Player->ObStrategyBlock->DynPtr->Position.vy = 36000;
Player->ObStrategyBlock->DynPtr->Position.vz = -52249;
Player->ObWorld.vx = -71893;
Player->ObWorld.vy = 36000;
Player->ObWorld.vz = -42249;
#endif
/* netgame support */
#if SupportWindows95
if(AvP.Network != I_No_Network) NetSendMessages();
/* KJL 11:50:18 03/21/97 - cheat modes */
HandleCheatModes();
#endif
#if PSX
HandleCheatModes();
#endif
/*------------Patrick 1/6/97---------------
New sound system
-------------------------------------------*/
#if PENTIUM_PROFILING_ON
ProfileStart();
#endif
if(playerPherModule)
{
PlatSetEnviroment(playerPherModule->m_sound_env_index,playerPherModule->m_sound_reverb);
}
SoundSys_Management();
DoPlayerSounds();
#if PENTIUM_PROFILING_ON
ProfileStop("SOUND SYS");
#endif
LevelSpecificChecks();
// NormaliseTest();
MessageHistory_Maintain();
if(AvP.LevelCompleted)
{
/*
If player is dead and has also completed level , then cancel
level completion.
*/
PLAYER_STATUS* PlayerStatusPtr = (PLAYER_STATUS*) Player->ObStrategyBlock->SBdataptr;
if(!PlayerStatusPtr->IsAlive)
{
AvP.LevelCompleted=0;
}
}
if (TRIPTASTIC_CHEATMODE)
{
extern int TripTasticPhase;
extern int CloakingPhase;
int a = GetSin(CloakingPhase&4095);
TripTasticPhase = MUL_FIXED(MUL_FIXED(a,a),128)+64;
}
if (JOHNWOO_CHEATMODE)
{
extern int LeanScale;
extern int TimeScale;
TimeScaleThingy();
//in john woo mode leanscale is dependent on the TimeScale
if (AvP.PlayerType==I_Alien)
{
LeanScale=ONE_FIXED*3;
}
else
{
LeanScale=ONE_FIXED;
}
LeanScale+=(ONE_FIXED-TimeScale)*5;
}
}
/* MODULE CALL BACK FUNCTIONS .... */
void ModuleObjectJustAllocated(MODULE *mptr)
{
}
void ModuleObjectAboutToBeDeallocated(MODULE *mptr)
{
}
void NewAndOldModules(int num_new, MODULE **m_new, int num_old, MODULE **m_old, char *m_currvis)
{
/* this is the important bit */
DoObjectVisibilities();
}
void LevelSpecificChecks(void)
{
/* ahem, level specific hacks might be more accurate */
}
extern void CheckCDStatus(void)
{
#if PREDATOR_DEMO||MARINE_DEMO||ALIEN_DEMO
// CDCommand_PlayLoop(2);
#endif
}
void TimeStampedMessage(char *stringPtr)
{
#if 0
static int time=0;
int t=timeGetTime();
LOGDXFMT(("%s %fs\n",stringPtr,(float)(t-time)/1000.0f ));
time = t;
#endif
}
#if 0
/* KJL 14:24:34 01/05/98 - Interesting floating point experiments
(UpdateGame is a useful point at which to test things) */
#define IEEE_MANT_BITS 23
#define IEEE_EXP_BITS 8
#define IEEE_SIGN_BITS 1
#define IEEE_EXP_BIAS 127
#define INVSQRT_TABLE_SEED_MANT_BITS 9
#define INVSQRT_TABLE_SEED_EXP_BITS 1
#define INVSQRT_TABLE_LENGTH_BITS (INVSQRT_TABLE_SEED_MANT_BITS + INVSQRT_TABLE_SEED_EXP_BITS)
#define INVSQRT_TABLE_NUM_ENTRIES (1 << INVSQRT_TABLE_LENGTH_BITS)
#define INVSQRT_TABLE_ENTRY_BITS 10
#define EXP_OF(x) (*(DWORD *)&(x) & 0x7f800000)
typedef struct _tab_in
{
unsigned int mpad: ((IEEE_MANT_BITS + 1) - INVSQRT_TABLE_LENGTH_BITS);
unsigned int lookup: INVSQRT_TABLE_LENGTH_BITS;
unsigned int epad: 7;
unsigned int spad: 1;
} tab_in;
typedef struct _tab_out
{
unsigned int mpad: (IEEE_MANT_BITS - INVSQRT_TABLE_ENTRY_BITS);
unsigned int lookup: INVSQRT_TABLE_ENTRY_BITS;
unsigned int epad: 8;
unsigned int spad: 1;
} tab_out;
union myfp
{
float fp;
// used to build the lookup table
tab_in tab_in_;
tab_out tab_out_;
};
unsigned int InvSqrtTab[INVSQRT_TABLE_NUM_ENTRIES];
void
BuildInvSqrtTable()
{
static int done = FALSE;
int i;
if (done) return;
done = TRUE;
for (i = 0; i < INVSQRT_TABLE_NUM_ENTRIES; i++)
{
union myfp fin, fout;
fin.fp = 1.0F;
fin.tab_in_.lookup = i;
// calculate the real value
fout.fp = 1.0F / (float)sqrt((double)fin.fp);
// Add the value to the table. 1.0 is special.
if (fout.fp == 1.0F)
InvSqrtTab[i] = 0x3FF << (IEEE_MANT_BITS - INVSQRT_TABLE_ENTRY_BITS);
else
InvSqrtTab[i] = fout.tab_out_.lookup << (IEEE_MANT_BITS -
INVSQRT_TABLE_ENTRY_BITS);
}
} // BuildInvSqrtTable()
float __stdcall
InverseSquareRoot(float x)
{
unsigned int index;
float r;
DWORD *dptr = (DWORD *)&r;
*(DWORD *)&r = ((((3 * IEEE_EXP_BIAS - 1) << IEEE_MANT_BITS) - EXP_OF(x)) >>
1) & 0x7f800000;
index = ((*(DWORD *)&x) >> (IEEE_MANT_BITS - INVSQRT_TABLE_ENTRY_BITS + 1))
& (INVSQRT_TABLE_NUM_ENTRIES - 1);
*dptr |= InvSqrtTab[index];
return r;
} // InverseSquareRoot()
void NormaliseTest(void)
{
int i;
float d;
int outside;
#if 0
i = 10000;
outside = 0;
ProfileStart();
while(i--)
{
VECTORCH v;
v.vx = (FastRandom()&65535)+1;
v.vy = (FastRandom()&65535)+1;
v.vz = (FastRandom()&65535)+1;
Normalise(&v);
{
int m = Magnitude(&v);
if (m<65530 || m>65540)
outside++;
}
}
ProfileStop("OLD NORM");
textprint("Outside Range: %d\n",outside);
i = 10000;
outside = 0;
ProfileStart();
while(i--)
{
VECTORCH v;
v.vx = (FastRandom()&65535)+1;
v.vy = (FastRandom()&65535)+1;
v.vz = (FastRandom()&65535)+1;
NewNormalise(&v);
{
int m = Magnitude(&v);
if (m<65536-50|| m>65536+50)
outside++;
}
}
ProfileStop("NEW NORM");
textprint("Outside Range: %d\n",outside);
#endif
i = 10000;
d=0;
while(--i)
{
int m;
VECTORCH v;
v.vx = FastRandom()&65535;
v.vy = FastRandom()&65535;
v.vz = FastRandom()&65535;
m = InverseMagnitude(&v);
d+=m;
}
#if 0
textprint("%f\n",d);
i = 10000;
d=0;
ProfileStart();
while(--i)
{
float m = sqrt((float)i);
d+=m;
}
ProfileStop("FSQRT");
#endif
textprint("%f\n",d);
}
static float fptmp;
static int itmp;
void IntToFloat(void);
# pragma aux IntToFloat = \
"fild itmp" \
"fstp fptmp";
/*
This macro makes usage of the above function easier and more elegant
*/
#define i2f(a, b) { \
itmp = (a); \
IntToFloat(); \
b = fptmp;}
int InverseMagnitude(VECTORCH *v)
{
int answer;
float m;
float mag;
{
float x,y,z;
x = v->vx;
y = v->vy;
z = v->vz;
mag = x*x+y*y+z*z;
}
{
unsigned int index;
float r;
DWORD *dptr = (DWORD *)&r;
*(DWORD *)&r = ((((3 * IEEE_EXP_BIAS - 1) << IEEE_MANT_BITS) - EXP_OF(mag)) >>
1) & 0x7f800000;
index = ((*(DWORD *)&mag) >> (IEEE_MANT_BITS - INVSQRT_TABLE_ENTRY_BITS + 1))
& (INVSQRT_TABLE_NUM_ENTRIES - 1);
*dptr |= InvSqrtTab[index];
m = 65536.0*r;
}
f2i(answer,m);
return answer;
}
void CurrentQNormalise(QUAT *q)
{
/* Normalise */
double oos = 1.0/(65536.0*65536.0);
double wsq = (double)q->quatw * (double)q->quatw * oos;
double xsq = (double)q->quatx * (double)q->quatx * oos;
double ysq = (double)q->quaty * (double)q->quaty * oos;
double zsq = (double)q->quatz * (double)q->quatz * oos;
double m = sqrt(wsq + xsq + ysq + zsq);
if(m == 0.0) m = 1.0; /* Just in case */
m = 1.0 / m;
q->quatw = (int) ((double)q->quatw * m);
q->quatx = (int) ((double)q->quatx * m);
q->quaty = (int) ((double)q->quaty * m);
q->quatz = (int) ((double)q->quatz * m);
}
void NewQNormalise(QUAT *q)
{
float nw = q->quatw;
float nx = q->quatx;
float ny = q->quaty;
float nz = q->quatz;
float m = sqrt(nw*nw+nx*nx+ny*ny+nz*nz);
if (!m) return;
m = 65536.0/m;
f2i(q->quatw,nw * m);
f2i(q->quatx,nx * m);
f2i(q->quaty,ny * m);
f2i(q->quatz,nz * m);
}
void QNormaliseTest(void)
{
QUAT q,q2;
int i;
for (i=0; i<10000; i++)
{
q.quatw = FastRandom()&65535;
q.quatx = FastRandom()&65535;
q.quaty = FastRandom()&65535;
q.quatz = FastRandom()&65535;
q2=q;
NewQNormalise(&q);
CurrentQNormalise(&q2);
if (q.quatw!=q2.quatw)
textprint("w%d ",q.quatw-q2.quatw);
if (q.quatx!=q2.quatx)
textprint("x%d ",q.quatx-q2.quatx);
if (q.quaty!=q2.quaty)
textprint("y%d ",q.quaty-q2.quaty);
if (q.quatz!=q2.quatz)
textprint("z%d ",q.quatz-q2.quatz);
}
}
#endif

5597
3dc/avp/HModel.c Normal file

File diff suppressed because it is too large Load diff

258
3dc/avp/HUDDEFS.H Normal file
View file

@ -0,0 +1,258 @@
/*KJL**************************************************************************
* HUDDEFS.H - *
* *
* this file contains all the prototypes of the platform-dependent functions *
* called in hud.c. *
**************************************************************************KJL*/
#ifndef _huddefs_h
#define _huddefs_h 1
#ifdef __cplusplus
extern "C" {
#endif
/*KJL****************************************************************************************
* D E F I N E S *
****************************************************************************************KJL*/
/*KJL**************************************************************************************
* Motion Tracker defines - Range is currently 30 metres. Don't worry about those casts to *
* floats, they're only there to ensure accuracy and are preprocessed away. For example, *
* 65536*65536 will probably cause an overflow in the preprocessor so I've used floats to *
* avoid this. *
**************************************************************************************KJL*/
#define MOTIONTRACKER_RANGE ((int)((float)30000*(float)GlobalScale))
#define MOTIONTRACKER_RANGE_SQUARED (MOTIONTRACKER_RANGE*MOTIONTRACKER_RANGE)
#define MOTIONTRACKER_SCALE (int)((65536.0*65536.0)/(float)MOTIONTRACKER_RANGE)
#define MOTIONTRACKER_SPEED (MUL_FIXED((65536*2),MotionTrackerSpeed))
#define MOTIONTRACKER_MAXBLIPS 10
#define MOTIONTRACKER_SMALLESTSCANLINESIZE 2200
typedef struct
{
int X;
int Y;
int Brightness;
} BLIP_TYPE;
/*KJL*************************************************
* Speed at which gunsight moves when smart-targeting *
*************************************************KJL*/
#define SMART_TARGETING_SPEED 4
#define SMART_TARGETING_RANGE 1000000
/*KJL*********************************************
* Numerical digits which occur in the marine HUD *
*********************************************KJL*/
enum MARINE_HUD_DIGIT
{
MARINE_HUD_MOTIONTRACKER_UNITS=0,
MARINE_HUD_MOTIONTRACKER_TENS,
MARINE_HUD_MOTIONTRACKER_HUNDREDS,
MARINE_HUD_MOTIONTRACKER_THOUSANDS,
MARINE_HUD_HEALTH_UNITS,
MARINE_HUD_HEALTH_TENS,
MARINE_HUD_HEALTH_HUNDREDS,
MARINE_HUD_ENERGY_UNITS,
MARINE_HUD_ENERGY_TENS,
MARINE_HUD_ENERGY_HUNDREDS,
MARINE_HUD_ARMOUR_UNITS,
MARINE_HUD_ARMOUR_TENS,
MARINE_HUD_ARMOUR_HUNDREDS,
MARINE_HUD_PRIMARY_AMMO_ROUNDS_UNITS,
MARINE_HUD_PRIMARY_AMMO_ROUNDS_TENS,
MARINE_HUD_PRIMARY_AMMO_ROUNDS_HUNDREDS,
MARINE_HUD_PRIMARY_AMMO_MAGAZINES_UNITS,
MARINE_HUD_PRIMARY_AMMO_MAGAZINES_TENS,
MARINE_HUD_SECONDARY_AMMO_ROUNDS_UNITS,
MARINE_HUD_SECONDARY_AMMO_ROUNDS_TENS,
MARINE_HUD_SECONDARY_AMMO_ROUNDS_HUNDREDS,
MARINE_HUD_SECONDARY_AMMO_MAGAZINES_UNITS,
MARINE_HUD_SECONDARY_AMMO_MAGAZINES_TENS,
MAX_NO_OF_MARINE_HUD_DIGITS
};
/*KJL***********************************************
* Numerical digits which occur in the predator HUD *
***********************************************KJL*/
enum PREDATOR_HUD_DIGIT
{
PREDATOR_HUD_ARMOUR_1,
PREDATOR_HUD_ARMOUR_2,
PREDATOR_HUD_ARMOUR_3,
PREDATOR_HUD_ARMOUR_4,
PREDATOR_HUD_ARMOUR_5,
PREDATOR_HUD_HEALTH_1,
PREDATOR_HUD_HEALTH_2,
PREDATOR_HUD_HEALTH_3,
PREDATOR_HUD_HEALTH_4,
PREDATOR_HUD_HEALTH_5,
/*
PREDATOR_HUD_THREATDISPLAY_1,
PREDATOR_HUD_THREATDISPLAY_2,
PREDATOR_HUD_THREATDISPLAY_3,
PREDATOR_HUD_THREATDISPLAY_4,
PREDATOR_HUD_THREATDISPLAY_5,
PREDATOR_HUD_THREATDISPLAY_6,
PREDATOR_HUD_THREATDISPLAY_7,
PREDATOR_HUD_THREATDISPLAY_8,
*/
MAX_NO_OF_PREDATOR_HUD_DIGITS
};
enum ALIEN_HUD_DIGIT
{
ALIEN_HUD_HEALTH_UNITS,
ALIEN_HUD_HEALTH_TENS,
ALIEN_HUD_HEALTH_HUNDREDS,
MAX_NO_OF_ALIEN_HUD_DIGITS
};
extern char ValueOfHUDDigit[];
enum GUNSIGHT_SHAPE
{
GUNSIGHT_CROSSHAIR=0,
GUNSIGHT_GREENBOX,
GUNSIGHT_REDBOX,
GUNSIGHT_REDDIAMOND,
MAX_NO_OF_GUNSIGHT_SHAPES
};
enum COMMON_HUD_DIGIT_ID
{
COMMON_HUD_DIGIT_HEALTH_UNITS,
COMMON_HUD_DIGIT_HEALTH_TENS,
COMMON_HUD_DIGIT_HEALTH_HUNDREDS,
COMMON_HUD_DIGIT_ARMOUR_UNITS,
COMMON_HUD_DIGIT_ARMOUR_TENS,
COMMON_HUD_DIGIT_ARMOUR_HUNDREDS,
MAX_NO_OF_COMMON_HUD_DIGITS
};
/*KJL****************************************************************************************
* P R O T O T Y P E S *
****************************************************************************************KJL*/
extern void PlatformSpecificInitMarineHUD(void);
/*KJL****************************************************************************************
* Okay. From now on everyone will call the fn above which loads and initialises ALL the gfx *
* required for a marine, eg. weapons, motion tracker stuff, gun sights, et al. *
* And sets up the riff mode RWH
****************************************************************************************KJL*/
extern void PlatformSpecificInitPredatorHUD(void);
/*KJL******************
* Ditto for predator. *
******************KJL*/
extern void PlatformSpecificInitAlienHUD(void);
/*RWH*****************
* Ditto for alien. *
******************REH*/
extern void PlatformSpecificExitingHUD(void);
/*KJL******************************************************************************************
* This is for the PSX (& possibly Saturn). Use this to pass your list of graphics to be drawn *
* to your GPU. *
******************************************************************************************KJL*/
extern void PlatformSpecificEnteringHUD(void);
/*KJL**************************************************
* Made to complement PlatformSpecificExitingHUD() fn. *
**************************************************KJL*/
extern void BLTMotionTrackerToHUD(int scanLineSize);
/*KJL******************************************************************************************
* draw motion tracker with its expanding scanline *
* 0 <= scanLineSize <= 65536 and denotes the scanline's on-screen radius (65536 = full size). *
******************************************************************************************KJL*/
extern void BLTMotionTrackerBlipToHUD(int x, int y, int brightness);
/*KJL********************************************************************
* -65536 <= x <= 65536, 0 <= y <= 65536, 0 <= brightness <= 65536 *
* (x=0,y=0) refers to the motiontracker's centre. (ie. centre hotspot) *
* brightness=65536 means brightest blip, 0 means darkest blip *
********************************************************************KJL*/
extern void BLTMarineNumericsToHUD(enum MARINE_HUD_DIGIT digitsToDraw);
extern void BLTPredatorNumericsToHUD(void);
extern void BLTAlienNumericsToHUD(void);
/*KJL********************************************************************
* Draws ALL the numeric digits (pertinent to the Marine) to the HUD. *
* *
* Ok, here's a quick explanation of how it's supposed to work: *
* *
* In hud.c there is a global array of chars called ValueOfHUDDigit[]. *
* The index of the array takes a value from the MARINE_HUD_DIGIT enum *
* which occurs later in this file, and each char in the array holds a *
* single digit, ie. a value from 0 to 9 inclusive. For example, *
* ValueOfHUDDigit[MARINE_HUD_HEALTH_TENS] holds the 'tens' digit of the *
* players health, say 5 if the players health was 152. So, the function *
* BLTMarineNumericsToHUD() simply goes through the array blitting each *
* digit to its correct position on screen. I do this by having another *
* array which holds the X,Y coords and font number for each digit, and *
* implementing a fn which takes the parameters (digit value,x,y,font) *
* and does the actual blitting. This is in avp/win95/ddplat.cpp. *
********************************************************************KJL*/
extern void BLTGunSightToScreen(int screenX, int screenY, enum GUNSIGHT_SHAPE gunsightShape);
/*KJL****************************************************************
* screenX & screenY are in pixels (scaled to SDB so should be okay) *
* (centre hotspot) *
* gunsightShape determines which sight to blit to screen. *
****************************************************************KJL*/
extern void InitHUD(void);
extern void BLTAlienOverlayToHUD(void);
/*KJL**************************
* Draw simple graphic overlay *
**************************KJL*/
extern void BLTPredatorOverlayToHUD(void);
/*KJL**************************
* Draw simple graphic overlay *
**************************KJL*/
extern void KillHUD(void);
/*KJL*********************
* Free memory of HUD gfx *
*********************KJL*/
/* KJL 11:00:22 05/20/97 - On-screen messaging system */
#define ON_SCREEN_MESSAGE_LIFETIME (ONE_FIXED*2)
extern void NewOnScreenMessage(unsigned char *messagePtr);
/*KJL********************************************************************
* The text pointed to by the messagePtr will be displayed on screen for *
* the time defined in ON_SCREEN_MESSAGE_LIFETIME. Any previous message *
* still being displayed will be overwritten. *
********************************************************************KJL*/
extern void DrawOnScreenMessage(unsigned char *messagePtr);
/*KJL*********************************************************************
* This is a platform specific fn which draws the required message to the *
* screen. Implemented in ddplat.cpp on the PC. *
*********************************************************************KJL*/
#ifdef __cplusplus
}; /* end of C-Linkage spec */
#endif
#endif /* one-time only guard */

762
3dc/avp/HUD_MAP.C Normal file
View file

@ -0,0 +1,762 @@
#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "dynblock.h"
#include "dynamics.h"
#include "hud_map.h"
#include "gamedef.h"
#define UseLocalAssert Yes
#include "ourasert.h"
#define PENTIUM_PROFILING_ON 0
#if PENTIUM_PROFILING_ON
#include "pentime.h"
#else
#define ProfileStart();
#define ProfileStop(x);
#endif
#define CircleRadius 99
#define DEFAULT_MAP_SCALE 400
#define DEFAULT_MAP_RADIUS 80
#define MAP_MAX_ZOOM 2000
#if PSX
#define MAP_MIN_ZOOM 200
#else
#define MAP_MIN_ZOOM 100
#endif
extern int sine[], cosine[]; /*Needed for GetSin and GetCos */
static void UpdateMapVisibilities(void);
static void DrawMapOverlay(void);
static void DrawPlayerArrow(void);
static int MapModuleCompletelyClipped(MODULE *modulePtr);
static void DrawMapModule(MODULE *modulePtr, enum MAP_COLOUR_ID colourID);
#if !PSX
static int ClipLine(VECTOR2D vertex[]);
static void MakeCircleLookUpTable(void);
static int PointInsideCircle(int x, int y);
#endif
static int IsHUDMapOn = 0;
extern int SetupPolygonAccessFromShapeIndex(int shapeIndex);
extern void RotateVertex(VECTOR2D *vertexPtr, int theta);
extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
extern DISPLAYBLOCK *Player;
extern int NormalFrameTime;
static int MapScale = DEFAULT_MAP_SCALE;
static int MapRadius = DEFAULT_MAP_RADIUS;
static int ClipScale;
static int MapCentreX;
static int MapCentreY;
static int MapMinX,MapMaxX;
static int MapMinY,MapMaxY;
/* point in the environment which is the centre of the map */
static VECTORCH MapWorldCentre;
static int MapOrientation;
void InitHUDMap(void)
{
#if !PSX
MakeCircleLookUpTable();
#endif
PlatformSpecificInitHUDMap();
#if PSX
MapCentreX = 128;
MapCentreY = 64;
#else
if (AvP.PlayerType == I_Alien)
{
MapCentreX = ScreenDescriptorBlock.SDB_Width-MapRadius*2;
MapCentreY = ScreenDescriptorBlock.SDB_Height-MapRadius*2;
}
else if (AvP.PlayerType == I_Predator)
{
MapCentreX = ScreenDescriptorBlock.SDB_Width-MapRadius;
MapCentreY = ScreenDescriptorBlock.SDB_Height/2-MapRadius;
}
else
{
MapCentreX = ScreenDescriptorBlock.SDB_Width-MapRadius;
MapCentreY = ScreenDescriptorBlock.SDB_Height-MapRadius;
}
#endif
}
void UpdateHUDMap(void)
{
/* update which modules are visible on the map */
UpdateMapVisibilities();
/* draw current map to screen */
ProfileStart();
if (IsHUDMapOn) DrawMapOverlay();
ProfileStop("MAP");
}
void HUDMapOn(void)
{
IsHUDMapOn=1;
}
void HUDMapOff(void)
{
IsHUDMapOn=0;
}
void HUDMapZoomOut(void)
{
MapScale-= (NormalFrameTime * MapScale) >> 17;
if (MapScale<MAP_MIN_ZOOM) MapScale=MAP_MIN_ZOOM;
}
void HUDMapZoomIn(void)
{
MapScale+= (NormalFrameTime * MapScale) >> 17;
if (MapScale>MAP_MAX_ZOOM) MapScale=MAP_MAX_ZOOM;
}
void HUDMapSmaller(void)
{
MapRadius-= NormalFrameTime>>10;
if (MapRadius<50) MapRadius=50;
}
void HUDMapLarger(void)
{
MapRadius+= NormalFrameTime>>10;
if (MapRadius>ScreenDescriptorBlock.SDB_Height/2)
MapRadius=ScreenDescriptorBlock.SDB_Height/2;
/* check it fits on screen... */
{
int allowedX = ScreenDescriptorBlock.SDB_Width - MapRadius;
if (MapCentreX>allowedX)
MapCentreX=allowedX;
else if (MapCentreX<MapRadius)
MapCentreX=MapRadius;
}
{
int allowedY = ScreenDescriptorBlock.SDB_Height - MapRadius;
if (MapCentreY>allowedY)
MapCentreY=allowedY;
else if (MapCentreY<MapRadius)
MapCentreY=MapRadius;
}
}
void HUDMapLeft(void)
{
MapCentreX -= NormalFrameTime>>9;
if (MapCentreX<MapRadius)
MapCentreX=MapRadius;
}
void HUDMapRight(void)
{
int allowedX = ScreenDescriptorBlock.SDB_Width - MapRadius;
MapCentreX += NormalFrameTime>>9;
if (MapCentreX>allowedX)
MapCentreX=allowedX;
}
void HUDMapUp(void)
{
MapCentreY -= NormalFrameTime>>9;
if (MapCentreY<MapRadius)
MapCentreY=MapRadius;
}
void HUDMapDown(void)
{
int allowedY = ScreenDescriptorBlock.SDB_Height - MapRadius;
MapCentreY += NormalFrameTime>>9;
if (MapCentreY>allowedY)
MapCentreY=allowedY;
}
void HUDMapWorldCentreLeft(void)
{
int mult = ((2000-MapScale) << 10)/500 + (1 << 10);
MapWorldCentre.vx -= (NormalFrameTime * mult) >> 19;
HUDMapClamp();
}
void HUDMapWorldCentreRight(void)
{
int mult = ((2000-MapScale) << 10)/500 + (1 << 10);
MapWorldCentre.vx += (NormalFrameTime * mult) >> 19;
HUDMapClamp();
}
void HUDMapWorldCentreUp(void)
{
int mult = ((2000-MapScale) << 10)/500 + (1 << 10);
MapWorldCentre.vy -= (NormalFrameTime * mult) >> 19;
HUDMapClamp();
}
void HUDMapWorldCentreDown(void)
{
int mult = ((2000-MapScale) << 10)/500 + (1 << 10);
MapWorldCentre.vy += (NormalFrameTime * mult) >> 19;
HUDMapClamp();
}
void HUDMapRotateRight(void)
{
MapOrientation += NormalFrameTime>>6;
if (MapOrientation>4095) MapOrientation -= 4096;
}
void HUDMapRotateLeft(void)
{
MapOrientation -= NormalFrameTime>>6;
if (MapOrientation<0) MapOrientation += 4096;
}
void HUDMapWorldForward(void)
{
int mult = ((2000-MapScale) << 6)/500 + (1 << 6);
MapWorldCentre.vx += (GetSin(MapOrientation) * mult) >> 16;
MapWorldCentre.vz += (GetCos(MapOrientation) * mult) >> 16;
HUDMapClamp();
}
void HUDMapWorldBackward(void)
{
int mult = ((2000-MapScale) << 6)/500 + (1 << 6);
MapWorldCentre.vx -= (GetSin(MapOrientation) * mult) >> 16;
MapWorldCentre.vz -= (GetCos(MapOrientation) * mult) >> 16;
HUDMapClamp();
}
void HUDMapWorldSlideLeft(void)
{
int mult = ((2000-MapScale) >> 2) + (1 << 6);
MapWorldCentre.vx -= (GetCos(MapOrientation) * mult) >> 16;
MapWorldCentre.vz += (GetSin(MapOrientation) * mult) >> 16;
HUDMapClamp();
}
void HUDMapWorldSlideRight(void)
{
int mult = ((2000-MapScale) >> 2) + (1 << 6);
MapWorldCentre.vx += (GetCos(MapOrientation) * mult) >> 16;
MapWorldCentre.vz -= (GetSin(MapOrientation) * mult) >> 16;
HUDMapClamp();
}
void HUDMapClamp()
{
if (MapWorldCentre.vx < MapMinX) MapWorldCentre.vx = MapMinX;
else if (MapWorldCentre.vx > MapMaxX) MapWorldCentre.vx = MapMaxX;
if (MapWorldCentre.vz < MapMinY) MapWorldCentre.vz = MapMinY;
else if (MapWorldCentre.vz > MapMaxY) MapWorldCentre.vz = MapMaxY;
}
void HUDMapResetDefaults(void)
{
MapWorldCentre = Player->ObWorld;
MapOrientation = Player->ObEuler.EulerY;
MapScale = DEFAULT_MAP_SCALE;
MapRadius = DEFAULT_MAP_RADIUS;
MapMaxX = Player->ObWorld.vx;
MapMinX = MapMaxX;
MapMaxY = Player->ObWorld.vz;
MapMinY = MapMaxY;
}
static void UpdateMapVisibilities(void)
{
extern int NumOnScreenBlocks;
extern DISPLAYBLOCK *OnScreenBlockList[];
int numberOfObjects = NumOnScreenBlocks;
while (numberOfObjects--)
{
DISPLAYBLOCK *objectPtr = OnScreenBlockList[numberOfObjects];
MODULE *modulePtr = objectPtr->ObMyModule;
if (modulePtr) /* Is object a module ? */
{
/* If module is not yet visible, flag it so that it is. */
if (!(modulePtr->m_flags & m_flag_visible_on_map))
modulePtr->m_flags |= m_flag_visible_on_map;
}
}
}
static void DrawMapOverlay(void)
{
extern SCENE Global_Scene;
extern int ModuleArraySize;
MODULE **moduleList;
int i;
PlatformSpecificEnteringHUDMap();
moduleList = MainSceneArray[Global_Scene]->sm_marray;
ClipScale = (MapScale*CircleRadius)/MapRadius;
#if !PSX
MapWorldCentre = Player->ObWorld;
MapOrientation = Player->ObEuler.EulerY;
#endif
for(i = 0; i < ModuleArraySize; i++)
{
MODULE *modulePtr = moduleList[i];
if (modulePtr)
{
if (modulePtr->m_flags & m_flag_visible_on_map)
{
int yCoord = MapWorldCentre.vy-modulePtr->m_world.vy;
if (!MapModuleCompletelyClipped(modulePtr))
{
if ((modulePtr->m_maxy < yCoord)||(modulePtr->m_miny > yCoord))
{
DrawMapModule(modulePtr,MAP_COLOUR_GREY);
}
else
{
DrawMapModule(modulePtr,MAP_COLOUR_WHITE);
}
}
}
}
}
DrawPlayerArrow();
PlatformSpecificExitingHUDMap();
return;
}
static int MapModuleCompletelyClipped(MODULE *modulePtr)
{
VECTOR2D offset;
/* calculate offset to map space */
offset.vx = modulePtr->m_world.vx-MapWorldCentre.vx;
offset.vy = modulePtr->m_world.vz-MapWorldCentre.vz;
/* test simple bounding boxes */
{
int maxX = MUL_FIXED(modulePtr->m_maxx + offset.vx,ClipScale);
if (maxX >= -CircleRadius)
{
int minX = MUL_FIXED(modulePtr->m_minx + offset.vx,ClipScale);
if (minX <= CircleRadius)
return 0;
}
}
{
int maxY = MUL_FIXED(modulePtr->m_maxy + offset.vy,ClipScale);
if (maxY >= -CircleRadius)
{
int minY = MUL_FIXED(modulePtr->m_miny + offset.vy,ClipScale);
if (minY <= CircleRadius)
return 0;
}
}
return 1;
}
static void DrawMapModule(MODULE *modulePtr, enum MAP_COLOUR_ID colourID)
{
MODULEMAPBLOCK *mapPtr = modulePtr->m_mapptr;
int numberOfItems;
VECTOR2D offset;
offset.vx = mapPtr->MapWorld.vx;
offset.vy = mapPtr->MapWorld.vz;
/* okay, let's setup the shape's data and access the first poly */
if (modulePtr->m_dptr)
{
numberOfItems = SetupPolygonAccess(modulePtr->m_dptr);
}
else if (mapPtr->MapMorphHeader)
{
numberOfItems = SetupPolygonAccessFromShapeIndex(mapPtr->MapMorphHeader->mph_frames->mf_shape2);
}
else
{
numberOfItems = SetupPolygonAccessFromShapeIndex(mapPtr->MapShape);
}
/* go through polys looking for those which intersect with the bounding box */
while(numberOfItems)
{
struct ColPolyTag polyPtr;
AccessNextPolygon();
GetPolygonNormal(&polyPtr);
if (polyPtr.PolyNormal.vy>-20000 && polyPtr.PolyNormal.vy<20000)
{
VECTOR2D vertex[6];
GetPolygonVertices(&polyPtr);
{
int highestVertex=0;
int nextHighestVertex=0;
int highestY=0x7fffffff;
int nextHighestY=0x7fffffff;
int v;
v = polyPtr.NumberOfVertices;
do
{
v--;
if (polyPtr.PolyPoint[v].vy<highestY)
{
highestVertex = v;
highestY = polyPtr.PolyPoint[v].vy;
}
}
while(v);
v = polyPtr.NumberOfVertices;
do
{
v--;
if (v==highestVertex) continue;
if (polyPtr.PolyPoint[v].vy<nextHighestY)
{
nextHighestVertex = v;
nextHighestY = polyPtr.PolyPoint[v].vy;
}
}
while(v);
vertex[0].vx = (polyPtr.PolyPoint[highestVertex].vx+offset.vx);
vertex[0].vy = (polyPtr.PolyPoint[highestVertex].vz+offset.vy);
vertex[1].vx = (polyPtr.PolyPoint[nextHighestVertex].vx+offset.vx);
vertex[1].vy = (polyPtr.PolyPoint[nextHighestVertex].vz+offset.vy);
if (vertex[0].vx > MapMaxX) MapMaxX = vertex[0].vx;
else if (vertex[0].vx < MapMinX) MapMinX = vertex[0].vx;
if (vertex[0].vy > MapMaxY) MapMaxY = vertex[0].vy;
else if (vertex[0].vy < MapMinY) MapMinY = vertex[0].vy;
if (vertex[1].vx > MapMaxX) MapMaxX = vertex[1].vx;
else if (vertex[1].vx < MapMinX) MapMinX = vertex[1].vx;
if (vertex[1].vy > MapMaxY) MapMaxY = vertex[1].vy;
else if (vertex[1].vy < MapMinY) MapMinY = vertex[1].vy;
vertex[0].vx -= MapWorldCentre.vx;
vertex[0].vy -= MapWorldCentre.vz;
vertex[1].vx -= MapWorldCentre.vx;
vertex[1].vy -= MapWorldCentre.vz;
}
#if PSX
// PSX has HUD map lines clipped to screen coordinates in DrawHUDMapLine
RotateVertex(&vertex[0],MapOrientation);
vertex[0].vx = MUL_FIXED(vertex[0].vx,MapScale);
vertex[0].vy = MUL_FIXED(vertex[0].vy,MapScale);
vertex[0].vx = MapCentreX + vertex[0].vx;
vertex[0].vy = MapCentreY - vertex[0].vy;
RotateVertex(&vertex[1],MapOrientation);
vertex[1].vx = MUL_FIXED(vertex[1].vx,MapScale);
vertex[1].vy = MUL_FIXED(vertex[1].vy,MapScale);
vertex[1].vx = MapCentreX + vertex[1].vx;
vertex[1].vy = MapCentreY - vertex[1].vy;
DrawHUDMapLine(&vertex[0],&vertex[1],colourID);
#else
if (ClipLine(vertex))
{
RotateVertex(&vertex[0],Player->ObEuler.EulerY);
vertex[0].vx = MUL_FIXED(vertex[0].vx,MapScale);
vertex[0].vy = MUL_FIXED(vertex[0].vy,MapScale);
vertex[0].vx = MapCentreX + vertex[0].vx;
vertex[0].vy = MapCentreY - vertex[0].vy;
RotateVertex(&vertex[1],Player->ObEuler.EulerY);
vertex[1].vx = MUL_FIXED(vertex[1].vx,MapScale);
vertex[1].vy = MUL_FIXED(vertex[1].vy,MapScale);
vertex[1].vx = MapCentreX + vertex[1].vx;
vertex[1].vy = MapCentreY - vertex[1].vy;
DrawHUDMapLine(&vertex[0],&vertex[1],colourID);
}
#endif
}
numberOfItems--;
}
}
static void DrawPlayerArrow(void)
{
VECTOR2D vertex1,vertex2;
int arrowLength;
#if PSX
VECTOR2D vertex3;
arrowLength = 475;
vertex1.vx = 0;
vertex1.vy = arrowLength;
RotateVertex(&vertex1,4096-Player->ObEuler.EulerY);
vertex1.vx += Player->ObWorld.vx - MapWorldCentre.vx;
vertex1.vy += Player->ObWorld.vz - MapWorldCentre.vz;
RotateVertex(&vertex1,MapOrientation);
vertex1.vx = MUL_FIXED(vertex1.vx,MapScale);
vertex1.vy = MUL_FIXED(vertex1.vy,MapScale);
vertex1.vx = MapCentreX + vertex1.vx;
vertex1.vy = MapCentreY - vertex1.vy;
vertex3.vx = vertex1.vx;
vertex3.vy = vertex1.vy;
vertex2.vx = 0;
vertex2.vy = -arrowLength;
RotateVertex(&vertex2,4096-Player->ObEuler.EulerY);
vertex2.vx += Player->ObWorld.vx - MapWorldCentre.vx;
vertex2.vy += Player->ObWorld.vz - MapWorldCentre.vz;
RotateVertex(&vertex2,MapOrientation);
vertex2.vx = MUL_FIXED(vertex2.vx,MapScale);
vertex2.vy = MUL_FIXED(vertex2.vy,MapScale);
vertex2.vx = MapCentreX + vertex2.vx;
vertex2.vy = MapCentreY - vertex2.vy;
DrawHUDMapLine(&vertex1,&vertex2,MAP_COLOUR_RED);
vertex2.vx = -arrowLength;
vertex2.vy = 0;
RotateVertex(&vertex2,4096-Player->ObEuler.EulerY);
vertex2.vx += Player->ObWorld.vx - MapWorldCentre.vx;
vertex2.vy += Player->ObWorld.vz - MapWorldCentre.vz;
RotateVertex(&vertex2,MapOrientation);
vertex2.vx = MUL_FIXED(vertex2.vx,MapScale);
vertex2.vy = MUL_FIXED(vertex2.vy,MapScale);
vertex2.vx = MapCentreX + vertex2.vx;
vertex2.vy = MapCentreY - vertex2.vy;
vertex1.vx = vertex3.vx;
vertex1.vy = vertex3.vy;
DrawHUDMapLine(&vertex1,&vertex2,MAP_COLOUR_RED);
vertex2.vx = arrowLength;
vertex2.vy = 0;
RotateVertex(&vertex2,4096-Player->ObEuler.EulerY);
vertex2.vx += Player->ObWorld.vx - MapWorldCentre.vx;
vertex2.vy += Player->ObWorld.vz - MapWorldCentre.vz;
RotateVertex(&vertex2,MapOrientation);
vertex2.vx = MUL_FIXED(vertex2.vx,MapScale);
vertex2.vy = MUL_FIXED(vertex2.vy,MapScale);
vertex2.vx = MapCentreX + vertex2.vx;
vertex2.vy = MapCentreY - vertex2.vy;
vertex1.vx = vertex3.vx;
vertex1.vy = vertex3.vy;
DrawHUDMapLine(&vertex1,&vertex2,MAP_COLOUR_RED);
vertex1.vx = MapCentreX;
vertex1.vy = MapCentreY;
vertex2.vx = MapCentreX;
vertex2.vy = MapCentreY;
DrawHUDMapLine (&vertex1,&vertex2,MAP_COLOUR_RED);
#else
arrowLength = MUL_FIXED(300,MapScale);
vertex1.vx = MapCentreX;
vertex1.vy = MapCentreY - arrowLength;
vertex2.vx = MapCentreX;
vertex2.vy = MapCentreY + arrowLength;
DrawHUDMapLine(&vertex1,&vertex2,MAP_COLOUR_RED);
vertex2.vx = MapCentreX - arrowLength;
vertex2.vy = MapCentreY;
DrawHUDMapLine(&vertex1,&vertex2,MAP_COLOUR_RED);
vertex2.vx = MapCentreX + arrowLength;
DrawHUDMapLine(&vertex1,&vertex2,MAP_COLOUR_RED);
#endif
}
#if !PSX
static int ClipLine(VECTOR2D vertex[])
{
int vertex0Inside=0,vertex1Inside=0;
if (PointInsideCircle(vertex[0].vx,vertex[0].vy))
vertex0Inside = 1;
if (PointInsideCircle(vertex[1].vx,vertex[1].vy))
vertex1Inside = 1;
/* line completely in */
if (vertex0Inside && vertex1Inside)
return 1;
/* line completely out */
if (!vertex0Inside && !vertex1Inside)
return 0;
/* crosses clipping boundary */
{
VECTOR2D minBound,maxBound;
VECTOR2D newGuess;
int searchCounter = 10;
if (vertex0Inside)
{
minBound = vertex[0];
maxBound = vertex[1];
}
else
{
minBound = vertex[1];
maxBound = vertex[0];
}
do
{
int pointInside;
newGuess.vx = (minBound.vx + maxBound.vx)/2;
newGuess.vy = (minBound.vy + maxBound.vy)/2;
pointInside = PointInsideCircle(newGuess.vx,newGuess.vy);
if(pointInside == 0)
{
maxBound = newGuess;
}
else if (pointInside == -1)
{
minBound = newGuess;
}
else break;
}
while(searchCounter--);
if (vertex0Inside)
{
vertex[1] = newGuess;
}
else
{
vertex[0] = newGuess;
}
}
return 1;
}
static char CircleXCoord[CircleRadius+1];
static void MakeCircleLookUpTable(void)
{
int y=CircleRadius;
extern unsigned char *ScreenBuffer;
do
{
CircleXCoord[y] = SqRoot32(CircleRadius*CircleRadius-y*y);
}
while(y--);
}
static int PointInsideCircle(int x, int y)
{
if (y<0) y=-y;
y = MUL_FIXED(y,ClipScale);
if (y>CircleRadius) return 0;
if (x<0) x=-x;
x = MUL_FIXED(x,ClipScale);
if (CircleXCoord[y]>x) return -1;
if (CircleXCoord[y]<x) return 0;
return 1;
}
#endif

51
3dc/avp/HUD_MAP.H Normal file
View file

@ -0,0 +1,51 @@
/* KJL 11:14:25 04/25/97 - hud_map.h */
/* platform independent prototypes */
extern void InitHUDMap(void);
extern void UpdateHUDMap(void);
/* fns to change the map display */
extern void HUDMapOn(void);
extern void HUDMapOff(void);
extern void HUDMapZoomIn(void);
extern void HUDMapZoomOut(void);
extern void HUDMapSmaller(void);
extern void HUDMapLarger(void);
extern void HUDMapLeft(void);
extern void HUDMapRight(void);
extern void HUDMapUp(void);
extern void HUDMapDown(void);
extern void HUDMapWorldCentreLeft(void);
extern void HUDMapWorldCentreRight(void);
extern void HUDMapWorldCentreUp(void);
extern void HUDMapWorldCentreDown(void);
extern void HUDMapResetDefaults(void);
extern void HUDMapRotateLeft(void);
extern void HUDMapRotateRight(void);
extern void HUDMapWorldForward(void);
extern void HUDMapWorldBackward(void);
extern void HUDMapWorldSlideLeft(void);
extern void HUDMapWorldSlideRight(void);
void HUDMapClamp(void);
/* platform specific stuff */
enum MAP_COLOUR_ID
{
MAP_COLOUR_WHITE,
MAP_COLOUR_GREY,
MAP_COLOUR_RED
};
extern void PlatformSpecificInitHUDMap(void);
extern void PlatformSpecificEnteringHUDMap(void);
extern void PlatformSpecificExitingHUDMap(void);
/* This is called once from StartGame */
extern void DrawHUDMapLine(VECTOR2D *vertex1, VECTOR2D *vertex2, enum MAP_COLOUR_ID colourID);

2336
3dc/avp/Hud.c Normal file

File diff suppressed because it is too large Load diff

36
3dc/avp/INVENTRY.H Normal file
View file

@ -0,0 +1,36 @@
/*KJL*****************************************************
* INVENTRY.H - contains externs to the fns in INVENTRY.C *
*****************************************************KJL*/
/*KJL****************************************************************************************
* P R O T O T Y P E S *
****************************************************************************************KJL*/
extern void InitialisePlayersInventory(PLAYER_STATUS *playerStatusPtr);
extern void MaintainPlayersInventory(void);
/*-------------------------------Patrick 11/3/97--------------------------------
Protoypes for a couple of little functions: see inventry.c for details...
------------------------------------------------------------------------------*/
extern void SetPlayerSecurityClearance(STRATEGYBLOCK *sbPtr, unsigned int securityLevel);
extern int ReturnPlayerSecurityClearance(STRATEGYBLOCK *sbPtr, unsigned int securityLevel);
//structure for starting equipment information loaded from rif files
typedef struct player_starting_equipment
{
unsigned int marine_jetpack :1;
unsigned int predator_pistol :1;
unsigned int predator_plasmacaster :1;
unsigned int predator_disc :1;
unsigned int predator_medicomp :1;
unsigned int predator_grappling_hook :1;
int predator_num_spears;
}PLAYER_STARTING_EQUIPMENT;
extern PLAYER_STARTING_EQUIPMENT StartingEquipment;
#define PISTOL_INFINITE_AMMO (netGameData.pistolInfiniteAmmo)

1882
3dc/avp/Inventry.c Normal file

File diff suppressed because it is too large Load diff

109
3dc/avp/LANGUAGE.C Normal file
View file

@ -0,0 +1,109 @@
/*KJL***************************************
* Language Internationalization Code *
***************************************KJL*/
#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "gamedef.h"
#include "langenum.h"
#include "language.h"
#include "huffman.hpp"
#if SupportWindows95
// DHM 12 Nov 97: hooks for C++ string handling code:
#include "strtab.hpp"
#endif
#define UseLocalAssert Yes
#include "ourasert.h"
#include "avp_menus.h"
#ifdef AVP_DEBUG_VERSION
#define USE_LANGUAGE_TXT 0
#else
#define USE_LANGUAGE_TXT 1
#endif
static char EmptyString[]="";
static char *TextStringPtr[MAX_NO_OF_TEXTSTRINGS]={&EmptyString,};
static char *TextBufferPtr;
void InitTextStrings(void)
{
char *textPtr;
int i;
/* language select here! */
GLOBALASSERT(AvP.Language>=0);
GLOBALASSERT(AvP.Language<I_MAX_NO_OF_LANGUAGES);
#if MARINE_DEMO
TextBufferPtr = LoadTextFile("menglish.txt");
#elif ALIEN_DEMO
TextBufferPtr = LoadTextFile("aenglish.txt");
#elif USE_LANGUAGE_TXT
TextBufferPtr = LoadTextFile("language.txt");
#else
TextBufferPtr = LoadTextFile(LanguageFilename[AvP.Language]);
#endif
LOCALASSERT(TextBufferPtr);
if (!strncmp (TextBufferPtr, "REBCRIF1", 8))
{
textPtr = (char*)HuffmanDecompress((HuffmanPackage*)(TextBufferPtr));
DeallocateMem(TextBufferPtr);
TextBufferPtr=textPtr;
}
else
{
textPtr = TextBufferPtr;
}
#if SupportWindows95
AddToTable( &EmptyString );
#endif
for (i=1; i<MAX_NO_OF_TEXTSTRINGS; i++)
{
/* scan for a quote mark */
while (*textPtr++ != '"');
/* now pointing to a text string after quote mark*/
TextStringPtr[i] = textPtr;
/* scan for a quote mark */
while (*textPtr != '"')
{
textPtr++;
}
/* change quote mark to zero terminator */
*textPtr = 0;
#if SupportWindows95
AddToTable( TextStringPtr[i] );
#endif
}
}
void KillTextStrings(void)
{
UnloadTextFile(LanguageFilename[AvP.Language],TextBufferPtr);
#if SupportWindows95
UnloadTable();
#endif
}
char *GetTextString(enum TEXTSTRING_ID stringID)
{
LOCALASSERT(stringID<MAX_NO_OF_TEXTSTRINGS);
return TextStringPtr[stringID];
}

42
3dc/avp/LANGUAGE.H Normal file
View file

@ -0,0 +1,42 @@
#ifndef _language_h_
#define _language_h_ 1
/* KJL 11:54:21 05/02/97 - language.h */
#include "langenum.h"
#define ENGLISH_TEXT_FILENAME "ENGLISH.TXT"
extern unsigned char *LanguageFilename[];
extern void InitTextStrings(void);
/*KJL***************************************************************
* Initialization to be called ONCE right at the start of the game. *
***************************************************************KJL*/
extern void KillTextStrings(void);
/*KJL********************************************************
* Free memory etc, to be called ONCE on exit from the game. *
********************************************************KJL*/
extern char *GetTextString(enum TEXTSTRING_ID stringID);
/*KJL**********************************************************
* This function returns a pointer to a null terminated string *
* which is described by its enumeration value, as defined in *
* the header file langenum.h. *
**********************************************************KJL*/
extern char *LoadTextFile(char *filename);
/*KJL*****************************************************
* Platform specific function, which loads the named file *
* and returns a pointer to the start of the file's data. *
*****************************************************KJL*/
extern void UnloadTextFile(char *filename, char *bufferPtr);
/*KJL**********************************************************
* Platform specific function, which unloads the named file *
* and frees the memory pointed to by the bufferPtr. You may *
* not need the filename, but I'm passing it for completeness. *
**********************************************************KJL*/
#endif

730
3dc/avp/LIGHTING.C Normal file
View file

@ -0,0 +1,730 @@
/*KJL***************************************************
* lighting.c - a lighting interface for simple effects *
***************************************************KJL*/
#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "stratdef.h"
#include "gamedef.h"
#include "bh_types.h"
#include "bh_weap.h"
#include "lighting.h"
#include "particle.h"
#include "dynamics.h"
#define UseLocalAssert Yes
#include "ourasert.h"
static VECTORCH RotatingLightPosition;
extern int CloakingPhase;
extern int NormalFrameTime;
extern VIEWDESCRIPTORBLOCK *Global_VDB_Ptr;
extern int LightScale;
void AddLightingEffectToObject(DISPLAYBLOCK *objectPtr, enum LIGHTING_EFFECTS_ID lfxID)
{
LIGHTBLOCK *lightPtr;
lightPtr = AddLightBlock(objectPtr, NULL);
if (!lightPtr) return;
switch(lfxID)
{
case LFX_EXPLOSION:
{
/* brightness */
lightPtr->LightBright = ONE_FIXED*4;
/* flags */
lightPtr->LightFlags = LFlag_Omni;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = EXPLOSION_LIGHT_RANGE;
lightPtr->RedScale=255*256;
lightPtr->GreenScale=120*256;
lightPtr->BlueScale=0;
#if PSX
lightPtr->LightColour.r=255;
lightPtr->LightColour.g=120;
lightPtr->LightColour.b=0;
#endif
break;
}
case LFX_BIGEXPLOSION:
{
/* brightness */
lightPtr->LightBright = ONE_FIXED << 2;
/* flags */
lightPtr->LightFlags = LFlag_Omni;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = EXPLOSION_LIGHT_RANGE;
lightPtr->RedScale=255*256;
lightPtr->GreenScale=120*256;
lightPtr->BlueScale=0;
#if PSX
lightPtr->LightColour.r=255;
lightPtr->LightColour.g=120;
lightPtr->LightColour.b=0;
#endif
break;
}
case LFX_MUZZLEFLASH:
{
/* brightness */
lightPtr->LightBright = 65536 - (FastRandom()&32767);
/* flags */
lightPtr->LightFlags = LFlag_Omni|LFlag_Deallocate;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
#if 0
lightPtr->LightRange = 5000; /* ? */
lightPtr->RedScale=255*256;
lightPtr->GreenScale=192*256;
lightPtr->BlueScale=128*256;
#else
lightPtr->LightRange = 10000; /* ? */
lightPtr->RedScale=255*256;
lightPtr->GreenScale=230*256;
lightPtr->BlueScale=200*256;
#endif
#if PSX
lightPtr->LightColour.r=255;
lightPtr->LightColour.g=192;
lightPtr->LightColour.b=128;
#endif
break;
}
case LFX_PARTICLECANNON:
{
/* brightness */
lightPtr->LightBright = 65536 - (FastRandom()&32767);
/* flags */
lightPtr->LightFlags = LFlag_Omni|LFlag_Deallocate;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = 10000; /* ? */
lightPtr->RedScale=255*256;
lightPtr->GreenScale=32*256;
lightPtr->BlueScale=0;
#if PSX
lightPtr->LightColour.r=255;
lightPtr->LightColour.g=32;
lightPtr->LightColour.b=0;
#endif
break;
}
case LFX_ROCKETJET:
{
/* brightness */
lightPtr->LightBright = ONE_FIXED*3/4;
/* flags */
lightPtr->LightFlags = LFlag_Omni|LFlag_CosAtten;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = 5000; /* ? */
lightPtr->RedScale=255*256;
lightPtr->GreenScale=255*256;
lightPtr->BlueScale=128*256;
#if PSX
lightPtr->LightColour.r=255;
lightPtr->LightColour.g=255;
lightPtr->LightColour.b=128;
#endif
break;
}
case LFX_FLARE:
{
/* brightness */
lightPtr->LightBright = 0;
/* flags */
lightPtr->LightFlags = LFlag_Omni;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = 10000; /* ? */
lightPtr->RedScale=255*256;
lightPtr->GreenScale=200*256;
lightPtr->BlueScale=255*256;
#if PSX
lightPtr->LightColour.r=255;
lightPtr->LightColour.g=64;
lightPtr->LightColour.b=255;
#endif
break;
}
case LFX_XENO_FIRING:
{
/* brightness */
lightPtr->LightBright = 226100;
/* flags */
lightPtr->LightFlags = LFlag_Omni|LFlag_Deallocate;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = 5000; /* ? */
lightPtr->RedScale=255*256;
lightPtr->GreenScale=64*256;
lightPtr->BlueScale=255*256;
#if PSX
lightPtr->LightColour.r=64;
lightPtr->LightColour.g=64;
lightPtr->LightColour.b=255;
#endif
break;
}
case LFX_PLASMA_BOLT:
{
/* brightness */
lightPtr->LightBright = ONE_FIXED/4;
/* flags */
lightPtr->LightFlags = LFlag_Omni|LFlag_CosAtten;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = 10000;
lightPtr->RedScale=200*256;
lightPtr->GreenScale=255*256;
lightPtr->BlueScale=255*256;
break;
}
case LFX_OBJECTONFIRE:
{
/* brightness */
lightPtr->LightBright = 16484 - (FastRandom()&4095);
/* flags */
lightPtr->LightFlags = LFlag_Omni|LFlag_Deallocate|LFlag_Thermal;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = 10000;
lightPtr->RedScale=255*256;
lightPtr->GreenScale=110*256;
lightPtr->BlueScale=50*256;
break;
}
case LFX_SPEARGUNBOLT:
{
/* Just an experiment. */
/* brightness */
lightPtr->LightBright = ONE_FIXED/4;
/* flags */
lightPtr->LightFlags = LFlag_Omni|LFlag_CosAtten;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = 10000;
lightPtr->RedScale=255*256;
lightPtr->GreenScale=255*256;
lightPtr->BlueScale=255*256;
break;
}
}
}
void LightBlockDeallocation(void)
{
extern int NumActiveBlocks;
extern DISPLAYBLOCK *ActiveBlockList[];
int numblocks = NumActiveBlocks;
while(numblocks)
{
DISPLAYBLOCK *dptr = ActiveBlockList[--numblocks];
int numlights = dptr->ObNumLights;
while(numlights)
{
LIGHTBLOCK *lightPtr = dptr->ObLights[--numlights];
if(lightPtr->LightFlags & LFlag_Deallocate)
DeleteLightBlock(lightPtr, dptr);
}
}
}
/*KJL******************************
* *
* LIGHT ELEMENT CODE *
* *
******************************KJL*/
#define MAX_NO_OF_LIGHTELEMENTS 500
LIGHTELEMENT LightElementStorage[MAX_NO_OF_LIGHTELEMENTS];
int NumActiveLightElements;
void InitialiseLightElementSystem(void)
{
NumActiveLightElements = 0;
}
static LIGHTELEMENT* AllocateLightElement(void)
{
LIGHTELEMENT *lightElementPtr = 0; /* Default to null ptr */
if (NumActiveLightElements != MAX_NO_OF_LIGHTELEMENTS)
{
lightElementPtr = &LightElementStorage[NumActiveLightElements];
NumActiveLightElements++;
}
else
{
/* unable to allocate a lightElement */
}
return lightElementPtr;
}
static void DeallocateLightElement(LIGHTELEMENT *lightElementPtr)
{
/* is pointer within array? */
LOCALASSERT(lightElementPtr>=LightElementStorage);
LOCALASSERT(lightElementPtr<=&LightElementStorage[MAX_NO_OF_LIGHTELEMENTS-1]);
NumActiveLightElements--;
*lightElementPtr = LightElementStorage[NumActiveLightElements];
}
void MakeLightElement(VECTORCH *positionPtr, enum LIGHTELEMENT_BEHAVIOUR_ID behaviourID)
{
LIGHTELEMENT *lightElementPtr = AllocateLightElement();
LIGHTBLOCK *lightPtr = &(lightElementPtr->LightBlock);
/* if we failed to make an element, get the hell out of here */
if (!lightElementPtr) return;
lightElementPtr->BehaviourID = behaviourID;
lightElementPtr->LightBlock.LightWorld = *positionPtr;
lightElementPtr->LifeTime=ONE_FIXED;
switch (behaviourID)
{
case LIGHTELEMENT_ROTATING:
{
RotatingLightPosition = *positionPtr;
break;
}
case LIGHTELEMENT_ALIEN_TEETH:
{
lightPtr->LightBright = ONE_FIXED/2;
/* flags */
lightPtr->LightFlags = LFlag_Omni;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = 200;
lightPtr->RedScale= ONE_FIXED;
lightPtr->GreenScale= ONE_FIXED;
lightPtr->BlueScale= ONE_FIXED;
{
VECTORCH position;
position.vx = MUL_FIXED(200,GetSin((CloakingPhase)&4095));
position.vy = MUL_FIXED(200,GetCos((CloakingPhase)&4095));
position.vz = 80+MUL_FIXED(50,GetCos((CloakingPhase/2)&4095));
{
MATRIXCH myMat = Global_VDB_Ptr->VDB_Mat;
TransposeMatrixCH(&myMat);
RotateVector(&(position), &(myMat));
position.vx += Global_VDB_Ptr->VDB_World.vx;
position.vy += Global_VDB_Ptr->VDB_World.vy;
position.vz += Global_VDB_Ptr->VDB_World.vz;
}
lightElementPtr->LightBlock.LightWorld = position;
}
lightElementPtr->LifeTime = 0;
break;
}
case LIGHTELEMENT_ALIEN_TEETH2:
{
lightPtr->LightBright = ONE_FIXED/2;
/* flags */
lightPtr->LightFlags = LFlag_Omni;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = 200;
lightPtr->RedScale= ONE_FIXED;
lightPtr->GreenScale= ONE_FIXED;
lightPtr->BlueScale= ONE_FIXED;
{
VECTORCH position;
position.vx = MUL_FIXED(200,GetSin((CloakingPhase/3+2048)&4095));
position.vy = MUL_FIXED(200,GetCos((CloakingPhase/3+2048)&4095));
position.vz = 80+MUL_FIXED(50,GetCos((CloakingPhase/2+2048)&4095));
{
MATRIXCH myMat = Global_VDB_Ptr->VDB_Mat;
TransposeMatrixCH(&myMat);
RotateVector(&(position), &(myMat));
position.vx += Global_VDB_Ptr->VDB_World.vx;
position.vy += Global_VDB_Ptr->VDB_World.vy;
position.vz += Global_VDB_Ptr->VDB_World.vz;
}
lightElementPtr->LightBlock.LightWorld = position;
}
lightElementPtr->LifeTime = 0;
break;
}
}
}
void HandleLightElementSystem(void)
{
int i = NumActiveLightElements;
LIGHTELEMENT *lightElementPtr = LightElementStorage;
while(i--)
{
LIGHTBLOCK *lightPtr = &(lightElementPtr->LightBlock);
switch(lightElementPtr->BehaviourID)
{
case LIGHTELEMENT_MOLTENMETAL:
{
lightPtr->LightBright = ONE_FIXED/4;
/* flags */
lightPtr->LightFlags = LFlag_Omni;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = EXPLOSION_LIGHT_RANGE;
lightPtr->RedScale= 255*256;
lightPtr->GreenScale= 120*256;
lightPtr->BlueScale= 0;
break;
}
case LIGHTELEMENT_PLASMACASTERHIT:
{
/* flags */
lightPtr->LightFlags = LFlag_Omni;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = EXPLOSION_LIGHT_RANGE;
if (lightElementPtr->LifeTime==ONE_FIXED)
{
lightPtr->LightBright = ONE_FIXED*4;
lightPtr->RedScale= 0*256;
lightPtr->GreenScale= 255*256;
lightPtr->BlueScale= 255*256;
}
else
{
lightPtr->LightBright = lightElementPtr->LifeTime/2;
lightPtr->LightRange = 1+MUL_FIXED(EXPLOSION_LIGHT_RANGE,lightElementPtr->LifeTime);
lightPtr->RedScale= 255*256;
lightPtr->GreenScale= 120*256;
lightPtr->BlueScale= 0*256;
}
lightElementPtr->LifeTime-=NormalFrameTime*4;
break;
}case LIGHTELEMENT_FROMFMV:
{
extern int FmvColourRed;
extern int FmvColourGreen;
extern int FmvColourBlue;
lightPtr->LightBright = ONE_FIXED*4;
/* flags */
lightPtr->LightFlags = LFlag_Omni;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = 15000;
lightPtr->RedScale= FmvColourRed;
lightPtr->GreenScale= FmvColourGreen;
lightPtr->BlueScale= FmvColourBlue;
break;
}
case LIGHTELEMENT_EXPLOSION:
{
/* flags */
lightPtr->LightFlags = LFlag_Omni;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
lightPtr->RedScale=255*256;
lightPtr->GreenScale=120*256;
lightPtr->BlueScale=0;
{
int scale = lightElementPtr->LifeTime*4;
if (scale < ONE_FIXED)
{
lightPtr->LightRange = 1+MUL_FIXED(EXPLOSION_LIGHT_RANGE,scale);
lightPtr->LightBright = scale*8;
}
else
{
lightPtr->LightRange = EXPLOSION_LIGHT_RANGE;
lightPtr->LightBright = ONE_FIXED*8;
}
}
{
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
if (playerStatusPtr->IsAlive)
{
VECTORCH d = lightElementPtr->LightBlock.LightWorld;
int m;
d.vx -= Global_VDB_Ptr->VDB_World.vx;
d.vy -= Global_VDB_Ptr->VDB_World.vy;
d.vz -= Global_VDB_Ptr->VDB_World.vz;
m = Approximate3dMagnitude(&d);
if (m<ONE_FIXED)
{
int maxTilt = MUL_FIXED((ONE_FIXED-m)>>9,lightElementPtr->LifeTime);
int halfTilt = maxTilt/2;
if (maxTilt)
{
HeadOrientation.EulerX = (FastRandom()%maxTilt)-halfTilt;
HeadOrientation.EulerY = (FastRandom()%maxTilt)-halfTilt;
HeadOrientation.EulerZ = (FastRandom()%maxTilt)-halfTilt;
if (HeadOrientation.EulerX < 0) HeadOrientation.EulerX += 4096;
if (HeadOrientation.EulerY < 0) HeadOrientation.EulerY += 4096;
if (HeadOrientation.EulerZ < 0) HeadOrientation.EulerZ += 4096;
}
}
}
}
lightElementPtr->LifeTime-=NormalFrameTime;
break;
}
case LIGHTELEMENT_ELECTRICAL_EXPLOSION:
{
int scale = ONE_FIXED*5/4-lightElementPtr->LifeTime;
/* flags */
lightPtr->LightFlags = LFlag_Omni|LFlag_Electrical;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
if (scale>65536) scale = 65536;
scale = ONE_FIXED - scale;
lightPtr->RedScale= scale;
lightPtr->GreenScale=ONE_FIXED;
lightPtr->BlueScale=ONE_FIXED;
lightPtr->LightRange = EXPLOSION_LIGHT_RANGE;// 1+MUL_FIXED(EXPLOSION_LIGHT_RANGE,scale);
lightPtr->LightBright = scale*16;
lightElementPtr->LifeTime-=NormalFrameTime;
break;
}
case LIGHTELEMENT_ELECTRICAL_SPARKS:
{
int scale = lightElementPtr->LifeTime;
/* flags */
lightPtr->LightFlags = LFlag_Omni|LFlag_Electrical;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
if (scale == ONE_FIXED)
{
lightPtr->RedScale=ONE_FIXED;
lightPtr->GreenScale=ONE_FIXED;
lightPtr->BlueScale=ONE_FIXED;
}
else
{
lightPtr->RedScale= 0;
lightPtr->GreenScale= scale/2;
lightPtr->BlueScale= scale;
}
lightPtr->LightRange = 4000;// 1+MUL_FIXED(EXPLOSION_LIGHT_RANGE,scale);
lightPtr->LightBright = scale;
lightElementPtr->LifeTime-=NormalFrameTime*2;
break;
}
case LIGHTELEMENT_ROTATING:
{
lightPtr->LightBright = ONE_FIXED/2;
/* flags */
lightPtr->LightFlags = LFlag_Omni;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
/* range */
lightPtr->LightRange = 10000;
lightPtr->RedScale= ONE_FIXED;
lightPtr->GreenScale= ONE_FIXED;
lightPtr->BlueScale= ONE_FIXED;
lightElementPtr->LightBlock.LightWorld = Player->ObWorld;//RotatingLightPosition;
// lightElementPtr->LightBlock.LightWorld.vx += MUL_FIXED(2000,GetCos((CloakingPhase/2)&4095));
lightElementPtr->LightBlock.LightWorld.vy -= 2200;
// lightElementPtr->LightBlock.LightWorld.vz += MUL_FIXED(2000,GetSin((CloakingPhase/2)&4095));
#if 0
{
VECTORCH zero = {0,0,0};
MakeParticle(&(lightElementPtr->LightBlock.LightWorld),&zero,PARTICLE_SPARK);
}
#endif
break;
}
case LIGHTELEMENT_ALIEN_TEETH:
case LIGHTELEMENT_ALIEN_TEETH2:
{
break;
}
case LIGHTELEMENT_PARGEN_FLAME :
{
if(lightElementPtr->LifeTime == ONE_FIXED)
{
lightElementPtr->LifeTime = 1;
/* flags */
lightPtr->LightFlags = LFlag_Omni;
/* lightblock light type */
lightPtr->LightType = LightType_PerVertex;
//lightPtr->RedScale= 255*256;
//lightPtr->GreenScale= 120*256;
lightPtr->RedScale= 255*(200+(CloakingPhase%56));
lightPtr->GreenScale= 120*(200+((CloakingPhase/8)%56));
lightPtr->BlueScale= 0;
lightPtr->LightRange = 6000;
lightPtr->LightBright = ONE_FIXED;
}
else
{
lightElementPtr->LifeTime = 0;
}
}
break;
default:
break;
}
lightPtr->BrightnessOverRange = DIV_FIXED(MUL_FIXED(lightPtr->LightBright,LightScale),lightPtr->LightRange);
if (lightElementPtr->LifeTime<=0)
{
DeallocateLightElement(lightElementPtr);
}
else
{
lightElementPtr++;
}
}
}
/*--------------------------**
** Load/Save Light Elements **
**--------------------------*/
#include "savegame.h"
typedef struct light_element_save_block_header
{
SAVE_BLOCK_HEADER header;
int NumActiveLightElements;
//followed by array of light elements
}LIGHT_ELEMENT_SAVE_BLOCK_HEADER;
void Load_LightElements(SAVE_BLOCK_HEADER* header)
{
int i;
LIGHT_ELEMENT_SAVE_BLOCK_HEADER* block = (LIGHT_ELEMENT_SAVE_BLOCK_HEADER*) header;
LIGHTELEMENT* saved_light_element = (LIGHTELEMENT*) (block+1);
int expected_size;
//make sure the block is the correct size
expected_size = sizeof(*block);
expected_size += sizeof(LIGHTELEMENT) * block->NumActiveLightElements;
if(header->size != expected_size) return;
for(i=0;i<block->NumActiveLightElements;i++)
{
LIGHTELEMENT* light_element = AllocateLightElement();
if(light_element)
{
*light_element = *saved_light_element++;
}
}
}
void Save_LightElements()
{
LIGHT_ELEMENT_SAVE_BLOCK_HEADER* block;
int i;
if(!NumActiveLightElements) return;
//get memory for header
GET_SAVE_BLOCK_POINTER(block);
//fill in header
block->header.type = SaveBlock_LightElements;
block->header.size = sizeof(*block) + NumActiveLightElements * sizeof(LIGHTELEMENT);
block->NumActiveLightElements = NumActiveLightElements;
//now save the light elements
for(i=0;i<NumActiveLightElements;i++)
{
LIGHTELEMENT* light = GET_SAVE_BLOCK_POINTER(light);
*light = LightElementStorage[i];
}
}

51
3dc/avp/LIGHTING.H Normal file
View file

@ -0,0 +1,51 @@
enum LIGHTING_EFFECTS_ID
{
LFX_EXPLOSION,
LFX_MUZZLEFLASH,
LFX_PARTICLECANNON,
LFX_ROCKETJET,
LFX_FLARE,
LFX_BIGEXPLOSION,
LFX_XENO_FIRING,
LFX_PLASMA_BOLT,
LFX_OBJECTONFIRE,
LFX_SPEARGUNBOLT
};
/* explosions light an area which has a max 15m radius */
#define EXPLOSION_LIGHT_RANGE 15000
//#define EXPLOSION_LIGHT_RANGE 30000
extern void AddLightingEffectToObject(DISPLAYBLOCK *objectPtr, enum LIGHTING_EFFECTS_ID lfxID);
extern void LightBlockDeallocation(void);
enum LIGHTELEMENT_BEHAVIOUR_ID
{
LIGHTELEMENT_MOLTENMETAL,
LIGHTELEMENT_PLASMACASTERHIT,
LIGHTELEMENT_FROMFMV,
LIGHTELEMENT_ROTATING,
LIGHTELEMENT_EXPLOSION,
LIGHTELEMENT_ELECTRICAL_EXPLOSION,
LIGHTELEMENT_ELECTRICAL_SPARKS,
LIGHTELEMENT_ALIEN_TEETH,
LIGHTELEMENT_ALIEN_TEETH2,
LIGHTELEMENT_PARGEN_FLAME,
};
typedef struct
{
enum LIGHTELEMENT_BEHAVIOUR_ID BehaviourID;
LIGHTBLOCK LightBlock;
int LifeTime;
} LIGHTELEMENT;
void InitialiseLightElementSystem(void);
void MakeLightElement(VECTORCH *positionPtr, enum LIGHTELEMENT_BEHAVIOUR_ID behaviourID);
void HandleLightElementSystem(void);

14
3dc/avp/MACRO.H Normal file
View file

@ -0,0 +1,14 @@
/*
Project specific inline macro support,
currently platform specific by
default
*/
#define GNU_ABS(x) (((x) < 0) ? -(x) : (x))
#define GNU_SIGN(x) (((x) < 0) ? -1 : +1)

78
3dc/avp/MAPS.C Normal file
View file

@ -0,0 +1,78 @@
/*
this now contains only the map processing
functions for the PC and saturn - compiled in maos
have been moved to comp_map
*/
#include "3dc.h"
#include "module.h"
#include "inline.h"
#include "stratdef.h"
#include "gamedef.h"
#define UseLocalAssert Yes
#include "ourasert.h"
/************ GLOBALS **********/
DISPLAYBLOCK *Player;
/***************************************************************/
/* MAP TYPE PROCESSING FUNCTIONS*/
/**************************************************************/
/*
The functions require a pointer to a display block. It uses "ObType"
in the block to select the function.
*/
static void Process_Default_MapType(DISPLAYBLOCK *dblockptr);
static void Process_Player_MapType(DISPLAYBLOCK *dblockptr);
static void Process_PlayerShipCamera_MapType(DISPLAYBLOCK *dblockptr);
static void Process_Sprite_MapType(DISPLAYBLOCK *dblockptr);
static void Process_Term_MapType(DISPLAYBLOCK *dblockptr);
void (*MapTypeFunctions[])(DISPLAYBLOCK *dblockptr) =
{
Process_Default_MapType,
Process_Player_MapType,
Process_PlayerShipCamera_MapType, /* Player ship camera */
Process_Sprite_MapType,
Process_Term_MapType
};
static void Process_Default_MapType(DISPLAYBLOCK *dptr)
{
dptr->ObLightType = LightType_PerVertex;
dptr->ObFlags |= ObFlag_MultLSrc;
}
static void Process_Player_MapType(DISPLAYBLOCK *dptr)
{
Player = dptr;
}
static void Process_PlayerShipCamera_MapType(DISPLAYBLOCK *dptr)
{
}
static void Process_Sprite_MapType(DISPLAYBLOCK *dblockptr)
{
}
static void Process_Term_MapType(DISPLAYBLOCK *dptr)
{}

156
3dc/avp/MessageHistory.c Normal file
View file

@ -0,0 +1,156 @@
#include "3dc.h"
#include "3dc.h"
#include "module.h"
#include "inline.h"
#include "stratdef.h"
#include "gamedef.h"
#include "language.h"
#define MAX_NO_OF_MESSAGES_IN_HISTORY 64
extern void NewOnScreenMessage(unsigned char *messagePtr);
struct MessageHistory
{
enum TEXTSTRING_ID StringID;
int Hours;
int Minutes;
int Seconds;
};
static struct MessageHistory MessageHistoryStore[MAX_NO_OF_MESSAGES_IN_HISTORY];
static int NumberOfEntriesInMessageHistory;
static int EntryToNextShow;
static int MessageHistoryAccessedTimer;
void MessageHistory_Initialise(void)
{
NumberOfEntriesInMessageHistory=0;
EntryToNextShow=0;
MessageHistoryAccessedTimer=0;
}
void MessageHistory_Add(enum TEXTSTRING_ID stringID)
{
if (NumberOfEntriesInMessageHistory<MAX_NO_OF_MESSAGES_IN_HISTORY)
{
MessageHistoryStore[NumberOfEntriesInMessageHistory].StringID = stringID;
MessageHistoryStore[NumberOfEntriesInMessageHistory].Hours = AvP.ElapsedHours;
MessageHistoryStore[NumberOfEntriesInMessageHistory].Minutes = AvP.ElapsedMinutes;
MessageHistoryStore[NumberOfEntriesInMessageHistory].Seconds = AvP.ElapsedSeconds/65536;
NumberOfEntriesInMessageHistory++;
}
}
void MessageHistory_DisplayPrevious(void)
{
if (EntryToNextShow)
{
unsigned char buffer[1024];
EntryToNextShow--;
sprintf
(
buffer,
"%s %d (%02dh%02dm%02ds) \n \n%s",
GetTextString(TEXTSTRING_INGAME_MESSAGENUMBER),
EntryToNextShow+1,
MessageHistoryStore[EntryToNextShow].Hours,
MessageHistoryStore[EntryToNextShow].Minutes,
MessageHistoryStore[EntryToNextShow].Seconds,
GetTextString(MessageHistoryStore[EntryToNextShow].StringID)
);
NewOnScreenMessage(buffer);
MessageHistoryAccessedTimer = 65536*4;
if (!EntryToNextShow && NumberOfEntriesInMessageHistory) EntryToNextShow = NumberOfEntriesInMessageHistory;
}
}
void MessageHistory_Maintain(void)
{
if (MessageHistoryAccessedTimer)
{
extern int NormalFrameTime;
MessageHistoryAccessedTimer -= NormalFrameTime;
if (MessageHistoryAccessedTimer<0)
{
MessageHistoryAccessedTimer=0;
}
}
else
{
EntryToNextShow = NumberOfEntriesInMessageHistory;
}
}
/*---------------------------**
** Load/Save message history **
**---------------------------*/
#include "savegame.h"
typedef struct message_history_save_block
{
SAVE_BLOCK_HEADER header;
int NumberOfEntriesInMessageHistory;
int EntryToNextShow;
int MessageHistoryAccessedTimer;
//follow by message history array
}MESSAGE_HISTORY_SAVE_BLOCK;
void Load_MessageHistory(SAVE_BLOCK_HEADER* header)
{
int i;
MESSAGE_HISTORY_SAVE_BLOCK* block = (MESSAGE_HISTORY_SAVE_BLOCK*) header;
struct MessageHistory* saved_message = (struct MessageHistory*) (block+1);
int expected_size;
//make sure the block is the correct size
expected_size = sizeof(*block);
expected_size += sizeof(struct MessageHistory) * block->NumberOfEntriesInMessageHistory;
if(header->size != expected_size) return;
//load the stuff then
NumberOfEntriesInMessageHistory = block->NumberOfEntriesInMessageHistory;
EntryToNextShow = block->EntryToNextShow;
MessageHistoryAccessedTimer = block->MessageHistoryAccessedTimer;
//load the message history
for(i=0;i<block->NumberOfEntriesInMessageHistory;i++)
{
MessageHistoryStore[i] = *saved_message++;
}
}
void Save_MessageHistory()
{
MESSAGE_HISTORY_SAVE_BLOCK* block;
int i;
//get memory for header
GET_SAVE_BLOCK_POINTER(block);
//fill in header
block->header.type = SaveBlock_MessageHistory;
block->header.size = sizeof(*block) + NumberOfEntriesInMessageHistory * sizeof(struct MessageHistory);
block->NumberOfEntriesInMessageHistory = NumberOfEntriesInMessageHistory;
block->EntryToNextShow = EntryToNextShow;
block->MessageHistoryAccessedTimer = MessageHistoryAccessedTimer;
for(i=0;i<NumberOfEntriesInMessageHistory;i++)
{
struct MessageHistory* message = GET_SAVE_BLOCK_POINTER(message);
*message = MessageHistoryStore[i];
}
}

1569
3dc/avp/PFARLOCS.C Normal file

File diff suppressed because it is too large Load diff

97
3dc/avp/PFARLOCS.H Normal file
View file

@ -0,0 +1,97 @@
/*------------------------Patrick 13/12/96-----------------------------
Header file for FAR AI alien module locations
--------------------------------------------------------------------*/
#ifndef _pfarlocs_h_
#define _pfarlocs_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/* various structure definitions used for module's auxilary location and
entry point data and headers...*/
typedef struct farlocationsheader
{
int numLocations;
struct vectorch *locationsList;
} FARLOCATIONSHEADER;
typedef struct farvalidatedlocation
{
int valid;
struct vectorch position;
} FARVALIDATEDLOCATION;
typedef struct farentrypoint
{
struct vectorch position;
int donorIndex;
unsigned int alien_only:1; //this entry point can only be used by aliens
} FARENTRYPOINT;
typedef struct farentrypointsheader
{
int numEntryPoints;
struct farentrypoint *entryPointsList;
} FARENTRYPOINTSHEADER;
/* enum of the different door types, as seen by NPC's */
typedef enum moduledoortype
{
MDT_NotADoor,
MDT_ProxDoor,
MDT_LiftDoor,
MDT_SecurityDoor,
} MODULEDOORTYPE;
/* globals */
extern FARLOCATIONSHEADER *FALLP_AuxLocs;
extern FARENTRYPOINTSHEADER *FALLP_EntryPoints;
/* defines for auxilary locations */
#define FAR_BB_HEIGHT 2000 /* should be height of a crouched alien */
#define FAR_BB_WIDTH 1000 /* should be the 'width' of an alien */
#define FAR_POS_HEIGHT 680 /* how high of the floor to put the alien (1/2 alien height + a bit) */
#define FAR_GRID_SIZE 6
#define FAR_MAX_LOCS 5
#define FAR_MIN_INCLINE 50
/* defines for entry points */
#define EPBB_XTRA 100
#define EP_POSNDISP 100
#define EP_MAXPOINTS 200
#define EP_MAXEDGES 200
/* defines for module door types insofar as they relate to alien behaviour
FADT stands for Far Alien Door Type*/
/* prototypes */
void BuildFarModuleLocs(void);
void KillFarModuleLocs(void);
MODULEDOORTYPE ModuleIsADoor(MODULE* target);
MODULEDOORTYPE AIModuleIsADoor(AIMODULE* target);
int ModuleIsPhysical(MODULE* target);
int AIModuleIsPhysical(AIMODULE* target);
int ModuleInModule(MODULE* target1, MODULE* target2);
int NumAdjacentModules(AIMODULE* target);
FARENTRYPOINT *GetModuleEP(MODULE* thisModule, MODULE*fromModule);
FARENTRYPOINT *GetAIModuleEP(AIMODULE* thisModule, AIMODULE*fromModule);
int PointIsInModule(MODULE* thisModule, VECTORCH* thisPoint);
#ifdef __cplusplus
}
#endif
#endif

648
3dc/avp/PHEROMON.C Normal file
View file

@ -0,0 +1,648 @@
/*-----------------------Patrick 12/11/96--------------------------
Source for AVP Pheromone system
-----------------------------------------------------------------*/
#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "stratdef.h"
#include "gamedef.h"
#include "bh_types.h"
#define UseLocalAssert Yes
#include "ourasert.h"
#include "pheromon.h"
#include "pfarlocs.h"
#include "pvisible.h"
#include "bh_alien.h"
#include "bh_far.h"
#include "bh_gener.h"
#include "showcmds.h"
#include "pldghost.h"
#if 1
static unsigned int *Pher_Player1;
static unsigned int *Pher_Player2;
static unsigned char *Pher_Ai1;
#else
#define MaxModules 300
static unsigned int Pher_Player1[MaxModules];
static unsigned int Pher_Player2[MaxModules];
static unsigned char Pher_Ai1[MaxModules];
#endif
/* these pointers indicate the current read from and write to
buffers for the player and ai pheromone systems */
unsigned int *PherPl_ReadBuf;
unsigned int *PherPl_WriteBuf;
unsigned char *PherAi_Buf;
#if SUPER_PHEROMONE_SYSTEM
static unsigned int *Pher_Aliens1;
static unsigned int *Pher_Aliens2;
unsigned int *PherAls_ReadBuf;
unsigned int *PherAls_WriteBuf;
unsigned int AlienPheromoneScale;
/* Marine pheromones: a pathfinding system only. */
static unsigned int *Pher_Marines1;
static unsigned int *Pher_Marines2;
unsigned int *PherMars_ReadBuf;
unsigned int *PherMars_WriteBuf;
#endif
/* This global is used to store the current player phermone intensity */
unsigned int PlayerSmell = 3;
MODULE *playerPherModule = (MODULE *)0;
/* external globals */
extern int AIModuleArraySize;
/* this define enables diagnostic text 'dump' for pheromone system */
#define logPheromoneDiagnostics 0
#if logPheromoneDiagnostics
static void LogPlayerPherValues(void);
static void LogModuleAdjacencies(void);
int printModAdj = 1;
#endif
/*----------------------Patrick 12/11/96---------------------------
Initialises pheromone systems
-------------------------------------------------------------------*/
void InitPheromoneSystem(void)
{
int i;
#if 1
/* allocate the pheromone buffers */
Pher_Player1 = (unsigned int *)AllocateMem((AIModuleArraySize+1)*sizeof(unsigned int));
if(!Pher_Player1)
{
memoryInitialisationFailure = 1;
return;
}
Pher_Player2 = (unsigned int *)AllocateMem((AIModuleArraySize+1)*sizeof(unsigned int));
if(!Pher_Player2)
{
memoryInitialisationFailure = 1;
return;
}
Pher_Ai1 = (unsigned char *)AllocateMem((AIModuleArraySize+1)*sizeof(unsigned char));
if(!Pher_Ai1)
{
memoryInitialisationFailure = 1;
return;
}
#endif
#if SUPER_PHEROMONE_SYSTEM
Pher_Aliens1 = (unsigned int *)AllocateMem((AIModuleArraySize+1)*sizeof(unsigned int));
if(!Pher_Aliens1)
{
memoryInitialisationFailure = 1;
return;
}
Pher_Aliens2 = (unsigned int *)AllocateMem((AIModuleArraySize+1)*sizeof(unsigned int));
if(!Pher_Aliens2)
{
memoryInitialisationFailure = 1;
return;
}
Pher_Marines1 = (unsigned int *)AllocateMem((AIModuleArraySize+1)*sizeof(unsigned int));
if(!Pher_Marines1)
{
memoryInitialisationFailure = 1;
return;
}
Pher_Marines2 = (unsigned int *)AllocateMem((AIModuleArraySize+1)*sizeof(unsigned int));
if(!Pher_Marines2)
{
memoryInitialisationFailure = 1;
return;
}
#endif
/* init the player phermone system */
for(i=0;i<AIModuleArraySize;i++)
{
Pher_Player1[i] = 1;
Pher_Player2[i] = 1;
}
PherPl_ReadBuf = &Pher_Player1[0];
PherPl_WriteBuf = &Pher_Player2[0];
PlayerSmell = 3;
playerPherModule = (MODULE *)0;
/* init the ai pheromone system */
for(i=0;i<AIModuleArraySize;i++)
{
Pher_Ai1[i] = 0;
}
PherAi_Buf = &Pher_Ai1[0];
#if SUPER_PHEROMONE_SYSTEM
for(i=0;i<AIModuleArraySize;i++)
{
Pher_Aliens1[i] = 0;
Pher_Aliens2[i] = 0;
}
PherAls_ReadBuf = &Pher_Aliens1[0];
PherAls_WriteBuf = &Pher_Aliens2[0];
AlienPheromoneScale=1;
for(i=0;i<AIModuleArraySize;i++)
{
Pher_Marines1[i] = 0;
Pher_Marines2[i] = 0;
}
PherMars_ReadBuf = &Pher_Marines1[0];
PherMars_WriteBuf = &Pher_Marines2[0];
#endif
#if logPheromoneDiagnostics
printModAdj = 1;
#endif
}
/*----------------------Patrick 14/3/96---------------------------
End of level clean up for pheromone system
-------------------------------------------------------------------*/
void CleanUpPheromoneSystem(void)
{
#if 1
if (Pher_Player1) DeallocateMem(Pher_Player1);
if (Pher_Player2) DeallocateMem(Pher_Player2);
if (Pher_Ai1) DeallocateMem(Pher_Ai1);
#endif
#if SUPER_PHEROMONE_SYSTEM
if (Pher_Aliens1) DeallocateMem(Pher_Aliens1);
if (Pher_Aliens2) DeallocateMem(Pher_Aliens2);
if (Pher_Marines1) DeallocateMem(Pher_Marines1);
if (Pher_Marines2) DeallocateMem(Pher_Marines2);
#endif
}
int AIModuleAdmitsPheromones(AIMODULE *targetModule) {
/* Check state. */
MODULEDOORTYPE doorStatus;
doorStatus = (AIModuleIsADoor(targetModule));
switch(doorStatus)
{
case(MDT_ProxDoor):
{
/* Go thru UNLOCKED proxdoors... */
MODULE *renderModule;
PROXDOOR_BEHAV_BLOCK *pdbblk;
renderModule=*(targetModule->m_module_ptrs);
pdbblk=((PROXDOOR_BEHAV_BLOCK *)renderModule->m_sbptr->SBdataptr);
if (pdbblk->lockable_door) {
if (pdbblk->door_locked) {
return(0);
} else {
return(1);
}
} else {
if (pdbblk->door_locked) {
return(0);
} else {
return(1);
}
}
}
case(MDT_LiftDoor):
{
GLOBALASSERT(targetModule->m_module_ptrs);
GLOBALASSERT(*(targetModule->m_module_ptrs));
if(GetState((*(targetModule->m_module_ptrs))->m_sbptr)) {
/* Open. */
return (1);
} else {
/* Closed. */
return (0);
}
break;
}
case(MDT_SecurityDoor):
{
GLOBALASSERT(targetModule->m_module_ptrs);
GLOBALASSERT(*(targetModule->m_module_ptrs));
if(GetState((*(targetModule->m_module_ptrs))->m_sbptr)) {
/* Open. */
return (1);
} else {
/* Closed. */
return (0);
}
break;
}
default:
{
LOCALASSERT(doorStatus==MDT_NotADoor);
return(1);
}
}
}
#if SUPER_PHEROMONE_SYSTEM
void AddMarinePheromones(AIMODULE *targetModule) {
int ThisModuleIndex;
ThisModuleIndex = targetModule->m_index;
PherAls_WriteBuf[ThisModuleIndex] += 3;
}
void MaintainMarineTargetZone(AIMODULE *targetModule) {
int ThisModuleIndex;
ThisModuleIndex = targetModule->m_index;
PherMars_WriteBuf[ThisModuleIndex] += 3;
}
#endif
/*----------------------Patrick 12/11/96---------------------------
Updates the player pheromone system:
this is used by the NPC far behaviour for hunting the player.
-------------------------------------------------------------------*/
void PlayerPheromoneSystem(void)
{
int moduleCounter;
AIMODULE *ModuleListPointer;
AIMODULE *ThisModulePtr;
int ThisModuleIndex;
AIMODULE **AdjModuleRefPtr;
int AdjModuleIndex;
#if logPheromoneDiagnostics
if(printModAdj)
{
printModAdj = 0;
LogModuleAdjacencies();
}
#endif
/* get a pointer to the global array of pointers to the modules
in the environment (interfaces'r'us).
First check if Global_ModulePtr is set. If not we're buggered,
so leave everything as it is and try again next frame*/
{
extern AIMODULE *AIModuleArray;
ModuleListPointer = AIModuleArray;
}
/* go through each module in the environment */
for(moduleCounter = 0; moduleCounter < AIModuleArraySize; moduleCounter++)
{
/* get a pointer to the next current module */
ThisModulePtr = &(ModuleListPointer[moduleCounter]);
LOCALASSERT(ThisModulePtr);
/* get it's index */
ThisModuleIndex = ThisModulePtr->m_index;
LOCALASSERT(ThisModuleIndex >= 0);
LOCALASSERT(ThisModuleIndex < AIModuleArraySize);
/* !!!!!!!!!!!!!!!!!!!!!
check for closed non-traversable door module here if detected, do not update its smell.
Actually, no: allow smell to pass thro' non-openable doors. Otherwise AIs that can open
doors will choose not to
!!!!!!!!!!!!!!!!!!!!!!!!*/
/* CDF 4/12/97: Actually, yes. AIs CAN'T open security doors, fool! */
/* check for universal module: don't want to update this! */
if(AIModuleIsPhysical(ThisModulePtr))
{
if (AIModuleAdmitsPheromones(ThisModulePtr)) {
/* get a pointer to the list of physically adjacent modules
and traverse them */
AdjModuleRefPtr = ThisModulePtr->m_link_ptrs;
if(AdjModuleRefPtr) /* check that there is a list of adjacent modules */
{
while(*AdjModuleRefPtr != 0)
{
/* get the index */
AdjModuleIndex = (*AdjModuleRefPtr)->m_index;
/* if adjacent module's previous smell is greater than
the current module's new smell (so far), then update
the current module's newq smell */
if(PherPl_ReadBuf[AdjModuleIndex] > PherPl_WriteBuf[ThisModuleIndex])
PherPl_WriteBuf[ThisModuleIndex] = (PherPl_ReadBuf[AdjModuleIndex] - 1);
#if SUPER_PHEROMONE_SYSTEM
if(PherAls_ReadBuf[AdjModuleIndex] > PherAls_WriteBuf[ThisModuleIndex]) {
PherAls_WriteBuf[ThisModuleIndex] = (PherAls_ReadBuf[AdjModuleIndex] - 1);
}
if (CheckAdjacencyValidity((*AdjModuleRefPtr),ThisModulePtr,0)) {
if(PherMars_ReadBuf[AdjModuleIndex] > PherMars_WriteBuf[ThisModuleIndex]) {
PherMars_WriteBuf[ThisModuleIndex] = (PherMars_ReadBuf[AdjModuleIndex] - 1);
}
}
#endif
/* next adjacent module reference pointer */
AdjModuleRefPtr++;
}
}
}
#if SUPER_PHEROMONE_SYSTEM
/* Decay pheromones. */
if (PherAls_WriteBuf[ThisModuleIndex]>0) {
PherAls_WriteBuf[ThisModuleIndex]--;
}
if (PherMars_WriteBuf[ThisModuleIndex]>0) {
PherMars_WriteBuf[ThisModuleIndex]--;
}
#endif
}
}
/*If in a network game add pheromon's for other players*/
if(AvP.Network!=I_No_Network && AvP.NetworkAIServer)
{
/* go through the strategy blocks looking for players*/
int sbIndex;
for(sbIndex=0;sbIndex<NumActiveStBlocks;sbIndex++)
{
STRATEGYBLOCK *playerSbPtr = ActiveStBlockList[sbIndex];
NETGHOSTDATABLOCK *ghostData;
if(playerSbPtr->I_SBtype!=I_BehaviourNetGhost) continue;
ghostData = (NETGHOSTDATABLOCK *)playerSbPtr->SBdataptr;
if(ghostData->type==I_BehaviourMarinePlayer ||
ghostData->type==I_BehaviourPredatorPlayer)
{
/*this is another player*/
if(playerSbPtr->containingModule)
{
PherPl_WriteBuf[playerSbPtr->containingModule->m_aimodule->m_index] = PlayerSmell;
AddMarinePheromones(playerSbPtr->containingModule->m_aimodule);
}
}
}
}
/* That completed, find which module the player is in, set it's smell to the
current player smell value, and update the player smell for the next frame */
{
extern DISPLAYBLOCK* Player;
VECTORCH playerPosition = Player->ObWorld;
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
playerPherModule = (ModuleFromPosition(&playerPosition, playerPherModule));
if(playerPherModule)
{
//the player must be alive to leave pheromones
//(mainly relevant in coop games)
if(playerStatusPtr->IsAlive)
{
PherPl_WriteBuf[playerPherModule->m_aimodule->m_index] = PlayerSmell;
#if SupportWindows95
if(playerPherModule->name)
{
if (ShowDebuggingText.Module)
{
ReleasePrintDebuggingText("Player Module: %d '%s'\n", playerPherModule->m_index,playerPherModule->name);
ReleasePrintDebuggingText("Player Module Coords: %d %d %d\n",playerPherModule->m_world.vx,playerPherModule->m_world.vy,playerPherModule->m_world.vz);
}
#if SUPER_PHEROMONE_SYSTEM
AlienPheromoneScale+=3;
if (AlienPheromoneScale==0) AlienPheromoneScale=1;
{
unsigned int prop=DIV_FIXED(PherAls_WriteBuf[playerPherModule->m_aimodule->m_index],AlienPheromoneScale);
textprint("Alien readable pheromones in Player Module: %d\n",prop);
}
/* No scale for 'marine' pheromones, the player will never see it. */
#endif
}
#endif
}
}
}
PlayerSmell++;
#if SUPER_PHEROMONE_SYSTEM
/* Note that marines should add pheromones at the AI level... */
{
unsigned int *tempBufPointer = PherAls_ReadBuf;
PherAls_ReadBuf = PherAls_WriteBuf;
PherAls_WriteBuf= tempBufPointer;
}
/* As should the pathfinding system. */
{
unsigned int *tempBufPointer = PherMars_ReadBuf;
PherMars_ReadBuf = PherMars_WriteBuf;
PherMars_WriteBuf= tempBufPointer;
}
#endif
/* swap the read and write buffers:
behaviours access most recent data thro' the read buffer */
{
unsigned int *tempBufPointer = PherPl_ReadBuf;
PherPl_ReadBuf = PherPl_WriteBuf;
PherPl_WriteBuf = tempBufPointer;
}
#if logPheromoneDiagnostics
LogPlayerPherValues();
#endif
}
/*----------------------Patrick 14/11/96---------------------------
Ai Pheromone system.
This system just keeps track of how many aliens are in each module,
and is calculated from scratch at the start of each frame.
Also, the numactivealiens bit of the hive data block is calculated
for this frame.
-------------------------------------------------------------------*/
void AiPheromoneSystem(void)
{
extern int NumActiveStBlocks;
extern STRATEGYBLOCK *ActiveStBlockList[];
int sbIndex = 0;
STRATEGYBLOCK *sbPtr;
int i;
/* first, zero the buffer, and hive counter */
for(i=0;i<AIModuleArraySize;i++) PherAi_Buf[i] = 0;
/* next, have a look at the sb list */
while(sbIndex < NumActiveStBlocks)
{
sbPtr = ActiveStBlockList[sbIndex++];
if((sbPtr->I_SBtype == I_BehaviourAlien)||(sbPtr->I_SBtype == I_BehaviourMarine))
{
if(sbPtr->containingModule)
{
PherAi_Buf[(sbPtr->containingModule->m_aimodule->m_index)]++;
}
}
}
}
#if logPheromoneDiagnostics
/* write out a list of module ajacencies */
static void LogModuleAdjacencies(void)
{
extern SCENE Global_Scene;
extern SCENEMODULE **Global_ModulePtr;
GLOBALASSERT(0);
/* This function does not use AI modules yet! */
FILE *logFile;
int i;
SCENEMODULE *ScenePtr;
MODULE **ModuleListPointer;
MODULE *ThisModulePtr;
int ThisModuleIndex;
MREF *AdjModuleRefPtr;
int AdjModuleIndex;
LOCALASSERT(Global_ModulePtr != 0);
ScenePtr = Global_ModulePtr[Global_Scene];
ModuleListPointer = ScenePtr->sm_marray;
logFile = fopen("D:/PATRICK/MODADJ.TXT","w");
if(logFile)
{
LOCALASSERT(ModuleArraySize);
for(i = 0; i < ModuleArraySize; i++)
{
ThisModulePtr = ModuleListPointer[i];
LOCALASSERT(ThisModulePtr);
/* get it's index */
ThisModuleIndex = ThisModulePtr->m_index;
LOCALASSERT(ThisModuleIndex >= 0);
LOCALASSERT(ThisModuleIndex < ModuleArraySize);
fprintf(logFile, "Module %d Adjoing modules: ", ThisModuleIndex);
/* get a pointer to the list of physically adjacent modules
and traverse them */
AdjModuleRefPtr = ThisModulePtr->m_link_ptrs;
if(AdjModuleRefPtr == 0)
{
fprintf(logFile, " None/n");
}
else
{
while(AdjModuleRefPtr->mref_ptr != 0)
{
/* get the index */
AdjModuleIndex = (AdjModuleRefPtr->mref_ptr)->m_index;
fprintf(logFile, " %d,", AdjModuleIndex);
/* next adjacent module reference pointer */
AdjModuleRefPtr++;
}
fprintf(logFile, "\n");
}
}
fclose(logFile);
}
/* also, initialise pheromone value file */
logFile = fopen("D:/PATRICK/MODPPHER.TXT","w");
if(logFile)
{
fprintf(logFile, "PLAYER PHEROMONE VALUES \n");
fclose(logFile);
}
}
/* Log the player pheromone values */
static void LogPlayerPherValues(void)
{
FILE *logFile;
int i;
logFile = fopen("D:/PATRICK/MODPPHER.TXT","a");
if (!logFile) return;
fprintf(logFile, "\n ***************************** \n");
for(i=0;i<AIModuleArraySize;i++)
{
if(i%7 == 0) fprintf(logFile, "\n");
fprintf(logFile, "%5d", PherPl_ReadBuf[i]);
}
fclose(logFile);
}
#endif

31
3dc/avp/PHEROMON.H Normal file
View file

@ -0,0 +1,31 @@
/*-----------------------Patrick 14/11/96--------------------------
Header for AVP Pheromone system
-----------------------------------------------------------------*/
#define SUPER_PHEROMONE_SYSTEM 1
/* Global Data access to pheromone system */
extern unsigned int *PherPl_ReadBuf;
extern unsigned int *PherPl_WriteBuf;
#if SUPER_PHEROMONE_SYSTEM
extern unsigned int *PherAls_ReadBuf;
extern unsigned int *PherAls_WriteBuf;
extern unsigned int *PherMars_ReadBuf;
extern unsigned int *PherMars_WriteBuf;
#endif
extern unsigned char *PherAi_Buf;
extern MODULE *playerPherModule;
/* function prototypes */
void InitPheromoneSystem(void);
void PlayerPheromoneSystem(void);
void AiPheromoneSystem(void);
void CleanUpPheromoneSystem(void);
int AIModuleAdmitsPheromones(AIMODULE *targetModule);
#if SUPER_PHEROMONE_SYSTEM
void AddMarinePheromones(AIMODULE *targetModule);
void MaintainMarineTargetZone(AIMODULE *targetModule);
#endif

85
3dc/avp/PMOVE.H Normal file
View file

@ -0,0 +1,85 @@
/*--------------Patrick 15/10/96 ---------------------
Header File for Player Movement Stuff
---------------------------------------------------*/
#ifndef _pmove_h_
#define _pmove_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*--------------Patrick 15/10/96 ---------------------
Enumeration of player movement states
Free movement indicates normal movement.
Special Movement indicates that the player is
executing a special move.
Aborting indicates that a special move is
prematurely terminating.
---------------------------------------------------*/
typedef enum player_mov_state
{
PMov_FreeMovement,
PMov_SpecialMovement,
PMov_AbortingSpecialMovement,
}PLAYER_MOVEMENT_STATE;
/*--------------Patrick 15/10/96 ---------------------
Enumeration of special move types
Special moves are flagged as belonging to a
character type
---------------------------------------------------*/
/*--------------Patrick 31/10/96 ---------------------
Enumeration of player's morphing states for crouching
and lying down.
---------------------------------------------------*/
typedef enum player_morph_state
{
PMph_Standing,
PMph_Crouching,
PMph_Lying,
PMph_StoC,
PMph_CtoS,
PMph_StoL,
PMph_LtoS,
}PLAYER_MORPH_STATE;
/*--------------Patrick 1/11/96 ---------------------
this define determines how crouching and lying down
are implemented for the player. It can either be
done by changing the shape, or by morphing....
Morphing is better, but doesn't work with the current
collision system.
---------------------------------------------------*/
#define CrouchByMorphingPlayer 0
/* Prototypes */
extern void InitPlayerMovementData(STRATEGYBLOCK* sbPtr);
extern void PlayerBehaviour(STRATEGYBLOCK* sbptr);
extern void ExecuteFreeMovement(STRATEGYBLOCK* sbPtr);
#ifdef __cplusplus
}
#endif
#endif

172
3dc/avp/PSND.H Normal file
View file

@ -0,0 +1,172 @@
/* Patrick 5/6/97 -------------------------------------------------------------
AvP sound management header
Provides support for sound samples, and for playing CDDA tracks.
NB These two systems are entirely seperate.
----------------------------------------------------------------------------*/
#ifndef PSND_H
#define PSND_H
#ifdef __cplusplus
extern "C" {
#endif
#include "psndproj.h"
/* Patrick 10/6/97 --------------------------------------------------------------
SUPPORT FOR SOUND SAMPLE SYSTEM
-----------------------------------------------------------------------------*/
/* Patrick 5/6/97 --------------------------------------------------------------
Enumeration of different sound priorities: sounds created with the maximum
priority may stop and displace sounds with the minimum priority, if the
maximum number of sounds is being played.
-----------------------------------------------------------------------------*/
typedef enum activesoundpriority
{
ASP_Minimum,
ASP_Maximum,
}ACTIVESOUNDPRIORITY;
/* this is a structure for new 3d sound support */
typedef struct sound3ddata
{
VECTORCH position;
VECTORCH velocity;
int inner_range;
int outer_range;
} SOUND3DDATA;
/* Patrick 5/6/97 --------------------------------------------------------------
Some platform independant defines:
SOUND_NOACTIVEINDEX: used to invalidate sound handles
MAX\MIN VOLUME: range of values accepted by functions for sound volume settings
MAX\MIN PITCH: range of values accepted by functions for sound pitch settings,
covers +- 4 octaves in 128ths of a semi-tone
-----------------------------------------------------------------------------*/
#define SOUND_NOACTIVEINDEX (-1)
#define SOUND_PLATFORMERROR (-1)
#define VOLUME_MAX (127)
#define VOLUME_MIN (0)
#define VOLUME_DEFAULT (127)
#define VOLUME_FADERATE (16) /* per second */
#define PITCH_MAX (6144)
#define PITCH_MIN (-6144)
#define PITCH_DEFAULT (0)
/* Patrick 5/6/97 --------------------------------------------------------------
SoundSys_Start() & SoundSys_End(): initialise and de-initialise the sound
system.
-----------------------------------------------------------------------------*/
extern void SoundSys_Start(void);
extern void SoundSys_End(void);
/* Patrick 5/6/97 --------------------------------------------------------------
The management function: cleans up sounds that have finished playing, and
updates 3d sounds. This must be called during the game loop, whenever sounds
are required.
-----------------------------------------------------------------------------*/
extern void SoundSys_Management(void);
/* Patrick 5/6/97 --------------------------------------------------------------
StopAll: stops all current sounds. New ones may be started immediately afterwards.
RemoveAll(): stops all sounds, and then unloads any loaded sounds. The
sound system remains initialised, but no sounds can be played until they are loaded.
-----------------------------------------------------------------------------*/
extern void SoundSys_StopAll(void);
extern void SoundSys_RemoveAll(void);
/* Patrick 5/6/97 --------------------------------------------------------------
Switch On/Off: can be used to turn on\off sound. If turened off, al sounds
stop and no further ones will be started until switched on again. Switch on
only succeeds if the sound system has been initialised succesfully.
-----------------------------------------------------------------------------*/
extern void SoundSys_SwitchOn(void);
extern void SoundSys_SwitchOff(void);
/* Patrick 5/6/97 --------------------------------------------------------------
IsOn returns true (1) if the sound system is currently switched on,
or false (0) otherwise.
NB IsOn always returns false if the sound system has not been initialised, ie
if SoundSys_Start() has not been called, or if the platform initialisation
failed.
-----------------------------------------------------------------------------*/
extern int SoundSys_IsOn(void);
/* Patrick 5/6/97 --------------------------------------------------------------
Change volume controls, which effect all current and future sounds.
NB These do not effect the CDDA player.
-----------------------------------------------------------------------------*/
extern void SoundSys_ChangeVolume(int volume);
/* New fading functionality KJL 99/4/5 */
extern void SoundSys_ResetFadeLevel(void);
extern void SoundSys_FadeIn(void);
extern void SoundSys_FadeOut(void);
extern void SoundSys_FadeOutFast(void);
/* Patrick 5/6/97 --------------------------------------------------------------
Sound play function: creates and plays and instance of a loaded game sound.
Has no effect if the maximum number of sounds are playing, or the maximum
number of the specified sound are playing (these are defined in psndplat.h)
The second paramter is a format string which identifies any further paramters,
and flags. If the second parameter is NULL, or points to a null string, the
sound is played in 2D, at default volume and pitch, with lowest priority,
will not loop, and will not return a handle to itself.
The following characters may be used in the format string (all others ignored):
'd': play the sound as 3d- The next parameter must be the world position, and
of type VECTORCH *
'n': play the sound as new 3d- The next parameter must be the world position, and
of type SOUND3DDATA *
'e': external sound handle refernce- the next parameter must be a pointer
to the external reference, and of type int*. The external refernce
may br used to subsequently stop the sound, change it's volume or
pitch, or update it's world space position. If the sound play function
fails, or if/when the sound subsequently stops playing,
SOUND_NOACTIVEINDEX is written to this external reference.
'v': Volume- the next parameter must be the sounds starting volume
of type int. Out of range values are forced into range.
'p': Pitch- the next parameter must be the sounds starting pitch shift (shifted from
the sound's base pitch value), and of type int. Out of range values are forced
into range.
'l': play the sound looping (an external reference must be supplied, or the
function has n effect)
'h': play sound with maximum priority (minimum is the default)
'm': flag for marines to ignore.
-----------------------------------------------------------------------------*/
extern void Sound_Play(SOUNDINDEX soundNumber, char* format, ...);
/* Patrick 5/6/97 --------------------------------------------------------------
The remaining functions are used to modify existing playing sounds. All take
a handle to a sound. If an invalid handle is passed, the functions have no
effect. Out or range volume or pitch values are forced into range.
ChangeVolume works on an absolute scale (where the sounds original volume
corresponds to the maximum volume), and ChangePitch works as a pitch-shift
from the base pitch of the sound.
-----------------------------------------------------------------------------*/
extern void Sound_Stop(int activeSoundNumber);
extern void Sound_ChangeVolume(int activeSoundNumber, int volume);
extern void Sound_ChangePitch(int activeSoundNumber, int pitch);
extern void Sound_Update3d(int activeSoundNumber, VECTORCH* posn);
extern void Sound_UpdateNew3d(int activeSoundNumber, SOUND3DDATA * s3d);
extern unsigned int SoundNumActiveVoices();
extern void Load_SoundState(int* soundHandle);
extern void Save_SoundState(int* soundHandle);
#ifdef __cplusplus
}
#endif
#endif

Some files were not shown because too many files have changed in this diff Show more