Feature improvement: tripwire, tripwire mines and directional eplosives can now be planted with the map editor.

- The action item system has been repaired for this. It has never worked correctly prior to this, but the errors never occured.
- New items from GameDir 1538 are required for this to work. They are direct copies of existing items, except for a new tag, <usActionItemFlag>.
- The name of the new action items should clarify in the editor what an item does.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5565 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2012-09-15 02:28:18 +00:00
parent 3cc8153a61
commit 3d6bc97289
5 changed files with 290 additions and 46 deletions
+130
View File
@@ -4,6 +4,7 @@
#include "Items.h"
#include "GameSettings.h"
#include "screenids.h"
#include "Action Items.h" // added by Flugente for the ACTION_ITEM_BLOW_UP value
int BODYPOSFINAL = GUNSLINGPOCKPOS;//RESET in initInventory
@@ -1158,6 +1159,46 @@ OLD_OBJECTTYPE_101& OLD_OBJECTTYPE_101::operator=(OBJECTTYPE& src)
this->ugYucky.ubGunState = src[0]->data.gun.ubGunState;
break;
}
// Flugente fix: there is a severe problem with Action items. The problem is that in the above switch statement, we use the default stuff for action items.
// If the action item is a bomb etc. (bActionValue = 3), we want to set the bomb item. But due to EXTREME RETARDNESS, the ugYucky-struct differs on variable positions.
// To be precise (see in ItemTypes.h: union OLD_OBJECTTYPE_101_UNION for reference), its
//
// ...
// INT8 bGunStatus; // status % of gun
// UINT8 ubGunAmmoType; // ammo type, as per weapons.h
// UINT8 ubGunShotsLeft; // duh, amount of ammo left
// UINT16 usGunAmmoItem; // the item # for the item table
// ...
//
// in the first struct, that is used for the default stuff, but
//
// ...
// INT8 bBombStatus; // % status
// INT8 bDetonatorType; // timed, remote, or pressure-activated
// UINT16 usBombItem; // the usItem of the bomb.
// union
// {
// ...
//
// in the struct that stores the bomb item.
// Now, if our action item has a Bombitem > 255, that value is read from UINT16 ubGunShotsLeft in OBJECT_GUN.
// In the OBJECTTYPE::data union, OBJECT_GUN and OBJECT_BOMBS_AND_OTHER both have the UINT16 that stores the usBombItem or ubGunShotsLeft at the same position. So until here it is ok...
// However, this value now gets written into ugYucky.ubGunShotsLeft - which is an UINT8 instead of UINT16. This means that any item number > 255 is cut down.
// This error seems to have always been here (13 years). It just never occured until now.
// An easy fix would be to just switch the positions of UINT8ubGunShotsLeft and UINT16 usGunAmmoItem. However we cannot do that, as that will affect every object read ever anywhere.
//
// For this reason, I now present you this filthy, ugly hack, specifically for action items handle bombs:
if ( src.usItem == ACTION_ITEM && src[0]->data.misc.bActionValue == ACTION_ITEM_BLOW_UP )
{
this->ugYucky.bDetonatorType = src[0]->data.misc.bDetonatorType;
this->ugYucky.usBombItem = src[0]->data.misc.usBombItem;
this->ugYucky.bDelay = src[0]->data.misc.bDelay;
this->ugYucky.ubBombOwner = src[0]->data.misc.ubBombOwner;
this->ugYucky.bActionValue = src[0]->data.misc.bActionValue;
this->ugYucky.ubTolerance = src[0]->data.misc.ubTolerance;
}
this->bTrap = src[0]->data.bTrap;
this->ubImprintID = src[0]->data.ubImprintID;
this->fUsed = src[0]->data.fUsed;
@@ -1331,6 +1372,95 @@ OBJECTTYPE& OBJECTTYPE::operator=(const OLD_OBJECTTYPE_101& src)
break;
}
// Flugente fix: there is a severe problem with Action items. The problem is that in the above switch statement, we use the default stuff for action items.
// If the action item is a bomb etc. (bActionValue = 3), we want to set the bomb item. But due to EXTREME RETARDNESS, the ugYucky-struct differs on variable positions.
// To be precise (see in ItemTypes.h: union OLD_OBJECTTYPE_101_UNION for reference), its
//
// ...
// INT8 bGunStatus; // status % of gun
// UINT8 ubGunAmmoType; // ammo type, as per weapons.h
// UINT8 ubGunShotsLeft; // duh, amount of ammo left
// UINT16 usGunAmmoItem; // the item # for the item table
// ...
//
// in the first struct, that is used for the default stuff, but
//
// ...
// INT8 bBombStatus; // % status
// INT8 bDetonatorType; // timed, remote, or pressure-activated
// UINT16 usBombItem; // the usItem of the bomb.
// union
// {
// ...
//
// in the struct that stores the bomb item.
// Now, if our action item has a Bombitem > 255, that value is read from UINT16 ubGunShotsLeft in OBJECT_GUN.
// In the OBJECTTYPE::data union, OBJECT_GUN and OBJECT_BOMBS_AND_OTHER both have the UINT16 that stores the usBombItem or ubGunShotsLeft at the same position. So until here it is ok...
// However, this value now gets written into ugYucky.ubGunShotsLeft - which is an UINT8 instead of UINT16. This means that any item number > 255 is cut down.
// This error seems to have always been here (13 years). It just never occured until now.
// An easy fix would be to just switch the positions of UINT8ubGunShotsLeft and UINT16 usGunAmmoItem. However we cannot do that, as that will affect every object read ever anywhere.
//
// For this reason, I now present you this filthy, ugly hack, specifically for action items handle bombs:
if ( src.usItem == ACTION_ITEM && src.ugYucky.bActionValue == ACTION_ITEM_BLOW_UP )
{
(*this)[0]->data.misc.bDetonatorType = src.ugYucky.bDetonatorType;
(*this)[0]->data.misc.usBombItem = src.ugYucky.usBombItem;
(*this)[0]->data.misc.bDelay = src.ugYucky.bDelay; // includes bFrequency
(*this)[0]->data.misc.ubBombOwner = src.ugYucky.ubBombOwner;
(*this)[0]->data.misc.bActionValue = src.ugYucky.bActionValue;
(*this)[0]->data.misc.ubTolerance = src.ugYucky.ubTolerance; // includes ubLocationID
(*this)[0]->data.ubWireNetworkFlag = TRIPWIRE_NETWORK_OWNER_ENEMY; // it is always assumed that preplated traps are of hostile origin
// if the item has any tripwire action item flags, use them, otherwise, use default values
if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_TRIPWIRE_ANY )
{
if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_TRIPWIRE_NETWORK_NET_1 )
(*this)[0]->data.ubWireNetworkFlag |= TRIPWIRE_NETWORK_NET_1;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_TRIPWIRE_NETWORK_NET_2 )
(*this)[0]->data.ubWireNetworkFlag |= TRIPWIRE_NETWORK_NET_2;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_TRIPWIRE_NETWORK_NET_3 )
(*this)[0]->data.ubWireNetworkFlag |= TRIPWIRE_NETWORK_NET_3;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_TRIPWIRE_NETWORK_NET_4 )
(*this)[0]->data.ubWireNetworkFlag |= TRIPWIRE_NETWORK_NET_4;
if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_TRIPWIRE_NETWORK_LVL_1 )
(*this)[0]->data.ubWireNetworkFlag |= TRIPWIRE_NETWORK_LVL_1;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_TRIPWIRE_NETWORK_LVL_2 )
(*this)[0]->data.ubWireNetworkFlag |= TRIPWIRE_NETWORK_LVL_2;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_TRIPWIRE_NETWORK_LVL_3 )
(*this)[0]->data.ubWireNetworkFlag |= TRIPWIRE_NETWORK_LVL_3;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_TRIPWIRE_NETWORK_LVL_4 )
(*this)[0]->data.ubWireNetworkFlag |= TRIPWIRE_NETWORK_LVL_4;
}
else
(*this)[0]->data.ubWireNetworkFlag |= (TRIPWIRE_NETWORK_NET_1|TRIPWIRE_NETWORK_LVL_1);
// if the item has any directional action item flag, use them, otherwise, direction does not matter
if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_DIRECTION_ANY )
{
if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_DIRECTION_NORTH )
(*this)[0]->data.ubDirection = NORTH;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_DIRECTION_NORTHEAST )
(*this)[0]->data.ubDirection = NORTHEAST;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_DIRECTION_EAST )
(*this)[0]->data.ubDirection = EAST;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_DIRECTION_SOUTHEAST )
(*this)[0]->data.ubDirection = SOUTHEAST;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_DIRECTION_SOUTH )
(*this)[0]->data.ubDirection = SOUTH;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_DIRECTION_SOUTHWEST )
(*this)[0]->data.ubDirection = SOUTHWEST;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_DIRECTION_WEST )
(*this)[0]->data.ubDirection = WEST;
else if ( Item[src.ugYucky.usBombItem].usActionItemFlag & ITEM_DIRECTION_NORTHWEST )
(*this)[0]->data.ubDirection = NORTHWEST;
}
else
(*this)[0]->data.ubDirection = DIRECTION_IRRELEVANT;
(*this)[0]->data.bDefuseFrequency = 0;
}
(*this)[0]->data.bTrap = src.bTrap; // 1-10 exp_lvl to detect
(*this)[0]->data.ubImprintID = src.ubImprintID; // ID of merc that item is imprinted on
(*this)[0]->data.fUsed = src.fUsed; // flags for whether the item is used or not