From 3c01b5364ef4ef035aa20f216f9aaca40bc4e5a7 Mon Sep 17 00:00:00 2001 From: Flugente Date: Sun, 29 Sep 2013 17:06:37 +0000 Subject: [PATCH] - new item: when planting tripwire roll (Item# 1640), a tripwire item is created, thereby making planting multiple wires much easier. Teipwires can be merged to create a roll - new item tag: connects items to other items. Connection specifics depend on items involved git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6455 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Tactical/Handle Items.cpp | 30 +++++++++++++++++++++++++----- Tactical/Item Types.h | 10 +++++++--- Tactical/Items.cpp | 32 ++++++++++++++++++++++++++++++++ Utils/XML_Items.cpp | 9 ++++++++- 4 files changed, 72 insertions(+), 9 deletions(-) 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"); }