Added: Ctrl+Shift+E now fill LBE items in sector with other items and places them in vehicles first.

Added: Right-Click on remove attachments button on sector inventory screen will not empty LBE items in sector
Changed: SLAY_STAYS_FOREVER disables Slay's hourly chance to leave when unattended
Added: SLAY_HOURLY_CHANCE_TO_LEAVE setting to Ja2_Options.ini
Fixed: a bunch of array index out of bounds bugs
Fixed: a bunch of typos in if contitions
Fixed: BuildListFile() function loading items from index 1 instead 0
Added translation: Polish text for some map inventory screen items
Added translation: English texts for new functionality for other language files
Cleaned up some old TODOs

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8404 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
TheBob
2017-05-19 13:40:34 +00:00
parent dc350d724d
commit b60a94afc5
39 changed files with 565 additions and 146 deletions
+2
View File
@@ -864,6 +864,8 @@ void LoadGameExternalOptions()
// CHRISL: New setting to allow Slay to remain as a hired PC
gGameExternalOptions.fEnableSlayForever = iniReader.ReadBoolean("Recruitment Settings", "SLAY_STAYS_FOREVER", FALSE);
// Bob: externalized Slay's chance to leave
gGameExternalOptions.ubHourlyChanceSlayWillLeave = iniReader.ReadInteger("Recruitment Settings", "SLAY_HOURLY_CHANCE_TO_LEAVE", 15, 0, 100);
// anv: playable Speck
gGameExternalOptions.fEnableRecruitableSpeck = iniReader.ReadBoolean("Recruitment Settings", "RECRUITABLE_SPECK", TRUE);
+2
View File
@@ -807,6 +807,8 @@ typedef struct
// CHRISL: option to allow Slay to remain as a hired PC
BOOLEAN fEnableSlayForever;
// Bob: % chance Slay will leave every hour if left alone in sector
UINT16 ubHourlyChanceSlayWillLeave;
// anv: playable Speck
BOOLEAN fEnableRecruitableSpeck;
+1 -1
View File
@@ -2309,7 +2309,7 @@ UINT16 DisplayProtection(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight)
break;
}
swprintf(sTemp, L"%d", iProtection, Armour[ Item[ usIndex ].ubClassIndex ].ubProtection); // FIXME: param4 is unused
swprintf(sTemp, L"%d", iProtection);
wcscat( sTemp, L"%%" );
swprintf( sTemp2, L"(%d)", Armour[ Item[ usIndex ].ubClassIndex ].ubProtection );
wcscat( sTemp, sTemp2 );
+3 -3
View File
@@ -212,8 +212,8 @@ void ResetTemp()
for(i=0; i<NUM_TEMP; i++)
{
gbriefingRoomDataTemp[i].uiIndex = i;
gbriefingRoomDataTemp[i].Name[ENCYCLOPEDIA_NAME_SIZE] = '\0';
gbriefingRoomDataTemp[i].sCode[ENCYCLOPEDIA_DECRIPTION_SIZE] = '\0';
gbriefingRoomDataTemp[i].Name[ENCYCLOPEDIA_NAME_SIZE-1] = '\0';
gbriefingRoomDataTemp[i].sCode[ENCYCLOPEDIA_DECRIPTION_SIZE-1] = '\0';
gbriefingRoomDataTemp[i].sImagePositionX[0] = 0;
gbriefingRoomDataTemp[i].sImagePositionY[0] = 0;
gbriefingRoomDataTemp[i].Hidden = FALSE;
@@ -468,7 +468,7 @@ BOOLEAN EnterEncyclopediaLocation()
DisableButton( guiEncyclopediaLocationPageButton[2] );
#endif
sprintf(str, "BriefingRoom\\mission%d.wav", gbriefingRoomDataTemp[LocationID].MissionID,IDimage);
sprintf(str, "BriefingRoom\\mission%d.wav", gbriefingRoomDataTemp[LocationID].MissionID);
if( FileExists(str) )
EnableButton ( guiSoundButtons[0] );
else
+1 -1
View File
@@ -49,7 +49,7 @@ typedef struct
BOOLEAN bvisible;
CHAR16 sCode[150];
CHAR16 sCode[ENCYCLOPEDIA_DECRIPTION_SIZE];
INT32 NextMission;
UINT32 MissionID;
+1 -1
View File
@@ -309,7 +309,7 @@ void HandleIMPBackgroundAnswers( UINT16 uiSkillPressed )
}
//make sure its a valid skill
if( uiSkillPressed > IMP_BACKGROUND_DISPLAYED_CHOICES )
if( uiSkillPressed >= IMP_BACKGROUND_DISPLAYED_CHOICES )
{
Assert( 0 );
return;
+1 -1
View File
@@ -1478,7 +1478,7 @@ void ProcessTransactionString(STR16 pString, FinanceUnitPtr pFinance)
break;
case PAY_SPECK_FOR_MERC:
swprintf(pString, L"%s", pTransactionText[ PAY_SPECK_FOR_MERC ], gMercProfiles[pFinance->ubSecondCode].zName); // FIXME: param4 unused
swprintf(pString, L"%s", pTransactionText[ PAY_SPECK_FOR_MERC ]);
break;
case MEDICAL_DEPOSIT:
+2 -2
View File
@@ -4833,7 +4833,7 @@ BOOLEAN CleanObject( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pOwner, OBJECTTYPE *
BOOLEAN bFullyCleaned = FALSE;
// no gun? We shouldn't be here...
if ( !Item[pObj->usItem].usItemClass & IC_GUN )
if ( !(Item[pObj->usItem].usItemClass & IC_GUN) )
Assert(0);
ubItemsInPocket = pObj->ubNumberOfObjects;
@@ -5033,7 +5033,7 @@ void HandleRepairBySoldier( SOLDIERTYPE *pSoldier )
// we spent some time cleaning so adjust repair points accordingly
if ( ubRepairPtsLeft > 0 && ubInitialCleaningPts > ubCleaningPtsLeft )
{
ubRepairPtsLeft = UINT8()(ubRepairPtsLeft * ubCleaningPtsLeft / ubInitialCleaningPts);
ubRepairPtsLeft = (UINT8)(ubRepairPtsLeft * ubCleaningPtsLeft / ubInitialCleaningPts);
}
}
+3 -1
View File
@@ -811,6 +811,8 @@ void HourlyStealUpdate()
#else
void HourlyCheckIfSlayAloneSoHeCanLeave()
{
if (gGameExternalOptions.fEnableSlayForever || gGameExternalOptions.ubHourlyChanceSlayWillLeave < 1) return;
SOLDIERTYPE *pSoldier;
pSoldier = FindSoldierByProfileID( SLAY, TRUE );
if( !pSoldier )
@@ -827,7 +829,7 @@ void HourlyCheckIfSlayAloneSoHeCanLeave()
}
if( PlayerMercsInSector( (UINT8)pSoldier->sSectorX, (UINT8)pSoldier->sSectorY, pSoldier->bSectorZ ) == 1 )
{
if( Chance( 15 ) )
if( Chance( gGameExternalOptions.ubHourlyChanceSlayWillLeave ) )
{
pSoldier->ubLeaveHistoryCode = HISTORY_SLAY_MYSTERIOUSLY_LEFT;
TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_CONTRACT_ENDING_NO_ASK_EQUIP, 0, 0 );
+6 -2
View File
@@ -2925,7 +2925,7 @@ SOLDIERTYPE * FindSoldierByProfileID2( UINT8 ubProfileID, BOOLEAN fPlayerMercsOn
BOOLEAN FindSoldier( SOLDIERTYPE **ppSoldier, UINT16 usSoldierIndex, BOOLEAN fPlayerMercsOnly)
{
SOLDIERTYPE Menptr[ TOTAL_SOLDIERS ];
//SOLDIERTYPE Menptr[ TOTAL_SOLDIERS ];
*ppSoldier = NULL;
@@ -12009,7 +12009,11 @@ static int l_SetStartMission(lua_State *L)
if ( idMission != -1 )
{
if ( gBriefingRoomData[idMission].CheckMission != MISSIONSTART || gBriefingRoomData[idMission].CheckMission != MISSIONEND || gBriefingRoomData[idMission].CheckMission == MISSIONNOSTARTED )
if (
(gBriefingRoomData[idMission].CheckMission != MISSIONSTART)
|| (gBriefingRoomData[idMission].CheckMission != MISSIONEND)
|| (gBriefingRoomData[idMission].CheckMission == MISSIONNOSTARTED)
)
{
gBriefingRoomData[idMission].CheckMission = MISSIONSTART; //set start mission
gBriefingRoomData[idMission].Hidden = TRUE; // set next mission
+141 -29
View File
@@ -337,6 +337,7 @@ void AnimateZoomInventory ( UINT16 iLocationInPool, UINT16 iCounter, INT32 iStar
// the currently-opened sector inventory ammo.
void SortSectorInventoryAmmo(bool useBoxes);
void SortSectorInventoryEjectAmmo();
void SortSectorInventoryEmptyLBE(); // Bob: added option to empty LBE items in sector
void SortSectorInventorySeparateAttachments();
void SortSectorInventoryStackAndMerge(bool ammoOnly);
// HEADROCK HAM 5: A quick function to rebuilt the Seen and Unseen item pools without saving the inventory.
@@ -2244,15 +2245,22 @@ void BuildStashForSelectedSector( INT16 sMapX, INT16 sMapY, INT16 sMapZ )
{
uiTotalNumberOfItems = guiNumWorldItems;
uiNumOfSlots = (uiTotalNumberOfItems / MAP_INVENTORY_POOL_SLOT_COUNT + 1) * MAP_INVENTORY_POOL_SLOT_COUNT;
if(pInventoryPoolList.size() < uiNumOfSlots)
if (pInventoryPoolList.size() < uiNumOfSlots) {
pInventoryPoolList.resize(uiNumOfSlots);
if(pUnSeenItems.size() < uiNumOfSlots)
}
if (pUnSeenItems.size() < uiNumOfSlots) {
pUnSeenItems.resize(uiNumOfSlots);
}
uiNumberOfSeenItems = 0;
uiNumberOfUnSeenItems = 0;
pwi = &gWorldItems.front();
pipl = &pInventoryPoolList.front();
pusi = &pUnSeenItems.front();
for(i=0; i<uiTotalNumberOfItems; i++, pwi++)
{
if(IsMapScreenWorldItemVisibleInMapInventory(pwi))
@@ -2814,13 +2822,21 @@ void MapInventoryPoolStackAndMergeBtn( GUI_BUTTON *btn, INT32 reason )
// HEADROCK HAM 5: Sort attachments button callback
void MapInventoryPoolSortAttachmentsBtn( GUI_BUTTON *btn, INT32 reason )
{
if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN || reason & MSYS_CALLBACK_REASON_RBUTTON_DWN)
{
if (!(btn->uiFlags & (BUTTON_CLICKED_ON)))
{
btn->uiFlags |= (BUTTON_CLICKED_ON);
}
}
if (reason & MSYS_CALLBACK_REASON_RBUTTON_UP)
{
if (btn->uiFlags & (BUTTON_CLICKED_ON))
{
SortSectorInventoryEmptyLBE();
btn->uiFlags &= ~(BUTTON_CLICKED_ON);
}
}
if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
{
if (btn->uiFlags & (BUTTON_CLICKED_ON))
@@ -2829,6 +2845,7 @@ void MapInventoryPoolSortAttachmentsBtn( GUI_BUTTON *btn, INT32 reason )
btn->uiFlags &=~ (BUTTON_CLICKED_ON);
}
}
}
// HEADROCK HAM 5: Eject Ammo button callback
@@ -4002,21 +4019,27 @@ BOOLEAN SortInventoryPoolQ(void)
BOOLEAN SwitchToInventoryPoolQ(UINT8 newidx)//dnl ch75 021113
{
UINT8 curidx = gInventoryPoolIndex & 0x0F;
if(curidx >= INVPOOLLISTNUM)
return(FALSE);
newidx &= 0x0F;
if(curidx == newidx)
return(FALSE);
MapInventoryFilterSet(IC_MAPFILTER_ALL);
#if 0
pInventoryPoolListQ[curidx] = pInventoryPoolList;
#else
UINT32 uiNumOfSlots = (iLastInventoryPoolPage + 1) * MAP_INVENTORY_POOL_SLOT_COUNT;
if(pInventoryPoolListQ[curidx].size() != uiNumOfSlots)
pInventoryPoolListQ[curidx].resize(uiNumOfSlots);
WORLDITEM *pwiQ1 = &pInventoryPoolListQ[curidx].front();
WORLDITEM *pwiQ2 = &pInventoryPoolListQ[curidx].back();
WORLDITEM *pwi1 = &pInventoryPoolList.front();
WORLDITEM *pwi2 = &pInventoryPoolList.back();
int cnt = 0;
while(pwi1 <= pwi2)
{
if(pwi1->fExists)
@@ -4027,22 +4050,23 @@ BOOLEAN SwitchToInventoryPoolQ(UINT8 newidx)//dnl ch75 021113
pwi1++;
cnt++;
}
while(pwiQ1 <= pwiQ2)
{
pwiQ1->fExists = FALSE;
pwiQ1->object.ubNumberOfObjects = 0;
pwiQ1++;
}
#endif
iCurrentInventoryPoolPageQ[curidx] = iCurrentInventoryPoolPage;
iLastInventoryPoolPageQ[curidx] = iLastInventoryPoolPage;
if(pInventoryPoolListQ[newidx].empty() == true)
pInventoryPoolListQ[newidx].resize(MAP_INVENTORY_POOL_SLOT_COUNT);
#if 0
pInventoryPoolList = pInventoryPoolListQ[newidx];
#else
if(pInventoryPoolList.size() < pInventoryPoolListQ[newidx].size())
pInventoryPoolList.resize(pInventoryPoolListQ[newidx].size());
pwiQ1 = &pInventoryPoolListQ[newidx].front();
pwiQ2 = &pInventoryPoolListQ[newidx].back();
pwi1 = &pInventoryPoolList.front();
@@ -4064,11 +4088,12 @@ BOOLEAN SwitchToInventoryPoolQ(UINT8 newidx)//dnl ch75 021113
pwi1->object.ubNumberOfObjects = 0;
pwi1++;
}
#endif
iCurrentInventoryPoolPage = iCurrentInventoryPoolPageQ[newidx];
iLastInventoryPoolPage = iLastInventoryPoolPageQ[newidx];
gInventoryPoolIndex = newidx | 0x30;
fMapPanelDirty = TRUE;
return(TRUE);
}
@@ -5011,23 +5036,98 @@ void SortSectorInventoryEjectAmmo()
fMapPanelDirty=TRUE;
}
void SortSectorInventorySeparateAttachments()
{
OBJECTTYPE gTempObject;
void SortSectorInventoryEmptyLBE() {
// current item
WORLDITEM * pInventoryItem = NULL;
SOLDIERTYPE * pSoldier = &(Menptr[gCharactersList[bSelectedInfoChar].usSolID]);
for (UINT32 uiLoop = 0; uiLoop < pInventoryPoolList.size(); uiLoop++) //for all items in sector
{
if ( pInventoryPoolList[uiLoop].bVisible == TRUE && // Visible
pInventoryPoolList[uiLoop].object.exists() == true && // Exists
pInventoryPoolList[uiLoop].usFlags & WORLD_ITEM_REACHABLE && // Reachable
!(pInventoryPoolList[uiLoop].usFlags & WORLD_ITEM_ARMED_BOMB) ) // Not booby-trapped!
{
pInventoryItem = &(pInventoryPoolList[uiLoop]);
if (pInventoryItem->bVisible == TRUE && // Visible
pInventoryItem->object.exists() == true && // Exists
pInventoryItem->usFlags & WORLD_ITEM_REACHABLE && // Reachable
!(pInventoryItem->usFlags & WORLD_ITEM_ARMED_BOMB)) // Not booby-trapped!
{
// Iterate through stacks
for (int x = 0; x < pInventoryPoolList[uiLoop].object.ubNumberOfObjects; ++x)
for (int x = 0; x < pInventoryItem->object.ubNumberOfObjects; ++x)
{
UINT8 size = 0, cnt = 0, uiLoopCnt = 0;
// Bob: empty LBE items in sector inventory
if (pInventoryItem->object.IsActiveLBE(x)) {
LBENODE * lbePtr = pInventoryItem->object.GetLBEPointer(x);
INVTYPE & LBEType = Item[pInventoryItem->object.usItem];
if (lbePtr != NULL) {
int dropCnt = 0;
for (auto lbeInvIter = lbePtr->inv.begin(); lbeInvIter != lbePtr->inv.end(); lbeInvIter++) {
OBJECTTYPE * LBEStack = lbeInvIter._Ptr;
dropCnt += LBEStack->ubNumberOfObjects;
AutoPlaceObjectToWorld(pSoldier, LBEStack, true);
if (LBEStack != NULL)
{
DeleteObj(lbeInvIter._Ptr);
}
}
if (dropCnt > 0) {
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzMapInventorySortingMessage[5], dropCnt, LBEType.szItemName);
}
else {
ScreenMsg(FONT_MCOLOR_LTRED, MSG_INTERFACE, gzMapInventorySortingMessage[6], LBEType.szItemName);
}
if (DestroyLBEIfEmpty(&(pInventoryItem->object), x)) {
ScreenMsg(FONT_MCOLOR_LTGREEN, MSG_INTERFACE, gzMapInventorySortingMessage[7], LBEType.szItemName);
}
else {
ScreenMsg(FONT_MCOLOR_LTRED, MSG_INTERFACE, gzMapInventorySortingMessage[8], LBEType.szItemName);
}
}
else { // can't get LBE pointer, something is wrong
ScreenMsg(FONT_MCOLOR_LTRED, MSG_INTERFACE, gzMapInventorySortingMessage[9], LBEType.szItemName);
}
} // IsActiveLBE
} // Iterate through stacks
} // pInventoryPoolList loop
}
// "FINISHED"
CHAR16 pStr[500];
swprintf(pStr, gzMapInventorySortingMessage[4], 'A' + sSelMapY - 1, sSelMapX);
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pStr);
// Dirty!
fMapPanelDirty = TRUE;
}
void SortSectorInventorySeparateAttachments()
{
// attachment ref and pointer
OBJECTTYPE gTempObject;
OBJECTTYPE * gpTempObject = NULL;
// current item
WORLDITEM * pInventoryItem = NULL;
SOLDIERTYPE * pSoldier = &(Menptr[gCharactersList[bSelectedInfoChar].usSolID]);
for (UINT32 uiLoop = 0; uiLoop < pInventoryPoolList.size(); uiLoop++) //for all items in sector
{
pInventoryItem = &(pInventoryPoolList[uiLoop]);
if (pInventoryItem->bVisible == TRUE && // Visible
pInventoryItem->object.exists() == true && // Exists
pInventoryItem->usFlags & WORLD_ITEM_REACHABLE && // Reachable
!(pInventoryItem->usFlags & WORLD_ITEM_ARMED_BOMB)) // Not booby-trapped!
{
// Iterate through stacks
for (int x = 0; x < pInventoryItem->object.ubNumberOfObjects; ++x)
{
UINT8 size = 0, cnt = 0, uiLoopCnt = 0;
@@ -5035,17 +5135,28 @@ void SortSectorInventorySeparateAttachments()
// launchers before detaching the launchers (and their grenade slots) themselves.
// Since the size of the attachmentList remains constant under NAS but decrements by one
// under OAS, recheck the list size every iteration in order to calculate an rindex.
while((size = pInventoryPoolList[uiLoop].object[x]->attachments.size()) != cnt)
while ((size = pInventoryItem->object[x]->attachments.size()) != cnt)
{
gTempObject = *(pInventoryPoolList[uiLoop].object[x]->GetAttachmentAtIndex(size - 1 - cnt));
OBJECTTYPE * pNewObj = new OBJECTTYPE();
gpTempObject = pInventoryItem->object[x]->GetAttachmentAtIndex(size - 1 - cnt);
//WarmSteel - This actually still works with NAS, be it by accident
if (pInventoryPoolList[uiLoop].object.RemoveAttachment(&gTempObject,0,x))
if (gpTempObject != NULL && pInventoryItem->object.RemoveAttachment(gpTempObject, pNewObj, x))
{
AutoPlaceObjectToWorld( pSoldier, &gTempObject, true );
if (&gTempObject != NULL)
// Bob: sanity check! I think RemoveAttachment shouldn't be used like it was here.
if (gpTempObject->usItem > 0 && (gpTempObject->ubNumberOfObjects != 1 || gpTempObject->usItem > MAXITEMS || gpTempObject->ubMission != 0)) {
gpTempObject = pNewObj;
}
// Bob: not sure why was this a ref instead of a pointer,
// I'll leave it here so it gets cleaned up when going out of scope
// since DeleteObj() doesn't free all the memory
gTempObject = *gpTempObject;
AutoPlaceObjectToWorld(pSoldier, gpTempObject, true);
if (gpTempObject != NULL)
{
DeleteObj( &gTempObject );
DeleteObj(gpTempObject);
}
}
else
@@ -5061,9 +5172,10 @@ void SortSectorInventorySeparateAttachments()
break;
}
}
} // Iterate through stacks
} // pInventoryPoolList loop
}
}
}
// "FINISHED"
CHAR16 pStr[500];
swprintf(pStr, gzMapInventorySortingMessage[1], 'A' + sSelMapY - 1, sSelMapX);
+172 -28
View File
@@ -1035,6 +1035,14 @@ void ChangeCharacterListSortMethod( INT32 iValue );
void MapscreenMarkButtonsDirty();
// Bob: functions for packing vehicles with filled LBE items
void moveSectorInventoryToVehicle(SOLDIERTYPE *pSoldier);
void fillCurrentSectorLBEItems(SOLDIERTYPE *pSoldier);
void fillLBEWithSectorItems(OBJECTTYPE * LBEObject);
void moveCurrentSectorItemsToVehicle(SOLDIERTYPE *pSoldier);
bool placeItemInVehicle(SOLDIERTYPE *pSoldier, WORLDITEM &worldItem);
bool placeItemInVehicle(SOLDIERTYPE *pSoldier, OBJECTTYPE &item);
extern BOOLEAN CanRedistributeMilitiaInSector( INT16 sClickedSectorX, INT16 sClickedSectorY, INT8 bClickedTownId );
extern INT32 GetNumberOfMercsInUpdateList( void );
@@ -7671,34 +7679,7 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
{
if (gGameExternalOptions.fVehicleInventory)
{
for (unsigned int i = 0; i < pInventoryPoolList.size(); i++)
{
if (pInventoryPoolList[i].fExists == TRUE && (pInventoryPoolList[i].usFlags & WORLD_ITEM_REACHABLE))
{
for (int x = 0; x < NUM_INV_SLOTS; x++)
{
if (vehicleInv[x] == FALSE)
continue;
if (pSoldier->inv[x].exists() == true)
{
if (pSoldier->inv[x].usItem != pInventoryPoolList[i].object.usItem)
continue;
else
pInventoryPoolList[i].object.AddObjectsToStack(pSoldier->inv[x], -1, pSoldier, x);
}
else
pInventoryPoolList[i].object.MoveThisObjectTo(pSoldier->inv[x], -1, pSoldier, x);
if (pInventoryPoolList[i].object.ubNumberOfObjects < 0)
{
//RemoveItemFromWorld(i);
break;
}
}
}
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
}
moveSectorInventoryToVehicle(pSoldier);
}
}
// Flugente: also allow mercs to qickly pick up items this way (but not EPCs)
@@ -16973,3 +16954,166 @@ void RetreatBandageCallback( UINT8 ubResult )
{
HandleRetreatBandaging( );
}
// Bob: moved here to expand what CHRISL did
// try to move all items in sector into the vehicle inventory. Try to use LBE items in sector to store as much stuff as possible
void moveSectorInventoryToVehicle(SOLDIERTYPE *pSoldier) {
fillCurrentSectorLBEItems(pSoldier); // puts LBE items in vehicle
// ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"---------------------------------------------");
// ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Moving remaining sector items into the car...");
moveCurrentSectorItemsToVehicle(pSoldier); // puts remaining items in vehicle
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
}
// fills all empty LBE items in currebt sector with other sector items then tries to place all LBE items in the vehicle (pSoldier)
void fillCurrentSectorLBEItems(SOLDIERTYPE *pSoldier) {
std::vector<OBJECTTYPE*> LBEObjects; // list of LBE objects found in sector
// build a list of LBE objects in sector. Stacks are split into separate items.
for (unsigned int i = 0; i < pInventoryPoolList.size(); i++)
{
WORLDITEM & stack = pInventoryPoolList[i];
OBJECTTYPE & stackContents = pInventoryPoolList[i].object;
INVTYPE & stackContentType = Item[stackContents.usItem];
if ( stack.fExists == TRUE
&& stack.usFlags & WORLD_ITEM_REACHABLE
&& stackContentType.usItemClass == IC_LBEGEAR
) {
for (int j = 0; j< stackContents.ubNumberOfObjects; j++) {
OBJECTTYPE * LBEObject = new OBJECTTYPE();
stackContents.MoveThisObjectTo(*LBEObject, 1);
LBEObjects.push_back(LBEObject);
}
}
}
// fill the LBE items in the list with items from current sector then try to put them in the vehicle
for (std::vector<OBJECTTYPE*>::iterator LBEItemIter = LBEObjects.begin(); LBEItemIter != LBEObjects.end(); LBEItemIter++) {
OBJECTTYPE* LBEItem = *LBEItemIter;
INVTYPE LBEItemType = Item[LBEItem->usItem];
LBETYPE LBEType = LoadBearingEquipment[LBEItemType.ubClassIndex];
//ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"===================================");
//ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Filling: %s", LBEItemType.szItemName);
if ( LBEItem->IsActiveLBE(0) == FALSE ) {
// init LBE data
CreateLBE(LBEItem, pSoldier->ubID, LBEType.lbePocketIndex.size());
// stuff it full of sector items
fillLBEWithSectorItems(LBEItem);
}
// try to put the LBE item in the vehicle, if we fail then drop it.
if (placeItemInVehicle(pSoldier, *LBEItem) == false) {
// ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Dropped %s on the ground", LBEItemType.szItemName);
AutoPlaceObjectToWorld(pSoldier, LBEItem);
} else {
// ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Moved %s into the car", LBEItemType.szItemName);
}
}
}
// fills LBEObject with items from currently loaded sector. Assumes that LBEObject contains only one item
void fillLBEWithSectorItems(OBJECTTYPE * LBEObject) {
LBENODE* pLBE = LBEObject->GetLBEPointer(0);
INVTYPE LBEItemType = Item[LBEObject->usItem];
LBETYPE LBEType = LoadBearingEquipment[LBEItemType.ubClassIndex];
int movedItemsTotal = 0;
for (int i = 0; i < LBEType.lbePocketIndex.size(); i++) {
INT16 lbePocket = LBEType.lbePocketIndex[i];
if (lbePocket == 0) continue;
POCKETTYPE lbePocketType = LBEPocketType[lbePocket];
for (auto itemIterator = pInventoryPoolList.begin(); itemIterator != pInventoryPoolList.end(); itemIterator++) {
WORLDITEM * sectorItemStack = &(*itemIterator);
OBJECTTYPE * sectorItemObject = &(itemIterator->object);
INVTYPE sectorItemType = Item[sectorItemObject->usItem];
if (sectorItemStack->fExists && sectorItemStack->usFlags & WORLD_ITEM_REACHABLE && sectorItemType.usItemClass != IC_LBEGEAR && sectorItemObject->usItem > 0) {
int pocketCapacity = lbePocketType.ItemCapacityPerSize[sectorItemType.ItemSize];
if (pocketCapacity > 0) {
OBJECTTYPE * pocketItemObject = new OBJECTTYPE();
int movedItems = (sectorItemObject->ubNumberOfObjects > pocketCapacity) ? pocketCapacity : sectorItemObject->ubNumberOfObjects;
int remainingItems = sectorItemObject->MoveThisObjectTo(*pocketItemObject, movedItems);
//ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Moved %s * %i (%i remaining) into %s (%s)", sectorItemType.szItemName, movedItems, remainingItems, LBEItemType.szItemName, lbePocketType.pName);
pLBE->inv[i] = (*pocketItemObject);
movedItemsTotal += movedItems;
break;
}
}
}
}
if (movedItemsTotal == 0) {
DestroyLBE(LBEObject);
}
}
void moveCurrentSectorItemsToVehicle(SOLDIERTYPE *pSoldier) {
for (unsigned int i = 0; i < pInventoryPoolList.size(); i++)
{
if (pInventoryPoolList[i].fExists == TRUE && (pInventoryPoolList[i].usFlags & WORLD_ITEM_REACHABLE))
{
placeItemInVehicle(pSoldier, pInventoryPoolList[i]);
}
}
}
bool placeItemInVehicle(SOLDIERTYPE *pSoldier, WORLDITEM &worldItem) {
return placeItemInVehicle(pSoldier, worldItem.object);
}
bool placeItemInVehicle(SOLDIERTYPE *pSoldier, OBJECTTYPE &item) {
if (item.usItem < 1) return false;
INVTYPE sectorItemType = Item[item.usItem];
for (int x = 0; x < NUM_INV_SLOTS && item.ubNumberOfObjects > 0; x++)
{
if (vehicleInv[x] == FALSE)
continue;
if (pSoldier->inv[x].exists() == true)
{
if (pSoldier->inv[x].usItem != item.usItem)
{
continue;
}
else
{
//ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Stacking %s * %i in car slot %i", sectorItemType.szItemName, item.ubNumberOfObjects, x);
pSoldier->inv[x].AddObjectsToStack(item, -1, pSoldier, x);
}
}
else
{
//ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Placing %s * %i in car slot %i", sectorItemType.szItemName, item.ubNumberOfObjects, x);
int result = item.MoveThisObjectTo(pSoldier->inv[x], -1, pSoldier, x);
}
if (item.ubNumberOfObjects < 0)
{
break;
}
}
return (item.ubNumberOfObjects == 0);
}
+2 -2
View File
@@ -676,7 +676,7 @@ samsiteEndElementHandle( void *userData, const XML_Char *name )
pData->curElement = SAMSITE_ELEMENT_SAM;
pData->curSamInfo.samOrientation = (INT8)atol( pData->szCharData );
if ( pData->curSamInfo.samOrientation != 3 || pData->curSamInfo.samOrientation != 4 )
if ( pData->curSamInfo.samOrientation != 3 && pData->curSamInfo.samOrientation != 4 )
{
pData->curSamInfo.samOrientation = 3;
}
@@ -2045,7 +2045,7 @@ void GetMapFileName( INT16 sMapX, INT16 sMapY, INT8 bSectorZ, STR8 bString, BOOL
// Debug str
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Map does not exist for %s, using default.", bTestString ) );
// Set to a string we know!
sprintf( bString, "H10.DAT", pVertStrings[sMapY], pHortStrings[sMapX] );
sprintf( bString, "H10.DAT");
ScreenMsg( FONT_YELLOW, MSG_DEBUG, L"Using PLACEHOLDER map!" );
}
return;
+4 -2
View File
@@ -589,8 +589,10 @@ UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLE
// Determine what type of quote to say...
// Are are we going to attack?
if ( pCiv->aiData.bAction == AI_ACTION_TOSS_PROJECTILE || pCiv->aiData.bAction == AI_ACTION_FIRE_GUN ||
pCiv->aiData.bAction == AI_ACTION_FIRE_GUN || pCiv->aiData.bAction == AI_ACTION_KNIFE_MOVE )
if ( pCiv->aiData.bAction == AI_ACTION_TOSS_PROJECTILE
|| pCiv->aiData.bAction == AI_ACTION_FIRE_GUN
|| pCiv->aiData.bAction == AI_ACTION_THROW_KNIFE
|| pCiv->aiData.bAction == AI_ACTION_KNIFE_MOVE )
{
return( CIV_QUOTE_ENEMY_THREAT );
}
+5 -5
View File
@@ -11002,7 +11002,7 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
else
{
SetFontForeground( 5 );
swprintf( pStr, L"=", iFloatModifier[cnt2] );
swprintf( pStr, L"=" );
}
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
}
@@ -12016,25 +12016,25 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
if (iModifier[cnt2])
{
SetFontForeground( 5 );
swprintf( pStr, L"=", iModifier[cnt2] );
swprintf( pStr, L"=" );
}
else
{
SetFontForeground( ITEMDESC_FONTPOSITIVE );
swprintf( pStr, L"Y", iModifier[cnt2] );
swprintf( pStr, L"Y" );
}
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
}
else if ( fComparisonMode && !iComparedModifier[0] )
{
SetFontForeground( ITEMDESC_FONTNEGATIVE );
swprintf( pStr, L"N", iModifier[cnt2] );
swprintf( pStr, L"N" );
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
}
else if (iModifier[cnt2])
{
SetFontForeground( ITEMDESC_FONTPOSITIVE );
swprintf( pStr, L"Y", iModifier[cnt2] ); // FIXME: unused param
swprintf( pStr, L"Y" );
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
}
else
+15 -11
View File
@@ -156,10 +156,10 @@ void CreateLBE (OBJECTTYPE* pObj, UINT8 ubID, int numSubPockets)
(*pObj)[0]->data.lbe.uniqueID = uniqueID;
}
bool DestroyLBEIfEmpty(OBJECTTYPE* pObj)
bool DestroyLBEIfEmpty(OBJECTTYPE* pObj, int stackIndex)
{
if (pObj->IsActiveLBE(0) == true) {
LBENODE* pLBE = pObj->GetLBEPointer(0);
if (pObj->IsActiveLBE(stackIndex) == true) {
LBENODE* pLBE = pObj->GetLBEPointer(stackIndex);
if (pLBE)
{
UINT16 plbesize = pLBE->inv.size();
@@ -174,19 +174,19 @@ bool DestroyLBEIfEmpty(OBJECTTYPE* pObj)
break;
}
}
(*pObj)[0]->data.lbe.uniqueID = 0;
(*pObj)[0]->data.lbe.bLBE = 0;
(*pObj)[stackIndex]->data.lbe.uniqueID = 0;
(*pObj)[stackIndex]->data.lbe.bLBE = 0;
return true;
}
}
return false;
}
void DestroyLBE(OBJECTTYPE* pObj)
void DestroyLBE(OBJECTTYPE* pObj, int stackIndex)
{
if(pObj->IsActiveLBE(0) == true)
if(pObj->IsActiveLBE(stackIndex) == true)
{
LBENODE* pLBE = pObj->GetLBEPointer(0);
LBENODE* pLBE = pObj->GetLBEPointer(stackIndex);
if(pLBE)
{
UINT16 plbesize = pLBE->inv.size();
@@ -206,8 +206,8 @@ void DestroyLBE(OBJECTTYPE* pObj)
}
}
(*pObj)[0]->data.lbe.uniqueID = 0;
(*pObj)[0]->data.lbe.bLBE = 0;
(*pObj)[stackIndex]->data.lbe.uniqueID = 0;
(*pObj)[stackIndex]->data.lbe.bLBE = 0;
return;
}
}
@@ -1009,7 +1009,11 @@ OBJECTTYPE* StackedObjectData::GetAttachmentAtIndex(UINT8 index)
}
if (iter != attachments.end()) {
return &(*iter);
OBJECTTYPE * attachment = &(*iter);
if (attachment->usItem > 0 && (attachment->ubNumberOfObjects != 1 || attachment->usItem > MAXITEMS || attachment->ubMission != 0) ) {
__debugbreak();
}
return attachment;
}
return 0;
}
+2 -2
View File
@@ -257,8 +257,8 @@ public:
bool checkLBEArrayIntegrity(bool verbose=false); // BOB: checks all worldItems for missing LBE info
void CreateLBE(OBJECTTYPE* pObj, UINT8 ubID, int numSubPockets);
bool DestroyLBEIfEmpty(OBJECTTYPE* pObj);
void DestroyLBE(OBJECTTYPE* pObj);
bool DestroyLBEIfEmpty(OBJECTTYPE* pObj, int stackIndex = 0);
void DestroyLBE(OBJECTTYPE* pObj, int stackIndex = 0);
void GetLBESlots(UINT32 LBEType, std::vector<INT8>& LBESlots);
void MoveItemsInSlotsToLBE( SOLDIERTYPE *pSoldier, std::vector<INT8>& LBESlots, LBENODE* pLBE, OBJECTTYPE* pObj);
+50 -1
View File
@@ -8248,6 +8248,7 @@ BOOLEAN ArmBomb( OBJECTTYPE * pObj, INT8 bSetting )
return( TRUE );
}
// pAttachment will be filled with garbage data, pass a new OBJECTTYPE as pNewObj to get the removed attachment or pass NULL to indicate the attachment is to be deleted
BOOLEAN OBJECTTYPE::RemoveAttachment( OBJECTTYPE * pAttachment, OBJECTTYPE * pNewObj, UINT8 subObject, SOLDIERTYPE * pSoldier, BOOLEAN fForceInseperable, BOOLEAN fRemoveProhibited )
{
BOOLEAN objDeleted = FALSE;
@@ -8280,6 +8281,12 @@ BOOLEAN OBJECTTYPE::RemoveAttachment( OBJECTTYPE* pAttachment, OBJECTTYPE * pNew
//This is so that you can click to remove an attachment and it will take off THAT attachment and not the first one that just "looks" like it.
for (std::list<OBJECTTYPE>::iterator iter = (*this)[subObject]->attachments.begin();
iter != (*this)[subObject]->attachments.end(); ++iter){
// Bob: sanity check!
if (pAttachment != NULL && pAttachment->usItem > 0 && (pAttachment->ubNumberOfObjects != 1 || pAttachment->usItem > MAXITEMS || pAttachment->ubMission != 0)) {
__debugbreak();
}
//Compare the adress
if(&(*iter) == pAttachment)
{
@@ -8294,6 +8301,11 @@ BOOLEAN OBJECTTYPE::RemoveAttachment( OBJECTTYPE* pAttachment, OBJECTTYPE * pNew
if(!objDeleted){
for (std::list<OBJECTTYPE>::iterator iter = (*this)[subObject]->attachments.begin();
iter != (*this)[subObject]->attachments.end(); ++iter){
// Bob: sanity check!
if (pAttachment != NULL && pAttachment->usItem > 0 && (pAttachment->ubNumberOfObjects != 1 || pAttachment->usItem > MAXITEMS || pAttachment->ubMission != 0)) {
__debugbreak();
}
//This compares the internal data of the objects.
if(*iter == *pAttachment)
{
@@ -8305,9 +8317,20 @@ BOOLEAN OBJECTTYPE::RemoveAttachment( OBJECTTYPE* pAttachment, OBJECTTYPE * pNew
}
}
}
// Bob: sanity check!
if (pAttachment != NULL && pAttachment->usItem > 0 && (pAttachment->ubNumberOfObjects != 1 || pAttachment->usItem > MAXITEMS || pAttachment->ubMission != 0)) {
__debugbreak();
}
if(!objDeleted)
return( FALSE );
// Bob: this function tends to leave this pointer in a messed up state, leading to other code to deal with bogus item data
if (pAttachment != NULL) {
__debugbreak();
}
//After removing an attachment, the ammo capacity might have changed.
if ( Item[this->usItem].usItemClass == IC_GUN && (*this)[subObject]->data.gun.usGunAmmoItem != NONE && (*this)[subObject]->data.gun.ubGunShotsLeft > 0 && oldMagSize != GetMagSize(this, subObject) )
{
@@ -8399,8 +8422,23 @@ BOOLEAN OBJECTTYPE::RemoveAttachment( OBJECTTYPE* pAttachment, OBJECTTYPE * pNew
RemoveProhibitedAttachments(pSoldier, &removedAttachment, removedAttachment.usItem);
RemoveProhibitedAttachments(pSoldier, this, this->usItem);
}
if(pNewObj != NULL)
// Bob: this function tends to leave this pointer in a messed up state, leading to other code to deal with bogus item data
if (pAttachment != NULL) {
__debugbreak();
}
if (pNewObj != NULL) {
*pNewObj = removedAttachment;
}
else {
*pAttachment = removedAttachment;
}
// Bob: this function tends to leave this pointer in a messed up state, leading to other code to deal with bogus item data
if (pAttachment != NULL) {
__debugbreak();
}
// Why is this here? By now, the object, pAttachment had been pointing to, has already been deconstructed via RemoveAttachmentAtIter.
@@ -8425,11 +8463,22 @@ BOOLEAN OBJECTTYPE::RemoveAttachment( OBJECTTYPE* pAttachment, OBJECTTYPE * pNew
pNewObj->AttachObject(NULL, &tmp, FALSE, 0, -1, 0);
}
}
// Bob: this function tends to leave this pointer in a messed up state, leading other code to deal with bogus item data
if (pAttachment != NULL) {
__debugbreak();
}
//Removing an attachment can alter slots, check them.
if(UsingNewAttachmentSystem()==true && fRemoveProhibited){
RemoveProhibitedAttachments(pSoldier, this, this->usItem);
}
// Bob: this function tends to leave this pointer in a messed up state, leading to other code to deal with bogus item data
if (pAttachment != NULL) {
__debugbreak();
}
//ADB ubWeight has been removed, see comments in OBJECTTYPE
//this->ubWeight = CalculateObjectWeight( this );
return( TRUE );
+16 -1
View File
@@ -2201,7 +2201,15 @@ BOOLEAN CalculateSoldierZPos( SOLDIERTYPE * pSoldier, UINT8 ubPosType, FLOAT * p
*pdZPos = ( WALL_HEIGHT_UNITS * 2 ) - 1;
}
*pdZPos += CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[pSoldier->sGridNo].sHeight );
// Bob: check if sGridNo is set, otherwise bail out to avoid access violation
INT32 grid = pSoldier->sGridNo;
if (grid > 0) {
*pdZPos += CONVERT_PIXELS_TO_HEIGHTUNITS(gpWorldLevelData[grid].sHeight);
}
else {
// ScreenMsg(FONT_MCOLOR_LTRED, MSG_INTERFACE, L"CalculateSoldierZPos: Caught bad LOS height check!");
}
return( TRUE );
}
@@ -2505,6 +2513,13 @@ INT32 LocationToLocationLineOfSightTest( INT32 sStartGridNo, INT8 bStartLevel, I
{
FLOAT dStartZPos, dEndZPos;
INT16 sStartXPos, sStartYPos, sEndXPos, sEndYPos;
// Bob: prevent access violation
if (sStartGridNo < 0) {
// ScreenMsg(FONT_MCOLOR_LTRED, MSG_INTERFACE, L"LocationToLocationLineOfSightTest: Caught bad LOS check!");
return 0;
}
// UINT8 ubStartID;
// sevenfm: always use standing heights
+15
View File
@@ -6703,6 +6703,21 @@ void SeperateItems()
break;
}
}
// Bob: also empty out LBE items in sector inventory
if (gWorldItems[uiLoop].object.IsActiveLBE(x)) {
LBENODE * lbePtr = gWorldItems[uiLoop].object.GetLBEPointer(x);
for (auto lbeInvIter = lbePtr->inv.begin(); lbeInvIter != lbePtr->inv.end(); lbeInvIter++) {
OBJECTTYPE * LBEStack = lbeInvIter._Ptr;
if (LBEStack->usItem != 0 && LBEStack->exists()) {
AddItemToPool(gWorldItems[uiLoop].sGridNo, LBEStack, 1, gWorldItems[uiLoop].ubLevel, WORLD_ITEM_REACHABLE, -1);
}
}
DestroyLBE(&(gWorldItems[uiLoop].object), x);
}
}
}
}
+2 -2
View File
@@ -2449,7 +2449,7 @@ BOOLEAN LoadVehicleInformationFromSavedGameFile( HWFILE hFile, UINT32 uiSavedGam
{
// ! The id of the soldier was saved in the passenger pointer. The passenger pointer is converted back
// ! to a UINT8 so we can get the REAL pointer to the soldier.
pVehicleList[cnt].pPassengers[ubPassengerCnt] = FindSoldierByProfileID( (UINT8)pVehicleList[cnt].pPassengers[ ubPassengerCnt ], FALSE );
pVehicleList[cnt].pPassengers[ubPassengerCnt] = FindSoldierByProfileID( (UINT8)(pVehicleList[cnt].pPassengers[ ubPassengerCnt ]), FALSE );
}
}
else
@@ -2458,7 +2458,7 @@ BOOLEAN LoadVehicleInformationFromSavedGameFile( HWFILE hFile, UINT32 uiSavedGam
{
// ! The id of the soldier was saved in the passenger pointer. The passenger pointer is converted back
// ! to a UINT8 so we can get the REAL pointer to the soldier.
pVehicleList[cnt].pPassengers[ubPassengerCnt] = FindSoldierByProfileID( (UINT8)pVehicleList[cnt].pPassengers[ ubPassengerCnt ], FALSE );
pVehicleList[cnt].pPassengers[ubPassengerCnt] = FindSoldierByProfileID( (UINT8)(pVehicleList[cnt].pPassengers[ ubPassengerCnt ]), FALSE );
}
else
{
+1 -1
View File
@@ -210,7 +210,7 @@ BOOLEAN WriteClothesStats()
UINT32 cnt;
FilePrintf(hFile,"<CLOTHESLIST>\r\n");
for(cnt = 0; cnt < MAXITEMS; ++cnt)
for(cnt = 0; cnt < CLOTHES_MAX; ++cnt)
{
FilePrintf(hFile,"\t<CLOTHES>\r\n");
+7 -5
View File
@@ -188,14 +188,16 @@ MercStartingGearEndElementHandle(void *userData, const XML_Char *name)
else if(strcmp(name, "mName") == 0)
{
pData->curElement = ELEMENT;
if(MAX_CHAR_DATA_LENGTH >= strlen(pData->szCharData))
strcpy(pData->curMercStartingGear.mName,pData->szCharData);
if (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH ) {
strncpy(pData->curMercStartingGear.mName, pData->szCharData, mNameLength);
}
else
{
strncpy(pData->curMercStartingGear.mName,pData->szCharData,MAX_CHAR_DATA_LENGTH);
pData->curMercStartingGear.mName[MAX_CHAR_DATA_LENGTH] = '\0';
strncpy(pData->curMercStartingGear.mName,pData->szCharData, mNameLength);
pData->curMercStartingGear.mName[mNameLength-1] = '\0';
}
for(int i=0;i<min((int)strlen(pData->szCharData),MAX_CHAR_DATA_LENGTH);i++)
for(int i=0;i<min( (int)strlen(pData->szCharData), mNameLength);i++)
{
temp = pData->szCharData[i];
pData->curMercStartingGear.mName[i] = temp;
+2 -2
View File
@@ -230,10 +230,10 @@ newCarEndElementHandle(void *userData, const XML_Char *name)
else
{
strncpy(pData->curNewCar.szIconFace,pData->szCharData,MAX_MAIN_VEHICLE_CHARS);
pData->curNewCar.szIconFace[MAX_MAIN_VEHICLE_CHARS] = '\0';
pData->curNewCar.szIconFace[MAX_MAIN_VEHICLE_CHARS-1] = '\0';
}
for(int i=0;i<min((int)strlen(pData->szCharData),MAX_MAIN_VEHICLE_CHARS);i++)
for(int i=0;i<min((int)strlen(pData->szCharData),MAX_MAIN_VEHICLE_CHARS-1);i++)
{
temp = pData->szCharData[i];
pData->curNewCar.szIconFace[i] = temp;
+6
View File
@@ -1218,6 +1218,12 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
return( 0 );
}
// Bob: if gridNo isn't set, this would cause a access violation later on
if (pSoldier->sGridNo < 0) {
// ScreenMsg(FONT_MCOLOR_LTRED, MSG_INTERFACE, L"DistanceVisible(): Caught bad LOS distance check!");
return(0);
}
// anv: some places in vehicle don't give passenger any view outside
INT8 bSeatIndex = GetSeatIndexFromSoldier( pSoldier );
if( bSeatIndex != (-1) )
+5 -2
View File
@@ -453,6 +453,9 @@ public:
}; // RECORDS
//////////////////////////////////////////////////////////////////////////////
#define mNameLength 80
#define mGearKitNameLength 80
// CHRISL: Class to handle profile equipment from XML_MercStartingGear
class MERCPROFILEGEAR {
public:
@@ -472,8 +475,8 @@ public:
UINT16 mIndex;
INT16 PriceModifier;
INT16 AbsolutePrice;
CHAR16 mGearKitName[80];
CHAR8 mName[80];
CHAR16 mGearKitName[mGearKitNameLength];
CHAR8 mName[mNameLength];
char endOfPOD; // marker for end of POD (plain old data)
std::vector<int> inv;
std::vector<int> iStatus;
+1 -1
View File
@@ -258,7 +258,7 @@ NPCQuoteInfo * LoadQuoteFile( UINT8 ubNPC )
//new profiles by Jazz
else if ( gProfilesIMP[ubNPC].ProfilId == ubNPC || gProfilesAIM[ubNPC].ProfilId == ubNPC || gProfilesMERC[ubNPC].ProfilId == ubNPC || ( gProfilesRPC[ubNPC].ProfilId == ubNPC && gMercProfiles[ ubNPC ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED ) )
{
sprintf( zFileName, "NPCData\\000.npc", ubNPC ); // FIXME: extra/unused argument
sprintf( zFileName, "NPCData\\000.npc" );
}
else
{
+1 -1
View File
@@ -254,7 +254,7 @@ INT32 FindClosestClimbPoint( SOLDIERTYPE *pSoldier, INT32 sStartGridNo, INT32 sD
BUILDING * CreateNewBuilding( UINT8 * pubBuilding )
{
if (gubNumberOfBuildings >= MAX_BUILDINGS)
if (gubNumberOfBuildings >= MAX_BUILDINGS-1)
{
return( NULL );
}
+1 -2
View File
@@ -759,13 +759,12 @@ void CreateTileDatabase( INT32 iTilesetID )
}
*/
Assert(gusNumAnimatedTiles < MAX_ANIMATED_TILES);
// set into animation controller array
gusAnimatedTiles[ gusNumAnimatedTiles ] = gTileDatabaseSize;
gusNumAnimatedTiles++;
Assert( gusNumAnimatedTiles <= MAX_ANIMATED_TILES );
TileElement.uiFlags |= ANIMATED_TILE;
}
TileElement.usWallOrientation = TileSurf->pAuxData[cnt2].ubWallOrientation;
+8 -1
View File
@@ -4323,7 +4323,7 @@ STR16 pMapScreenInvenButtonHelpText[] =
L"合并堆叠同类的物品", // HEADROCK HAM 5: Stack and Merge
L"|鼠|标|左|击: 将子弹分类装入弹箱 \n|鼠|标|右|击: 将子弹分类装入纸盒 ", //L"|L|e|f|t |C|l|i|c|k: 将子弹分类装入弹箱\n|R|i|g|h|t |C|l|i|c|k: 将子弹分类装入纸盒", HEADROCK HAM 5: Sort ammo
// 6 - 10
L"移除所有物品的附件", // HEADROCK HAM 5: Separate Attachments
L"|鼠|标|左|击: 移除所有物品的附件\n|鼠|标|右|击: empty LBE in sector", // HEADROCK HAM 5: Separate Attachments
L"退出所有武器的子弹", //HEADROCK HAM 5: Eject Ammo
L"|鼠|标|左|击: 显示全部物品 \n|鼠|标|右|击: 隐藏全部物品 ", // HEADROCK HAM 5: Filter Button
L"|鼠|标|左|击: 切换显示武器 \n|鼠|标|右|击: 只显示武器 ", // HEADROCK HAM 5: Filter Button
@@ -8637,6 +8637,13 @@ STR16 gzMapInventorySortingMessage[] =
L"已完成 移除所有物品上的附件 在区域 %c%d.",
L"已完成 退出所有武器里的子弹 在区域 %c%d.",
L"已完成 合并后堆叠了所有物品 在区域 %c%d.",
// Bob: new strings for emptying LBE items
L"Finished emptying LBE items in sector %c%d.",
L"Dropped %i item(s) from %s", // Bunch of stuff removed from LBE item %s
L"No droppable items in %s!", // LBE item %s had a LBENode assigned but it contained no items (error!)
L"%s is now empty.", // LBE item %s contained stuff and was emptied
L"Cannot empty %s!", // Removed everything we could from LBE item %s but it's still not marked as empty (error!)
L"%s contents lost!", // LBE item %s not marked as empty but LBENode not found (error!!!)
};
STR16 gzMapInventoryFilterOptions[] =
+8 -1
View File
@@ -4328,7 +4328,7 @@ STR16 pMapScreenInvenButtonHelpText[] =
L"Stack and merge items", // HEADROCK HAM 5: Stack and Merge
L"|L|e|f|t |C|l|i|c|k: Sort ammo into crates\n|R|i|g|h|t |C|l|i|c|k: Sort ammo into boxes", // HEADROCK HAM 5: Sort ammo
// 6 - 10
L"Remove all item attachments", // HEADROCK HAM 5: Separate Attachments
L"|L|e|f|t |C|l|i|c|k: Remove all item attachments\n|R|i|g|h|t |C|l|i|c|k: empty LBE in sector", // HEADROCK HAM 5: Separate Attachments; Bob: empty LBE items
L"Eject ammo from all weapons", //HEADROCK HAM 5: Eject Ammo
L"|L|e|f|t |C|l|i|c|k: Show all items\n|R|i|g|h|t |C|l|i|c|k: Hide all items", // HEADROCK HAM 5: Filter Button
L"|L|e|f|t |C|l|i|c|k: Toggle Guns\n|R|i|g|h|t |C|l|i|c|k|: Show only Guns", // HEADROCK HAM 5: Filter Button
@@ -8655,6 +8655,13 @@ STR16 gzMapInventorySortingMessage[] =
L"Finished removing attachments from items in sector %c%d.",
L"Finished ejecting ammo from weapons in sector %c%d.",
L"Finished stacking and merging all items in sector %c%d.",
// Bob: new strings for emptying LBE items
L"Finished emptying LBE items in sector %c%d.",
L"Dropped %i item(s) from %s", // Bunch of stuff removed from LBE item %s
L"No droppable items in %s!", // LBE item %s had a LBENode assigned but it contained no items (error!)
L"%s is now empty.", // LBE item %s contained stuff and was emptied
L"Cannot empty %s!", // Removed everything we could from LBE item %s but it's still not marked as empty (error!)
L"%s contents lost!", // LBE item %s not marked as empty but LBENode not found (error!!!)
};
STR16 gzMapInventoryFilterOptions[] =
+8 -1
View File
@@ -4324,7 +4324,7 @@ STR16 pMapScreenInvenButtonHelpText[] =
L"Stack and merge items", // HEADROCK HAM 5: Stack and Merge
L"|L|e|f|t |C|l|i|c|k: Sort ammo into crates\n|R|i|g|h|t |C|l|i|c|k: Sort ammo into boxes", // HEADROCK HAM 5: Sort ammo
// 6 - 10
L"Remove all item attachments", // HEADROCK HAM 5: Separate Attachments
L"|L|e|f|t |C|l|i|c|k: Remove all item attachments\n|R|i|g|h|t |C|l|i|c|k: empty LBE in sector", // HEADROCK HAM 5: Separate Attachments; Bob: empty LBE items
L"Eject ammo from all weapons", //HEADROCK HAM 5: Eject Ammo
L"|L|e|f|t |C|l|i|c|k: Show all items\n|R|i|g|h|t |C|l|i|c|k: Hide all items", // HEADROCK HAM 5: Filter Button
L"|L|e|f|t |C|l|i|c|k: Toggle Guns\n|R|i|g|h|t |C|l|i|c|k|: Show only Guns", // HEADROCK HAM 5: Filter Button
@@ -8639,6 +8639,13 @@ STR16 gzMapInventorySortingMessage[] =
L"Finished removing attachments from items in sector %c%d.",
L"Finished ejecting ammo from weapons in sector %c%d.",
L"Finished stacking and merging all items in sector %c%d.",
// Bob: new strings for emptying LBE items
L"Finished emptying LBE items in sector %c%d.",
L"Dropped %i item(s) from %s", // Bunch of stuff removed from LBE item %s
L"No droppable items in %s!", // LBE item %s had a LBENode assigned but it contained no items (error!)
L"%s is now empty.", // LBE item %s contained stuff and was emptied
L"Cannot empty %s!", // Removed everything we could from LBE item %s but it's still not marked as empty (error!)
L"%s contents lost!", // LBE item %s not marked as empty but LBENode not found (error!!!)
};
STR16 gzMapInventoryFilterOptions[] =
+8 -1
View File
@@ -4331,7 +4331,7 @@ STR16 pMapScreenInvenButtonHelpText[] =
L"Empiler les mêmes objets", // HEADROCK HAM 5: Stack and Merge
L"|C|l|i|c |G|. : Trier munitions par caisse\n|C|l|i|c |D|. : Trier munitions par boîte", // HEADROCK HAM 5: Sort ammo
// 6 - 10
L"Ôter tous les accessoires des objets", // HEADROCK HAM 5: Separate Attachments
L"|C|l|i|c |G|. : Ôter tous les accessoires des objets\n|C|l|i|c |D|. : empty LBE in sector", // HEADROCK HAM 5: Separate Attachments
L"Décharger toutes les armes", //HEADROCK HAM 5: Eject Ammo
L"|C|l|i|c |G|. : Voir tous les objets\n|C|l|i|c |D|. : Cacher tous les objets", // HEADROCK HAM 5: Filter Button
L"|C|l|i|c |G|. : Avec/sans armes\n|C|l|i|c |D|. : Voir que les armes", // HEADROCK HAM 5: Filter Button
@@ -8640,6 +8640,13 @@ STR16 gzMapInventorySortingMessage[] =
L"Fin du démontage de tous les accessoires au secteur %c%d.",
L"Fin du déchargement des armes au secteur %c%d.",
L"Fin du classement et de l'empilage par type au secteur %c%d.",
// Bob: new strings for emptying LBE items
L"Finished emptying LBE items in sector %c%d.",
L"Dropped %i item(s) from %s", // Bunch of stuff removed from LBE item %s
L"No droppable items in %s!", // LBE item %s had a LBENode assigned but it contained no items (error!)
L"%s is now empty.", // LBE item %s contained stuff and was emptied
L"Cannot empty %s!", // Removed everything we could from LBE item %s but it's still not marked as empty (error!)
L"%s contents lost!", // LBE item %s not marked as empty but LBENode not found (error!!!)
};
STR16 gzMapInventoryFilterOptions[] =
+8 -1
View File
@@ -4317,7 +4317,7 @@ STR16 pMapScreenInvenButtonHelpText[] =
L"Gegenstände stapeln und verbinden", // HEADROCK HAM 5: Stack and Merge
L"|L|i|n|k|e|r |K|l|i|c|k: Munition in Kisten sortieren\n|R|e|c|h|t|e|r |K|l|i|c|k: Munition in Boxen sortieren", // HEADROCK HAM 5: Sort ammo
// 6 - 10
L"Alle Gegenstandsanbauten entfernen", // HEADROCK HAM 5: Separate Attachments
L"|L|i|n|k|e|r |K|l|i|c|k: Alle Gegenstandsanbauten entfernen\n|R|e|c|h|t|e|r |K|l|i|c|k: empty LBE in sector", // HEADROCK HAM 5: Separate Attachments
L"Munition aus allen Waffen entfernen", //HEADROCK HAM 5: Eject Ammo
L"|L|i|n|k|e|r |K|l|i|c|k: Alle Gegenstände anzeigen\n|R|e|c|h|t|e|r |K|l|i|c|k: Alle Gegenstände ausblenden", // HEADROCK HAM 5: Filter Button
L"|L|i|n|k|e|r |K|l|i|c|k: Ein-/Ausblenden von Waffen\n|R|e|c|h|t|e|r |K|l|i|c|k: Nur Waffen anzeigen", // HEADROCK HAM 5: Filter Button
@@ -8470,6 +8470,13 @@ STR16 gzMapInventorySortingMessage[] =
L"Das Entfernen von Gegenstandsanbauten im Sektor %c%d wurde fertiggestellt.",
L"Das Entfernen von Munition der Waffen im Sektor %c%d wurde fertiggestellt.",
L"Das Stapeln und Zusammenführen von Gegenständen im Sektor %c%d wurde fertiggestellt.",
// Bob: new strings for emptying LBE items
L"Finished emptying LBE items in sector %c%d.",
L"Dropped %i item(s) from %s", // Bunch of stuff removed from LBE item %s
L"No droppable items in %s!", // LBE item %s had a LBENode assigned but it contained no items (error!)
L"%s is now empty.", // LBE item %s contained stuff and was emptied
L"Cannot empty %s!", // Removed everything we could from LBE item %s but it's still not marked as empty (error!)
L"%s contents lost!", // LBE item %s not marked as empty but LBENode not found (error!!!)
};
STR16 gzMapInventoryFilterOptions[] =
+8 -1
View File
@@ -4322,7 +4322,7 @@ STR16 pMapScreenInvenButtonHelpText[] =
L"Stack and merge items", // HEADROCK HAM 5: Stack and Merge
L"|L|e|f|t |C|l|i|c|k: Sort ammo into crates\n|R|i|g|h|t |C|l|i|c|k: Sort ammo into boxes", // HEADROCK HAM 5: Sort ammo
// 6 - 10
L"Remove all item attachments", // HEADROCK HAM 5: Separate Attachments
L"|L|e|f|t |C|l|i|c|k: Remove all item attachments\n|R|i|g|h|t |C|l|i|c|k: empty LBE in sector", // HEADROCK HAM 5: Separate Attachments; Bob: empty LBE items
L"Eject ammo from all weapons", //HEADROCK HAM 5: Eject Ammo
L"|L|e|f|t |C|l|i|c|k: Show all items\n|R|i|g|h|t |C|l|i|c|k: Hide all items", // HEADROCK HAM 5: Filter Button
L"|L|e|f|t |C|l|i|c|k: Toggle Guns\n|R|i|g|h|t |C|l|i|c|k|: Show only Guns", // HEADROCK HAM 5: Filter Button
@@ -8645,6 +8645,13 @@ STR16 gzMapInventorySortingMessage[] =
L"Finished removing attachments from items in sector %c%d.",
L"Finished ejecting ammo from weapons in sector %c%d.",
L"Finished stacking and merging all items in sector %c%d.",
// Bob: new strings for emptying LBE items
L"Finished emptying LBE items in sector %c%d.",
L"Dropped %i item(s) from %s", // Bunch of stuff removed from LBE item %s
L"No droppable items in %s!", // LBE item %s had a LBENode assigned but it contained no items (error!)
L"%s is now empty.", // LBE item %s contained stuff and was emptied
L"Cannot empty %s!", // Removed everything we could from LBE item %s but it's still not marked as empty (error!)
L"%s contents lost!", // LBE item %s not marked as empty but LBENode not found (error!!!)
};
STR16 gzMapInventoryFilterOptions[] =
+12 -5
View File
@@ -4333,7 +4333,7 @@ STR16 pMapScreenInvenButtonHelpText[] =
L"Stack and merge items", // HEADROCK HAM 5: Stack and Merge
L"|L|e|f|t |C|l|i|c|k: Sort ammo into crates\n|R|i|g|h|t |C|l|i|c|k: Sort ammo into boxes", // HEADROCK HAM 5: Sort ammo
// 6 - 10
L"Remove all item attachments", // HEADROCK HAM 5: Separate Attachments
L"|L|e|f|t |C|l|i|c|k: Remove all item attachments\n|R|i|g|h|t |C|l|i|c|k: empty LBE in sector", // HEADROCK HAM 5: Separate Attachments; Bob: empty LBE items
L"Eject ammo from all weapons", //HEADROCK HAM 5: Eject Ammo
L"|L|e|f|t |C|l|i|c|k: Show all items\n|R|i|g|h|t |C|l|i|c|k: Hide all items", // HEADROCK HAM 5: Filter Button
L"|L|e|f|t |C|l|i|c|k: Toggle Guns\n|R|i|g|h|t |C|l|i|c|k|: Show only Guns", // HEADROCK HAM 5: Filter Button
@@ -8653,10 +8653,17 @@ STR16 gzNCTHlabels[]=
// HEADROCK HAM 5: Screen messages for sector inventory sorting reports.
STR16 gzMapInventorySortingMessage[] =
{
L"Finished sorting ammo into crates in sector %c%d.",
L"Finished removing attachments from items in sector %c%d.",
L"Finished ejecting ammo from weapons in sector %c%d.",
L"Finished stacking and merging all items in sector %c%d.",
L"Spakowano amunicję do skrzyń w sektorze %c%d.",
L"Usunięto dodatki z przedmiotów w sektorze %c%d.",
L"Rozładowano amunicję z broni w sektorze %c%d.",
L"Poukładano i scalono przedmioty w sektorze %c%d.",
// Bob: new strings for emptying LBE items
L"Rozładowano LBE w sektorze %c%d.",
L"Wyrzucono %i przedmiot(ów) z %s", // Bunch of stuff removed from LBE item %s
L"Nie można nic wyjąć z %s!", // LBE item %s had a LBENode assigned but it contained no items (error!)
L"Rozładowano %s.", // LBE item %s contained stuff and was emptied
L"Nie udało się rozładować %s!", // Removed everything we could from LBE item %s but it's still not marked as empty (error!)
L"Utracona zawartość %s!", // LBE item %s not marked as empty but LBENode not found (error!!!)
};
STR16 gzMapInventoryFilterOptions[] =
+8 -1
View File
@@ -4324,7 +4324,7 @@ STR16 pMapScreenInvenButtonHelpText[] =
L"Сложить и объединить предметы", // HEADROCK HAM 5: Stack and Merge
L"|Л|е|в|ы|й| |щ|е|л|ч|о|к|: Собрать патроны в ящики\n|П|р|а|в|ы|й| |щ|е|л|ч|о|к|: Собрать патроны в коробки", // HEADROCK HAM 5: Sort ammo
// 6 - 10
L"Снять всю навеску \nс предметов", // HEADROCK HAM 5: Separate Attachments
L"|Л|е|в|ы|й| |щ|е|л|ч|о|к|: Снять всю навеску \nс предметов\n|П|р|а|в|ы|й| |щ|е|л|ч|о|к|: empty LBE in sector", // HEADROCK HAM 5: Separate Attachments
L"Разрядить всё оружие", //HEADROCK HAM 5: Eject Ammo
L"|Л|е|в|ы|й| |щ|е|л|ч|о|к|: Показать все предметы\n|П|р|а|в|ы|й| |щ|е|л|ч|о|к|: Скрыть все предметы", // HEADROCK HAM 5: Filter Button
L"|Л|е|в|ы|й| |щ|е|л|ч|о|к|: Скрыть оружие\n|П|р|а|в|ы|й| |щ|е|л|ч|о|к|: Показать оружие", // HEADROCK HAM 5: Filter Button
@@ -8639,6 +8639,13 @@ STR16 gzMapInventorySortingMessage[] =
L"С предметов в секторе %c%d снята вся навеска.",
L"В секторе %c%d всё оружие разряжено.",
L"В секторе %c%d все вещи сгруппированы и объединены.",
// Bob: new strings for emptying LBE items
L"Finished emptying LBE items in sector %c%d.",
L"Dropped %i item(s) from %s", // Bunch of stuff removed from LBE item %s
L"No droppable items in %s!", // LBE item %s had a LBENode assigned but it contained no items (error!)
L"%s is now empty.", // LBE item %s contained stuff and was emptied
L"Cannot empty %s!", // Removed everything we could from LBE item %s but it's still not marked as empty (error!)
L"%s contents lost!", // LBE item %s not marked as empty but LBENode not found (error!!!)
};
STR16 gzMapInventoryFilterOptions[] =
+4 -2
View File
@@ -372,7 +372,7 @@ void BuildListFile( )
fOKFiles = TRUE;
cnt = 0;
while( !feof( infoFile ) )
while( !feof( infoFile ) && cnt < numEntries )
{
fgets( currFilename, 128, infoFile );
@@ -384,9 +384,11 @@ void BuildListFile( )
if ( usState != 5555 )
{
// Bob: swapped places, there's numEntries things to be put in pusStates, I'm guessing supposed to start at 0
pusStates[cnt] = usState;
cnt++;
ubNumStates = (UINT8)cnt;
pusStates[ cnt ] = usState;
// pusStates[ cnt ] = usState;
}
else
{
+1 -1
View File
@@ -893,7 +893,7 @@ png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_fcTL) &&
width != NULL && height != NULL &&
x_offset != NULL && x_offset != NULL &&
x_offset != NULL && y_offset != NULL &&
delay_num != NULL && delay_den != NULL &&
dispose_op != NULL && blend_op != NULL)
{