Open ngc92 opened 5 years ago
@ngc92 Your help will greatly help the development patch . Thank ! I think @Sh0wdown will be happy.
Hey @ngc92 thank you for this list!!! I am gonna test those values asap!!!
Wow, thank you so much, this is exactly the kind of thing I was hoping for with my post!! In combination with my own experiments, this allows me to provide the addresses in the exe for the health values of all units. I'm sure some people here already have a list like this, otherwise the patch would probably not be possible, but I hope it is still of help to some:
TROOP_INDICES.archer = 0x74E9B0; Nr. 3 TROOP_INDICES.xbow = 0x74E9B0; Nr. 4 TROOP_INDICES.spear = 0x74E9C0; Nr. 1 TROOP_INDICES.pike = 0x74E9C0; Nr. 2 TROOP_INDICES.mace = 0x74E9C0; Nr. 3 TROOP_INDICES.sword = 0x74E9C0; Nr. 4 TROOP_INDICES.knight = 0x74E9D0; Nr. 1 TROOP_INDICES.ladder = 0x74E9D0; Nr. 2 TROOP_INDICES.builder = 0x74E9D0; Nr. 3 TROOP_INDICES.monk = 0x74E9F0; Nr. 2 TROOP_INDICES.catapult = 0x74E9F0; Nr. 4 TROOP_INDICES.trebuchet = 0x74EA00; Nr. 1 TROOP_INDICES.manguel = 0x74EA00; Nr. 2 TROOP_INDICES.lion = 0x74EA10 ; Nr. 2 TROOP_INDICES.siege_tent = 0x74EA20; Nr. 3 TROOP_INDICES.lord = 0x74EA30; Nr. 4 TROOP_INDICES.stower = 0x74EA40; Nr. 3 TROOP_INDICES.ram = 0x74EA40; Nr. 4 TROOP_INDICES.shield = 0x74EA50; Nr. 1 TROOP_INDICES.ballista = 0x74EA50; Nr. 2 TROOP_INDICES.dog = 0x74EA60; Nr. 4 TROOP_INDICES.aarcher = 0x74EA70; Nr. 3 TROOP_INDICES.slave = 0x74EA70; Nr. 4 TROOP_INDICES.slinger = 0x74EA80; Nr. 1 TROOP_INDICES.assassin = 0x74EA80; Nr. 2 TROOP_INDICES.rarcher = 0x74EA80; Nr. 3 TROOP_INDICES.asword = 0x74EA80; Nr. 4 TROOP_INDICES.thrower = 0x74EA90; Nr. 1 TROOP_INDICES.fballista = 0x74EA90; Nr. 2
For those who don't know, each address, for example 0x74EA30, refers to one 16-hex-number line in the hex editor. I'm not really well versed in the technical details, so I can't explain the background - but, on the practical side of things, each line in this section holds the health values for 4 units and each value in turn is made up of 4 hex-numbers, like 10 27 00 00, where the third one is usually 00 and the last one always (actually reduces health in a weird way if set to another value). As far as I understand, the numbers' places are reversed, so 10 27 00 ist actually 00 27 10, or, in decimal, 10,000.
So, for example, if you open your exe, go to address 0x74E9B0 and set the third set of hex numbers to FF FF FF 00, you'll get near-immortal archers, while setting it to all zeros makes them die from one hit of anything.
Could anyone provide a similar list for unit/building costs, and/or damage and range values? Even just knowing the general area in the exe would be of much help. I've benn waiting for triple-range firethrowers, cow-throwers, invisible knights and so on basically since my childhood...!
... just thought of it: the addresses might vary by stronghold version in some way, I'm not sure about that!
some more data from my Cheat Engine lua scripts. I think quite a bit overlaps with what is already in this path, but maybe you find something useful. These are the addresses within the running process, I dont know how they translate into the exe.
UNIT_COST_BASE = 0x00AB8114
UNIT_COST_INDICES = {}
UNIT_COST_INDICES.archer = 0
UNIT_COST_INDICES.xbow = 1
UNIT_COST_INDICES.spear = 2
UNIT_COST_INDICES.pike = 3
UNIT_COST_INDICES.mace = 4
UNIT_COST_INDICES.sword = 5
UNIT_COST_INDICES.knight = 6
UNIT_COST_INDICES.aarcher = 10
UNIT_COST_INDICES.slave = 11
UNIT_COST_INDICES.slinger = 12
UNIT_COST_INDICES.assassin = 13
UNIT_COST_INDICES.rarcher = 15
-- gold cost
function getUnitCostAddress(unit)
return UNIT_COST_BASE + 4 * UNIT_COST_INDICES[unit]
end
UNIT_HP_BASE_ADDRESS = 0xB4D960
function getHPAddress(unit)
return UNIT_HP_BASE_ADDRESS + 4 * TROOP_INDICES[unit]
end
-- projectile damage
function getArrowDamageAddress(target)
-- archers
local base = 0xB4DAA0
return base + 4 * TROOP_INDICES[target]
end
function getStoneDamageAddress(target)
-- slingers
local base = 0xB4DBE0
return base + 4 * TROOP_INDICES[target]
end
function getBoltDamageAddress(target)
-- crossbow
local base = 0xB4DD20
return base + 4 * TROOP_INDICES[target]
end
function getDamageAddress(attacker, attacked)
-- knight vs peasant: 0xB50164
-- knight vs sword 0xB501CC
-- sword vs sword 0xB5008C
-- distance (byte): 320 = 0x140
-- distance 80 = 0x50
local knight_base = 0xB50160;
local entry_size = 0x140;
local attacker_base = (TROOP_INDICES[attacker] - TROOP_INDICES.knight) *
entry_size + knight_base
local offset = 4 * TROOP_INDICES[attacked]
return attacker_base + offset
end
PlayerOffset = 0x39F4
function getMoneyAddress(player)
local P1 = 0x115ECF0
return P1 + (player-1)*PlayerOffset
end
function getPopularityAddress(player)
local P1 = 0x115e844
return P1 + (player-1)*PlayerOffset
end
function getMenCountAddress(type, player)
local P1 = 0x1160844
return P1 + TROOP_INDICES[type]*4 + (player-1)*PlayerOffset
end
BUILDING_INDICES = {}
BUILDING_INDICES.round_tower = 78
BUILDING_INDICES.square_tower = 77
BUILDING_INDICES.defense_tower = 76
BUILDING_INDICES.out_tower = 75
BUILDING_INDICES.guard_tower = 74
BUILDING_MATERAL_INDICES = {}
BUILDING_MATERAL_INDICES.wood = 0
BUILDING_MATERAL_INDICES.stone = 1
BUILDING_MATERAL_INDICES.iron = 2
BUILDING_MATERAL_INDICES.pitch = 3
BUILDING_MATERAL_INDICES.gold = 4
BUILDING_MATERAL_INDICES.count = 5
function getBuildingHPAddress(building)
local base = 0x005B9218;
return BUILDING_INDICES[building] * 4 + base
end
function getBuildingCostAddress(building, material)
local ref = 0x11242f0
local base = ref + 4 * BUILDING_MATERAL_INDICES.count * (BUILDING_INDICES[building] - BUILDING_INDICES.square_tower)
return base + 4 * BUILDING_MATERAL_INDICES[material]
end
Wow, I didn't know cheatengine could do/ be used for something as detailed as that! Those indices were really useful, they allowed me to find build costs for units and buildings as well as unit move speeds. I could make lists of those too if anyone is interested. Still waiting and looking for damage and range!
That cheat engine stuff might be interesting for @Sh0wdown or no. I have no idea exactly. But I think he already knows about how to get costs, and probably about the building hp. Although it can be quite useful for balance changes in the future. Do you know where the current population is stored?
OK, so I think the absolute addresses in my post are not valid for 1.41, but the relative structure should still be the same.
To get the address of the current population, you can open a map in the editor, set a military unit, turn it into a peasant and let cheat engine scan for an entry of 1, then add more peasants and rescan until you have narrowed it down. However, I could not manage it to get below 5 addresses which all seem to contain the current population, but it should give you a starting point
But is that not the count of peasants? I mean, does it include workers?
Thanks for those addresses, they might help me in the future. Because after making AI-Character changes possible through text files in the upcoming version, maybe I could also do the same for units and buildings.
@Lwndt what crusader version are yours from?
@ByBurton That might be why there are still quite a few addresses left. I will look into it later today, maybe I can get it down to one address. Or actually two, one for peasants and one for population.
@Sh0wdown Maybe it would make sense to enable the Wiki for this repo, so we could collect memory addresses and data structures there.
For player 1: The number of peasants at the campfire is one of
"Stronghold Crusader.exe"+D5F878
"Stronghold Crusader.exe"+D622F8
The total population is one of
"Stronghold Crusader.exe"+D5F864
"Stronghold Crusader.exe"+D6196C
"Stronghold Crusader.exe"+D61A28
"Stronghold Crusader.exe"+1627086
Maybe one of you can help me with the static positions from the tiles above Towers. The Positions are stored inside of the exe and for better Graphic mod packs it will be cool to change them. Im not so good to find the bytes for it inside the exe, maybe one of you have more luck with it. I also have created an issue for that: https://github.com/Sh0wdown/UnofficialCrusaderPatch/issues/375
The tiles are above are the following: The static tiles on Top that dissapear if anyone stand on top of the Tower, i can make them invisible from start on, maybe i add this in the Converter Programm:
And the other static Images that have the fixed Positions inside Stronghold exe:
If i can change the Positions and maybe the Platforms the soldiers stand on, we can make in future bigger Castle kepps, higher and bigger towers etc..
It will help me alot with my Converter: https://github.com/Gaaammmler/Gm1KonverterCrossPlatform
Maybe i also can help @Sh0wdown with a Unit Editor, if i know the Byte Positions inside the exe and how to change them i write a Porgramm for it or add it to this github Project.
Also if anyone can help metalvoidzz and me, i start to extend the Editor Features, but therefore we need more research for the bytes in the .map files: I linked here metalvoidzz wiki with the .map format he started: https://github.com/Sh0wdown/UnofficialCrusaderPatch/issues/395
@ngc92 do you have a more detailed list of building indices? along with maybe damage recieved my each unit? I have a large list of data im trying to find in this area, and your lua script has been helpful so far. Also how did you find all these?
yes, I do have a more extensive list by now, but currently have no access to a windows machine so I've not been working on it recently. The last thing I was working on was trying to decode the data structures used for buildings. Unfortunately I do not have the newer scripts on my PC right now, I'll try to remember and copy them on the next occasion.
As for getting the unit indices, I tracked the location in the code where the unit type is passed to the spawn function in the unit editor, placed a debugger breakpoint, and then just placed archers in the editor but changed the value at the breakpoint to systematically go through all possible units, and then looked what kind of unit actually spawned. Did the same thing for buildings, there seem to be some unused ones in the game (e.g. a bear cave, if I remember correctly)
@PodeCaradox I would actually prefer the scriped approach to a pre-programmed exe editor. Makes it far easier to do changes (no need to re-patch the exe, you could change after loading) while keeping the changes to the exe to a minimum. Path in a lua interpreter or a call to load lua as a dll, make it call some lua start up script and provide some function to edit memory.
@ngc92 Nice, I started collecting Crusader-related data, starting point was the data in this thread, but I also expanded it quite a bit :) If you have more/additional data, feel free to add it.
@GRhin This is what I have on building IDs:
BUILDING_NAMES = {}
BUILDING_NAMES[1] = "hovel"
BUILDING_NAMES[2] = "hovel"
BUILDING_NAMES[3] = "woodcutter"
BUILDING_NAMES[4] = "ox tether"
BUILDING_NAMES[5] = "iron mine"
BUILDING_NAMES[6] = "pitch rig"
BUILDING_NAMES[7] = "hunter"
BUILDING_NAMES[8] = "merc post"
BUILDING_NAMES[9] = "barracks"
BUILDING_NAMES[10] = "stockpile"
BUILDING_NAMES[11] = "armory"
BUILDING_NAMES[12] = "fletcher"
BUILDING_NAMES[13] = "blacksmith"
BUILDING_NAMES[14] = "poleturner"
BUILDING_NAMES[15] = "armorer"
BUILDING_NAMES[16] = "tanner"
BUILDING_NAMES[17] = "bakery"
BUILDING_NAMES[18] = "brewery"
BUILDING_NAMES[19] = "granary"
BUILDING_NAMES[20] = "quarry"
BUILDING_NAMES[21] = "quarry stone pile"
BUILDING_NAMES[22] = "inn"
BUILDING_NAMES[23] = "apothecary"
BUILDING_NAMES[24] = "engineer's guild"
BUILDING_NAMES[25] = "tunneler's guild"
BUILDING_NAMES[26] = "market"
BUILDING_NAMES[27] = "well"
BUILDING_NAMES[28] = "smelter"
BUILDING_NAMES[29] = "???"
BUILDING_NAMES[30] = "wheat farm"
BUILDING_NAMES[31] = "hops farm"
BUILDING_NAMES[32] = "orchard"
BUILDING_NAMES[33] = "dairy"
BUILDING_NAMES[34] = "mill"
BUILDING_NAMES[35] = "stables"
BUILDING_NAMES[36] = "chapel"
BUILDING_NAMES[37] = "church"
BUILDING_NAMES[38] = "cathedral"
BUILDING_NAMES[39] = "???"
BUILDING_NAMES[40] = "manor"
BUILDING_NAMES[41] = "keep"
BUILDING_NAMES[42] = "stronghold"
BUILDING_NAMES[43] = "???" -- has taxes menu
BUILDING_NAMES[44] = "???" -- has taxes menu
BUILDING_NAMES[45] = "large gate"
BUILDING_NAMES[46] = "small gate"
BUILDING_NAMES[47] = "???" -- gate?
BUILDING_NAMES[48] = "postern gate"
BUILDING_NAMES[49] = "drawbridge"
BUILDING_NAMES[50] = "tunnel entrance"
BUILDING_NAMES[51] = "training ground"
BUILDING_NAMES[52] = "signpost"
BUILDING_NAMES[53] = "training ground 2"
BUILDING_NAMES[54] = "siege tent (fire ballista)"
BUILDING_NAMES[55] = "camp ground"
BUILDING_NAMES[56] = "archery range"
BUILDING_NAMES[57] = "training ground 3" -- large post
BUILDING_NAMES[58] = "training ground 4" -- lance target?
BUILDING_NAMES[59] = "training ground 5" -- guilds
BUILDING_NAMES[60] = "???"
BUILDING_NAMES[61] = "???"
BUILDING_NAMES[62] = "gallows"
BUILDING_NAMES[63] = "stocks"
BUILDING_NAMES[64] = "witch hoist"
BUILDING_NAMES[65] = "maypole"
BUILDING_NAMES[66] = "gardens"
BUILDING_NAMES[67] = "killing pit"
BUILDING_NAMES[68] = "pitch"
BUILDING_NAMES[69] = "???"
BUILDING_NAMES[70] = "water pot"
BUILDING_NAMES[71] = "???" -- has taxes
BUILDING_NAMES[72] = "???" -- has taxes
BUILDING_NAMES[73] = "???" -- has taxes
BUILDING_NAMES[74] = "watchtower"
BUILDING_NAMES[75] = "perimeter tower"
BUILDING_NAMES[76] = "defence tower"
BUILDING_NAMES[77] = "square tower"
BUILDING_NAMES[78] = "round tower"
BUILDING_NAMES[79] = "round tower ruin"
BUILDING_NAMES[80] = "siege tent (catapult)"
BUILDING_NAMES[81] = "siege tent (trebuchet)"
BUILDING_NAMES[82] = "siege tent (tower)"
BUILDING_NAMES[83] = "siege tent (ram)"
BUILDING_NAMES[84] = "siege tent (shield)"
BUILDING_NAMES[85] = "???"
BUILDING_NAMES[86] = "watchtower ruin"
BUILDING_NAMES[87] = "perimeter tower ruin"
BUILDING_NAMES[88] = "defence tower ruin"
BUILDING_NAMES[89] = "square tower ruin"
BUILDING_NAMES[90] = "???"
BUILDING_NAMES[91] = "cesspit"
BUILDING_NAMES[92] = "stake"
BUILDING_NAMES[93] = "gibbet"
BUILDING_NAMES[94] = "dungeon"
BUILDING_NAMES[95] = "rack"
BUILDING_NAMES[96] = "flogging rack" -- weird, this does not seem to exist in game
BUILDING_NAMES[97] = "chopping block"
BUILDING_NAMES[98] = "drunken stool"
BUILDING_NAMES[99] = "war dogs"
BUILDING_NAMES[100] = "statue"
BUILDING_NAMES[101] = "shrine"
BUILDING_NAMES[102] = "beehive"
BUILDING_NAMES[103] = "bear"
BUILDING_NAMES[104] = "???"
BUILDING_NAMES[105] = "bear cave"
BUILDING_NAMES[106] = "outpost"
BUILDING_NAMES[107] = "arab outpost"
BUILDING_NAMES[108] = "???"
BUILDING_NAMES[109] = "???"
Hope this helps
How did you find the unit costs? They seem to be more reliably used than what we were finding. For example changing a unit cost is shown in the barracks as well as the deducted amount. While other times ppl have found unit prices it is just the deducted amount.
Maybe this can be added to the wiki? @Krarilotus
UNIT TYPES
ID Name
1 Peasant
2 Burning Person
3 Woodcutter
4 Fletcher
5 Tunneler
6 Hunter
7 Quarry Mason
8 Quarry Worker
9 Quarry Ox
10 Pitchman
11 Wheat Farmer
12 Hops Farmer
13 Apple Farmer
14 Dairy Farmer
15 Miller
16 Baker
17 Brewer
18 Pole Turner
19 Blacksmith
20 Armorer
21 Tanner
22 Archer
23 Crossbowman
24 Spearman
25 Pikeman
26 Maceman
27 Swordsman
28 Knight
29 Ladderman
30 Engineer
31 Miner (Manufacturer)
32 Miner (Worker)
33 Priest
34 Healer
35 Drunkard
36 Innkeeper
37 Monk
38 // (no unit function like crow and seagull)
39 Catapult
40 Trebuchet
41 Mangonel
42 Trader
43 Horse (Trader)
44 Deer
45 Wolf (Lion)
46 Rabbit
47 Bear (Camel)
48 Crow
49 Seagull
50 Siege Tent
51 Cow
52 Dog (Hunter)
53 Fire Watch
54 Ghost
55 Lord
56 Lady
57 Jester
58 Siege Tower
59 Battering Ram
60 Portable Shield
61 Ballista
62 Chicken
63 Mother
64 Child
65 Juggler
66 Fire Eater
67 War Dog
68 Burning Animal (big)
69 Burning Animal (small)
70 Arabian Bow
71 Slave
72 Slinger
73 Assassin
74 Horse Archer
75 Arabian Swordsman
76 Fire Thrower
77 Fire Ballista
78 empty
79 empty
Unit IDs from some old experimentation of mine. Should extend the list in
Unit.cs
quite a bit