Destiny of an Emperor Rom Hacking Guide

Some assembly required…

This post should be a "living document" to hold all of the most important DoaE ROM hacking information. We can edit and add any important new information as it is discovered.

The primary technical contributors to this information are MiDKnighT (me), ludmeister, Niahak, Meteorstrike, James, sonic penguin, Xhinaeria, and several regulars on the LYS message board. Big thanks to everybody that contributed to taking apart Destiny of an Emperor and his highness Lord Yuan Shu and James for giving us a place for a great DoaE community (one of the best games ever made).

RECOMMENDED SOFTWARE:

  • Destiny of an Editor (DoaE tool)
  • A hex editor that supports loading tables (I'm using Hexecute and the editor in FCE Ultra).
  • An emulator that has good debugging features. FCE Ultra works great for me.

For Portraits and Graphics:

DOAE ROM HACKING BEST PRACTICES:

  • Back up your ROM often! Perhaps under a different name with the date in the name each time so that you have a history to fall back to.
  • If it was tough to figure something out, document it. Or better yet, post it on this message board so that others can use your findings and perhaps even improve on it.
  • Make a good ROM! Yes it may take weeks, months, or even years to make a great mod. If you're going to share a finished product don't just change Liu Bei's character and call it a day. A fantastic mod would be one that uses most if not all of the techniques in this guide well and gives the player a brand new and unique gameplay experience.

Places to Find ROMs and Talk about DoaE Modding:
Lord Yuan Shu Forums: http://www.lordyuanshu.com/forums/forum/destiny-of-an-emperor
Scholars of Shen Zhou: http://the-scholars.com/viewforum.php?f=3
Facebook: http://www.facebook.com/pages/Destiny-of-an-Emperor-Mods and http://www.facebook.com/game.walkthroughs

For Contributors:

  • To contribute, go to the bottom of the page, join the page, and enter the password.
  • It is probably easiest to edit sections individually with +Options —> "Edit Sections" at the bottom of the page.

Page 2 Contains:

  • Tactics
  • Officer Attributes

Page 3 Contains:

  • Portraits & Sprites
  • Towns
  • Level Ups
  • Events
  • Miscellaneous
  • Additional Reading
  • Advanced ROM Debugging

Destiny of an Editor

Credit: Niahak, MiDKnighT, and others who assisted (see bottom of README)

Anything that can be edited by "Destiny of an Editor" by Niahak, should be. This tool makes it easier to edit some of the most important aspects of the game like officers, portraits, text, battles, tactics, items, etc…

That said, download Destiny of an Editor HERE

Generals

0wu62YL.png

After opening your ROM with DoaEditor, you can use this page to edit all the key attributes of every general in the game.

Text

gL7w8nU.png

This tab makes it possible to change the text in the game. It can be sorted in ROM order or Alphabetical order. After changing a line of text make sure to hit the "Check my line" button to check the length of the text, etc…

Map

Xsy1t1k.png

This interface allows you to easily drag and drop tiles from the right side to the map area in the middle. There is also a "Region Selector" to help find the region you are looking for. Activate this by clicking on the "Select from map" button at the bottom.

There are certain regions that should not be edited. These are:

  • Any region where an event in the game triggers a map change. For example this happens at Qing Zhou castle, directly below Gui Yang castle, the bridge above Nan Yang, the "canal" area of Wu, and the Luo Yang area and just south of it.
  • Do not edit any region that is outside of the playable area. The general rule is, if you can't walk there in the original game, you probably can't walk there in a modified game.
  • Do not edit any region that is used in more than one place. For example this would be a region that contains all water, all mountains, etc…

There are also special considerations when creating a castle, house, gate, or village. See the LOCATIONS, WARPS, and BATTLES sections below for more info.

Battles

tBc5k2f.png

Edit the battle lineup here. The battles are in the order displayed at: http://kongming.net/doae/rom_hacking/battles/

You can also change the before and after battle taunts and the location of the battle based on the coordinates (see the "Locations" section for more on the coordinates).

Tactics

KSjQbbA.png

Edit attributes of each tactic here. This view is with IPS 1.3 and above. More info about what you are editing here is in the "Tactics" section of this guide.

Profiles

xMhjexy.png

This page is for IPS 1.3 and above only. You can edit officer profiles. Profiles include what tactics the officer can learn when leveling up, what weapons they can use, and what they might be inclined to do as an enemy. On the "Generals" tab you can then assign different officers to different profiles.

Items

S7eYIlA.png

On this page you can edit item names, prices, icons, and various other attributes specific to each item.

Places

JXK760N.png

Edit villagers in each town, inns, weapon stores, merchant stores, provisions, and more here.

Readme

DoaEditor was created by Niahak (www.niahak.org). Check there for the latest version. The current version is 0.98f.

Directions:
1) Load a valid DoaE ROM.
2) Click on an officer's name.
3) Change that officer's stats and name as desired.
4) Click "Save" to save changes to that officer.
5) Repeat 2-4 for each officer. There is no error accounting for using *too much* space - generally I would say it would lead to Very Bad Things. However, it does tell you how much space is left.
6) When you're ready to save the new ROM, click file->Export to ROM. I recommend saving it in a new file and testing, just in case it still isn't all working.

Oh, and some additional info:

Agility is never shown in the game, but it affects order during a round.

Region determines where the officer is found in random encounters, but [i]does not[/i] affect when you can recruit them. If you have them in your party, you won't find them in random encounters.

Sprites are mostly listed by their most memorable (or recognizable) character - most of these were given their names by James.

Sprite color is a value that also affects A.P. when you fight them as an enemy officer, so there are numbers by each color set. For allies, it doesn't matter.

There are multiple leveling schemes in the Soldier drop-downs. These are used for the 5 Tigers, Zhuge Liang, and Jiang Wei. Any character can be made to level. Additional schemes seem to exist in the ROM but are unpredictable.

Highest Tactic determines the highest possible tactic an enemy officer can use. It is also bounded by INT, though - for example, you could give Cheng Yuanzhi access to all tactics, but he can't use any because he's not smart enough.

Portrait values are, yes, raw hex. It's not recommended to mess with these at random, but you can keep track of them to build portraits (like I did with Cao Cao's below).

Portrait Background is usually white for the "special" characters (Liu Bei, Zhao Yun etc). You can give them other colors, but they affect the palette.

Generally: Many values are listed as "Unknown" with a hex value, particularly in portrait backgrounds. Usually these correspond to known values, but are listed separately because they may have unknown side effects.

I cannot guarantee DoaEditor will be completely bug-free. It has been tested multiple times, and seems to be working properly. If you do run into an error, please let me know so I can look into fixing it!

Text-editing has been recently added to this edition, as well as preliminary map-editing.

ROM Expansion explanation:
This feature expands the ROM and allows access to multiple portrait banks, allowing more than 300 portraits to be added to the game (and/or 120 or so new sprites).
Portraits and sprites can be added following a procedure written by MiDKnighT, found here:
http://www.lordyuanshu.com/forums/topic/destiny-of-an-emperor-rom-hacking-guide-1#post-25204

The ROM automatically loads portraits from the file itself, so new portraits can be viewed and used in the editor. Sprite loading is not yet complete.

Thanks go out to:

  • James (www.kongming.net) for a huge amount of help in building tables of AP, AC, and sprites, in addition to ripping the sprites and testing the program.
  • Lord Yuan Shu (www.lordyuanshu.com) for encouragement, testing, and for declaring himself emperor too early.
  • Taishi Ci (2.0) for his Destiny of an Emperor parody, which partially inspired DoaEditor.
  • MeteorStrike of the DoaE GameFAQs board, for much aid in figuring out where things are.
  • MiDKnighT of Scholars of Shen Zhou and LYS.com for helping discover how maps work and ripping their graphics, as well as some awesome work on ROM expansion.
  • sonic.penguin of Scholars of Shen Zhou and LYS.com for keeping the flame lit despite how dark things may seem in the DOAE-hacking world.

DoaE IPS Patch

We've added several of our DoaE "enhancements" into 1 DoaE IPS patch bundle. This patch is geared towards modders who want to quickly add enhancements to their game but it can be used against the original DoaE as well. If you've played DoaE before and have some time, please try it out and give feedback.

Enhancements/fixes added in IPS patch version 1.1:

- Iron Ore / Treasure Chest Bug Fix
- Portrait Expansion Code
- Sprite Expansion Code
- Pre-loaded sprite bank(s)
- 8 tactics
- Agility on status page
- Critical hit formula changes (subtle increase in number of critical hits)
- Agility Based Multi-attacks
- Modified soldier bars to support more troops
- 25 soldier gain level up patterns
- Modified TP gains at level-up
- Change food usage (subtle decrease in amount of food used)
- DoaE2 like damage
- 8 New Chapters
- "Life" and "Raise" tactics
- Smoke pot lasts twice as long

Added in version 1.2:

- Everything in IPS Patch 1.1 and…
- DOAE Artificial Intelligence Enhancements
- "Duel" Tactic (replaces Shui Jian)
- "Charge" Tactic (replaces Cheng Nei)
- "Protect" Tactic (combines Wuo Jian, Shui Jian, and Cheng Nei)
- Enhanced "An Sha" tactic
- Level/soldier based damage for tactics
- Guard tactic only defends against physical attacks
- Defend now halves damage from physical and tactic attacks + gains TP
- Enemy Profiles (Which tactics they are likely to use)
- Equip Menu Enhancement (less steps to equip new items)
- Weapon, Armor, and Tactic icons

Added in version 1.3:

- Everything in IPS Patch 1.2 and…
- Base AC Enhancement
- Expanded number of items, weapons, armor, helmets
- Default icons for items, weapons, armor, helmets, and tactics
- Item, weapon, armor, helmet, and tactic names expanded to 9 characters (including icon) each
- Tactic name list expanded to 255 names (for future expansion)
- New Attributes (LDR, VIT, POL)
- Party leader's LDR affects duel outcome and more to come for LDR.
- VIT is used for Base AC enhancement and more to come for VIT.
- POL is used for item drops and more to come for POL.
- Spoils of war enhancement (item drops)
- Guo Si bug fix
- Tactic Expansion Framework and Tactics Using New Attributes
- Tactic Level Up Profiles
- Many new tactics

This patch will not overwrite your generals, portraits, or custom text. It is only designed to add the new enhancements to your ROM that are in the above list.

Instructions:

  1. Expand your ROM with DoaEditor if you haven't done so already. Note that this will destroy existing save states.
  2. Once the ROM expansion is done, DoaEditor will prompt you to ask if you want to apply a DoaE IPS Patch. Click yes to apply. It is also available as a menu item if you decide to patch later or update your patching with the latest changes.

If using IPS patch 1.2 or greater, there are 2 patches:

Patch 1 – Formats the new code areas on the ROM (apply once)
Patch 2 – Adds all the other enhancements. Note that patch 2 will not overwrite custom lists but patch 1 will.

Usually things that the modder will customize (like palettes, lists, and such) will be changed in patch 1 but patch 2 won't touch those items. DoaEditor will automatically apply patch 1 if it hasn't been applied yet and always apply patch 2 if you choose to apply or update your IPS patch.

Next, just play the game… (Note that FCE Ultra is the most tested emulator with DoaE expanded ROMs – any other emulator must support mapper 245). Obvious changes are the general status page, agility based multi-hits, tactic list if you are using a save state and enter battle, and more.

Let us know how it's working! Please give any feedback on the enhancements or report any bugs.

*** Note that if you are already using the latest features, back up these lists before patching for the first time if you were already using IPS patch 1.2 or above:

0×4450-0x446F = mismatch list – winner
0×4470-0x448F = mismatch list – loser
0×4490-0x44CF = no kill list
0x44D0-0x44EF = rare duel list (for rulers mainly)
0x44F0-0x450F = bigger no an sha list

0x7A400-0x7A4FF = where you assign a profile to an officer

Patch 1.3 and above only:

