This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
user:loggy:combatsim [2022/11/18 18:47] loggy created |
user:loggy:combatsim [2023/01/16 03:26] (current) loggy target picking algorithm, mostly done I hope |
||
---|---|---|---|
Line 7: | Line 7: | ||
* All units not in squads get one created for them and they are all assigned together, which doesn' | * All units not in squads get one created for them and they are all assigned together, which doesn' | ||
* Spawn blood slave units (and take the " | * Spawn blood slave units (and take the " | ||
+ | * Deploy commanders on the field, then units, then retinues. Cast start battle spells. | ||
+ | * " | ||
+ | * for each commander... and then each squad on that commander... | ||
+ | * if ordertype is 1 attack | ||
+ | * gettarget | ||
+ | * if formation type 1, 2, or 4 (line, skirmish, dbl line) write action type 0xf to all squad members | ||
+ | * otherwise, write action type 0xc | ||
+ | * if ordertype is 3 unknown | ||
+ | * gettarget | ||
+ | * write action type 0xc to squad members | ||
+ | * if ordertype is 2 fire | ||
+ | * gettarget (with ranged weapons) | ||
+ | * write action 2 to all squad members | ||
+ | * if ordertype is 4 guard commander | ||
+ | * DON'T GETTARGET | ||
+ | * write action 8 to all squad members, target unit = their commander, target squad = -1 | ||
+ | * if ordertype is 6 hold and attack | ||
+ | * gettarget | ||
+ | * write action 0xd to all squad members | ||
+ | * if ordertype is 0xb hold and fire | ||
+ | * gettarget (with ranged weapons) | ||
+ | * write action 0x13 to all squad members | ||
+ | * if order type is 0xc unknown 12 (" | ||
+ | * gettarget | ||
+ | * write action 0x14 to squad members | ||
+ | * if order type is 7 retreat | ||
+ | * write action 3 to all squad members, target unit = their commander | ||
+ | * if order type is 9 fire keep distance | ||
+ | * gettarget | ||
+ | * write action 0xb to all squad members | ||
+ | |||
+ | * autocommunions - skipping for now, lots of checking player spellbooks which I don't have a grasp of and doesn' | ||
+ | |||
+ | * Set the delay for all squads to random 0-999, or keep whatever they had if it was higher. All squad members get the same value | ||
+ | * Commanders also get a random 0-999, rolled separately per commander | ||
+ | * Autobless everyone that gets it (Ind's effect, presence of pretender in friendly dominion) | ||
+ | * TickBattle until it's over. | ||
+ | * Projectiles land and exert their effects | ||
+ | * If someone has time stop active, remove 90 ticks from their delay | ||
+ | * If it's not post battle cleanup | ||
+ | * Count: total of all units on the field, number of defender' | ||
+ | * If delay is zero or negative, do executeorder, | ||
+ | * Repeat the above two steps, but for all units on the battlefield owned by anyone who isn't the defender | ||
+ | * If the battle round counter (ticks/ | ||
+ | * If the current tick counter % 150 == 0: | ||
+ | * I don't know what this does. I think it's going to be either sound or graphics related though, so not really of interest to me. | ||
+ | * If current tick counter/10 % 750 == 0 or 375 (I guess this is every 3750 ticks then, but why not just mod 375...) | ||
+ | * Update the battle " | ||
+ | * If current tick counter / 10 % 750 == 1, fire a holy avenger strike for the attacker' | ||
+ | * If current tick counter / 10 % 750 == 2, fire a holy avenger strike for the defender nation | ||
+ | * Some units do unitautoeffects. Specifically, | ||
+ | * I've written the finer points of these things elsewhere, but... | ||
+ | * Berserkers gain (value+1)/2 rounded down fatigue. | ||
+ | * All units lose 1 point of fatigue | ||
+ | * Reinvigoration removes its fatigue here | ||
+ | * Land encumbrance adds its fatigue | ||
+ | * Blood surge removes (magnitude/ | ||
+ | * If your fatigue is 100+ at this point, you lose 4 fatigue AND stop berserking, even if this 4 fatigue pushed you below 100 | ||
+ | * Temporary morale modifiers (fear, the unused morale bonus effect) have their value halved here | ||
+ | * If the unit being checked is a pretender in friendly dominion it blesses all sacreds on the field | ||
+ | * Hell power has a (20 + marks*2) chance to spawn a lesser horror in a 5x5 square around you | ||
+ | * Entanglement escape check: if you have blink movement you succeed automatically, | ||
+ | * Web escape check: blink movement succeeds automatically, | ||
+ | * Net escape check: identical to web's except 23+ to escape | ||
+ | * Bonds of fire escape check: blink movement doesn' | ||
+ | * False fetters: MR + open 2d6 of 21+ to escape. No modifiers (penetration, | ||
+ | * Slime: MR + open 2d6 of 22+ to end. No modifiers matter | ||
+ | * Unknown affliction 274877906944 is removed unconditionally | ||
+ | * Encase in ice does 5 AN cold fatigue damage. Roll (strength + open 2d6) - (12 + open 2d6). Subtract this many points of encase in ice. If this results was 0 or negative, subtract one point anyway. | ||
+ | * If you are fleeing and have a mind collar (LA Phlegra iron guard), take damage equal to your mind collar attribute, and gain the marker to say it's happened (this is a slot effect). The damage is magical AN internal, no effect on mindless, and always targets the head. | ||
+ | * If you are swallowed, the thing swallowing you applies Digest/ | ||
+ | * If you were swallowed and the thing that had swallowed you died, you get released. | ||
+ | * Reduce paralysis and cursed luck duration, if applicable | ||
+ | * If you have poison damage accumulated, | ||
+ | * Blood surge has a 20% chance to be removed | ||
+ | * Decay does its stuff, see [[: | ||
+ | * Affliction 274877906944 does 1 AN internal damage per round with a 20% chance of ending, if you are undead it does 2 damage (random hit location) and has no chance of being removed here | ||
+ | * If you have landdamage of 100+ and are on land you take 1 point of true damage with no rolls (random hit location) | ||
+ | * If you have uwdamage of 100+ and are underwater, the same | ||
+ | * Burning does its damage of a closed d(size) of true damage without rolls, and you might get extinguished | ||
+ | * Bleeding does its damage/ | ||
+ | * Freezing does its fatigue and you might thaw, especially if you have cold vulnerability due to an oopsy | ||
+ | * Desiccation does its thing, but only if you have nonzero encumbrance. You take open 2d8 fatigue damage with the true flag set, and the effect ends if you roll MR + 2d6 of 23+. No modifier affect this MR roll | ||
+ | * Plague effects: unless the carrier is undead/ | ||
+ | * " | ||
+ | * Regeneration triggers. Unless you're homesick. | ||
+ | * Bug soul vessels have a 20% chance to transform back to the unit type that died and spawned them via swarmbody. This also removes feeblemindedness | ||
+ | * Shrink/ | ||
+ | * FIXME Something happens that probably involves battlefield positions. I don't really understand this at the moment | ||
+ | * Some units get to do something. Specifically, | ||
+ | * This does a couple of things I don't understand | ||
+ | * But, if you are asleep, you have a 5% chance to wake up | ||
+ | * Same, but with % 188. This is where innate casters do their thing, and cast-spell-every-round stuff on items etc happens | ||
+ | * Innate caster + time stop is handled. | ||
+ | * Some units get to do something. Specifically, | ||
+ | * This one is auras. | ||
+ | * Harassment penalty is multiplied by 95/100 then rounded down. | ||
+ | * Stun duration is reduced, and might end | ||
+ | * Petrify duration is reduced, and might end (deals 999 AN damage to the body, MRN, earth effect, always pen +2) | ||
+ | * If the current tick/10 & 7 == 0, remove enchantments that meet some criteria. | ||
+ | * If the current tick/10 & 31 == 0, updates the battle lighting/ | ||
+ | * Battle enchants are processed. This goes in much the same way as the stuff on a per-unit basis. Start at current tick/10 % 31, do that one, add 32 to the current one to check, continue until there aren't any more... | ||
+ | * This function has its own 16 cycle timer (5120 ticks) which is used for a few enchantments, | ||
+ | * If the current tick/10 & 127 == 0, do lingering effects (clouds). This is also done by starting at index (current tick/10) & 127 and adding 128 until there are no more | ||
+ | * Deal with bounceblasts (chain lightning), these too are done by starting at (current tick/10) & 3 and adding 4 until there are no more | ||
+ | * If %%((tickcount/ | ||
+ | * If %%((tickcount/ | ||
+ | * If (tickcount/ | ||
+ | * If (tickcount/ | ||
+ | * A battle is over and the game proceses the post-battle rounds once all units on the field belong to the same nation at any point. This is not a reversible state, if another nation' | ||
+ | |||
+ | === gettarget === | ||
+ | |||
+ | This is used in a few different places. Time to take a closer look... | ||
+ | |||
+ | * If we were asked to get a ranged weapon, get the unit's "main ranged weapon..." | ||
+ | * Get the first ranged weapon of the unit | ||
+ | * If: | ||
+ | * That weapon was out of ammo | ||
+ | * OR the battle is UW and that weapon can't be fired UW | ||
+ | * OR that weapon' | ||
+ | * Get the unit's second ranged weapon. | ||
+ | * If that has no ammo, give up and say there isn't a main ranged weapon. | ||
+ | * Otherwise, return the first ranged weapon, if one existed | ||
+ | * If your main ranged weapon has a precision stat of 20+, use ranged weapons = 2, otherwise it should stay at 1... I think | ||
+ | * If use ranged weapons < 2, and either the ranged weapon' | ||
+ | * If (ranged weapon' | ||
+ | * Make sure something is in range of your weapon. If it's not, bail and return no target. | ||
+ | * If the highest unit ID in the game < 39999, set val1 to (highest unit ID in the game)/2 rounded up | ||
+ | * Otherwise, val1 = 20000 | ||
+ | * If target type = 1 (commanders) | ||
+ | * FIXME | ||
+ | * If target type = 2 (archers) | ||
+ | * Make up to (val1/2) attempts, rounded down. Pick a random unit ID up to the highest. Continue until all the following are true: | ||
+ | * It's in the current battle | ||
+ | * It's alive | ||
+ | * It's not swallowed by another creature | ||
+ | * It's owned by a nation other than the attacker | ||
+ | * Its unit type innately has any weapon with range > 0 **[Giving bows to commanders that don't inherently have a ranged attack will not be specifically picked out by this]** | ||
+ | * And at least one of the following: | ||
+ | * The target is mindless, and the weapon we are using has no effect on mindless | ||
+ | * The target has more of its friends than enemies in a 3x3 box around it | ||
+ | * If this fails to find something, use fallback | ||
+ | * If target type = 3 (cavalry) | ||
+ | * This is identical to archers except it checks for the mounted flag instead of having an innate ranged weapon | ||
+ | * If target type = 4 (fliers) | ||
+ | * Same again, except the target needs to be able to fly RIGHT NOW. In cases like perpetual storm, this will therefore go only for storm immune/ | ||
+ | * If target type = 5 (closest) | ||
+ | * Check all units in the game, starting at 0 and ascending. | ||
+ | * In order to be valid, units have to meet all of: | ||
+ | * Be in the battle province | ||
+ | * Be on the field | ||
+ | * Either: | ||
+ | * The target has more of its friends than enemies in a 3x3 box around it | ||
+ | * userangedweapons != 1 | ||
+ | * Any one of: | ||
+ | * there is no ranged weapon being used | ||
+ | * the ranged weapon being used does not only hit mindless | ||
+ | * the target is not mindless | ||
+ | * Calculate a " | ||
+ | * closed d3 - 1 + Abs(difference in front-back coordinate) + Abs(difference in left-right coordinate)/ | ||
+ | * Add 50 if the target is routing | ||
+ | * The final target is the lowest " | ||
+ | * If target type = 6 (horrors) | ||
+ | * Make up to (val1/2) attempts, rounded down. Pick a random unit ID up to the highest. Accept it if it's in the battle, it's alive, it's not owned by the unit doing the targeting, and it has a nonzero number of horror marks. | ||
+ | * If the above fails, go through all unit IDs in ascending order, and accept the LAST one found that matches the criteria above. | ||
+ | * If that fails, use fallback | ||
+ | * If target type = 7 (magic users) | ||
+ | * **NOTE**: here for completeness. To the best of my current knowledge I do not believe a player can set this command legitimately. I am not aware of anything in the game that uses this in normal gameplay. | ||
+ | * Make 3000 attempts... | ||
+ | * Pick a random commander ID: RandInt(HighestCommanderID + 1) | ||
+ | * If it is all of the following | ||
+ | * In the battle province | ||
+ | * Has current hitpoints > 0 | ||
+ | * is not owned by the nation doing the targeting | ||
+ | * Has non-holy magic paths | ||
+ | * Has its Front-back coordinate greater than 0 | ||
+ | * Either not using a ranged weapon, the ranged weapon does not hit mindless only, or the target is not mindless | ||
+ | * The target has more of its friends than enemies in a 3x3 box around it | ||
+ | * Accept the first target that matches if one is found | ||
+ | * If those attempts failed: | ||
+ | * Make 1500 more attempts, this time include holy levels as well | ||
+ | * Otherwise, proceed through all commanders in ascending ID order, and accept the one with the highest ID | ||
+ | * If target type = 8 (large monsters) | ||
+ | * Make up to (val1/2) attempts, rounded down. Pick a random unit ID up to the highest. Accept it if all of the following: | ||
+ | * It's in the battle province | ||
+ | * it's alive | ||
+ | * it's not owned by the unit doing the targeting | ||
+ | * Any of: | ||
+ | * we are not using a ranged weapon | ||
+ | * our ranged weapon does not affect only mindless | ||
+ | * the target is not mindless | ||
+ | * The target has more of its friends than enemies in a 3x3 box around it | ||
+ | * Either: | ||
+ | * The target is size 5 or 6 | ||
+ | * The target is size 4-6 inclusive AND (val1/2) < (number of attempts * 2) | ||
+ | * Otherwise, use fallback | ||
+ | * If target type = 9 (rear) | ||
+ | * Proceed in ascending unit ID order, starting at 0. | ||
+ | * If the unit is in the battle province, owned by someone other than the one doing the targeting, has hp > 0, and is in the battle (coordinate check) | ||
+ | * Get the to-be-targeted unit's front-back coordinate. | ||
+ | * If the owner of the targeted unit is on the attacking (left hand side) of the battlefield, | ||
+ | * If the owner of the targeted unit is neither the attacking nor defending nation (eg Call Horror etc), its front/back coordinate is considered to be -99999 instead. | ||
+ | * If the target is retreating, subtract 50 from its front/back coordinate. | ||
+ | * Its front/back coordinate at this point is now a " | ||
+ | * Accept the unit as the " | ||
+ | * Either: | ||
+ | * It is the lowest unit ID to make it here | ||
+ | * closed d100 - 1 <= (400 / (number of alive units in the province that do not belong to the player doing the targeting/3 + 10) + 15 | ||
+ | * Any of: | ||
+ | * We are not using a ranged weapon | ||
+ | * The ranged weapon we are using does not affect only mindless | ||
+ | * The target is not mindless | ||
+ | * The target has more of its friends than enemies in a 3x3 box around it | ||
+ | * The " | ||
+ | * Fallback target type (also used as a "none of the above" option) | ||
+ | * Make up to val1/2 attempts... | ||
+ | * Roll RandInt(HighestUnitID + 1) | ||
+ | * Check that... | ||
+ | * Unit is in battle province | ||
+ | * Unit is alive | ||
+ | * Unit isn't owned by nation doing the targeting | ||
+ | * Unit is not any of the various kinds of temporary (persists after batle, eg is not PD or battlesummoned or a product of secondtmpshape) | ||
+ | * Unit's front-back coordinate > 0 | ||
+ | * Either: | ||
+ | * The ranged weapon we are using doesn' | ||
+ | * The target is not mindless | ||
+ | * Continuing... | ||
+ | * If function param5 > 1 and the total number of size points in the target unit's squad is less than param5 and this condition has been met less than three times: | ||
+ | * multiply param5 by 9, divide by 10 then round down | ||
+ | * start again as if you failed one of the above checks | ||
+ | * If userangedweapons > 2: | ||
+ | * If (your ranged weapon' | ||
+ | * If the target has more of its friends than enemies in a 3x3 box around it, start again as if you failed one of the above checks | ||
+ | * Otherwise, accept this unit | ||
+ | * If this failed and userangedeweapons < 5: | ||
+ | * Check all units in ascending unit ID until one is found. | ||
+ | * Needs to be in the battle province | ||
+ | * Needs to be alive | ||
+ | * Needs to be owned by someone other than nation doing the targeting | ||
+ | * Needs a front-back coordinate on the field | ||
+ | * Ranged weapon needs to hit non-mindless or the target must be non-mindless | ||
+ | * If use ranged weapons < 3, accept this unit | ||
+ | * If (your ranged weapon' | ||
+ | * The target must has more of its friends than enemies in a 3x3 box around it | ||
+ | * If you got here, accept this as the target | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
- | My head hurts and I got disatracted. :( |