Jump to content

R&D Inventory, Items & Weapons Overhaul


anUser

Recommended Posts

Ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh!!!!!!!!!!!!

 

Sometimes I think those programmers at Firaxis are real jerks :confused:

 

As written above, smoke grenades are not equippable. And why are they not equippable? Someone apparently decided it would be good to hard-code in smoke grenades specifically to be non-equippable, via:

if(iItem == 86)
{
}
// End:0x46F

else

 

This means my clean "only needs hex change in one place" mod now requires another change in the strategy game :(

 

The following small hex change to XcomStrategyGame.upk >> XGFacility_Lockers.GetLockerItems:

before:

 

16 25 16 07 7E 03 9A 00 06 2D 00 00 2C 56 16 06 6F 04 07 AF 03
after:
16 25 16 07 7E 03 9A 00 06 2D 00 00 2C C3 16 06 6F 04 07 AF 03

 

will change the conditional to:

if(iItem == 195)
{
}
// End:0x46F
else

 

(195 = eItem_MAX in case you are curious)

 

Sigh ...

Link to comment
Share on other sites

  • Replies 129
  • Created
  • Last Reply

Top Posters In This Topic

Sigh ... I found another glitch. I guess I should do more testing before posting.

 

Apparently granting a soldier a perk in the tactical game applies it permanently. I had intended to give the soldier temporary access to the perk in order to use the equipped item, but somehow the information is getting back to the strategy game and is being made a permanent part of the soldier's profile. This is not at all what I had intended.

 

Back to it, I suppose.

 

---------------------------------

 

Oh, the irony. AnUser has been struggling because he can't get the "item used" information back from the tactical to the strategy game.

 

I've discovered that the entire TCharacter data structure is copied from each XGUnit into the DropShipCargo in the StrategyGameTransport, and from there is copied into the XGStrategySoldier's TCharacter data member. The TCharacter structure is where the m_aAbilities array (which holds the perks) is stored.

 

I can't just turn off the TCharacter copy though .... whole bunch of necessary information is in there:

 

 

struct native TCharacter
{
var string strName;
var int iType;
var TInventory kInventory;
var int aUpgrades[111];
var int aAbilities[89];
var int aProperties[14];
var int aStats[19];
var int aTraversals[15];
var XGTacticalGameCoreData.ESoldierClass eClass;
var bool bHasPsiGift;
The most critical one is the stats, of which HP is clearly pretty important to get back to the strategy game. So I'm stuck on the other side ... info is being sent back to the strategy game that I DON'T want.
Edited by Amineri
Link to comment
Share on other sites

I have to say you've done a great work here. My concern about your approach was removing the perk after the mission, too, but now I cannot think of any undesired effect it may cause having those perks permanently, in the end that is what I did in a first instance, but just giving them the perk once.. but what if they have smoke grenade several times? For politeness that could be checked, especially if they appear several times, which i doubt, but in anycase, the only real implication would be that soldiers would be granted certain perks upon equipping certain items, as opposed to selecting that perk upon leveling. Since item charges are set according to equipped items having the ability per se means nothing. The only issue is those abilities will be displayed and given a number as available actions, even when out of charges from the beggining.

I missed that lockers check, i had actualy cannibalized another item before knowing we coul add extra items and now that I can build pretty smoke grenades I couldnt equip them... not any more, thanks to you.

 

Regarding inventory expansion and micromanagement issues... I get your point, but giving free items to soldiers and devoting more perks to item management goes quite in the opposite direction of what I intended. My motto here is everything has it's cost, either in terms of resources as in terms of oportunity cost, ie equipping something instead of someting else. And a side effect of this was that it fred several perks from trees so there are more possible choices. I have discarded many default skills like dense smoke and combat drugs, and if inventory can be expanded the ide is to remove entirely all item related perks from level up choices (no field medic, grenadier, etc). You want 4 grenaes, equip them, but forget about armor vest, scope, grapple, invisibility module (mind shield), grenade launcher module, and more yet to be created. Honestly I never thought of having to equip the second item as a nuissance until you guys said that. I guess i'll just have to play for a while with 3 item slots or so and see how tedious it gets. Maybe an auto equip function could solve that, as dubiousintent suggested, but I've got no idea how feasible that would be to implement, neither how desirable that would be considering there coul be a limited amount of each item. So in any case it should auto equip the extra items on selecting the unit for a mission... but then there should be as well a call to releaseLoadout or whatever that clears soldiers claim on iems when clearing soldier to pick another one

 

Hey, that soldiers' full copy going over tactical and strategy game is great news. I guess that's why in UpdateItemCharges it says SET charges, not increase... I will give a look at it, the problem now I guess it will be finding a function to re use to remove the items, and the more items we add the longer the function we'll need, right now it's just frag and alien grenades, medikits, battlescanner and smoke grenades, but it would be nice to find good space for extra items, such as rockets and ammo, and damaged armor or armor vests

 

Now it's just a random thought, considering expanding this circumpstancial perk trick to armor and weapons. Lightning reflexes and Run and gun on heavy armor? maybe not anymore, or making chitingnplating or titan armor grants resilience, etc. Some weapons having rapid fire (shotguns) or rather a new ability that would deplete both cannons, so no aim penalty, 1 shot, double damage, double ammo cost, and many more that we may come up wih. In this case we'd def need a way to remove perks after battle, since those arent related to num of charges.

Link to comment
Share on other sites

Oh, well the issue with the perk setting being permanent is the following.

 

In my intended design, a soldier without the Smoke Grenade perk that equips one Smoke Grenade item should have 1 charge. This is what occurs on the first mission.

 

However, on SUBSEQUENT missions, because the soldier retained the Smoke Grenade perk, if she had one Smoke Grenade item equipped she would have 3 charges.

 

As to the micromanagement vs choice/consequences issue -- I guess it's just difference in preference. I still feel like there are choices and consequences being made -- the choice of one perk (to carry the extra items) precludes choosing another perk. Thus the consequences of the choices are much longer term than one mission. Both styles are certainly valid -- I hope you didn't feel like I was impugning your design :)

 

I guess I just figured that I'd try and roll with the perks as they are, but expand around them with equipable items (particularly since adding more than 3 small item slots is going to be quite a challenge). I might look at the Actionscipt code at some poin and see if some of the UI spacing can be tightened up a bit to get the 3rd item squeezed in there.

 

--------------------------------------

 

Unfortunately it's not quite a full copy of EVERYTHING that is being passed back and forth through the StrategyGameTransport.

 

The full XGItem class contains a field bool m_bDamaged which would be ideal for carrying back information about item state. Consumables could be marked if used ... or armor could be marked if too much damage taken, for example. However, the kInventory structure that is passed between tactical and strategy only contains the item IDs.

 

 

 

struct native TInventory
{
var int iArmor;
var int iPistol;
var const int arrLargeItems[16];
var const int iNumLargeItems;
var const int arrSmallItems[16];
var const int iNumSmallItems;
var const int arrCustomItems[16];
var const int iNumCustomItems;

 

The current design is that items are not removed from the strategy game STORAGE() when assigned to soldiers -- they are merely marked as 'claimed'. Thus the full inventory information is sent back from tactical to strategy in order to perform garbage collection. What you may find interesting is that the inventory could be very large -- up to 50 items in total.

 

--------------------------------------------------------------------

 

I think I've found the right place to prevent the perk information from being passed back to the strategy game. Once again it's an issue of trying to free up enough bytes. The call sequence goes:

1) XGStrategy.PostCombat, which calls

2) XGShip_DropShip.ReconstructTransferData, which calls

