Jump to content

Combined mod


Tycus

Recommended Posts

Amneri said, "There is a bit of a gap on the wiki between making simple value hex edits and more significant code changes, but I haven't figured out how to structure a tutorial. I've been working with Zybertryx to try to explain some of the fundamentals, so I'm hoping that he'll take the materials I sent him and put together a wiki tutorial while the learning process is still fresh in his mind (*hint hint* :wink: )."

 

And I will as soon as I'm able to make new changes beyond single byte replacements myself that don't break vital functions or crash the game (everytime) :(

 

There's a lot to soak in, your basic work flow system of breaking down an entire function into its discrete hex blocks which correspond exactly to the different lines in the decompiled code is a very important bridge between simple hex-side integer replacements and the "WTF" of the rest of it though. The more one does this, the more one sees patterns and the more easily one is able to isolate the beginning and end of different calls (lines/sub-functions) with in a function. I have this down now, it's just that splicing X into Y where X previously didn't exist usually results in my breaking Y . . .

 

@ Tycus,

 

Differing difficulty levels is a small price to pay for such an amazing control over alien stats. You also said that "damage reduction" is meaningless without "perks" to "go along with it". I don't understand this at all. What is a perk but a function which modifies a general mechanic specific to the unit which has it? The Aliens Upgrade modlet does exactly that on a per-species basis. Damage Reduction via the DGC is a "perk" for all practical purposes, as is Regeneration via the same method etc.

Link to comment
Share on other sites

@ Tycus,

 

Differing difficulty levels is a small price to pay for such an amazing control over alien stats. You also said that "damage reduction" is meaningless without "perks" to "go along with it". I don't understand this at all. What is a perk but a function which modifies a general mechanic specific to the unit which has it? The Aliens Upgrade modlet does exactly that on a per-species basis. Damage Reduction via the DGC is a "perk" for all practical purposes, as is Regeneration via the same method etc.

No, no, you got it all wrong. What I mean I have compiled list of perks (passive perks taken from XCOM soldiers) for aliens, and Damage Reduction should have been just one more in line of them. And no, I was not referring to difficulty levels as a feature (more likely replicated bug) of my mod (was really small feature anyway: basically, what it does, its when new chryssalid spawns from zombie, it stats would be taken from different difficulty level, so I made newborn chryssalids a bit weaker but faster, than "regular" chryssalids; also it will look differently for some reason; same was happening with thinmen, that are dropping from sky in council missions, but only if you loaded mid-mission from save; vanilla bug).

 

 

 

 

Define "standart". And why not just use that code? I mean, I recall reading about that, and it seemed perfectly suited to do what I need.

 

By "standard" I mean that every alien on the map will have the same stats.

 

The original dynamic alien progression modlet hooks into the difficulty code to change the root characters from which all units draw their stats.

 

The dynamic progression certainly works well. Sorry if I'm throwing too many different options at you :smile:

Why do you keep mixing up my response, people? I was refering for perk-as-items code, not about dynamic alien progression.

 

 

I've been thinking about releasing an update that allows for adjustments for all difficulties as well as variable number of upgrades per alien (and more than 2). However, this requires stable installers that can force the game to load the DefaultGameCore.ini from the file instead of from the Resource Cache.

 

I'm pretty sure that dubiousintent and Yzaxtol got that working, but until it becomes "common practice" there's not much use in building a mod that depends on it.

 

Yes, I was not happy at losing diffuclty options as well, but the main problem in forcing game to load the DefaultGameCore.ini lies in increased mission load times (which would suck), so I redesigned my mod in a way that such radical changes wasn't needed at all.

 

I think I'm stuck with XGUnit.DebugAnims option to add perks for aliens (btw, is there any limit on how much perks can be granted to single alien type by this method?). Some step-by-step instruction also would be nice (so I would not accidentally mess up).

 

Here is the list (would love some feedback on that perk composition as well):

 

Sectoid: Low Profile,

Thinmen: Lightning Reflexes, Opportunist, **

Floater: Damn Good Ground, Aggression, Low Profile

Heavy Floater: Damn Good Ground, Aggression, Low Profile, Hardened(s), Vengeance(iq) *

Muton: Covering Fire, Tactical Sense, ***

Muton Elite: Covering Fire, Tactical Sense, Will to survive, Hardened(s), Mayhem(iq), *, ***

Muton Berserker: Tactical Sense(q*), Resilience (s)

Cyberdisc: Squadsight(iq), Damn Good Ground, Dangerzone, Mayhem(iq), *, ***

Drone: Holo-target (iq), Damn Good Ground, Low Profile (do they even use cover, like ever?)

Sectopod: ???, *

Chryssalid: Lightning Reflexes

Outsider: Lightning Reflexes, Close Combat Specialist(q*), Bring Em On(q*), *

Sectoid Commander: Low Profile

Ethereal: ???

 

*Rapid Reaction (and/or Opportunist)//Sentinel for those aliens may be redundant

**Thimen are special case, since they are dropped in overwatch state on council missions

***Grenadier perk may be redundant, if number of grenades on aliens can be adjusted manually (can it?; i do remember reading something about that)

(s) marks are for consequential/simultaneous upgrades (by upgrade I mean option, not actuall in-game upgrade)

(iq) = in question, perks are being tested/not working (my primary concern for unappliable perks; that marks them for priority in testing; can anyone drop any hints about those?)

??? - no ideas (what to give them, that is)

(q*) - questionable ideas, may be unfluffy (those most likely be revisioned, if they contradict lore too much)

 

On subject of learning of rescripting:

 

There is a bit of a gap on the wiki between making simple value hex edits and more significant code changes, but I haven't figured out how to structure a tutorial. I've been working with Zybertryx to try to explain some of the fundamentals, so I'm hoping that he'll take the materials I sent him and put together a wiki tutorial while the learning process is still fresh in his mind (*hint hint* :wink: ).

I am sadly aware of it, and judging by his response it looks like tough luck for me.

Edited by Tycus
Link to comment
Share on other sites

Wow, lots of replies in this topic recently.//Surprise, surprise...

Anyway...
UPDATE:
While my progress on a mod has been put on backburner for a while (mostly due to RL reasons), I am happy to inform you all, that my mod steadily closes in for open beta test status, as I am adding much needed features to it, most recent being me finally being able to add perks for aliens (thanks to Amineri, who was awesome as always and shared workable code with me with for that).
Here it is for anyone interested:

Ok, following original Amineri's code:
1. Need to modify XGUnit.Init function to hook up DebugAnims

[Find]
40 B0 00 00 50 55 00 00 00 00 00 00 25 B0 00 00 13 32 00 00 00 00 00 00 2B B0 00 00 00 00 00 00 7D 05 00 00 01 BF 00 00 4F 02 00 00 BF 01 00 00 49 02 00 28 15 49 02 00 27 15 1C 13 32 00 00 00 2B B0 00 00 00 2A B0 00 00 00 29 B0 00 00 2D 00 28 B0 00 00 4A 16 0F 01 62 AF 00 00 01 ED F9 FF FF 0F 01 0A 31 00 00 00 2A B0 00 00 19 01 0A 31 00 00 0A 00 00 00 00 00 00 1B F3 3A 00 00 00 00 00 00 16 1B 5C 02 00 00 00 00 00 00 35 CE 0D 00 00 D5 0D 00 00 00 00 19 01 0A 31 00 00 09 00 C3 A2 00 00 00 01 C3 A2 00 00 4A 16 0F 01 63 AF 00 00 00 2B B0 00 00 1B E8 5D 00 00 00 00 00 00 16 1B D5 5D 00 00 00 00 00 00 16 1B DE 5D 00 00 00 00 00 00 16 1B E6 5D 00 00 00 00 00 00 16 14 2D 01 89 AF 00 00 19 01 0A 31 00 00 0A 00 B7 A2 00 00 00 2D 01 B7 A2 00 00 1B 20 62 00 00 00 00 00 00 24 00 16 1B 9E 66 00 00 00 00 00 00 2D 00 27 B0 00 00 4A 16 07 52 01 72 01 09 31 00 00 2A 16 04 28 07 6E 01 2D 00 28 B0 00 00 07 6E 01 1B E1 19 00 00 00 00 00 00 16 04 28 19 00 29 B0 00 00 15 00 00 00 00 00 00 1B 75 02 00 00 00 00 00 00 17 2D 01 F1 30 00 00 16 07 B2 01 1B C6 3C 00 00 00 00 00 00 16 1B 5B 3A 00 00 00 00 00 00 16 06 BF 01 07 BF 01 1B 82 3D 00 00 00 00 00 00 16 07 03 02 9A 35 D3 0D 00 00 D5 0D 00 00 00 00 19 01 0A 31 00 00 09 00 C3 A2 00 00 00 01 C3 A2 00 00 2C 0E 16 14 2D 01 EF 30 00 00 27 1B 2F 63 00 00 00 00 00 00 4A 16 1B BC 61 00 00 00 00 00 00 24 00 16 1B 6E 13 00 00 00 00 00 00 16 1B F1 01 00 00 00 00 00 00 16 0F 01 68 AF 00 00 1B 2F 35 00 00 00 00 00 00 16 04 27 04 3A 26 B0 00 00 53

[Replace]
40 B0 00 00 50 55 00 00 00 00 00 00 25 B0 00 00 13 32 00 00 00 00 00 00 2B B0 00 00 00 00 00 00 7D 05 00 00 01 BF 00 00 53 02 00 00 BF 01 00 00 49 02 00 28 15 49 02 00 27 15 1C 13 32 00 00 00 2B B0 00 00 00 2A B0 00 00 00 29 B0 00 00 2D 00 28 B0 00 00 4A 16 0F 01 62 AF 00 00 01 ED F9 FF FF 0F 01 0A 31 00 00 00 2A B0 00 00 19 01 0A 31 00 00 0A 00 00 00 00 00 00 1B F3 3A 00 00 00 00 00 00 16 1B 5C 02 00 00 00 00 00 00 35 CE 0D 00 00 D5 0D 00 00 00 00 19 01 0A 31 00 00 09 00 C3 A2 00 00 00 01 C3 A2 00 00 4A 16 0F 01 63 AF 00 00 00 2B B0 00 00 1B E8 5D 00 00 00 00 00 00 16 1B D5 5D 00 00 00 00 00 00 16 1B DE 5D 00 00 00 00 00 00 16 1B E6 5D 00 00 00 00 00 00 16 14 2D 01 89 AF 00 00 19 01 0A 31 00 00 0A 00 B7 A2 00 00 00 2D 01 B7 A2 00 00 1B 20 62 00 00 00 00 00 00 24 00 16 1B 9E 66 00 00 00 00 00 00 2D 00 27 B0 00 00 4A 16 07 52 01 72 01 09 31 00 00 2A 16 04 28 07 6E 01 2D 00 28 B0 00 00 07 6E 01 1B E1 19 00 00 00 00 00 00 16 04 28 19 00 29 B0 00 00 15 00 00 00 00 00 00 1B 75 02 00 00 00 00 00 00 17 2D 01 F1 30 00 00 16 07 CD 01 1B C6 3C 00 00 00 00 00 00 16 1B 5B 3A 00 00 00 00 00 00 16 1B 91 14 00 00 00 00 00 00 00 2B B0 00 00 00 2B B0 00 00 16 0B 0B 07 11 02 9A 35 D3 0D 00 00 D5 0D 00 00 00 00 19 01 0A 31 00 00 09 00 C3 A2 00 00 00 01 C3 A2 00 00 2C 0E 16 14 2D 01 EF 30 00 00 27 1B 2F 63 00 00 00 00 00 00 4A 16 1B BC 61 00 00 00 00 00 00 24 00 16 1B 6E 13 00 00 00 00 00 00 16 1B F1 01 00 00 00 00 00 00 16 0F 01 68 AF 00 00 1B 2F 35 00 00 00 00 00 00 16 04 27 53

2. Here comes somewhat difficult (and a bit tedious) part:

- Compile list of perks for aliens

Example:

Sectoid: Low Profile,
Thinmen: Lightning Reflexes, Opportunist, Rapid Reaction
Floater: Damn Good Ground, Aggression, Low Profile
Heavy Floater: Damn Good Ground, Aggression, Low Profile, Rapid Reaction, Opportunist
Muton: Covering Fire, Tactical Sense, Grenadier
Muton Elite: Covering Fire, Tactical Sense, Will to survive, Mayhem, Rapid Reaction, Opportunist, Grenadier
Muton Berserker: Tactical Sense, Resilience
Cyberdisc: Squadsight, Damn Good Ground, Dangerzone, Mayhem, Opportunist, Sentinel, Grenadier
Drone: Holo-target, Damn Good Ground, Low Profile
Sectopod: Sentinel
Chryssalid: Lightning Reflexes
Outsider: Lightning Reflexes, Close Combat Specialist, Rapid Reaction
Sectoid Commander: Low Profile

- Use next list to find out codes of perks available:

05 = 0x05 -- Low Profile
10 = 0x0A -- Opportunist
15 = 0x0F -- Damn Good Ground
17 = 0x11 -- Will to Survive
19 = 0x13 -- Holo Targeting
23 = 0x17 -- Rapid Reaction
25 = 0x19 -- Danger Zone
32 = 0x20 -- Aggression
33 = 0x21 -- Tactical Sense
34 = 0x22 -- Close and Personal
35 = 0x23 -- Lightning Reflexes
39 = 0x27 -- Bring 'Em On
40 = 0x28 -- Close Combat Specialist
43 = 0x2B -- Resilience
47 = 0x2F -- Covering Fire
54 = 0x36 -- Sentinel
91 = 0x5B -- HEAT Ammo
94 = 0x5E -- Mayhem

24 = 0x18 -- Greanadier (not confirmed if works)
42 = 0x2A -- Vengeance
30 = 0x1E -- Ready for anything

- Now we need list of pawntypes to get alien types, which would have perks granted:

28 = 1C = ePawnType_Sectoid,
29 = 1D = ePawnType_Sectoid_Commander,
30 = 1E = ePawnType_Floater,
31 = 1F = ePawnType_Floater_Heavy,
32 = 20 = ePawnType_Muton,
33 = 21 = ePawnType_Muton_Elite,
34 = 22 = ePawnType_Muton_Berserker,
35 = 23 = ePawnType_ThinMan,
36 = 24 = ePawnType_Elder,
37 = 25 = ePawnType_CyberDisc,
38 = 26 = ePawnType_Reaper,
39 = 27 = ePawnType_Chryssalid,
40 = 28 = ePawnType_Sectopod,
41 = 29 = ePawnType_SectopodDrone,
42 = 2A = ePawnType_Zombie,
43 = 2B = ePawnType_Outsider,
44 = 2C = ePawnType_EtherealUber

- Time to modify some code:

Example code:
// Sectoid given Low Profile
(Offset == 28 ? m_kCharacter.GivePerk(5) : nothing) (40 bytes perk added) + 12 = 0xC virtual bytes per call
45 9A 00 97 B5 00 00 2C 1C 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 05 16 01 00 0B

As you can see, marked values is those that hold pawn_type and perk_code.

- Next we just can copy/paste that code (use example form to keep trace which part of your code does what) with simply putting values needed in brackets

// Sectoid given Low Profile
45 9A 00 97 B5 00 00 2C 1C 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 05 16 01 00 0B

// Sectoid Commander given Low Profile
45 9A 00 97 B5 00 00 2C 1D 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 05 16 01 00 0B

-----

// Floater given Low Profile
45 9A 00 97 B5 00 00 2C 1E 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 05 16 01 00 0B

// Floater given Damn Good Ground
45 9A 00 97 B5 00 00 2C 1E 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0F 16 01 00 0B

// Floater given Aggression
45 9A 00 97 B5 00 00 2C 1E 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 20 16 01 00 0B

-----

// Floater_Heavy given Low Profile
45 9A 00 97 B5 00 00 2C 1F 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 05 16 01 00 0B

// Floater_Heavy given Damn Good Ground
45 9A 00 97 B5 00 00 2C 1F 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0F 16 01 00 0B

// Floater_Heavy given Aggression
45 9A 00 97 B5 00 00 2C 1F 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 20 16 01 00 0B

// Floater_Heavy given Rapid Reaction
45 9A 00 97 B5 00 00 2C 1F 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 17 16 01 00 0B

// Floater_Heavy given Opportunist
45 9A 00 97 B5 00 00 2C 1F 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0A 16 01 00 0B

-----

// Muton given Covering Fire
45 9A 00 97 B5 00 00 2C 20 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 2F 16 01 00 0B

// Muton given Tactical Sense
45 9A 00 97 B5 00 00 2C 20 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 21 16 01 00 0B

// Muton given Grenadier
45 9A 00 97 B5 00 00 2C 20 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 18 16 01 00 0B

-----

// Muton_Elite given Covering Fire
45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 2F 16 01 00 0B


// Muton_Elite given Tactical Sense
45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 21 16 01 00 0B

// Muton_Elite given Grenadier
45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 18 16 01 00 0B

// Muton_Elite given Rapid Reaction
45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 17 16 01 00 0B

// Muton_Elite given Opportunist
45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0A 16 01 00 0B

// Muton_Elite given Will to Survive
45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 11 16 01 00 0B

// Muton_Elite given Mayhem
45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 5E 16 01 00 0B

-----

// Muton_Berserker given Tactical Sense
45 9A 00 97 B5 00 00 2C 22 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 21 16 01 00 0B


// Muton_Berserker given Resilience
45 9A 00 97 B5 00 00 2C 22 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 2B 16 01 00 0B

-----

// ThinMan given Lightning Reflexes
45 9A 00 97 B5 00 00 2C 23 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 23 16 01 00 0B

// ThinMan given Rapid Reaction
45 9A 00 97 B5 00 00 2C 23 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 17 16 01 00 0B

// ThinMan given Opportunist
45 9A 00 97 B5 00 00 2C 23 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0A 16 01 00 0B

-----

// CyberDisc given Squadsight
45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 03 16 01 00 0B

// CyberDisc given Damn Good Ground
45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0F 16 01 00 0B

// CyberDisc given Sentinel
45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 36 16 01 00 0B

// CyberDisc given Opportunist
45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0A 16 01 00 0B

// CyberDisc given Grenadier
45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 18 16 01 00 0B

// CyberDisc given Danger Zone
45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 19 16 01 00 0B

// CyberDisc given Mayhem
45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 5E 16 01 00 0B

------

// Chryssalid given Lightning Reflexes
45 9A 00 97 B5 00 00 2C 27 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 23 16 01 00 0B

------

// Sectopod given Sentinel
45 9A 00 97 B5 00 00 2C 28 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 36 16 01 00 0B

------

// SectopodDrone given Low Profile
45 9A 00 97 B5 00 00 2C 29 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 05 16 01 00 0B

// SectopodDrone given Damn Good Ground
45 9A 00 97 B5 00 00 2C 29 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0F 16 01 00 0B

// SectopodDrone given Holo Targeting
45 9A 00 97 B5 00 00 2C 29 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 13 16 01 00 0B

------

// Outsider given Lightning Reflexes
45 9A 00 97 B5 00 00 2C 2B 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 23 16 01 00 0B

// Outsider given Close Combat Specialist
45 9A 00 97 B5 00 00 2C 2B 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 28 16 01 00 0B

// Outsider given Rapid Reaction
45 9A 00 97 B5 00 00 2C 2B 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 17 16 01 00 0B

// Outsider given Opportunist
45 9A 00 97 B5 00 00 2C 2B 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0A 16 01 00 0B

// Outsider given Resilience
45 9A 00 97 B5 00 00 2C 2B 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 2B 16 01 00 0B

Total 39 perks granted

- After that we can assemble our replacement function (just make sure that replacement code has same size as original, otherwise bad stuff will happen):

Example code:

[Original]

{header}
B3 B5 00 00 50 55 00 00 00 00 00 00 93 B5 00 00 00 00 00 00 00 00 00 00 9E B5 00 00 00 00 00 00 FE 23 00 00 84 8D 04 00 B2 0E 00 00 02 0A 00 00

{body}
14 2D 00 99 B5 00 00 27 0F 00 98 B5 00 00 25 14 2D 00 95 B5 00 00 FE 19 00 9D B5 00 00 09 00 CD 6E 00 00 00 01 CD 6E 00 00 19 17 09 00 04 FA FF FF 00 01 04 FA FF FF 16 07 AF 0E 82 82 77 01 09 31 00 00 2A 16 18 20 00 19 00 9D B5 00 00 0A 00 FD 6E 00 00 00 2D 01 FD 6E 00 00 16 18 39 00 84 FE 19 00 9D B5 00 00 09 00 CD 6E 00 00 00 01 CD 6E 00 00 21 50 55 00 00 00 00 00 00 16 18 0B 00 2D 00 95 B5 00 00 16 16 0F 00 94 B5 00 00 19 00 9E B5 00 00 13 00 D4 F8 FF FF 00 1C 13 FC FF FF 01 DE F8 FF FF 16 19 00 9E B5 00 00 11 00 00 00 00 00 00 1C 12 FC FF FF 24 FF 24 FF 24 FF 4A 16 19 00 9E B5 00 00 4A 00 00 00 00 00 00 1C 11 FC FF FF 35 1C FD FF FF 5B F9 FF FF 00 00 00 94 B5 00 00 B8 35 1B FD FF FF 5B F9 FF FF 00 01 00 94 B5 00 00 1E 00 00 70 41 16 4A 16 19 00 9E B5 00 00 26 00 00 00 00 00 00 1C 15 FC FF FF 38 57 19 17 09 00 04 FA FF FF 00 01 04 FA FF FF 4A 4A 4A 4A 16 19 00 9E B5 00 00 4A 00 00 00 00 00 00 1C 11 FC FF FF 35 1C FD FF FF 5B F9 FF FF 00 00 00 94 B5 00 00 B8 35 1B FD FF FF 5B F9 FF FF 00 01 00 94 B5 00 00 1E 00 00 70 41 16 4A 16 19 00 9E B5 00 00 28 00 00 00 00 00 00 1C 15 FC FF FF A8 1F 43 75 72 72 41 63 74 69 6F 6E 3A 00 38 56 01 E2 30 00 00 16 4A 4A 4A 4A 16 07 8C 02 1B DB 3D 00 00 00 00 00 00 16 19 00 9E B5 00 00 11 00 00 00 00 00 00 1C 12 FC FF FF 24 96 24 FF 24 96 4A 16 06 B2 02 19 00 9E B5 00 00 11 00 00 00 00 00 00 1C 12 FC FF FF 24 FF 24 96 24 96 4A 16 19 00 9E B5 00 00 4A 00 00 00 00 00 00 1C 11 FC FF FF 35 1C FD FF FF 5B F9 FF FF 00 00 00 94 B5 00 00 B8 35 1B FD FF FF 5B F9 FF FF 00 01 00 94 B5 00 00 1E 00 00 70 41 16 4A 16 19 00 9E B5 00 00 6A 00 00 00 00 00 00 1C 15 FC FF FF A8 A8 A8 1F 4C 6F 63 61 74 69 6F 6E 3A 00 38 58 19 01 09 31 00 00 09 00 DE F8 FF FF 00 01 DE F8 FF FF 16 1F 52 6F 74 61 74 69 6F 6E 3A 00 16 38 59 19 01 09 31 00 00 09 00 DD F8 FF FF 00 01 DD F8 FF FF 16 4A 4A 4A 4A 16 19 00 9E B5 00 00 4A 00 00 00 00 00 00 1C 11 FC FF FF 35 1C FD FF FF 5B F9 FF FF 00 00 00 94 B5 00 00 B8 35 1B FD FF FF 5B F9 FF FF 00 01 00 94 B5 00 00 1E 00 00 70 41 16 4A 16 19 00 9E B5 00 00 1D 00 00 00 00 00 00 1C 15 FC FF FF A8 1F 53 74 61 74 65 3A 00 38 57 61 1C 16 16 4A 4A 4A 4A 16 19 00 9E B5 00 00 4A 00 00 00 00 00 00 1C 11 FC FF FF 35 1C FD FF FF 5B F9 FF FF 00 00 00 94 B5 00 00 B8 35 1B FD FF FF 5B F9 FF FF 00 01 00 94 B5 00 00 1E 00 00 70 41 16 4A 16 19 00 9E B5 00 00 B5 00 00 00 00 00 00 1C 15 FC FF FF A8 A8 A8 A8 A8 1F 50 68 79 73 69 63 73 3A 00 38 52 19 01 09 31 00 00 09 00 C3 FE FF FF 00 01 C3 FE FF FF 16 1F 50 68 79 73 57 65 69 67 68 74 3A 00 16 38 55 19 19 01 09 31 00 00 09 00 57 FD FF FF 00 01 57 FD FF FF 09 00 D2 FC FF FF 00 01 D2 FC FF FF 16 1F 4D 6F 74 6F 72 3A 00 16 38 55 19 2E CF 37 00 00 01 09 31 00 00 09 00 04 36 00 00 00 01 04 36 00 00 16 4A 4A 4A 4A 16 19 00 9E B5 00 00 11 00 00 00 00 00 00 1C 12 FC FF FF 24 FF 24 FF 24 FF 4A 16 07 AF 0E 82 77 19 01 09 31 00 00 09 00 F1 34 00 00 00 01 F1 34 00 00 2A 16 18 22 00 77 19 01 09 31 00 00 09 00 EE 34 00 00 00 01 EE 34 00 00 2A 16 16 07 25 06 82 77 19 01 09 31 00 00 09 00 ED 34 00 00 00 01 ED 34 00 00 2A 16 18 35 00 19 19 01 09 31 00 00 09 00 ED 34 00 00 00 01 ED 34 00 00 0A 00 A2 FF FF FF 00 2D 01 A2 FF FF FF 16 0F 00 98 B5 00 00 26 06 30 06 0F 00 98 B5 00 00 25 07 C0 06 77 19 19 01 09 31 00 00 09 00 F1 34 00 00 00 01 F1 34 00 00 0A 00 E4 F9 FF FF 00 1B F9 34 00 00 00 00 00 00 16 2A 16 0F 00 96 B5 00 00 19 19 19 01 09 31 00 00 09 00 F1 34 00 00 00 01 F1 34 00 00 0A 00 E4 F9 FF FF 00 1B F9 34 00 00 00 00 00 00 16 09 00 00 FA FF FF 00 01 00 FA FF FF 06 D3 06 0F 00 96 B5 00 00 21 9C 6D 00 00 00 00 00 00 07 DE 07 82 77 19 19 01 09 31 00 00 09 00 F1 34 00 00 00 01 F1 34 00 00 0A 00 E4 F9 FF FF 00 1B F9 34 00 00 00 00 00 00 16 2A 16 18 4D 00 77 19 19 19 01 09 31 00 00 09 00 F1 34 00 00 00 01 F1 34 00 00 0A 00 E4 F9 FF FF 00 1B F9 34 00 00 00 00 00 00 16 09 00 E3 F9 FF FF 00 01 E3 F9 FF FF 2A 16 16 0F 00 9A B5 00 00 19 19 19 19 19 01 09 31 00 00 09 00 F1 34 00 00 00 01 F1 34 00 00 0A 00 E4 F9 FF FF 00 1B F9 34 00 00 00 00 00 00 16 09 00 E3 F9 FF FF 00 01 E3 F9 FF FF 09 00 F5 F9 FF FF 00 01 F5 F9 FF FF 09 00 04 FA FF FF 00 01 04 FA FF FF 06 F1 07 0F 00 9A B5 00 00 21 9C 6D 00 00 00 00 00 00 07 FD 08 84 9B 38 3A 19 19 01 09 31 00 00 09 00 57 FD FF FF 00 01 57 FD FF FF 09 00 B0 FE FF FF 00 01 B0 FE FF FF 38 3A 24 02 16 18 3C 00 9B 38 3A 19 19 01 09 31 00 00 09 00 57 FD FF FF 00 01 57 FD FF FF 09 00 AF FE FF FF 00 01 AF FE FF FF 38 3A 24 00 16 16 0F 00 9B B5 00 00 70 70 70 70 1F 52 4D 20 5B 00 38 52 19 19 01 09 31 00 00 09 00 57 FD FF FF 00 01 57 FD FF FF 09 00 B0 FE FF FF 00 01 B0 FE FF FF 16 1F 5D 20 52 4D 52 20 5B 00 16 38 52 19 19 01 09 31 00 00 09 00 57 FD FF FF 00 01 57 FD FF FF 09 00 AF FE FF FF 00 01 AF FE FF FF 16 1F 5D 00 16 07 FC 09 9B 19 19 01 09 31 00 00 09 00 F1 34 00 00 00 01 F1 34 00 00 09 00 37 FA FF FF 00 01 37 FA FF FF 2C 04 16 0F 00 9C B5 00 00 A8 A8 A8 A8 A8 70 70 70 70 1F 28 00 38 53 36 19 19 01 09 31 00 00 09 00 57 FD FF FF 00 01 57 FD FF FF 09 00 D4 FF FF FF 00 01 D4 FF FF FF 16 1F 3A 00 16 38 57 00 9A B5 00 00 16 1F 29 00 16 38 53 92 19 19 01 09 31 00 00 09 00 F1 34 00 00 00 01 F1 34 00 00 09 00 37 FA FF FF 00 01 37 FA FF FF 26 16 16 1F 4D 72 3A 00 16 38 53 00 98 B5 00 00 16 00 9B B5 00 00 16 38 57 00 96 B5 00 00 16 06 C5 0C 07 AD 0B 82 82 9A 19 19 01 09 31 00 00 09 00 F1 34 00 00 00 01 F1 34 00 00 09 00 37 FA FF FF 00 01 37 FA FF FF 2C 04 16 18 38 00 9B 19 19 01 09 31 00 00 09 00 EE 34 00 00 00 01 EE 34 00 00 09 00 37 FA FF FF 00 01 37 FA FF FF 2C 21 16 16 18 38 00 9B 19 19 01 09 31 00 00 09 00 EE 34 00 00 00 01 EE 34 00 00 09 00 37 FA FF FF 00 01 37 FA FF FF 2C 22 16 16 0F 00 9C B5 00 00 A8 A8 A8 A8 A8 A8 70 70 70 70 1F 28 00 38 53 36 19 19 01 09 31 00 00 09 00 57 FD FF FF 00 01 57 FD FF FF 09 00 D4 FF FF FF 00 01 D4 FF FF FF 16 1F 3A 00 16 38 57 00 9A B5 00 00 16 1F 29 00 16 38 53 92 19 19 01 09 31 00 00 09 00 F1 34 00 00 00 01 F1 34 00 00 09 00 37 FA FF FF 00 01 37 FA FF FF 26 16 16 38 53 92 19 19 01 09 31 00 00 09 00 EE 34 00 00 00 01 EE 34 00 00 09 00 37 FA FF FF 00 01 37 FA FF FF 26 16 16 1F 4D 72 3A 00 16 38 53 00 98 B5 00 00 16 00 9B B5 00 00 16 38 57 00 96 B5 00 00 16 06 C5 0C 0F 00 9C B5 00 00 A8 A8 A8 A8 A8 A8 A8 70 70 70 70 1F 28 00 38 53 36 19 19 01 09 31 00 00 09 00 57 FD FF FF 00 01 57 FD FF FF 09 00 D4 FF FF FF 00 01 D4 FF FF FF 16 1F 3A 00 16 38 57 00 9A B5 00 00 16 1F 29 00 16 38 53 92 19 19 01 09 31 00 00 09 00 F1 34 00 00 00 01 F1 34 00 00 09 00 37 FA FF FF 00 01 37 FA FF FF 26 16 16 38 53 92 19 19 01 09 31 00 00 09 00 EE 34 00 00 00 01 EE 34 00 00 09 00 37 FA FF FF 00 01 37 FA FF FF 26 16 16 1F 4D 72 3A 00 16 38 53 00 98 B5 00 00 16 00 9B B5 00 00 16 38 57 19 01 53 AF 00 00 03 00 05 FA FF FF 00 61 1C 16 16 38 57 00 96 B5 00 00 16 07 54 0D 97 36 01 44 AF 00 00 25 16 0F 00 97 B5 00 00 7E 10 93 36 01 44 AF 00 00 26 16 01 44 AF 00 00 1F 5D 00 4A 4A 4A 16 07 54 0D 82 9B 00 97 B5 00 00 1D FF FF FF FF 16 18 33 00 7A 7F 10 93 36 01 44 AF 00 00 26 16 01 44 AF 00 00 92 00 97 B5 00 00 2C 02 16 4A 16 00 9C B5 00 00 16 16 14 2D 00 99 B5 00 00 28 07 E9 0D 2D 00 99 B5 00 00 07 7F 0D 97 36 01 44 AF 00 00 2C 14 16 40 01 44 AF 00 00 25 26 16 55 01 44 AF 00 00 23 00 A8 70 70 1F 5B 00 38 53 A5 01 43 AF 00 00 16 16 1F 5D 00 16 00 9C B5 00 00 16 16 07 CC 0D 97 01 43 AF 00 00 1D E8 03 00 00 16 0F 01 43 AF 00 00 25 07 E9 0D 2D 00 95 B5 00 00 07 E9 0D 7B 00 9B B5 00 00 1F 00 16 07 AF 0E 19 00 9D B5 00 00 0A 00 FC 6E 00 00 00 2D 01 FC 6E 00 00 58 01 44 AF 00 00 00 9C B5 00 00 00 4A AE 0E 19 00 9E B5 00 00 4A 00 00 00 00 00 00 1C 11 FC FF FF 35 1C FD FF FF 5B F9 FF FF 00 00 00 94 B5 00 00 B8 35 1B FD FF FF 5B F9 FF FF 00 01 00 94 B5 00 00 1E 00 00 70 41 16 4A 16 19 00 9E B5 00 00 17 00 00 00 00 00 00 1C 15 FC FF FF 00 9C B5 00 00 4A 4A 4A 4A 16 31 30 04 0B 53 [offset 00907C90]


[Replacement][offset 00907290]

{header}
B3 B5 00 00 50 55 00 00 00 00 00 00 93 B5 00 00 00 00 00 00 00 00 00 00 9E B5 00 00 00 00 00 00 FE 23 00 00 84 8D 04 00 96 0A 00 00 02 0A 00 00

{body}
0F 00 97 B5 00 00 38 3A 1B F1 33 00 00 00 00 00 00 16 45 9A 00 97 B5 00 00 2C 1C 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 05 16 01 00 0B 45 9A 00 97 B5 00 00 2C 1D 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 05 16 01 00 0B 45 9A 00 97 B5 00 00 2C 1E 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 05 16 01 00 0B 45 9A 00 97 B5 00 00 2C 1E 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0F 16 01 00 0B 45 9A 00 97 B5 00 00 2C 1E 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 20 16 01 00 0B 45 9A 00 97 B5 00 00 2C 1F 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 05 16 01 00 0B 45 9A 00 97 B5 00 00 2C 1F 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0F 16 01 00 0B 45 9A 00 97 B5 00 00 2C 1F 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 20 16 01 00 0B 45 9A 00 97 B5 00 00 2C 1F 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 17 16 01 00 0B 45 9A 00 97 B5 00 00 2C 1F 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0A 16 01 00 0B 45 9A 00 97 B5 00 00 2C 20 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 2F 16 01 00 0B 45 9A 00 97 B5 00 00 2C 20 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 21 16 01 00 0B 45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 2F 16 01 00 0B 45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 21 16 01 00 0B 45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 17 16 01 00 0B 45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0A 16 01 00 0B 45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 11 16 01 00 0B 45 9A 00 97 B5 00 00 2C 21 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 5E 16 01 00 0B 45 9A 00 97 B5 00 00 2C 22 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 21 16 01 00 0B 45 9A 00 97 B5 00 00 2C 22 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 2B 16 01 00 0B 45 9A 00 97 B5 00 00 2C 23 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 23 16 01 00 0B 45 9A 00 97 B5 00 00 2C 23 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 17 16 01 00 0B 45 9A 00 97 B5 00 00 2C 23 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0A 16 01 00 0B 45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 03 16 01 00 0B 45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0F 16 01 00 0B 45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 36 16 01 00 0B 45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0A 16 01 00 0B 45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 19 16 01 00 0B 45 9A 00 97 B5 00 00 2C 25 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 5E 16 01 00 0B 45 9A 00 97 B5 00 00 2C 27 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 23 16 01 00 0B 45 9A 00 97 B5 00 00 2C 28 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 36 16 01 00 0B 45 9A 00 97 B5 00 00 2C 29 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 05 16 01 00 0B 45 9A 00 97 B5 00 00 2C 29 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0F 16 01 00 0B 45 9A 00 97 B5 00 00 2C 29 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 13 16 01 00 0B 45 9A 00 97 B5 00 00 2C 2B 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 23 16 01 00 0B 45 9A 00 97 B5 00 00 2C 2B 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 28 16 01 00 0B 45 9A 00 97 B5 00 00 2C 2B 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 17 16 01 00 0B 45 9A 00 97 B5 00 00 2C 2B 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 0A 16 01 00 0B 45 9A 00 97 B5 00 00 2C 2B 16 21 00 19 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B7 35 00 00 00 00 00 00 2C 2B 16 01 00 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 04 0B 53

3. Now only thing is left is to update header for our changed function size:

B3 B5 00 00 50 55 00 00 00 00 00 00 93 B5 00 00 00 00 00 00 00 00 00 00 9E B5 00 00 00 00 00 00 FE 23 00 00 84 8D 04 00 96 0A 00 00 02 0A 00 00
Here is important bytes: 96 0A 00 00 are the defined memory size of the function. Since we added new lines, the defined memory size has to be made larger to match.
- Just to make sure it is large enough (if you have added a lot of perks), we temporarily set the memory size to 0x1A96 (96 1A 00 00).
- After that Open the token view and scroll to the very end
- Read the memory position of the End Of Script (or EOS) token. In my version it reads : (BD9/A01) [53] EOS(1/1)
- The 0xBD9 is the memory position of the end-of-script token (the 0xA01 is the file position)
This means that the total file memory size is +1, or 0xBDA in my case
Replace the next-to-last word in the header with the correct function memory size DA 0B 00 00

new header:
B3 B5 00 00 50 55 00 00 00 00 00 00 93 B5 00 00 00 00 00 00 00 00 00 00 9E B5 00 00 00 00 00 00 FE 23 00 00 84 8D 04 00 DA 0B 00 00 02 0A 00 00

 

After that everything should work as advertised.

 


Also I realised (a while ago, actually), that my concern for increased mission load times has been moot (because there is fix for that, here is the link http://forums.nexusmods.com/index.php?/topic/1001468-forcing-game-to-load-from-defaultgamecoreini/?p=8404760) (how I could missed it? :confused: ).
Anyway, with that possibility in mind I decided to split my mod into two versions: Lite (basic version, that was planned from start) and Extended (where I go crazy with as much of awesome stuff as I could find and put into it; of course, balance would be adjusted accordingly).

Now, I'm am just waiting for code to make certain perks-to-items, and possible solution to improve cover. After that mod would be ready for test launch.

However, this mod needs appropriate name for that to happen ("Combined mod" being a work title), so I'm open for suggestions.

Also here is short tactical guide for it (which is as incomplete as mod itself):

 

 

{Tactical Guide} (sort of preview of changes being made so far)

So this mod was created with two overarching goals in mind:
1) To create as much challenging as possible tactical fights (without making them actually impossible to win);
2) To give player as much as possible control on battlefield (linked to previous goal);
Both of which would result in immersive and thrilling gameplay experience.

