Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
Our weekly protagonist poll is now up! Vote for your favorite Conquest protagonist in the poll by clicking here.
Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.
It's alright, all of us procrastinate to some extent. By the way since you have added a updated animations section, I might as well share my updated Mud Shot animation:
Step 1: First, add this command in commands.bsh for Battle Script Pro (credit to KDS for first discovering this when he posted his Incinerate script):
Spoiler:
#command removeitem 0x6A 0x1 "Bank" 0x1
(this command to remove items is already in the game so you don't need to add code or anything, it's just unidentified by BSP)
Step 2:
Compile the following table and put it into free space, make sure you take note of the offset you put it in. We'll refer to this table as NATURAL GIFT TABLE:
When compiled, the format of this table will be [XX XX] [YY] [ZZ], with XXXX being the index number of the item, YY being the type that Natural Gift will change into, and ZZ being the base power. This table only covers the berries that are in Gen 3, so if you've added new berries then you'll have to add them into the table. MAKE SURE YOU LEAVE THE FOUR FF BYTES AT THE END, DO NOT OVERWRITE IT. (or change them to FE bytes, and in Step 3 modify the line "mov r4, 0xFF" to "mov r4, 0xFE").
Step 3:
Insert this routine into free space, and take note of its offset. We'll refer to this as ASM ROUTINE 1:
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global test
main:
push {lr}
ldr r0, .UserBank
ldr r1, .BattleData
ldrb r0, [r0]
mov r2, #0x58
mul r2, r0
add r1, #0x2E
add r1, r2
ldrh r0, [r1] /*r0 should now have held item. r1 is the RAM offset of the held item*/
cmp r0, #0x0
beq Abort
ldr r2, .NaturalGiftTable
mov r4, #0xFF
Make sure you put in the offset of the Natural Gift table at the last line.
Step 4:
Now, insert this routine into free space as well, and take note of its offset. We'll refer to this as ASM ROUTINE 2:
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global test
GetOpponentType:
push {lr}
ldr r0, .TargetBank
ldr r1, .BattleData
ldrb r0, [r0]
mov r2, #0x58
mul r2, r0
add r1, #0x21
add r1, r2
ldrb r0, [r1] /*r0 should now have opponent Type 1*/
ldrb r2, [r1, #0x1] /*r2 should now have opponent Type 2*/
GetNaturalGiftType:
ldr r1, .MemAddress
ldr r1, [r1]
add r1, #0x13
ldrb r1, [r1] /*r1 should now have modified Natural Gift type*/
ldr r3, .TypeChart
/*check attacking type*/
Check1:
ldrb r4, [r3] /*r4 has Type Chart attacking type*/
ldrb r5, [r3, #0x1] /*r5 has Type Chart defending type*/
ldrb r6, [r3, #0x2] /*r6 has Type Chart effectiveness*/
cmp r4, #0xFE
beq Abort
cmp r1, r4 /*check NG type with Attacking type*/
bne Recheck
cmp r0, r5 /*check opponent Type 1 with Defending type*/
beq Type1Match
cmp r2, r5 /*check opponent Type 2 with Defending type*/
beq OkNowCheckType1
add r3, #0x3
b Check1
OkNowCheckType1:
ldr r3, .TypeChart
b StillCheckinglol
/*we should be here if Type 2 was a match but Type 1 wasn't*/
StillCheckinglol:
ldrb r4, [r3] /*r4 has Type Chart attacking type*/
ldrb r5, [r3, #0x1] /*r5 has Type Chart defending type*/
ldrb r7, [r3, #0x2] /*r7 has Type Chart effectiveness*/
cmp r4, #0xFE
beq SameOutcome
cmp r1, r4 /*check NG type with Attacking type*/
bne Recheck3
cmp r0, r5 /*check opponent Type 1 Defending type*/
beq Type2Match
add r3, #0x3
b Check2
Type1Match:
ldr r3, .TypeChart
b Check2
Check2:
ldrb r4, [r3] /*r4 has Type Chart attacking type*/
ldrb r5, [r3, #0x1] /*r5 has Type Chart defending type*/
ldrb r7, [r3, #0x2] /*r7 has Type Chart effectiveness*/
cmp r4, #0xFE
beq SameOutcome
cmp r1, r4 /*check NG type with Attacking type*/
bne Recheck2
cmp r2, r5 /*check opponent Type 2 Defending type*/
beq Type2Match
add r3, #0x3
b Check2
WeakDamage:
ldr r0, .Outcome
mov r1, #0x04
strb r1, [r0]
b End
NoDamage:
ldr r0, .Outcome
mov r1, #0x08
strb r1, [r0]
b End
SuperDamage:
ldr r0, .Outcome
mov r1, #0x02
strb r1, [r0]
b End
Abort:
End:
pop {r0}
bx r0
.align 2
.Outcome: .word 0x02023DCC .TypeChart: .word 0x0824F050 /*make sure you replace this with the offset of your own type chart*/
.BattleData: .word 0x02023BE4
.TargetBank: .word 0x02023D6C
.MemAddress: .word 0x02023FE8
Note: If you have repointed your type chart, then you will have to put its new offset where I've bolded above.
Here's an explanation as to how this works:
So as you can see, "ASM ROUTINE 1" looks up the custom table we inserted and matches your held item to it (the move will fail if you're not holding an item or if you're holding an item that's not in the table), and then updates the type and base power accordingly. Now, with this routine alone, the damage and type calculations are correct, but the outcome message will always act as a regular move (regular as in not super-effective or not not-very-effective) unless if you don't have an item in the table (then it will just fail), and turns out the reason why is for some reason the outcome RAM offset (02023DCC) wasn't getting updated even though the battle engine should theoretically already have done so (if you have the routine be the first thing in the script). So what "ASM ROUTINE 2" does is that it looks up the type chart and the opponent's types and determines the outcome that way (and yes, I checked and double checked and triple checked with various berry & type combinations, so it works). It wasn't ideal, but it was necessary in order to get the correct message to show up.
"But Chaos, couldn't you just look at how Weather Ball and Hidden Power does it"? Well, I did (for anyone curious, the Weather Ball command's routine is at 0802D090, while the Hidden Power command's routine is at 0802B678), and what both do is that they update the value held by the pointer at 02023FE8(a dynamic memory location) + 0x13, usually the pointer at 02023FE8 leads to 02000010, so the type value is (usually) at 02000023. No matter what I tried with updating that value, it always played the normal hit sound (but would still do more or less damage depending on type, such as Electric type Natural Gift doing more damage to Pidgey than Water type Natural Gift), unless if it was a type immunity in which case it worked as expected. For testing reasons I tried giving a new test move Hidden Power's battle script ID, and turns out the correct sound effect doesn't play either (but it does with Hidden Power itself, even though I gave them the same battle script ID), and turns out the outcome offset was only being updated when using the actual Hidden Power, which leads me to believe that Hidden Power and Weather Ball's move ID's are hard-coded to update the outcome offset. So the whole purpose of "ASM ROUTINE 2" is to circumvent that. "ASM ROUTINE 2" manually looks up the type chart and what outcome it should be, and updates the outcome value at 02023DCC accordingly.
As for the animation, I just use Acid's animation but modified with Sleep Powder's palette, which makes it look a nice greenish-brown color just like the official games.
Power Trick: (note that this doesn't account for Baton Passing like the official games, sorry :P)
Exactly the same as above for Gastro Acid, but use this string and ASM instead.
String:
FD 0F 00 E7 EB DD E8 D7 DC D9 D8 00 DD E8 E7 00 BB E8 E8 D5 D7 DF 00 FE D5 E2 D8 00 BE D9 DA D9 E2 E7 D9 AB FF 00
StatusCheck: /*checks if target is readying a status move*/
ldr r0, .TargetBank /*get target slot ID*/
ldrb r0, [r0, #0x0] /*r0 has target bank*/
lsl r0, #0x1
ldr r1, .MovesUsed /*r1 has MovesUsed*/
add r0, r1 /*Target's moved used?*/
ldrh r6, [r0]
ldrh r0, [r0] /*r0 has the move that target is going to use*/
ldr r1, .MoveTable /*r1 now has MoveTable*/
mov r2, #0xc /*move data is C bytes*/
mul r0, r2 /*move ID x C*/
add r0, r1 /*get move offset*/
ldrb r0, [r0, #0xa] /*check the move's class*/
cmp r0, #0x2 /*is it a status move?*/
beq Abort /*if so, the move fails*/ sub r6, #0x1
lsr r6, #0x1
cmp r6, #0xB5 /*fail if Natural Gift*/
beq Abort
OrderCheck:
ldr r0, .TargetBank
ldr r1, .UserBank
ldrb r4, [r0, #0x0] /*put target bank into R4*/
ldrb r5, [r1, #0x0] /*put user bank into R5*/
ldr r1, .TurnOrder /*put turn order offset into R1*/
Loop:
ldrb r2, [r1, #0x0] /*put attacking PKMN into r2*/
cmp r2, r4 /*is the attacking PKMN the target?*/
beq Abort /*if so, quit*/
cmp r2, r5 /*is the attacking PKMN the user?*/
beq End /*if so, attack*/
add r1, #0x1 /*move on to next attacking PKMN*/
b Loop
Abort:
ldr r0, .CurrentScript
ldr r1, .FailScript
str r1, [r0, #0x0]
b End
.UserBank: .word 0x02023D6B
.TargetBank: .word 0x02023D6C
.BattleStruct: .word 0x02023BE4
.MovesUsed: .word 0x02023dc4
.MoveTable: .word 0x08(offset of your move data table)
.CurrentAttack: .word 0x02023D4A
ASM routine 3:
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global test
Main:
push {lr}
ldr r0, .TargetBank /*what slot is the target*/
ldrb r0, [r0, #0x0]
ldr r1, .BattleStruct
mov r2, #0x58
mul r0, r2
add r5, r0, r1
SetStuff:
ldr r0, .TargetBank /*get target slot ID*/
ldrb r0, [r0, #0x0] /*r0 has target bank*/
lsl r0, #0x1
ldr r1, .MovesUsed /*r1 has MovesUsed*/
add r0, r1 /*Target's moved used?*/
ldrh r6, [r0]
ldrh r0, [r0] /*r0 has the move that target is going to use*/
ldr r1, .MoveTable /*r1 now has MoveTable*/
mov r2, #0xc /*move data is C bytes*/
mul r0, r2 /*move ID x C*/
add r0, r1 /*get move offset*/
ldrb r0, [r0, #0xA]
ldrb r3, [r0, #0x0] /*r0 should now have move effect*/
cmp r0, #0x2
beq Abort
StealMove:
ldr r1, .EffectTable
mov r2, #0x4
mul r3, r2
add r1, r3 /*r1 should now be at the correct offset of the move table*/
ldr r1, [r1] /*r1 should now have the effect script offset*/
ldr r0, .CurrentScript
str r1, [r0]
b End
Abort:
ldr r0, .CurrentScript
ldr r1, .FailScript
str r1, [r0, #0x0]
b End
End:
pop {r0}
bx r0
.align 2
.UserBank: .word 0x02023D6B
.TargetBank: .word 0x02023D6C
.BattleStruct: .word 0x02023BE4
.BasePower: .word 0x02023F50
.TurnOrder: .word 0x02023bde
.MonsMoved: .word 0x02023be2
.MovesUsed: .word 0x02023dc4
.MoveTable: .word 0x08(offset of your move data table)
.EffectTable: .word 0x08(offset of your move effect table)
.CurrentScript: .word 0x02023d74
.FailScript: .word 0x081D7DF0
And finally, use this battle script:
Spoiler:
#org @MeFirst
attackcanceler
attackstring
callasm 0x8(offset of the first ASM routine + 1)
attackanimation
waitanimation
callasm 0x8(offset of the second ASM routine + 1)
setbyte 0x2023FDC 0x0
setbyte 0x2023FDD 0x0
printstring 0x4
callasm 0x8(offset of the third ASM routine + 1)
I know this method seems rather ridiculous to require 3 callasm's (and maybe there might be some redundant checks left in there because they were all modified heavily from Doesnt's Sucker Punch routine), but basically this method insures that it first prints "[user] used Me First!", does Me First's unique animation, then updates the RAM to the stolen Move ID, then says, "[user] used [stolen move]!" and plays the stolen move's animation. Having three check routines in between commands was necessary for Me First to have it's own unique animation AND still play the new animation afterwards AND display the updated string afterwards.
-----------------------------------------------------
(these particles are just for Power Trick and Wring Out. Use Psych Up's movement for Power Trick, and use Gust's movement for Wring Out)
(FireRed) Psycho Cut animation that looks more similar to the in-game one. Psycho Cut is not a contact move, so this would be more fitting (it's basically Air Cutter with the Psychic background). Basically the concept is that the user creates a blade with his/her Psychic powers.
Also have some particles. They're already indexed. Use the Aura Sphere particle with Shadow Ball's movement and that bright-blue BG. Use the Energy Ball particle with Shadow Ball's movement as well. Use the Power Gem particle with Hidden Power's movement. And lastly, the Sucker Punch particle can be used for any Dark or Poison move where you want a purple hit marker.
And heres my take on a Dragon Rush animation. Since the 4th/5th gen animations are kind of generic, my one is also. Its just the slam animation with Blaze Burn/Hydro Cannon's "solarize" like effect.
The recharging stones part from the Ancient Power's animation then blast from the Rock Blast animation with an attack background like it was shown in D/P/Pt/HG/SS. The animation almost looks like from the games but I would make a particle of the Rock Wrecker soon.
But first, you need to have the attack backgrounds expanded. If you don't know how, read this thread: https://www.pokecommunity.com/threads/281520. If you do, you need to have the image, palette, and tilemap inserted in game. To where you have inserted it, replace XX with that value (example: 1B is the background). The image, palette, and tilemap are in the zip in the attachment below. Credits to MrDollSteak for the Rock Wrecker background. Sorry to rip from your ROM Base since it is an open resource anyway. :3
PS : I wanted to created an effect like Judgment, but I don't know if there is a function to set the attack's type. And I don't remember the function to check the held object. Also, is it possible to change the ratio of drained HP in the drain effect, in order to make Oblivion Wing ? Thanks.
Didn't test the other, but U-turn doesn't take in count Shadowtag ability. A jumpifability 0x0 0x17 should be enough I guess
And it fail if you have only one pokemon
EDIT : Nope, I still can switch in double battle. And the move completely fail in one vs one. It's a progress I guess..
Tested your command out on Emerald and got some weird result. Since the final command on the Emerald Battle Command Table is F8, and I use F9 for callasm, I set cureprimarystatus as FA.
When I tried to attack a sleeping opponent with Wake-Up Slap, the game froze when the battle script reached cureprimary status.
I pretty much copy pasted all your stuff so it should be all right. I did not forget to put +1 at asm offsets either.
EDIT: Scald just completely glitches out before the attack-animation. This is unlikely to be due to the command though.
Tested your command out on Emerald and got some weird result. Since the final command on the Emerald Battle Command Table is F8, and I use F9 for callasm, I set cureprimarystatus as FA.
When I tried to attack a sleeping opponent with Wake-Up Slap, the game froze when the battle script reached cureprimary status.
I pretty much copy pasted all your stuff so it should be all right. I did not forget to put +1 at asm offsets either.
EDIT: Scald just completely glitches out before the attack-animation. This is unlikely to be due to the command though.
Quick question: I'm trying to get your Psycho Shift to work, but I just get "the move failed" every time. When I tried to complie the script, BSP wouldn't let me include "#include std.bsh" -- could that be the reason?
What does std.bsh do and would you know how I can get BSP to compile with it?
Quick question: I'm trying to get your Psycho Shift to work, but I just get "the move failed" every time. When I tried to complie the script, BSP wouldn't let me include "#include std.bsh" -- could that be the reason?
What does std.bsh do and would you know how I can get BSP to compile with it?
Just callasm this routine before the attackcanceler in battle script. Pm if there is bug/problem/other
I think it's not optimized but whatever, it works. I'll see if I can change it
I actually got this and Judgement without the help of your second routine.
It is also displaying the correct outcome and the proper effectiveness sound is playing.
(I used Tackle and Move Effect ID 1 for this).
The problem lies with the placement of the 1st routine.
The battle script should be:
Move type changing routines should be placed before the attack canceler because it contains checks for abilities like Flash Fire, Water Absorb etc. The original battle script wouldn't account for this.
Also this might be the reason why the outcome might not be properly handled.
Judgment should a script like that of Weatherball i.e callasm then goto the regular attack routine.
Also the fail address pointer in the 1st routine should be (0x081D7DF2 - 0x5). Even though with the original value it is working. It might not be the case with other scripts.
While branching to custom scripts with callasm command, 0x5 must be subtracted from their offset, because callasm always adds 0x5 to the script pointer regardless of the branch.
Did any1 find a way to make Bind etc. do 1/8 damage as opposed to 1/16? I know it's been found for Rough skin so I guess it would only require a byte change or two.
Got a problem here. I put my routine before the attackcanceler as you adviced, water/volt absorb didn't work, but levitate did. Do I have to callasm (myroutine - 0x5 +1) or (myroutine - 0x5) or just (myroutine +1) as usual ? I didn't get what you said in your last post.
Hmm, I'll like into the volt absorb thingy if I have time.
Routine+1 is correct. (The -5 is for an alternate script. It is used if the routine specified in the callasm command can branch to more than one different battle scripts.)
Accuracy checker should be there in thd battle script. If you want infinite accuracy you can just set the move accuracy to zero using an editor.
Hmm, I'll like into the volt absorb thingy if I have time.
Routine+1 is correct. (The -5 is for an alternate script. It is used if the routine specified in the callasm command can branch to more than one different battle scripts.)
Accuracy checker should be there in thd battle script. If you want infinite accuracy you can just set the move accuracy to zero using an editor.
For the accuracy, I just followed the Jambo51's advice in his tutorial. Because set accuracy to zero make the move always miss, but set it to 255 will make it never miss. The problem is I don't like seeing accuracy = 255 in move description, it doesn't look legit at all.
Would be great to have a routine that make appear "---" instead of "255" but anyway. Would be cool if you find a way to fix absorb ability
For the accuracy, I just followed the Jambo51's advice in his tutorial. Because set accuracy to zero make the move always miss, but set it to 255 will make it never miss. The problem is I don't like seeing accuracy = 255 in move description, it doesn't look legit at all.
Would be great to have a routine that make appear "---" instead of "255" but anyway. Would be cool if you find a way to fix absorb ability
Actually it seems that the absorb abilities are called from the accuracy checker command. So you need to include the accuracy checker as well.
To set the move accuracy to display --- , you need to set the accuracy to 0.
Judgment has 100% accuracy according to bulbapedia not infinite.
Also, you can reduce Judgement's battle script to 2 lines only.
I.e 1. callasm offset
2. goto basic damage script