Weapon Power- Status display: 0×78640 (none), 0×78641 to 0x7865f (ID #40 – #5e)
0×79010-791FF – Enemy tactic profiles (what are they going to do)
0x7AA00-0x7AAFF = LDR settings for officers
0x7AB00-0x7ABFF = VIT settings for officers
0x7AC00–0x7ACFF = POL settings for officers
0x7E710-0x7E777 – Weapon/Item Expansion Details
0xE8400-0xE96FF – Tactic Attributes and Profiles
Page 3E (0xF8010-0xFC00F) = expanded weapon and tactic names
0xFE710-0xFE777 – Weapon/Item Expansion Details

Patch 1.1 and 1.2 only:

0×5710-0x572F = tactic no fail list
0×5730-0x573F: STR bonus list (put tactic ID in this list for STR bonus)
0×5740-0x574F: AGI bonus list (put tactic ID in this list for AGI bonus)
0×5750-0x575F: INT bonus list (put tactic ID in this list for INT bonus)
0x7A510-0x7A6DF = tactic profiles

Joint Projects

Credit: MiDKnighT and Boneduke

For Yuan Shao's Revenge 3.0 Boneduke and I teamed up on it. I did the main ROM work but Boneduke exclusively handled maps and warps. How did we do this? We used IPS patches. I would date a ROM then send it to Boneduke like so:

O4I1X3y.png

Then Boneduke would update maps and warps and send me a copy of the ROM back. I would then receive the ROM, look at the date in the ROM and find the ROM I sent him with that date. I would then use an IPS patching tool (Lunar IPS) to create an IPS patch:

rN0i4n4.png

Unmodified File –> The original ROM I sent him.
Modified File –> The one he sent me with map changes.

Then I’d create an IPS patch from that. The IPS patch basically could surgically insert his map changes without disturbing the rest of the ROM. Then I’d simply apply the IPS patch to my latest ROM and whala, new maps. I’d then check out the maps and move villagers around as necessary, change text, etc… to correspond to the map changes. Then I’d date the ROM again and send it back. We called this the merged ROM. I lost count of how many times we did this but it was a lot. He’d generally update one chapter at a time, or a maze or two, or a town or two, etc… We kind of timed it around real life events too. If Boneduke was going out of town he would send me his latest before leaving, etc…

This strategy worked very well. The golden rule is you can’t touch each other’s stuff. If I started updating maps and Boneduke did too then once I IPS patched the ROM the map would look like a garbled corrupted mess. Likewise if Boneduke updated text then the text pointers would be different in his ROM then if I IPS patched the entire text bank could get corrupted with text moved all over the place. So the trick to making this work is to segregate jobs. You updated this part, I update that part, etc… For a huge ROM project I highly recommend this approach. It’s just too much for one person to do an entire ROM. Possible jobs that could be broken out:

  • ROM master: Person responsible for receiving IPS patches, injecting changes, and sending out the merged ROM.
  • Officer planner: In charge of officer stats, sprites, portraits, profiles, and tactics.
  • Battle planner: Should be the same as the officer planner but also sets up battles.
  • Text planner: In charge of updating text banks. Nobody else should touch text or it will corrupt!
  • Map planner: In charge of maps and warps.
  • Treasure / hidden item planner: In charge of filling chests (works with map planner)
  • Code / event planner: In charge of special events and assembly coding.
  • Music planner: In charge of music

So in theory it's possible to have up to 8 people working on a ROM as long as the jobs are completely separated. As long as nobody updates each other's areas it should work fine.

Locations

Credit: MiDKnighT and Meteorstrike

Everywhere you step in the game, you are stepping on a unique address. Think of it as the "mailing address" of that spot. This address is stored in memory from $0060 to $0063. An example address is: 0C 05 07 12

In this example, OC is the vertical position in your "zone". 05 is the vertical zone that you are in. 07 is the horizontal position in your "zone". 12 is the horizontal "zone" that you are in. The game uses these addresses to place items, location of castles, location of battles, etc…

How do you know your current address? You have to look at the memory while the game is running. For example, in FCE Ultra you open the Hex editor and look at 60-63 in memory (found this from the Meteorstrike post on Gamefaqs).

Here's a pic from the Yuan Shao mod:

MAP1.jpg

So where am I standing? I'm standing in zone 7-10 (7 vertical, 10 horizontal) and I'm standing at 01-0F within that zone. So I'm standing on the last block of the top row in that zone.

Knowing how these location addresses work are critical for being able to place warps, battles, and items.

Item Placement

Credit: Meteorstrike and James

For reference, here's the item list:

  • 00 ~*006038 coins [glitch]
  • 01 ~96 coins
  • 02 ~237 coins
  • 03 ~592 coins
  • 04 ~1013 coins
  • 05 ~1533 coins
  • 06 ~4028 coins
  • 07 ~29 food
  • 08 ~125 food
  • 09 ~821 food
  • 0A ~2011 food
  • 0B ~5902 food
  • 0C ~10151 food
  • 0D ~2098390 food
  • 0E ~2148799 food
  • 0F ~*86607 food [glitch]
  • 10 [blank] ->
  • 16 [blank]
  • 17 Silver Key ->
  • 18 Silver Key
  • 19 Gemsword
  • 1A Ma Letter [???]
  • 1B Gun Powder
  • 1C Intro Letr
  • 1D Iron Ore
  • 1E Dead Wood
  • 1F Saltpeter
  • 20 [glitch]
  • 21 Chi Tu Ma [Red Hare]
  • 22 Zhou Letr [Zhang Ltr]
  • 23 Gold Key
  • 24 Gullwing ->
  • 28 Gullwing
  • 29 [blank] ->
  • 2A [blank]
  • 2B Smoke Pot
  • 2C Steed
  • 2D Resurrect -> (Glitched, use 30)
  • 30 Resurrect
  • 31 Elixir A
  • 32 Elixir B
  • 33 Elixir C
  • 34 Elixir D
  • 35 Power Pill -> (Glitched, use 38)
  • 38 Power Pill
  • 39 Dagger ->
  • 40 Dagger
  • 41 Flail
  • 42 Ax
  • 43 Club
  • 44 Spear
  • 45 Sabre
  • 46 Trident
  • 47 Bow
  • 48 Sword
  • 49 Battleax
  • 4A Scimitar
  • 4B Crossbow
  • 4C Lance
  • 4D Wan Sheng
  • 4E Bo Ye
  • 4F Qing Guang
  • 50 Nu Long
  • 51 Qing Long
  • 52 Halberd
  • 53 Robe ->
  • 59 Robe
  • 5A Leather ->
  • 5B Leather
  • 5C Padded ->
  • 5D Padded
  • 5E Ring M ->
  • 5F Ring M
  • 60 Chain M ->
  • 61 Chain M
  • 62 Splint M ->
  • 63 Splint M
  • 64 Plate M ->
  • 65 Plate M
  • 66 Bandana ->
  • 68 Bandana
  • 69 Cap
  • 6A Hood
  • 6B Wood H
  • 6C Copper H
  • 6D Bronze H
  • 6E Iron H
  • 6F Steel H
  • 6F [glitch] ->
  • 7F [glitch]
  • 80 "I found a small keyhole." ->
  • FF "I found a small keyhole."

Ref: http://the-scholars.com/viewtopic.php?f=3&t=19872&st=0&sk=t&sd=a&start=20

Meteorstrike's missing item FAQ has a list of items and their locations:

HIDDEN = 20

$668E => Chapter 1 – Mt. Da Xing – (001.048.013.001) => 42 = Ax
$6680 => Chapter 2 – World Map – (013.010.012.017) => 21 = Chi Tu Ma
$668F => Chapter 2 – Hu Lao Guan – (001.048.012.003) => 42 = Ax
$6682 => Chapter 2 – Luo Yang – (002.026.012.004) => FF = (~)
$6691 => Chapter 2 – Yang Zhou – (001.047.010.008) => 43 = Club
$6693 => Chapter 3 – Nan Yang – (006.022.005.027) => 46 = Trident
$6684 => Chapter 4 – Guang Zong – (002.007.008.024) => 45 = Sabre
$6685 => Chapter 4 – Ji Zhou – (006.012.007.026) => 47 = Bow
$6688 => Chapter 5 – Wu Ling – (004.031.008.027) => 47 = Bow
$6686 => Chapter 5 – Chang Sha – (004.028.012.026) => 48 = Sword
$6687 => Chapter 5 – Gui Yang – (004.030.012.030) => 48 = Sword
$6692 => Chapter 5 – Ling Ling – (002.047.006.010) => 48 = Sword
$6689 => Chapter 6 – Luo – (006.029.000.024) => 49 = Battleax
$668A => Chapter 6 – Cheng Du – (008.025.008.020) => 4A = Scimitar
$6683 => Chapter 7 – Jian An – (003.028.004.020) => 1E = Dead Wood
$668B => Chapter 7 – Jian An – (001.028.004.020) => 4A = Scimitar
$6690 => Chapter 7 – Hui Ji – (001.048.012.005) => 4A = Scimitar
$668C => Chapter 7 – Wu – (007.026.013.018) => 4B = Crossbow
$668D => Chapter 7 – Wu – (012.026.013.018) => 63 = Splint M
$6681 => Chapter 8 – Guang Ling – (009.026.013.015) => 4E = Bo Ye

For items in this list, the addresses are stored in separate arrays.

$8A00,X = 0x30A10,X = Map address value 1
$8A40,X = 0x30A50,X = Map address value 2
$8A80,X = 0x30A90,X = Map address value 3
$8AC0,X = 0x30AD0,X = Map address value 4
$8B00,X = 0x30B10,X = Item

For dead wood X = 03 (6683 – 6680 = 03). So if you wanted to change the location of dead wood here are the addresses to change:

0x30A13 = Map address value 1
0x30A53 = Map address value 2
0x30A93 = Map address value 3
0x30AD3 = Map address value 4
0x30B13 = Item

CHESTS = 43

$667A : bit 7 => Chapter 1 – Tie Men Xia – (001.029.003.006) => 42 = Ax
$6604 : bit 7 => Chapter 1 – Cave – (003.003.002.004) => 42 = Ax
$6676 : bit 7 => Chapter 2 – Fan Shui Guan – (001.029.003.006) => 42 = Ax
$662A : bit 7 => Chapter 2 – Cave 1 – (002.035.007.029) => 23 = Gold Key
$662A : bit 6 => Chapter 2 – Cave 1 – (003.034.007.026) => 04 = coins
$6629 : bit 2 => Chapter 2 – Cave 2 – (002.041.009.007) => 43 = Club
$664D : bit 7 => Chapter 3 – Chen Cang – (001.029.003.006) => 44 = Spear
$662B : bit 7 => Chapter 3 – Cave – (002.038.005.023) => 69 = Cap
$662B : bit 6 => Chapter 3 – Cave – (002.038.003.023) => 44 = Spear
$662B : bit 5 => Chapter 3 – Cave – (011.039.007.015) => 69 = Cap
$662B : bit 4 => Chapter 3 – Cave – (005.039.013.016) => 59 = Robe
$662B : bit 3 => Chapter 3 – Cave – (002.039.001.017) => 59 = Robe
$662B : bit 2 => Chapter 3 – Cave – (011.040.003.015) => 44 = Spear
$662B : bit 1 => Chapter 3 – Cave – (011.040.007.016) => 44 = Spear
$662B : bit 0 => Chapter 3 – Cave – (011.040.013.017) => 05 = coins
$662C : bit 7 => Chapter 3 – Cave – (007.036.004.023) => 69 = Cap
$662C : bit 6 => Chapter 3 – Cave – (011.036.007.023) => 04 = coins
$662C : bit 5 => Chapter 3 – Cave – (007.036.011.023) => 38 = Power Pill
$662C : bit 4 => Chapter 3 – Cave – (002.036.009.023) => 59 = Robe
$6629 : bit 4 => Chapter 6 – Cave – (002.035.002.009) => 05 = coins
$6629 : bit 3 => Chapter 6 – Cave – (010.033.010.012) => 1D = Iron Ore
$664C : bit 7 => Chapter 6 – Mian Zhu Guan – (001.029.003.006) => 49 = Battleax
$6630 : bit 7 => Chapter 7 – Cave 1 – (011.045.002.001) => 1F = Saltpeter
$6629 : bit 7 => Chapter 7 – Cave 2 – (011.039.000.008) => 34 = Elixir D
$6629 : bit 6 => Chapter 7 – Cave 2 – (010.037.003.015) => 50 = Nu Long
$6629 : bit 5 => Chapter 7 – Cave 2 – (002.036.002.012) => 6F = Steel H
$662F : bit 7 => Chapter 8 – Cave 1 – (009.044.013.024) => 38 = Power Pill
$662F : bit 6 => Chapter 8 – Cave 1 – (006.043.009.024) => 6D = Bronze H
$662F : bit 5 => Chapter 8 – Cave 1 – (012.043.015.018) => 2B = Smoke Pot
$662F : bit 4 => Chapter 8 – Cave 1 – (007.044.013.022) => 4D = Wan Sheng
$662F : bit 3 => Chapter 8 – Cave 1 – (005.044.013.022) => 65 = Plate M
$662F : bit 2 => Chapter 8 – Cave 1 – (003.044.013.022) => 6D = Bronze H
$662D : bit 7 => Chapter 8 – Cave 2 – (005.043.011.015) => 65 = Plate M
$662D : bit 6 => Chapter 8 – Cave 2 – (005.043.013.015) => 28 = Gullwing
$662D : bit 5 => Chapter 8 – Cave 2 – (007.043.011.015) => 34 = Elixir D
$662D : bit 4 => Chapter 8 – Cave 2 – (007.043.013.015) => 63 = Splint M
$662D : bit 3 => Chapter 8 – Cave 2 – (009.043.011.015) => 6E = Iron H
$662D : bit 2 => Chapter 8 – Cave 2 – (009.043.013.015) => 6F = Steel H
$662D : bit 1 => Chapter 8 – Cave 2 – (003.042.003.015) => 52 = Halberd
$662E : bit 7 => Chapter 8 – Cave 2 – (010.041.009.011) => 38 = Power Pill
$662E : bit 6 => Chapter 8 – Cave 2 – (000.042.015.011) => 4F = Qing Guang
$662E : bit 5 => Chapter 8 – Cave 2 – (010.042.011.012) => 28 = Gullwing
$662E : bit 4 => Chapter 8 – Cave 2 – (006.041.013.012) => 34 = Elixir D

Ref: http://faqs.ign.com/articles/974/974431p1.html#VIII.A

Placing items from this list is easy. Just put the world map address then the item ID in the ROM. For example, if I stand on the treasure chest in Fan Shui Guan I am at 01 1D 03 06. The contents of the treasure chest is an Ax (42). So in the ROM I see: "01 1D 03 06 42" at 0x309DD. If I change the 42 to 52 I get a halberd instead of an Ax :D Or to move the item you'd just give it a new map address.

Expanded Treasure Feature

Credit: MiDKnighT

The way DOAE normally works for treasure chests is that it looks up the location ID for where you are standing. It uses the location ID to find the starting treasure chest point using the tables at 0x30820 and 0x30890. It will then scan 8 chests of 5 bytes each looking for the chest that's either on your screen or that you are standing on. What does that mean for us modders?

  • We can't move chests outside of that range of 8 chests. We have seen this problem when we move a treasure chest in DoaEditor but then the game can't see the contents because it is outside of it's location ID spread of 8 chests.
  • You are limited to 8 chests per location ID.

So what this enhancement does is…

  • Makes chests movable to any location ID. Ie…every time we search for the chest on the screen we will search through ALL chests not just the 8 for our location ID. So you should be able to move chests to different caves, etc… without issue.
  • Expands the number of treasure chests from 44 to 102
  • You won't be able to see the new chests in DoaEditor until the DoaEditor Version 59 or above.
  • New chests are placed in first Guan Ping cave screen at 06.41 (first one is 01 29 01 06 02)
  • As a bonus, because I freed up some space on the OE page with this feature I threw in the change where you can see AGI with bonus in billeting (Billeting was not showing adjusted AGI before, just base AGI).
  • If you already have a working ROM chest Open / Close may be wonky depending on what you have in your save state. If you zero out $6600-$667F in memory all assigned chests should be closed and full of loot.
  • There are some caveats regarding the tent chests. The rules for these will be this:

Don't move the tent chests in location IDs 7A, 76, 4C, and 4D. In the original ROM these are:

Chapter 1 – Tie Men Xia – (001.029.003.006) => 42 = Ax
Chapter 2 – Fan Shui Guan – (001.029.003.006) => 42 = Ax
Chapter 3 – Chen Cang – (001.029.003.006) => 44 = Spear
Chapter 6 – Mian Zhu Guan – (001.029.003.006) => 49 = Battleax

In the ROM they are at 0x309D3:

011D030642 011D030642 011D030644 011D030649

  • Also there is at least one game event based on treasure that this feature breaks. Namely the Gold Key event where Guan Ping is waiting at the end. This change will allow Guan Ping to be waiting for you no matter what:

0x366a0:
008D08058D09058D0A05A90E854360EA
EAEAEAEAEAEAEAEAEAEA60AD6E674AB0

Treasure Feature Changes:

0x38150:
60200DD121006020A9D420E4C4209EC4
4C5B066868A9EA48A95448A2078E3164
20A5BBA90920C8E360EAEAEAEAEAEAEA
EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA
EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA
EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA
EAEAEAEAEAEAEA20008720D5C0207ACE

0x306B0:
A549C904F00160A5F3C9F7B00160A94C
85F3A98185F460EAEAEAEAEAEAEAEAEA
A90185F3A98885F4A447C07AD009E6F4
A9D285F3A23060C076D009E6F4A9CD85
F3A23160C04CD009E6F4A9C385F3A232
60C04DD008E6F4A9C885F3A233600000
A20020C086EAEAEAEAEAA000A98085F1
BD006685F2A000B1F3C8C560D017B1F3
C8C561D011B1F3C8C562D00BB1F3C8C5
63D005F00EC8C8C8C806F246F1C028D0
D6F01806F2B040B1F3856EEAEABD0066
05F19D0066A5F18D000160E8E028D003
4CCE8720A086A5F3C9F79014A90085F3
A5F4186901C98A90016085F4E84C0A87
A5F318692885F34C0A8768A99C486000
000000A20020C086EAEAA000BD006685
F2B1F3C8C51CD017B1F3C8C51DD011B1
F3C8C51ED00BB1F3C8C51FD005F038C8
C8C8C806F2C028D0D8E8E028D00568A9
674860A5F3C9F79014A90085F3A5F418
6901C98A90016085F4E84C9A87A5F318
692885F34C9A8768A9A5486000000000

Note that this section starting at 0x30810 is NOT in IPS 1.3 patch 2 so as to not overwrite chest locations. This section is the NEW chests that will be placed on Guan Ping's cave first page. If you have an existing mod and are just adding this enhancement you should copy this part in manually:

0x30810:
00012901060202290106020329010602
04290106020529010602062901060207
29010602082901060209290106020A29
0106020B290106020C290106020D2901
06020E29010602012902060202290206
02032902060204290206020529020602
06290206020729020602082902060209
290206020A290206020B290206020C29
0206020D290206020E29020602012903
06020229030602032903060204290306
02052903060206290306020729030602
082903060209290306020A290306020B
290306020C290306020D290306020E29
03060201290406020229040602032904
06020429040602052904060206290406
02072904060208290406020929040602
0x39390:
8DAF61ACAF60A9092053814C52EA205D

0x7D970:
C901D04BA90C2082C4209387EAEAEAEA
EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA
EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA
EAEAEAEAEAEAEAEAEAEAEAEAEAEA06F2

0xFD970:
C901D04BA90C2082C4209387EAEAEAEA
EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA
EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA
EAEAEAEAEAEAEAEAEAEAEAEAEAEA06F2

Changing the Chapter for the Region

Credit: MiDKnighT and Meteorstrike

Each region has a single digit to specify what chapter that region belongs to. This code will control what enemies you face and how much gold and experience you gain after battle. The chapter control digits start at 0x37df5:

000000000000044444000000
000000000000004444111100
000000000044444441111100
000000044444444411111100
000000443332222211111100
000000443332222221111100
000000044333322222111100
000000044333388888888888
000006665533338888888888
000066665553338888888888
000066665555555888888888
000066655555555778888888
000066655555555778778888
000006666655555777778888
000066666665555777778888
000066666677777777770000
000066666677777777770000
000066666677777777770000
000000000077777777770000
000000000077777777770000

Each number represents a chapter number (0-8). The chapter numbers are:

0=No Random Encounters
1=Yellow Turbans
2=Dong Zhuo
3=Yuan Shu
4=Yuan Shao
5=Jingzhou
6=Shu
7=Wu
8=Wei

Here is a picture showing these layed out on the map:

World_Chapters.jpg

Each number corresponds to a 'region' on the map. Want to change the Chapter 1 Xu Zhou area to be Chapter 8 (Wei)? Simply change all 1's to 8's in the above section. Knowledge of how the zones are layed out will allow us to *customize* enemy areas. Maybe the snow area will no longer be just chapter 4. Maybe it will be chapter 2 on the west side and chapter 3 on the east side. Or maybe you can break Wei up into separate chapters…

Special Map Regions:

The chapters for some regions are uneditable by DOAEditor and thus must be edited directly in the hex. Those special addresses are listed below.

QingZhou 37E16
Jian An 37EBA
Wu Cave 37EC9
Chen ?????

8 New Chapters

Credit: MiDKnighT

Basically I'm having 8 new chapters *share* rebel forces, etc… from previous chapters. The mapping is:

1 2 3 4 5 6 7 8
9 A B C D E F 0

Which means that chapter 9 will share chapter 1's rebel forces, chapter A will share chapter 2's rebel forces, etc… So you could split each chapter in 2 if you wanted to. So in chapter 9 you would see chapter 9's generals and chapter 1's rebel forces. In chapter 0 you would see chapter 0's generals and chapter 8's rebel forces. Here's the hex changes to make this happen:

0x399D2-0x399D4: AE3670
0x39AB7-0x39AB9: AD3670
0x3A49E-0x3A4A0: AE3670
0x3B311: 20E0BF
0x3B3CB: AD3670
0x3B3DD: AD3670
0x3BFF0: AD2660C9099002E908C901B002A9088D367060

Original ROM size:

0x3DFD3: 20E0BF
0x3E01D: AE2660
0x3E043: AE3670
0x3E092: AD36700A6D3670

1MB ROM:

0x7DFD3: 20E0BF
0x7E01D: AE2660
0x7E043: AE3670
0x7E092: AD36700A6D3670
0xFDFD3: 20E0BF
0xFE01D: AE2660
0xFE043: AE3670
0xFE092: AD36700A6D3670

Then put your new chapters on the map using the "Changing the Chapter for the Region" instructions and to put your general(s) in the new chapter you would change his "Region" value to the new chapter.

So…the logical chapter order would be:

1 9 – 2 A – 3 B – 4 C – 5 D – 6 E – 7 F – 8 0

Where "-" represents a switch to a stronger rebel force. So if you were to split the Yellow Scarves area you would use chapters 1 and 9. If you were to split Wei you would use chapters 8 and 0.

  • Note that chapters 1-5 and 9-D will have bandit forces, brigand, pirate, etc…

*** Note that this battle damage formula changes the same area of the ROM as the "Expanded Chapters" enhancement. If you want this enhancement *and* ludmeister's DoaE2-like damage enhancement do the following:

1. Add the Agility based extra attacks enhancement.

2. Add the DoaE2-like Damage enhancement.

3. Edit the following:

0×39826: "4cc7a1"

Original ROM size:

0x3a1d7: "4603 6604 88C0 00D0 F7A5 0418 6500 8515 4C17 98"

1MB ROM:

0x7a1d7: "4603 6604 88C0 00D0 F7A5 0418 6500 8515 4C17 98"
0xfa1d7: "4603 6604 88C0 00D0 F7A5 0418 6500 8515 4C17 98"

4. Add the 8 Chapters enhancement.

How the Map is Built

Credit: MiDKnighT (although Meteorstrike has figured a lot of this out before but it wasn't documented)

1. Location ID is stored in memory at $6013 and $47.

It all starts with the warp (see the warp section below). This is where it gets the location ID. Here it is getting the location ID for Xu Zhou:

A:00 X:01 Y:00 S:2E P:nvUbdIzc                  $06D0:A0 08     LDY #$08
A:00 X:01 Y:08 S:2E P:nvUbdIzc                  $06D2:B1 1A     LDA ($1A),Y @ $8383 = #$7E

Note that every time it uses a warp, it stores the what "hierarchy" it came from in $6012. That's how it knows to warp back to the world map when leaving Xu Zhou because it's going from hierarchy 01 to hierarchy 00.

Not every region on the map has it warp in it. But as Liu Bei is walking around the map, it doesn't matter. The PPU graphics, palette, etc… only change when it steps through a warp. Until that happens, it just keeps the same PPU graphics, palette, etc… that you had before.

Note that this presents a problem for loading map regions into DoaEditor that is documented here:
http://www.lordyuanshu.com/forums/topic/town-and-cave-editing/page/2/#post-53352

2. Look up which group of tiles are loaded into PPU memory.

How does it know which set of graphics to load?

A:00 X:0F Y:02 S:2A P:nvUbdIZC $BF38:A5 47 LDA $0047 = #$7E
A:7E X:0F Y:02 S:2A P:nvUbdIzC $BF3A:4A LSR
A:3F X:0F Y:02 S:2A P:nvUbdIzc $BF3B:A8 TAY
A:3F X:0F Y:3F S:2A P:nvUbdIzc $BF3C:B9 86 BF LDA $BF86,Y @ $BFC5 = #$55
A:55 X:0F Y:3F S:2A P:nvUbdIzc $BF3F:B0 04 BCS $BF45
A:55 X:0F Y:3F S:2A P:nvUbdIzc $BF41:4A LSR
A:2A X:0F Y:3F S:2A P:nvUbdIzC $BF42:4A LSR
A:15 X:0F Y:3F S:2A P:nvUbdIzc $BF43:4A LSR
A:0A X:0F Y:3F S:2A P:nvUbdIzC $BF44:4A LSR
A:05 X:0F Y:3F S:2A P:nvUbdIzc $BF45:29 0F AND #$0F
A:05 X:0F Y:3F S:2A P:nvUbdIzc $BF47:85 49 STA $0049 = #$00

What this is doing, loading the location ID (Xu Zhou / 7E), then LSR’ing it, transferring it to Y, and looking up from a table at $BF86-$BFC5 on page 0E (0x3bf95-0x3bfd5). Then it stores the value in $49 and uses it here to find where to look up tiles:

A:00 X:BA Y:00 S:28 P:nvUbdIZc $DEF5:A5 49 LDA $0049 = #$05
A:05 X:BA Y:00 S:28 P:nvUbdIzc $DEF7:0A ASL
A:0A X:BA Y:00 S:28 P:nvUbdIzc $DEF8:0A ASL
A:14 X:BA Y:00 S:28 P:nvUbdIzc $DEF9:0A ASL
A:28 X:BA Y:00 S:28 P:nvUbdIzc $DEFA:69 80 ADC #$80
A:A8 X:BA Y:00 S:28 P:NvUbdIzc $DEFC:85 01 STA $0001 = #$60
A:A8 X:BA Y:00 S:28 P:NvUbdIzc $DEFE:A9 00 LDA #$00
A:00 X:BA Y:00 S:28 P:nvUbdIZc $DF00:85 00 STA $0000 = #$78

So here it's going to use $A800 for the next lookup on the graphics page. $A800 = Town graphics:

World map graphics: 0x10010-0x1080f
Inside an Inn/House: 0x10810-0x1100f
Cave graphics: 0x11010-0x1180f
Inside castle graphics: 0x11810-0x1200f
Fortress graphics: 0x12010-0x1280f
Town graphics: 0x12810-0x1300f
Burnt Luo Yang: 0x13010-0x1380f

Now to put this info to use, let’s change Xu Zhou’s PPU tiles…

If I give Xu Zhou the "Burnt Luo Yang" graphics and palette I get some interesting results:

AWCicbP.png

Someone burnt down Xu Zhou!

3. Find the Map Region

First, the address in the warp when you walk into Xu Zhou is “0E 08 0F 01″ which is in the format Y1 Y2 X1 X2. With the Y2/X2 values being the region and the Y1/X1 values being the location on the region.

Now it will find the lookup table location for the region:

Load $1F which is the X2 value for the region (01), ASL (left shift) it, then store in $F3 (02).

Load $1D (Y2 value) which is 09 then multiply it by 40 which gives us 240. It then takes the “40″ and adds $F3 to it giving us 42. It then loads the “2″ from 240 and adds A7 to it giving us A9. This gives us the address to look up our region info which is $A942 which is used next.

Page 09 contains a table which includes a page number and a modifier. For example when I walk into Xu Zhou it loads the modifier at $A942 and $A943 which is 07 D5:

$D8D2:B1 10 LDA ($10),Y @ $A942 = #$D5 A:00 X:24 Y:00 S:22 P:nvUbdIZc
$D8D4:AA TAX A:D5 X:24 Y:00 S:22 P:NvUbdIzc
$D8D5:C8 INY A:D5 X:D5 Y:00 S:22 P:NvUbdIzc
$D8D6:B1 10 LDA ($10),Y @ $A943 = #$07 A:D5 X:D5 Y:01 S:22 P:nvUbdIzc

The ROM location for this table is at 0×26710-0x2770F so $A942 is at 0x26952.

Testing this… Let’s mess with the modifier and see what happens. I’ll replace D5 with DB and look what happens, it replaces an entire region in Xu Zhou:

bXgdHx8.png

4. Load the Map Tiles

So once it goes to page 07, it load D5 into memory then multiplies it by 8 which gives 0x06a8 and stores these values in $F4 (06) and $F3 (A8). Then it takes our 06a8 number and multiplies it by 8 again giving us 0x3540. Then it takes the “40″ and adds $F3 to it giving us E8 and it takes the “35″ number and adds $F4 to it giving us 0x3b then it takes that number and adds 0x80 to it giving us our region location which is $BBE8 on page 07 in this case. It uses $BBE8, applies a Y value, and looks up the tile here:

$D91E:B1 12 LDA ($12),Y @ $BC03 = #$8A A:1B X:06 Y:1B S:22 P:nvUbdIzc

Using this, I tracked down one of Xu Zhou’s regions stored at $BDE0 on page 07 which is 0x1FDF0. If I zero out that line look what happens:

GNBFIlt.png

5. Build the Map Tiles

Tracing how this tile is built:

DskcuSa.png

First it loads “C0″ (the tile ID) into memory via $D91E. Remember that in the world map there are 2 versions of “C0″. We have to figure out which one by loading the control code. More about that in Niahak’s old post here:

http://www.lordyuanshu.com/forums/topic/how-to-move-castles-change-graphics-etc-in-doae1#post-38133

So here it is loading the control code:

A:45 X:03 Y:45 S:22 P:nvUbdIzc $D931:B1 12 LDA ($12),Y @ $91FD = #$7F

7F = 01111111

This tile is in the middle of that row so it gets the high value “1″. Which means it’s tile # 2_192.

Blowing up the picture and looking at the PPU viewer you can see exactly how the small tiles make it up (4×4):

tbdll2o.png

To load the actual (small) tiles first it takes the tile ID. In this case "C0" and multiplies it by 4 (0x300) and stores it in $14 (00) and $15 (03). Then if the control code was "1" it adds 4 to $15 which gives us #07 (if control code was 0 it would stay at 03) then it loads the value from the table at D9B6. Testing this further I found that when it loads this value at $D944 the value for X is:

0 = World Map
1 = Inn/House, Caves, & Inside Castles
2 = Fortress, Town, & Burnt Luo Yang

So that table is at 0x3d9c6 (normal ROM) and 0x7d9c6/0xfd9c6 (expanded ROM): "80 8D 9A"

A:F0 X:FF Y:45 S:22 P:NvUbdIzC                              $D939:A5 15     LDA $0015 = #$03
A:03 X:FF Y:45 S:22 P:nvUbdIzC                              $D93B:69 03     ADC #$03
A:07 X:FF Y:45 S:22 P:nvUbdIzc                              $D93D:85 15     STA $0015 = #$03
A:07 X:FF Y:45 S:22 P:nvUbdIzc                              $D93F:A6 48     LDX $0048 = #$00
A:07 X:00 Y:45 S:22 P:nvUbdIZc                              $D941:A5 15     LDA $0015 = #$07
A:07 X:00 Y:45 S:22 P:nvUbdIzc                              $D943:18        CLC
A:07 X:00 Y:45 S:22 P:nvUbdIzc                              $D944:7D B6 D9  ADC $D9B6,X @ $D9B6 = #$80
A:87 X:00 Y:45 S:22 P:NvUbdIzc                              $D947:85 15     STA $0015 = #$07

This look up value (8700) will be used soon.

The value for Y in the next section depends on $1C which is derived from the Y1 value and $1E which is derived from the X1 value. I think the Y value used at $F657 and $F56D comes from which direction the character is walking so 00 should be ok. These values are stored at:

0x3F667 and 0x3F57D (normal ROM)
0x7F667, 0xFF667 and 0x7F57D and 0xFF57D (expanded ROM)

A:FF X:6E Y:00 S:22 P:NvUbdIzc                              $D80F:A6 61     LDX $0061 = #$08 <-- Y2
A:FF X:08 Y:00 S:22 P:nvUbdIzc                              $D811:86 1D     STX $001D = #$07
A:FF X:08 Y:00 S:22 P:nvUbdIzc                              $D813:A6 60     LDX $0060 = #$01 <-- Y1
A:FF X:01 Y:00 S:22 P:nvUbdIzc                              $D815:86 1C     STX $001C = #$09

$1C getting set basically translates to Y1.

A:F7 X:01 Y:00 S:22 P:NvUbdIzC                              $D82F:A6 63     LDX $0063 = #$01  <-- X2
A:F7 X:01 Y:00 S:22 P:nvUbdIzC                              $D831:86 1F     STX $001F = #$01
A:F7 X:01 Y:00 S:22 P:nvUbdIzC                              $D833:A6 62     LDX $0062 = #$0C  <-- X1
A:F7 X:0C Y:00 S:22 P:nvUbdIzC                              $D835:86 1E     STX $001E = #$0C

$1E getting set basically translates to X1.

Here is how it uses those values to generate a Y value which could be anywhere from 00 to 03:

A:00 X:02 Y:42 S:22 P:nvUbdIZc                              $D94E:A0 00     LDY #$00
A:00 X:02 Y:00 S:22 P:nvUbdIZc                              $D950:A5 1C     LDA $001C = #$05
A:05 X:02 Y:00 S:22 P:nvUbdIzc                              $D952:4A        LSR  <-- Right shift
A:02 X:02 Y:00 S:22 P:nvUbdIzC                              $D953:90 02     BCC $D957
A:02 X:02 Y:00 S:22 P:nvUbdIzC                              $D955:C8        INY
A:02 X:02 Y:01 S:22 P:nvUbdIzC                              $D956:C8        INY
A:02 X:02 Y:02 S:22 P:nvUbdIzC                              $D957:A5 1E     LDA $001E = #$0A
A:0A X:02 Y:02 S:22 P:nvUbdIzC                              $D959:4A        LSR  <-- Right shift
A:05 X:02 Y:02 S:22 P:nvUbdIzc                              $D95A:90 01     BCC $D95D
A:05 X:02 Y:02 S:22 P:nvUbdIzc                              $D95D:B1 14     LDA ($14),Y @ $9C2A = #$3A

It right shifts each one ($1C and $1E) and the original bit 0 is shifted into the carry.

Y starts as 0, then:
If X1 LSR (right shift) forces a binary “1″ into carry, then increase Y by 2
If Y1 LSR (right shift) forces a binary “1″ into carry, then increase Y by 1.

So any number that has a “1″ in the right most binary value will set the carry flag:

0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
1010 = 10
1011 = 11
1100 = 12
1101 = 13
1110 = 14
1111 = 15

So for example if X1 is 6 then it will not cause Y to increase. If X1 is 7 then Y will increase by 2. Same with Y1. If the carry flag is set for X1 it will increase Y by 2, if it’s set for Y1 then Y will increase by 1.

Then we grab that lookup value (8700 in this case from page 09), add the Y value, and pull the value then store it in Y:

A:03 X:00 Y:02 S:22 P:nvUbdIzc                              $D95D:B1 14     LDA ($14),Y @ $8702 = #$0E
...
A:0E X:00 Y:02 S:22 P:nvUbdIzC                              $D9B0:A8        TAY

Then it uses the Y value to re-populate $14 and $15 with:

A:00 X:00 Y:0E S:24 P:nvUbdIZc                            $F57D:A9 00     LDA #$00
A:00 X:00 Y:0E S:24 P:nvUbdIZc                            $F57F:85 14     STA $0014 = #$00
A:00 X:00 Y:0E S:24 P:nvUbdIZc                            $F581:A6 48     LDX $0048 = #$00
A:00 X:00 Y:0E S:24 P:nvUbdIZc                            $F583:BD BA F6  LDA $F6BA,X @ $F6BA = #$88
A:88 X:00 Y:0E S:24 P:NvUbdIzc                            $F586:85 15     STA $0015 = #$87

As for the table at $F6BA, I think it follows the same rules for the X value as before:

0 = World Map
1 = Inn/House, Caves, & Inside Castles
2 = Fortress, Town, & Burnt Luo Yang

This table lives at:

Normal Rom:

0x3f6ca: 88 95 A2

Expanded ROM:

0x7f6ca: 88 95 A2
0xff6ca: 88 95 A2

So now the lookup value is $8800 which it adds Y to next. It then loads the (small) tiles 4 at a time and it actually looks like it looks up the tile IDs on page 9:

A:10 X:10 Y:0E S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $880E = #$C0
A:11 X:11 Y:0E S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $890E = #$C1
A:34 X:34 Y:0E S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $8A0E = #$D0
A:35 X:35 Y:0E S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $8B0E = #$D1

A:12 X:12 Y:0F S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $880F = #$C2
A:13 X:13 Y:0F S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $890F = #$C3
A:36 X:36 Y:0F S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $8A0F = #$D2
A:37 X:37 Y:0F S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $8B0F = #$D3

A:10 X:10 Y:0C S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $880C = #$B0
A:11 X:11 Y:0C S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $890C = #$A1
A:34 X:34 Y:0C S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $8A0C = #$B0
A:35 X:35 Y:0C S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $8B0C = #$B1

A:12 X:12 Y:0D S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $880D = #$A2
A:13 X:13 Y:0D S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $890D = #$A3
A:36 X:36 Y:0D S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $8A0D = #$B2
A:37 X:37 Y:0D S:24 P:nvUbdIzc $F59E:B1 14 LDA ($14),Y @ $8B0D = #$B3

These are locations are coming from:

$880E = 0x2481E = C0
$890E = 0x2491E = C1
$8A0E = 0x24A1E = D0
$8B0E = 0x24B1E = D1

When it loads the actual tile ID (C0,C1,D0,D1, etc…), it’s giving the location in PPU memory starting with tile $80. That means for the world map, tile $80 is at 0x10010 and so on.

6. Load the Graphics Into PPU Memory

Next it actually loads the actual graphics into PPU memory. The graphics are located in these locations:

World map graphics: 0x10010-0x1080f
Inside an Inn/House: 0x10810-0x1100f
Cave graphics: 0x11010-0x1180f
Inside castle graphics: 0x11810-0x1200f
Fortress graphics: 0x12010-0x1280f
Town graphics: 0x12810-0x1300f
Burnt Luo Yang: 0x13010-0x1380f

And it loads them exactly how you see them in the FCEUX PPU Viewer. This is the first one loaded for Xu Zhou:

 1F:C3BD:B1 00     LDA ($00),Y @ $A800 = #$01
 1F:C3BF:8D 07 20  STA $2007 = #$95

Here's what it looks like in the PPU viewer (tiles $80-$FF):

NLMDJga.png

7. Load the Palettes

Here we see it starting to load the palette starting at $C655 in this case ($A3 is populated from $49 from step 2):

A:10 X:10 Y:38 S:27 P:nvUBdIzC                         $C5A8:A6 A3     LDX $00A3 = #$05
A:10 X:05 Y:38 S:27 P:nvUBdIzC                         $C5AA:BD B2 C6  LDA $C6B2,X @ $C6B7 = #$55
A:55 X:05 Y:38 S:27 P:nvUBdIzC                         $C5AD:85 F3     STA $00F3 = #$07
A:55 X:05 Y:38 S:27 P:nvUBdIzC                         $C5AF:BD C2 C6  LDA $C6C2,X @ $C6C7 = #$C6
A:C6 X:05 Y:38 S:27 P:NvUBdIzC                         $C5B2:85 F4     STA $00F4 = #$24
A:C6 X:05 Y:38 S:27 P:NvUBdIzC                         $C5B4:A0 00     LDY #$00
A:C6 X:05 Y:00 S:27 P:nvUBdIZC                         $C5B6:B1 F3     LDA ($F3),Y @ $C655 = #$01

The location look up value tables are at:

Normal ROM:

0x3C6C2-0x3C6D1: EF 11 22 33 44 55 66 77 77 88 99 B2 B2 B2 B2 B2
0x3C6D2-0x3C6E1: C5 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6

Expanded ROM:

0x7C6C2-0x7C6D1 & 0xFC6C2-0xFC6D1: EF 11 22 33 44 55 66 77 77 88 99 B2 B2 B2 B2 B2
0x7C6D2-0x7C6E1 & 0xFC6D2-0xFC6E1: C5 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6 C6

Palettes are stored in these locations.

Normal ROM:

0x3C5FF (World Map): 00 0F 27 29 1A 0F 00 30 29 0F 17 37 29 0F 20 31 11
0x3C621 (Inn/House): 01 27 16 00 0F 30 21 00 0F 38 27 00 0F 20 31 11
0x3C632 (Cave): 01 39 28 18 0F 37 27 17 0F 30 2B 1B 0F 20 2C 1C
0x3C643 (Inside Castle): 01 37 27 16 0F 30 25 37 0F 30 2B 27 0F 20 2C 27
0x3C654 (Fortress): 01 17 38 15 0F 17 29 19 0F 17 38 27 0F 20 38 17
0x3C665(Town): 01 27 37 15 0F 19 29 27 0F 20 10 27 0F 20 31 11
0x3C676 (Burnt Luo Yang): 01 27 37 15 0F 27 37 1A 0F 27 37 17 0F 20 10 11

Expanded ROM:

0x7C5FF & 0xFC5FF (World Map): 00 0F 27 29 1A 0F 00 30 29 0F 17 37 29 0F 20 31 11
0x7C621 & 0xFC621 (Inn/House): 01 27 16 00 0F 30 21 00 0F 38 27 00 0F 20 31 11
0x7C632 & 0xFC632 (Cave): 01 39 28 18 0F 37 27 17 0F 30 2B 1B 0F 20 2C 1C
0x7C643 & 0xFC643 (Inside Castle): 01 37 27 16 0F 30 25 37 0F 30 2B 27 0F 20 2C 27
0x7C654 & 0xFC654 (Fortress): 01 17 38 15 0F 17 29 19 0F 17 38 27 0F 20 38 17
0x7C665 & 0xFC665 (Town): 01 27 37 15 0F 19 29 27 0F 20 10 27 0F 20 31 11
0x7C676 & 0xFC676 (Burnt Luo Yang): 01 27 37 15 0F 27 37 1A 0F 27 37 17 0F 20 10 11

NES palettes:

pallettes.jpg

The remaining locations after these are other palettes (officer status screen, text etc…)

How DOAE Loads Tiles Into PPU Memory

Credit: MiDKnighT

So I tried to write directly to PPU memory using the instructions from:
https://github.com/battlelinegames/nes-starter-kit

Ie… write the PPU location to $2006 then do the actual write to PPU memory by writing to $2007. When I did this it worked but it caused the screen to glitch at times and the pointer at $2007 would sometimes move and overwrite things like officer names (not good). I figured my writes were competing with the game's writes. So to combat this I learned how the game writes to PPU memory and decided to piggy back onto that.

DOAE buffers PPU writes into $0400-$04FF. It keeps a pointer at $0040 and $0041 to determine a starting point. So when you want to write to DOAE PPU memory you have to load the current position from $0041 and starting writing from there. So for example if $0040 = #FB then you start writing at $04FB. And what do you write there?

A:01 X:FB Y:04 S:F6 P:NvUbdIzc  $DA09:BD 00 04  LDA $0400,X @ $04FB = #$00  Update graphics?  2006 PPU location 1
A:18 X:FC Y:01 S:F6 P:NvUbdIzc  $DA12:BD 00 04  LDA $0400,X @ $04FC = #$00  <--- 2006 PPU location 2
A:00 X:FD Y:01 S:F6 P:NvUbdIzc  $DA19:BD 00 04  LDA $0400,X @ $04FD = #$60 <--- how many tiles?

So if I wanted to write one tile to PPU location 2700 and my pointer was at $0040=#FB I'd have to do something like:

LDA 27  <----- PPU location 1
STA 04FB
LDA 00  <----- PPU location 1
STA 04FC
LDA 01  <---- one tile
STA O4FD
LDA 00 <---- STOP
STA O4FE
LDA FF
STA 0040 <---- updated  pointer location

Then you have to store the new pointer at $0040 which in this case would be #FF. Then you just call the game to write the graphics. I found one way of doing this is calling this function —> JSR $C09F which eventually calls $DA07 which is the actual function that loads the graphics.

You can use this information to write whatever items from PPU memory (see PPU viewer) you want onto the screen wherever you want.

Warps

Credit: Meteorstrike, MiDKnighT, and Boneduke

Warps happen whenever you step into a town or village, or even if you walk into a castle , store, or house while you are in town. You essentially teleport from one address to another address. Most of these warps are stored in the 0x1C### area of the ROM. There is the address of the place on the world map followed by the address of the entrance of a place. So if for example, you want to move a castle, here's what you would do…

Either use the latest DoaEditor and right click / move the warps. Or if you want the gory details:

1. With FCE Ultra or some emulator where you can view memory in real-time, watch $0060-$0063 when you walk around. Walk into your castle then walk out and don't move. That's where your "world map" warp is. Record this address…

2. Now use DoaEditor to remove the castle graphics on the map and put them somewhere else. Save your ROM.

3. Now go back into your emulator, walk to the spot where your castle entrance is, and record the address again.

4. Now find the old address in the ROM with a hex editor and change it to the new address.

However you're not done yet. If there was a castle battle at that address you will have to move that too. To do that see the BATTLES section below.

Thankfully, the battle address area of the ROM gives us the mailing address to most castles and gates. I have compiled a list here of castle world map entrances and town/inside addresses.

Place – World Map – Entrance – Location Code
LuoSang – 09070613 – 0C180618 – 7F
XuZhou – 0B070712 – 0E080F01 – 7E
QingZhou – 05060712 – 0E0B0002 – 7D
DaXing – 0A070211 – 0E0E0801 – 7C
TieMenXia – 0C090412 – 0E020C0A – 7B
HuLaoGuan – 080A0410 – 0E010D18 – 75
LuoYang1 – 0D09050E – 0E1A0707 – 21
LuoYang2 – C31A0707 – 0D0E001D – 71
YangZhou – 10A010D – 0907001D – 70
ChangAn – 09080A0A – 0E0B0F1D – 6F
Yuan – 030B060C – 0C13 081B – 6E
HuaiNan – 090C010B – 0E07071B – 6D
ChenCang – 030B010B – 0E1A041E – 6C
NanYang – 0B080209 – 0E170F1A – 6A
BoHai – 0507010B – 0E0F071A – 69
Chang – 0D070D0C – 0E010713 – 68
GuangZong – C3200708 – 05060017 – 67
JiZhou – 0D050D10 – 0A0C0F19 – 66
ChangSha – 0710010E – 0E1C0B1A – 65
GuiYang – 0912030E – 0E1E071E – 64
LingLing – 07100D09 – 0C1A081B – 63
WuLing – 890E0F0A – 0C1F0F1B – 62
LuoFengPo – 07140D04 – 0E100801 – 61
FuShui – 0D100907 – 0E1B0918 – 60
Luo – 030E0906 – 0E1E0318 – 5F
MianZhuGuan – 050D0605 – 0E120401 – 5E
ChengDu – 0B0C0107 – 0E1A0714 – 5D
JianAn – 0B14050B – 0E1C0514 – 5C
HuiJi – 0516090B – 0E140801 – 5B
Wu – 0D14010F – 0E1A0812 – 5A
PoYang – 080F070F – 0E010416 – 59
JinDu – 0D120F10 – 0E1F0912 – 58
JianYe – 09100D13 – 0E1F0F14 – 57
GuangLing – 0B0E0F15 – 0E1B070F – 56
HeFei – 0C0B0915 – 0E01040D – 55
RuNan – 0B0D0113 – 201E0910 – 54
ChenLiu – 060D0C0E – 0E01040F – 53
Chen – 0B0B090E – ? – 52
LuoYang – 0D09050E – ? – 51

In addition the first digit can be used to control the orientation of the party when arriving to the warp location.

0 - Screen fade in/out, Facing up/north, All party member sprites are visible/in order
1 - Screen wipe from right to left, party is collapsed and leading general faces up
2 - Screen fade in/out, Facing down/south, All party member sprites are visible/in order
3 - Screen wipe from right to left, party is collapsed and leading general faces down
4 - Screen fade in/out, Facing left/east, All party member sprites are visible/in order
5 - Screen wipe from right to left, party is collapsed and leading general faces left
6 - Screen fade in/out, Facing right/west, All party member sprites are visible/in order
7 - Screen wipe from right to left, party is collapsed and leading general faces right
8 - Screen fade in/out, Facing up/north, Party is collapsed under the leading generals sprite
9 - Screen wipe from right to left, party is collapsed and leading general faces up (seems to be same as 1)
A - Screen fade in/out, Facing down/south, Party is collapsed under the leading generals sprite
B - Screen wipe from right to left, party is collapsed and leading general faces down (seems to be same as 3)
C - Screen fade in/out, Facing left/east, Party is collapsed under the leading generals sprite
D - Screen wipe from right to left, party is collapsed and leading general faces left (seems to be same as 5)
E - Screen fade in/out, Facing right/west, Party is collapsed under the leading generals sprite
F - Screen wipe from right to left, party is collapsed and leading general faces right (seems to be same as 7)

For example if your target warp location is 0A2B0F1A you can the first "0A" to "4A" if you want the party facing left when the new location loads.

Screen fade in/out type warps can be used when transitioning to a place with different graphics - for example a warp from the world map into a cave. Screen wipe type warps can only be used when the source and target locations use the same graphics - for example from one section of a cave to another.

Note: This does not work with town warps - this must be controlled somewhere else yet to be determined. For example the warp for Jian An is 0E1C0514 - if it is changed to 2E1C0514 it will not change the orientation of the party from facing north to facing south. Rather it will simply warp to a different location altogether.

Also in some cases certain types seem to cause the game to freeze.

Warp Hierarchy

When you walk into a town, typically your "Hierarchy of the map" at $6011 will move up one. Then when you walk into an inn or shop your "Hierarchy of the map" will again move up another one. When you step out it decreases the "Hierarchy of the map" by 1 and takes you back to where you originally stepped in (the first warp address). Some warps DO NOT change the "Hierarchy of the map" for example when you step into a cave. We did some tracing and testing and found that there is not something in the warp itself that causes this. It is looking up MAP information to determine this. For example:

qafekng.png

See there is two versions of this tile…one of them was from the original Runan (which had the hidden cave exit - thus a traditional stack kinda warp wouldn't do for this castle). If you used a normal warp to walk into Runan then when you stepped into the cave then the world map the "Hierarchy of the map" would be wrong / corrupted. So the answer to this was to not raise the "Hierarchy of the map" when you walked into Runan. You can control if you want the hierarchy to change based on what tile you use.

And don't forget…there are…

Special considerations for warps:

  • There are also addresses for gullwings. These are generally 1 below the castle address. So Xu Zhou's gullwing address is 0C070712 and is stored at 0x38E04. After this the other "gullwing" castle addresses are stored. So after Xu Zhou's address is one tile south of Yang Zhou's address.
  • LuoSang village has 2 locations stored (09070613 and 09070713). 09070613 is the first warp and is at 0x1c370 while the other address is listed at 0×35564 and 0×36001.
  • There are at least 3 locations that I can think of that have 2 warps. Fan Shui Guan (Hua Xiong), Luo Yang (first Dong Zhou fight), and Guang Zong (Zhao Yun). These warp from the world map to another screen then to the castle. So for example Luo Yang's warps are:

0D09050E 0E1A0707 21 (warp to the field where you talk to Yuan)
C31A0707 0D0E001D 71 (warp to the entrance of the castle)

Battles

Changing the Battle Lineup

Credit: Meteorstrike, James, and Niahak (for DoaEditor changes)

Destiny of an Editor now supports battle editing!

For manual editing see: http://kongming.net/doae/rom_hacking/battles/

HEX OFFICER
03 Bandit Force
C8 Bao Long
02 Brigand Force
63 Bu Xi
18 Cai Yong
74 Cao Ang
70 Cao Cao
75 Cao Chun
73 Cao Hong
71 Cao Pi
72 Cao Ren
76 Cao Xiu
96 Cao Zhang
77 Cao Zhen
95 Cao Zhi
3B Chen Deng
1F Chen Ji
94 Chen Jiao
23 Chen Lan
34 Chen Lin
6A Chen Pu
90 Chen Qun
62 Chen Wu
44 Chen Ying
89 Cheng Yu
10 Cheng Yuan Zhi
79 Dian Wei
CB Ding Feng
BD Dong Min
BB Dong Zhuo
52 Fa Zheng
5F Fan Zhang
15 Fen Chou
CF Gan Ning
C2 Gao Lan
C9 Gao Pei
3F Gong Zhi
CE Gu Yong
AF Guan Ping
A4 Guan Suo
AC Guan Xing
A9 Guan Yu
12 Guo Ji
97 Guo Jia
33 Guo Tu
64 Han Dang
24 Han Xian
40 Han Xuan
38 Han Zhong
82 Hou Cheng
16 Hu Zhen
14 Hua Xiong
5E Huang Gai
53 Huang Quan
41 Huang Zhong
B8 Huo Hu
61 Jang Qin
1D Ji Ling
1A Jia Xu
8F Jiang Gan
D4 Jiang Wei
3E Jin Xuan
30 Ju Shou
6C Kan Ze
7C Le Xin
1E Lei Bo
4E Lei Tong
C6 Leng Bao
7D Li Dian
21 Li Feng
13 Li Jue
17 Li Ru
11 Li Su
37 Li Yan
22 Liang Gang
20 Liang Ji
60 Ling Tong
50 Liu Ba
A8 Liu Bei
AB Liu Chan
92 Liu Dai
35 Liu Du
AE Liu Feng
46 Liu Kui
4A Liu Xun
7F Liu Ye
47 Liu Zheng
BC Lu Bu (Dong Zhuo)
C4 Lu Bu (Ji Zhou)
C0 Lu Bu (Nan Yang)
B7 Lu Bu (Shu)
BF Lu Fan
C1 Lu Guang
6F Lu Ji
CC Lu Meng
65 Lu Su
69 Lu Sun
D1 Lu Wen
C3 Lu Xiang
B0 Ma Chao
B1 Ma Dai
9F Ma Liang
A0 Ma Su
2A Ma Yan
0F Ma Yuan Yi
8B Mao Jie
48 Meng Da
3D Mi Zhe
80 Niu Jin
B2 Pang De
9D Pang Tong
B4 Pirate
01 Pirate Force
04 Rebel Force
2E Shen Pei
8E Si Ma Shi
88 Si Ma Yi
8D Si Ma Zhao
0A Song Ren
8C Song Xian
0B Song Yong
56 Sun Ce [E]
9E Sun Gan
59 Sun Huan
57 Sun Quan
5A Sun Yi
58 Sun Yu
5D Tai Si Ci
D8 Tao Qian
31 Tian Feng
8A Wang Can
09 Wang Gui
93 Wang Lang
54 Wang Lei
87 Wang Shuang
81 Wei Xu
42 Wei Yan
2D Wen Hun
6D Wu Fan
4D Wu Lan
4C Wu Yi
85 Xia Hou De
7A Xia Hou Dun
84 Xia Hou Mao
86 Xia Hou Shang
7B Xia Hou Yuan
C5 Xing Dao Rong
D0 Xu Huang
BE Xu Rong
CA Xu Sheng
32 Xu Shou
D6 Xu Zhe
78 Xu Zhu
6B Xue Zong
D2 Xun Huo
D3 Xun You
2C Yan Liang
6E Yan Xun
4F Yan Yan
4B Yang Huai
B9 Yang Jin
43 Yang Ling
91 Yang Xiu
A5 Yi Ji [E]
7E Yu Jin
27 Yuan Shang
26 Yuan Shao
1B Yuan Shu
28 Yuan Tan
29 Yuan Xi
25 Yuan Yin
AD Zhang Bao
AA Zhang Fei
2F Zhang He
68 Zhang Hong
0C Zhang Jao
19 Zhang Ji
0E Zhang Liang
83 Zhang Liao
49 Zhang Ren
51 Zhang Song
1C Zhang Xun
2B Zhang Yi
67 Zhang Zhao
C7 Zhao Fan
D7 Zhao Yun
BA Zheng Mao
99 Zhou Cang
08 Zhou Chao
5C Zhou Tai
66 Zhou Yu
CD Zhu Ge Jin
D5 Zhu Ge Liang
5B Zhu Zhi
01 Pirate Force
02 Brigand Force
03 Bandit Force
04 Rebel Force
08 Zhou Chao
09 Wang Gui
10 Cheng Yuan Zhi
11 Li Su
12 Guo Ji
13 Li Jue
14 Hua Xiong
15 Fen Chou
16 Hu Zhen
17 Li Ru
18 Cai Yong
19 Zhang Ji
20 Liang Ji
21 Li Feng
22 Liang Gang
23 Chen Lan
24 Han Xian
25 Yuan Yin
26 Yuan Shao
27 Yuan Shang
28 Yuan Tan
29 Yuan Xi
30 Ju Shou
31 Tian Feng
32 Xu Shou
33 Guo Tu
34 Chen Lin
35 Liu Du
7F Liu Ye
37 Li Yan
38 Han Zhong
40 Han Xuan
41 Huang Zhong
42 Wei Yan
43 Yang Ling
44 Chen Ying
46 Liu Kui
47 Liu Zheng
48 Meng Da
49 Zhang Ren
50 Liu Ba
51 Zhang Song
52 Fa Zheng
53 Huang Quan
54 Wang Lei
56 Sun Ce
57 Sun Quan
58 Sun Yu
59 Sun Huan
60 Ling Tong
61 Jang Qin
62 Chen Wu
63 Bu Xi
64 Han Dang
65 Lu Su
66 Zhou Yu
67 Zhang Zhao
68 Zhang Hong
69 Lu Sun
70 Cao Cao
71 Cao Pi
72 Cao Ren
73 Cao Hong
74 Cao Ang
75 Cao Chun
76 Cao Xiu
77 Cao Zhen
78 Xu Zhu
79 Dian Wei
80 Niu Jin
81 Wei Xu
82 Hou Cheng
83 Zhang Liao
84 Xia Hou Mao
85 Xia Hou De
86 Xia Hou Shang
87 Wang Shuang
88 Si Ma Yi
89 Cheng Yu
90 Chen Qun
91 Yang Xiu
92 Liu Dai
93 Wang Lang
94 Chen Jiao
95 Cao Zhi
96 Cao Zhang
97 Guo Jia [F]
99 Zhou Cang
0A Song Ren
0B Song Yong
0C Zhang Jao
AD Zhang Bao
0E Zhang Liang
0F Ma Yuan Yi
1A Jia Xu
1B Yuan Shu
1C Zhang Xun
1D Ji Ling
1E Lei Bo
1F Chen Ji
2A Ma Yan
2B Zhang Yi
2C Yan Liang
2D Wen Hun
2E Shen Pei
2F Zhang He
3B Chen Deng
3D Mi Zhe
3E Jin Xuan
3F Gong Zhi
4A Liu Xun
4B Yang Huai
4C Wu Yi
4D Wu Lan
4E Lei Tong
4F Yan Yan
5A Sun Yi
5B Zhu Zhi
5C Zhou Tai
5D Tai Si Ci
5E Huang Gai
5F Fan Zhang
6A Chen Pu
6B Xue Zong
6C Kan Ze
6D Wu Fan
6E Yan Xun
6F Lu Ji
7A Xia Hou Dun
7B Xia Hou Yuan
7C Le Xin
7D Li Dian
7E Yu Jin
8A Wang Can
8B Mao Jie
8C Song Xian
8D Si Ma Zhao
8E Si Ma Shi
8F Jiang Gan
9D Pang Tong
9E Sun Gan
9F Ma Liang
A0 Ma Su
A4 Guan Suo
A5 Yi Ji [E]
A8 Liu Bei
A9 Guan Yu
AA Zhang Fei
AB Liu Chan
AC Guan Xing
AE Liu Feng
AF Guan Ping
B0 Ma Chao
B1 Ma Dai
B2 Pang De
B4 Pirate
B7 Lu Bu (Shu)
B8 Huo Hu
B9 Yang Jin
BA Zheng Mao
BB Dong Zhuo
BC Lu Bu (Dong Zhuo)
BD Dong Min
BE Xu Rong
BF Lu Fan
C0 Lu Bu (Nan Yang)
C1 Lu Guang
C2 Gao Lan
C3 Lu Xiang
C4 Lu Bu (Ji Zhou)
C5 Xing Dao Rong
C6 Leng Bao
C7 Zhao Fan
C8 Bao Long
C9 Gao Pei
CA Xu Sheng
CB Ding Feng
CC Lu Meng
CD Zhu Ge Jin
CE Gu Yong
CF Gan Ning
D0 Xu Huang
D1 Lu Wen
D2 Xun Huo
D3 Xun You
D4 Jiang Wei
D5 Zhu Ge Liang
D6 Xu Zhe
D7 Zhao Yun
D8 Tao Qian

The battles are listed in order starting at 0x30D70 and each contains 5 slots. One for each general ID. You can see the general IDs in DoaEditor on the Generals page.

Changing the Battle Location

Credit: Meteorstrike and MiDKnighT

Want to move a battle somewhere else? Sure… These are stored in our "world map" addresses. All the original battles are stored at:

BattleID Location Vert VertZone Horiz HorizZone
0 – Qing Zhou – 05 06 07 12
1 – Mt. Da Xing – 0A 07 02 11
2 – Tie Man Xia – 0C 09 04 12
3 – Qing Zhou (Cave) – 00 00 00 00
4 – Ma Yuan Yi – 00 00 00 00
5 – Qing Zhou (Front) – 05 06 07 12
6 – Si Shui Gate – 07 18 07 07
7 – Hu Lao Gate – 08 0A 04 10
8 – Luo Yang (Gate 1) *1* – 07 0A 08 0E
9 – Luo Yang (Gate 2) *2* – 03 0A 06 0E
A – Luo Yang – 03 1A 07 07
B – Yang Zhou – 01 0A 01 0D
C – Chang An (Gate 1) – 0B 08 00 0B
D – Chang An – 09 08 0A 0A
E – Yuan – 03 0B 06 0C
F – Huai Nan – 09 0C 01 0B
10 – Chen Cang Fortress – 03 0B 01 0B
11 – Nan Yang (Gate 1) – 05 09 02 09
12 – Nan Yang (Gate 2) – 01 09 00 09
13 – Nan Yang – 0B 08 02 09
14 – Bo Hai – 05 07 01 0B
15 – Xu Shou’s Fortress – 0D 07 0D 0C
16 – Guan Zhong – 03 20 07 08
17 – Yuan Shang (Town) – 00 00 00 00
18 – Ji Zhou (Gate 1) – 09 05 0D 10
19 – Ji Zhou (Gate 2) – 0B 05 0D 10
1A – Ji Zhou – 0D 05 0D 10
1B – Gui Yang – 00 00 00 00
1C – Ling Ling – 07 10 0D 09
1D – Ling Ling (Gate 1) – 03 10 0B 09
1E – Wu Ling – 09 0E 0F 0A
1F – Chang Sha – 07 10 01 0E
20 – Liu Kui’s Fortress – 07 14 0D 04
21 – Fu Shui – 0D 10 09 07
22 – Fu Shui (Gate 1) – 00 11 09 07
23 – Luo (Gate 1) – 01 0E 09 06
24 – Luo Castle – 03 0E 09 06
25 – Mian Zhu Guan Fortress – 05 0D 06 05
26 – Cheng Du (Gate 1) – 0D 0C 01 07
27 – Cheng Du – 0B 0C 01 07
28 – Ling Ling (Wu) – 07 10 0D 09
29 – Wu Ling (Wu) – 09 0E 0F 0A
2A – Jian An – 0B 14 05 0B
2B – Hui Ji Fortress – 05 16 09 0B
2C – Yan Xun *3* – 00 00 00 00
2D – Wu – 0D 14 01 0F
2E – Po Yang – 08 0F 07 0F
2F – Po Yang (Gate 1) – 0B 0F 07 0F
30 – Jin Du – 0D 12 0F 10
31 – Jin Du (Gate 1) – 0A 12 0F 10
32 – Lu Meng (Town) – 00 00 00 00
33 – Jian Ye (Gate 1) – 04 11 09 13
34 – Jian Ye (Gate 2) – 01 11 0A 13
35 – Jian Ye (Gate 3) – 0D 10 0A 13
36 – Jian Ye – 09 10 0D 13
37 – Guang Ling – 0B 0E 0F 15
38 – Guang Ling (Gate 1) – 0E 0E 0E 15
39 – He Nei Fortress – 0C 0B 09 15
3A – He Nei Fortress (Gate 1) – 05 0C 08 15
3B – Ru Nan (Gate 1) – 05 0D 02 13
3C – Ru Nan (Gate 2) – 08 0D 01 13
3D – Ru Nan – 0B 0D 01 13
3E – Chen Liu Fortress – 06 0D 0C 0E
3F – Chen Liu Fortress (Gate 1) – 08 0D 0C 0E
40 – Chen Jiao *4* – 00 00 00 00
41 – Xu Huang *5* – 00 00 00 00
42 – Chin – 0B 0B 09 0E
43 – Luo Yang (Gate 1) – 0B 0A 08 0E
44 – Luo Yang (Gate 2) – 07 0A 08 0E
45 – Luo Yang (Gate 3) – 03 0A 06 0E
46 – Luo Yang (Sima Zhao and Shi) – 0D 09 05 0E
47 – Luo Yang (Sima Yi) – 0D 09 05 0E
48 – Yuan Shao (Ambush) – 08 08 02 09
49 – Zhou Cang *6* – 00 00 00 00
4A – Huang Zhong and Wei Yan *7* – 00 00 00 00
4B – Pang Tong (Ambush) – 00 00 00 00
4C – Pirate Inn – 00 00 00 00
4D – Jian Ye (Taishi Ci) – 09 10 0D 13
4E – Ru Nan (Sima Yi) – 0B 0D 01 13
4F – Lu Bu (Shu Ambush) – 00 00 00 00

The battles with 0 0 0 0 address are triggered by an event (ie…talking to someone) or in Lu Bu and Pang Tong's case it comes as a random battle. For explanations on the *'s see: http://kongming.net/doae/rom_hacking/battles/

To change the battle location, the 4 address values are stored in:

0x30C10 = List of coordinate 1 positions for all boss battles.
0x30C68 = List of coordinate 2 positions for all boss battles.
0x30CC0 = List of coordinate 3 positions for all boss battles.
0x30D18 = List of coordinate 4 positions for all boss battles.

Ref: http://www.gamefaqs.com/boards/563402-destiny-of-an-emperor/47999342?page=4

Simply change all 4 values for the battle you are editing and the battle should be moved.

Enemy Soldier Counts

Are stored in 0x33EE0-0x33FDF. Each value is swapped. So "A2 01" = 100 and "85 00" = 418.

Battle Taunts

Credit: MiDKnighT

The opening line pointers for all battles are stored at 0x3AF21:

A6B7 AE00 0000 2324 8187 2628 8507 8081
8385 8387 8486 8200 8187 6D00 8084 8500
8084 8285 0086 8180 8582 8780 8683 8186
8180 0084 8182 FF86 82B9 8085 84BE D882
8386 DE84 8081 E7ED 5E00 0006 0060 D000

So A6 is the Qing Zhou battle, B7 is the Mt. Da Xing battle, AE is the Tie Man Xia battle, etc… The order of the battles can be found above. Which text bank it will use is at 0x3AF79:

0000 00FF FFFF 0101 0202 0101 0201 0202
0202 0202 0202 02FF 0202 02FF 0202 0203
0202 0202 0202 0202 0202 0202 0202 0202
0202 FF02 0202 FF02 0202 0202 0202 0202
0202 0202 0202 0202 0100 0003 FF02 02FF

Closing comments (like "Retreat they are too strong", etc…) are stored at 0x3B0A3:

CACA CA00 00D6 FF25 0000 27FF 0008 0000
0000 0058 0000 0000 0000 CF00 1000 0001
0000 0000 0100 0017 1B1A 0000 0000 0000
0000 0000 0000 6200 00BA 0000 0000 D900
0000 DF00 0000 ECEE 5F00 0007 0061 D3FA

Text banks for those are at 0x3B0FB:

0000 00FF FF80 FF01 FFFF 01FF FF81 FFFF
FFFF FF01 FFFF FFFF FFFF 81FF 83FF FF03
FFFF FFFF 02FF FF83 0303 FFFF FFFF FFFF
FFFF FFFF FFFF 02FF FF02 FFFF FFFF 02FF
FFFF 02FF FFFF 0202 01FF FF03 FF02 0202

Choose Battle Taunt Portraits

Credit: MiDKnighT

This enhancement will allow you to swap the opening or closing taunt portrait of any battle with whatever officer you want. The Taishi Ci battle at Jian Ye is the only battle in the game where someone else (Sun Quan) does the opening and closing taunt. This enhancement catches that spot at each place and diverts it to a lookup table on page 3D to replace the taunting officer's portrait. Here's the intercept points:

Opening Taunt:

A:1E X:BC Y:01 S:2C P:nvUbdIZc $AE5E:A6 75 LDX $0075 = #$0B <— Battle ID (Lu Bu gemsword battle)
A:1E X:0B Y:01 S:2C P:nvUbdIzc $AE60:E0 4D CPX #$4D <— Special Taishi Ci battle?
A:1E X:0B Y:01 S:2C P:NvUbdIzc $AE62:F0 F2 BEQ $AE56 <— Take a different code path

Then if it goes that direction, it loads Sun Quan's officer ID directly:

0E:AE56:A9 57 LDA #$57 <—- Sun Quan
0E:AE58:20 A9 CF JSR $CFA9

Using a debugger I swapped the value at $0075 and had Sun Quan talk instead of Lu Bu.

Closing Taunt:

0E:AFCC:A6 75 LDX $0075 = #$03 <— Load battle ID
>0E:AFCE:E0 4D CPX #$4D <— Special Taishi Ci battle?
0E:AFD0:F0 EF BEQ $AFC1 <— take a different code path

>0E:AFC1:20 B3 AB JSR $ABB3
0E:AFC4:A9 57 LDA #$57 <— Sun Quan
0E:AFC6:20 A9 CF JSR $CFA9

Hex Changes to use this enhancement (we have to add Sun Quan into the tables to keep the existing game Taishi Ci battle behavior):

0x3ae60:
38E901D0F660EA9820A9CF4C7DAEA93D
2082C4EABD69AFC9FFD00CA575C904D0

0x3afd0:
FF20B3ABA50020A9CF4CE7AFA93D2082
C4EABDEBB0C9FFD0034C5FB00A0820B3

0xf6e60:
00A90E2082C40000000000000000A90E
2082C4A675BDF0AFC900D0034C5EAEA8
4C51AE00000000000000000000000000

0xf6fc0:
000000000000000000000000A90E2082
C40000000000000000000000A90E2082
C4A675BDF0B0C900D0034CCCAF85004C
BCAF0000000000000000000000000000

0xf704d —> 57 (Sun Quan talks instead of Taishi Ci)
0xf714d —> 57 (Sun Quan talks instead of Taishi Ci)

Tables for storing which officer ID taunts for each battle:

Opening taunt officer table:
0xF70## where ## = battle ID

Closing taunt officer table:
0xF71## where ## = battle ID

Each value represents an officer ID. If it is "00" then the default behavior happens and the top enemy officer taunts.

Ambush Battles

Credit: Meteorstrike

The default ambush battles are:

Quote:
#$48 = 072 = (Nan Yang Outside) Yuan Shao
#$39 = 057 = (He Fei) Cao Pi
#$3D = 061 = (Ru Nan) Cao Pi
#$4E = 078 = (Ru Nan) Si Ma Yi
If, on the other hand, you want to change the 4 possible ambush battles to be different ones, OR get rid of them altogether, you can do this very easily:

0x39CEB = First boss battle that will be an ambush. (Should be 0×48 by default)
0x39CEF = Second boss battle that will be an ambush. (Should be 0×39 by default)
0x39CF3 = Third boss battle that will be an ambush. (Should be 0x3D by default)
0x39CF7 = Fourth boss battle that will be an ambush. (Should be 0x4E by default)

By changing the values at the above addresses, you will change the hard-coded opcodes that will test for the ambush-able boss battles… the values to use here are the boss battle IDs. A list of all the boss battle IDs can be found in the Damage Calculator.

If you want to get rid of ambush-able battles, simply use FF for the boss battle ID, since there is no boss battle with ID of FF.

Ref: http://www.gamefaqs.com/boards/563402-destiny-of-an-emperor/47999342?page=3

Random Enemies

Credit: Meteorstrike, James, sonic penguin, and ludmeister

Random enemy info is documented very well in this post:

Editing Guide for Rebels, Bandits, Brigands and Pirates
Below you can find all the information you need to edit strength, intelligence, agility, attack power, defense power, and soldiers for the Rebels, Bandits, Brigands and Pirates through the game. Thanks go out to MeteorStrike! If not for his research this would not be possible.

Random Enemies' Strength/Intelligence/Agility
Strength, Intelligence and Agility values for Bandits, Brigands, Pirates and Rebels are stored in two tables, one for Bandits, Brigands and Pirates, and another dedicated to Rebels, with eight entries—one for each chapter—and three hexadecimal values for each entry. Each entry’s hexadecimal values correspond to Strength, Intelligence and Agility. Strength and Agility are modified by a variance factor (see STR/INT Variance Factor below) but Agility is assigned as a raw value. Please note that if Strength or Intelligence are increased above 255 by the variance factor they will reset to 0 and start counting up from there. Values below 213 for Strength and Intelligence are probably safe unless a higher variance has been entered.

random_str_int_agi.png

Original ROM Size:

0x3E45B = Pirate/Brigand/Bandit Force

1MB ROM:

0x7E45B = Pirate/Brigand/Bandit Force
0xFE45B = Pirate/Brigand/Bandit Force

Code:
Ch.1 20 17 04 = 32 23 04
Ch.2 24 1A 0C = 36 26 12
Ch.3 2A 1E 14 = 42 30 20
Ch.4 30 22 1C = 48 34 28
Ch.5 37 27 28 = 55 39 40
Ch.6 3F 2D 38 = 63 45 56 * Rebel Force only in Shu
Ch.7 49 34 48 = 73 52 72 * Rebel Force only in Wu
Ch.8 54 3C 58 = 84 60 88 * Rebel Force only in Wei
0x3E473 = Rebel Force (0x7E473 and 0xFE473 for 1MB ROM)

Code:

Ch.1  2A 1E 08 = 42 30 08
Ch.2  30 23 18 = 48 35 24
Ch.3  38 28 28 = 56 40 40
Ch.4  40 2E 38 = 64 46 56
Ch.5  49 34 50 = 73 52 80
Ch.6  54 3C 70 = 84 60 112
Ch.7  61 45 90 = 97 69 144
Ch.8  6F 50 B0 = 111 80 176

0x3E48B = STR/INT Variance Factor (0x7E48B and 0xFE48B for 1MB ROM)

Strength, Intelligence and Agility values for Bandits, Brigands, Pirates and Rebels are randomized based on one of sixteen hexadecimal values stored at 0x3E48B, which are, by default, 00 = 0, 19 = 25, 26 = 38, or 33 = 51. There are many duplicate entries. To determine the variance this value is applied to the equation 1+($value/256). Please see below for formulas for the game’s default values. And also note that if your multipliers create numbers larger than 255 they will cycle down to 0 an start counting up again.

random_str_int_agi_variance.png

Code:

00 = 1 + ( 0 / 256 ) = 1.00
19 = 1 + ( 25 / 256 ) =~ 1.10
26 = 1 + ( 38 / 256 ) =~ 1.15
33 = 1 + ( 51 / 256 ) =~ 1.20

Random Enemies' Attack

Attack values are stored with one hexadecimal entry per chapter per unit of Pirate, Brigand, Bandit and Rebel Force. Pirates, Brigands and Bandits share attack values, but Rebels have their own table. To change defense values enter the desired value from the Weapon Selection Table below. Please note that the hexadecimal values entered correspond to a weapon in the game, not to a raw value (e.g. 09 would give the unit the same attack power as the Sword, which is 120 assuming you haven’t changed it elsewhere in the ROM).

random_attack.png

0x3E49B = Pirate/Brigand/Bandit Force (0x7E49B and 0xFE49B for 1MB ROM)

Code:

Ch.1  03 = 20 (Ax)
Ch.2  04 = 30 (Club)
Ch.3  04 = 30 (Club)
Ch.4  05 = 50 (Spear)
Ch.5  05 = 50 (Spear)
Ch.6  06 = 70 (Sabre)      * Rebel Force only in Shu
Ch.7  07 = 100 (Trident)   * Rebel Force only in Wu
Ch.8  08 = 80 (Bow)        * Rebel Force only in Wei

0x3E4A3 = Rebel Force (0x7E4A3 and 0xFE4A3 for 1MB ROM)

Code:

Ch.1  02 = 15 (Flail)
Ch.2  03 = 20 (Ax)
Ch.3  03 = 20 (Ax)
Ch.4  04 = 30 (Club)
Ch.5  04 = 30 (Club)
Ch.6  05 = 50 (Spear)
Ch.7  05 = 50 (Spear)
Ch.8  06 = 70 (Sabre)

Weapon Selection Table

Code:

00 =   0  (N/A)
 01 =  10  (Dagger)
 02 =  15  (Flail)
 03 =  20  (Ax)
 04 =  30  (Club)
 05 =  50  (Spear)
 06 =  70  (Sabre)
 07 = 100  (Trident)
 08 =  80  (Bow)
 09 = 120  (Sword)
 0A = 140  (Battleax)
 0B = 150  (Scimitar)
 0C = 130  (Crossbow)
 0D = 170  (Lance)
 0E = 190  (Wan Sheng)
 0F = 190  (Bo Ye)
 10 = 240  (Qing Guang)
 11 = 240  (Nu Long)
 12 = 240  (Qing Long)
 13 = 250  (Halberd)

Random Enemies' Defense

Attack values are stored with one hexadecimal entry per chapter per unit of Pirate, Brigand, Bandit and Rebel Force. Pirates and Brigands share defense values, but Bandits and Rebels have their own tables. To change defense values enter the desired value from the Defense Selection Table below.

random_defense.png

0x3E4BB = Pirate/Brigand Force (0x7E4BB and 0xFE4BB for 1MB ROM)

Code:

 Ch.1  00 = 10
 Ch.2  00 = 10
 Ch.3  01 = 20
 Ch.4  02 = 25
 Ch.5  03 = 35
 Ch.6  04 = 40   * Rebel Force only in Shu
 Ch.7  05 = 45   * Rebel Force only in Wu
 Ch.8  06 = 48   * Rebel Force only in Wei

0x3E4C3 = Bandit Force (0x7E4C3 and 0xFE4C3 for 1MB ROM)

Code:

Ch.1  00 = 10
 Ch.2  00 = 10
 Ch.3  01 = 20
 Ch.4  01 = 20
 Ch.5  02 = 25
 Ch.6  03 = 35   * Rebel Force only in Shu
 Ch.7  04 = 40   * Rebel Force only in Wu
 Ch.8  05 = 45   * Rebel Force only in Wei

0x3E4B3 = Rebel Force (0x7E4B3 and 0xFE4B3 for 1MB ROM)

Code:

Ch.1  00 = 10
 Ch.2  01 = 20
 Ch.3  02 = 25
 Ch.4  03 = 35
 Ch.5  04 = 40
 Ch.6  05 = 45
 Ch.7  06 = 48
 Ch.8  07 = 50

Defense Selection Table

Code:

 00 = 10
 01 = 20
 02 = 25
 03 = 35
 04 = 40
 05 = 45
 06 = 48
 07 = 50
 08 = 60
 09 = 70
 15 = 80
 0B = 85
 16 = 90
 28 = 95
 0D = 100
 0A = 110
 43 = 130
 0C = 160
 0E = 170
 0F = 180
 48 = 185
 59 = 200
 C3 = 215
 C8 = 230
 51 = 244
 1F = 255

Random Enemies' Soldiers

There are four possible soldier values for Bandit, Brigand, Pirate and Rebel Forces in each chapter. Whenever a unit is generated it is assigned one of the values below. Values are stored in two pairs. To convert to decimal reverse each hex value, treat as a single value, and convert to decimal (e.g. 0E 01 = 10E = 270). Do this in reverse to make a proper two-party hexadecimal entry into the ROM.

random_soldiers.png

Chapter 1 0x3E41B (0x7E41B and 0xFE41B for 1MB ROM)

Code:

 64 00 = 100
 64 00 = 100
 78 00 = 120
 8C 00 = 140

Chapter 2 0x3E423 (0x7E423 and 0xFE423 for 1MB ROM)

Code:

 78 00 = 120
 78 00 = 120
 96 00 = 150
 B4 00 = 180

Chapter 3 0x3E42B (0x7E42B and 0xFE42B for 1MB ROM)

Code:

 C8 00 = 200
 DC 00 = 220
 E6 00 = 230
 FA 00 = 250

Chapter 4 0x3E433 (0x7E433 and 0xFE433 for 1MB ROM)

Code:

 E6 00 = 230
 FA 00 = 250
 0E 01 = 270
 2C 01 = 300

Chapter 5 0x3E43B (0x7E43B and 0xFE43B for 1MB ROM)

Code:

 2C 01 = 300
 40 01 = 320
 5E 01 = 350
 7C 01 = 380

Chapter 6 0x3E443 (0x7E443 and 0xFE443 for 1MB ROM)

Code:

 BC 02 = 700
 52 03 = 850
 84 03 = 900
 E8 03 = 1000

Chapter 7 0x3E44B (0x7E44B and 0xFE44B for 1MB ROM)

Code:

 E8 03 = 1000
 4C 04 = 1100
 B0 04 = 1200
 14 05 = 1300

Chapter 8 0x3E453 (0x7E453 and 0xFE453 for 1MB ROM)

Code:

 DC 05 = 1500
 72 06 = 1650
 08 07 = 1800
 6C 07 = 1900

Many thanks to MeteorStrike for making this possible!
Ref: http://the-scholars.com/viewtopic.php?f=3&t=19872&st=0&sk=t&sd=a&start=10#p487840

To change the portrait of pirate force, brigand force, bandit force, rebel force, or even the Wu pirates, you need to first change the background from black 00 to some other color such as white 09. Once that is done, simply replace the 6 slices/strips for each force found below. – Keep in mind that these values can CHANGE as the rom is edited. These are *relatively accurate* values but not necessarily precise.

Sprites:
32803 Pirate Sprite
32824 Brigand Sprite
32846 Bandit Sprite
32867 Rebel Sprite

Pirate Force Portrait Color 32810
Pirate Force Portrait Strips 3280A-3280F

Brigand Force Portrait Color 32831
Brigand Force Portrait Strips 3282B-32830

Bandit Force Portrait Color 32853
Bandit Force Portrait Strips 3284D-32852

Rebel Force Portrait Color 32874
Rebel Force Portrait Strips 3286E-32873

Pirate (in Wu House) Portrait Color 33A35
Pirate Portrait Strips 33A2F-33A34

For example, if I change
32810 to 09
3280A to 00
3280B to 01
3280C to 02
3280D to 03
3280E to 04
3280F to 05

Then we will get Liu Bei's portrait to appear every time we encounter a Pirate Force. Pretty scary huh?

Note: The 6th Hex value BEFORE the first portrait slice controls the AP/Color of the Force. The 7th Hex value BEFORE the first portrait slice will allow you to change the sprite. These have address but I haven't typed them out yet.

Manually Editing Officer Stats

Credit: Niahak w/notes by sonic penguin

Here is a more accurate breakdown of how officer data is displayed in the hex:
Officer structure notes (from various sources, as well as DoaEd code).
Raw Hex Values: for example FF=255
ID # – this is not a raw hex number, it is a pointer to another table where the data is stored. This data can be easily referenced to in the ‘tables’ folder of DOAEditor.

STR – (Raw Hex Value)
INT (Raw Hex Value)
Region (chapter in which they are encountered) (Raw Hex Value)
Sprite (Graphic) (ID # from doae table)
Sprite Color (ID # from doae table)
DP as Enemy (ID # from doae table)
Soldiers (Enemy) (ID # from doae table)
Soldiers (Ally) (ID # from doae table)
Tactics (ID # from doae table)
AGI (Raw Hex Value)
Portrait Slice 1
Portrait Slice 2
Portrait Slice 3
Portrait Slice 4
Portrait Slice 5
Portrait Slice 6
Portrait BG (single-color BG only)
Page the portrait slices are found in (F0-FF)
unknown
Name Spacing
Officer Name

ludmeister: The game only allows Rebel Forces to attack you in Shu/Wu/Wei. If the game determines that the battle that is taking place is in one of these regions, normal encounters will be with Rebel Forces. I wanted to change this behavior, and allow the other "forces" to attack me. Here's how you do this:

Code:
0x3b315: "06" -> "09"
Also, if you want a different force to default to attack you when officers attack, here's where you'd change that:

Code:
0x3b319: "04" ->
"01" for Pirate Force
"02" for Brigand Force
"03" for Bandit Force

Soldier Bars

Credit: ludmeister and sonic penguin

In 0x3adfe-0x3ae13, we find data pertaining to how long the soldier line visualization is in battle, and the soldier count thresholds for when those lengths change (along with the color). I have not figured out where the color info is.

The length/color used is determined by the allied general who has the most soldiers when at maximum.

0x3adfe-0x3ae09: # of soldiers per pixel length
0a28 64c8 2c90 (Byte 1)
0000 0000 0101 (Byte 2)

000a (10), 0028 (40), 0064 (100), 00c8 (200), 012c (300), 0190 (400)

0x3ae0a-0x3ae13: Threshold value.
0107 1327 3a (Byte 2)
f4d1 8911 99 (Byte 1)

01f4 (500), 7d1 (2001), 1389 (5001), 2711 (10001), 3a99 (15001)

Changing these to more well-spaced-out values makes it possible to see the variations in late Wei soldier totals, as stock DoaE green soldier bars top out when an officer is currently leading around 25000 men.

Example change:

"0a1e 50c8 fae8
0000 0000 0103
0105 0f27 61
f4dd a111 a9"

Thresholds: 500, 1501, 4001, 10001, 25001
Soldiers/pixel: 10, 30, 80, 200, 500, 1000

Soldier Bar Color

The soldier bar color can be changed by modifying the values between 3ADF8-3ADFD. If I changed 3ADF8 to 19, then my pink bars turn green! Each of the 6 values controls the color of the bar for each of the colors in game. The stock colors are pink, orange, pale yellow, sky blue, and light green. You will need to refer to the color palette for color choices.

pallettes.jpg

Gold Awarded for Winning Battles and Item Sales

Credit: ludmeister

0x39ad7-0x39ae6: Gold awarded per chapter multipliers
0014 0028 003d 007a 00cc 0199 02cc 0400

For some reason, these are not stored like other values are, and are meant to be read as I divided them. So those multipliers are:

20 (Yellow Scarves campaign)
40 (Dong Zhou)
61 (Yuan Shu)
122 (Yuan Shao)
204 (Jing Zhou)
409 (Shu)
716 (Wu)
1024 (Wei)

One more little tidbit that controls the cash flow of the game, especially as your army begins swapping out expensive weapons/armor for more expensive ones… the sell rate that item shops observe. The multiplier is 75%, and this is found in the code here:

Code:
0E:8F17:A9 C0 LDA #$C0 <– Rate of selling, out of 255.
Therefore, to change this rate of exchange, edit this byte:

Code:
0x38f28: "c0"
"40" would be 25%, "80" would be 50%, and so on.

Give 1/4th More Gold If Battling an Enemy Officer

Credit: MiDKnighT

This is for 1MB ROMs only.

The idea is that fighting officers is harder than fighting bandits so you should get a bonus for fighting officers right? This enhancement gives you 1/4th more gold for fighting officers:

Gold bonus by 1/4th for defeating enemy general:

0x39AC0: 
15BDC69A8514A93E2082C4EAEAEAEAEA
EAEAEAEAEAEA60000D001B002A004B00

0xF9AB0:
000000000000205FC1A41CF007A90585
15205BC168AAA90E2082C4ADAF6018C9
0590E3A51148A51048A5148510A51585
114611661046116610EAEAEAEA18A514
65108514A51569008515688510688511
4CA69A00000000000000000000000000

Version 2 of this feature.

This will drop an additional 1/8th food for each of the first 3 enemy generals on the list (they must have a general ID > 5). So….

1/8th more gold if there is one enemy general fought
1/4th more gold if there are two enemy generals fought
3/8th more gold if there are three enemy generals fought

Changes:

0x39AC0: 
15BDC69A8514A93E2082C4EAEAEAEAEA
EAEAEAEAEAEA60000D001B002A004B00

0xF9AB0:
000000000000205FC1A41CF007A90585
15205BC168AAA90E2082C4ADAF60C905
90E4A51148A51048A5148510A5158511
46116610461166104611661018A51465
108514A51569008515ADB060C905900D
18A51465108514A51569008515ADB160
C905900D18A51465108514A515690085
156885106885114CA69A000000000000

Note that both versions seem to give more rations if fighting enemy officers too.

Enemy Generals Dropping Food After Random Battles

Credit: MiDKnighT

This enhancement allows for the enemy to drop food *IF* there is an actual general leading the enemy (ie… General ID > 5)

0x3A400: 
05CA10F420E2C0C612D0EBA93E2082C4
EAEAEAEAEAEA200DD13D004C13A4200D

0xFA410:
4C10A42082C4000000A90E2082C40000
A57AF0034C18E6ADAF6018C905B0034C
09A4A90E4C03A4000000000000000000

Note that I have not messed with the food amount in this enhancement. The game determines that. So with that said I'd adjust the "food consumption" to balance this.

Spoils of War – POL version (uses POL to determine drop rate)

Credit: ludmeister (with some minor additions by MiDKnighT)

It requires at least a 512K ROM, and uses page 1E for its work.

0x3a547:

Code:
"A900 8573 20D79A A202 1E0005 38 7E0005 CA 10F6" -> "a91e 2082c4 200d82 2095d4 ea a900 8573 20d79a"
0x7a530:

Code:

 A200A9009D05629DAF60E8E006D0F560
 00000000000000A90E2082C44C50A5EA
 2082C400000000000000000000000000
 2020A52050A6A2021E0005387E0005CA
 10F6A92EC500F00FA5AD65604A65AF65
 10297FC56E3005A90E4C40A565AE4A65
 61651165AD290F856EAD3670AACA8A29
 070A0A0A0A656E856EEAEAEAA5AE6552
 651165626563297FC9153010A56EA8B9
 D0A5856EA900856F4C37A5EAA56EA8B9
 50A6856EA900856F4C37A5EA00000000
 31313131313131313132303030282B2C
 313131313131323232303030282B2C38
 323232323232323330303028282B2C38
 323232333333303028282B2B2C2C3838
 32333333333330302828282B2C2C3838
 33333333333334303028282B2C2C3838
 34343434343434303028282B2C2C3838
 343434343434302128282B2B2C2C3838
 AD9060AABD2064C900D005A908856E60
 4A4A4A4A856E60000000000000000000

0x7a560: This contains the algorithm guts. It decides whether something was found, and if so, whether it was a rare drop or not. Then, it picks a random item from 0 to 15, and gets that item from the correct chapter. Extra chapters are treated as the normal chapter of the same rank (Extended Wu would be treated as Wu).

0x7a5e0 – 0x7a65f: These are the random common drops. 8 regions, 16 items per region. This item table just has ordinary items (Elixirs, Gullwings, Steeds, Power Pills, Revives, and Smoke Pots), except for one Red Hare in Wei's region.

EDIT: Alternately, this table weaves in some gold and ration drops:

Code:

01010731313131313132303030282B2C
 010208313131323232303030282B2C38
 020309093232323233303028282B2C38
 03040A3232333333303028282B2C2C38
 04040A33333333303028282B2C2C3838
 04050A0B3333333334303028282B2C38
 05060B0C34343434343028282B2C2C38
 060C0C34343434213028282B2C2C3838

0x7a660 – 0x7a6df: These are the random rare drops. 8 regions, 16 items per region. You will probably want to make these more helpful drops, such as equipment, as they can be offered rarely and thus can be made to not totally break the game. The format for this table is exactly the same as the common drop table.

Party leader's POL attribute affects how often items are dropped. If your party leader has higher POL you will get more item drops.

You can change the ratio of rare to common drops. The value to change is in this instruction:

Code:

1E:A59C:C9 15     CMP #$15

This is the chance, out of 128, that this current drop is rare, as when execution reaches this instruction, we know we are receiving a drop. Change 0x7a5ad, making the value smaller to make rare drops more rare, and larger to make them more common. If you change this value to greater than 0×40, you would be making "rare" drops more common than "common" drops– silly you :geek: . Default chance for this drop to be rare is 20/128, or 5 out of 32.

3. Obviously, you can change the items that drop. It does seem that you can make more gold coins or food rations drop. I don't recommend that you allow reception of items that you cannot sell or discard :wink:

Spoils of War Original (does not use POL to determine drop)

Credit: ludmeister

First, here are the Hex changes to the ROM. It requires at least a 512K ROM, and uses page 1E for its work.

0x3a547:
Code:
“A900 8573 20D79A A202 1E0005 38 7E0005 CA 10F6″ -> “a91e 2082c4 200d82 2095d4 ea a900 8573 20d79a”

0x7a547:
Code:
a90e 2082c4 4c50a5 ea 2082c4

0x7a560: This contains the algorithm guts. It decides whether something was found, and if so, whether it was a rare drop or not. Then, it picks a random item from 0 to 15, and gets that item from the correct chapter. Extra chapters are treated as the normal chapter of the same rank (Extended Wu would be treated as Wu).

Code:

a202 1e0005 38 7e0005 ca 10f6 a5ad 6560
4a 65af 6510 297f c908 3005 a90e 4c40a5
65ae 4a 6561 6511 65ad 290f 856e ad3670
aa ca 8a 2907 0a 0a 0a 0a 656e 856e eaeaea
a5ae 6552 6511 6562 6563 297f c915 3010
a56e a8 b9d0a5 856e a900 856f 4c37a5 ea
a56e a8 b950a6 856e a900 856f 4c37a5 ea

0x7a5e0 – 0x7a65f: These are the random common drops. 8 regions, 16 items per region. This item table just has ordinary items (Elixirs, Gullwings, Steeds, Power Pills, Revives, and Smoke Pots), except for one Red Hare in Wei’s region.
Code:

31313131313131313132303030282B2C
313131313131323232303030282B2C38
323232323232323330303028282B2C38
323232333333303028282B2B2C2C3838
32333333333330302828282B2C2C3838
33333333333334303028282B2C2C3838
34343434343434303028282B2C2C3838
343434343434302128282B2B2C2C3838

EDIT: Alternately, this table weaves in some gold and ration drops:

Code:

01010731313131313132303030282B2C
010208313131323232303030282B2C38
020309093232323233303028282B2C38
03040A3232333333303028282B2C2C38
04040A33333333303028282B2C2C3838
04050A0B3333333334303028282B2C38
05060B0C34343434343028282B2C2C38
060C0C34343434213028282B2C2C3838

0x7a660 – 0x7a6df: These are the random rare drops. 8 regions, 16 items per region. You will probably want to make these more helpful drops, such as equipment, as they can be offered rarely and thus can be made to not totally break the game. The format for this table is exactly the same as the common drop table.

Helpful tips to make Battle Spoils work for you

1. You can make all drops more or less common. The value to change is in this instruction:

Code:
1E:A567:C9 08 CMP #$08

This determines the chance, out of 128, to gain an item. Change 0x7a578, making it larger to make drops more common, and of course make it smaller to make drops more rare. Default drop chance is 8/128, or 1 in 16.

2. You can change the ratio of rare to common drops. The value to change is in this instruction:

Code:
1E:A59C:C9 15 CMP #$15

This is the chance, out of 128, that this current drop is rare, as when execution reaches this instruction, we know we are receiving a drop. Change 0x7a5ad, making the value smaller to make rare drops more rare, and larger to make them more common. If you change this value to greater than 0×40, you would be making “rare” drops more common than “common” drops– silly you :geek: . Default chance for this drop to be rare is 20/128, or 5 out of 32.

3. Obviously, you can change the items that drop. It does seem that you can make more gold coins or food rations drop. I don’t recommend that you allow reception of items that you cannot sell or discard :wink:

I have tested this algorithm, and it will not bork the game if you don’t have any space to put the item; it will just scream at you with the default message saying that you don’t have any more room.

Here is a list of item ID’s you can use:
00 ~*006038 coins [glitch]
01 ~96 coins
02 ~237 coins
03 ~592 coins
04 ~1013 coins
05 ~1533 coins
06 ~4028 coins
07 ~29 food
08 ~125 food
09 ~821 food
0A ~2011 food
0B ~5902 food
0C ~10151 food
0D ~2098390 food
0E ~2148799 food
0F ~*86607 food [glitch]
10 [blank] ->
16 [blank]
17 Silver Key ->
18 Silver Key
19 Gemsword
1A Ma Letter [???]
1B Gun Powder
1C Intro Letr
1D Iron Ore
1E Dead Wood
1F Saltpeter
20 [glitch]
21 Chi Tu Ma [Red Hare]
22 Zhou Letr [Zhang Ltr]
23 Gold Key
24 Gullwing ->
28 Gullwing
29 [blank] ->
2A [blank]
2B Smoke Pot
2C Steed
2D Resurrect -> (glitched, use 30)
30 Resurrect
31 Elixir A
32 Elixir B
33 Elixir C
34 Elixir D
35 Power Pill -> (glitched, use 38)
38 Power Pill
39 Dagger ->
40 Dagger
41 Flail [Club]
42 Ax [Ax]
43 Club [Mace]
44 Spear [Flail]
45 Sabre [Spear]
46 Trident
47 Bow
48 Sword
49 Battleax [Great Ax]
4A Scimitar
4B Crossbow
4C Lance [Dadao]
4D Wan Sheng [Wansheng]
4E Bo Ye [Boye]
4F Qing Guang [Qingguang]
50 Nu Long [Nulong]
51 Qing Long [Qinglong]
52 Halberd
53 Robe ->
59 Robe
5A Leather ->
5B Leather
5C Padded ->
5D Padded
5E Ring M ->
5F Ring M
60 Chain M ->
61 Chain M
62 Splint M ->
63 Splint M
64 Plate M ->
65 Plate M
66 Bandana ->
68 Bandana
69 Cap
6A Hood
6B Wood H
6C Copper H
6D Bronze H
6E Iron H
6F Steel H
6F [glitch] ->
7F [glitch]
80 “I found a small keyhole.” ->
FF “I found a small keyhole.”

Officer Recruitibility

Credit: ludmeister and Meteorstrike

First of all, all officers have their status byte stored in memory in $6300-$63ff. They're stored in General ID order (to figure out a specific General's ID #, check him out in Destiny of an Editor).

If you check there, you'll see a number of repeating values… mostly 80, 90, 98, and C0.

80- You can never meet this officer in random battles.
90- You can meet this officer in random battles, and you can recruit him after the battle.
98- You can meet this officer in random battles, but you cannot recruit him after the battle.
C0- I don't know what this value means. Possibly linked to special cases… see below.

How officers are (normally) set to be recruitable

Furthermore, most castle battles will seek out a table of bits in the DoaE ROM, stored @ 0x3b153-0x3b172, and based on whether the a participant General's bit in this table is 1 or 0, will set the officer's status byte to "90" or not. In other words, if you meet Yang Huai in a castle battle, after the battle, it will check bit #0x4b in this table… bit #4 of 0x3b15c… and seeing that that bit is set (is = 1) will set Yang Huai as recruitable.

This is how the table @ 0x3b153-0x3b172 looks:

00 00 7f cf f8 3e f1 81 18 ff b8 1f ff ff 00 4d
a1 39 f9 00 00 10 20 03 72 f7 e0 80 00 00 00 00

Let's look @ 0x3b155 specifically now:

7f = 0111 1111

0 – 1 – 1 – 1 – 1 – 1 – 1 – 1 (bit-by-bit representation of 0x7f)
10- 11- 12- 13- 14- 15- 16- 17 (General ID)

So, if we met any of the officers with IDs between 11 and 17 in a (normal) castle battle, after the battle we could recruit them. If we met General ID 10 in battle, he'd stay resolute against our allies' cause and would not be recruitable… in fact their status would not change. If 80 (cannot be met), that would not change. If 98 (can meet him), that also would not change.

Officer's initial statuses

Initial statuses for generals are based upon a separate bit table, found at 0×35722-0×35741:

00 00 ff ef fc ff f7 83 f8 ff b8 ff ff ff 3f ff
ff 79 ff 00 00 00 00 23 76 f7 e0 80 00 00 00 00

If the bit is set, the initial status is 0×98 (you can encounter him in random battle but cannot recruit him). If not set, the initial status is 0×80 (you cannot meet him in random battle).

Special cases

I have not ferreted out special cases, but it is clear that there are exceptions to these rules… like when you beat the Zhang brothers in the cave behind Qing Zhou, and therefore don't engage Zheng Mao and Chengyuan Zhi, but they are still recruitable after that battle.

To make all officers recruitable… always

A change so powerful it might almost be considered cheating… to make any officer recruitable from a random battle… always, try this:

0x3a45d: "98" -> "99"

What this does is it changes this statement:

0e:a44c:C9 98 cmp #$98

to a statement that is never true, since no officer has a status of 0×99. Therefore, any and all officers you could engage in a random battle would be recruitable.

Officer Battle Recruit Event

Credit: MiDKnighT, sonic.penguin

Officer joins your party for free 3A48B
Default Value is 06

Decreasing this value will lower the likelihood an officer will join your party free of charge. Increasing the value will make it more likely they will join your party free of charge.

Officer joins your party for money or a steed 3A497
Default Value is 0C

Decreasing this value will lower the likelihood an officer will ask for money and increase the likelihood an officer will ask for a steed, for example 02. Increasing this value will increase the likelihood an officer will ask for money and decrease the likelihood an officer will ask for a steed for example 0E.

This can all be found here courtesy of MiDKnighT:

0E:A466:A5 AC LDA $00AC = #$0F <– Get random number
0E:A468:65 AE ADC $00AE = #$9A <– Get random number
0E:A46A:85 AC STA $00AC = #$0F <– Get random number
0E:A46C:29 0F AND #$0F
0E:A46E:C9 03 CMP #$03 <– If the value is < 03 he only serves his master.
0E:A470:B0 08 BCS $A47A <– He may join
0E:A472:20 0D D1 JSR $D10D <– I serve only my master!
0E:A475:6C 00
0E:A477:4C 1F A5 JMP $A51F
0E:A47A:C9 06 CMP #$06 <– If less < 06, auto join
0E:A47C:B0 08 BCS $A486
0E:A47E:20 0D D1 JSR $D10D
0E:A481:A0 02
0E:A483:4C D0 A4 JMP $A4D0
0E:A486:C9 0C CMP #$0C
0E:A488:B0 5F BCS $A4E9 <– Money or steed (if under 0C money, if over 0C horse)

So with this info we can control recruiting behavior. You could make it so that they always ask for a horse, always ask for money, or change the percentages…

Retreat Using LDR and AGI Attributes

Credit: MiDKnighT

I've made LDR and AGI important for retreating. Want to get away from most battles? Have someone with high LDR and AGI leading your party. Changes:

0x39FB0:
A5751013E8EAEAEAEAEAEAEAEAEAEAEA
EAEAEAEAEAEAEAA91E2082C4EAEAEAEA
EAEA200DD12F00A21420BCC0A209A900

0x79FB0:
000A3264060A0C0E000A326401020406
00000000000000A90E2082C48E3064AE
9060BD00644A8D3264BDB4614A6D3264
A207BD00644A8D3364EA4CE29FA90E20
82C4BDB4614A6D3364AE3064AD326438
ED33649011A003D9A09FB0038810F8B9
A49F85F3101438E90149FFA003D9A89F
B0038810F8B9AC9F85F34C30A0000000
00000000000000A90E2082C44C27A000
A5AD65AE290FC5F390034CB79F4CDD9F

How the regular retreat code works:

0E:9FA5:AD AF 60 LDA $60AF = #$04 <– Enemy leader general ID
0E:9FA8:C9 02 CMP #$02 <– Is it higher than pirate or brigand?
0E:9FAA:90 0B BCC $9FB7
0E:9FAC:E8 INX <– If so increment X making it harder to escape
0E:9FAD:C9 04 CMP #$04 <– Is it higher than bandit force?
0E:9FAF:90 06 BCC $9FB7
0E:9FB1:E8 INX <– If so increment X making it harder to escape
0E:9FB2:C9 08 CMP #$08 <– Is it higher than rebel force?
0E:9FB4:90 01 BCC $9FB7
0E:9FB6:E8 INX <– If so increment X making it harder to escape
0E:9FB7:A5 AD LDA $00AD = #$7B <– Random number check
0E:9FB9:65 AF ADC $00AF = #$6A <– Random number check
0E:9FBB:29 1F AND #$1F <– Random number check
0E:9FBD:DD 83 A6 CMP $A683,X @ $A781 = #$AC <– Check to see if it's less than this number, if so they got away. The numbers it checks against are 1E 1B 18 14. The higher X is, the harder it is to escape
0E:9FC0:90 20 BCC $9FE2 <– Got away
0E:9FC2:20 0D D1 JSR $D10D <– Didn't get away

So here are my changes:

I've re-worked the retreat code to make it more like a tactic succeed/fail. Now it is purely based on LDR+AGI of own leader vs enemy leader + randomness. The type of force (bandit, rebel, etc…) no longer matters. Only LDR+AGI matters.

1E:9FBC:8E 30 64 STX $6430 = #$04 <– Store current X value
1E:9FBF:AE 90 60 LDX $6090 = #$02 <– What general is leading our army?
1E:9FC2:BD 00 64 LDA $6400,X @ $6404 = #$73 <– Get LDR for leader
1E:9FC5:4A LSR
1E:9FC6:8D 32 64 STA $6432 = #$4F <– Get AGI for leader
1E:9FC9:BD B4 61 LDA $61B4,X @ $61B8 = #$36
1E:9FCC:4A LSR
1E:9FCD:6D 32 64 ADC $6432 = #$4F <– Combine LDR + AGI
1E:9FD0:A2 07 LDX #$07 <– Get enemy leader
1E:9FD2:BD 00 64 LDA $6400,X @ $6404 = #$73 <– Get enemy leader's LDR
1E:9FD5:4A LSR
1E:9FD6:8D 33 64 STA $6433 = #$29
1E:9FD9:EA NOP
1E:9FDA:4C E2 9F JMP $9FE2 <– Gotta skip ahead to leave space for a jump point
1E:9FDD:A9 0E LDA #$0E
1E:9FDF:20 82 C4 JSR $C482
1E:9FE2:BD B4 61 LDA $61B4,X @ $61B8 = #$36 <– Get enemy leader's AGI
1E:9FE5:4A LSR
1E:9FE6:6D 33 64 ADC $6433 = #$29 <– Combine enemy leader's LDR+AGI
1E:9FE9:AE 30 64 LDX $6430 = #$04 <– Get X back
1E:9FEC:AD 32 64 LDA $6432 = #$4F <– Get allied leader's LDR+AGI

Similar to tactic succeed/fail:

1E:9FEF:38 SEC
1E:9FF0:ED 33 64 SBC $6433 = #$0C <– Subtract enemy LDR+AGI from party leader's LDR+AGI
1E:9FF3:90 11 BCC $A006

We have higher LDR+AGI

1E:9FF5:A0 03 LDY #$03
1E:9FF7:D9 A0 9F CMP $9FA0,Y @ $9FA0 = #$00
1E:9FFA:B0 03 BCS $9FFF
1E:9FFC:88 DEY
1E:9FFD:10 F8 BPL $9FF7
1E:9FFF:B9 A4 9F LDA $9FA4,Y @ $9FA4 = #$06
1E:A002:85 F3 STA $00F3 = #$D4
1E:A004:10 14 BPL $A01A

Enemy has higher LDR+AGI:

1E:A006:38 SEC
1E:A007:E9 01 SBC #$01
1E:A009:49 FF EOR #$FF
1E:A00B:A0 03 LDY #$03
1E:A00D:D9 A8 9F CMP $9FA8,Y @ $9FA8 = #$00
1E:A010:B0 03 BCS $A015
1E:A012:88 DEY
1E:A013:10 F8 BPL $A00D
1E:A015:B9 AC 9F LDA $9FAC,Y @ $9FAC = #$01
1E:A018:85 F3 STA $00F3 = #$D4
1E:A01A:4C 30 A0 JMP $A030

Check to see if we made it:

1E:A030:A5 AD LDA $00AD = #$A0
1E:A032:65 AE ADC $00AE = #$2B
1E:A034:29 0F AND #$0F
1E:A036:C5 F3 CMP $00F3 = #$D4
1E:A038:90 03 BCC $A03D
1E:A03A:4C B7 9F JMP $9FB7 <– Didn't make it
1E:A03D:4C DD 9F JMP $9FDD <– Successful retreat

Preferred Weapons

Credit: MiDKnighT

*Note that this enhancement requires the enemy profiles enhancement*

With this change officers can only use the weapon types that are in their profile. This is based on the icon at the front of the weapon name so obviously this requires the use of icons to work.

DoaE_IPS_13_Patch2-11_zpsfca1cb1f.png

Changes:

0x388F0: E8C6F3D0EFA6F2201ABC

0x393F0: 9C60A93E2082C4

0x3BC20:
0A3264010204069D0061A93E2082C468
60020202040602080A01020401010801

0×78910:
0000A90E2082C4

0x7BCA0:
00000000000000004848BD0061684C02
89000000000000000000000000000000

0xEBC40:
0000000000000000000000000000A93E
2082C48C2278A54AA8B9A860A8A9F085
00A9998501B9F08ED0034C6EBCA8A500
1869109002E601850088C000D0F2A00B
B100CD2278D009BD0061EAEA684C32BC
C8C010D0EBA00FB9A0BC99507E8810F7
20507EA91E2082C40000000000000000
20B0C9200DD10F00A93A2082C4600000

0xEBCF0:
0000000000000000000000A93E2082C4
A9F08500A9998501BDF08ED0034C11BD
A8A5001869109002E601850088C000D0
F2A00BB100991878C8C010D0F6A000B9
B09B992878C8C005D0F54CEBBC000000

0xF93F0:
0000A90E2082C4A9C09D00632010BC4C
EBBC2009BC980A0A0AA8A200B90061C9
8010034C34948C2F78E980A8B900B085
00B970B08501A002B100A000D92378D0
034C4094C8C00BD0F3AC2F78B90061E9
80990061C8E8E009D0C2EAEAEAEAEAEA
2009BC980A0A0AA8A200B90061C9C0D0
07C9DFF0034C7094E8C8E009D0EC2009
BCA90099C060EAEAEAEAEAEAEAEAEAEA
2009BC4CE293

0xFBC10:
000000000000000000AE2078AC217860
8E20788C217860000000A90E2082C420
10BC68C9E9F00300000048BD0061A8B9
00B08500B970B08501A002B100A8A93A
2082C42009BC4C1ABC00000000000000

0xFBCF0:
0000000000000000000000A93A2082C4
4CF293

Showing Tactic Statuses During Battle

The enhancement allows you to see what tactics are active during battle. Especially useful for keeping track of a complicated battle. Here I went into memory and flipped every tactic on, took a picture, then labeled it. Here’s what we have:

oFPxSCs.png

This is what it looks like in a more realistic battle:

GaUq8is.png

It updates tactic statuses every time a new portrait is loaded in battle. This could be during the deciding what to do phase or during battle when the swords are flying. Ie… if someone casts guard it will immediately show up at the bottom.

Battle Status Changes:

0x39D7C (moving portrait lookup reference): "96CF" --> "707F"

0x3AB80 (moving portrait lookup reference):: "96CF" --> "707F"

0x80010 (loading new code into mememory upon reset:
A05FB9208099707F8810F7A07FB98080
99007E8810F7A90E4CB7C40000000000
A9382082C4200080209FC0200090209F
C0A90E2082C42096CF60000000000000
85EDC91F9006A902484CA07FA90048EA
A5ED0AC93F9002E94048A9068D008068
8D018018690148A9078D0080688D0180
A9008D0080688D018060000000000000
0DF8150AFB0A1B13210AF84BEAFB0A22
23210AF87785FB0A181D230AF87785FB
0A1016180AF87785FB0A2518230AF877
85FB0A1F1E1B0AF87785FB0A101F0A0A
F87785FB0A10120A0AF87785FE000000
00000000000000000000000000000000
23C002FFFF23DA03AAAA2223E203AAAA
2223EA03AAAA2223F203AAAA22FF0000
FDF90E0AFB221E1B1318142122F81F86
FE20B8C920A07E20809920E2C9600000
A017A90A9948038810FAA573D006A901
8585D00510034CE2C0A93A2082C46000

0xE0010 (main guts of battle status changes - individual statuses):
A20AAD2F622901C900F002A20F8E607F
A20AAD2D622901C900F002A2748E617F
A20AAD2A622901C900F002A2758E627F
EAEAAD28622901C900F002A27F8E627F
A20AAD2F622902C900F002A20F8E637F
A20AAD2D622902C900F002A2748E647F
A20AAD2A622902C900F002A2758E657F
EAEAAD28622902C900F002A27F8E657F
A20AAD2F622904C900F002A20F8E667F
A20AAD2D622904C900F002A2748E677F
A20AAD2A622904C900F002A2758E687F
EAEAAD28622904C900F002A27F8E687F
A20AAD2F622908C900F002A20F8E697F
A20AAD2D622908C900F002A2748E6A7F
A20AAD2A622908C900F002A2758E6B7F
EAEAAD28622908C900F002A27F8E6B7F
A20AAD2F622910C900F002A20F8E6C7F
A20AAD2D622910C900F002A2748E6D7F
A20AAD2A622910C900F002A2758E6E7F
EAEAAD28622910C900F002A27F8E6E7F
A6408641EAEAEAEAEAEAEAEAEAEAEAEA
A9249D0004E8A9409D0004E8A9019D00
04E8AD607F9D0004E8EAEAEAEAEAEAEA
A9249D0004E8A9609D0004E8A9019D00
04E8AD617F9D0004E8EAEAEAEAEAEAEA
A9249D0004E8A9809D0004E8A9019D00
04E8AD627F9D0004E8EAEAEAEAEAEAEA
A9249D0004E8A9A09D0004E8A9019D00
04E8AD637F9D0004E8EAEAEAEAEAEAEA
A9249D0004E8A9C09D0004E8A9019D00
04E8AD647F9D0004E8EAEAEAEAEAEAEA
A9249D0004E8A9E09D0004E8A9019D00
04E8AD657F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A9009D0004E8A9019D00
04E8AD667F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A9209D0004E8A9019D00
04E8AD677F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A9409D0004E8A9019D00
04E8AD687F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A9609D0004E8A9019D00
04E8AD697F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A9809D0004E8A9019D00
04E8AD6A7F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A9A09D0004E8A9019D00
04E8AD6B7F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A9C09D0004E8A9019D00
04E8AD6C7F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A9E09D0004E8A9019D00
04E8AD6D7F9D0004E8EAEAEAEAEAEAEA
A9269D0004E8A9009D0004E8A9019D00
04E8AD6E7F9D0004E88640EAEAEAEAEA
A20AAD2E622901C900F002A20F8E607F
A20AAD2C622901C900F002A2748E617F
A20AAD2B622901C900F002A2758E627F
EAEAAD29622901C900F002A27F8E627F
A20AAD2E622902C900F002A20F8E637F
A20AAD2C622902C900F002A2748E647F
A20AAD2B622902C900F002A2758E657F
EAEAAD29622902C900F002A27F8E657F
A20AAD2E622904C900F002A20F8E667F
A20AAD2C622904C900F002A2748E677F
A20AAD2B622904C900F002A2758E687F
EAEAAD29622904C900F002A27F8E687F
A20AAD2E622908C900F002A20F8E697F
A20AAD2C622908C900F002A2748E6A7F
A20AAD2B622908C900F002A2758E6B7F
EAEAAD29622908C900F002A27F8E6B7F
A20AAD2E622910C900F002A20F8E6C7F
A20AAD2C622910C900F002A2748E6D7F
A20AAD2B622910C900F002A2758E6E7F
EAEAAD29622910C900F002A27F8E6E7F
A640EAEAEAEAEAEAEAEAEAEAEAEAEAEA
A9249D0004E8A95F9D0004E8A9019D00
04E8AD607F9D0004E8EAEAEAEAEAEAEA
A9249D0004E8A97F9D0004E8A9019D00
04E8AD617F9D0004E8EAEAEAEAEAEAEA
A9249D0004E8A99F9D0004E8A9019D00
04E8AD627F9D0004E8EAEAEAEAEAEAEA
A9249D0004E8A9BF9D0004E8A9019D00
04E8AD637F9D0004E8EAEAEAEAEAEAEA
A9249D0004E8A9DF9D0004E8A9019D00
04E8AD647F9D0004E8EAEAEAEAEAEAEA
A9249D0004E8A9FF9D0004E8A9019D00
04E8AD657F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A91F9D0004E8A9019D00
04E8AD667F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A93F9D0004E8A9019D00
04E8AD677F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A95F9D0004E8A9019D00
04E8AD687F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A97F9D0004E8A9019D00
04E8AD697F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A99F9D0004E8A9019D00
04E8AD6A7F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A9BF9D0004E8A9019D00
04E8AD6B7F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A9DF9D0004E8A9019D00
04E8AD6C7F9D0004E8EAEAEAEAEAEAEA
A9259D0004E8A9FF9D0004E8A9019D00
04E8AD6D7F9D0004E8EAEAEAEAEAEAEA
A9269D0004E8A91F9D0004E8A9019D00
04E8AD6E7F9D0004E8EAEAEAEAEAEAEA
A9009D00048640600000000000000000

0xE1010 (main guts of battle status changes - party statuses)::
A20AAD0A622901C900F002A2518E607F
A20AAD23622901C900F002A24D8E617F
A20AAD23622902C900F002A25A8E627F
A20AAD23622904C900F002A25B8E637F
A20AAD23622910C900F002A25C8E647F
A20AAD23622920C900F002A25D8E657F
A20AAD23622940C900F002A2588E667F
A20AAD23622980C900F002A27A8E677F
A20AAD23622908C900F002A22A8E687F
A20AAD2562EAEAC900F002A2738E697F
A20AAD2762EAEAC900F002A2728E6A7F
A6408641EAEAEAEAEAEAEAEAEAEAEAEA
A9279D0004E8A9809D0004E8A90B9D00
0485F1A000E8B9607F9D0004E8C8C4F1
D0F48640EAEAEAEAEAEAEAEAEAEAEAEA
A20AAD0A622902C900F002A2518E607F
A20AAD22622901C900F002A24D8E617F
A20AAD22622902C900F002A25A8E627F
A20AAD22622904C900F002A25B8E637F
A20AAD22622910C900F002A25C8E647F
A20AAD22622920C900F002A25D8E657F
A20AAD22622940C900F002A2588E667F
A20AAD22622980C900F002A27A8E677F
A20AAD22622908C900F002A22A8E687F
A20AAD2462EAEAC900F002A2738E697F
A20AAD2662EAEAC900F002A2728E6A7F
A640EAEAEAEAEAEAEAEAEAEAEAEAEAEA
A9279D0004E8A9959D0004E8A90B9D00
0485F1A000E8B9607F9D0004E8C8C4F1
D0F4A9009D0004864060EAEAEAEAEAEA

The tricky part - memory update. Open and copy this into RAM memory to avoid save states borking (do for each save state):

0x7F70:
A9382082C4200080209FC0200090209F
C0A90E2082C42096CF60000000000000

Damage

Critical Hits

Credit: MiDKnighT and Meteorstrike

Without going into too much detail, the amount of damage you will do will mainly depend on your STR and A.P. However, there is some randomization that occurs when you hit. See this post:

Now pick a random number between 0 and 255, and if the number is greater than or equal to 240 (F0), this is an excellent blow, so damage potential is 51. Otherwise, pick a random number between 0 and 15, and use this number to extract the damage potential from an array. The end resulting damage potential will be one of the following:

51 = 1 in 16 chance, excellent blow. Otherwise, damage potential is one of the following 3 values:
20 = 2 in 16 chance
23 = 6 in 16 chance
25 = 8 in 16 chance

These values live at 0×39948:

14 17 17 17 19 19 19 19 19 19 19 19 17 17 17 14

If you change these values you are changing the randomization of how random your normal attacks are (yours and the enemies). For example if you changed one of those 19's to a 1 and a normal attack will sometimes barely touch the opponent. Or change to an FF and occasionally a normal attack will result in brutal damage. But that's not what we would want to do…we would rather change the critical hits. With that said…

To change critical hit chances and damage there are 3 checks in the code to see if our random value is above F0 which means we got a critical hit. They are at:

00:AC19:A6 7C LDX $007C = #$4F
00:AC1B:A9 00 LDA #$00
00:AC1D:A4 7A LDY $007A = #$01
00:AC1F:F0 02 BEQ $AC23
00:AC21:A9 02 LDA #$02
00:AC23:E0 F0 CPX #$F0

Check whether to make "critical hit" sound

00:9847:A5 7C LDA $007C = #$62
00:9849:C9 F0 CMP #$F0

Check whether to do "critical hit" damage

00:9920:A5 7C LDA $007C = #$B4
00:9922:C9 F0 CMP #$F0

Check to see if "critical hit" text is used

In the ROM:

0x3AC33: E0 F0 <– for the sound
0x39859: C9 F0 <– for the damage
0x39932: C9 F0 <– for the text

And we have the "how bad will a critical hit hurt value":

00:984D:A9 33 LDA #$33

Default is 33 (51). This value is stored in:

0x3984D: A9 33

So if we were to make a critical hit twice as likely and make it hurt twice as bad we would make the following changes:

0x3AC33: E0 E1
0x39859: C9 E1
0x39932: C9 E1
0x3985D: A9 66

Note that lowering the first 3 values from F0 to E1 increases the critical hit chances.

Just for testing purposes if you set the first 3 to 00 and the last one to FF then every hit will be a brutal critical hit.

Weapon Damage

Credit: Meteorstrike and James

12 = ( NONE )
25 = Dagger
38 = Flail
56 = Ax
84 = Club
128 = Spear
192 = Sabre
435 = Trident
289 = Bow
655 = Sword
1024 = Battleax
1280 = Scimitar
768 = Crossbow
1536 = Lance
1792 = Wan Sheng
1792 = Bo Ye
2048 = Qing Guang
2048 = Nu Long
2048 = Qing Long
4096 = Halberd

Ref: http://www.gamefaqs.com/boards/563402-destiny-of-an-emperor/44112071

The low byte values for these are stored starting at 0x3E710 and the high byte values are stored starting at 0x3E724.

(7E710-7E737 and FE710-FE737 in 1MB Expanded Rom, low then high value order remains)

Changing the A.P. strength of weapons displayed in a general's profile:

0x38609 -> 00 0A 0F 14 1E 32 46

Dagger
Flail
Ax
Club
Spear
Sabre

0x38610 -> 64 50 78 8C 96 82 AA BE BE F0 F0 F0 FA

Trident
Bow
Sword
Battleax
Scimitar
Crossbow
Lance
Bo Ye
Wan Sheng
Qing Guang
Nu Long
Qing Long
Halberd

Change that FA at the end to FF and the Halberd displays an attack power of 255.

Change the BE BE to F0 F0 and all the magical swords have a displayed attack power of 240.

Ref: http://www.lordyuanshu.com/forums/topic/destiny-of-an-emperor-hacking-notes

DoaE2 Attack Algorithm

Credit: ludmeister

Since you all were wondering (maybe), here is the code for implementing a more DoaE2-like damage function, and then I'll discuss what it changes:

@ 0x397f2… to 0x3982d (0x3b bytes)

Old:

B9D0 6085 03B9 D160 8504 B9D2 6085 0520
88D6 A000 B904 01D0 07C8 C008 D0F6 F01B
84F2 A907 38E5 F285 F2A8 A900 8515 A5F2
1865 1585 1588 D0F6 205B C1

New:

B9D0 6085 04B9 D160 8503 A8C0 00F0 1F30
08C0 0830 12C0 2030 07A2 27A0 0A4C 1498
A20F A008 4C14 98A2 07A0 074C 1498 A201
A005 8600 4CE0 BFEA 205B C1

@ 0x3bff0… to 0x3c003 (0×14 bytes)

Old:

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

New:

4603 6604 88C0 00D0 F7A5 0418 6500 8515 4C17 9800

To illustrate what the calculation does, here's a before and after.

Before:
*

Army size (soldiers) Strength multiplier (x = army size)
1 to 9 –> 1
10 to 99 –> 4
100 to 999 –> 9
1000 to 9999 –> 16
10000+ –> 25

Meteorstrike's discussion of the damage function helped me in this as he provided clues as to what to look for, so I would know that damage was being calculated.

Quite literally, the game calculated the number of digits in your current soldier total (like it might calculate the length of a string), and then squared that result. That number was multiplied by your strength, your weapon damage rating (not what you see in the status screen), and finally a number from the random table.

After
*

With my edits to the damage algorithm, your current soldiers modify the damage in this way:

Army size (soldiers) Strength multiplier (x = army size)
1 to 255 –> (x / 32) + 1
256 to 2047 –> (x / 128) + 7
2048 to 8191 –> (x / 256) + 15
8192+ –> (x / 1024) + 37

Hence, until you reach 256, you gain +1 to your strength multiplier every 32 soldiers. Then, from 384 to 2048, you gain +1 every 128 soldiers. At 2304 and every 256 soliders until 8192, you gain +1. Once you hit 8192 soldiers, you need another 1024 soldiers to gain a +1. Let's compare damage ratings with real figures.

Soldiers – Previous – Modified
10 soldiers – 4x – 1x
75 soldiers – 4x – 3x
550 soliders – 9x – 11x
1896 soldiers – 16x – 21x
5000 soldiers – 16x – 34x
40000 soldiers – 25x – 76x

Don't mess with overwhelming forces… or get overwhelmed! Mwa-hahaha

//Note that this battle damage formula changes the same area of the ROM as the "Expanded Chapters" enhancement. If you want this enhancement *and* ludmeister's DoaE2-like damage enhancement do the following:

1. Add the Agility based extra attacks enhancement.
2. Add the DoaE2-like Damage enhancement.
3. Edit the following:

0×39826: "4cc7a1"
0x3a1d7: "4603 6604 88C0 00D0 F7A5 0418 6500 8515 4C17 98"

4. Add the 8 Chapters enhancement.//

Agility Based Multi-attacks

Credit: ludmeister

Edits:

@ 0x3a1d2-0x3a1f9:

—- a91e 2082 c400 0000 0000 0000 0000
0000 0000 0000 0000 0000 d006 208d ab4c
5aa1 0000 0000 0000 a678 …..

@ 0x7a1d0-0x7a1f9:

0000 0000 0000 004c fbb1 0000 0000 0000
0000 0000 00a9 0e20 82c4 0000 0000 0000
0000 00a9 0e20 82c4 0000

@ 0x7b200-0x7b20f:

0000 0000 0000 0000 0000 00a9 0b20 82c4

@ 0x7b300-0x7b30f:

0000 0000 004c e3a1 0000 0000 004c d5a1

@ 0x2f210-0x2f30f (0×100, or 256 bytes)

bdd0 61d0 2aa9 409d d061 980a 0a0a a8b9
0061 c9c7 f010 eaea eaea eaea eaea eaea
eaea c9cb d003 4c9d b2c8 9829 07d0 e0a4
4ab9 b461 8510 a900 8511 bdd0 61a8 c040
f017 8884 12a9 00a0 3cc6 1088 c510 f02d
c000 d0f5 a412 4c3e b2a9 0085 12a5 ad65
ae65 10ea 85ad 290f a8b9 e0b2 8515 205b
c138 a44b b9b4 614c 8ab2 eaea ea4c d7b2
a44a fed0 61a9 004c f8b2 a8a9 00c6 1188
c511 f0e9 c000 d0f5 4c80 b200 00a5 ad65
ae65 1085 ad4c f8b2 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 00ea eaa9 00a4 4a4c f0b2
1926 3340 4c59 6673 8099 a6b3 c0cc e6ff
a91e 2082 c400 0000 a91e 2082 c400 0000

What it does:

1. Keeps the Bow/Crossbow bonus hit… applies this first. This is only valid for allies, as only allies have item packs.

2. After that, Agility is modified by a random percentage from a table @ 0x2f2f0. This is achieved by multiplying by a chosen value, then dividing by 256.

1926 3340 4c59 6673 8099 a6b3 c0cc e6ff

These values correspond to these percentages:
10%, 15%, 20%, 25%, 30%, 35%, 40%, 45%, 50%, 60%, 65%, 70%, 75%, 80%, 90%, 100-%

3. Then, that modified value is compared with the defender's agility.

4. If the defender's Agility is greater, then the turn ends. If not, a new attack is performed…. and the check is done again.

5. Each successive hit renders a cumulative 60 Agility penalty to all checks against the enemy's agility. Therefore, the chance to make another attack becomes nil very quickly… only the very fastest officers ever get a legitimate chance for three hits… and only on slow generals.

6. The Agility-based check is valid for allies as well as enemies hitting you… if you plan on using this modification, Agility will be a very important stat and thought will need to be spent on how you balance out officer's Agility throughout the game.

7. One interesting thing about this implementation… bonus attacks are not always awarded. A 255 Agility officer could hit a 160 Agility officer up to three times (255 – 120 penalty = 135… which would automatically fail that check against 160 Agility. However, because of the random table, it is *much* more likely that they would strike once, or twice.

Possible customization to the algorithm:

1. There are twelve "EA" NOPs in 0x2f226-0x2f231. These are intentionally left in, because that space is perfect for placing up to 3 extra item checks. This is what an item check looks like:

0x2f222 – 0B:B212:

C9 C7– CMP #$C7

(Is it an equipped Bow?)
0x2f224 – 0B:B214:

F0 10– BEQ $B226

*$B226 = $B214 + $#0010 (from statement) + $#0002 (trust me). To create a valid branch, you'll need to take whatever address to which you want to branch (always $B226 here), subtract the address of your branch statement (in this case, that's $B214), and subtract also the length of your branch statement (in 6502 assembly, I believe this value is always 2). That's how I arrived at the "10" at 0x2f225.

2. Obviously, the table for percentages (0x2f2f0-0x2f2ff) is editable. Note that in later IPS patches change 0x2f2## to 0x55## as this code was moved.

3. To remove the Random Agility check, and use this edit simply for expanded item checking:
Change 0x2f23f-0x2f241 to "4cd7b2"

0x2f23f – 0B:B22F: (0x553F in later IPS patches)

4C D7 B2– JMP $B2D7

(what that statement says)

4. To cap the number of extra hits from Agility at one, do this:
Change 0x2f252-0x2f254 to "4cd7b2"

0x2f252 – 0B:B242:

4C D7 B2– JMP $B2D7

5. To edit the cumulative Agility penalty on successive hits, edit this:
Change 0x2f258 to whatever you want.

0x2f257 – 0B:B247:

A0 3C– LDY $#3c

(Default penalty is 60)

Let's review.

1. Any bonus attack for equipment/item possession is applied first. There is a maximum of one item-based attack bonus. After that's out of the way…

2. Attacker Agility is first penalized based on the number of attacks made.

3. Then, it is multiplied by a random value from the table.

4. Then, the result is divided by 256.

5. Finally, this value is compared against the defender's agility.

6. If, after all that, the defender's agility is lower, a new attack is made… and after that attack is completed (and there's still an enemy standing), we'll do this check all over again.

7. With my default setup, it's rarer than it sounds to make extra attacks… unless the defender's Agility is abysmal.

Happy serendipities

In stock DoaE, if you get two attacks (for example, via equipped Crossbow), and manage a critical hit on strike #1, strike #2 is an automatic critical. This has been corrected, at least within successive hits based on Agility. I believe the auto-critical is also corrected if you make a critical on strike #1 with an equipped bow, though this has not been explicitly tested.

Errata

I noticed that after I had used a successful Negate tactic, Pang Tong got a second hit. That was not expected, but not bad. I wonder if this modification will suffer from the same difficulty that the Ambush tactic does… if an officer successfully uses Ambush and uses a Healing tactic the next round, often times he will strike his ally. More testing may be necessary to track this and fix it. However, I have used healing tactics successfully without extra attacks being applied to allies, so I don't think this is too much of a worry.

Also… Jiang Wei just hit that absolute maximum number of non-bow attacks… struck a group of chapter 2 Brigands <i>5 additional times.</i> (He was repelled once). Of course, he has 255 Agility, and the poor Brigands only had an Agility of 12… poor poor Brigands.

UPDATE: To have Qi Shou influence agility based attacks:

I believe I've had success updating the Agility-based multi-strike algorithm. Here's what's changed:

@ 0x3a1d2-0x3a1f9:

—- a91e 2082 c400 0000 0000 0000 0000
0000 0000 0000 0000 0000 d006 208d ab4c
5aa1 0000 0000 0000 a678 …..

@ 0x7a1d0-0x7a1f9:

0000 0000 0000 004c fb94 0000 0000 0000
0000 0000 00a9 0e20 82c4 0000 0000 0000
0000 00a9 0e20 82c4 0000

@ 0×79500-0x7950f:

0000 0000 0000 0000 0000 00a9 0120 82c4

@ 0×79600-0x7960f:

0000 0000 004c e3a1 0000 0000 004c d5a1

@ 0×5510-0×5686 (0×177, or 375 bytes)

BDD061D02AA9409DD061980A0A0AA8B9
00618412A000D9D095F010C8C007D0F6
A412C8982907D0E74C2F954C9D95EA4C
0096EAEAEAEAA9008511BDD061A8C040
F017888412A900A03CC61088C510F02D
C000D0F5A4124C3E95A9008512A5AD65
AE6510EA85AD290FA8B9E0958515205B
C1384C4096EAEA4C8A95EAEAEA4CD795
A44AFED061A9004CF895A8A900C61188
C511F0E9C000D0F54C80950000A5AD65
AE651085AD4CF8950000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
C7CBFFFFFFFFFFEAEAA900A44A4CF095
192633404C5966738099A6B3C0CCE6FF
A91E2082C4000000A91E2082C4000000
A44AB9B4618510A54BC907B007A8AD2D
624C1A96E907A8AD2C62C000F005884A
4C1A962901C901F0034C369546104C36
95000000000000000000000000000000
A44BB9B4618512A54AC907B007A8AD2D
624C5A96E907A8AD2C62C000F005884A
4C5A962901C901F0034C6E964612A512
A00084124C8A95

Data Tables

0x55e0-0x55e6 — Bonus Attack Item ID table. These items grant a guaranteed bonus strike.
0x55f0-0x55ff — Random % of attacker's AGI

Adding this code in place of the original guts of my Agility-based multi-strikes code will upgrade it so that you have the following functionality:

1. An Item ID table is read from when determining which items will grant one extra attack. The default IDs are "c7 cb ff ff ff ff ff". You do not need to modify the algorithm to add additional items to this. Remember, any item that is 80 to ff is considered equipped.

2. When an officer (enemy or ally) attacks a defender who has Qi Shou active, the attacker's AGI is halved for the purposes of executing multiple strikes.

3. When an officer (enemy or ally) has Qi Shou active and attacks, the defender's AGI is halved for the purposes of negating multiple strikes.

Therefore, if both attacker and defender have Qi Shou active, the attacker will pit half of their AGI against half of the defender's AGI.

Why the algorithm was implemented like this

When determining how to apply Qi Shou bonuses, I had to be mindful of the 8-bit nature of the NES. It would not do to multiply AGI by 2, because that would result in 8-bit overflows. Instead, I needed to use division, and therefore we have the resulting algorithm.

Base AC and Item Expansion

Credit: ludmeister

I've actually got an IPS patch together that does the Base AC and Item Expansion edits– just click on the link below to download it. You can only apply it (safely) to a 1MB ROM. If you're using Firefox… right clicky -> Save as.

Download Base AC and Item Expansion patch Note that IPS 1.3 and above also include this.

Patch details
***

Here's the nitty gritty of the stuff that has it's location changed:
Weapon Power- Status display: 0×78640 (none), 0×78641 to 0x7865f (ID #40 – #5e)
Weapon Damage- least significant byte: 0xfe710 to 0xfe72f (0×20 bytes), also 0x7e710 to 0x7e72f
Weapon Damage- most significant byte: 0xfe730 to 0xfe74f (0×20 bytes), also 0x7e730 to 0x7e74f
Armor Defense: 0xfe750 to 0xfe758 – Displayed AC in status screen (0×09 bytes), also 0x7e750 to 0x7e758
Helm Defense: 0xfe759 to 0xfe760 – Displayed AC in status screen (0×28 bytes), also 0x7e759 to 0x7e760
Defense values for opposing generals: 0xfe750 to 0xfe777 (0×28 bytes), also 0x7e750 to 0x7e777
Item Name Pointers: 0xfb010 to 0xfb0ef (0xe0 bytes)
Item Names: 0xfb110 to 0xfb80f (0×700 bytes)

That may look like a lot, but most of the stuff above is encapsulated in the 0xfe710 to 0xfe777 and 0x7e710 to 0x7e777 ranges.

So, Item IDs #40-#5e are used for weapons, #5f-#67 are for Armor, and #68-6f are for Helmets.

The patch creates the dummy names for the expansion items, and makes sure that all items are still in the same place (whether given at the start, sold in stores, or found in chests on hidden on the ground). Armor defense is not re-aligned for use with Base AC enhancement; it uses stock DoaE defense values.

The Base AC enhancement works as advertised (at least, as far as my meager testing as gone). The equation used is:

let x = STR/2 + INT/4 + AGI/4
Base AC = x * 3 * level / 256, capped at 100

In IPS patch 1.3 the formula is:

let x = VIT/2 + STR/4 + AGI/4
Base AC = x * 2 * level / 256, capped at 100

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License