diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp
index 53b9b9ef..45381374 100644
--- a/Tactical/Handle Items.cpp
+++ b/Tactical/Handle Items.cpp
@@ -4986,27 +4986,47 @@ void BombMessageBoxCallBack( UINT8 ubExitValue )
}
}
- if ( ArmBomb( &(gpTempSoldier->inv[HANDPOS]), ubExitValue ) )
+ // Flugente: tripwire rolls are not planted - instead we spawn tripwire and plant that
+ OBJECTTYPE* pObj = &(gpTempSoldier->inv[HANDPOS]);
+ if ( Item[ gpTempSoldier->inv[ HANDPOS ].usItem ].usItemFlag & TRIPWIREROLL && Item[ gpTempSoldier->inv[ HANDPOS ].usItem ].usBuddyItem != NOTHING )
+ {
+ (*pObj)[0]->data.objectStatus--;
+
+ if ( !(*pObj)[0]->data.objectStatus )
+ {
+ // Delete object
+ DeleteObj( pObj );
+
+ // dirty interface panel
+ DirtyMercPanelInterface( gpTempSoldier, DIRTYLEVEL2 );
+ }
+
+ CreateItem( Item[ gpTempSoldier->inv[ HANDPOS ].usItem ].usBuddyItem, 100, &gTempObject );
+
+ pObj = &gTempObject;
+ }
+
+ if ( ArmBomb( pObj, ubExitValue ) )
{
// SANDRO - STOMP traits - Demolitions bonus to trap level
if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( gpTempSoldier, DEMOLITIONS_NT ))
{
// increase trap level for Demolitions trait
- gpTempSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( max( 10, (8 + gSkillTraitValues.ubDEPlacedBombLevelBonus)), (( EffectiveExplosive( gpTempSoldier ) / 20) + (EffectiveExpLevel( gpTempSoldier ) / 3) + gSkillTraitValues.ubDEPlacedBombLevelBonus) );
+ (*pObj)[0]->data.bTrap = __min( max( 10, (8 + gSkillTraitValues.ubDEPlacedBombLevelBonus)), (( EffectiveExplosive( gpTempSoldier ) / 20) + (EffectiveExpLevel( gpTempSoldier ) / 3) + gSkillTraitValues.ubDEPlacedBombLevelBonus) );
}
else
{
- gpTempSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( 10, ( EffectiveExplosive( gpTempSoldier ) / 20) + (EffectiveExpLevel( gpTempSoldier ) / 3) );
+ (*pObj)[0]->data.bTrap = __min( 10, ( EffectiveExplosive( gpTempSoldier ) / 20) + (EffectiveExpLevel( gpTempSoldier ) / 3) );
}
// Flugente: backgrounds
if ( gpTempSoldier->HasBackgroundFlag( BACKGROUND_TRAPLEVEL ) )
- gpTempSoldier->inv[ HANDPOS ][0]->data.bTrap++;
+ (*pObj)[0]->data.bTrap++;
// HACK IMMINENT!
// value of 1 is stored in maps for SIDE of bomb owner... when we want to use IDs!
// so we add 2 to all owner IDs passed through here and subtract 2 later
- if (gpTempSoldier->inv[HANDPOS].MoveThisObjectTo(gTempObject, 1) == 0)
+ if ( pObj != &(gpTempSoldier->inv[HANDPOS]) || gpTempSoldier->inv[HANDPOS].MoveThisObjectTo(gTempObject, 1) == 0)
{
gTempObject[0]->data.misc.ubBombOwner = gpTempSoldier->ubID + 2;
gTempObject[0]->data.ubDirection = gpTempSoldier->ubDirection; // Flugente: direction of bomb is direction of soldier
diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h
index 9efb361b..2b6e6871 100644
--- a/Tactical/Item Types.h
+++ b/Tactical/Item Types.h
@@ -758,8 +758,8 @@ extern OBJECTTYPE gTempObject;
#define SCUBA_MASK 0x00400000 //4194304 // item is a scuba gear breathing mask
#define SCUBA_FINS 0x00800000 //8388608 // this item speed up swimming, but slows walking and running
-/*#define PLAYER_NET_1_LVL_3 0x01000000 //16777216
-#define PLAYER_NET_2_LVL_3 0x02000000 //33554432
+#define TRIPWIREROLL 0x01000000 //16777216 // this item is a tripwire roll
+/*#define PLAYER_NET_2_LVL_3 0x02000000 //33554432
#define PLAYER_NET_3_LVL_3 0x04000000 //67108864
#define PLAYER_NET_4_LVL_3 0x08000000 //134217728
@@ -1157,6 +1157,9 @@ typedef struct
// Flugente: determine wether the AI should pick this item for its choices only at certain times
UINT8 usItemChoiceTimeSetting;
+ // Flugente: item is connected to another item. Type of connection depends on item specifics
+ UINT16 usBuddyItem;
+
} INVTYPE;
@@ -1762,7 +1765,8 @@ typedef enum
TEMPERATURE,
EXPLOSIVE_MERGE_EASY, //Madd: new merge types
MECHANICAL_MERGE_EASY,
- MECHANICAL_MERGE_HARD
+ MECHANICAL_MERGE_HARD,
+ TRIPWIRE_ROLL,
} MergeType;
extern UINT16 Merge[MAXITEMS+1][6];
diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp
index 35516124..22f86ff8 100644
--- a/Tactical/Items.cpp
+++ b/Tactical/Items.cpp
@@ -5151,6 +5151,32 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac
}
break;
+ case TRIPWIRE_ROLL:
+ {
+ // check if this can work
+ if ( Item[ this->usItem ].tripwire && Item[pAttachment->usItem].tripwire && Item[ this->usItem ].usItemFlag == TRIPWIREROLL )
+ {
+ if ( (*this)[subObject]->data.objectStatus < 100 )
+ (*this)[subObject]->data.objectStatus++;
+ else
+ {
+ pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 );
+ return( FALSE );
+ }
+
+ pAttachment->RemoveObjectsFromStack(1);
+ }
+
+ //UINT16 usOldItem = this->usItem;
+ //this->usItem = usResult;
+
+ //WarmSteel - Replaced this with one that also checks default attachments, otherwise you could not replace built-in bonuses with default inseperable attachments.
+ //RemoveProhibitedAttachments(pSoldier, this, usResult);
+ //ReInitMergedItem(pSoldier, this, usOldItem, 0);
+ }
+ break;
+ // fall through
+
case ELECTRONIC_MERGE:
if ( pSoldier )
{
@@ -5312,6 +5338,12 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac
if ( ubType != TREAT_ARMOUR )
{
(*this)[subObject]->data.objectStatus = ((*this)[subObject]->data.objectStatus + (*pAttachment)[0]->data.objectStatus) / 2;
+
+ // Flugente: if the new item has the TRIPWIREROLL property, it only gets status 2 upon creation via merges
+ if ( Item[ this->usItem ].usItemFlag == TRIPWIREROLL )
+ {
+ (*this)[subObject]->data.objectStatus = 2;
+ }
}
//ADB ubWeight has been removed, see comments in OBJECTTYPE
diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp
index b081ce3d..da197414 100644
--- a/Utils/XML_Items.cpp
+++ b/Utils/XML_Items.cpp
@@ -275,7 +275,8 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
strcmp(name, "randomitem") == 0 ||
strcmp(name, "randomitemcoolnessmodificator") == 0 ||
strcmp(name, "FlashLightRange") == 0 ||
- strcmp(name, "ItemChoiceTimeSetting") == 0 ))
+ strcmp(name, "ItemChoiceTimeSetting") == 0 ||
+ strcmp(name, "buddyitem") == 0 ))
{
pData->curElement = ELEMENT_PROPERTY;
//DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("itemStartElementHandle: going into element, name = %s",name) );
@@ -1425,6 +1426,11 @@ itemEndElementHandle(void *userData, const XML_Char *name)
// no nonsense, only values between 0 and + 2
pData->curItem.usItemChoiceTimeSetting = min(2, max(0, (UINT8) atol(pData->szCharData) ) );
}
+ else if(strcmp(name, "buddyitem") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curItem.usBuddyItem = (UINT16) atol(pData->szCharData);
+ }
pData->maxReadDepth--;
}
@@ -2065,6 +2071,7 @@ BOOLEAN WriteItemStats()
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].randomitemcoolnessmodificator );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usFlashLightRange );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usItemChoiceTimeSetting );
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usBuddyItem );
FilePrintf(hFile,"\t\r\n");
}