3) XGStrategySoldier.RebuildAfterCombat

 

 

function RebuildAfterCombat(TTransferSoldier kTransfer)
{
m_kChar = kTransfer.kChar;
m_kSoldier = kTransfer.kSoldier;
m_aStatModifiers[0] = kTransfer.iHPAfterCombat - GetMaxStat(0);
m_bMIA = kTransfer.bLeftBehind;
}
is where the soldier data is transferred from the StrategyGameTransport structure to the XGStrategySoldier data structure. The m_kChar is of type TCharacter, while m_kSoldier is of type TSoldier. TSoldier contains things like XP, PsiXP, Number of kills, as well as cosmetic settings for the soldier (hair style, etc).
The only info really that has to be transfered in the TCharacter is the aStats line. I -think- it would work if the first line could be replaced by m_kChar.aStats = kTransfer.kChar.aStats. My issue is that the function is so tiny that finding the space is a serious challenge.
----------------------------------------------------------------------
For most items that give perks, my plan is to set the perk when the item is loaded, in the strategy game. The XGStrategySoldier.aUpgrades[iPerk] entry can be incremented and decremented when the item is equipped and unequipped. This would work perfectly with your design to limit the number of charges based upon actual items equipped (as would permanently setting the perk).
However, with my admittedly more ambitious attempt to combine charges from both the perks and the items equipped this won't work.
It would work perfectly for perks like Rapid Fire guns, Low Profile Armor, Lightning Reflexes armor, Bullet Swarm guns, etc, etc. It will also work great for my planned SHIV accessories.
If I can figure out how to prevent perks from flowing back, you could also specially code certain items to inhibit particular perks, as you suggested.
Link to comment
Share on other sites