With that said, this mod probably will be the hardest mod you have played so far. But don't be afraid of its difficulty (it is, after all, part of the fun), because while it is harder, it is more fair than vanilla and I have given player tools to manage almost any kind of situation. So I recommend this mod for any player that is up to challenge. I played the mod myself and it is possible for perfect playthrough, ie no soldiers/countries lost on Ironman Impossible.

This mod, however, should not feel easy at any point, so if you are not fighting aliens teeth-and-nails - I am clearly not doing my job :smile:

Then I decided to write this tactical guide to help people playing my mod.

Weapon changes:
kinetic weapons are slightly better (generally +1 base damage compared to vanilla);
now all weapons (except special weapons like sniper rifles and shotguns) can suppress;
pistols were improved, so with gunslinger perk they are equivalent in damage to full-size assault rifle of same tier;
also pistols unlimited ammo has been removed, now they need to reload, like any other weapon;
damage line-up for same tier weapon is next: special weapons (sniper rifles and shotguns) deals +1 damage compared to assault rifle, heavy weapon deals +1 damage compared to them (so specialists would still prefer their special weapons (despite their limitations), and since heavy does not carry back-up weapon and have less shots, than others - at least he can make those shots count);
close combat range increased in 1.5 times, but aim climb was made smoother to compensate (now range matters more; also shotguns are slightly more effective at range);
Also all explosives deal 25% more damage, than before.

