Files
source/Laptop/history.cpp
T
Overhaul 7a27e7105d New attack busy system
Added missing #includes

Added LUA scripting and console

Changed the way tracers are visualized, so they work more like real tracers instead of a light fountain

Fixed signedness of many grid variables used in GetMouseMapPos calls

Fixed enemy weapon choosing:  Sometimes a mortar is chosen but later rejected, but the grenade class was not reset.  Caused assertion failure

Added checks so enemies don't try to chuck RPG grenades with their hands

Now possible to shoot a someone in the head if he's in water

Fixed InitSightArrays to also clear soldier interrupt duel points.  This was causing an assertion failure elsewhere in the code because the interrupt list still had soldiers on it sometimes when this function was called.

Soldiers are much less willing to forfeit their turn over an attempt to use more APs than they have

Removed early setting of muzzle flash.  This would allow enemies to get an interrupt before you even fired.

Fixed item dropping by AI.  If AI tried to drop something while standing it would cause deadlock

Change to greatly speed up closing the sector inventory window in an unloaded sector

Added conditional compile flag to always give robot weapon ready advantage, even for 360 degree sighting


Check builddefines.h for the conditional flags.  Of greatest interest might be LUA_CONSOLE.  This will cause the game to bring up a command console when run.  However this console is severely lacking in many areas.  If anybody knows of an open-source terminal/console that could be used instead, it would be appreciated.  The existing console does bad things when you try to close it, and since it counts as a separate app, it pauses the game while it has focus.

