Files
source/Tactical/World Items.cpp
T
Kriplo f008316275 Brief: //dnl ch74
- Couple map editor fixes.
Details:
- Map loading not properly set Vanilla global variable switch.
- Loading AIMNAS maps of version 28 cause CTD due to incorrect StackedObjectData loading sizeof.
- Only in editor mode and if NAS setting is on inseparable and default attachments will be always add, but default attachments will not, so older maps should be converted from mapeditor to new version.
- Fix CTD if try to place items from tab selection which contains no items.
- There was missing part from ch4 for mouse wheel support in mapeditor.
- There was conflict between keyboard and mouse events creating problems when try to select taskbar options by mouse.
- Fix annoying message of using improper attachment during item place if item consist of default or inseparable attachments.
- Remove hints to display if loading map from editor.
- Fix CTD if have previously selected merc and loading another (smaller) map.
- Saving map as Vanilla will check if attachment is valid for 1.12, that means you will lost some stuff from NIV if save in Vanilla mode, so you should always save map in newest format if want play map in 1.13.
- Add correct weight recalculation when saving in Vanilla format using old OBJECTTYPE.
- Remove entry points check during map save as Scheinworld reported problem with basement levels and similar maps which doesn't need entry points.
- Fix displaying wrong map version in summary window because MapInfo is incorrectly saved in all previous mapeditors.


git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6530 3b4a5df2-a311-0410-b5c6-a8a6f20db521
2013-10-25 18:48:37 +00:00

872 lines
25 KiB
C++

