mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
- Equip Milita Improvements: I've written code, which adds attachments to free positions on the gun militia chose to pick up (by navaroe)
- Bugfix: Reinforcements: Parts of roadblocks were resurrected after reinforcements death (by navaroe) git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7995 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+23
-19
@@ -764,7 +764,7 @@ void AssociateEnemiesWithStrategicGroups()
|
||||
{
|
||||
SECTORINFO *pSector;
|
||||
GROUP *pGroup;
|
||||
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks;
|
||||
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks; //how many soldiers of the type do we still have to assign to a group?
|
||||
UINT8 ubISNumAdmins, ubISNumTroops, ubISNumElites, ubISNumTanks;
|
||||
UINT8 ubNumElitesInGroup, ubNumTroopsInGroup, ubNumAdminsInGroup, ubNumTanksInGroup;
|
||||
INT32 i;
|
||||
@@ -784,10 +784,10 @@ void AssociateEnemiesWithStrategicGroups()
|
||||
ubNumTanks = pSector->ubNumTanks;
|
||||
|
||||
//Now go through our enemies in the autoresolve array, and assign the ubGroupID to the soldier
|
||||
//Stationary groups have a group ID of 0
|
||||
//Stationary groups have a group ID of 0 - first assign enemies from those stationary groups
|
||||
for( i = 0; i < gpAR->ubEnemies; ++i )
|
||||
{
|
||||
if ( gpEnemies[i].uiFlags & CELL_TANK && ubNumTanks )
|
||||
if ( gpEnemies[i].uiFlags & CELL_TANK && ubNumTanks ) //is this soldier a tank? and we still have some tanks to add? (since there might not be a static tank in sector)
|
||||
{
|
||||
gpEnemies[i].pSoldier->ubGroupID = 0;
|
||||
gpEnemies[i].uiFlags |= CELL_ASSIGNED;
|
||||
@@ -835,36 +835,36 @@ void AssociateEnemiesWithStrategicGroups()
|
||||
ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks;
|
||||
for( i = 0; i < gpAR->ubEnemies; i++ )
|
||||
{
|
||||
if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) )
|
||||
if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) ) //has this soldier already been assigned to a cell and therefore a group (while processing the static enemies above) ?
|
||||
{
|
||||
if( ubNumTanks && ubNumTanksInGroup )
|
||||
if (ubNumTanks && ubNumTanksInGroup && gpEnemies[i].uiFlags & CELL_TANK ) //is there still a tank to assign and is this a cell for tank?
|
||||
{
|
||||
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
|
||||
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
|
||||
ubNumTanks--;
|
||||
ubNumTanksInGroup--;
|
||||
}
|
||||
else if( ubNumElites && ubNumElitesInGroup )
|
||||
else if (ubNumElites && ubNumElitesInGroup && gpEnemies[i].uiFlags & CELL_ELITE)
|
||||
{
|
||||
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
|
||||
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
|
||||
ubNumElites--;
|
||||
ubNumElitesInGroup--;
|
||||
}
|
||||
else if( ubNumTroops && ubNumTroopsInGroup )
|
||||
else if (ubNumTroops && ubNumTroopsInGroup && gpEnemies[i].uiFlags & CELL_TROOP)
|
||||
{
|
||||
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
|
||||
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
|
||||
ubNumTroops--;
|
||||
ubNumTroopsInGroup--;
|
||||
}
|
||||
else if( ubNumAdmins && ubNumAdminsInGroup )
|
||||
else if (ubNumAdmins && ubNumAdminsInGroup && gpEnemies[i].uiFlags & CELL_ADMIN)
|
||||
{
|
||||
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
|
||||
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
|
||||
ubNumAdmins--;
|
||||
ubNumAdminsInGroup--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -876,7 +876,7 @@ void AssociateEnemiesWithStrategicGroups()
|
||||
pGroup = gpGroupList;
|
||||
while( pGroup )
|
||||
{
|
||||
// Don't process road block. It'll be processed as static
|
||||
// Don't process road block. It'll be processed as static (because their ubGroupID is 0 so the first term eval to false)
|
||||
if ( pGroup->ubGroupID && pGroup->usGroupTeam == ENEMY_TEAM && IsGroupInARightSectorToReinforce( pGroup, gpAR->ubSectorX, gpAR->ubSectorY ) )
|
||||
{
|
||||
ubNumElitesInGroup = pGroup->pEnemyGroup->ubNumElites;
|
||||
@@ -887,28 +887,28 @@ void AssociateEnemiesWithStrategicGroups()
|
||||
{
|
||||
if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) )
|
||||
{
|
||||
if ( ubNumTanks && ubNumTanksInGroup )
|
||||
if (ubNumTanks && ubNumTanksInGroup && gpEnemies[i].uiFlags & CELL_TANK)
|
||||
{
|
||||
gpEnemies[i].pSoldier->ubGroupID = pGroup->ubGroupID;
|
||||
gpEnemies[i].uiFlags |= CELL_ASSIGNED;
|
||||
ubNumTanks--;
|
||||
ubNumTanksInGroup--;
|
||||
}
|
||||
else if ( ubNumElites && ubNumElitesInGroup )
|
||||
else if (ubNumElites && ubNumElitesInGroup && gpEnemies[i].uiFlags & CELL_ELITE)
|
||||
{
|
||||
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
|
||||
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
|
||||
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
|
||||
ubNumElites--;
|
||||
ubNumElitesInGroup--;
|
||||
}
|
||||
else if( ubNumTroops && ubNumTroopsInGroup )
|
||||
else if (ubNumTroops && ubNumTroopsInGroup && gpEnemies[i].uiFlags & CELL_TROOP)
|
||||
{
|
||||
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
|
||||
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
|
||||
ubNumTroops--;
|
||||
ubNumTroopsInGroup--;
|
||||
}
|
||||
else if( ubNumAdmins && ubNumAdminsInGroup )
|
||||
else if (ubNumAdmins && ubNumAdminsInGroup && gpEnemies[i].uiFlags & CELL_ADMIN)
|
||||
{
|
||||
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
|
||||
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
|
||||
@@ -921,7 +921,7 @@ void AssociateEnemiesWithStrategicGroups()
|
||||
pGroup = pGroup->next;
|
||||
}
|
||||
|
||||
// Set GroupID = 0 for the rest
|
||||
// Set GroupID = 0 for the rest (that includes reinforcements)
|
||||
ubDirAmount = GetAdjacentSectors( pSectors, gpAR->ubSectorX, gpAR->ubSectorY );
|
||||
|
||||
for( ubCurrSI = 0; ubCurrSI < ubDirAmount; ++ubCurrSI )
|
||||
@@ -935,7 +935,7 @@ void AssociateEnemiesWithStrategicGroups()
|
||||
|
||||
for( i = 0; i < gpAR->ubEnemies; ++i )
|
||||
{
|
||||
if( ubISNumAdmins + ubISNumTroops + ubISNumElites + ubISNumTanks <= gubReinforcementMinEnemyStaticGroupSize ) break;
|
||||
if( ubISNumAdmins + ubISNumTroops + ubISNumElites + ubISNumTanks <= gubReinforcementMinEnemyStaticGroupSize ) break; //if group would be left understaffed, it wont reinforce - go chceck another sector (what if are there more groups here?)
|
||||
|
||||
if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) )
|
||||
{
|
||||
@@ -978,6 +978,10 @@ void AssociateEnemiesWithStrategicGroups()
|
||||
}
|
||||
}
|
||||
}
|
||||
/*at this point, all enemies should have been assigned to their cell and group. If not, there is a bug around
|
||||
Because number and type of cells should be computed for the same composition of enemies as the one we see in this function, it should not happen though*/
|
||||
AssertMsg(!(ubISNumAdmins & ubISNumTroops & ubISNumElites & ubISNumTanks), "Mapping between actual enemies and autoresolve cells is wrong.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2531,9 +2535,9 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
|
||||
{
|
||||
if( gpEnemies[ i ].pSoldier )
|
||||
{
|
||||
if( fDeleteForGood && gpEnemies[ i ].pSoldier->stats.bLife < OKLIFE )
|
||||
if( fDeleteForGood && gpEnemies[ i ].pSoldier->stats.bLife < OKLIFE ) //if we are finished with battle and soldier is either dead or dying
|
||||
{
|
||||
TrackEnemiesKilled( ENEMY_KILLED_IN_AUTO_RESOLVE, gpEnemies[ i ].pSoldier->ubSoldierClass );
|
||||
TrackEnemiesKilled( ENEMY_KILLED_IN_AUTO_RESOLVE, gpEnemies[ i ].pSoldier->ubSoldierClass ); //add casualty to some statistic
|
||||
if( ProcessLoyalty() )HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_ENEMY_KILLED, gpAR->ubSectorX, gpAR->ubSectorY, 0 );
|
||||
ProcessQueenCmdImplicationsOfDeath( gpEnemies[ i ].pSoldier );
|
||||
AddDeadSoldierToUnLoadedSector( gpAR->ubSectorX, gpAR->ubSectorY, 0, gpEnemies[ i ].pSoldier, RandomGridNo(), ADD_DEAD_SOLDIER_TO_SWEETSPOT );
|
||||
|
||||
@@ -655,7 +655,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
|
||||
if (mapMaximumNumberOfEnemies > gGameExternalOptions.ubGameMaximumNumberOfEnemies)
|
||||
mapMaximumNumberOfEnemies = gGameExternalOptions.ubGameMaximumNumberOfEnemies;
|
||||
|
||||
//is there more enemies in the sector then we can actually place on map?
|
||||
//are there more enemies in the sector then we can actually place on map?
|
||||
gfPendingNonPlayerTeam[ENEMY_TEAM] = (NumNonPlayerTeamMembersInSector( gWorldSectorX, gWorldSectorY, ENEMY_TEAM ) > mapMaximumNumberOfEnemies);
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ UINT32 guiMilitiaReinforceTurn = 0, guiMilitiaArrived = 0;//dnl ch68 090913
|
||||
void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks )
|
||||
{
|
||||
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks;
|
||||
UINT16 pusMoveDir[4][3];
|
||||
UINT16 pusMoveDir[4][3]; //first column in this matrix is number of sector, except for 4th row
|
||||
UINT8 ubDirNumber, ubIndex;
|
||||
|
||||
GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumTanks );
|
||||
@@ -57,10 +57,10 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
|
||||
GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
|
||||
|
||||
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
|
||||
{
|
||||
{ //take number of the involved sector, find its X and Y coordintes and then ask for number of troops there
|
||||
GetNumberOfStationaryEnemiesInSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ), &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks );
|
||||
|
||||
while( ubNumElites + ubNumTroops + ubNumAdmins + ubNumTanks > gubReinforcementMinEnemyStaticGroupSize)
|
||||
while( ubNumElites + ubNumTroops + ubNumAdmins + ubNumTanks > gubReinforcementMinEnemyStaticGroupSize) //count how many of static group will reinforce the battle, but leave minimal group size to guard
|
||||
{
|
||||
if( ubNumElites )
|
||||
{
|
||||
|
||||
+101
-17
@@ -86,6 +86,7 @@ ARMY_GUN_CHOICE_TYPE gExtendedArmyGunChoices[SOLDIER_GUN_CHOICE_SELECTIONS][ARMY
|
||||
// { /* 10- rocket rifle */ 5, ROCKET_RIFLE, AUTO_ROCKET_RIFLE , RPK74, HK21E, MINIMI , -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
|
||||
//};
|
||||
|
||||
|
||||
// Flugente: created separate gun choices for different soldier classes
|
||||
ARMY_GUN_CHOICE_TYPE gArmyItemChoices[SOLDIER_GUN_CHOICE_SELECTIONS][MAX_ITEM_TYPES];
|
||||
|
||||
@@ -103,7 +104,6 @@ UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness);
|
||||
UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness, BOOLEAN getMatchingCoolness);
|
||||
UINT16 PickARandomAttachment(UINT8 typeIndex, INT8 bSoldierClass, UINT16 usBaseItem, UINT8 maxCoolness, BOOLEAN getMatchingCoolness);
|
||||
|
||||
|
||||
void InitArmyGunTypes(void)
|
||||
{
|
||||
ARMY_GUN_CHOICE_TYPE *pGunChoiceTable;
|
||||
@@ -3701,7 +3701,7 @@ enum {
|
||||
SI_LEGS,
|
||||
SI_SIGHT, // for sunglasses and NVGs
|
||||
SI_FACE2,
|
||||
SI_FACE_SPARESIGHT, // for sunglasses at night an NVGs during the day - militia take those at well, otherwise mobiles are ill equipped when the night begins/ends
|
||||
SI_FACE_SPARESIGHT, // for sunglasses at night an NVGs during the day - militia take those as well, otherwise mobiles are ill equipped when the night begins/ends
|
||||
SI_GASMASK,
|
||||
SI_MELEE,
|
||||
SI_GRENADE,
|
||||
@@ -3722,6 +3722,8 @@ struct ItemSearchStruct {
|
||||
UINT32 val; // the fitness value of this object
|
||||
};
|
||||
|
||||
void addAttachementsToMilitiaWeapon(std::vector<WORLDITEM>& pWorldItem, UINT16 usTabooFlag, SOLDIERCREATE_STRUCT *pp);
|
||||
|
||||
// evaluate an object an remember it if it is the best so far
|
||||
void EvaluateObjForItem( std::vector<WORLDITEM>& pWorldItem, OBJECTTYPE* pObj, UINT32 uiCount, ItemSearchStruct* pSi )//dnl ch75 271013
|
||||
{
|
||||
@@ -3764,40 +3766,73 @@ void EvaluateObjForItem_WithAmmo( std::vector<WORLDITEM>& pWorldItem, OBJECTTYPE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Makes sure that stack of items on stacksIndexInWorldItem is removed, if it does not contain any items now.
|
||||
|
||||
Use after removing stuff from pWorldItem like by attaching it to something or by putting it into inventory.
|
||||
*/
|
||||
void RemoveStackIfEmpty(std::vector<WORLDITEM>& pWorldItem, UINT32 stacksIndexInWorldItem) {
|
||||
if (pWorldItem[stacksIndexInWorldItem].object.ubNumberOfObjects < 1)
|
||||
{
|
||||
// account for items with invalid gridnos...
|
||||
if (pWorldItem[stacksIndexInWorldItem].sGridNo != NOWHERE)
|
||||
{
|
||||
RemoveItemFromPool(pWorldItem[stacksIndexInWorldItem].sGridNo, stacksIndexInWorldItem, pWorldItem[stacksIndexInWorldItem].ubLevel);
|
||||
}
|
||||
|
||||
// setting this to false can lead to cases where we 'forget' items without a valid gridno - though I am unsure why.
|
||||
//pWorldItem[ pSi->pos ].fExists = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// forward declaration for default parameter
|
||||
// if pSi has an entry, move gun from pWorldItem into pp
|
||||
void SearchItemRetrieval( std::vector<WORLDITEM>& pWorldItem, ItemSearchStruct* pSi, SOLDIERCREATE_STRUCT *pp, UINT8 usTake = 1 );//dnl ch75 271013
|
||||
|
||||
|
||||
/** Used after taking item from world and putting it into militias inventory.
|
||||
Makes sure TAKEN_BY_MILITIA flags are set in manner reflecting the flags on items stack of origin.
|
||||
*/
|
||||
void SetTakenByMilitiaFlagsWhenForRetrievedItem(std::vector<WORLDITEM>& pWorldItem, UINT32 itemsPositionInWorld, SOLDIERCREATE_STRUCT *pp, UINT32 slotInInventory, UINT8 numberOfItemsToMark) {
|
||||
for (UINT8 i = 0; i < numberOfItemsToMark; ++i)
|
||||
{
|
||||
(pp->Inv[slotInInventory])[i]->data.sObjectFlag |= TAKEN_BY_MILITIA;
|
||||
}
|
||||
|
||||
if (pWorldItem[itemsPositionInWorld].usFlags & WORLD_ITEM_TABOO_FOR_MILITIA_EQ_GREEN)
|
||||
(pp->Inv[slotInInventory])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_GREEN; //remember the taboo we set on item while it was on ground
|
||||
if (pWorldItem[itemsPositionInWorld].usFlags & WORLD_ITEM_TABOO_FOR_MILITIA_EQ_BLUE)
|
||||
(pp->Inv[slotInInventory])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_BLUE;
|
||||
}
|
||||
|
||||
// if pSi has an entry, move gun from pWorldItem into pp
|
||||
void SearchItemRetrieval( std::vector<WORLDITEM>& pWorldItem, ItemSearchStruct* pSi, SOLDIERCREATE_STRUCT *pp, UINT8 usTake )//dnl ch75 271013
|
||||
{
|
||||
if ( pSi->found && !pSi->done )
|
||||
{
|
||||
UINT8 usRealTake = min(usTake, pWorldItem[ pSi->pos ].object.ubNumberOfObjects);
|
||||
pWorldItem[ pSi->pos ].object.MoveThisObjectTo(pp->Inv[ pSi->soldierslot ], usRealTake );
|
||||
//never take more than there actually is on the given stack (atm. we try to take 2 grenades, but there might be only 1)
|
||||
UINT8 usRealTake = min(usTake, pWorldItem[ pSi->pos ].object.ubNumberOfObjects);
|
||||
//move objects (like weapon) to soldiers slot, position of object in the world and target slot are determined by values in pSi
|
||||
pWorldItem[ pSi->pos ].object.MoveThisObjectTo(pp->Inv[ pSi->soldierslot ], usRealTake );
|
||||
|
||||
for ( UINT8 i = 0; i < usRealTake; ++i )
|
||||
SetTakenByMilitiaFlagsWhenForRetrievedItem(pWorldItem, pSi->pos, pp, pSi->soldierslot, usRealTake);
|
||||
/* for ( UINT8 i = 0; i < usRealTake; ++i )
|
||||
(pp->Inv[ pSi->soldierslot ])[i]->data.sObjectFlag |= TAKEN_BY_MILITIA;
|
||||
|
||||
if ( pWorldItem[ pSi->pos ].usFlags & WORLD_ITEM_TABOO_FOR_MILITIA_EQ_GREEN )
|
||||
(pp->Inv[ pSi->soldierslot ])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_GREEN;
|
||||
if ( pWorldItem[ pSi->pos ].usFlags & WORLD_ITEM_TABOO_FOR_MILITIA_EQ_GREEN )
|
||||
(pp->Inv[ pSi->soldierslot ])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_GREEN;
|
||||
if ( pWorldItem[ pSi->pos ].usFlags & WORLD_ITEM_TABOO_FOR_MILITIA_EQ_BLUE )
|
||||
(pp->Inv[ pSi->soldierslot ])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_BLUE;
|
||||
|
||||
if ( pWorldItem[ pSi->pos ].object.ubNumberOfObjects < 1 )
|
||||
{
|
||||
// account for items with invalid gridnos...
|
||||
if ( pWorldItem[ pSi->pos ].sGridNo != NOWHERE )
|
||||
RemoveItemFromPool(pWorldItem[ pSi->pos ].sGridNo, (pSi->pos), pWorldItem[ pSi->pos ].ubLevel);
|
||||
(pp->Inv[ pSi->soldierslot ])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_BLUE;*/
|
||||
|
||||
// setting this to false can lead to cases where we 'forget' items without a valid gridno - though I am unsure why.
|
||||
//pWorldItem[ pSi->pos ].fExists = FALSE;
|
||||
}
|
||||
// account for items with invalid gridnos - when we take last item from the stack, the whole stack object should be gone
|
||||
RemoveStackIfEmpty(pWorldItem, pSi->pos);
|
||||
|
||||
}
|
||||
|
||||
pSi->done = TRUE;
|
||||
}
|
||||
|
||||
|
||||
typedef std::map<UINT8, UINT32> AmmoType_BulletCountMap; // used to count how many bullets of an ammotype we have
|
||||
typedef std::map<UINT8, AmmoType_BulletCountMap> Calibre_BulletCountMap; // this map stores a map containing all the different ammotypes and how many bulltes we have for them
|
||||
|
||||
@@ -4510,6 +4545,8 @@ void TakeMilitiaEquipmentfromSector( INT16 sMapX, INT16 sMapY, INT8 sMapZ, SOLDI
|
||||
|
||||
// take this gun
|
||||
SearchItemRetrieval( pWorldItem, &si[SI_GUN], pp );
|
||||
//soldier has his gun now, look for attachments for it
|
||||
addAttachementsToMilitiaWeapon(pWorldItem, usTabooFlag, pp);
|
||||
|
||||
// empty the gun, create a mag
|
||||
if ( !fSearchForAmmo )
|
||||
@@ -4535,6 +4572,8 @@ void TakeMilitiaEquipmentfromSector( INT16 sMapX, INT16 sMapY, INT8 sMapZ, SOLDI
|
||||
|
||||
// take this gun
|
||||
SearchItemRetrieval( pWorldItem, &si[SI_GUN], pp );
|
||||
//soldier has his gun now, look for attachments for it
|
||||
addAttachementsToMilitiaWeapon(pWorldItem, usTabooFlag, pp);
|
||||
|
||||
// empty the gun, create a mag
|
||||
if ( !fSearchForAmmo )
|
||||
@@ -4808,4 +4847,49 @@ void TakeMilitiaEquipmentfromSector( INT16 sMapX, INT16 sMapY, INT8 sMapZ, SOLDI
|
||||
///////////////////////////////// Exit /////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Goes through items in pWorldItem and looks for scopes, foregrips, lasers, etc. and tries to attach them to thing in soldiers (pp) hand. Hopefuly,
|
||||
it is a weapon. If thing is successfuly attached, it is removed from world. Attachement has to be reachable and not a taboo for militia.
|
||||
|
||||
Does not attempt to improve current attachments, first item to fit in a position will remain there.
|
||||
*/
|
||||
void addAttachementsToMilitiaWeapon(std::vector<WORLDITEM>& pWorldItem, UINT16 usTabooFlag, SOLDIERCREATE_STRUCT *pp) {
|
||||
for (UINT32 uiCount = 0; uiCount < pWorldItem.size(); ++uiCount) // ... for all items in the world ...
|
||||
{
|
||||
if ((pWorldItem)[uiCount].fExists) // ... if item exists ...
|
||||
{
|
||||
OBJECTTYPE* pObj = &((pWorldItem)[uiCount].object); // ... get pointer for this item ...
|
||||
|
||||
if (pObj != NULL && pObj->exists()) // ... if pointer is not obviously useless ...
|
||||
{
|
||||
// this would be the place where we check wether the militia is allowed to pick up an item depending on its soldierclass
|
||||
// test wether item is reachable and its not taboo
|
||||
if (((pWorldItem)[uiCount].usFlags & WORLD_ITEM_REACHABLE) && !((pWorldItem)[uiCount].usFlags & usTabooFlag))
|
||||
{
|
||||
|
||||
UINT32 usItemClass = Item[(pWorldItem)[uiCount].object.usItem].usItemClass;
|
||||
UINT64 nasAttachmentClass = Item[(pWorldItem)[uiCount].object.usItem].nasAttachmentClass; //eg. 16 for scope
|
||||
UINT32 attachmentClass = Item[(pWorldItem)[uiCount].object.usItem].attachmentclass;
|
||||
|
||||
//check if this item is something we might want to attach, bipods are excluded atm because militia mainly runs around and doesn't camp enough
|
||||
//also under barrel launchers are not dealt with (at least for now)
|
||||
if (usItemClass & IC_MISC && attachmentClass & (AC_SCOPE | AC_FOREGRIP | AC_STOCK | AC_SIGHT | AC_LASER | AC_MUZZLE | AC_SLING)) {
|
||||
//we got something, lets get the weapon and try to attach it.
|
||||
OBJECTTYPE* gun = &pp->Inv[HANDPOS]; //we are looking to attach to thing in hand, should be gun
|
||||
OBJECTTYPE* attachment = &(pWorldItem)[uiCount].object;
|
||||
BOOLEAN isAttachedNow = gun->AttachObject(NULL, attachment, FALSE); //do the actual attaching
|
||||
|
||||
if (isAttachedNow) { //might be false, if attachement was not valid for the gun (like small scope to M-960A)
|
||||
RemoveStackIfEmpty(pWorldItem, uiCount); //chceck uiCount stack, might be empty now and should be removed
|
||||
//SetTakenByMilitiaFlagsWhenForRetrievedItem(pWorldItem,... //Nav:I realized, this is not required for attachement, hopefuly correctly (because weapon got proper flags already)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////// Flugente: militia equipment feature ///////////////////////////////////
|
||||
|
||||
+6
-6
@@ -2329,7 +2329,7 @@ BOOLEAN ValidItemAttachmentSlot( OBJECTTYPE * pObj, UINT16 usAttachment, BOOLEAN
|
||||
OBJECTTYPE * tmpObj = FindAttachmentByClass(pObj,IC_GUN,subObject);
|
||||
usSimilarItem = tmpObj->usItem;
|
||||
}
|
||||
if ( !fSameItem )
|
||||
if ( !fSameItem ) //Nav: why is this check here? fSameItem can only be false here, doesn't hurt I guess...
|
||||
{
|
||||
for(int i = 0;i<sizeof(IncompatibleAttachments);i++)
|
||||
{
|
||||
@@ -2340,9 +2340,9 @@ BOOLEAN ValidItemAttachmentSlot( OBJECTTYPE * pObj, UINT16 usAttachment, BOOLEAN
|
||||
break;
|
||||
}
|
||||
|
||||
if ( IncompatibleAttachments[i][0] == NONE )
|
||||
break;
|
||||
if ( IncompatibleAttachments[i][0] == usAttachment && FindAttachment (pObj,IncompatibleAttachments[i][1],subObject) != 0 )
|
||||
if ( IncompatibleAttachments[i][0] == NONE )
|
||||
break; //0 terminated, end search, when we are done with all entries and nothing meaningful is left
|
||||
if ( IncompatibleAttachments[i][0] == usAttachment && FindAttachment (pObj,IncompatibleAttachments[i][1],subObject) != 0 ) //TODO fill in comment 1
|
||||
{
|
||||
fSimilarItems = TRUE;
|
||||
usSimilarItem = IncompatibleAttachments[i][1];
|
||||
@@ -4682,7 +4682,7 @@ BOOLEAN OBJECTTYPE::AttachObject( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttachme
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//WarmSteel - if uiItemPos is -1, we're not checking for a specific slot, but scrolling through them all. TODO comment the rest
|
||||
BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttachment, BOOLEAN playSound, UINT8 subObject, INT32 iItemPos, BOOLEAN fRemoveProhibited, std::vector<UINT16> usAttachmentSlotIndexVector )
|
||||
{
|
||||
|
||||
@@ -4950,7 +4950,7 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac
|
||||
pAttachment->MoveThisObjectTo(attachmentObject,1,pSoldier,NUM_INV_SLOTS,1);
|
||||
}
|
||||
else
|
||||
pAttachment->MoveThisObjectTo(attachmentObject,1,pSoldier,NUM_INV_SLOTS,1);
|
||||
pAttachment->MoveThisObjectTo(attachmentObject,1,pSoldier,NUM_INV_SLOTS,1);
|
||||
}
|
||||
|
||||
//WarmSteel - Because we want every attachment to stay in place in NAS, we must first delete the "null" attachment, then insert the new one.
|
||||
|
||||
@@ -1327,7 +1327,7 @@ public:
|
||||
UINT32 uiLastAssignmentChangeMin; // timestamp of last assignment change in minutes
|
||||
INT32 iTotalLengthOfInsuranceContract;
|
||||
|
||||
UINT8 ubSoldierClass; //admin, elite, troop (creature types?)
|
||||
UINT8 ubSoldierClass; //admin, elite, troop (creature types?) Nav: 2 seems to mean elite, 3 troop so admin is 1
|
||||
UINT8 ubAPsLostToSuppression;
|
||||
UINT8 ubSuppressorID;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user