diff --git a/INSTALL.md b/INSTALL.md index ca38695af..12fe3aa03 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,3 +1,35 @@ +# Vagrant + +The simplest way to get pokecrystal to compile is to use Vagrant and +VirtualBox. Follow these steps: + +* [Download and install Vagrant](http://www.vagrantup.com/downloads.html) +* Follow the instructions to [download and install VirtualBox](http://docs-v1.vagrantup.com/v1/docs/getting-started/) +* Run these commands: + + vagrant box add pokecrystal http://diyhpl.us/~bryan/irc/pokecrystal/pokecrystal.box + mkdir vagrantbox + cd vagrantbox + vagrant init pokecrystal + vagrant up + vagrant ssh -c "cd /vagrant && git clone git://github.com/kanzure/pokecrystal.git" + vagrant ssh -c "cd /vagrant/pokecrystal && git submodule init && git submodule update" + vagrant ssh + +Running "vagrant ssh" will give you a shell to type commands into for compiling +the source code. The the "virtualbox" directory on the host appears as a shared +folder inside of the guest virtual machine at "/vagrant". + +To build the project, run these commands in the guest (that is, inside "vagrant +ssh"): + + cd /vagrant/pokecrystal + make + +To make the build work you will need to copy baserom.gbc into the "pokecrystal" +directory inside the "virtualbox" directory on the host machine. Eventually +this will not be required. + # Linux Dependencies: diff --git a/Makefile b/Makefile index 150e9bb80..b77607436 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ crystal: pokecrystal.gbc clean: rm -f $(roms) $(all_obj) - find -iname '*.tx' -exec rm {} + + find . -iname '*.tx' -exec rm {} + baserom.gbc: ; @echo "Wait! Need baserom.gbc first. Check README and INSTALL for details." && false diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 000000000..ef8ee2f03 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,59 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# TODO: insert scripts to build the box instead of trusting the uploaded +# version. The default should be to build the box when running "vagrant up", +# rather than just downloading a pre-existing box. + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + # All Vagrant configuration is done here. The most common configuration + # options are documented and commented below. For a complete reference, + # please see the online documentation at vagrantup.com. + + # Every Vagrant virtual environment requires a box to build off of. + config.vm.box = "pokecrystal" + config.vm.box_url = "http://diyhpl.us/~bryan/irc/pokecrystal/pokecrystal.box" + + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + config.vm.box_check_update = false + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + config.vm.network "forwarded_port", guest: 80, host: 8650 + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: "192.168.33.10" + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + config.vm.network "public_network" + + # If true, then any SSH connections made will enable agent forwarding. + # Default value: false + config.ssh.forward_agent = true + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + config.vm.synced_folder "./", "/vagrant" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + config.vm.provider "virtualbox" do |vb| + # Don't boot with headless mode + vb.gui = false + + # Use VBoxManage to customize the VM. For example to change memory: + vb.customize ["modifyvm", :id, "--memory", "1024"] + end +end diff --git a/battle/ai/scoring.asm b/battle/ai/scoring.asm index 5e43470d7..52112faf6 100644 --- a/battle/ai/scoring.asm +++ b/battle/ai/scoring.asm @@ -21,6 +21,9 @@ AI_Basic: ; 38591 ld a, [wEnemyMoveStruct + MOVE_EFFECT] ld c, a +; Dismiss moves with special effects if they are +; useless or not a good choice right now. +; For example, healing moves, weather moves, Dream Eater... push hl push de push bc @@ -30,6 +33,7 @@ AI_Basic: ; 38591 pop hl jr nz, .discourage +; Dismiss status-only moves if the player can't be statused. ld a, [wEnemyMoveStruct + MOVE_EFFECT] push hl push de @@ -47,6 +51,7 @@ AI_Basic: ; 38591 and a jr nz, .discourage +; Dismiss Safeguard if it's already active. ld a, [PlayerScreens] bit SCREENS_SAFEGUARD, a jr z, .checkmove @@ -69,6 +74,10 @@ AI_Basic: ; 38591 AI_Setup: ; 385e0 ; Use stat-modifying moves on turn 1. +; 50% chance to greatly encourage stat-up moves during the first turn of enemy's Pokemon. +; 50% chance to greatly encourage stat-down moves during the first turn of player's Pokemon. +; Almost 90% chance to greatly discourage stat-modifying moves otherwise. + ld hl, Buffer1 - 1 ld de, EnemyMonMoves ld b, EnemyMonMovesEnd - EnemyMonMoves + 1 @@ -140,7 +149,10 @@ AI_Setup: ; 385e0 AI_Types: ; 38635 -; Use super-effective moves. +; Dismiss any move that the player is immune to. +; Encourage super-effective moves. +; Discourage not very effective moves unless +; all damaging moves are of the same type. ld hl, Buffer1 - 1 ld de, EnemyMonMoves @@ -229,7 +241,7 @@ AI_Types: ; 38635 AI_Offensive: ; 386a2 -; Discourage non-damaging moves. +; Greatly discourage non-damaging moves. ld hl, Buffer1 - 1 ld de, EnemyMonMoves @@ -391,6 +403,9 @@ AI_Smart: ; 386be AI_Smart_Sleep: ; 387e3 +; Greatly encourage sleep inducing moves if the enemy has either Dream Eater or Nightmare. +; 50% chance to greatly encourage sleep inducing moves otherwise. + ld b, EFFECT_DREAM_EATER call AIHasMoveEffect jr c, .asm_387f0 @@ -415,14 +430,19 @@ AI_Smart_LeechHit: ; 387f7 callab Function347c8 pop hl +; 60% chance to discourage this move if not very effective. ld a, [$d265] cp 10 ; 1.0 jr c, .asm_38815 + +; Do nothing if effectiveness is neutral. ret z +; Do nothing if enemy's HP is full. call AICheckEnemyMaxHP ret c +; 80% chance to encourage this move otherwise. call AI_80_20 ret c @@ -546,23 +566,31 @@ AI_Smart_LockOn: ; 3881d AI_Smart_Explosion: ; 388a6 +; Selfdestruct, Explosion + +; Unless this is the enemy's last Pokemon... push hl callba CountEnemyAliveMons pop hl jr nc, .asm_388b7 +; ...greatly discourage this move unless this is the player's last Pokemon too. push hl call AICheckLastPlayerMon pop hl jr nz, .asm_388c6 .asm_388b7 +; Greatly discourage this move if enemy's HP is above 50%. call AICheckEnemyHalfHP jr c, .asm_388c6 +; Do nothing if enemy's HP is below 25%. call AICheckEnemyQuarterHP ret nc +; If enemy's HP is between 25% and 50%, +; over 90% chance to greatly discourage this move. call Random cp 20 ret c @@ -576,9 +604,11 @@ AI_Smart_Explosion: ; 388a6 AI_Smart_DreamEater: ; 388ca +; 90% chance to greatly encourage this move. +; The AI_Basic layer will make sure that +; Dream Eater is only used against sleeping targets. call Random - - cp $19 + cp 25 ret c dec [hl] dec [hl] @@ -588,17 +618,22 @@ AI_Smart_DreamEater: ; 388ca AI_Smart_EvasionUp: ; 388d4 + +; Dismiss this move if enemy's evasion can't raise anymore. ld a, [EnemyEvaLevel] cp $d jp nc, AIDiscourageMove +; If enemy's HP is full... call AICheckEnemyMaxHP jr nc, .asm_388f2 +; ...greatly encourage this move if player is badly poisoned. ld a, [PlayerSubStatus5] bit SUBSTATUS_TOXIC, a jr nz, .asm_388ef +; ...70% chance to greatly encourage this move if player is not badly poisoned. call Random cp $b2 jr nc, .asm_38911 @@ -609,21 +644,27 @@ AI_Smart_EvasionUp: ; 388d4 ret .asm_388f2 + +; Greatly discourage this move if enemy's HP is below 25%. call AICheckEnemyQuarterHP jr nc, .asm_3890f +; If enemy's HP is above 25% but not full, 4% chance to greatly encourage this move. call Random cp $a jr c, .asm_388ef +; If enemy's HP is between 25% and 50%,... call AICheckEnemyHalfHP jr nc, .asm_3890a +; If enemy's HP is above 50% but not full, 20% chance to greatly encourage this move. call AI_80_20 jr c, .asm_388ef jr .asm_38911 .asm_3890a +; ...50% chance to greatly discourage this move. call AI_50_50 jr c, .asm_38911 @@ -631,6 +672,11 @@ AI_Smart_EvasionUp: ; 388d4 inc [hl] inc [hl] +; 30% chance to end up here if enemy's HP is full and player is not badly poisoned. +; 77% chance to end up here if enemy's HP is above 50% but not full. +; 96% chance to end up here if enemy's HP is between 25% and 50%. +; 100% chance to end up here if enemy's HP is below 25%. +; In other words, we only end up here if the move has not been encouraged or dismissed. .asm_38911 ld a, [PlayerSubStatus5] bit SUBSTATUS_TOXIC, a @@ -640,12 +686,14 @@ AI_Smart_EvasionUp: ; 388d4 bit SUBSTATUS_LEECH_SEED, a jr nz, .asm_38941 +; Discourage this move if enemy's evasion level is higher than player's accuracy level. ld a, [EnemyEvaLevel] ld b, a ld a, [PlayerAccLevel] cp b jr c, .asm_38936 +; Greatly encourage this move if the player is in the middle of Fury Cutter or Rollout. ld a, [PlayerFuryCutterCount] and a jr nz, .asm_388ef @@ -659,6 +707,9 @@ AI_Smart_EvasionUp: ; 388d4 inc [hl] ret +; Player is badly poisoned. +; 80% chance to greatly encourage this move. +; This would counter any previous discouragement. .asm_38938 call Random cp $50 @@ -667,6 +718,9 @@ AI_Smart_EvasionUp: ; 388d4 dec [hl] ret +; Player is seeded. +; 50% chance to encourage this move. +; This would partly counter any previous discouragement. .asm_38941 call AI_50_50 ret c @@ -677,10 +731,14 @@ AI_Smart_EvasionUp: ; 388d4 AI_Smart_AlwaysHit: ; 38947 +; 80% chance to greatly encourage this move if either... + +; ...enemy's accuracy level has been lowered three or more stages ld a, [EnemyAccLevel] cp $5 jr c, .asm_38954 +; ...or player's evasion level has been raised three or more stages. ld a, [PlayerEvaLevel] cp $a ret c @@ -696,27 +754,37 @@ AI_Smart_AlwaysHit: ; 38947 AI_Smart_MirrorMove: ; 3895b + +; If the player did not use any move last turn... ld a, [LastEnemyCounterMove] and a jr nz, .asm_38968 - call AICompareSpeed +; ...do nothing if enemy is slower than player + call AICompareSpeed ret nc +; ...or dismiss this move if enemy is faster than player. jp AIDiscourageMove +; If the player did use a move last turn... .asm_38968 push hl - ld hl, GoodMoves + ld hl, UsefulMoves ld de, 1 call IsInArray pop hl + +; ...do nothing if he didn't use a useful move. ret nc +; If he did, 50% chance to encourage this move... call AI_50_50 ret c dec [hl] + +; ...and 90% chance to encourage this move again if the enemy is faster. call AICompareSpeed ret nc @@ -730,16 +798,21 @@ AI_Smart_MirrorMove: ; 3895b AI_Smart_AccuracyDown: ; 38985 + +; If player's HP is full... call AICheckPlayerMaxHP jr nc, .asm_389a0 +; ...and enemy's HP is above 50%... call AICheckEnemyHalfHP jr nc, .asm_389a0 +; ...greatly encourage this move if player is badly poisoned. ld a, [PlayerSubStatus5] bit SUBSTATUS_TOXIC, a jr nz, .asm_3899d +; ...70% chance to greatly encourage this move if player is not badly poisoned. call Random cp $b2 jr nc, .asm_389bf @@ -750,20 +823,26 @@ AI_Smart_AccuracyDown: ; 38985 ret .asm_389a0 + +; Greatly discourage this move if player's HP is below 25%. call AICheckPlayerQuarterHP jr nc, .asm_389bd +; If player's HP is above 25% but not full, 4% chance to greatly encourage this move. call Random cp $a jr c, .asm_3899d +; If player's HP is between 25% and 50%,... call AICheckPlayerHalfHP jr nc, .asm_389b8 +; If player's HP is above 50% but not full, 20% chance to greatly encourage this move. call AI_80_20 jr c, .asm_3899d jr .asm_389bf +; ...50% chance to greatly discourage this move. .asm_389b8 call AI_50_50 jr c, .asm_389bf @@ -772,6 +851,7 @@ AI_Smart_AccuracyDown: ; 38985 inc [hl] inc [hl] +; We only end up here if the move has not been already encouraged. .asm_389bf ld a, [PlayerSubStatus5] bit SUBSTATUS_TOXIC, a @@ -781,12 +861,14 @@ AI_Smart_AccuracyDown: ; 38985 bit SUBSTATUS_LEECH_SEED, a jr nz, .asm_389ef +; Discourage this move if enemy's evasion level is higher than player's accuracy level. ld a, [EnemyEvaLevel] ld b, a ld a, [PlayerAccLevel] cp b jr c, .asm_389e4 +; Greatly encourage this move if the player is in the middle of Fury Cutter or Rollout. ld a, [PlayerFuryCutterCount] and a jr nz, .asm_3899d @@ -799,6 +881,9 @@ AI_Smart_AccuracyDown: ; 38985 inc [hl] ret +; Player is badly poisoned. +; 80% chance to greatly encourage this move. +; This would counter any previous discouragement. .asm_389e6 call Random cp $50 @@ -807,6 +892,9 @@ AI_Smart_AccuracyDown: ; 38985 dec [hl] ret +; Player is seeded. +; 50% chance to encourage this move. +; This would partly counter any previous discouragement. .asm_389ef call AI_50_50 ret c @@ -817,6 +905,8 @@ AI_Smart_AccuracyDown: ; 38985 AI_Smart_Haze: ; 389f5 + +; 85% chance to encourage this move if any of enemy's stat levels is lower than -2. push hl ld hl, EnemyAtkLevel ld c, $8 @@ -828,6 +918,7 @@ AI_Smart_Haze: ; 389f5 jr c, .asm_38a12 jr .asm_389fb +; 85% chance to encourage this move if any of player's stat levels is higher than +2. .asm_38a05 ld hl, PlayerAtkLevel ld c, $8 @@ -846,6 +937,9 @@ AI_Smart_Haze: ; 389f5 dec [hl] ret +; Discourage this move if neither: +; Any of enemy's stat levels is lower than -2. +; Any of player's stat levels is higher than +2. .asm_38a1b pop hl inc [hl] @@ -854,6 +948,8 @@ AI_Smart_Haze: ; 389f5 AI_Smart_Bide: ; 38a1e +; 90% chance to discourage this move unless enemy's HP is full. + call AICheckEnemyMaxHP ret c call Random @@ -865,10 +961,16 @@ AI_Smart_Bide: ; 38a1e AI_Smart_Whirlwind: ; 38a2a +; Whirlwind, Roar. + +; Discourage this move if the player has not shown +; a super-effective move against the enemy. +; Consider player's type(s) if its moves are unknown. + push hl callab Function3484e ld a, [$c716] - cp $a + cp 10 ; neutral pop hl ret c inc [hl] @@ -880,6 +982,10 @@ AI_Smart_Heal: AI_Smart_MorningSun: AI_Smart_Synthesis: AI_Smart_Moonlight: ; 38a3a +; 90% chance to greatly encourage this move if enemy's HP is below 25%. +; Discourage this move if enemy's HP is higher than 50%. +; Do nothing otherwise. + call AICheckEnemyQuarterHP jr nc, .asm_38a45 call AICheckEnemyHalfHP @@ -899,6 +1005,8 @@ AI_Smart_Moonlight: ; 38a3a AI_Smart_Toxic: AI_Smart_LeechSeed: ; 38a4e +; Discourage this move if player's HP is below 50%. + call AICheckPlayerHalfHP ret c inc [hl] @@ -908,6 +1016,8 @@ AI_Smart_LeechSeed: ; 38a4e AI_Smart_LightScreen: AI_Smart_Reflect: ; 38a54 +; Over 90% chance to discourage this move unless enemy's HP is full. + call AICheckEnemyMaxHP ret c call Random @@ -919,6 +1029,9 @@ AI_Smart_Reflect: ; 38a54 AI_Smart_Ohko: ; 38a60 +; Dismiss this move if player's level is higher than enemy's level. +; Else, discourage this move is player's HP is below 50%. + ld a, [BattleMonLevel] ld b, a ld a, [EnemyMonLevel] @@ -932,10 +1045,15 @@ AI_Smart_Ohko: ; 38a60 AI_Smart_Bind: ; 38a71 +; Bind, Wrap, Fire Spin, Clamp + +; 50% chance to discourage this move if the player is already trapped. ld a, [$c730] and a jr nz, .asm_38a8b +; 50% chance to greatly encourage this move if player is either +; badly poisoned, in love, identified, stuck in Rollout, or has a Nightmare. ld a, [PlayerSubStatus5] bit SUBSTATUS_TOXIC, a jr nz, .asm_38a91 @@ -944,10 +1062,12 @@ AI_Smart_Bind: ; 38a71 and 1< player's current HP]. + push hl ld hl, EnemyMonHP ld b, [hl] @@ -1417,6 +1579,9 @@ AI_Smart_PainSplit: ; 38ca4 AI_Smart_Snore: AI_Smart_SleepTalk: ; 38cba +; Greatly encourage this move if enemy is fast asleep. +; Greatly discourage this move otherwise. + ld a, [EnemyMonStatus] and $7 cp $1 @@ -1436,6 +1601,9 @@ AI_Smart_SleepTalk: ; 38cba AI_Smart_DefrostOpponent: ; 38ccb +; Greatly encourage this move if enemy is frozen. +; No move has EFFECT_DEFROST_OPPONENT, so this layer is unused. + ld a, [EnemyMonStatus] and $20 ret z @@ -1512,6 +1680,8 @@ Function_0x38d16; 38d16 AI_Smart_DestinyBond: AI_Smart_Reversal: AI_Smart_SkullBash: ; 38d19 +; Discourage this move if enemy's HP is above 25%. + call AICheckEnemyQuarterHP ret nc inc [hl] @@ -1520,6 +1690,10 @@ AI_Smart_SkullBash: ; 38d19 AI_Smart_HealBell: ; 38d1f +; Dismiss this move if none of the opponent's Pokemon is statused. +; Encourage this move if the enemy is statused. +; 50% chance to greatly encourage this move if the enemy is fast asleep or frozen. + push hl ld a, [OTPartyCount] ld b, a @@ -1533,6 +1707,7 @@ AI_Smart_HealBell: ; 38d1f or [hl] jr z, .next + ; status dec hl dec hl dec hl @@ -1575,12 +1750,14 @@ AI_Smart_HealBell: ; 38d1f AI_Smart_PriorityHit: ; 38d5a call AICompareSpeed - ret c + +; Dismiss this move if the player is flying or underground. ld a, [PlayerSubStatus3] and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND jp nz, AIDiscourageMove +; Greatly encourage this move if it will KO the player. ld a, $1 ld [hBattleTurn], a push hl @@ -1605,6 +1782,8 @@ AI_Smart_PriorityHit: ; 38d5a AI_Smart_Thief: ; 38d93 +; Don't use Thief unless it's the only move available. + ld a, [hl] add $1e ld [hl], a @@ -1659,7 +1838,7 @@ AI_Smart_Disable: ; 38dd1 push hl ld a, [LastEnemyCounterMove] - ld hl, GoodMoves + ld hl, UsefulMoves ld de, 1 call IsInArray @@ -1695,18 +1874,22 @@ AI_Smart_MeanLook: ; 38dfb pop hl jp z, AIDiscourageMove +; 80% chance to greatly encourage this move if the enemy is badly poisoned (weird). ld a, [EnemySubStatus5] bit SUBSTATUS_TOXIC, a jr nz, .asm_38e26 +; 80% chance to greatly encourage this move if the player is either +; in love, identified, stuck in Rollout, or has a Nightmare. ld a, [PlayerSubStatus1] and 1<