Weapon suppression rates depends on a weapon equipped and is next:
Pistols usually don't have very high suppression rates (howerer, they still do remove overwatches/prevent reaction fire)
- pistol 10
- laser pistol 15
- plasma pistol 20
Rifles are an okay weapon for suppression, except more advanced variants, which are better at this task
- rifle 15
- laser rifle 20
- light plasme rifle 25
- plasma rifle 30
And heavy weapons usually excell in suppression (howerer, they still spend a lot of ammo)
- machinegun 25
- heavy laser 30
- heavy plasma 35

Now please do keep in mind, that aliens have same damage values and suppression rates for their corresponding weapons and all alien weapons (except integrated ones), also have to reload as well (been that way already), with an exception of sectoids (but they deal 1 less damage) and cyberdisc (it has to reload); exception was made for balance/technical reasons (and I am not happy with it as well);

soldiers start with 3 base hp, which is upped at sergeant and colonel ranks (5 hp max); but armor provides higher bonuses to compensate;
Also recovery times are longer
Also I have changed critical wound chance - now it is same as will of soldier +any bonuses that provides "Don't die on me" upgrade in OTS.
Soldiers XP requirements for higher ranks is increased exponentially and is next
rookie
squaddie
corporal
sergeant
lieteant 2x
captain 3x
major 4x
colonel 5x
Most advanced tech research time is increased (so getting research labs/research credits is more important)
//most strategic part rebalance would be changed in future//