Regarding where the item charges come from, either only from equipped items or as well from perks, I think both approaches are valid, you might have noticed I'm pushing things here to make it all very dependant on item purchasing, and sort of resources management, kinda I want to try the extreme version before finding the nice point in between.

 

As for the technical issues of your implementation, I don't see them. If your mod consistently increases the perk count in 1 for each of those items when equipped and decreases it later by 1 when unequipped, having the perk beforehand will only make it so that perk count never reaches 0 when unequipping. This would require a small change to the function, first setting the perks according to equipped items, and then giving the charges based solely on perks count. So a soldier with no perks, equips a smoke grenade, then it gets 1 smoke grenade perk, then 1 smoke gren charge. A soldier with smoke grenade perk equips 1 smoke grenade, first it gets 1 smoke grenade perk (one more, so 2 now), ergo it gets 2 smoke gren charges. Otherwise you could spare the action-granting perks from perk trees (such as smoke grenade), and re-use other perks (like Smoke and Mirrors) to give free items. The pity there aren't many perks, but there shouldn't be any problem in cannibalizing one of those unused perks, change the display icon and text, and use them for granting extra items.

 

 

Regarding consumible items, it's not enough to have access to units' inventory. Relevant data is stored in this variables, defined in CheckpointRecord struct, under XGUnitNativeBase.

 

    var int m_iMediKitCharges;
    var int m_iShredderRockets;
    var int m_iRockets;
    var int m_iGhostCharges;
    var int m_iSmokeGrenades;
    var int m_iBattleScanners;
(...)
    var int m_iArcThrowerCharges;
    var int m_iFragGrenades;
    var int m_iAlienGrenades;

Unfortunately that's still somehow obscure to me, and actualy I don't know if this information is still present back in the strategy game, and if so where it could be or how it could be accessed.

 

I'm aware the way the game treats storage and soldier's claim on items. So far I've completely disabled the InfiniteItems array (just tweaking the IsInfinite function to return always false), and I found the way to remove items on mission ending, calling a reworked and previously unused function ReleseSmallItems, which releaseItem (releases soldier's claim), and removeItem (actualy removes it from storage), and just in case I set TACTICAL().TInventorySmallItemsSetItem to 0 for that inventory slot, which empties it, or so it seems to do. So as for removing the items upon mission ending it has been done and tested, so the concern now is getting those variables in strategy game, and getting enough space to script the many checks we'll need to balance multiple charges items and perk-given items.

 

OR in case those aren't available, since now we know soldier's inventory is available during tactical game, we could remove the items during the tactical game on the fly as relevant abilities are used. If we could sneak a call to a custom function every time an ability is used, we could use that custom function to remove items from inventory depending on the ability used, as well as decreasing those "charges" variables (m_iFragGrenades, etc). This way we could avoid post-mission tricky checks for item charges and remaining items in the inventory, etc. We should only check the soldier's got the item before removing it. If it hasn't got the item it is to assume that was a perk free item.

Link to comment
Share on other sites

As for the technical issues of your implementation, I don't see them. If your mod consistently increases the perk count in 1 for each of those items when equipped and decreases it later by 1 when unequipped, having the perk beforehand will only make it so that perk count never reaches 0 when unequipping. This would require a small change to the function, first setting the perks according to equipped items, and then giving the charges based solely on perks count. So a soldier with no perks, equips a smoke grenade, then it gets 1 smoke grenade perk, then 1 smoke gren charge. A soldier with smoke grenade perk equips 1 smoke grenade, first it gets 1 smoke grenade perk (one more, so 2 now), ergo it gets 2 smoke gren charges. Otherwise you could spare the action-granting perks from perk trees (such as smoke grenade), and re-use other perks (like Smoke and Mirrors) to give free items. The pity there aren't many perks, but there shouldn't be any problem in cannibalizing one of those unused perks, change the display icon and text, and use them for granting extra items.

 

