static void XMLCALL facilityEndElementHandle(void *userData, const XML_Char *name) { facilityParseData * pData = (facilityParseData *)userData; if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading { if(strcmp(name, "SECTORFACILITIES") == 0) { pData->curElement = ELEMENT_NONE; NUM_FACILITIES = pData->curIndex; } else if(strcmp(name, "FACILITY") == 0) { pData->curIndex++; pData->curElement = ELEMENT_LIST; if (pData->ubCurFacilityType != 0) { gFacilityLocations[SECTOR(pData->sCurSectorX,pData->sCurSectorY)][pData->ubCurFacilityType].fFacilityHere = TRUE; gFacilityLocations[SECTOR(pData->sCurSectorX,pData->sCurSectorY)][pData->ubCurFacilityType].ubHidden = pData->ubHidden; } } else if(strcmp(name, "SectorGrid") == 0 ) { UINT8 x, y; pData->curElement = ELEMENT; y = (UINT8)pData->szCharData[0] & 0x1F; x = (UINT8)atol(&pData->szCharData[1]); if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) { pData->sCurSectorX = x; pData->sCurSectorY = y; } } else if(strcmp(name, "FacilityType") == 0 ) { pData->curElement = ELEMENT; pData->ubCurFacilityType = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "ubHidden") == 0 ) { pData->curElement = ELEMENT; pData->ubHidden = (BOOLEAN) atol(pData->szCharData); } pData->maxReadDepth--; } pData->currentDepth--; }
static void XMLCALL SectorCoolnessEndElementHandle(void *userData, const XML_Char *name) { SectorCoolnessParseData * pData = (SectorCoolnessParseData *) userData; if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading { if(strcmp(name, "COOLNESS_BY_SECTOR") == 0 && pData->curElement == ELEMENT_LIST) { pData->curElement = ELEMENT_NONE; } else if(strcmp(name, "MAP_ROW") == 0 && pData->curElement == ELEMENT) { STR8 curBuffer = pData->szCharData + strspn(pData->szCharData," \t\n\r"); UINT32 curCellIndex = 0; UINT32 curNumber; pData->curElement = ELEMENT_LIST; while(curBuffer[0] != '\0') { sscanf( curBuffer,"%d",&curNumber); gCoolnessBySector[SECTOR(curCellIndex+1, pData->uiRowNumber) ] = curNumber; curCellIndex++; curBuffer += strcspn(curBuffer," \t\n\r\0"); curBuffer += strspn(curBuffer," \t\n\r"); } } pData->maxReadDepth--; } pData->currentDepth--; }
size_t lm_write(sect_t lsn, sect_t size, int mapdir_flag) { int lbn; int lpn; int offset; // logical page number int pbn; int sect_num = SECT_NUM_PER_PAGE; int s_psn, s_lsn; int i; sect_t lsns[SECT_NUM_PER_PAGE]; lbn = lsn / SECT_NUM_PER_BLK; lpn = lsn/SECT_NUM_PER_PAGE; offset = (lsn % SECT_NUM_PER_BLK); pbn = getPbnFromBMT(lbn); memset (lsns, 0xFF, sizeof (lsns)); s_psn = SECTOR(pbn, offset); s_lsn = lpn * SECT_NUM_PER_PAGE; for (i = 0; i < SECT_NUM_PER_PAGE; i++) { lsns[i] = s_lsn + i; } size = nand_oob_read(s_psn); /* valid_flag = 1 -> valid sect num = 4 valid_flag = -1 -> valid sect num = 0; valid_flag = 0 -> all are free (nothing written) */ if( size != 0 ) { // Call writeToLogBlock memset (lsns, 0xFF, sizeof (lsns)); writeToLogBlock(lsn,lbn,lpn); } else { nand_page_write(s_psn, lsns, 0, 1); } return sect_num; }
/////////////////////////////// Reinforcement Sector Selection //////////////////////////////////////////// void ReinforcementSector::Setup( UINT32 aVal ) { Destroy(); SOLDIERTYPE * pSoldier = NULL; GetSoldier( &pSoldier, gusSelectedSoldier ); if ( pSoldier == NULL ) return; if ( pSoldier->CanUseSkill(aVal) ) { SetupPopup("Reinforcements sector"); POPUP_OPTION *pOption; CHAR16 pStr[300]; // check wether we can call artillery from the 4 adjacent sectors for (UINT8 i = 0; i < 4; ++i) { INT16 loopX = pSoldier->sSectorX; INT16 loopY = pSoldier->sSectorY; if ( i == 0 ) ++loopY; else if ( i == 1 ) ++loopX; else if ( i == 2 ) --loopY; else if ( i == 3 ) --loopX; if ( loopX < 1 || loopX >= MAP_WORLD_X - 1 || loopY < 1 || loopY >= MAP_WORLD_Y - 1 ) continue; UINT32 sectornr = (UINT32)SECTOR( loopX, loopY ); swprintf( pStr, L"%c%d", loopY + 'A' - 1, loopX ); pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Setup_ReinforcementNumber, sectornr ) ); // grey out if no reinforcements can be called from this sector if ( !CanRequestMilitiaReinforcements( pSoldier->sSectorX, pSoldier->sSectorY, loopX, loopY ) ) { // Set this option off. pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL )); } GetPopup()->addOption( *pOption ); } // cancel option swprintf( pStr, pSkillMenuStrings[SKILLMENU_CANCEL] ); pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Cancel_ReinforcementSector, 0 ) ); GetPopup()->addOption( *pOption ); } // same y, different x SetPos(gSkillSelection.GetMaxPosX(), usTraitMenuPosY); }
// start a new incident void StartIncident(INT16 sX, INT16 sY, INT8 sZ) { gCampaignStats.usHighestID++; gCurrentIncident.usID = gCampaignStats.usHighestID; gCurrentIncident.usTime = GetWorldTotalSeconds(); gCurrentIncident.usSector = SECTOR(sX, sY); gCurrentIncident.usLevel = sZ; }
void StrategicAddMilitiaToSector(INT16 sMapX, INT16 sMapY, UINT8 ubRank, UINT8 ubHowMany) { SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] ); pSectorInfo->ubNumberOfCivsAtLevel[ ubRank ] += ubHowMany; // update the screen display fMapPanelDirty = TRUE; }
void ContinueTrainingInThisSector( void ) { UINT8 ubSector; Assert( pMilitiaTrainerSoldier ); // pay up in the sector where pMilitiaTrainerSoldier is ubSector = SECTOR( pMilitiaTrainerSoldier->sSectorX, pMilitiaTrainerSoldier->sSectorY ); PayForTrainingInSector( ubSector ); }
BOOLEAN DoesPlayerHaveAnyMilitia( void ) { INT16 sX, sY; // run through list of towns that might have militia..if any return TRUE..else return FALSE for( sX = 1; sX < MAP_WORLD_X - 1; sX++ ) { for( sY = 1; sY < MAP_WORLD_Y - 1; sY++ ) { if( ( SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] + SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ ELITE_MILITIA ] ) > 0 ) { // found at least one return( TRUE ); } } } // no one found return( FALSE ); }
static struct request *make_request(int rw, struct buffer *buf) { struct request *req = slab_alloc(request_cachep); if (!req) panic("No memory for block request"); // FIXME: block until memory available req->rw = rw; req->sector = SECTOR(buf); req->nr_sectors = NR_SECTORS(buf); req->mem = buf->b_data; req->buf = buf; buf->b_count++; return req; }
static void XMLCALL garrisonEndElementHandle(void *userData, const XML_Char *name) { garrisonParseData * pData = (garrisonParseData *) userData; if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading { if(strcmp(name, "GARRISON_INFO") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON_INFO) { pData->curElement = GARRISON_ELEMENT_NONE; iOrigGarrisonArraySize = pData->uiGarrisonCount; } else if(strcmp(name, "GARRISON") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON) { pData->curElement = GARRISON_ELEMENT_GARRISON_INFO; if ( pData->curGarrisonInfo.fValidSector && pData->uiGarrisonCount < MAX_GARRISON_GROUPS ) { gOrigGarrisonGroup[ pData->uiGarrisonCount ].ubSectorID = pData->curGarrisonInfo.ubSectorID; gOrigGarrisonGroup[ pData->uiGarrisonCount ].ubComposition = pData->curGarrisonInfo.ubComposition; pData->uiGarrisonCount++; } } else if(strcmp(name, "Sector") == 0 && pData->curElement == GARRISON_ELEMENT_SECTOR) { UINT8 x, y; pData->curElement = GARRISON_ELEMENT_GARRISON; y = (UINT8)pData->szCharData[0] & 0x1F; x = (UINT8)atol(&pData->szCharData[1]); if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) { pData->curGarrisonInfo.fValidSector = TRUE; pData->curGarrisonInfo.ubSectorID = SECTOR(x,y); } else { pData->curGarrisonInfo.fValidSector = FALSE; } } else if(strcmp(name, "Composition") == 0 && pData->curElement == GARRISON_ELEMENT_COMPOSITION) { pData->curElement = GARRISON_ELEMENT_GARRISON; pData->curGarrisonInfo.ubComposition = (UINT8) atol(pData->szCharData); } pData->maxReadDepth--; } pData->currentDepth--; }
// add this incident to the campaign stats and then clear it void FinishIncident(INT16 sX, INT16 sY, INT8 sZ) { // it is possible to enter a combat without any real fighting. // For now, lets just assume this happens with undetected spies. If nothing of interest happened, don't add this incident (it would be boring to read anyway) if ( gCurrentIncident.usIncidentFlags & (INCIDENT_SPYACTION_ENEMY|INCIDENT_SPYACTION_PLAYERSIDE) && !(gCurrentIncident.usIncidentFlags & INCIDENT_SPYACTION_UNCOVERED) ) { // if noting of interest happened... if ( !(gCurrentIncident.usIncidentFlags & INCIDENT_EVENT) && gCurrentIncident.usOneTimeEventFlags == 0 ) { UINT16 i = 0; // if nobody was harmed... for (i = 0; i < CAMPAIGNHISTORY_SD_MAX; ++i) { if ( gCurrentIncident.usKills[i] || gCurrentIncident.usWounds[i] || gCurrentIncident.usPrisoners[i] ) break; } if ( i == CAMPAIGNHISTORY_SD_MAX ) { // totally boring. Don't add this, just clean it an exit gCurrentIncident.clear(); return; } } } // due to odd coding, we do not know when an incident starts // (checking for entering combat isn't enough, as we do that multiple times per battle) // we thus set the relevant data when finishing an incident gCampaignStats.usHighestID++; gCurrentIncident.usID = gCampaignStats.usHighestID; gCurrentIncident.usTime = GetWorldTotalSeconds(); gCurrentIncident.usSector = SECTOR(sX, sY); gCurrentIncident.usLevel = sZ; // add flags depending on quests etc. // if this is incident 1, we just landed - special text then if ( gCampaignStats.usHighestID == 1 ) gCurrentIncident.usOneTimeEventFlags |= INCIDENT_ONETIMEEVENT_OMERTA; gCampaignStats.AddNewIncident(gCurrentIncident); // reset incident after adding it gCurrentIncident.clear(); }
void ClearMapControlledFlags( void ) { INT32 iCounterA = 0, iCounterB = 0; UINT16 usMapSector = 0; for( iCounterA = 1; iCounterA < MAP_WORLD_X - 1; iCounterA++ ) { for( iCounterB = 1; iCounterB < MAP_WORLD_Y - 1; iCounterB++ ) { usMapSector = iCounterA + ( iCounterB * MAP_WORLD_X ); StrategicMap[ usMapSector ].fEnemyControlled = FALSE; SectorInfo[ SECTOR( iCounterA, iCounterB ) ].fPlayer[ 0 ] = TRUE; } } }
void StrategicRemoveMilitiaFromSector(INT16 sMapX, INT16 sMapY, UINT8 ubRank, UINT8 ubHowMany) { SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] ); // damn well better have that many around to remove! Assert(pSectorInfo->ubNumberOfCivsAtLevel[ ubRank ] >= ubHowMany); //KM : July 21, 1999 patch fix if( pSectorInfo->ubNumberOfCivsAtLevel[ ubRank ] < ubHowMany ) { return; } pSectorInfo->ubNumberOfCivsAtLevel[ ubRank ] -= ubHowMany; // update the screen display fMapPanelDirty = TRUE; }
void AddTextToBlankSectorBox( void ) { UINT32 hStringHandle; UINT16 usSectorValue = 0; // get the sector value usSectorValue = SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ); switch( usSectorValue ) { case SEC_D2: //Chitzena SAM if( !fSamSiteFound[ SAM_SITE_ONE ] ) AddMonoString( &hStringHandle, pLandTypeStrings[ TROPICS ] ); else AddMonoString( &hStringHandle, pLandTypeStrings[ TROPICS_SAM_SITE ] ); break; case SEC_D15: //Drassen SAM if( !fSamSiteFound[ SAM_SITE_TWO ] ) AddMonoString( &hStringHandle, pLandTypeStrings[ SPARSE ] ); else AddMonoString( &hStringHandle, pLandTypeStrings[ SPARSE_SAM_SITE ] ); break; case SEC_I8: //Cambria SAM if( !fSamSiteFound[ SAM_SITE_THREE ] ) AddMonoString( &hStringHandle, pLandTypeStrings[ SAND ] ); else AddMonoString( &hStringHandle, pLandTypeStrings[ SAND_SAM_SITE ] ); break; // SAM Site 4 in Meduna is within town limits, so it's handled in AddTextToTownBox() default: AddMonoString( &hStringHandle, pLandTypeStrings[ ( SectorInfo[ usSectorValue ].ubTraversability[ 4 ] ) ] ); break; } // blank line AddMonoString( &hStringHandle, L"" ); // sector AddSectorToBox(); }
BOOLEAN CanNearbyMilitiaScoutThisSector( INT16 sSectorX, INT16 sSectorY ) { INT16 sSectorValue = 0, sSector = 0; INT16 sCounterA = 0, sCounterB = 0; UINT8 ubScoutingRange = 1; // get the sector value sSector = sSectorX + sSectorY * MAP_WORLD_X; for( sCounterA = sSectorX - ubScoutingRange; sCounterA <= sSectorX + ubScoutingRange; sCounterA++ ) { for( sCounterB = sSectorY - ubScoutingRange; sCounterB <= sSectorY + ubScoutingRange; sCounterB++ ) { // skip out of bounds sectors if ( ( sCounterA < 1 ) || ( sCounterA > 16 ) || ( sCounterB < 1 ) || ( sCounterB > 16 ) ) { continue; } sSectorValue = SECTOR( sCounterA, sCounterB ); // check if any sort of militia here if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ GREEN_MILITIA ] ) { return( TRUE ); } else if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] ) { return( TRUE ); } else if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ ELITE_MILITIA ] ) { return( TRUE ); } } } return( FALSE ); }
void ResetDoneFlagForAllMilitiaTrainersInSector( UINT8 ubSector ) { INT32 iCounter = 0; SOLDIERTYPE *pSoldier = NULL; for( iCounter = 0; iCounter <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; iCounter++ ) { pSoldier = &Menptr[ iCounter ]; if( pSoldier->bActive ) { if( pSoldier->bAssignment == TRAIN_TOWN ) { if( ( SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) == ubSector ) && ( pSoldier->bSectorZ == 0 ) ) { pSoldier->fDoneAssignmentAndNothingToDoFlag = FALSE; pSoldier->usQuoteSaidExtFlags &= ~SOLDIER_QUOTE_SAID_DONE_ASSIGNMENT; } } } } }
// adds text to town info box void AddTextToTownBox( void ) { UINT32 hStringHandle = 0; CHAR16 wString[ 64 ]; UINT8 ubTownId = 0; UINT16 usTownSectorIndex; INT16 sMineSector = 0; // remember town id ubTownId = GetTownIdForSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ); Assert((ubTownId >= FIRST_TOWN) && (ubTownId < NUM_TOWNS)); usTownSectorIndex = SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ); AssertGE(usTownSectorIndex, 0); AssertLT(usTownSectorIndex,256); //////////////////////////////////// // HEADROCK HAM 5: // Read and verify XML sector names BOOLEAN fSectorHasXMLNames = TRUE; CHAR16 zUnexplored[MAX_SECTOR_NAME_LENGTH]; CHAR16 zExplored[MAX_SECTOR_NAME_LENGTH]; wcscpy( zUnexplored, gzSectorNames[ usTownSectorIndex ][0] ); wcscpy( zExplored, gzSectorNames[ usTownSectorIndex ][2] ); if (zUnexplored[0] == 0 || zExplored[0] == 0) { fSectorHasXMLNames = FALSE; } if (fSectorHasXMLNames) // ABOVE GROUND XML { // HEADROCK HAM 3.6: The program can now read custom names from XML for all above-ground sectors. // In the event that a specific name or set of names is missing, the program generates a default // name as it always has. // I've also updated the SAM Site sectors to rely on SamSite.XML data. BOOLEAN fVisited = (SectorInfo[ usTownSectorIndex ].uiFlags & SF_ALREADY_VISITED); BOOLEAN fSAMSiteKnown = FALSE; // Test for known SAM Site at this location for (UINT16 x=0; x < MAX_NUMBER_OF_SAMS; x++) { if ( pSamList[x] == usTownSectorIndex ) { if ( fSamSiteFound[ x ] ) { fSAMSiteKnown = TRUE; } } } if (fVisited || fSAMSiteKnown) { AddMonoString( &hStringHandle, zExplored ); } else { AddMonoString( &hStringHandle, zUnexplored ); } } else // ABOVE GROUND HARDCODED { switch( usTownSectorIndex ) { case SEC_B13: AddMonoString( &hStringHandle, pLandTypeStrings[ DRASSEN_AIRPORT_SITE ] ); break; case SEC_F8: AddMonoString( &hStringHandle, pLandTypeStrings[ CAMBRIA_HOSPITAL_SITE ] ); break; case SEC_J9: //Tixa //if( !fFoundTixa ) if( gfHiddenTown[ TIXA ] == FALSE ) AddMonoString( &hStringHandle, pLandTypeStrings[ SAND ] ); else AddMonoString( &hStringHandle, pTownNames[ TIXA ] ); break; case SEC_K4: //Orta //if( !fFoundOrta ) if( gfHiddenTown[ ORTA ] == FALSE ) AddMonoString( &hStringHandle, pLandTypeStrings[ SWAMP ] ); else AddMonoString( &hStringHandle, pTownNames[ ORTA ] ); break; case SEC_N3: AddMonoString( &hStringHandle, pLandTypeStrings[ MEDUNA_AIRPORT_SITE ] ); break; default: if( usTownSectorIndex == SEC_N4 && fSamSiteFound[ SAM_SITE_FOUR ] ) { //Meduna's SAM site AddMonoString( &hStringHandle, pLandTypeStrings[ MEDUNA_SAM_SITE ] ); } else { // town name swprintf( wString, L"%s", pTownNames[ ubTownId ] ); AddMonoString( &hStringHandle, wString ); } break; } } // blank line AddMonoString( &hStringHandle, L"" ); // sector AddSectorToBox(); // town size if( gfHiddenTown[ GetTownIdForSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ] ) { swprintf( wString, L"%s:", pwTownInfoStrings[ 0 ] ); AddMonoString( &hStringHandle, wString ); swprintf( wString, L"%d", GetTownSectorSize( ubTownId ) ); AddSecondColumnMonoString( &hStringHandle, wString ); } // main facilities // HEADROCK HAM 3.6: This function now does all the work of assembling a facility entry. AddFacilitiesToBox( bCurrentTownMineSectorX, bCurrentTownMineSectorY, &hStringHandle, TRUE ); // the concept of control is only meaningful in sectors where militia can be trained if ( MilitiaTrainingAllowedInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY, 0 ) && gfHiddenTown[ GetTownIdForSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ] ) { // town control swprintf( wString, L"%s:", pwTownInfoStrings[ 2 ] ); AddMonoString( &hStringHandle, wString ); swprintf( wString, L"%d%%%%", (GetTownSectorsUnderControl( ubTownId ) * 100) / GetTownSectorSize( ubTownId )); AddSecondColumnMonoString( &hStringHandle, wString ); } // the concept of town loyalty is only meaningful in towns where loyalty is tracked if( gTownLoyalty[ ubTownId ].fStarted && gfTownUsesLoyalty[ ubTownId ] && gfHiddenTown[ GetTownIdForSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ] ) { // town loyalty swprintf( wString, L"%s:", pwTownInfoStrings[ 5 ] ); AddMonoString( &hStringHandle, wString ); swprintf( wString, L"%d%%%%", gTownLoyalty[ ubTownId ].ubRating ); AddSecondColumnMonoString( &hStringHandle, wString ); } // if the town has a mine sMineSector = GetMineSectorForTown( ubTownId ); if( sMineSector != -1 && gfHiddenTown[ GetTownIdForSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ] ) { // Associated Mine: Sector swprintf( wString, L"%s:", pwTownInfoStrings[ 4 ] ); AddMonoString( &hStringHandle, wString ); GetShortSectorString( ( INT16 )( sMineSector % MAP_WORLD_X ), ( INT16 )( sMineSector / MAP_WORLD_X ), wString ); AddSecondColumnMonoString( &hStringHandle, wString ); } }
UINT32 ExtractOreFromMine( INT8 bMineIndex, UINT32 uiAmount ) { // will remove the ore from the mine and return the amount that was removed UINT32 uiAmountExtracted = 0; UINT32 uiOreRunningOutPoint = 0; INT16 sSectorX, sSectorY; Assert( ( bMineIndex >= 0 ) && ( bMineIndex < MAX_NUMBER_OF_MINES ) ); // if mine is shut down if ( gMineStatus[ bMineIndex ].fShutDown) { return ( 0 ); } // if not capable of extracting anything, bail now if (uiAmount == 0) { return ( 0 ); } // will this exhaust the ore in this mine? if( uiAmount >= gMineStatus[ bMineIndex ].uiRemainingOreSupply ) { // exhaust remaining ore uiAmountExtracted = gMineStatus[ bMineIndex ].uiRemainingOreSupply; gMineStatus[ bMineIndex ].uiRemainingOreSupply = 0; gMineStatus[ bMineIndex ].uiMaxRemovalRate = 0; gMineStatus[ bMineIndex ].fEmpty = TRUE; gMineStatus[ bMineIndex ].fRunningOut = FALSE; // tell the strategic AI about this, that mine's and town's value is greatly reduced GetMineSector( bMineIndex, &sSectorX, &sSectorY ); StrategicHandleMineThatRanOut( ( UINT8 ) SECTOR( sSectorX, sSectorY ) ); AddHistoryToPlayersLog( HISTORY_MINE_RAN_OUT, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY ); } else // still some left after this extraction { // set amount used, and decrement ore remaining in mine uiAmountExtracted = uiAmount; gMineStatus[ bMineIndex ].uiRemainingOreSupply -= uiAmount; // one of the mines (randomly chosen) will start running out eventually, check if we're there yet if (gMineStatus[ bMineIndex ].uiRemainingOreSupply < gMineStatus[ bMineIndex ].uiOreRunningOutPoint) { gMineStatus[ bMineIndex ].fRunningOut = TRUE; // round all fractions UP to the next REMOVAL_RATE_INCREMENT gMineStatus[ bMineIndex ].uiMaxRemovalRate = (UINT32) (((FLOAT) gMineStatus[ bMineIndex ].uiRemainingOreSupply / 10) / REMOVAL_RATE_INCREMENT + 0.9999) * REMOVAL_RATE_INCREMENT; // if we control it if (PlayerControlsMine(bMineIndex)) { // and haven't yet been warned that it's running out if (!gMineStatus[ bMineIndex ].fWarnedOfRunningOut) { // that mine's head miner tells player that the mine is running out IssueHeadMinerQuote( bMineIndex, HEAD_MINER_STRATEGIC_QUOTE_RUNNING_OUT ); gMineStatus[ bMineIndex ].fWarnedOfRunningOut = TRUE; AddHistoryToPlayersLog( HISTORY_MINE_RUNNING_OUT, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY ); } } } } return( uiAmountExtracted ); }
/////////////////////////////// Artillery Sector Selection //////////////////////////////////////////// void ArtillerySector::Setup( UINT32 aVal ) { Destroy(); SOLDIERTYPE * pSoldier = NULL; GetSoldier( &pSoldier, gusSelectedSoldier ); if ( pSoldier == NULL ) return; if ( pSoldier->CanUseSkill(SKILLS_RADIO_ARTILLERY) ) { SetupPopup("ArtillerySector"); POPUP_OPTION *pOption; CHAR16 pStr[300]; // check wether we can call artillery from the 4 adjacent sectors for (UINT8 i = 0; i < 4; ++i) { INT16 loopX = pSoldier->sSectorX; INT16 loopY = pSoldier->sSectorY; if ( i == 0 ) ++loopY; else if ( i == 1 ) ++loopX; else if ( i == 2 ) --loopY; else if ( i == 3 ) --loopX; if ( loopX < 1 || loopX >= MAP_WORLD_X - 1 || loopY < 1 || loopY >= MAP_WORLD_Y - 1 ) continue; UINT32 sectornr = (UINT32)SECTOR( loopX, loopY ); swprintf( pStr, L"%c%d", loopY + 'A' - 1, loopX ); pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Setup_ArtilleryTeam, sectornr ) ); // grey out if no artillery can be called from this sector if ( !IsValidArtilleryOrderSector( loopX, loopY, pSoldier->bSectorZ, pSoldier->bTeam ) && !IsValidArtilleryOrderSector( loopX, loopY, pSoldier->bSectorZ, MILITIA_TEAM ) ) { // Set this option off. pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL )); } GetPopup()->addOption( *pOption ); } // cancel option swprintf( pStr, pSkillMenuStrings[SKILLMENU_CANCEL] ); pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_ArtillerySector, 0 ) ); GetPopup()->addOption( *pOption ); // certain traits have skills whose effects depend on wether someone is near to us (squadleader, commissar). We therefore display our radius of effect while this display is open SetTraitToDisplay(RADIO_OPERATOR_NT); SetGridNoForTraitDisplay(sTraitsMenuTargetGridNo); ToggleTraitRangeView(TRUE); } // same y, different x SetPos(gSkillSelection.GetMaxPosX(), usTraitMenuPosY); }
static void XMLCALL BloodcatsEndElementHandle(void *userData, const XML_Char *name) { BloodcatsParseData * pData = (BloodcatsParseData *)userData; if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading { if(strcmp(name, "BLOODCAT_PLACEMENTS") == 0) { pData->curElement = BLOODCAT_ELEMENT_NONE; } else if(strcmp(name, "SECTOR") == 0) { pData->curElement = BLOODCAT_ELEMENT_PLACEMENTS; UINT8 ubSectorId = SECTOR(pData->sCurSectorX, pData->sCurSectorY); if (ubSectorId >= 0 && ubSectorId < 256) { // Set placement type for this sector. Only first array has this set, as it is not difficulty-dependent. gBloodcatPlacements[ ubSectorId ][0].PlacementType = pData->CurPlacement[0].PlacementType; for (UINT8 x = 0; x < 4; x++) { if (pData->CurPlacement[0].PlacementType == 0) { // Ambush placement. Bloodcats will appear in this sector randomly. gBloodcatPlacements[ ubSectorId ][x].ubMinBloodcats = pData->CurPlacement[x].ubMinBloodcats; gBloodcatPlacements[ ubSectorId ][x].ubMaxBloodcats = pData->CurPlacement[x].ubMaxBloodcats; gBloodcatPlacements[ ubSectorId ][x].ubAmbushChance = pData->CurPlacement[x].ubAmbushChance; gBloodcatPlacements[ ubSectorId ][x].ubFactionAffiliation = 0; gBloodcatPlacements[ ubSectorId ][x].fRespawn = 0; } else if (pData->CurPlacement[0].PlacementType == 1) { // Static placement. Bloodcats always appear here, but never respawn, and may be unaggressive // to enemies. gBloodcatPlacements[ ubSectorId ][x].ubMinBloodcats = 0; gBloodcatPlacements[ ubSectorId ][x].ubMaxBloodcats = pData->CurPlacement[x].ubMaxBloodcats; gBloodcatPlacements[ ubSectorId ][x].ubAmbushChance = 0; gBloodcatPlacements[ ubSectorId ][x].ubFactionAffiliation = pData->CurPlacement[x].ubFactionAffiliation; gBloodcatPlacements[ ubSectorId ][x].fRespawn = 0; } else if (pData->CurPlacement[0].PlacementType == 2) { // Lair sector. There can be only one, and it is affected by the Quest. Bloodcats can regenerate // their numbers here over time. gubBloodcatLairSectorId = ubSectorId; gBloodcatPlacements[ ubSectorId ][x].ubMinBloodcats = 0; gBloodcatPlacements[ ubSectorId ][x].ubMaxBloodcats = pData->CurPlacement[x].ubMaxBloodcats; gBloodcatPlacements[ ubSectorId ][x].ubAmbushChance = 0; gBloodcatPlacements[ ubSectorId ][x].ubFactionAffiliation = 0; gBloodcatPlacements[ ubSectorId ][x].fRespawn = pData->CurPlacement[x].fRespawn; } } } } else if(strcmp(name, "SectorGrid") == 0 ) { UINT8 x, y; pData->curElement = BLOODCAT_ELEMENT_SECTOR; y = (UINT8)pData->szCharData[0] & 0x1F; x = (UINT8)atol(&pData->szCharData[1]); if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) { pData->sCurSectorX = x; pData->sCurSectorY = y; } SGP_THROW_IFFALSE( (SECTOR(x,y) >= 0 && SECTOR(x,y) < 256) , L"Illegal sector number in BloodcatPlacements.XML" ); } else if(strcmp(name, "ubPlacementType") == 0 ) { pData->curElement = BLOODCAT_ELEMENT_SECTOR; // Only set for first array (Difficulty Irrelevant) pData->CurPlacement[0].PlacementType = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "NOVICE") == 0 ) { // Just return to sector data. pData->curElement = BLOODCAT_ELEMENT_SECTOR; } else if(strcmp(name, "EXPERIENCED") == 0 ) { // Just return to sector data. pData->curElement = BLOODCAT_ELEMENT_SECTOR; } else if(strcmp(name, "EXPERT") == 0 ) { // Just return to sector data. pData->curElement = BLOODCAT_ELEMENT_SECTOR; } else if(strcmp(name, "INSANE") == 0 ) { // Just return to sector data. pData->curElement = BLOODCAT_ELEMENT_SECTOR; } else if(strcmp(name, "ubMinBloodcats") == 0 ) { pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY; pData->CurPlacement[pData->ubCurDifficulty].ubMinBloodcats = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "ubMaxBloodcats") == 0 ) { pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY; pData->CurPlacement[pData->ubCurDifficulty].ubMaxBloodcats = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "ubAmbushChance") == 0 ) { pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY; pData->CurPlacement[pData->ubCurDifficulty].ubAmbushChance = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "ubFactionAffiliation") == 0 ) { pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY; pData->CurPlacement[pData->ubCurDifficulty].ubFactionAffiliation = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "fRespawn") == 0 ) { pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY; pData->CurPlacement[pData->ubCurDifficulty].fRespawn = (UINT8) atol(pData->szCharData); } pData->maxReadDepth--; } pData->currentDepth--; }
// adds text to town info box void AddTextToTownBox( void ) { UINT32 hStringHandle = 0; CHAR16 wString[ 64 ]; UINT8 ubTownId = 0; UINT16 usTownSectorIndex; INT16 sMineSector = 0; // remember town id ubTownId = GetTownIdForSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ); Assert((ubTownId >= FIRST_TOWN) && (ubTownId < NUM_TOWNS)); usTownSectorIndex = SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ); switch( usTownSectorIndex ) { case SEC_B13: AddMonoString( &hStringHandle, pLandTypeStrings[ DRASSEN_AIRPORT_SITE ] ); break; case SEC_F8: AddMonoString( &hStringHandle, pLandTypeStrings[ CAMBRIA_HOSPITAL_SITE ] ); break; case SEC_J9: //Tixa if( !fFoundTixa ) AddMonoString( &hStringHandle, pLandTypeStrings[ SAND ] ); else AddMonoString( &hStringHandle, pTownNames[ TIXA ] ); break; case SEC_K4: //Orta if( !fFoundOrta ) AddMonoString( &hStringHandle, pLandTypeStrings[ SWAMP ] ); else AddMonoString( &hStringHandle, pTownNames[ ORTA ] ); break; case SEC_N3: AddMonoString( &hStringHandle, pLandTypeStrings[ MEDUNA_AIRPORT_SITE ] ); break; default: if( usTownSectorIndex == SEC_N4 && fSamSiteFound[ SAM_SITE_FOUR ] ) { //Meduna's SAM site AddMonoString( &hStringHandle, pLandTypeStrings[ MEDUNA_SAM_SITE ] ); } else { // town name swprintf( wString, L"%s", pTownNames[ ubTownId ] ); AddMonoString( &hStringHandle, wString ); } break; } // blank line AddMonoString( &hStringHandle, L"" ); // sector AddSectorToBox(); // town size swprintf( wString, L"%s:", pwTownInfoStrings[ 0 ] ); AddMonoString( &hStringHandle, wString ); swprintf( wString, L"%d", GetTownSectorSize( ubTownId ) ); AddSecondColumnMonoString( &hStringHandle, wString ); // main facilities swprintf( wString, L"%s:", pwTownInfoStrings[ 8 ] ); AddMonoString( &hStringHandle, wString ); wcscpy(wString, L""); GetSectorFacilitiesFlags( bCurrentTownMineSectorX, bCurrentTownMineSectorY, wString ); AddSecondColumnMonoString( &hStringHandle, wString ); // the concept of control is only meaningful in sectors where militia can be trained if ( MilitiaTrainingAllowedInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY, 0 ) ) { // town control swprintf( wString, L"%s:", pwTownInfoStrings[ 2 ] ); AddMonoString( &hStringHandle, wString ); swprintf( wString, L"%d%%%%", (GetTownSectorsUnderControl( ubTownId ) * 100) / GetTownSectorSize( ubTownId )); AddSecondColumnMonoString( &hStringHandle, wString ); } // the concept of town loyalty is only meaningful in towns where loyalty is tracked if( gTownLoyalty[ ubTownId ].fStarted && gfTownUsesLoyalty[ ubTownId ]) { // town loyalty swprintf( wString, L"%s:", pwTownInfoStrings[ 5 ] ); AddMonoString( &hStringHandle, wString ); swprintf( wString, L"%d%%%%", gTownLoyalty[ ubTownId ].ubRating ); AddSecondColumnMonoString( &hStringHandle, wString ); } // if the town has a mine sMineSector = GetMineSectorForTown( ubTownId ); if( sMineSector != -1 ) { // Associated Mine: Sector swprintf( wString, L"%s:", pwTownInfoStrings[ 4 ] ); AddMonoString( &hStringHandle, wString ); GetShortSectorString( ( INT16 )( sMineSector % MAP_WORLD_X ), ( INT16 )( sMineSector / MAP_WORLD_X ), wString ); AddSecondColumnMonoString( &hStringHandle, wString ); } }
// ALL changes of control to enemy must be funneled through here! BOOLEAN SetThisSectorAsEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fContested ) { UINT16 usMapSector = 0; BOOLEAN fWasPlayerControlled = FALSE; INT8 bTownId = 0; UINT8 ubTheftChance; UINT8 ubSectorID; //KM : August 6, 1999 Patch fix // This check was added because this function gets called when player mercs retreat from an unresolved // battle between militia and enemies. It will get called again AFTER autoresolve is finished. if( gfAutomaticallyStartAutoResolve ) { return( FALSE ); } if( bMapZ == 0 ) { usMapSector = sMapX + ( sMapY * MAP_WORLD_X ); fWasPlayerControlled = !StrategicMap[ usMapSector ].fEnemyControlled; StrategicMap[ usMapSector ].fEnemyControlled = TRUE; // if player lost control to the enemy if ( fWasPlayerControlled ) { if( PlayerMercsInSector( (UINT8)sMapX, (UINT8)sMapY, (UINT8)bMapZ ) ) { //too premature: Player mercs still in sector. return FALSE; } // check if there's a town in the sector bTownId = StrategicMap[ usMapSector ].bNameId; SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = FALSE; // and it's a town if ((bTownId >= FIRST_TOWN) && (bTownId < NUM_TOWNS)) { ubSectorID = (UINT8)SECTOR( sMapX, sMapY ); if( !bMapZ && ubSectorID != SEC_J9 && ubSectorID != SEC_K4 ) { HandleMoraleEvent( NULL, MORALE_TOWN_LOST, sMapX, sMapY, bMapZ ); HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_LOSE_TOWN_SECTOR, sMapX, sMapY, bMapZ ); CheckIfEntireTownHasBeenLost( bTownId, sMapX, sMapY ); } } // if the sector has a mine which is still worth something if ( IsThereAMineInThisSector( sMapX, sMapY ) ) { // if it isn't empty if ( GetTotalLeftInMine( GetMineIndexForSector( sMapX, sMapY ) ) > 0) { QueenHasRegainedMineSector(GetMineIndexForSector (sMapX, sMapY)); HandleMoraleEvent( NULL, MORALE_MINE_LOST, sMapX, sMapY, bMapZ ); HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_LOSE_MINE, sMapX, sMapY, bMapZ ); } } // if it's a SAM site sector if( IsThisSectorASAMSector( sMapX, sMapY, bMapZ ) ) { HandleMoraleEvent( NULL, MORALE_SAM_SITE_LOST, sMapX, sMapY, bMapZ ); HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_LOSE_SAM, sMapX, sMapY, bMapZ ); } // if it's a helicopter refueling site sector if( IsRefuelSiteInSector( sMapX, sMapY) ) { UpdateRefuelSiteAvailability( ); } // ARM: this must be AFTER all resulting loyalty effects are resolved, or reduced mine income shown won't be accurate NotifyPlayerWhenEnemyTakesControlOfImportantSector( sMapX, sMapY, 0, fContested ); } // NOTE: Stealing is intentionally OUTSIDE the fWasPlayerControlled branch. This function gets called if new // enemy reinforcements arrive, and they deserve another crack at stealing what the first group missed! :-) // stealing should fail anyway 'cause there shouldn't be a temp file for unvisited sectors, but let's check anyway if ( GetSectorFlagStatus( sMapX, sMapY, ( UINT8 ) bMapZ, SF_ALREADY_VISITED ) == TRUE ) { // enemies can steal items left lying about (random chance). The more there are, the more they take! ubTheftChance = 5 * NumEnemiesInAnySector( sMapX, sMapY, bMapZ ); // max 90%, some stuff may just simply not get found if (ubTheftChance > 90 ) { ubTheftChance = 90; } RemoveRandomItemsInSector( sMapX, sMapY, bMapZ, ubTheftChance ); } // don't touch fPlayer flag for a surface sector lost to the enemies! // just because player has lost the sector doesn't mean he realizes it - that's up to our caller to decide! } else { // underground sector control is always up to date, because we don't track control down there SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = FALSE; } //KM : Aug 11, 1999 -- Patch fix: Relocated this check so it gets called everytime a sector changes hands, // even if the sector isn't a SAM site. There is a bug _somewhere_ that fails to update the airspace, // even though the player controls it. UpdateAirspaceControl( ); // redraw map/income if in mapscreen fMapPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; return fWasPlayerControlled; }
void AddCommonInfoToBox(void) { CHAR16 wString[ 64 ]; UINT32 hStringHandle = 0; BOOLEAN fUnknownSAMSite = FALSE; UINT8 ubMilitiaTotal = 0; UINT8 ubNumEnemies; switch( SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ) { case SEC_D2: //Chitzena SAM if( !fSamSiteFound[ SAM_SITE_ONE ] ) fUnknownSAMSite = TRUE; break; case SEC_D15: //Drassen SAM if( !fSamSiteFound[ SAM_SITE_TWO ] ) fUnknownSAMSite = TRUE; break; case SEC_I8: //Cambria SAM if( !fSamSiteFound[ SAM_SITE_THREE ] ) fUnknownSAMSite = TRUE; break; // SAM Site 4 in Meduna is within town limits, so it's always controllable default: break; } // in sector where militia can be trained, // control of the sector matters, display who controls this sector. Map brightness no longer gives this! if ( MilitiaTrainingAllowedInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY, 0 ) && !fUnknownSAMSite ) { // controlled: swprintf( wString, L"%s:", pwMiscSectorStrings[ 4 ] ); AddMonoString( &hStringHandle, wString ); // No/Yes swprintf( wString, L"%s", pwMiscSectorStrings[ ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ].fEnemyControlled ) ? 6 : 5 ] ); AddSecondColumnMonoString( &hStringHandle, wString ); // militia - is there any? swprintf( wString, L"%s:", pwTownInfoStrings[ 11 ] ); AddMonoString( &hStringHandle, wString ); ubMilitiaTotal = CountAllMilitiaInSector(bCurrentTownMineSectorX, bCurrentTownMineSectorY); if (ubMilitiaTotal > 0) { // some militia, show total & their breakdown by level swprintf( wString, L"%d (%d/%d/%d)", ubMilitiaTotal, MilitiaInSectorOfRank(bCurrentTownMineSectorX, bCurrentTownMineSectorY, GREEN_MILITIA), MilitiaInSectorOfRank(bCurrentTownMineSectorX, bCurrentTownMineSectorY, REGULAR_MILITIA), MilitiaInSectorOfRank(bCurrentTownMineSectorX, bCurrentTownMineSectorY, ELITE_MILITIA)); AddSecondColumnMonoString( &hStringHandle, wString ); } else { // no militia: don't bother displaying level breakdown wcscpy( wString, L"0"); AddSecondColumnMonoString( &hStringHandle, wString ); } // percentage of current militia squad training completed swprintf( wString, L"%s:", pwTownInfoStrings[ 10 ] ); AddMonoString( &hStringHandle, wString ); swprintf( wString, L"%d%%%%", SectorInfo[ SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ].ubMilitiaTrainingPercentDone ); AddSecondColumnMonoString( &hStringHandle, wString ); } // enemy forces swprintf( wString, L"%s:", pwMiscSectorStrings[ 0 ] ); AddMonoString( &hStringHandle, wString ); // how many are there, really? ubNumEnemies = NumEnemiesInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ); switch ( WhatPlayerKnowsAboutEnemiesInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ) { case KNOWS_NOTHING: // show "Unknown" wcscpy(wString, pwMiscSectorStrings[ 3 ] ); break; case KNOWS_THEYRE_THERE: // if there are any there if ( ubNumEnemies > 0 ) { // show "?", but not exactly how many wcscpy(wString, L"?" ); } else { // we know there aren't any (or we'd be seing them on map, too) wcscpy(wString, L"0" ); } break; case KNOWS_HOW_MANY: // show exactly how many swprintf( wString, L"%d", ubNumEnemies ); break; } AddSecondColumnMonoString( &hStringHandle, wString ); }
void GetSectorFacilitiesFlags( INT16 sMapX, INT16 sMapY, STR16 sFacilitiesString ) { // will build a string stating current facilities present in sector if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags == 0 ) { // none swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 0 ] ); return; } // hospital if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_HOSPITAL ) { swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 1 ] ); } // industry if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_INDUSTRY ) { if( wcslen( sFacilitiesString ) == 0 ) { swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 2 ] ); } else { wcscat( sFacilitiesString, L","); wcscat( sFacilitiesString, sFacilitiesStrings[ 2 ]); } } // prison if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_PRISON ) { if( wcslen( sFacilitiesString ) == 0 ) { swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 3 ] ); } else { wcscat( sFacilitiesString, L","); wcscat( sFacilitiesString, sFacilitiesStrings[ 3 ]); } } // airport if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_AIRPORT ) { if( wcslen( sFacilitiesString ) == 0 ) { swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 5 ] ); } else { wcscat( sFacilitiesString, L","); wcscat( sFacilitiesString, sFacilitiesStrings[ 5 ]); } } // gun range if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_GUN_RANGE ) { if( wcslen( sFacilitiesString ) == 0 ) { swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 6 ] ); } else { wcscat( sFacilitiesString, L","); wcscat( sFacilitiesString, sFacilitiesStrings[ 6 ]); } } sFacilitiesString[ wcslen( sFacilitiesString ) ] = 0; return; }
// ALL changes of control to player must be funneled through here! BOOLEAN SetThisSectorAsPlayerControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fContested ) { // NOTE: MapSector must be 16-bit, cause MAX_WORLD_X is actually 18, so the sector numbers exceed 256 although we use only 16x16 UINT16 usMapSector = 0; BOOLEAN fWasEnemyControlled = FALSE; INT8 bTownId = 0; UINT8 ubSectorID; if( AreInMeanwhile( ) ) { return FALSE; } if( bMapZ == 0 ) { usMapSector = sMapX + ( sMapY * MAP_WORLD_X ); /* // if enemies formerly controlled this sector if (StrategicMap[ usMapSector ].fEnemyControlled) { // remember that the enemies have lost it StrategicMap[ usMapSector ].fLostControlAtSomeTime = TRUE; } */ if( NumHostilesInSector( sMapX, sMapY, bMapZ ) ) { //too premature: enemies still in sector. return FALSE; } // check if we ever grabbed drassen airport, if so, set fact we can go to BR's if( ( sMapX == BOBBYR_SHIPPING_DEST_SECTOR_X ) && ( sMapY == BOBBYR_SHIPPING_DEST_SECTOR_Y ) ) { LaptopSaveInfo.fBobbyRSiteCanBeAccessed = TRUE; //If the player has been to Bobbyr when it was down, and we havent already sent email, send him an email if( LaptopSaveInfo.ubHaveBeenToBobbyRaysAtLeastOnceWhileUnderConstruction == BOBBYR_BEEN_TO_SITE_ONCE && LaptopSaveInfo.ubHaveBeenToBobbyRaysAtLeastOnceWhileUnderConstruction != BOBBYR_ALREADY_SENT_EMAIL ) { AddEmail( BOBBYR_NOW_OPEN, BOBBYR_NOW_OPEN_LENGTH, BOBBY_R, GetWorldTotalMin()); LaptopSaveInfo.ubHaveBeenToBobbyRaysAtLeastOnceWhileUnderConstruction = BOBBYR_ALREADY_SENT_EMAIL; } } fWasEnemyControlled = StrategicMap[ usMapSector ].fEnemyControlled; StrategicMap[ usMapSector ].fEnemyControlled = FALSE; SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = TRUE; bTownId = StrategicMap[ usMapSector ].bNameId; // check if there's a town in the sector if ((bTownId >= FIRST_TOWN) && (bTownId < NUM_TOWNS)) { // yes, start tracking (& displaying) this town's loyalty if not already doing so StartTownLoyaltyIfFirstTime( bTownId ); } // if player took control away from enemy if( fWasEnemyControlled && fContested ) { // and it's a town if ((bTownId >= FIRST_TOWN) && (bTownId < NUM_TOWNS)) { // don't do these for takeovers of Omerta sectors at the beginning of the game if ((bTownId != OMERTA) || (GetWorldDay() != 1)) { ubSectorID = (UINT8)SECTOR( sMapX, sMapY ); if( !bMapZ && ubSectorID != SEC_J9 && ubSectorID != SEC_K4 ) { HandleMoraleEvent( NULL, MORALE_TOWN_LIBERATED, sMapX, sMapY, bMapZ ); HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_GAIN_TOWN_SECTOR, sMapX, sMapY, bMapZ ); // liberation by definition requires that the place was enemy controlled in the first place CheckIfEntireTownHasBeenLiberated( bTownId, sMapX, sMapY ); } } } // if it's a mine that's still worth something if ( IsThereAMineInThisSector( sMapX, sMapY ) ) { if ( GetTotalLeftInMine( GetMineIndexForSector( sMapX, sMapY ) ) > 0) { HandleMoraleEvent( NULL, MORALE_MINE_LIBERATED, sMapX, sMapY, bMapZ ); HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_GAIN_MINE, sMapX, sMapY, bMapZ ); } } // if it's a SAM site sector if( IsThisSectorASAMSector( sMapX, sMapY, bMapZ ) ) { if ( 1 /*!GetSectorFlagStatus( sMapX, sMapY, bMapZ, SF_SECTOR_HAS_BEEN_LIBERATED_ONCE ) */) { // SAM site liberated for first time, schedule meanwhile HandleMeanWhileEventPostingForSAMLiberation( GetSAMIdFromSector( sMapX, sMapY, bMapZ ) ); } HandleMoraleEvent( NULL, MORALE_SAM_SITE_LIBERATED, sMapX, sMapY, bMapZ ); HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_GAIN_SAM, sMapX, sMapY, bMapZ ); // if Skyrider has been delivered to chopper, and already mentioned Drassen SAM site, but not used this quote yet if ( IsHelicopterPilotAvailable() && ( guiHelicopterSkyriderTalkState >= 1 ) && ( !gfSkyriderSaidCongratsOnTakingSAM ) ) { SkyRiderTalk( SAM_SITE_TAKEN ); gfSkyriderSaidCongratsOnTakingSAM = TRUE; } if ( !SectorInfo[ SECTOR( sMapX, sMapY ) ].fSurfaceWasEverPlayerControlled ) { // grant grace period if ( gGameOptions.ubDifficultyLevel >= DIF_LEVEL_HARD ) { UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + 2 ) ); } else { UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + 1 ) ); } } } // if it's a helicopter refueling site sector if( IsRefuelSiteInSector( sMapX, sMapY) ) { UpdateRefuelSiteAvailability( ); } // SetSectorFlag( sMapX, sMapY, bMapZ, SF_SECTOR_HAS_BEEN_LIBERATED_ONCE ); if ( bMapZ == 0 && ( ( sMapY == MAP_ROW_M && (sMapX >= 2 && sMapX <= 6) ) || sMapY == MAP_ROW_N && sMapX == 6) ) { HandleOutskirtsOfMedunaMeanwhileScene(); } } if( fContested ) { StrategicHandleQueenLosingControlOfSector( (UINT8)sMapX, (UINT8)sMapY, (UINT8)bMapZ ); } } else { if( sMapX == 3 && sMapY == 16 && bMapZ == 1 ) { //Basement sector (P3_b1) gfUseAlternateQueenPosition = TRUE; } } // also set fact the player knows they own it SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = TRUE; if ( bMapZ == 0 ) { SectorInfo[ SECTOR( sMapX, sMapY ) ].fSurfaceWasEverPlayerControlled = TRUE; } //KM : Aug 11, 1999 -- Patch fix: Relocated this check so it gets called everytime a sector changes hands, // even if the sector isn't a SAM site. There is a bug _somewhere_ that fails to update the airspace, // even though the player controls it. UpdateAirspaceControl( ); // redraw map/income if in mapscreen fMapPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; return fWasEnemyControlled; }
void AddCommonInfoToBox(void) { CHAR16 wString[ 64 ]; UINT32 hStringHandle = 0; BOOLEAN fKnownSite = FALSE; UINT8 ubMilitiaTotal = 0; UINT8 ubNumEnemies; UINT16 usSectorValue = 0; // get the sector value usSectorValue = SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ); BOOLEAN fVisited = (SectorInfo[ usSectorValue ].uiFlags & SF_ALREADY_VISITED); UINT8 ubTownId = GetTownIdForSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ); // visited sector check if ( fVisited ) fKnownSite = TRUE; // known town check, to exclude non-town sectors else if( gfHiddenTown[ ubTownId ] && ubTownId != BLANK_SECTOR ) fKnownSite = TRUE; // known SAM Site check else { for (UINT16 x=0; x < MAX_NUMBER_OF_SAMS; x++) { if ( pSamList[x] == usSectorValue ) { if ( fSamSiteFound[ x ] ) fKnownSite = TRUE; } } } /*// ABOVE GROUND HARDCODED fKnownSite = TRUE; switch( usSectorValue ) { case SEC_D2: //Chitzena SAM if( !fSamSiteFound[ SAM_SITE_ONE ] ) fKnownSite = FALSE; break; case SEC_D15: //Drassen SAM if( !fSamSiteFound[ SAM_SITE_TWO ] ) fKnownSite = FALSE; break; case SEC_I8: //Cambria SAM if( !fSamSiteFound[ SAM_SITE_THREE ] ) fKnownSite = FALSE; break; // SAM Site 4 in Meduna is within town limits, so it's always controllable default: break; } */ // in sector where militia can be trained, // control of the sector matters, display who controls this sector. Map brightness no longer gives this! if ( MilitiaTrainingAllowedInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY, 0 ) && fKnownSite ) { // controlled: swprintf( wString, L"%s:", pwMiscSectorStrings[ 4 ] ); AddMonoString( &hStringHandle, wString ); // No/Yes swprintf( wString, L"%s", pwMiscSectorStrings[ ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ].fEnemyControlled ) ? 6 : 5 ] ); AddSecondColumnMonoString( &hStringHandle, wString ); // militia - is there any? swprintf( wString, L"%s:", pwTownInfoStrings[ 11 ] ); AddMonoString( &hStringHandle, wString ); ubMilitiaTotal = CountAllMilitiaInSector(bCurrentTownMineSectorX, bCurrentTownMineSectorY); if (ubMilitiaTotal > 0) { // some militia, show total & their breakdown by level swprintf( wString, L"%d (%d/%d/%d)", ubMilitiaTotal, MilitiaInSectorOfRank(bCurrentTownMineSectorX, bCurrentTownMineSectorY, GREEN_MILITIA), MilitiaInSectorOfRank(bCurrentTownMineSectorX, bCurrentTownMineSectorY, REGULAR_MILITIA), MilitiaInSectorOfRank(bCurrentTownMineSectorX, bCurrentTownMineSectorY, ELITE_MILITIA)); AddSecondColumnMonoString( &hStringHandle, wString ); } else { // no militia: don't bother displaying level breakdown wcscpy( wString, L"0"); AddSecondColumnMonoString( &hStringHandle, wString ); } // HEADROCK HAM 3.6: Only show these for sectors that have a training facility BOOLEAN fMilitiaTrainingAllowed = FALSE; BOOLEAN fMobileTrainingAllowed = FALSE; // percentage of current militia squad training completed swprintf( wString, L"%s:", pwTownInfoStrings[ 10 ] ); AddMonoString( &hStringHandle, wString ); // Sector contains Militia training facility? for (UINT8 ubCounter = 0; ubCounter < MAX_NUM_FACILITY_TYPES; ubCounter++) { if (gFacilityLocations[usSectorValue][ubCounter].fFacilityHere) { if (gFacilityTypes[ubCounter].ubMilitiaTrainersAllowed) { fMilitiaTrainingAllowed = TRUE; } } } if (fMilitiaTrainingAllowed) { // Show percent completed swprintf( wString, L"%d%%%%", SectorInfo[ usSectorValue ].ubMilitiaTrainingPercentDone ); AddSecondColumnMonoString( &hStringHandle, wString ); } else { // Show N/A AddSecondColumnMonoString( &hStringHandle, New113HAMMessage[19] ); } // HEADROCK HAM 3.6: percentage of current Mobile Militia squad training completed swprintf( wString, L"%s:", pwTownInfoStrings[ 12 ] ); AddMonoString( &hStringHandle, wString ); // Sector contains Mobile training facility? for (UINT8 ubCounter = 0; ubCounter < MAX_NUM_FACILITY_TYPES; ubCounter++) { if (gFacilityLocations[usSectorValue][ubCounter].fFacilityHere) { if (gFacilityTypes[ubCounter].ubMobileMilitiaTrainersAllowed) { fMobileTrainingAllowed = TRUE; } } } if (fMobileTrainingAllowed) { // Show percentage completed swprintf( wString, L"%d%%%%", SectorInfo[ usSectorValue ].ubMobileMilitiaTrainingPercentDone ); AddSecondColumnMonoString( &hStringHandle, wString ); } else { // Show N/A AddSecondColumnMonoString( &hStringHandle, New113HAMMessage[19] ); } } // enemy forces swprintf( wString, L"%s:", pwMiscSectorStrings[ 0 ] ); AddMonoString( &hStringHandle, wString ); // how many are there, really? ubNumEnemies = NumEnemiesInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ); AssertGE(gGameExternalOptions.ubGameMaximumNumberOfEnemies, NumFreeEnemySlots()); unsigned numEnemiesOnMap = gGameExternalOptions.ubGameMaximumNumberOfEnemies - NumFreeEnemySlots(); switch ( WhatPlayerKnowsAboutEnemiesInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ) { case KNOWS_NOTHING: // show "Unknown" wcscpy(wString, pwMiscSectorStrings[ 3 ] ); break; // HEADROCK HAM 5: New Case case KNOWS_THEYRE_THERE: case KNOWS_THEYRE_THERE_AND_WHERE_GOING: // if there are any there if ( ubNumEnemies > 0 ) { // show "?", but not exactly how many wcscpy(wString, L"?" ); } else { // we know there aren't any (or we'd be seing them on map, too) wcscpy(wString, L"0" ); } break; // HEADROCK HAM 5: New case case KNOWS_HOW_MANY: case KNOWS_HOW_MANY_AND_WHERE_GOING: // show exactly how many if (numEnemiesOnMap != ubNumEnemies) swprintf( wString, L"%d (%d)", numEnemiesOnMap, ubNumEnemies ); else swprintf( wString, L"%d", ubNumEnemies ); break; } AddSecondColumnMonoString( &hStringHandle, wString ); }
void AddTextToBlankSectorBox( void ) { UINT32 hStringHandle; UINT16 usSectorValue = 0; // get the sector value usSectorValue = SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ); AssertGE(usSectorValue, 0); AssertLT(usSectorValue,256); //////////////////////////////////// // HEADROCK HAM 5: // Read and verify XML sector names BOOLEAN fSectorHasXMLNames = TRUE; CHAR16 zUnexplored[MAX_SECTOR_NAME_LENGTH]; CHAR16 zExplored[MAX_SECTOR_NAME_LENGTH]; wcscpy( zUnexplored, gzSectorNames[ usSectorValue ][0] ); wcscpy( zExplored, gzSectorNames[ usSectorValue ][2] ); if (zUnexplored[0] == 0 || zExplored[0] == 0) { fSectorHasXMLNames = FALSE; } if (fSectorHasXMLNames) // ABOVE GROUND XML { // HEADROCK HAM 3.6: The program can now read custom names from XML for all above-ground sectors. // In the event that a specific name or set of names is missing, the program generates a default // name as it always has. // I've also updated the SAM Site sectors to rely on SamSite.XML data. BOOLEAN fVisited = (SectorInfo[ usSectorValue ].uiFlags & SF_ALREADY_VISITED); BOOLEAN fSAMSiteKnown = FALSE; // Test for known SAM Site at this location for (UINT16 x=0; x < MAX_NUMBER_OF_SAMS; x++) { if ( pSamList[x] == usSectorValue ) { if ( fSamSiteFound[ x ] ) { fSAMSiteKnown = TRUE; } } } if (fVisited || fSAMSiteKnown) { AddMonoString( &hStringHandle, zExplored ); } else { AddMonoString( &hStringHandle, zUnexplored ); } } else // ABOVE GROUND HARDCODED { switch( usSectorValue ) { case SEC_D2: //Chitzena SAM if( !fSamSiteFound[ SAM_SITE_ONE ] ) AddMonoString( &hStringHandle, pLandTypeStrings[ TROPICS ] ); else AddMonoString( &hStringHandle, pLandTypeStrings[ TROPICS_SAM_SITE ] ); break; case SEC_D15: //Drassen SAM if( !fSamSiteFound[ SAM_SITE_TWO ] ) AddMonoString( &hStringHandle, pLandTypeStrings[ SPARSE ] ); else AddMonoString( &hStringHandle, pLandTypeStrings[ SPARSE_SAM_SITE ] ); break; case SEC_I8: //Cambria SAM if( !fSamSiteFound[ SAM_SITE_THREE ] ) AddMonoString( &hStringHandle, pLandTypeStrings[ SAND ] ); else AddMonoString( &hStringHandle, pLandTypeStrings[ SAND_SAM_SITE ] ); break; // SAM Site 4 in Meduna is within town limits, so it's handled in AddTextToTownBox() default: AddMonoString( &hStringHandle, pLandTypeStrings[ ( SectorInfo[ usSectorValue ].ubTraversability[ 4 ] ) ] ); break; } } // blank line AddMonoString( &hStringHandle, L"" ); // sector AddSectorToBox(); // HEADROCK HAM 3.6: Facilities AddFacilitiesToBox( bCurrentTownMineSectorX, bCurrentTownMineSectorY, &hStringHandle, FALSE ); }
void ExitBoxing( void ) { //DBrot: More Rooms //UINT8 ubRoom; UINT16 usRoom; SOLDIERTYPE* pSoldier; UINT32 uiLoop; UINT8 ubPass; // find boxers and turn them neutral again // first time through loop, look for AI guy, then for PC guy.... for stupid // oppcnt/alert status reasons for( ubPass = 0; ubPass < 2; ++ubPass ) { // because boxer could die, loop through all soldier ptrs for ( uiLoop = 0; uiLoop < gTacticalStatus.Team[ CIV_TEAM ].bLastID; ++uiLoop ) { pSoldier = MercPtrs[ uiLoop ]; if ( pSoldier != NULL ) { if ( ( pSoldier->flags.uiStatusFlags & SOLDIER_BOXER ) && InARoom( pSoldier->sGridNo, &usRoom ) && usRoom == BOXING_RING ) { if ( pSoldier->flags.uiStatusFlags & SOLDIER_PC ) { if ( ubPass == 0 ) // pass 0, only handle AI { continue; } // put guy under AI control temporarily pSoldier->flags.uiStatusFlags |= SOLDIER_PCUNDERAICONTROL; //SB: this flag don't allow merc leave the ring pSoldier->flags.uiStatusFlags &= ~SOLDIER_ENGAGEDINACTION; } else { if ( ubPass == 1 ) // pass 1, only handle PCs { continue; } // reset AI boxer to neutral SetSoldierNeutral( pSoldier ); RecalculateOppCntsDueToBecomingNeutral( pSoldier ); } CancelAIAction( pSoldier, TRUE ); pSoldier->aiData.bAlertStatus = STATUS_GREEN; pSoldier->aiData.bUnderFire = 0; // HEADROCK HAM 3.6: Make sure all boxers' APs have been reset to a reasonable number. Otherwise, // the AI combatant may fail several conditions in subsequent functions, and fail to leave the ring // as a result. if (pSoldier->bActionPoints < (APBPConstants[AP_MAXIMUM]*6)/10) { pSoldier->bActionPoints = (APBPConstants[AP_MAXIMUM]*6)/10; } // if necessary, revive boxer so he can leave ring if (pSoldier->stats.bLife > 0 && (pSoldier->stats.bLife < OKLIFE || pSoldier->bBreath < OKBREATH ) ) { pSoldier->stats.bLife = __max( OKLIFE * 2, pSoldier->stats.bLife ); if (pSoldier->bBreath < 100) { // deduct -ve BPs to grant some BPs back (properly) DeductPoints( pSoldier, 0, (INT16) - ( (100 - pSoldier->bBreath) * 100 ) ); } pSoldier->BeginSoldierGetup( ); } } } } } DeleteTalkingMenu(); EndAllAITurns(); if ( CheckForEndOfCombatMode( FALSE ) ) { EndTopMessage(); #ifdef NEWMUSIC GlobalSoundID = MusicSoundValues[ SECTOR( gWorldSectorX, gWorldSectorY ) ].SoundTacticalNothing[gbWorldSectorZ]; if ( MusicSoundValues[ SECTOR( gWorldSectorX, gWorldSectorY ) ].SoundTacticalNothing[gbWorldSectorZ] != -1 ) SetMusicModeID( MUSIC_TACTICAL_NOTHING, MusicSoundValues[ SECTOR( gWorldSectorX, gWorldSectorY ) ].SoundTacticalNothing[gbWorldSectorZ] ); else #endif SetMusicMode( MUSIC_TACTICAL_NOTHING ); // Lock UI until we get out of the ring guiPendingOverrideEvent = LU_BEGINUILOCK; } }
static void XMLCALL creatureplacementEndElementHandle(void *userData, const XML_Char *name) { CreatureParseData * pData = (CreatureParseData *) userData; if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading { if(strcmp(name, "CREATURE_INFO") == 0 && pData->curElement == CREATURE_ELEMENT_CREATUREINFO) { pData->curElement = CREATURE_ELEMENT_NONE; } else if(strcmp(name, "COMPOSITION_LIST") == 0 && pData->curElement == CREATURE_ELEMENT_COMPOSITIONLIST) { pData->curElement = CREATURE_ELEMENT_CREATUREINFO; // CompIndex starts at 0 NUMBER_OF_CREATURE_COMPOSITIONS = pData->uiCompHighestIndex + 1; } else if(strcmp(name, "COMPOSITION") == 0 && pData->curElement == CREATURE_ELEMENT_COMPOSITION) { pData->curElement = CREATURE_ELEMENT_COMPOSITIONLIST; if ( pData->curIndex != INVALID_CREATURESITE_INDEX ) { // valid creature composition index starts at 0 gCreatureComposition[pData->curIndex].ubLarvaePercent = pData->curCompositionInfo.ubLarvaePercent; gCreatureComposition[pData->curIndex].ubInfantPercent = pData->curCompositionInfo.ubInfantPercent; gCreatureComposition[pData->curIndex].ubYoungMalePercent = pData->curCompositionInfo.ubYoungMalePercent; gCreatureComposition[pData->curIndex].ubYoungFemalePercent = pData->curCompositionInfo.ubYoungFemalePercent; gCreatureComposition[pData->curIndex].ubAdultMalePercent = pData->curCompositionInfo.ubAdultMalePercent; gCreatureComposition[pData->curIndex].ubAdultFemalePercent = pData->curCompositionInfo.ubAdultFemalePercent; gCreatureComposition[pData->curIndex].iMaxPopulation = pData->curCompositionInfo.iMaxPopulation; } } else if(strcmp(name, "CompIndex") == 0 && pData->curElement == CREATURE_ELEMENT_COMPINDEX) { pData->curElement = CREATURE_ELEMENT_COMPOSITION; pData->curIndex = atol(pData->szCharData); // CompIndex starts at 0 if ( pData->curIndex < 0 || pData->curIndex > MAX_NUMBER_OF_CREATURE_COMPOSITIONS ) { pData->curIndex = INVALID_COMPOSITION_INDEX; } else if ( pData->curIndex > pData->uiCompHighestIndex ) { pData->uiCompHighestIndex = pData->curIndex; } } else if(strcmp(name, "LarvaePercent") == 0 && pData->curElement == CREATURE_ELEMENT_LARVAEPERCENT) { pData->curElement = CREATURE_ELEMENT_COMPOSITION; pData->curCompositionInfo.ubLarvaePercent = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "InfantPercent") == 0 && pData->curElement == CREATURE_ELEMENT_INFANTPERCENT) { pData->curElement = CREATURE_ELEMENT_COMPOSITION; pData->curCompositionInfo.ubInfantPercent = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "YoungMalePercent") == 0 && pData->curElement == CREATURE_ELEMENT_YMALEPERCENT) { pData->curElement = CREATURE_ELEMENT_COMPOSITION; pData->curCompositionInfo.ubYoungMalePercent = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "YoungFemalePercent") == 0 && pData->curElement == CREATURE_ELEMENT_YFEMALEPERCENT) { pData->curElement = CREATURE_ELEMENT_COMPOSITION; pData->curCompositionInfo.ubYoungFemalePercent = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "AdultMalePercent") == 0 && pData->curElement == CREATURE_ELEMENT_AMALEPERCENT) { pData->curElement = CREATURE_ELEMENT_COMPOSITION; pData->curCompositionInfo.ubAdultMalePercent = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "AdultFemalePercent") == 0 && pData->curElement == CREATURE_ELEMENT_AFEMALEPERCENT) { pData->curElement = CREATURE_ELEMENT_COMPOSITION; pData->curCompositionInfo.ubAdultFemalePercent = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "MaxPopulation") == 0 && pData->curElement == CREATURE_ELEMENT_MAXPOPULATION) { pData->curElement = CREATURE_ELEMENT_COMPOSITION; pData->curCompositionInfo.iMaxPopulation = (INT32) atol(pData->szCharData); } else if(strcmp(name, "PLACEMENT_LIST") == 0 && pData->curElement == CREATURE_ELEMENT_PLACEMENTLIST) { pData->curElement = CREATURE_ELEMENT_CREATUREINFO; NUMBER_OF_INFECTIBLE_SITES = pData->uiHighestIndex; } else if(strcmp(name, "PLACEMENT") == 0 && pData->curElement == CREATURE_ELEMENT_PLACEMENT) { pData->curElement = CREATURE_ELEMENT_PLACEMENTLIST; if ( pData->curIndex != INVALID_CREATURESITE_INDEX ) { // valid giLairID starts at 1 gCreaturePlacements[pData->curIndex].sAltMapX = pData->curPlacementInfo.sAltMapX; gCreaturePlacements[pData->curIndex].sAltMapY = pData->curPlacementInfo.sAltMapY; gCreaturePlacements[pData->curIndex].ubAltMapZ = pData->curPlacementInfo.ubAltMapZ; gCreaturePlacements[pData->curIndex].sQueenX = pData->curPlacementInfo.sQueenX; gCreaturePlacements[pData->curIndex].sQueenY = pData->curPlacementInfo.sQueenY; gCreaturePlacements[pData->curIndex].ubQueenZ = pData->curPlacementInfo.ubQueenZ; gCreaturePlacements[pData->curIndex].sAttackSourceX = pData->curPlacementInfo.sAttackSourceX; gCreaturePlacements[pData->curIndex].sAttackSourceY = pData->curPlacementInfo.sAttackSourceY; gCreaturePlacements[pData->curIndex].iAttackSourceGridNo = pData->curPlacementInfo.iAttackSourceGridNo; gCreaturePlacements[pData->curIndex].sWarpToX = pData->curPlacementInfo.sWarpToX; gCreaturePlacements[pData->curIndex].sWarpToY = pData->curPlacementInfo.sWarpToY; gCreaturePlacements[pData->curIndex].ubWarpToZ = pData->curPlacementInfo.ubWarpToZ; gCreaturePlacements[pData->curIndex].iWarpToGridNo = pData->curPlacementInfo.iWarpToGridNo; for (UINT8 y = 0; y < MAX_NUMBER_OF_CREATURE_SECTORS; y++) { gCreaturePlacements[pData->curIndex].Habitat[y].sX = pData->curPlacementInfo.Habitat[y].sX; gCreaturePlacements[pData->curIndex].Habitat[y].sY = pData->curPlacementInfo.Habitat[y].sY; gCreaturePlacements[pData->curIndex].Habitat[y].ubZ = pData->curPlacementInfo.Habitat[y].ubZ; gCreaturePlacements[pData->curIndex].Habitat[y].ubComposition = pData->curPlacementInfo.Habitat[y].ubComposition; gCreaturePlacements[pData->curIndex].Habitat[y].fValid = pData->curPlacementInfo.Habitat[y].fValid; // Clear pData Habitat Array as different creature site has different number of habitats pData->curPlacementInfo.Habitat[y].sX = 0; pData->curPlacementInfo.Habitat[y].sY = 0; pData->curPlacementInfo.Habitat[y].ubZ = 0; pData->curPlacementInfo.Habitat[y].ubComposition = 0; pData->curPlacementInfo.Habitat[y].fValid = 0; } } } else if(strcmp(name, "Index") == 0 && pData->curElement == CREATURE_ELEMENT_INDEX) { pData->curElement = CREATURE_ELEMENT_PLACEMENT; pData->curIndex = atol(pData->szCharData); if ( !pData->curIndex || pData->curIndex > MAX_NUMBER_OF_INFECTIBLE_SITES + 1 ) { pData->curIndex = INVALID_CREATURESITE_INDEX; } else if ( pData->curIndex > pData->uiHighestIndex ) { pData->uiHighestIndex = pData->curIndex; } } else if(strcmp(name, "ATTACKSOURCE") == 0 && pData->curElement == CREATURE_ELEMENT_ATTACKSOURCE) { pData->curElement = CREATURE_ELEMENT_PLACEMENT; } else if(strcmp(name, "SectorGrid") == 0 && pData->curElement == CREATURE_ELEMENT_ATTACKSOURCE_SECTOR) { UINT8 x, y; pData->curElement = CREATURE_ELEMENT_ATTACKSOURCE; y = (UINT8)pData->szCharData[0] & 0x1F; x = (UINT8)atol(&pData->szCharData[1]); if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) { pData->curPlacementInfo.sAttackSourceX = x; pData->curPlacementInfo.sAttackSourceY = y; } SGP_THROW_IFFALSE( (SECTOR(x,y) >= 0 && SECTOR(x,y) < 256) , L"Illegal sector number in CreaturePlacements.XML" ); } else if(strcmp(name, "GridNo") == 0 && pData->curElement == CREATURE_ELEMENT_ATTACKSOURCE_GRIDNO) { pData->curElement = CREATURE_ELEMENT_ATTACKSOURCE; pData->curPlacementInfo.iAttackSourceGridNo = (INT32) atol(pData->szCharData); } else if(strcmp(name, "ALTERNATEMAP") == 0 && pData->curElement == CREATURE_ELEMENT_ALTERNATEMAP) { pData->curElement = CREATURE_ELEMENT_PLACEMENT; } else if(strcmp(name, "SectorGrid") == 0 && pData->curElement == CREATURE_ELEMENT_ALTERNATEMAP_SECTOR) { UINT8 x, y; pData->curElement = CREATURE_ELEMENT_ALTERNATEMAP; y = (UINT8)pData->szCharData[0] & 0x1F; x = (UINT8)atol(&pData->szCharData[1]); if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) { pData->curPlacementInfo.sAltMapX = x; pData->curPlacementInfo.sAltMapY = y; } SGP_THROW_IFFALSE( (SECTOR(x,y) >= 0 && SECTOR(x,y) < 256) , L"Illegal sector number in CreaturePlacements.XML" ); } else if(strcmp(name, "SectorZ") == 0 && pData->curElement == CREATURE_ELEMENT_ALTERNATEMAP_Z) { pData->curElement = CREATURE_ELEMENT_ALTERNATEMAP; pData->curPlacementInfo.ubAltMapZ = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "WARPTOSECTOR") == 0 && pData->curElement == CREATURE_ELEMENT_WARPTO) { pData->curElement = CREATURE_ELEMENT_PLACEMENT; } else if(strcmp(name, "SectorGrid") == 0 && pData->curElement == CREATURE_ELEMENT_WARPTO_SECTOR) { UINT8 x, y; pData->curElement = CREATURE_ELEMENT_WARPTO; y = (UINT8)pData->szCharData[0] & 0x1F; x = (UINT8)atol(&pData->szCharData[1]); if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) { pData->curPlacementInfo.sWarpToX = x; pData->curPlacementInfo.sWarpToY = y; } SGP_THROW_IFFALSE( (SECTOR(x,y) >= 0 && SECTOR(x,y) < 256) , L"Illegal sector number in CreaturePlacements.XML" ); } else if(strcmp(name, "SectorZ") == 0 && pData->curElement == CREATURE_ELEMENT_WARPTO_Z) { pData->curElement = CREATURE_ELEMENT_WARPTO; pData->curPlacementInfo.ubWarpToZ = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "GridNo") == 0 && pData->curElement == CREATURE_ELEMENT_WARPTO_GRIDNO) { pData->curElement = CREATURE_ELEMENT_WARPTO; pData->curPlacementInfo.iWarpToGridNo = (INT32) atol(pData->szCharData); } else if(strcmp(name, "CREATURESECTOR") == 0 && pData->curElement == CREATURE_ELEMENT_CREATURESECTOR) { pData->curElement = CREATURE_ELEMENT_PLACEMENT; } else if(strcmp(name, "QUEENSECTOR") == 0 && pData->curElement == CREATURE_ELEMENT_QUEEN) { pData->curElement = CREATURE_ELEMENT_CREATURESECTOR; } else if(strcmp(name, "SectorGrid") == 0 && pData->curElement == CREATURE_ELEMENT_QUEEN_SECTOR) { UINT8 x, y; pData->curElement = CREATURE_ELEMENT_QUEEN; y = (UINT8)pData->szCharData[0] & 0x1F; x = (UINT8)atol(&pData->szCharData[1]); if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) { pData->curPlacementInfo.sQueenX = x; pData->curPlacementInfo.sQueenY = y; } SGP_THROW_IFFALSE( (SECTOR(x,y) >= 0 && SECTOR(x,y) < 256) , L"Illegal sector number in CreaturePlacements.XML" ); } else if(strcmp(name, "SectorZ") == 0 && pData->curElement == CREATURE_ELEMENT_QUEEN_Z) { pData->curElement = CREATURE_ELEMENT_QUEEN; pData->curPlacementInfo.ubQueenZ = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "HABITATSECTOR") == 0 && pData->curElement == CREATURE_ELEMENT_HABITAT) { pData->curElement = CREATURE_ELEMENT_CREATURESECTOR; } else if(strcmp(name, "SectorGrid") == 0 && pData->curElement == CREATURE_ELEMENT_HABITAT_SECTOR) { UINT8 x, y; pData->curElement = CREATURE_ELEMENT_HABITAT; y = (UINT8)pData->szCharData[0] & 0x1F; x = (UINT8)atol(&pData->szCharData[1]); if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) { pData->curPlacementInfo.Habitat[pData->curHabitat].sX = x; pData->curPlacementInfo.Habitat[pData->curHabitat].sY = y; } SGP_THROW_IFFALSE( (SECTOR(x,y) >= 0 && SECTOR(x,y) < 256) , L"Illegal sector number in CreaturePlacements.XML" ); } else if(strcmp(name, "SectorZ") == 0 && pData->curElement == CREATURE_ELEMENT_HABITAT_Z) { pData->curElement = CREATURE_ELEMENT_HABITAT; pData->curPlacementInfo.Habitat[pData->curHabitat].ubZ = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "Composition") == 0 && pData->curElement == CREATURE_ELEMENT_HABITAT_COMPOSITION) { pData->curElement = CREATURE_ELEMENT_HABITAT; pData->curPlacementInfo.Habitat[pData->curHabitat].ubComposition = (UINT8) atol(pData->szCharData); // valid creature habitat if using other than queen habitat if ( pData->curPlacementInfo.Habitat[pData->curHabitat].ubComposition ) pData->curPlacementInfo.Habitat[pData->curHabitat].fValid = TRUE; pData->curHabitat++; } pData->maxReadDepth--; } pData->currentDepth--; }
//returns the UINT8 ID for the specified sector. UINT8 GetLoadScreenID( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ) { SECTORINFO *pSector; UINT8 ubSectorID; BOOLEAN fNight = FALSE; ubSectorID = SECTOR( sSectorX, sSectorY ); if( NightTime() ) //before 5AM or after 9PM { fNight = TRUE; } switch( bSectorZ ) { case 0: switch( ubSectorID ) { case SEC_A2: case SEC_B2: if( fNight ) return LOADINGSCREEN_NIGHTCHITZENA; return LOADINGSCREEN_DAYCHITZENA; case SEC_A9: if( !DidGameJustStart() ) { if( fNight ) return LOADINGSCREEN_NIGHTOMERTA; return LOADINGSCREEN_DAYOMERTA; } return LOADINGSCREEN_HELI; case SEC_A10: if( fNight ) return LOADINGSCREEN_NIGHTOMERTA; return LOADINGSCREEN_DAYOMERTA; case SEC_P3: if( fNight ) return LOADINGSCREEN_NIGHTPALACE; return LOADINGSCREEN_DAYPALACE; case SEC_H13: case SEC_H14: //military installations case SEC_I13: case SEC_N7: if( fNight ) return LOADINGSCREEN_NIGHTMILITARY; return LOADINGSCREEN_DAYMILITARY; case SEC_K4: if( fNight ) return LOADINGSCREEN_NIGHTLAB; return LOADINGSCREEN_DAYLAB; case SEC_J9: if( fNight ) return LOADINGSCREEN_NIGHTPRISON; return LOADINGSCREEN_DAYPRISON; case SEC_D2: case SEC_D15: case SEC_I8: case SEC_N4: if( fNight ) return LOADINGSCREEN_NIGHTSAM; return LOADINGSCREEN_DAYSAM; case SEC_F8: if( fNight ) return LOADINGSCREEN_NIGHTHOSPITAL; return LOADINGSCREEN_DAYHOSPITAL; case SEC_B13: case SEC_N3: if( fNight ) return LOADINGSCREEN_NIGHTAIRPORT; return LOADINGSCREEN_DAYAIRPORT; case SEC_L11: case SEC_L12: if( fNight ) return LOADINGSCREEN_NIGHTBALIME; return LOADINGSCREEN_DAYBALIME; case SEC_H3: case SEC_H8: case SEC_D4: if( fNight ) return LOADINGSCREEN_NIGHTMINE; return LOADINGSCREEN_DAYMINE; } pSector = &SectorInfo[ ubSectorID ]; switch( pSector->ubTraversability[ 4 ] ) { case TOWN: if( fNight ) { if( Random( 2 ) ) { return LOADINGSCREEN_NIGHTTOWN2; } return LOADINGSCREEN_NIGHTTOWN1; } if( Random( 2 ) ) { return LOADINGSCREEN_DAYTOWN2; } return LOADINGSCREEN_DAYTOWN1; case SAND: case SAND_ROAD: if( fNight ) { return LOADINGSCREEN_NIGHTDESERT; } return LOADINGSCREEN_DAYDESERT; case FARMLAND: case FARMLAND_ROAD: case ROAD: if( fNight ) { return LOADINGSCREEN_NIGHTGENERIC; } return LOADINGSCREEN_DAYGENERIC; case PLAINS: case SPARSE: case HILLS: case PLAINS_ROAD: case SPARSE_ROAD: case HILLS_ROAD: if( fNight ) { return LOADINGSCREEN_NIGHTWILD; } return LOADINGSCREEN_DAYWILD; case DENSE: case SWAMP: case SWAMP_ROAD: case DENSE_ROAD: if( fNight ) { return LOADINGSCREEN_NIGHTFOREST; } return LOADINGSCREEN_DAYFOREST; case TROPICS: case TROPICS_ROAD: case WATER: case NS_RIVER: case EW_RIVER: case COASTAL: case COASTAL_ROAD: if( fNight ) { return LOADINGSCREEN_NIGHTTROPICAL; } return LOADINGSCREEN_DAYTROPICAL; default: Assert( 0 ); if( fNight ) { return LOADINGSCREEN_NIGHTGENERIC; } return LOADINGSCREEN_DAYGENERIC; } break; case 1: switch( ubSectorID ) { case SEC_A10: //Miguel's basement case SEC_I13: //Alma prison dungeon case SEC_J9: //Tixa prison dungeon case SEC_K4: //Orta weapons plant case SEC_O3: //Meduna case SEC_P3: //Meduna return LOADINGSCREEN_BASEMENT; default: //rest are mines return LOADINGSCREEN_MINE; } break; case 2: case 3: //all level 2 and 3 maps are caves! return LOADINGSCREEN_CAVE; default: // shouldn't ever happen Assert( FALSE ); if( fNight ) { return LOADINGSCREEN_NIGHTGENERIC; } return LOADINGSCREEN_DAYGENERIC; } }