update: balance in strategic part of game is severely broken, so mod will not be released until I fix that.

Next section is very important, as it has major impact on gameplay.

I'm glad to reintroduce reaction fire back to the game. Basically now all active units in game have a chance to trigger reaction/overwatch shot on enemy movement (higher reaction rating grants better chance vs enemy with lower reaction and vice versa). Now keep in mind that chance is pretty small (like base 10% for human soldiers), but it is rolled for each step independently (ie for each square boundarie that unit crosses on path of its movement and is visible to enemy). While reaction shots essentially have all advantages and disadvantages of overwatch shots, there is no limit, how much of them can happen in single turn and it does not interfere with normal overwatch shots (ie with sentinel perk it is 2 overwatch shots and any amount of lucky dice rolls); howerer reaction cannot happen if unit is in middle of animation of returning to cover after previous overwatch/reaction shot (so too many reaction shots on single unit cannot happen), and obviously unit cannot do reaction shots if it is out of ammo.


[Warning!!!]
All of the above applies to alien units as well, so when you are running in field of vision of unsuppressed enemy - you rolling a dice for not to die for each step you take in its field of vision (please do carefully consider all risks before attempting something like that).

Reaction rating of aliens (human soldiers rated as normal):

sectoid - slow (alien eq. of armed civilian);
thinman - very fast (fast, deadly, hard to hit, but squishy);
floater - normal (somewhat a failure of a cyborg);
heavy floater - very fast (not a failure any more);
muton - fast (being bioengineered supersoldier do that for ya);
muton elite - very fast (they aren't l33t for nothing!);
sectoid commander - normal (bigger brain, better reflexes);

ethereal - unapliable (as they are not even bothering with conventional weaponry);

Non-organic units have reaction ratings beyond reach of organics, so BEWARE.

[!](rated on independent scale)
SHIV - slow (human technology can only reach so far);
drone - slow (it is non-combat REPAIR drone, ffs);
cyberdisk - fastest (advanced alien craft and sensors sometimes do miracles, pretty nasty miracles at that);
sectopod - very fast (be very cautious of his turret);
outsider - fast (being of almost pure energy has its advantages after all).

Melee unit have their special rules (as they can react only at melee distance), and their reaction rating somewhat mitigates chances of reaction fire (so they would not be mowed down by massed reaction fire).

[!](rated on independent scale)
zombie - slow (they may seem slow, but you really should not be running circles around zombies);
chryssalid - normal (they may seem fast, but not too much with their slow and deadly attack);
muton berserker - fast (moving at arms length around bioengineered supersoldier, that is BERSERKING - that is definetely NOT A GOOD idea. He may miss with his swing, though; but don't count on that).

I reorganised perks (removed perks that were breaking my willing suspension of disbelief, like shredder rocket or moved them to be items: battlescanners, smoke grenades, HEAT ammo (now named Anti-Armor Kit), will be replaced by several other damage incresing items in Extended version of my mod. Also shared lot of perks/moved them in trees for them to be arranged in more logical fashion, also there is no obviously better choices in perk trees (everyone can have their preferences). Also while it may seem, that classes/roles may overlap - it is actually not the case. Also I believe I have improved interclass balance, as any class now can be as combat capable as any other (while maintaining their unique niche on battlefield).

I have also added perks for aliens (to create unique and more challenging situations on battlefield). Please keep in mind that I removed silly defense/aim/crit bonuses from those aliens, which should not have them.
All alien flight capable units now counting as hovering all the time (as they technically ARE hovering), which reflects in passive +10 defense at all times (it is much harder to hit something capable of 3D evasive maneuvers), it stacks with its flight bonus (when they are actually flying);
Aliens with very high reaction can also receive defense bonuses (being capable of dodging enemy fire, sometimes);

I also buffed HP of mutons significantly (to amount they should have as alien's main frontline unit), also increased HP of late game enemies (so they would remain a credible threat to high-leveled and well-geared XCOM soldiers).

I would like to remind you that my mod focuses on impossible difficulty (in a way, yes, I am creating Harder than Impossible difficulty). I created it mostly for my personal use (and my friends, who agreed with me that vanilla Impossible was way too easy for something labeled like that) and then decided to share it with everyone interested.

Word of advise and a little hint for those playing on Ironman: if RNG decides to completely wreck you - do NOT FINISH your/theirs turn, kill game process, reload, and give all bad rolls for the enemy (by memorizing sequence of perceived results I have managed to weasel out of any kind of bad situation (said situations was not result of my actions). If you make honest mistake - face the consequences. Those type of situation is quite rare (like whole 6 man team missing all shots on exposed enemies), so mentioned method should be used only as last resort.


And here is changelist (which I made to form, that one can easily apply and modify any features/changes as needed):

coming soon; scheduled for version 1.0 release

 

Edited by Tycus
Link to comment
Share on other sites

 

 

Drone: Holo-target (iq), Damn Good Ground, Low Profile (do they even use cover, like ever?)

 

I think all of the robots are constrained from using cover at all, along with the melee units.

 

 

Looking forward to seeing more mods come out.

 

We'll get the right flavor of the item mod so you can get the perks on items set up how you want. To start you might try adding the hex code for the "new items" off the wiki. It's listed as WIP primarily because it's not "installable" for an end-user, but with a bit of configuration help Yzaxtol and johnnylump both got it installed and working.

Link to comment
Share on other sites

I hate to be bringer of bad news, but mod is being frozen until further notice.

 

While I managed to successfully (more or less) implement reworked cover, implementing certain perks-as-items happen to get across severe issue. Basically, code that lies on wiki is customized (for Long War) version, that is also not mod-friendly (I asked Amineri directly about the issue, and she said that changes I need require complete rewrite of function in question, but she has no time nor inclination to do that, and obviously, I cannot do that myself yet).

 

Also another issue remaining is terribly repetitive (ergo boring) and disbalancing UFO grind mid-to-late game (one of earlier changes, that I have made to my mod, was increasing number of abduction mission to 5 per month (to apply pressure via panic early) and making UFOs on missions visible to player, so it would be possible to mitigate effect by taking out said UFOs. While early in-game this works as intended, starting from third month and later game becomes horrible grind of large scout UFOs (that are preceding abductions and are trivial to take down at this point in-game). That could be resolved be dynamic UFO selection on missions (here link to R&D thread: http://forums.nexusmods.com/index.php?/topic/1043023-r-d-dynamic-ufo-selection), along (not instead) with other changes (like changing UFO's and interceptor's characteristics or allowing overdamaged UFOs explode mid-flight).

 

I have already incorporated lots of features into my mod (that can be found on this forum), and scheduled some more, but without those two issues resolved I cannot release my mod (which still has no official name).

Here is short list of both:

 

Mine changes from start:
DGC.ini changes (and all, that is possible in XTGC); will shift to actual DGC.ini in future

Used someone's else code:
Toolbox fixes
Enhanced perk tree (complete with modlets unlocking Bulletswarm and DoubleTap)
every non air war feature from "Long War upk changes" thread (by johnnylump)

every non-duplicated in "Long War upk changes" feature from "Interesting UPK stuff I have found" thread (by Black Alpha)
Fragments Friendly Explosives (updated for patch 4)
Squadsight aim penalty+reworked cover
Revive bug fix and optional boost
+Customizable Zhang and customization options (tester request)

Mine adjusted and tested addition:
Visible UFos on mission (from Long War upk changes thread)+Mass abductions
Alien perks

Not created equal (SW option fix)

Mine experimental additions:
Activating aliens (still being tested)
Will-to-chance of critical wounds (compatible with both Revive boost and No lose will from Toolbox)

+several custom fixes (made by me) for certain aliens types

 

List of future additions:
All countries contribute modlet
Explosives random damage
Explosives random radius

Randomized Environmental Damage
New function for damage randomization (from R&D Damage Mods thread)

Unlocked rush construction
Harder Volunteer Requirement
SW fixed Hidden Potential (in progress following tutorial)

 

In-decision:
Mod- Explosions destroy corpses

Additional Options for SHIV Customization
-------------------------------
AI bug hunt (probably a must have)
AI Improvement (lot of fixes)

 

Many features/changes are not listed individually, but are referred in this list by threads, in which they can be found or are referred as in packages. This is why this is short list :wink:.

 

 

 

Anyway, I am asking any experienced coder for help with first issue. Here is link to wiki: http://wiki.tesnexus.com/index.php/Additional_Items_Mod_XCOM:EU_-_2012 (original mod), function in question:

function UpdateItemCharges()
{
// End:0x98
if((m_kCharacter.m_kChar.aUpgrades[48] & 1) > 0)
{
SetMediKitCharges((3 * GetInventory().GetNumItems(76)) + (2 * GetInventory().GetNumItems(90)));
}
// End:0xE8
else
{
SetMediKitCharges(GetInventory().GetNumItems(76) + GetInventory().GetNumItems(90));
}
// End:0x11C
if(GetCharacter().HasUpgrade(93))
{
SetRockets(2);
}
// End:0x128
else
{
SetRockets(1);
}
// End:0x159
if(GetCharacter().HasUpgrade(22))
{
SetShredderRockets(1);
}
// End:0x1A2
if((m_kCharacter.m_kChar.aUpgrades[8] & 1) > 0)
{
SetBattleScannerCharges(2);
}
// End:0x201
if(GetInventory().GetNumItems(99) > 0)
{
SetBattleScannerCharges(m_iBattleScanners + GetInventory().GetNumItems(99));
}
// End:0x24A
if((m_kCharacter.m_kChar.aUpgrades[44] & 1) > 0)
{
SetSmokeGrenadeCharges(1);
}
// End:0x2A9
if(GetInventory().GetNumItems(86) > 0)
{
SetSmokeGrenadeCharges(m_iSmokeGrenades + GetInventory().GetNumItems(86));
}
// End:0x2E5
if(GetCharacter().HasUpgrade(92))
{
SetSmokeGrenadeCharges(2 * m_iSmokeGrenades);
}
// End:0x36D
if(GetCharacter().HasUpgrade(24))
{
SetFragGrenades(GetInventory().GetNumItems(85) * 2);
SetAlienGrenades(GetInventory().GetNumItems(88) * 2);
}
// End:0x3C5
else
{
SetFragGrenades(GetInventory().GetNumItems(85));
SetAlienGrenades(GetInventory().GetNumItems(88));
}
SetGhostCharges(4);
SetArcThrowerCharges(GetInventory().GetNumItems(80));
// End:0x439
if(GetCharacter().HasUpgrade(103))
{
SetArcThrowerCharges(4 * m_iArcThrowerCharges);
}
//return;
}

original decompiled code:, what it should look like:

function UpdateItemCharges()
{
// End:0x98
if((m_kCharacter.m_kChar.aUpgrades[48] & 1) > 0)
{
SetMediKitCharges((3 * GetInventory().GetNumItems(76)) + (2 * GetInventory().GetNumItems(90)));
}
// End:0xE8
else
{
SetMediKitCharges(GetInventory().GetNumItems(76) + GetInventory().GetNumItems(90));
}
// End:0x11C
if(GetCharacter().HasUpgrade(93))
{
SetRockets(2);
}
// End:0x128
else
{
SetRockets(1);
}
// End:0x159
if(GetCharacter().HasUpgrade(22))
{
SetShredderRockets(1);
}
// End:0x1A2
if((m_kCharacter.m_kChar.aUpgrades[8] & 1) > 0)
{
SetBattleScannerCharges(2);
}
// End:0x201
if(GetInventory().GetNumItems(99) > 0)
{
SetBattleScannerCharges(m_iBattleScanners + (2*GetInventory().GetNumItems(99)));
}
// End:0x24A
if((m_kCharacter.m_kChar.aUpgrades[44] & 1) > 0)
{
SetSmokeGrenadeCharges(1);
}
// End:0x2A9
if(GetInventory().GetNumItems(86) > 0)
{
SetSmokeGrenadeCharges(m_iSmokeGrenades + (2*GetInventory().GetNumItems(86)));
}
// End:0x2E5
if(GetCharacter().HasUpgrade(24))
{
SetSmokeGrenadeCharges(2 * m_iSmokeGrenades);
}
// End:0x36D
if(GetCharacter().HasUpgrade(24))
{
SetFragGrenades(GetInventory().GetNumItems(85) * 2);
SetAlienGrenades(GetInventory().GetNumItems(88) * 2);
}
// End:0x3C5
else
{
SetFragGrenades(GetInventory().GetNumItems(85));
SetAlienGrenades(GetInventory().GetNumItems(88));
}
SetGhostCharges(4);
SetArcThrowerCharges(GetInventory().GetNumItems(80)*4);
// End:0x439
//return;
}

 

 

Edit: I decided to continue work on mod anyway (by adding features from wait list), but mod will not be released, until both stated above issues are not resolved.

Edited by Tycus
Link to comment
Share on other sites

  • 3 weeks later...

UPDATE:

Well, I have some good news, some bad, and then some...mixed (to put it mildly).

The good: last week at Sunday I have finished adding features to my mod (almost all of wait list and some more).

The bad: still no progress on UFO selection. However, I *might* have resolved item charges issue (*not tested if works as intended*), which for anyone familiar with jump-offsets is fairly easy task and can be done under half-hour, I believe. And I wasted almost a week resolving that; there is silver lining to this, as I now understand this whole jump-offset business, and by looking back I wonder how I could have missed such obvious solution (must have been brain-block or something :rolleyes:).

The ugly: BUGS!!! Bugs everywhere! Now I am on general bug hunt within my mod: as it turns out, I failed to make regular back-ups and checks for each feature I've added/changed, so basically I have to rebuild (and test) my mod from scratch, which could be quite tedious and bothersome task, as estimated total sum of upk changes made so far could easily go up to a hundred (I splitted my mod into 18 semi-separate modules, each with multiple functional upk changes).

 

So as soon as I am through initial test run (in which I fix all obvious/game-breaking bugs) - my mod is out. I believe, between UFO selection and Alien Bases there is no major features left for me to add, so after those (if ever) would be added, I call it complete. After that only minor features/tweaks and fixes be added, and, of course, balance polishing.

However, I am a bit wary to give exact ETA of my mod release, as I have ever-decreasing time to work on my mod (due to RL reasons).

 

I wonder, if there any guide or something on bug hunting? Or can somebody give me some tips on a subject? (or better, join me on the ride :wink:)

So, lets say, game crashes during tactical mission start (after pressing launch button/before skyranger cutscene) - any particular part of code I should look after?

Edited by Tycus
Link to comment
Share on other sites

Without a debugging IDE to set breakpoints or step through code, we kind of have to go back to old-school debugging mechanisms.

 

I generally use a mix of two things:

1) Adding / removing function hex changes to resolve which specific hex change is causing the problem (very rarely I see a side effect or combination of two changes causing a problem)

2) Within a larger hex change I'll add return statements to force a function to exit early. This allows testing which portion of the function is causing the crash. Narrowing the cause of the crash to a couple of lines makes deconstructing the cause a lot easier.

 

Once I've isolated which hex replacement is causing the crash (step 1), you have to dig in and figure out which section of the function is causing it (step 2).

 

Generally how I add return statements is by replacing the 07 ## ## portion of a jump conditional. These three bytes also only take three memory bytes. If the function returns a boolean, int, or has no return value the 07 ## ## can be change to 04 27 0B (or 28 for false), 04 2C 00, or 04 0B 0B

 

This cuts off any later code in the function from executing. If the game still crashes then the bug is before that point.

 

Alternatively you can cause the "true" portion of a conditional to always be skipped by changing the 07 ## ## to 06 ## ##, changing the conditional jump into an unconditional jump.

 

I keep a scratch pad file of such temporary changes to the upks. Sometimes I've had to make up to 6 or 8 such hex changes before isolating the lines causing the crash. 95% of my crashes are due to incorrect jump offsets. The others are a mix of various odd things.

Link to comment
Share on other sites

Most of the below you probably already know but for future reference and the small chance that any of it will be helpfull to you...

 

I use UE Explorer 1.2.4.1 to export all functions I make changes to and edit them separately in hxd before importing them back. (it is a little extra work but pays of in the end, and as bonus you can cut and paste freely in the code and easily identify and correct any resulting size mismatch, in addtion to view buffer and HxD being alligned from byte 0, not to mention that it makes using the Jump Assistant tool much easier to use... )

 

That way I can restore and apply mods on functional level in this kind of situation.... I guess you could do it in reverse by exporting your existing functions, and then open a backup of the upk-file and export the originals to have both versions. Then you can replace all functions (worst case) with originals and apply them one by one until you find the one causing the crash.

 

One important thing to observe is that UE Explorer don't actually save changes to the upk.file until you exit the program (but you can import and export freely regardless and everything is updated in the tool).

 

The most common reason for me to end up with crash is miscalculated jump offsets or forgetting to modify the header offset (decimal byte 41-44) which should always point to address of 53 token +1

 

If you look at a function in View Tokens mode in UE Explorer and token 53 is missing, the reason is that you have not calculated header correctly. It is easy fixed by adding ~255 bytes to current value and look in view tokens again to find correct value and add 1 to it.

Link to comment
Share on other sites

That way I can restore and apply mods on functional level in this kind of situation.... I guess you could do it in reverse by exporting your existing functions, and then open a backup of the upk-file and export the originals to have both versions. Then you can replace all functions (worst case) with originals and apply them one by one until you find the one causing the crash.

Without a debugging IDE to set breakpoints or step through code, we kind of have to go back to old-school debugging mechanisms.

 

I generally use a mix of two things:

1) Adding / removing function hex changes to resolve which specific hex change is causing the problem (very rarely I see a side effect or combination of two changes causing a problem)

<..>

Once I've isolated which hex replacement is causing the crash (step 1), you have to dig in and figure out which section of the function is causing it (step 2).

That was the plan. I was only asking if there is any way to narrow list of suspects, so to speak, so I don't have to go through every single change (there is a lot of them). Because in process of updating one of my latest experimental additions I realized that game does not crash (hang up) until incorrect part of code is called, so by knowing which functions is called in a moment I described earlier and by knowing what parts have been modified I can track it down to what exactly causing the crash.

 

<..> or forgetting to modify the header offset (decimal byte 41-44) which should always point to address of 53 token +1

This is most likely, as sometimes I replace the function (complete with correct header and all), then do a minor adjustment to modded function, but forget to update the header. Of course, I do not completely exclude other reason (broken jump offsets), as while I modify and keep track of jump offsets in modded part of function I may *accidentally* break jump offsets (which I have missed) in unmodded part (done some changes like that before your tool was available).

 

Btw, could be anything helpful in a log file?

Edited by Tycus
Link to comment
Share on other sites

So, specifically, if the game is crashing after pressing "Launch Mission" there are unfortunately a few areas that could be the problem.

 

That button is what switches the execution from running in XComStrategyGame.upk to XComGame.upk. Basically, the strategy game code gets put on hold and the tactical game starts to init. All of the battles initiation code executes, which includes setting up the map and both the XCOM and alien squads.

 

Key classes that init are XGBattle (fairly high level initiation), XGBattleDesc (loading mesh / animation assets for all actors), XGSquad (for both the alien and human player), XGUnit (for both human and alien players). The code that is creating the aliens with perks is getting executed, as is the XGUnit.UpdateItemCharges code for both the human and alien units.

 

So unfortunately there are quite a few possibilities ... :(

 

Typically when I am building a larger modlet (having never actually created an integrated mod) ... say .. like the alien base stuff, which had 15 or so separate hex changes. Anyhow, what I do is map out a plan in which I can rewrite each function one at a time, and run the game after each function hex change. The functionality won't be complete, but I can verify that the code will execute. I'd say that at best about 50% of my hex changes actually run on the first try, and sometimes it takes several iterations before I get a running piece of code.

 

I also have to have a test game that will actually execute the piece of code. An incorrect memory size in the header will cause the game to crash at launch, but an incorrect jump offset will only cause the game to crash when that particular jump is executed. So, as an example with an if/else statement if the jump on the second unconditional jump is incorrect the game will only crash if the if evaluates true.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...