Well, the perk count actually never goes above 1. The function GivePerk actually does the following :

if(m_kChar.aUpgrades[iPerk] <= 0)

{
++ m_kChar.aUpgrades[iPerk];
}
So, the value in aUpgrades[iPerk] never goes above one. Even though it is an array of integers, it is being used as an array of booleans.
The issue I'd been having was trying to distinguish between the following three cases:
1) Soldier does not have perk that grants items, but has manually equipped one or more items
2) Soldier has perk that grants items, but has not manually equipped any items
3) Soldier has perk that grants items, AND has manually equipped one or more items
You've (anUser) totally nailed a really elegant solution. At the very least I could treat the aUpgrades array as a array of ternary values. 0 = no perk, no items, 1 = perk or item (is interpretted contextually depending on inventory), 2 = perk AND item.
As you point out, though, since aUpgrades is a full integer, it can actually hold the number of item charges directly.
This means that the calls from assigning the perk will now have to use ++ m_kChar.aUpgrades[iPerk]; directly instead of GivePerk. Otherwise, if a soldier were already had an perk-granting item equipped, the GivePerk call would fail to increment the counter, thus failing to properly implement the perk. Also, when the item was removed, the count in aUpgrades[iPerk] would go back to zero.
There will also be a side-effect to be addressed when assigning perks. Currently whether a perk is active in the perk tree is based on the value of aUpgrades[iPerk]. If an item is equipped, the game will consider that the perk has already been selected when a soldier levels up. Removing the items would allow the perk to be selected, but that's an ugly workaround.
-------------------------------------------------------------------
As a side note, when I changed m_kChar = kTransfer.kChar; to m_kChar.aStats = m_kSoldier.m_kChar.aStats; (it decompiled correctly, and ran without crashing, but ...) all of the soldiers on a mission had their stats set to zero when returning.
It was kind of funny, when the next mission started. Sight Radius for all soldier was zero, so the entire map was fog of war. Also, all soldiers had 0 aim, and only 2 health (in Long War, Kevlar grants +2 HP). So that idea didn't pan out. I'm really glad anUser saw a better solution.
As a side benefit, this opens up the option to actually give perks to soldiers as mission rewards or for completing certain objectives within missions. Since setting the perk in the tactical game permanently gives that soldier the perk, this could be a way to give soldiers more than the 7 perks assignable in the Barracks Ability perk tree.
For example, surviving a mission with 1 HP left could grant the perk "Will to Survive". Just some semi-random musings.
Link to comment
Share on other sites

It seems to me the most elegant solution regarding item-related perks would be: 1) Make perks could be selected multiple times; and 2) use the m_kChar.aUpgrades[iPerk] value as the number of charges.

This way soldiers could select the Smoke Grenade perk while having a smoke grenade item already equipped, and both tree perks and item perks would sum towards the same value. I guess though that would require changing the way perks are assigned on selection, if there's enough space to replace each GivePerk(x) for a m_kChar.aUpgrades[x]+=1 that would be an optimal solution imo.

 