#ifdef PRECOMPILEDHEADERS
#include "Tactical All.h"
#else
#include "items.h"
#include "handle Items.h"
#include "overhead.h"
#include "weapons.h"
#include "tiledef.h"
#include "worlddef.h"
#include "interface.h"
#include "renderworld.h"
#include "Animation Control.h"
#include "font control.h"
#include "World items.h"
#include "debug.h"
#include "Isometric utils.h"
#include "sys globals.h"
#include "Tactical Save.h"
#include "strategicmap.h"
#include "Campaign Types.h"
#include "random.h"
#include "Action Items.h"
#include "pits.h"
#include "GameSettings.h"
#include "Quests.h"
#include "Soldier Profile.h"
#include "message.h"
#include "map screen interface map inventory.h" // added by Flugente
#include "connect.h"
#endif
//Global dynamic array of all of the items in a loaded map.
WORLDITEM * gWorldItems = NULL;
UINT32 guiNumWorldItems = 0;
WORLDBOMB * gWorldBombs = NULL;
UINT32 guiNumWorldBombs = 0;
void DeleteWorldItemsBelongingToTerroristsWhoAreNotThere( void );
void DeleteWorldItemsBelongingToQueenIfThere( void );
extern UINT16 StandardGunListAmmoReplacement( UINT16 usAmmo );
extern UINT8 GetDealerItemCategoryNumber( UINT16 usItemIndex );
//dnl ch33 120909
OLD_WORLDITEM_101& OLD_WORLDITEM_101::operator=(WORLDITEM& src)
{
if((void*)this != (void*)&src)
{
memset(this, 0, sizeof(OLD_WORLDITEM_101));
this->fExists = src.fExists;
this->sGridNo = src.sGridNo;
this->ubLevel = src.ubLevel;
this->usFlags = src.usFlags;
this->bRenderZHeightAboveLevel = src.bRenderZHeightAboveLevel;
this->bVisible = src.bVisible;
this->ubNonExistChance = src.ubNonExistChance;
this->oldObject = src.object;
}
return(*this);
}
bool WORLDITEM::operator<(WORLDITEM& compare)
{
if ( this->fExists == false || this->object.exists() == false) {
return false;
}
if ( compare.fExists == false || compare.object.exists() == false) {
return true;
}
UINT8 ubItem1Category = GetDealerItemCategoryNumber( this->object.usItem );
UINT8 ubItem2Category = GetDealerItemCategoryNumber( compare.object.usItem );
// lower category first
if ( ubItem1Category < ubItem2Category ) {
return( true );
}
else if ( ubItem1Category > ubItem2Category ) {
return false;
}
// the same category
//Madd: sort by name (for now at least):
int retVal = _wcsicmp(Item[this->object.usItem].szBRName,Item[compare.object.usItem].szBRName);
if ( retVal < 0 ) {
return true;
}
else if ( retVal > 0 ) {
return false;
}
if (this->object.ubNumberOfObjects > compare.object.ubNumberOfObjects) {
return true;
}
else if (this->object.ubNumberOfObjects < compare.object.ubNumberOfObjects) {
return false;
}
/*
if (this->object[0]->attachments.size() > compare.object[0]->attachments.size()) {
return true;
}
else if (this->object[0]->attachments.size() < compare.object[0]->attachments.size()) {
return false;
}
*/
// higher quality first
if ( this->object[0]->data.objectStatus > compare.object[0]->data.objectStatus ) {
return( true );
}
else {
// identical items!
return( false );
}
return false;
}
void WORLDITEM::initialize()
{
this->fExists = 0;
this->sGridNo = 0;
this->ubLevel = 0;
this->usFlags = 0;
this->bRenderZHeightAboveLevel = 0;
this->bVisible = 0;
this->ubNonExistChance = 0;
this->soldierID = -1;
this->object.initialize();
}
WORLDITEM& WORLDITEM::operator=(OLD_WORLDITEM_101& src)
{
//the first conversion is simple enough that it can be done here
this->fExists = src.fExists;
this->sGridNo = src.sGridNo;
this->ubLevel = src.ubLevel;
this->usFlags = src.usFlags;
this->bRenderZHeightAboveLevel = src.bRenderZHeightAboveLevel;
this->bVisible = src.bVisible;
this->ubNonExistChance = src.ubNonExistChance;
this->soldierID = -1;
//convert the OBJECTTYPE
this->object = src.oldObject;
return *this;
}
WORLDITEM& WORLDITEM::operator=(_OLD_WORLDITEM& src)//dnl ch42 280909
{
if((void*)this != (void*)&src)
{
fExists = src.fExists;
sGridNo = src.sGridNo;
ubLevel = src.ubLevel;
usFlags = src.usFlags;
bRenderZHeightAboveLevel = src.bRenderZHeightAboveLevel;
bVisible = src.bVisible;
ubNonExistChance = src.ubNonExistChance;
soldierID = -1;
object = src.object;
}
return(*this);
}
WORLDITEM& WORLDITEM::operator=(const WORLDITEM& src)
{
this->fExists = src.fExists;
this->sGridNo = src.sGridNo;
this->ubLevel = src.ubLevel;
this->usFlags = src.usFlags;
this->bRenderZHeightAboveLevel = src.bRenderZHeightAboveLevel;
this->bVisible = src.bVisible;
this->ubNonExistChance = src.ubNonExistChance;
this->soldierID = src.soldierID;
this->object = src.object;
return *this;
}
INT32 GetFreeWorldBombIndex( void )
{
UINT32 uiCount;
WORLDBOMB *newWorldBombs;
UINT32 uiOldNumWorldBombs;
for(uiCount=0; uiCount < guiNumWorldBombs; uiCount++)
{
if ( gWorldBombs[ uiCount ].fExists == FALSE )
return( (INT32)uiCount );
}
uiOldNumWorldBombs = guiNumWorldBombs;
guiNumWorldBombs += 10;
//Allocate new table with max+10 items.
newWorldBombs = (WORLDBOMB*)MemRealloc( gWorldBombs, sizeof( WORLDBOMB ) * guiNumWorldBombs );
if (newWorldBombs == NULL)
{
return( -1 );
}
//Clear the rest of the new array
memset( &newWorldBombs[ uiOldNumWorldBombs ], 0,
sizeof( WORLDBOMB ) * ( guiNumWorldBombs - uiOldNumWorldBombs ) );
gWorldBombs = newWorldBombs;
// Return uiCount.....
return( uiCount );
}
UINT32 GetNumUsedWorldBombs( void )
{
UINT32 uiCount, uiNumItems;
uiNumItems = 0;
if ( guiNumWorldBombs == 0 )
{
return( 0 );
}
for( uiCount = 0; uiCount < guiNumWorldBombs; uiCount++ )
{
if( gWorldBombs[ uiCount ].fExists )
{
uiNumItems++;
}
}
return( uiNumItems );
}
INT32 AddBombToWorld( INT32 iItemIndex )
{
UINT32 iBombIndex;
iBombIndex = GetFreeWorldBombIndex( );
//Add the new world item to the table.
gWorldBombs[ iBombIndex ].fExists = TRUE;
gWorldBombs[ iBombIndex ].iItemIndex = iItemIndex;
return ( iBombIndex );
}
void RemoveBombFromWorld( INT32 iBombIndex )
{
//Remove the world bomb from the table.
gWorldBombs[ iBombIndex ].fExists = FALSE;
}
void RemoveBombFromWorldByItemIndex( INT32 iItemIndex )
{
// Find the world bomb which corresponds with a particular world item, then
// remove the world bomb from the table.
UINT32 uiBombIndex;
for (uiBombIndex = 0; uiBombIndex < guiNumWorldBombs; uiBombIndex++)
{
if (gWorldBombs[ uiBombIndex ].fExists && gWorldBombs[ uiBombIndex].iItemIndex == iItemIndex )
{
RemoveBombFromWorld( uiBombIndex );
return;
}
}
}
INT32 FindWorldItemForBombInGridNo( INT32 sGridNo, INT8 bLevel )
{
UINT32 uiBombIndex;
for (uiBombIndex = 0; uiBombIndex < guiNumWorldBombs; uiBombIndex++)
{
if (gWorldBombs[ uiBombIndex ].fExists && gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].sGridNo == sGridNo && gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].ubLevel == bLevel )
{
return( gWorldBombs[ uiBombIndex ].iItemIndex );
}
}
return( -1 );
}
// Flugente: is there a planted tripwire at this gridno? fKnown = TRUE: only return true if we know of that one already
INT32 FindWorldItemForTripwireInGridNo( INT32 sGridNo, INT8 bLevel, BOOLEAN fKnown )
{
UINT32 uiBombIndex;
OBJECTTYPE* pObj = NULL;
for (uiBombIndex = 0; uiBombIndex < guiNumWorldBombs; uiBombIndex++)
{
if (gWorldBombs[ uiBombIndex ].fExists && gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].sGridNo == sGridNo && gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].ubLevel == bLevel )
{
pObj = &( gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].object );
if ( pObj && Item[pObj->usItem].tripwire )
{
if ( !fKnown )
return( gWorldBombs[ uiBombIndex ].iItemIndex );
// owned by the player team - we know of this thing
if ( (*pObj)[0]->data.ubWireNetworkFlag & TRIPWIRE_NETWORK_OWNER_PLAYER )
return( gWorldBombs[ uiBombIndex ].iItemIndex );
// something is here, as a blue flag is planted
if ( gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_PLAYER_MINE_PRESENT )
return( gWorldBombs[ uiBombIndex ].iItemIndex );
}
}
}
return( -1 );
}
void FindPanicBombsAndTriggers( void )
{
// This function searches the bomb table to find panic-trigger-tuned bombs and triggers
UINT32 uiBombIndex;
OBJECTTYPE * pObj;
STRUCTURE * pSwitch;
INT32 sGridNo = NOWHERE;
INT8 bPanicIndex;
for (uiBombIndex = 0; uiBombIndex < guiNumWorldBombs; uiBombIndex++)
{
if (gWorldBombs[ uiBombIndex ].fExists)
{
pObj = &(gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].object);
if ((*pObj)[0]->data.misc.bFrequency == PANIC_FREQUENCY || (*pObj)[0]->data.misc.bFrequency == PANIC_FREQUENCY_2 || (*pObj)[0]->data.misc.bFrequency == PANIC_FREQUENCY_3 )
{
if (pObj->usItem == SWITCH)
{
sGridNo = gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].sGridNo;
switch( (*pObj)[0]->data.misc.bFrequency )
{
case PANIC_FREQUENCY:
bPanicIndex = 0;
break;
case PANIC_FREQUENCY_2:
bPanicIndex = 1;
break;
case PANIC_FREQUENCY_3:
bPanicIndex = 2;
break;
default:
// augh!!!
continue;
}
pSwitch = FindStructure( sGridNo, STRUCTURE_SWITCH );
if (pSwitch)
{
switch( pSwitch->ubWallOrientation )
{
case INSIDE_TOP_LEFT:
case OUTSIDE_TOP_LEFT:
sGridNo += DirectionInc( SOUTH );
break;
case INSIDE_TOP_RIGHT:
case OUTSIDE_TOP_RIGHT:
sGridNo += DirectionInc( EAST );
break;
default:
break;
}
}
gTacticalStatus.sPanicTriggerGridNo[ bPanicIndex ] = sGridNo;
gTacticalStatus.ubPanicTolerance[ bPanicIndex ] = (*pObj)[0]->data.misc.ubTolerance;
if ((*pObj).fFlags & OBJECT_ALARM_TRIGGER)
{
gTacticalStatus.bPanicTriggerIsAlarm[ bPanicIndex ] = TRUE;
}
gTacticalStatus.fPanicFlags |= PANIC_TRIGGERS_HERE;
bPanicIndex++;
if (bPanicIndex == NUM_PANIC_TRIGGERS)
{
return;
}
}
else
{
gTacticalStatus.fPanicFlags |= PANIC_BOMBS_HERE;
}
}
}
}
}
INT32 GetFreeWorldItemIndex( void )
{
UINT32 uiCount;
WORLDITEM *newWorldItems;
UINT32 uiOldNumWorldItems;
for(uiCount=0; uiCount < guiNumWorldItems; uiCount++)
{
if ( gWorldItems[ uiCount ].fExists == FALSE )
return( (INT32)uiCount );
}
uiOldNumWorldItems = guiNumWorldItems;
// grow by 3/2 as a better strategy, minimum 10
guiNumWorldItems = max(10, guiNumWorldItems * 3 / 2);
//Allocate new table with max+10 items.
newWorldItems = new WORLDITEM [ guiNumWorldItems ];
if (newWorldItems == NULL)
{
return( -1 );
}
if (gWorldItems)
{
for (unsigned int x = 0; x < uiOldNumWorldItems; ++x)
{
newWorldItems[x] = gWorldItems[x];
}
delete[] gWorldItems;
}
gWorldItems = newWorldItems;
// Return uiCount.....
return( uiCount );
}
UINT32 GetNumUsedWorldItems( void )
{
UINT32 uiCount, uiNumItems;
uiNumItems = 0;
for( uiCount = 0; uiCount < guiNumWorldItems; uiCount++ )
{
if( gWorldItems[ uiCount ].fExists )
{
uiNumItems++;
}
}
return( uiNumItems );
}
INT32 AddItemToWorld( INT32 sGridNo, OBJECTTYPE *pObject, UINT8 ubLevel, UINT16 usFlags, INT8 bRenderZHeightAboveLevel, INT8 bVisible, INT8 soldierID )
{
UINT32 iItemIndex;
INT32 iReturn;
// ATE: Check if the gridno is OK
if ( TileIsOutOfBounds(sGridNo))
{
// Display warning.....
#ifdef JA2BETAVERSION
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Error: Item %d was given invalid grid location %d. Please report", pObject->usItem, sGridNo);
#endif
return( -1 );
}
iItemIndex = GetFreeWorldItemIndex( );
//Add the new world item to the table.
gWorldItems[ iItemIndex ].fExists = TRUE;
gWorldItems[ iItemIndex ].sGridNo = sGridNo;
gWorldItems[ iItemIndex ].ubLevel = ubLevel;
gWorldItems[ iItemIndex ].usFlags = usFlags;
gWorldItems[ iItemIndex ].bVisible = bVisible;
gWorldItems[ iItemIndex ].bRenderZHeightAboveLevel = bRenderZHeightAboveLevel;
gWorldItems[ iItemIndex ].soldierID = soldierID;
gWorldItems[ iItemIndex ].object = *pObject;
// Add a bomb reference if needed
// Flugente: we can arm bombs in our inventory and then throw them out, which will cause them to be added to the world. Only way to identify those items is via a check for their bDetonatorType
if (usFlags & WORLD_ITEM_ARMED_BOMB || ( (Item[pObject->usItem].usItemClass & (IC_BOMB)) && ( ( (*pObject)[0]->data.misc.bDetonatorType == BOMB_TIMED ) || ( (*pObject)[0]->data.misc.bDetonatorType == BOMB_REMOTE ) ) ) )
{
iReturn = AddBombToWorld( iItemIndex );
if (iReturn == -1)
{
return( -1 );
}
else
{
// OJW - 20091002 - Explosives
if (is_networked && is_client)
{
SOLDIERTYPE* pSoldier = NULL;
if (soldierID == -1)
{
if (gWorldItems[ iItemIndex ].object[0]->data.misc.ubBombOwner > 1)
{
soldierID = gWorldItems[ iItemIndex ].object[0]->data.misc.ubBombOwner - 2; // undo the hack
pSoldier = MercPtrs[ soldierID ];
}
}
if (pSoldier != NULL)
{
// if soldier is on our team, or is AI and we are the server
if (pSoldier->bTeam == 0 || (pSoldier->bTeam == 1 && is_server))
{
// this is a local bomb, so init it that way
gWorldBombs[iReturn].iMPWorldItemIndex = 0;
gWorldBombs[iReturn].ubMPTeamIndex = pSoldier->bTeam;
gWorldBombs[iReturn].bIsFromRemotePlayer = false;
// <TODO> the 99 is a hack..though probably doesnt matter
send_plant_explosive(soldierID , pObject->usItem , 99 , usFlags , sGridNo , ubLevel , iItemIndex );
}
}
}
}
}
return ( iItemIndex );
}
void RemoveItemFromWorld( INT32 iItemIndex )
{
// Ensure the item still exists, then if it's a bomb,
// remove the appropriate entry from the bomb table
if (gWorldItems[ iItemIndex ].fExists)
{
if (gWorldItems[ iItemIndex ].usFlags & WORLD_ITEM_ARMED_BOMB)
{
RemoveBombFromWorldByItemIndex( iItemIndex );
}
gWorldItems[ iItemIndex ].fExists = FALSE;
}
}
void TrashWorldItems()
{
UINT32 i;
if( gWorldItems )
{
for( i = 0; i < guiNumWorldItems; i++ )
{
if( gWorldItems[ i ].fExists )
{
RemoveItemFromPool( gWorldItems[ i ].sGridNo, i, gWorldItems[ i ].ubLevel );
}
}
delete[] gWorldItems;
gWorldItems = NULL;
guiNumWorldItems = 0;
}
if ( gWorldBombs )
{
MemFree( gWorldBombs );
gWorldBombs = NULL;
guiNumWorldBombs = 0;
}
}
//dnl ch33 150909 //dnl ch74 191013
void SaveWorldItemsToMap(HWFILE fp, float dMajorMapVersion, UINT8 ubMinorMapVersion)
{
UINT32 i, uiBytesWritten, uiActualNumWorldItems=0;
OLD_WORLDITEM_101 oldWorldItem;
for(i=0; i<guiNumWorldItems; i++)
{
if(gWorldItems[i].fExists)
{
if(dMajorMapVersion == VANILLA_MAJOR_MAP_VERSION && ubMinorMapVersion == VANILLA_MINOR_MAP_VERSION && gWorldItems[i].object.usItem >= OLD_MAXITEMS)
continue;
uiActualNumWorldItems++;
}
}
FileWrite(fp, &uiActualNumWorldItems, sizeof(UINT32), &uiBytesWritten);
for(i=0; i<guiNumWorldItems; i++)
{
if(gWorldItems[i].fExists)
{
if(dMajorMapVersion == VANILLA_MAJOR_MAP_VERSION && ubMinorMapVersion == VANILLA_MINOR_MAP_VERSION)
{
if(gWorldItems[i].object.usItem >= OLD_MAXITEMS)
continue;
oldWorldItem = gWorldItems[i];
FileWrite(fp, &oldWorldItem, sizeof(OLD_WORLDITEM_101), &uiBytesWritten);
}
else
gWorldItems[i].Save(fp, TRUE);
}
}
}
// WANNE - BMP: DONE!
void LoadWorldItemsFromMap( INT8 **hBuffer, float dMajorMapVersion, int ubMinorMapVersion )
{
// Start loading itmes...
UINT32 i;
WORLDITEM dummyItem;
INT32 iItemIndex;
UINT32 uiNumWorldItems;
//If any world items exist, we must delete them now.
TrashWorldItems();
//Read the number of items that were saved in the map.
LOADDATA( &uiNumWorldItems, *hBuffer, 4 );
if( gTacticalStatus.uiFlags & LOADING_SAVED_GAME && !gfEditMode )
{ //The sector has already been visited. The items are saved in a different format that will be
//loaded later on. So, all we need to do is skip the data entirely.
if (dMajorMapVersion >= 6.0 && ubMinorMapVersion > 26 ) {
for (unsigned int x = 0; x < uiNumWorldItems; ++x)
{
//ADB WORLDITEM's size on disk is unknown
dummyItem.Load(hBuffer, dMajorMapVersion, ubMinorMapVersion);
}
}
else
{
*hBuffer += sizeof ( OLD_WORLDITEM_101 ) * uiNumWorldItems;
}
return;
}
else for ( i = 0; i < uiNumWorldItems; i++ )
{ //Add all of the items to the world indirectly through AddItemToPool, but only if the chance
//associated with them succeed.
dummyItem.Load(hBuffer, dMajorMapVersion, ubMinorMapVersion);
gMapTrn.GetTrnCnt(dummyItem.sGridNo);//dnl ch44 270909 WORLDITEM translation
if( dummyItem.object.usItem == OWNERSHIP )
{
dummyItem.ubNonExistChance = 0;
}
if( gfEditMode || dummyItem.ubNonExistChance <= PreRandom( 100 ) ||
(gGameExternalOptions.ubMapItemChanceOverride > 0 && (gGameExternalOptions.ubMapItemChanceOverride >= PreRandom(100)) ) ) //Madd: map item chance override, note this calc is done in reverse
{
if( !gfEditMode )
{
//check for matching item existance modes and only add if there is a match!
//if we are in platinum mode, REALISTIC items are allowed, but not SCIFI items
if( dummyItem.usFlags & WORLD_ITEM_SCIFI_ONLY && !(gGameOptions.ubGameStyle == STYLE_SCIFI) ||
dummyItem.usFlags & WORLD_ITEM_REALISTIC_ONLY && (gGameOptions.ubGameStyle == STYLE_SCIFI) )
{ //no match, so don't add item to world
continue;
}
/*
if ( !gGameOptions.fGunNut )
{
UINT16 usReplacement;
// do replacements?
if ( Item[ dummyItem.object.usItem ].usItemClass == IC_GUN )
{
INT8 bAmmo, bNewAmmo;
usReplacement = StandardGunListReplacement( dummyItem.object.usItem );
if ( usReplacement )
{
// everything else can be the same? no.
bAmmo = dummyItem.object[0]->data.gun.ubGunShotsLeft;
bNewAmmo = (Weapon[ usReplacement ].ubMagSize * bAmmo) / Weapon[ dummyItem.object.usItem ].ubMagSize;
if ( bAmmo > 0 && bNewAmmo == 0 )
{
bNewAmmo = 1;
}
dummyItem.object.usItem = usReplacement;
dummyItem.object[0]->data.gun.ubGunShotsLeft = bNewAmmo;
}
}
if ( Item[ dummyItem.object.usItem ].usItemClass == IC_AMMO )
{
usReplacement = StandardGunListAmmoReplacement( dummyItem.object.usItem );
if ( usReplacement )
{
UINT8 ubLoop;
// go through status values and scale up/down
for ( ubLoop = 0; ubLoop < dummyItem.object.ubNumberOfObjects; ubLoop++ )
{
dummyItem.object.status.bStatus[ ubLoop ] = dummyItem.object.status.bStatus[ ubLoop ] * Magazine[ Item[ usReplacement ].ubClassIndex ].ubMagSize / Magazine[ Item[ dummyItem.object.usItem ].ubClassIndex ].ubMagSize;
}
// then replace item #
dummyItem.object.usItem = usReplacement;
}
}
}
*/
}
if( dummyItem.object.usItem == ACTION_ITEM && gfLoadPitsWithoutArming )
{ //if we are loading a pit, they are typically loaded without being armed.
if( dummyItem.object[0]->data.misc.bActionValue == ACTION_ITEM_SMALL_PIT || dummyItem.object[0]->data.misc.bActionValue == ACTION_ITEM_LARGE_PIT )
{
dummyItem.usFlags &= ~WORLD_ITEM_ARMED_BOMB;
dummyItem.bVisible = BURIED;
dummyItem.object[0]->data.misc.bDetonatorType = 0;
}
}
else if ( dummyItem.bVisible == HIDDEN_ITEM && dummyItem.object[0]->data.bTrap > 0 && ( Item[dummyItem.object.usItem].mine || dummyItem.object.usItem == TRIP_FLARE || dummyItem.object.usItem == TRIP_KLAXON) )
{
ArmBomb( &dummyItem.object, BOMB_PRESSURE );
dummyItem.usFlags |= WORLD_ITEM_ARMED_BOMB;
// this is coming from the map so the enemy must know about it.
gpWorldLevelData[ dummyItem.sGridNo ].uiFlags |= MAPELEMENT_ENEMY_MINE_PRESENT;
}
if ( dummyItem.usFlags & WORLD_ITEM_ARMED_BOMB )
{ //all armed bombs are buried
dummyItem.bVisible = BURIED;
}
#if 0//dnl ch74 201013 this is already done in OBJECTTYPE::Load()
//Madd: ok, so this drives me nuts -- why bother with default attachments if the map isn't going to load them for you?
//this should fix that...
for(UINT8 cnt = 0; cnt < MAX_DEFAULT_ATTACHMENTS; cnt++)
{
if(Item [ dummyItem.object.usItem ].defaultattachments[cnt] == 0)
break;
OBJECTTYPE defaultAttachment;
CreateItem(Item [ dummyItem.object.usItem ].defaultattachments[cnt],100,&defaultAttachment);
dummyItem.object.AttachObject(NULL,&defaultAttachment, FALSE);
}
#endif
AddItemToPoolAndGetIndex( dummyItem.sGridNo, &dummyItem.object, dummyItem.bVisible, dummyItem.ubLevel, dummyItem.usFlags, dummyItem.bRenderZHeightAboveLevel, dummyItem.soldierID, &iItemIndex );
gWorldItems[ iItemIndex ].ubNonExistChance = dummyItem.ubNonExistChance;
}
}
if ( !gfEditMode )
{
DeleteWorldItemsBelongingToTerroristsWhoAreNotThere();
if ( gWorldSectorX == 3 && gWorldSectorY == MAP_ROW_P && gbWorldSectorZ == 1 )
{
DeleteWorldItemsBelongingToQueenIfThere();
}
}
}
void DeleteWorldItemsBelongingToTerroristsWhoAreNotThere( void )
{
UINT32 uiLoop;
UINT32 uiLoop2;
INT32 sGridNo;
UINT8 ubLevel;
// only do this after Carmen has talked to player and terrorists have been placed
//if ( CheckFact( FACT_CARMEN_EXPLAINED_DEAL, 0 ) == TRUE )
{
for ( uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ )
{
// loop through all items, look for ownership
if ( gWorldItems[ uiLoop ].fExists && gWorldItems[ uiLoop ].object.usItem == OWNERSHIP )
{
// if owner is a terrorist
if ( IsProfileATerrorist( (UINT8) gWorldItems[ uiLoop ].object[0]->data.owner.ubOwnerProfile ) )
{
// and they were not set in the current sector
if ( gMercProfiles[ gWorldItems[ uiLoop ].object[0]->data.owner.ubOwnerProfile ].sSectorX != gWorldSectorX ||
gMercProfiles[ gWorldItems[ uiLoop ].object[0]->data.owner.ubOwnerProfile ].sSectorY != gWorldSectorY )
{
// then all items in this location should be deleted
sGridNo = gWorldItems[ uiLoop ].sGridNo;
ubLevel = gWorldItems[ uiLoop ].ubLevel;
for ( uiLoop2 = 0; uiLoop2 < guiNumWorldItems; uiLoop2++ )
{
// loop through all items, look for ownership
if ( gWorldItems[ uiLoop2 ].fExists && gWorldItems[ uiLoop2 ].sGridNo == sGridNo && gWorldItems[ uiLoop2 ].ubLevel == ubLevel )
{
RemoveItemFromPool( sGridNo, uiLoop2, ubLevel );
}
}
}
}
}
}
}
// else the terrorists haven't been placed yet!
}
void DeleteWorldItemsBelongingToQueenIfThere( void )
{
UINT32 uiLoop;
UINT32 uiLoop2;
INT32 sGridNo;
UINT8 ubLevel;
INT8 bSlot;
if ( gMercProfiles[ QUEEN ].sSectorX == gWorldSectorX &&
gMercProfiles[ QUEEN ].sSectorY == gWorldSectorY &&
gMercProfiles[ QUEEN ].bSectorZ == gbWorldSectorZ )
{
for ( uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ )
{
// loop through all items, look for ownership
if ( gWorldItems[ uiLoop ].fExists && gWorldItems[ uiLoop ].object.usItem == OWNERSHIP )
{
// if owner is the Queen
if ( gWorldItems[ uiLoop ].object[0]->data.owner.ubOwnerProfile == QUEEN )
{
// then all items in this location should be deleted
sGridNo = gWorldItems[ uiLoop ].sGridNo;
ubLevel = gWorldItems[ uiLoop ].ubLevel;
for ( uiLoop2 = 0; uiLoop2 < guiNumWorldItems; uiLoop2++ )
{
// loop through all items, look for those in same tile
if ( gWorldItems[ uiLoop2 ].fExists && gWorldItems[ uiLoop2 ].sGridNo == sGridNo && gWorldItems[ uiLoop2 ].ubLevel == ubLevel )
{
// upgrade equipment
switch ( gWorldItems[ uiLoop2 ].object.usItem )
{
case AUTO_ROCKET_RIFLE:
bSlot = FindObjectInSoldierProfile( QUEEN, ROCKET_RIFLE );
if ( bSlot != NO_SLOT )
{
// give her auto rifle
gMercProfiles[ QUEEN ].inv[ bSlot ] = AUTO_ROCKET_RIFLE;
}
break;
case SPECTRA_HELMET_18:
gMercProfiles[ QUEEN ].inv[ HELMETPOS ] = SPECTRA_HELMET_18;
break;
case SPECTRA_VEST_18:
gMercProfiles[ QUEEN ].inv[ VESTPOS ] = SPECTRA_VEST_18;
break;
case SPECTRA_LEGGINGS_18:
gMercProfiles[ QUEEN ].inv[ LEGPOS ] = SPECTRA_LEGGINGS_18;
break;
default:
break;
}
RemoveItemFromPool( sGridNo, uiLoop2, ubLevel );
}
}
}
}
}
}
}
// Refresh item pools
void RefreshWorldItemsIntoItemPools( WORLDITEM * pItemList, INT32 iNumberOfItems )
{
INT32 i;
for ( i = 0; i < iNumberOfItems; i++ )
{
if( pItemList[ i ].fExists )
{
WORLDITEM& dummyItem = pItemList[ i ];
AddItemToPool( dummyItem.sGridNo, &dummyItem.object, dummyItem.bVisible, dummyItem.ubLevel, dummyItem.usFlags, dummyItem.bRenderZHeightAboveLevel, dummyItem.soldierID );
}
}
}
// Flugente: Cool/decay down all items in this sector
void CoolDownWorldItems()
{
HandleSectorCooldownFunctions( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, gWorldItems, guiNumWorldItems, FALSE );
}