<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="Algorithms.xsl"?> <algorithms> <intro> The following are the algorithms used by xu4. Most of them are exact matches to the original Ultima IV, while others are simply guessed. Algorithms have a certain level of accuracy to the original Ultima IV, which is indicated by the "Accuracy" column. Values are: exact - Exact emulation of the original Ultima IV behavior near - Near-exact emulation unknown - Level of accuracy unknown </intro> <section name="Camping"> <algorithm desc="Ambushed during rest?" prec="exact"> <line>random(8) == 0</line> </algorithm> <algorithm desc="Healed after camping?" prec="exact"> <line>(((moves/100) >= 0x10000) or (((moves/100) & 0xffff) != lastcamp))</line> <line>lastcamp = (moves/100) & 0xffff</line> </algorithm> <algorithm desc="Ambushed by rogues at inn?" prec="exact"> <line>random(8) == 0</line> </algorithm> <algorithm desc="Innkeeper warns about rats?" prec="exact"> <line>random(4) == 0</line> </algorithm> <algorithm desc="Visited by Isaac the Ghost?" prec="exact"> <line>(map == Skara Brae) and (random(4) == 0)</line> </algorithm> </section> <section name="Combat"> <algorithm desc="Place monster's leader's leader" prec="exact"> <line>random(32) == 0</line> </algorithm> <algorithm desc="Place monster's leader" prec="exact"> <line>!placedLeadersLeader and (random(8) == 0)</line> </algorithm> <algorithm desc="# of creatures (town)" prec="exact"> <line>if (guard)<line>ncreatures = numPartyMembers * 2</line></line> <line>else<line>ncreatures = 1</line></line> </algorithm> <algorithm desc="# of creatures (normal)" prec="near"> <line>ncreatures = random(8) + 1</line> <line>if (ncreatures == 1) { <line>if (creature.encountersize == 0) <line>ncreatures = random(creature.encountersize) + creature.encountersize + 1</line></line> <line>else ncreatures = 8</line> </line> <line>}</line> <line>while (ncreatures > (2 * numPartyMembers)) <line>ncreatures = random(16) + 1</line> </line> </algorithm> <algorithm desc="Does player get an extra turn?" prec="near"> <line>(aura == quick) and playerIsNotDisabled and (random(2) == 0)</line> </algorithm> <algorithm desc="Does player wake up?" prec="exact"> <line>random(8) == 0</line> </algorithm> <algorithm desc="Monster placement" prec="exact"> <pseudo>Add monster to random empty location in combat monsters location array</pseudo> </algorithm> <algorithm desc="Player poisoned by ranged poison attack" prec="exact"><line>random(2) == 0 and !alreadyPoisoned</line></algorithm> <algorithm desc="Player slept by ranged sleep attack" prec="exact"><line>random(2) == 0</line></algorithm> <algorithm desc="Player damage to creature" prec="exact"> <line>maxDamage = weapon.damage</line> <line>maxDamage += player.strength</line> <line>if(maxDamage > 255)<line>maxDamage=255</line></line> <line>realDamage = random(maxDamage)</line> </algorithm> <algorithm desc="Creature damage to player/creature" prec="exact"> <line>x = random(creature.basehp >> 2)</line> <line>damage = (x >> 4) + ((x >> 2) & 0xfc)</line> <line>damage += x % 10</line> </algorithm> <algorithm desc="Creature hits player" prec="exact"> <line>xu4_random(0x100) > armor.defense</line> </algorithm> <algorithm desc="Player hits creature" prec="exact"> <line>(player.dex + 0x80) >= xu4_random(0x100)</line> </algorithm> <algorithm desc="Player is disabled" prec="exact"> <line>(player.status == 'G') or (player.status == 'P')</line> </algorithm> </section> <section name="Party"> <algorithm desc="Is karma adjusted?" prec="near"> <line> if (!adjustment.isTimeLimited or (<line>((moves / 16) >= 0x10000) or (((moves / 16) & 0xFFFF) != lastvirtue))) {</line> <line>lastvirtue = (moves / 16) & 0xFFFF;</line> <line>return true;</line> </line> <line>}</line> </algorithm> <algorithm desc="Player poisoned on swamp?" prec="exact"> <line>random(5) == 0</line> </algorithm> <algorithm desc="Player slept on sleep field?" prec="exact"> <line>random(2) == 0</line> </algorithm> <algorithm desc="Ship repaired this turn?" prec="exact"> <line>(hull < 50) and (random(4) == 0)</line> </algorithm> <algorithm desc="Amount of gold in chest" prec="exact"> <line>random(50) + random(8) + 10</line> </algorithm> <algorithm desc="Party immobilized" prec="exact"> <pseudo>yes if all party members are disabled</pseudo> </algorithm> <algorithm desc="Can person join party?" prec="exact"> <line>!(person of that class already in party) and</line> <line>(numPartyMembers + 1 < (avatar.hpMax / 100)) and </line> <line>((party.karma[class] == 0) or (party.karma[class] >= 40))</line> </algorithm> </section> <section name="Game"> <algorithm desc="Spawned creature location in dungeon" prec="exact"> <line>for (i = 0; i < 0x20; i++) { <line>test_x = random(map.width)</line> <line>test_y = random(map.height)</line> <line>tile = map.tileAt(test_x, test_y)</line> <line>if (tile.isCreatureWalkable()) { <line>x = test_x</line> <line>y = test_y</line> </line> <line>}</line> </line> <line>}</line> </algorithm> <algorithm desc="Spawned creature location (world map)" prec="exact"> <line>bool ok = false</line> <line>int tries = 0</line> <line>static const int MAX_TRIES = 10</line> <line>while (!ok and (tries < MAX_TRIES)) { <line>dx = 7</line> <line>dy = random(7)</line> <line>if (random(2))<line>dx = -dx</line></line> <line>if (random(2))<line>dy = -dy</line></line> <line>if (random(2)) { <line>temp = dx</line> <line>dx = dy</line> <line>dy = temp</line> </line> <line>}</line> <line>if (creature.canMoveOn(map.tileAt(avatar.x + dx, avatar.y + dy))) { <line>spawn_x = avatar.x + dx</line> <line>spawn_y = avatar.y + dy</line> <line>ok = true</line> </line> <line>} else tries++</line> </line> </algorithm> </section> </algorithms>