It just occurred to me that if perk count is decreased on item unequipping, then it should be scripted manually for consumible items as well... :( If not using tree perks' free items then those perks could be safely reset to 0 at mission ending...

Link to comment
Share on other sites

We're thinking in parallel lines here, which is encouraging to me.

 

Unfortunately, the current "perk selection" UI code bases everything on whether the soldier currently has a perk. For example, when a soldier hits corporal, and the player selects the Abilities option in order to select the new perk granted, the code decides whether or not ANY perk can be selected based on whether one of the corporal-level perks is already active for the soldier.

 

This also prevents placing a perk in the tree multiple times. For example, say you wanted to give Bullet Swarm as an option at both Corporal and Lieutenant. If the player chose Bullet Swarm at Corporal, then the current design actually prevents the player from chosing another perk at Lieutenant (because a Lieutenant perk (Bullet Swarm) has already been "chosen").

 

I'm working on a fix for this, to more explicitly store which level's perks have been chosen and which have not. (I'm also going to peek at the actionscript code to see if I can unlock selection of up to three perks per level). This would allow selection of a perk at a level "even if the soldier already has a perk at that level". Unfortunately, it still leaves open a small flaw. If the code allows selecting a perk when the soldier already has the same perk, then putting in multiple opportunities to select a perk could allow the player to select the same perk multiple times -- potentially to no benefit. I suppose that sort of flaw is acceptable, though.

 

First I have to see if I can actually get the changes in and working. I think I finally managed to squeeze out enough bytes for the new code. Just have to finish writing the new hex and then lots and lots of testing.

Link to comment
Share on other sites

Unfortunately, the current "perk selection" UI code bases everything on whether the soldier currently has a perk. For example, when a soldier hits corporal, and the player selects the Abilities option in order to select the new perk granted, the code decides whether or not ANY perk can be selected based on whether one of the corporal-level perks is already active for the soldier.

 

This also prevents placing a perk in the tree multiple times. For example, say you wanted to give Bullet Swarm as an option at both Corporal and Lieutenant. If the player chose Bullet Swarm at Corporal, then the current design actually prevents the player from chosing another perk at Lieutenant (because a Lieutenant perk (Bullet Swarm) has already been "chosen").

Maybe I didn't explain myself very well... that's what I meant when I said making perks can be selected multiple times, first, removing the check that discards already picked perks, and second, giving sense to multiple occurrences of the same perk (of course some will still apply once, so modders must take care not placing a redundant perk when customizing trees, for the rest it should be safe to go with).

I'm working on a fix for this, to more explicitly store which level's perks have been chosen and which have not. (I'm also going to peek at the actionscript code to see if I can unlock selection of up to three perks per level). This would allow selection of a perk at a level "even if the soldier already has a perk at that level". Unfortunately, it still leaves open a small flaw. If the code allows selecting a perk when the soldier already has the same perk, then putting in multiple opportunities to select a perk could allow the player to select the same perk multiple times -- potentially to no benefit. I suppose that sort of flaw is acceptable, though.

 

First I have to see if I can actually get the changes in and working. I think I finally managed to squeeze out enough bytes for the new code. Just have to finish writing the new hex and then lots and lots of testing.

What I'm saying is there's no need to keep track of what perk was selected and what was granted by items, we should just take care that equipping certain items always grants +1 to certain perk, and unequipping or spending that item always removes -1 of that perk.

 

oh well, it has the problem that it would grant the same amount of charges either choosing the perk or equipping an item, so no distinction could be made here... I'm not saying you should use my approach, which is clearly inferior, I'm just saying that in case you didn't get it and wanted to save the extra work of tracking choosen perks sepparatedly this seems to be functional enough.

Edited by anUser
Link to comment
Share on other sites

Maybe I didn't explain myself very well... that's what I meant when I said making perks can be selected multiple times, first, removing the check that discards already picked perks, and second, giving sense to multiple occurrences of the same perk (of course some will still apply once, so modders must take care not placing a redundant perk when customizing trees, for the rest it should be safe to go with).

 

 

 

 

It's also possible that I didn't understand, hence the continuing dialogue -- a good thing!

 

I'm pretty sure that simply removing the check that prevents selecting of the perk would have the following side effect : the player would be able to select all perks listed in the perk tree, not just 1 per soldier level. A soldier having the one perk option is what prevents the selection of the other perk option -- that's how the game-logic determines whether a particular "column" can have a perk choice made.

 

If you take an existing level 7 colonel, with perks all selected, and then modify the perk tree so that a level offers two options that weren't available before, then load the save game, the soldier can now make a new perk selection.

 

The whole level-up process is highly convolved with what perks a soldier already has, which is what makes this thing such a huge mess to try and figure out.

 

------------------------------------------------

 

I apologize for dragging this away from the main topic -- equipment R&D. However, some perks effectively grant access to additional equipment, so I guess it's not COMPLETELY off topic.

 

That said, I've got the Actionscript files from JL, and it's on my to-do list to look at the loadout screen UI. At the very least I'm hopeful that the margins and such can be trimmed down a bit to allow the third small item slot to be utilized. In the best case, a scroll bar (like in the right-hand window) could be added, allowing effectively unlimited equipment choices to be made.

 

If that is opened up, then the field is pretty wide-open. There is room to create ~30 new items in BuildItems(), although there is likely a shortage of image graphics . JL and I discovered that there doesn't appear to be a SHIV Plasma graphic -- the Interceptor Plasma graphic had to be re-used for Long War.

 

I think the Large and Small Items arrays are hard-coded to 22 items -- not much of a limit. However, only 1 armor and 1 pistol are allowed.

Edited by Amineri
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...