LUA scripting is very limited, basically just proof of concept.  There is one global variable, the Soldiers array.  An array index gives you the soldier in that slot in the currently loaded sector.  The soldier has a few things that can be accessed:  name (short name); fullname (long name); grid (current grid #, can be changed); walkto(grid) (function to walk to another grid); runto(grid) (function to run to another grid)


git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@924 3b4a5df2-a311-0410-b5c6-a8a6f20db521
2007-06-09 09:01:04 +00:00

1764 lines
47 KiB
C++

#ifdef PRECOMPILEDHEADERS
#include "Laptop All.h"
#else
#include "laptop.h"
#include "History.h"
#include "Game clock.h"
#include "Utilities.h"
#include "WCheck.h"
#include "Debug.h"
#include "WordWrap.h"
#include "Render Dirty.h"
#include "Encrypted File.h"
#include "cursors.h"
#include "Soldier Profile.h"
#include "strategicmap.h"
#include "QuestText.h"
#include "text.h"
#include "message.h"
#include "LaptopSave.h"
#endif
#define TOP_X LAPTOP_SCREEN_UL_X
#define TOP_Y LAPTOP_SCREEN_UL_Y
#define BLOCK_HIST_HEIGHT 10
#define BOX_HEIGHT 14
#define TOP_DIVLINE_Y iScreenHeightOffset + 101
#define DIVLINE_X iScreenWidthOffset + 130
#define MID_DIVLINE_Y iScreenHeightOffset + 155
#define BOT_DIVLINE_Y iScreenHeightOffset + 204
#define TITLE_X iScreenWidthOffset + 140
#define TITLE_Y iScreenHeightOffset + 33
#define TEXT_X iScreenWidthOffset + 140
#define PAGE_SIZE 22
#define RECORD_Y TOP_DIVLINE_Y
#define RECORD_HISTORY_WIDTH 200
#define PAGE_NUMBER_X TOP_X+20
#define PAGE_NUMBER_Y TOP_Y+33
#define HISTORY_DATE_X PAGE_NUMBER_X+85
#define HISTORY_DATE_Y PAGE_NUMBER_Y
#define RECORD_LOCATION_WIDTH 142
#define HISTORY_HEADER_FONT FONT14ARIAL
#define HISTORY_TEXT_FONT FONT12ARIAL
#define RECORD_DATE_X TOP_X+10
#define RECORD_DATE_WIDTH 31
#define RECORD_HEADER_Y iScreenHeightOffset + 90
#define NUM_RECORDS_PER_PAGE PAGE_SIZE
#define SIZE_OF_HISTORY_FILE_RECORD ( sizeof( UINT8 ) + sizeof( UINT8 ) + sizeof( UINT32 ) + sizeof( UINT16 ) + sizeof( UINT16 ) + sizeof( UINT8 ) + sizeof( UINT8 ) )
// button positions
#define NEXT_BTN_X iScreenWidthOffset + 577
#define PREV_BTN_X iScreenWidthOffset + 553
#define BTN_Y iScreenHeightOffset + 53
// graphics handles
extern UINT32 guiTITLE; // symbol already defined in laptop.cpp (jonathanl)
//UINT32 guiGREYFRAME;
extern UINT32 guiTOP; // symbol already defined in finances.cpp (jonathanl)
//UINT32 guiMIDDLE;
//UINT32 guiBOTTOM;
//UINT32 guiLINE;
extern UINT32 guiLONGLINE; // symbol already defined in finances.cpp (jonathanl)
UINT32 guiSHADELINE;
//UINT32 guiVERTLINE;
//UINT32 guiBIGBOX;
enum{
PREV_PAGE_BUTTON=0,
NEXT_PAGE_BUTTON,
};
// the page flipping buttons
INT32 giHistoryButton[2];
INT32 giHistoryButtonImage[2];
BOOLEAN fInHistoryMode=FALSE;
// current page displayed
INT32 iCurrentHistoryPage=1;
// the History record list
HistoryUnitPtr pHistoryListHead=NULL;
// current History record (the one at the top of the current page)
HistoryUnitPtr pCurrentHistory=NULL;
// last page in list
UINT32 guiLastPageInHistoryRecordsList = 0;
// function definitions
BOOLEAN LoadHistory( void );
void RenderHistoryBackGround( void );
void RemoveHistory( void );
void CreateHistoryButtons( void );
void DestroyHistoryButtons( void );
void CreateHistoryButtons( void );
void DrawHistoryTitleText( void );
UINT32 ProcessAndEnterAHistoryRecord( UINT8 ubCode, UINT32 uiDate, UINT8 ubSecondCode, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubColor );
void OpenAndReadHistoryFile( void );
BOOLEAN OpenAndWriteHistoryFile( void );
void ClearHistoryList( void );
void DisplayHistoryListHeaders( void );
void DisplayHistoryListBackground( void );
void DrawAPageofHistoryRecords( void );
BOOLEAN IncrementCurrentPageHistoryDisplay( void );
void DisplayPageNumberAndDateRange( void );
void ProcessHistoryTransactionString(STR16 pString, HistoryUnitPtr pHistory);
void SetHistoryButtonStates( void );
BOOLEAN LoadInHistoryRecords( UINT32 uiPage );
BOOLEAN LoadNextHistoryPage( void );
BOOLEAN LoadPreviousHistoryPage( void );
void SetLastPageInHistoryRecords( void );
UINT32 ReadInLastElementOfHistoryListAndReturnIdNumber( void );
BOOLEAN AppendHistoryToEndOfFile( HistoryUnitPtr pHistory );
BOOLEAN WriteOutHistoryRecords( UINT32 uiPage );
void GetQuestStartedString( UINT8 ubQuestValue, STR16 sQuestString );
void GetQuestEndedString( UINT8 ubQuestValue, STR16 sQuestString );
INT32 GetNumberOfHistoryPages();
#ifdef JA2TESTVERSION
void PerformCheckOnHistoryRecord( UINT32 uiErrorCode, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
#endif
// callbacks
void BtnHistoryDisplayNextPageCallBack(GUI_BUTTON *btn,INT32 reason);
void BtnHistoryDisplayPrevPageCallBack(GUI_BUTTON *btn,INT32 reason);
UINT32 SetHistoryFact( UINT8 ubCode, UINT8 ubSecondCode, UINT32 uiDate, INT16 sSectorX, INT16 sSectorY )
{
// adds History item to player's log(History List), returns unique id number of it
// outside of the History system(the code in this .c file), this is the only function you'll ever need
UINT32 uiId=0;
UINT8 ubColor = 0;
HistoryUnitPtr pHistory = pHistoryListHead;
// clear the list
ClearHistoryList( );
// process the actual data
if( ubCode == HISTORY_QUEST_FINISHED )
{
ubColor = 0;
}
else
{
ubColor = 1;
}
uiId = ProcessAndEnterAHistoryRecord(ubCode, uiDate, ubSecondCode, sSectorX, sSectorY, 0, ubColor);
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_HISTORY_UPDATED ] );
// history list head
pHistory = pHistoryListHead;
// append to end of file
AppendHistoryToEndOfFile( pHistory );
// if in history mode, reload current page
if( fInHistoryMode )
{
iCurrentHistoryPage--;
// load in first page
LoadNextHistoryPage( );
}
// return unique id of this transaction
return uiId;
}
UINT32 AddHistoryToPlayersLog(UINT8 ubCode, UINT8 ubSecondCode, UINT32 uiDate, INT16 sSectorX, INT16 sSectorY)
{
// adds History item to player's log(History List), returns unique id number of it
// outside of the History system(the code in this .c file), this is the only function you'll ever need
UINT32 uiId=0;
HistoryUnitPtr pHistory = pHistoryListHead;
// clear the list
ClearHistoryList( );
// process the actual data
uiId = ProcessAndEnterAHistoryRecord(ubCode, uiDate, ubSecondCode, sSectorX, sSectorY, 0, 0);
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_HISTORY_UPDATED ] );
// history list head
pHistory = pHistoryListHead;
// append to end of file
AppendHistoryToEndOfFile( pHistory );
// if in history mode, reload current page
if( fInHistoryMode )
{
iCurrentHistoryPage--;
// load in first page
LoadNextHistoryPage( );
}
// return unique id of this transaction
return uiId;
}
void GameInitHistory()
{
if( ( FileExists( HISTORY_DATA_FILE ) ) )
{
// unlink history file
FileClearAttributes( HISTORY_DATA_FILE );
FileDelete( HISTORY_DATA_FILE );
}
AddHistoryToPlayersLog(HISTORY_ACCEPTED_ASSIGNMENT_FROM_ENRICO, 0, GetWorldTotalMin( ), -1, -1);
}
void EnterHistory()
{
// load the graphics
LoadHistory( );
// create History buttons
CreateHistoryButtons( );
// reset current to first page
if( LaptopSaveInfo.iCurrentHistoryPage > 0 )
iCurrentHistoryPage = LaptopSaveInfo.iCurrentHistoryPage - 1;
else
iCurrentHistoryPage = 0;
// load in first page
LoadNextHistoryPage( );
// render hbackground
RenderHistory( );
// set the fact we are in the history viewer
fInHistoryMode=TRUE;
// build Historys list
//OpenAndReadHistoryFile( );
// force redraw of the entire screen
//fReDrawScreenFlag=TRUE;
// set inital states
SetHistoryButtonStates( );
return;
}
void ExitHistory()
{
LaptopSaveInfo.iCurrentHistoryPage = iCurrentHistoryPage;
// not in History system anymore
fInHistoryMode=FALSE;
// write out history list to file
//OpenAndWriteHistoryFile( );
// delete graphics
RemoveHistory( );
// delete buttons
DestroyHistoryButtons( );
ClearHistoryList( );
return;
}
void HandleHistory()
{
// DEF 2/5/99 Dont need to update EVERY FRAME!!!!
// check and update status of buttons
// SetHistoryButtonStates( );
}
void RenderHistory( void )
{
//render the background to the display
RenderHistoryBackGround( );
// the title bar text
DrawHistoryTitleText( );
// the actual lists background
DisplayHistoryListBackground( );
// the headers to each column
DisplayHistoryListHeaders( );
// render the currentpage of records
DrawAPageofHistoryRecords( );
// stuff at top of page, the date range and page numbers
DisplayPageNumberAndDateRange( );
// title bar icon
BlitTitleBarIcons( );
return;
}
BOOLEAN LoadHistory( void )
{
VOBJECT_DESC VObjectDesc;
// load History video objects into memory
// title bar
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
FilenameForBPP("LAPTOP\\programtitlebar.sti", VObjectDesc.ImageFile);
CHECKF(AddVideoObject(&VObjectDesc, &guiTITLE));
// top portion of the screen background
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
FilenameForBPP("LAPTOP\\historywindow.sti", VObjectDesc.ImageFile);
CHECKF(AddVideoObject(&VObjectDesc, &guiTOP));
// shaded line
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
FilenameForBPP("LAPTOP\\historylines.sti", VObjectDesc.ImageFile);
CHECKF(AddVideoObject(&VObjectDesc, &guiSHADELINE));
/*
Not being used??? DF commented out
// vert line
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
FilenameForBPP("LAPTOP\\historyvertline.sti", VObjectDesc.ImageFile);
CHECKF(AddVideoObject(&VObjectDesc, &guiVERTLINE));
*/
// black divider line - long ( 480 length)
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
FilenameForBPP("LAPTOP\\divisionline480.sti", VObjectDesc.ImageFile);
CHECKF(AddVideoObject(&VObjectDesc, &guiLONGLINE));
return (TRUE);
}
void RemoveHistory( void )
{
// delete history video objects from memory
DeleteVideoObjectFromIndex(guiLONGLINE);
DeleteVideoObjectFromIndex(guiTOP);
DeleteVideoObjectFromIndex(guiTITLE);
DeleteVideoObjectFromIndex(guiSHADELINE);
return;
}
void RenderHistoryBackGround( void )
{
// render generic background for history system
HVOBJECT hHandle;
INT32 iCounter=0;
// get title bar object
GetVideoObject(&hHandle, guiTITLE);
// blt title bar to screen
BltVideoObject(FRAME_BUFFER, hHandle, 0,TOP_X, TOP_Y -2 , VO_BLT_SRCTRANSPARENCY,NULL);
// get and blt the top part of the screen, video object and blt to screen
GetVideoObject(&hHandle, guiTOP);
BltVideoObject(FRAME_BUFFER, hHandle, 0,TOP_X, TOP_Y + 22, VO_BLT_SRCTRANSPARENCY,NULL);
// display background for history list
DisplayHistoryListBackground( );
return;
}
void DrawHistoryTitleText( void )
{
// setup the font stuff
SetFont(HISTORY_HEADER_FONT);
SetFontForeground(FONT_WHITE);
SetFontBackground(FONT_BLACK);
SetFontShadow(DEFAULT_SHADOW);
// draw the pages title
mprintf(TITLE_X,TITLE_Y,pHistoryTitle[0]);
return;
}
void CreateHistoryButtons( void )
{
// the prev page button
giHistoryButtonImage[PREV_PAGE_BUTTON]= LoadButtonImage( "LAPTOP\\arrows.sti" ,-1,0,-1,1,-1 );
giHistoryButton[PREV_PAGE_BUTTON] = QuickCreateButton( giHistoryButtonImage[PREV_PAGE_BUTTON], PREV_BTN_X, BTN_Y,
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
(GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnHistoryDisplayPrevPageCallBack);
// the next page button
giHistoryButtonImage[NEXT_PAGE_BUTTON]= LoadButtonImage( "LAPTOP\\arrows.sti" ,-1,6,-1,7,-1 );
giHistoryButton[NEXT_PAGE_BUTTON] = QuickCreateButton( giHistoryButtonImage[NEXT_PAGE_BUTTON], NEXT_BTN_X, BTN_Y,
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
(GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnHistoryDisplayNextPageCallBack);
// set buttons
SetButtonCursor(giHistoryButton[0], CURSOR_LAPTOP_SCREEN);
SetButtonCursor(giHistoryButton[1], CURSOR_LAPTOP_SCREEN);
return;
}
void DestroyHistoryButtons( void )
{
// remove History buttons and images from memory
// next page button
RemoveButton(giHistoryButton[1] );
UnloadButtonImage(giHistoryButtonImage[1] );
// prev page button
RemoveButton(giHistoryButton[0] );
UnloadButtonImage(giHistoryButtonImage[0] );
return;
}
void BtnHistoryDisplayPrevPageCallBack(GUI_BUTTON *btn,INT32 reason)
{
// force redraw
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
fReDrawScreenFlag=TRUE;
}
// force redraw
if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
fReDrawScreenFlag=TRUE;
btn->uiFlags&=~(BUTTON_CLICKED_ON);
// this page is > 0, there are pages before it, decrement
if(iCurrentHistoryPage > 0)
{
LoadPreviousHistoryPage( );
//iCurrentHistoryPage--;
DrawAPageofHistoryRecords( );
}
// set new state
SetHistoryButtonStates( );
}
}
void BtnHistoryDisplayNextPageCallBack(GUI_BUTTON *btn,INT32 reason)
{
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
fReDrawScreenFlag=TRUE;
}
// force redraw
if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
// increment currentPage
btn->uiFlags&=~(BUTTON_CLICKED_ON);
LoadNextHistoryPage( );
// set new state
SetHistoryButtonStates( );
fReDrawScreenFlag=TRUE;
}
}
BOOLEAN IncrementCurrentPageHistoryDisplay( void )
{
// run through list, from pCurrentHistory, to NUM_RECORDS_PER_PAGE +1 HistoryUnits
HistoryUnitPtr pTempHistory=pCurrentHistory;
BOOLEAN fOkToIncrementPage=FALSE;
INT32 iCounter=0;
HWFILE hFileHandle;
UINT32 uiFileSize=0;
UINT32 uiSizeOfRecordsOnEachPage = 0;
if ( ! (FileExists( HISTORY_DATA_FILE ) ) )
return( FALSE );
// open file
hFileHandle=FileOpen( HISTORY_DATA_FILE,( FILE_OPEN_EXISTING | FILE_ACCESS_READ ), FALSE );
// failed to get file, return
if(!hFileHandle)
{
return( FALSE );
}
// make sure file is more than 0 length
if ( FileGetSize( hFileHandle ) == 0 )
{
FileClose( hFileHandle );
return( FALSE );
}
uiFileSize = FileGetSize( hFileHandle ) - 1;
uiSizeOfRecordsOnEachPage = ( NUM_RECORDS_PER_PAGE * ( sizeof( UINT8 ) + sizeof( UINT32 ) + 3*sizeof( UINT8 )+ sizeof(INT16) + sizeof( INT16 ) ) );
// is the file long enough?
// if( ( FileGetSize( hFileHandle ) - 1 ) / ( NUM_RECORDS_PER_PAGE * ( sizeof( UINT8 ) + sizeof( UINT32 ) + 3*sizeof( UINT8 )+ sizeof(INT16) + sizeof( INT16 ) ) ) + 1 < ( UINT32 )( iCurrentHistoryPage + 1 ) )
if( uiFileSize / uiSizeOfRecordsOnEachPage + 1 < ( UINT32 )( iCurrentHistoryPage + 1 ) )
{
// nope
FileClose( hFileHandle );
return( FALSE );
}
else
{
iCurrentHistoryPage++;
FileClose( hFileHandle );
}
/*
// haven't reached end of list and not yet at beginning of next page
while( ( pTempHistory )&&( ! fOkToIncrementPage ) )
{
// found the next page, first record thereof
if(iCounter==NUM_RECORDS_PER_PAGE+1)
{
fOkToIncrementPage=TRUE;
pCurrentHistory=pTempHistory->Next;
}
//next record
pTempHistory=pTempHistory->Next;
iCounter++;
}
*/
// if ok to increment, increment
return( TRUE );
}
UINT32 ProcessAndEnterAHistoryRecord( UINT8 ubCode, UINT32 uiDate, UINT8 ubSecondCode, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ , UINT8 ubColor )
{
UINT32 uiId=0;
HistoryUnitPtr pHistory=pHistoryListHead;
// add to History list
if(pHistory)
{
// go to end of list
while(pHistory->Next)
pHistory=pHistory->Next;
// alloc space
pHistory->Next = (history *) MemAlloc(sizeof(HistoryUnit));
// increment id number
uiId = pHistory->uiIdNumber + 1;
// set up information passed
pHistory = pHistory->Next;
pHistory->Next = NULL;
pHistory->ubCode = ubCode;
pHistory->ubSecondCode = ubSecondCode;
pHistory->uiDate = uiDate;
pHistory->uiIdNumber = uiId;
pHistory->sSectorX = sSectorX;
pHistory->sSectorY = sSectorY;
pHistory->bSectorZ = bSectorZ;
pHistory->ubColor = ubColor;
}
else
{
// alloc space
pHistory = (HistoryUnitPtr) MemAlloc(sizeof(HistoryUnit));
// setup info passed
pHistory->Next = NULL;
pHistory->ubCode = ubCode;
pHistory->ubSecondCode = ubSecondCode;
pHistory->uiDate = uiDate;
pHistory->uiIdNumber = uiId;
pHistoryListHead = pHistory;
pHistory->sSectorX = sSectorX;
pHistory->sSectorY = sSectorY;
pHistory->bSectorZ = bSectorZ;
pHistory->ubColor = ubColor;
}
return uiId;
}
void OpenAndReadHistoryFile( void )
{
// this procedure will open and read in data to the History list
HWFILE hFileHandle;
UINT8 ubCode, ubSecondCode;
UINT32 uiDate;
INT16 sSectorX, sSectorY;
INT8 bSectorZ = 0;
UINT8 ubColor;
INT32 iBytesRead=0;
UINT32 uiByteCount=0;
// clear out the old list
ClearHistoryList( );
// no file, return
if ( ! (FileExists( HISTORY_DATA_FILE ) ) )
return;
// open file
hFileHandle=FileOpen( HISTORY_DATA_FILE,( FILE_OPEN_EXISTING | FILE_ACCESS_READ ), FALSE );
// failed to get file, return
if(!hFileHandle)
{
return;
}
// make sure file is more than 0 length
if ( FileGetSize( hFileHandle ) == 0 )
{
FileClose( hFileHandle );
return;
}
// file exists, read in data, continue until file end
while( FileGetSize( hFileHandle ) > uiByteCount)
{
// read in other data
FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubSecondCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &uiDate, sizeof(UINT32), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &sSectorX, sizeof(INT16), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &sSectorY, sizeof(INT16), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &bSectorZ, sizeof(INT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubColor, sizeof( UINT8 ), (UINT32 *)&iBytesRead );
#ifdef JA2TESTVERSION
//perform a check on the data to see if it is pooched
PerformCheckOnHistoryRecord( 1, sSectorX, sSectorY, bSectorZ );
#endif
// add transaction
ProcessAndEnterAHistoryRecord( ubCode, uiDate, ubSecondCode, sSectorX, sSectorY, bSectorZ, ubColor );
// increment byte counter
uiByteCount += SIZE_OF_HISTORY_FILE_RECORD;
}
// close file
FileClose( hFileHandle );
return;
}
BOOLEAN OpenAndWriteHistoryFile( void )
{
// this procedure will open and write out data from the History list
HWFILE hFileHandle;
INT32 iBytesWritten=0;
HistoryUnitPtr pHistoryList=pHistoryListHead;
// open file
hFileHandle=FileOpen( HISTORY_DATA_FILE, FILE_ACCESS_WRITE|FILE_CREATE_ALWAYS, FALSE);
// if no file exits, do nothing
if(!hFileHandle)
{
return ( FALSE );
}
// write info, while there are elements left in the list
while(pHistoryList)
{
#ifdef JA2TESTVERSION
//perform a check on the data to see if it is pooched
PerformCheckOnHistoryRecord( 2, pHistoryList->sSectorX, pHistoryList->sSectorY, pHistoryList->bSectorZ );
#endif
// now write date and amount, and code
FileWrite( hFileHandle, &(pHistoryList->ubCode ), sizeof ( UINT8 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->ubSecondCode ), sizeof ( UINT8 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->uiDate ), sizeof ( UINT32 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->sSectorX ), sizeof ( INT16 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->sSectorY ), sizeof ( INT16 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->bSectorZ ), sizeof ( INT8 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->ubColor ), sizeof ( UINT8 ), NULL );
// next element in list
pHistoryList = pHistoryList->Next;
}
// close file
FileClose( hFileHandle );
// clear out the old list
ClearHistoryList( );
return ( TRUE );
}
void ClearHistoryList( void )
{
// remove each element from list of transactions
HistoryUnitPtr pHistoryList=pHistoryListHead;
HistoryUnitPtr pHistoryNode=pHistoryList;
// while there are elements in the list left, delete them
while( pHistoryList )
{
// set node to list head
pHistoryNode=pHistoryList;
// set list head to next node
pHistoryList=pHistoryList->Next;
// delete current node
MemFree(pHistoryNode);
}
pHistoryListHead=NULL;
return;
}
void DisplayHistoryListHeaders( void )
{
// this procedure will display the headers to each column in History
INT16 usX, usY;
// font stuff
SetFont(HISTORY_TEXT_FONT);
SetFontForeground(FONT_BLACK);
SetFontBackground(FONT_BLACK);
SetFontShadow(NO_SHADOW);
// the date header
FindFontCenterCoordinates(RECORD_DATE_X + 5,0,RECORD_DATE_WIDTH,0, pHistoryHeaders[0], HISTORY_TEXT_FONT,&usX, &usY);
mprintf(usX, RECORD_HEADER_Y, pHistoryHeaders[0]);
// the date header
FindFontCenterCoordinates(RECORD_DATE_X + RECORD_DATE_WIDTH + 5,0,RECORD_LOCATION_WIDTH,0, pHistoryHeaders[ 3 ], HISTORY_TEXT_FONT,&usX, &usY);
mprintf(usX, RECORD_HEADER_Y, pHistoryHeaders[3]);
// event header
FindFontCenterCoordinates(RECORD_DATE_X + RECORD_DATE_WIDTH + RECORD_LOCATION_WIDTH + 5,0,RECORD_LOCATION_WIDTH,0, pHistoryHeaders[ 3 ], HISTORY_TEXT_FONT,&usX, &usY);
mprintf(usX, RECORD_HEADER_Y, pHistoryHeaders[4]);
// reset shadow
SetFontShadow(DEFAULT_SHADOW);
return;
}
void DisplayHistoryListBackground( void )
{
// this function will display the History list display background
HVOBJECT hHandle;
INT32 iCounter=0;
// get shaded line object
GetVideoObject(&hHandle, guiSHADELINE);
for(iCounter=0; iCounter <11; iCounter++)
{
// blt title bar to screen
BltVideoObject(FRAME_BUFFER, hHandle, 0,TOP_X + 15, (TOP_DIVLINE_Y + BOX_HEIGHT * 2 * iCounter), VO_BLT_SRCTRANSPARENCY,NULL);
}
// the long hortizontal line int he records list display region
GetVideoObject(&hHandle, guiLONGLINE);
BltVideoObject(FRAME_BUFFER, hHandle, 0,TOP_X + 9, (TOP_DIVLINE_Y ), VO_BLT_SRCTRANSPARENCY,NULL);
BltVideoObject(FRAME_BUFFER, hHandle, 0,TOP_X + 9, (TOP_DIVLINE_Y + BOX_HEIGHT * 2 * 11 ), VO_BLT_SRCTRANSPARENCY,NULL);
return;
}
void DrawHistoryRecordsText( void )
{
// draws the text of the records
HistoryUnitPtr pCurHistory=pHistoryListHead;
HistoryUnitPtr pTempHistory=pHistoryListHead;
CHAR16 sString[512];
INT32 iCounter=0;
INT16 usX, usY;
INT32 iBalance=0;
INT16 sX =0, sY =0;
// setup the font stuff
SetFont(HISTORY_TEXT_FONT);
SetFontForeground(FONT_BLACK);
SetFontBackground(FONT_BLACK);
SetFontShadow(NO_SHADOW);
// error check
if( !pCurHistory)
return;
// loop through record list
for(iCounter; iCounter <NUM_RECORDS_PER_PAGE; iCounter++)
{
if( pCurHistory->ubColor == 0 )
{
SetFontForeground(FONT_BLACK);
}
else
{
SetFontForeground(FONT_RED);
}
// get and write the date
swprintf(sString, L"%d", ( pCurHistory->uiDate / ( 24 * 60 ) ) );
FindFontCenterCoordinates(RECORD_DATE_X + 5, 0, RECORD_DATE_WIDTH,0, sString, HISTORY_TEXT_FONT,&usX, &usY);
mprintf(usX, RECORD_Y + ( iCounter * ( BOX_HEIGHT ) ) + 3, sString);
// now the actual history text
//FindFontCenterCoordinates(RECORD_DATE_X + RECORD_DATE_WIDTH,0,RECORD_HISTORY_WIDTH,0, pHistoryStrings[pCurHistory->ubCode], HISTORY_TEXT_FONT,&usX, &usY);
ProcessHistoryTransactionString(sString, pCurHistory);
// mprintf(RECORD_DATE_X + RECORD_DATE_WIDTH + 25, RECORD_Y + ( iCounter * ( BOX_HEIGHT ) ) + 3, pHistoryStrings[pCurHistory->ubCode] );
mprintf(RECORD_DATE_X + RECORD_LOCATION_WIDTH +RECORD_DATE_WIDTH + 15, RECORD_Y + ( iCounter * ( BOX_HEIGHT ) ) + 3, sString );
// no location
if( ( pCurHistory->sSectorX == -1 )||( pCurHistory->sSectorY == -1 ) )
{
FindFontCenterCoordinates( RECORD_DATE_X + RECORD_DATE_WIDTH, 0,RECORD_LOCATION_WIDTH + 10, 0, pHistoryLocations[0] ,HISTORY_TEXT_FONT, &sX, &sY );
mprintf(sX, RECORD_Y + ( iCounter * ( BOX_HEIGHT ) ) + 3, pHistoryLocations[0] );
}
else
{
GetSectorIDString( pCurHistory->sSectorX, pCurHistory->sSectorY, pCurHistory->bSectorZ, sString, TRUE );
FindFontCenterCoordinates( RECORD_DATE_X + RECORD_DATE_WIDTH, 0, RECORD_LOCATION_WIDTH + 10, 0, sString ,HISTORY_TEXT_FONT, &sX, &sY );
ReduceStringLength( sString, RECORD_LOCATION_WIDTH + 10, HISTORY_TEXT_FONT );
mprintf(sX, RECORD_Y + ( iCounter * ( BOX_HEIGHT ) ) + 3, sString );
}
// restore font color
SetFontForeground(FONT_BLACK);
// next History
pCurHistory = pCurHistory->Next;
// last page, no Historys left, return
if( ! pCurHistory )
{
// restore shadow
SetFontShadow(DEFAULT_SHADOW);
return;
}
}
// restore shadow
SetFontShadow(DEFAULT_SHADOW);
return;
}
void DrawAPageofHistoryRecords( void )
{
// this procedure will draw a series of history records to the screen
INT32 iCurPage=1;
INT32 iCount=0;
pCurrentHistory=pHistoryListHead;
// (re-)render background
// the title bar text
DrawHistoryTitleText( );
// the actual lists background
DisplayHistoryListBackground( );
// the headers to each column
DisplayHistoryListHeaders( );
// error check
if(iCurrentHistoryPage==-1)
{
iCurrentHistoryPage=0;
}
// current page is found, render from here
DrawHistoryRecordsText( );
// update page numbers, and date ranges
DisplayPageNumberAndDateRange( );
return;
}
void DisplayPageNumberAndDateRange( void )
{
// this function will go through the list of 'histories' starting at current until end or
// MAX_PER_PAGE...it will get the date range and the page number
INT32 iLastPage=0;
INT32 iCounter=0;
UINT32 uiLastDate;
HistoryUnitPtr pTempHistory=pHistoryListHead;
CHAR16 sString[50];
// setup the font stuff
SetFont(HISTORY_TEXT_FONT);
SetFontForeground(FONT_BLACK);
SetFontBackground(FONT_BLACK);
SetFontShadow(NO_SHADOW);
if( !pCurrentHistory )
{
swprintf( sString, L"%s %d / %d",pHistoryHeaders[1], 1, 1 );
mprintf( PAGE_NUMBER_X, PAGE_NUMBER_Y, sString );
swprintf( sString, L"%s %d - %d",pHistoryHeaders[2], 1 , 1 );
mprintf( HISTORY_DATE_X, HISTORY_DATE_Y, sString );
// reset shadow
SetFontShadow(DEFAULT_SHADOW);
return;
}
uiLastDate=pCurrentHistory->uiDate;
/*
// find last page
while(pTempHistory)
{
iCounter++;
pTempHistory=pTempHistory->Next;
}
// set last page
iLastPage=iCounter/NUM_RECORDS_PER_PAGE;
*/
iLastPage = GetNumberOfHistoryPages();
// set temp to current, to get last date
pTempHistory=pCurrentHistory;
// reset counter
iCounter=0;
// run through list until end or num_records, which ever first
while((pTempHistory)&&(iCounter < NUM_RECORDS_PER_PAGE))
{
uiLastDate=pTempHistory->uiDate;
iCounter++;
pTempHistory = pTempHistory->Next;
}
// get the last page
swprintf( sString, L"%s %d / %d",pHistoryHeaders[1], iCurrentHistoryPage , iLastPage +1 );
mprintf( PAGE_NUMBER_X, PAGE_NUMBER_Y, sString );
swprintf( sString, L"%s %d - %d",pHistoryHeaders[2], pCurrentHistory->uiDate / ( 24 * 60 ) , uiLastDate/( 24 * 60 ) );
mprintf( HISTORY_DATE_X, HISTORY_DATE_Y, sString );
// reset shadow
SetFontShadow(DEFAULT_SHADOW);
return;
}
void ProcessHistoryTransactionString(STR16 pString, HistoryUnitPtr pHistory)
{
CHAR16 sString[ 128 ];
switch( pHistory->ubCode)
{
case HISTORY_ENTERED_HISTORY_MODE:
swprintf(pString, pHistoryStrings[ HISTORY_ENTERED_HISTORY_MODE ]);
break;
case HISTORY_HIRED_MERC_FROM_AIM:
swprintf(pString, pHistoryStrings[ HISTORY_HIRED_MERC_FROM_AIM ], gMercProfiles[pHistory->ubSecondCode].zName );
break;
case HISTORY_MERC_KILLED:
if( pHistory->ubSecondCode != NO_PROFILE )
swprintf(pString, pHistoryStrings[ HISTORY_MERC_KILLED ], gMercProfiles[pHistory->ubSecondCode].zName );
#ifdef JA2BETAVERSION
else
{
swprintf(pString, pHistoryStrings[ HISTORY_MERC_KILLED ], L"ERROR!!! NO_PROFILE" );
}
#endif
break;
case HISTORY_HIRED_MERC_FROM_MERC:
swprintf(pString, pHistoryStrings[ HISTORY_HIRED_MERC_FROM_MERC ], gMercProfiles[pHistory->ubSecondCode].zName );
break;
case HISTORY_SETTLED_ACCOUNTS_AT_MERC:
swprintf(pString, pHistoryStrings[ HISTORY_SETTLED_ACCOUNTS_AT_MERC ] );
break;
case HISTORY_ACCEPTED_ASSIGNMENT_FROM_ENRICO:
swprintf(pString, pHistoryStrings[ HISTORY_ACCEPTED_ASSIGNMENT_FROM_ENRICO ] );
break;
case( HISTORY_CHARACTER_GENERATED ):
swprintf(pString, pHistoryStrings[ HISTORY_CHARACTER_GENERATED ] );
break;
case( HISTORY_PURCHASED_INSURANCE ):
swprintf(pString, pHistoryStrings[ HISTORY_PURCHASED_INSURANCE ], gMercProfiles[pHistory->ubSecondCode].zNickname );
break;
case( HISTORY_CANCELLED_INSURANCE ):
swprintf(pString, pHistoryStrings[ HISTORY_CANCELLED_INSURANCE ], gMercProfiles[pHistory->ubSecondCode].zNickname );
break;
case( HISTORY_INSURANCE_CLAIM_PAYOUT ):
swprintf(pString, pHistoryStrings[ HISTORY_INSURANCE_CLAIM_PAYOUT ], gMercProfiles[pHistory->ubSecondCode].zNickname );
break;
case HISTORY_EXTENDED_CONTRACT_1_DAY:
swprintf(pString, pHistoryStrings[ HISTORY_EXTENDED_CONTRACT_1_DAY ], gMercProfiles[pHistory->ubSecondCode].zNickname );
break;
case HISTORY_EXTENDED_CONTRACT_1_WEEK:
swprintf(pString, pHistoryStrings[ HISTORY_EXTENDED_CONTRACT_1_WEEK ], gMercProfiles[pHistory->ubSecondCode].zNickname );
break;
case HISTORY_EXTENDED_CONTRACT_2_WEEK:
swprintf(pString, pHistoryStrings[ HISTORY_EXTENDED_CONTRACT_2_WEEK ], gMercProfiles[pHistory->ubSecondCode].zNickname );
break;
case( HISTORY_MERC_FIRED ):
swprintf(pString, pHistoryStrings[ HISTORY_MERC_FIRED ], gMercProfiles[pHistory->ubSecondCode].zNickname );
break;
case( HISTORY_MERC_QUIT ):
swprintf(pString, pHistoryStrings[ HISTORY_MERC_QUIT ], gMercProfiles[pHistory->ubSecondCode].zNickname );
break;
case( HISTORY_QUEST_STARTED ):
GetQuestStartedString( pHistory->ubSecondCode, sString );
swprintf(pString, sString );
break;
case( HISTORY_QUEST_FINISHED ):
GetQuestEndedString( pHistory->ubSecondCode, sString );
swprintf(pString, sString );
break;
case( HISTORY_TALKED_TO_MINER ):
swprintf(pString, pHistoryStrings[ HISTORY_TALKED_TO_MINER ], pTownNames[ pHistory->ubSecondCode ] );
break;
case( HISTORY_LIBERATED_TOWN ):
swprintf(pString, pHistoryStrings[ HISTORY_LIBERATED_TOWN ], pTownNames[ pHistory->ubSecondCode ] );
break;
case( HISTORY_CHEAT_ENABLED ):
swprintf(pString, pHistoryStrings[ HISTORY_CHEAT_ENABLED ] );
break;
case HISTORY_TALKED_TO_FATHER_WALKER:
swprintf( pString, pHistoryStrings[ HISTORY_TALKED_TO_FATHER_WALKER ] );
break;
case HISTORY_MERC_MARRIED_OFF:
swprintf( pString, pHistoryStrings[ HISTORY_MERC_MARRIED_OFF ], gMercProfiles[pHistory->ubSecondCode].zNickname );
break;
case HISTORY_MERC_CONTRACT_EXPIRED:
swprintf( pString, pHistoryStrings[ HISTORY_MERC_CONTRACT_EXPIRED ], gMercProfiles[pHistory->ubSecondCode].zName );
break;
case HISTORY_RPC_JOINED_TEAM:
swprintf( pString, pHistoryStrings[ HISTORY_RPC_JOINED_TEAM ], gMercProfiles[pHistory->ubSecondCode].zName );
break;
case HISTORY_ENRICO_COMPLAINED:
swprintf( pString, pHistoryStrings[ HISTORY_ENRICO_COMPLAINED ] );
break;
case HISTORY_MINE_RUNNING_OUT:
case HISTORY_MINE_RAN_OUT:
case HISTORY_MINE_SHUTDOWN:
case HISTORY_MINE_REOPENED:
// all the same format
swprintf(pString, pHistoryStrings[ pHistory->ubCode ], pTownNames[ pHistory->ubSecondCode ] );
break;
case HISTORY_LOST_BOXING:
case HISTORY_WON_BOXING:
case HISTORY_DISQUALIFIED_BOXING:
case HISTORY_NPC_KILLED:
case HISTORY_MERC_KILLED_CHARACTER:
swprintf( pString, pHistoryStrings[ pHistory->ubCode ], gMercProfiles[pHistory->ubSecondCode].zNickname );
break;
// ALL SIMPLE HISTORY LOG MSGS, NO PARAMS
case HISTORY_FOUND_MONEY:
case HISTORY_ASSASSIN:
case HISTORY_DISCOVERED_TIXA:
case HISTORY_DISCOVERED_ORTA:
case HISTORY_GOT_ROCKET_RIFLES:
case HISTORY_DEIDRANNA_DEAD_BODIES:
case HISTORY_BOXING_MATCHES:
case HISTORY_SOMETHING_IN_MINES:
case HISTORY_DEVIN:
case HISTORY_MIKE:
case HISTORY_TONY:
case HISTORY_KROTT:
case HISTORY_KYLE:
case HISTORY_MADLAB:
case HISTORY_GABBY:
case HISTORY_KEITH_OUT_OF_BUSINESS:
case HISTORY_HOWARD_CYANIDE:
case HISTORY_KEITH:
case HISTORY_HOWARD:
case HISTORY_PERKO:
case HISTORY_SAM:
case HISTORY_FRANZ:
case HISTORY_ARNOLD:
case HISTORY_FREDO:
case HISTORY_RICHGUY_BALIME:
case HISTORY_JAKE:
case HISTORY_BUM_KEYCARD:
case HISTORY_WALTER:
case HISTORY_DAVE:
case HISTORY_PABLO:
case HISTORY_KINGPIN_MONEY:
//VARIOUS BATTLE CONDITIONS
case HISTORY_LOSTTOWNSECTOR:
case HISTORY_DEFENDEDTOWNSECTOR:
case HISTORY_LOSTBATTLE:
case HISTORY_WONBATTLE:
case HISTORY_FATALAMBUSH:
case HISTORY_WIPEDOUTENEMYAMBUSH:
case HISTORY_UNSUCCESSFULATTACK:
case HISTORY_SUCCESSFULATTACK:
case HISTORY_CREATURESATTACKED:
case HISTORY_KILLEDBYBLOODCATS:
case HISTORY_SLAUGHTEREDBLOODCATS:
case HISTORY_GAVE_CARMEN_HEAD:
case HISTORY_SLAY_MYSTERIOUSLY_LEFT:
swprintf( pString, pHistoryStrings[ pHistory->ubCode ] );
break;
}
}
void DrawHistoryLocation( INT16 sSectorX, INT16 sSectorY )
{
// will draw the location of the history event
return;
}
void SetHistoryButtonStates( void )
{
// this function will look at what page we are viewing, enable and disable buttons as needed
if( iCurrentHistoryPage == 1 )
{
// first page, disable left buttons
DisableButton( giHistoryButton[PREV_PAGE_BUTTON] );
}
else
{
// enable buttons
EnableButton( giHistoryButton[PREV_PAGE_BUTTON] );
}
if( IncrementCurrentPageHistoryDisplay( ) )
{
// decrement page
iCurrentHistoryPage--;
DrawAPageofHistoryRecords( );
// enable buttons
EnableButton( giHistoryButton[ NEXT_PAGE_BUTTON ] );
}
else
{
DisableButton( giHistoryButton[ NEXT_PAGE_BUTTON ] );
}
}
BOOLEAN LoadInHistoryRecords( UINT32 uiPage )
{
// loads in records belogning, to page uiPage
// no file, return
BOOLEAN fOkToContinue=TRUE;
INT32 iCount =0;
HWFILE hFileHandle;
UINT8 ubCode, ubSecondCode;
INT16 sSectorX, sSectorY;
INT8 bSectorZ;
UINT32 uiDate;
UINT8 ubColor;
INT32 iBytesRead=0;
UINT32 uiByteCount=0;
// check if bad page
if( uiPage == 0 )
{
return ( FALSE );
}
if ( ! (FileExists( HISTORY_DATA_FILE ) ) )
return( FALSE );
// open file
hFileHandle=FileOpen( HISTORY_DATA_FILE,( FILE_OPEN_EXISTING | FILE_ACCESS_READ ), FALSE );
// failed to get file, return
if(!hFileHandle)
{
return( FALSE );
}
// make sure file is more than 0 length
if ( FileGetSize( hFileHandle ) == 0 )
{
FileClose( hFileHandle );
return( FALSE );
}
// is the file long enough?
if( ( FileGetSize( hFileHandle ) - 1 ) / ( NUM_RECORDS_PER_PAGE * SIZE_OF_HISTORY_FILE_RECORD ) + 1 < uiPage )
{
// nope
FileClose( hFileHandle );
return( FALSE );
}
FileSeek( hFileHandle, ( uiPage - 1 ) * NUM_RECORDS_PER_PAGE * ( SIZE_OF_HISTORY_FILE_RECORD), FILE_SEEK_FROM_START );
uiByteCount = ( uiPage - 1 ) * NUM_RECORDS_PER_PAGE * (SIZE_OF_HISTORY_FILE_RECORD );
// file exists, read in data, continue until end of page
while( ( iCount < NUM_RECORDS_PER_PAGE )&&( fOkToContinue ) )
{
// read in other data
FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubSecondCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &uiDate, sizeof(UINT32), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &sSectorX, sizeof(INT16), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &sSectorY, sizeof(INT16), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &bSectorZ, sizeof(INT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubColor, sizeof(UINT8), (UINT32 *)&iBytesRead );
#ifdef JA2TESTVERSION
//perform a check on the data to see if it is pooched
PerformCheckOnHistoryRecord( 3, sSectorX, sSectorY, bSectorZ );
#endif
// add transaction
ProcessAndEnterAHistoryRecord(ubCode, uiDate, ubSecondCode, sSectorX, sSectorY, bSectorZ, ubColor);
// increment byte counter
uiByteCount += SIZE_OF_HISTORY_FILE_RECORD;
// we've overextended our welcome, and bypassed end of file, get out
if( uiByteCount >= FileGetSize( hFileHandle ) )
{
// not ok to continue
fOkToContinue = FALSE;
}
iCount++;
}
// close file
FileClose( hFileHandle );
// check to see if we in fact have a list to display
if( pHistoryListHead == NULL )
{
// got no records, return false
return( FALSE );
}
// set up current finance
pCurrentHistory = pHistoryListHead;
return( TRUE );
}
BOOLEAN WriteOutHistoryRecords( UINT32 uiPage )
{
// loads in records belogning, to page uiPage
// no file, return
BOOLEAN fOkToContinue=TRUE;
INT32 iCount =0;
HWFILE hFileHandle;
HistoryUnitPtr pList;
INT32 iBytesRead=0;
UINT32 uiByteCount=0;
// check if bad page
if( uiPage == 0 )
{
return ( FALSE );
}
if ( ! (FileExists( HISTORY_DATA_FILE ) ) )
return( FALSE );
// open file
hFileHandle=FileOpen( HISTORY_DATA_FILE,( FILE_OPEN_EXISTING | FILE_ACCESS_WRITE ), FALSE );
// failed to get file, return
if(!hFileHandle)
{
return( FALSE );
}
// make sure file is more than 0 length
if ( FileGetSize( hFileHandle ) == 0 )
{
FileClose( hFileHandle );
return( FALSE );
}
// is the file long enough?
if( ( FileGetSize( hFileHandle ) - 1 ) / ( NUM_RECORDS_PER_PAGE * SIZE_OF_HISTORY_FILE_RECORD ) + 1 < uiPage )
{
// nope
FileClose( hFileHandle );
return( FALSE );
}
pList = pHistoryListHead;
if( pList == NULL )
{
return( FALSE );
}
FileSeek( hFileHandle, sizeof( INT32 ) + ( uiPage - 1 ) * NUM_RECORDS_PER_PAGE * SIZE_OF_HISTORY_FILE_RECORD, FILE_SEEK_FROM_START );
uiByteCount = /*sizeof( INT32 )+ */( uiPage - 1 ) * NUM_RECORDS_PER_PAGE * SIZE_OF_HISTORY_FILE_RECORD;
// file exists, read in data, continue until end of page
while( ( iCount < NUM_RECORDS_PER_PAGE )&&( fOkToContinue ) )
{
#ifdef JA2TESTVERSION
//perform a check on the data to see if it is pooched
PerformCheckOnHistoryRecord( 4, pList->sSectorX, pList->sSectorY, pList->bSectorZ );
#endif
FileWrite( hFileHandle, &(pList->ubCode ), sizeof ( UINT8 ), NULL );
FileWrite( hFileHandle, &(pList->ubSecondCode ), sizeof ( UINT8 ), NULL );
FileWrite( hFileHandle, &(pList->uiDate ), sizeof ( UINT32 ), NULL );
FileWrite( hFileHandle, &(pList->sSectorX ), sizeof ( INT16 ), NULL );
FileWrite( hFileHandle, &(pList->sSectorY ), sizeof ( INT16 ), NULL );
FileWrite( hFileHandle, &(pList->bSectorZ ), sizeof ( INT8 ), NULL );
FileWrite( hFileHandle, &(pList->ubColor ), sizeof ( UINT8 ), NULL );
pList = pList->Next;
// we've overextended our welcome, and bypassed end of file, get out
if( pList == NULL )
{
// not ok to continue
fOkToContinue = FALSE;
}
iCount++;
}
// close file
FileClose( hFileHandle );
ClearHistoryList( );
return( TRUE );
}
BOOLEAN LoadNextHistoryPage( void )
{
// clear out old list of records, and load in previous page worth of records
ClearHistoryList( );
// now load in previous page's records, if we can
if ( LoadInHistoryRecords( iCurrentHistoryPage + 1 ) )
{
iCurrentHistoryPage++;
return ( TRUE );
}
else
{
LoadInHistoryRecords( iCurrentHistoryPage );
return ( FALSE );
}
}
BOOLEAN LoadPreviousHistoryPage( void )
{
// clear out old list of records, and load in previous page worth of records
ClearHistoryList( );
// load previous page
if( ( iCurrentHistoryPage == 1 ) )
{
return ( FALSE );
}
// now load in previous page's records, if we can
if ( LoadInHistoryRecords( iCurrentHistoryPage - 1 ) )
{
iCurrentHistoryPage--;
return ( TRUE );
}
else
{
LoadInHistoryRecords( iCurrentHistoryPage );
return ( FALSE );
}
}
void SetLastPageInHistoryRecords( void )
{
// grabs the size of the file and interprets number of pages it will take up
HWFILE hFileHandle;
INT32 iBytesRead=0;
// no file, return
if ( ! (FileExists( HISTORY_DATA_FILE ) ) )
return;
// open file
hFileHandle=FileOpen( HISTORY_DATA_FILE,( FILE_OPEN_EXISTING | FILE_ACCESS_READ ), FALSE );
// failed to get file, return
if(!hFileHandle)
{
guiLastPageInHistoryRecordsList = 1;
return;
}
// make sure file is more than 0 length
if ( FileGetSize( hFileHandle ) == 0 )
{
FileClose( hFileHandle );
guiLastPageInHistoryRecordsList = 1;
return;
}
// done with file, close it
FileClose( hFileHandle );
guiLastPageInHistoryRecordsList = ReadInLastElementOfHistoryListAndReturnIdNumber( ) / NUM_RECORDS_PER_PAGE;
return;
}
UINT32 ReadInLastElementOfHistoryListAndReturnIdNumber( void )
{
// this function will read in the last unit in the history list, to grab it's id number
HWFILE hFileHandle;
INT32 iBytesRead=0;
INT32 iFileSize = 0;
// no file, return
if ( ! (FileExists( HISTORY_DATA_FILE ) ) )
return 0;
// open file
hFileHandle=FileOpen( HISTORY_DATA_FILE,( FILE_OPEN_EXISTING | FILE_ACCESS_READ ), FALSE );
// failed to get file, return
if(!hFileHandle)
{
return 0;
}
// make sure file is more than balance size + length of 1 record - 1 byte
if ( FileGetSize( hFileHandle ) < SIZE_OF_HISTORY_FILE_RECORD )
{
FileClose( hFileHandle );
return 0;
}
// size is?
iFileSize = FileGetSize( hFileHandle );
// done with file, close it
FileClose( hFileHandle );
// file size / sizeof record in bytes is id
return ( ( iFileSize ) / ( SIZE_OF_HISTORY_FILE_RECORD ) );
}
BOOLEAN AppendHistoryToEndOfFile( HistoryUnitPtr pHistory )
{
// will write the current finance to disk
HWFILE hFileHandle;
INT32 iBytesWritten=0;
HistoryUnitPtr pHistoryList=pHistoryListHead;
// open file
hFileHandle=FileOpen( HISTORY_DATA_FILE, FILE_ACCESS_WRITE|FILE_OPEN_ALWAYS, FALSE);
// if no file exits, do nothing
if(!hFileHandle)
{
return ( FALSE );
}
// go to the end
if( FileSeek( hFileHandle,0,FILE_SEEK_FROM_END ) == FALSE )
{
// error
FileClose( hFileHandle );
return( FALSE );
}
#ifdef JA2TESTVERSION
//perform a check on the data to see if it is pooched
PerformCheckOnHistoryRecord( 5, pHistoryList->sSectorX, pHistoryList->sSectorY, pHistoryList->bSectorZ );
#endif
// now write date and amount, and code
FileWrite( hFileHandle, &(pHistoryList->ubCode ), sizeof ( UINT8 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->ubSecondCode ), sizeof ( UINT8 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->uiDate ), sizeof ( UINT32 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->sSectorX ), sizeof ( INT16 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->sSectorY ), sizeof ( INT16 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->bSectorZ ), sizeof ( INT8 ), NULL );
FileWrite( hFileHandle, &(pHistoryList->ubColor ), sizeof ( UINT8 ), NULL );
// close file
FileClose( hFileHandle );
return( TRUE );
}
void ResetHistoryFact( UINT8 ubCode, INT16 sSectorX, INT16 sSectorY )
{
// run through history list
INT32 iOldHistoryPage = iCurrentHistoryPage;
HistoryUnitPtr pList = pHistoryListHead;
BOOLEAN fFound = FALSE;
// set current page to before list
iCurrentHistoryPage = 0;
SetLastPageInHistoryRecords( );
OpenAndReadHistoryFile( );
pList = pHistoryListHead;
while( pList )
{
if( ( pList -> ubSecondCode == ubCode ) && ( pList->ubCode == HISTORY_QUEST_STARTED ) )
{
// reset color
pList -> ubColor = 0;
fFound = TRUE;
// save
OpenAndWriteHistoryFile( );
pList = NULL;
}
if( fFound != TRUE )
{
pList = pList->Next;
}
}
if( fInHistoryMode )
{
iCurrentHistoryPage--;
// load in first page
LoadNextHistoryPage( );
}
SetHistoryFact( HISTORY_QUEST_FINISHED, ubCode, GetWorldTotalMin(), sSectorX, sSectorY );
return;
}
UINT32 GetTimeQuestWasStarted( UINT8 ubCode )
{
// run through history list
INT32 iOldHistoryPage = iCurrentHistoryPage;
HistoryUnitPtr pList = pHistoryListHead;
BOOLEAN fFound = FALSE;
UINT32 uiTime = 0;
// set current page to before list
iCurrentHistoryPage = 0;
SetLastPageInHistoryRecords( );
OpenAndReadHistoryFile( );
pList = pHistoryListHead;
while( pList )
{
if( ( pList -> ubSecondCode == ubCode ) && ( pList->ubCode == HISTORY_QUEST_STARTED ) )
{
uiTime = pList->uiDate;
fFound = TRUE;
pList = NULL;
}
if( fFound != TRUE )
{
pList = pList->Next;
}
}
if( fInHistoryMode )
{
iCurrentHistoryPage--;
// load in first page
LoadNextHistoryPage( );
}
return( uiTime );
}
void GetQuestStartedString( UINT8 ubQuestValue, STR16 sQuestString )
{
// open the file and copy the string
LoadEncryptedDataFromFile( "BINARYDATA\\quests.edt", sQuestString, 160 * ( ubQuestValue * 2 ), 160 );
}
void GetQuestEndedString( UINT8 ubQuestValue, STR16 sQuestString )
{
// open the file and copy the string
LoadEncryptedDataFromFile( "BINARYDATA\\quests.edt", sQuestString, 160 * ( ( ubQuestValue * 2 ) + 1), 160 );
}
#ifdef JA2TESTVERSION
void PerformCheckOnHistoryRecord( UINT32 uiErrorCode, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
CHAR zString[512];
if( sSectorX > 16 || sSectorY > 16 || bSectorZ > 3 || sSectorX < -1 || sSectorY < -1 || bSectorZ < 0 )
{
sprintf( zString, "History page is pooched, please remember what you were just doing, send your latest save to dave, and tell him this number, Error #%d.", uiErrorCode );
AssertMsg( 0, zString );
}
}
#endif
INT32 GetNumberOfHistoryPages()
{
HWFILE hFileHandle;
UINT32 uiFileSize=0;
UINT32 uiSizeOfRecordsOnEachPage = 0;
INT32 iNumberOfHistoryPages = 0;
if ( ! (FileExists( HISTORY_DATA_FILE ) ) )
return( 0 );
// open file
hFileHandle=FileOpen( HISTORY_DATA_FILE,( FILE_OPEN_EXISTING | FILE_ACCESS_READ ), FALSE );
// failed to get file, return
if(!hFileHandle)
{
return( 0 );
}
// make sure file is more than 0 length
if ( FileGetSize( hFileHandle ) == 0 )
{
FileClose( hFileHandle );
return( 0 );
}
uiFileSize = FileGetSize( hFileHandle ) - 1;
uiSizeOfRecordsOnEachPage = ( NUM_RECORDS_PER_PAGE * ( sizeof( UINT8 ) + sizeof( UINT32 ) + 3*sizeof( UINT8 )+ sizeof(INT16) + sizeof( INT16 ) ) );
iNumberOfHistoryPages = (INT32)( uiFileSize / uiSizeOfRecordsOnEachPage );
FileClose( hFileHandle );
return( iNumberOfHistoryPages );
}