Gw Temp

Menu

Tutorial - 'ABS Tutorial Part 5 - Targetting and Other Spells' by AzureFenrir

An item about RPGMaker 2000 posted on

Blurb

The fifth installment of AzureFenrir's huge ABS tutorials that reveals the secrets to targetable spells as well as delayed spells and continuous spells.

Download the accompanying demo project for Part 3, 4, and 5 here: http://staff.whahay.net/AzureFenrir/Tutorial/ABSDemo.zip

Body

ABS Tutorial Part 5 - Targetting, Delayed spells, and Continuous Spells


Wow, I just realized that the last three tutorials took me a combined 19-26 hours to write. It seems like I have no life outside of writing tutorials after all!

This tutorial covers how you can implement many different targetting spells (spells that allow you to specify exactly WHERE you want to target), as well as making delayed-impact spells (spells that wait a while before inflicting damage) and continuous spells (spells that continuously damage an enemy as long as he stands on it). Whahay!

So, without further ado, let's get started. Here's what you need to know before you read this tutorial:

THINGS THAT YOU NEED TO KNOW:

Serious Experience with and Knowledge of RM2K Commands
Using and Manipulating Switches
Using and Manipulating Variables
Fork Statements
Serious Experience with Using/Manipulating the RM2K Coordinate System
Knowledge of Pixel and Coordinate Conversions


And of course, the flexible switches and variables:

SWITCHES AND VARIABLES:

4 Variables - "WatchX", "WatchY", "SpellX", "SpellY"
Additional switches and variables vary by spell type.


Before I begin, I would like to point out that this tutorial includes a DEMO Project, which you can download here: http://staff.whahay.net/AzureFenrir/Tutorial/ABSDemo.zip



Making a Map Targetting System (that can target any spot on the screen)

A Map Targetting System is basically a targetting system that allows you to select a square tile on the map. Once you select it, that tile becomes "targetted," and the spell effect will occur at that tile:



Fist of all, all map targetting spells can have the same setup code (the code that detects if the user pressed the "spell" key and initiates the targetting), since the targetting will remain the same.

Obviously, we need a new parallel process event to detect if the player pressed the "spell key," right? So, let's create one and name it "Spellgiver." Put the following code in there (I'll explain what they do afterwards):

RPG Maker 2000 Code:

<>Enter Password: [0006:Temp]
<>Set Screen Tone:[R050,G050,B050,S100],0.5sec

<>Variable Ch:[0007:SpellX] Set, Hero PicsX
<>Variable Ch:[0008:SpellY] Set, Hero PicsY
<>Variable Ch:[0007:SpellX] -, 8
<>Variable Ch:[0008:SpellY] -, 16
<>Variable Ch:[0007:SpellX] /, 16
<>Variable Ch:[0008:SpellY] /, 16

<>Variable Ch:[0009:TempX] Set, Var.[0007]val.
<>Variable Ch:[0009:TempX] *, 16
<>Variable Ch:[0009:TempX] +, 8
<>Variable Ch:[0010:TempY] Set, Var.[0007]val.
<>Variable Ch:[0010:TempY] *, 16
<>Variable Ch:[0010:TempY] +, 8

<>Show Picture: 16, Targetting, (V[0009],V[0010])
<>Change Switch:[0042:Target Method MAP]-ON Set


As you know, this code initializes the targetting cursor (the little targetting cross) to the tile where the hero is standing (it's some kind of RPG Convention).

However, before it could do that, it needs to detect whether the player WANTS to shoot the spell. To do that, I used an "Enter Password" command so that the rest of the code won't run until the Decision Key (or whatever your spell key is) is pressed. Make sure to check the "Wait Until Key Hit"!

The "Set Screen Tone" just darkens the screen to show that targetting is occuring and all events are paused. It's normal RPG convention (and it looks better), but you can remove it if you want.

The next parts are the most "complex" aspects of this entire thing. The first block of code detects where the hero is (in relation to the upper-left corner of the viewing screen). To do that, it starts off by detecting the pixel coordinates of the center of the hero's feet. Because this is the hero's feet (8 pixels to the right and 16 pixels below the tile), we need to subtract the extraneous pixels fist, and then divide by 16 to find the tile.

Then, we convert the coordinates back into pixels since that's how pictures are displayed. Because each tile is 16x16, we must multiply the "Tile Coordinates" by 16 to get the pixel coordinates. Also, we want the pixel coordinates of the CENTER of the tile, so we must also add 1/2 of 16 (which is 8).

Notice that we used TempX and TempY instead of SpellX and SpellY. That's because the Temp variables only temporarily store the "target cross" picture's X and Y coordinates. We still need the tile coordinates for calculation!

Finally, we show the cross target and changes a "Targetting Switch" ON. Make sure that you add a page at the end and make its start conditions "Switch: Target Event MAP - ON" so that this event won't bug us when the user is trying to target his spell!

Now, we need another event (you could use the second page of the Spellgiver event if you'd like) for actually moving the target cross and firing the spell. To do that, we need an Auto Start event. Why Auto Start? Because it prevents the enemies from moving when the user is trying to target an enemy. Believe me, that's not simply RPG convention - it IS a good thing.

So, inside this auto-start event, change the start conditions to "Target Method MAP", and add the following code to the page:

RPG Maker 2000 Code:

<>Enter Password: [0006:Temp]
<>FORK Optn:Varbl[0006:Temp]-1
    <>Variable Ch:[0008:SpellY] +, 1

    <>FORK Optn:Varbl[0007:SpellX]-0less
        <>Variable Ch:[0007:SpellX] Set, 19
        <>
    : End Case
    <>FORK Optn:Varbl[0007:SpellX]-19abov
        <>Variable Ch:[0007:SpellX] Set, 0
        <>
    : End Case
    <>FORK Optn:Varbl[0008:SpellY]-0less
        <>Variable Ch:[0008:SpellY] Set, 14
        <>
    : End Case
    <>FORK Optn:Varbl[0008:SpellY]-14abov
        <>Variable Ch:[0008:SpellY] Set, 0
        <>
    : End Case

    <>Variable Ch:[0009:TempX] Set, Var.[0007]val.
    <>Variable Ch:[0009:TempX] *, 16
    <>Variable Ch:[0009:TempX] +, 8
    <>Variable Ch:[0010:TempY] Set, Var.[0007]val.
    <>Variable Ch:[0010:TempY] *, 16
    <>Variable Ch:[0010:TempY] +, 8

    <>Move Picture: 16, (V[0009],V[0010]),0.1sec(W)

    <>
: END Case


I guess I have to explain that (at least the italic part), right?

Well, first of all, you obviously must be able to control (move) the target with the arrow keys. So...the same "wait until key hit" Enter Password again :). This time, make sure that you check the arrow keys, the decision key, and the cancel key (all three). You'll see why later.

Obviously, since 1 correlates with "down", the FORK statement is detecting if the player pressed the down key. If it does, then it increases the variable SpellY (the tile coordinates of the targetted tile) by one, essentially moving it down.

Now comes the italic part. The first four FORK statements detect whether the cursor moved off the screen (remember that the RM2K(3) screen is 20x15). If it did, then move the cursor to the opposite edge of the screen. Then, it converts "SpellX" and "SpellY" into pixel coordinates in the same fashion as described above, and moves the :targetting" picture to the new coordinates.

After that, there's the END CASE. EVERYTHING HAS ENDED!!! NOES...:P

Anyway, you have to repeat this code for every arrow key. So:

RPG Maker 2000 Code:

<>FORK Optn:Varbl[0006:Temp]-2
    <>Variable Ch:[0007:SpellX] -, 1
    <>Insert Italicized Code Segment (from above) here.
    <>
: END Case
<>FORK Optn:Varbl[0006:Temp]-3
    <>Variable Ch:[0007:SpellX] +, 1
    <>Insert Italicized Code Segment (from above) here.
    <>
: END Case
<>FORK Optn:Varbl[0006:Temp]-4
    <>Variable Ch:[0008:SpellY] -, 1
    <>Insert Italicized Code Segment (from above) here.
    <>
: END Case
<>FORK Optn:Varbl[0006:Temp]-5
    <>Set Screen Tone:(R100,G100,B100,S100),0.5sec
    <>Erase Picture: 16

    <>Variable Ch:[0009:TempX] Set, Hero PicsX
    <>Variable Ch:[0010:TempY] Set, Hero PicsY
    <>Variable Ch:[0009:TempX] -, 8
    <>Variable Ch:[0010:TempY] -, 16
    <>Variable Ch:[0009:TempX] /, 16
    <>Variable Ch:[0010:TempY] /, 16

    <>Variable Ch:[0001:HeroX] Set, Hero X pos
    <>Variable Ch:[0002:HeroY] Set, Hero Y pos
    <>Variable Ch:[0001:HeroX] -, Var.[0009:TempX]val.
    <>Variable Ch:[0002:HeroY] -, Var.[0010:TempY]val.

    <>Variable Ch:[0007:SpellX] +, Var.[0001:HeroX]val.
    <>Variable Ch:[0008:SpellY] +, Var.[0002:HeroY]val.

    <>NOTE: =====================================================
    <>NOTE: Insert Spell Effect Here!
    <>NOTE: =====================================================


    <>Change Switch: [0042:Target Method MAP]-OFF Set
    <>
: END Case
<>FORK Optn:Varbl[0006:Temp]-6
    <>Set Screen Tone:(R100,G100,B100,S100),0.5sec
    <>Erase Picture: 16
    <>Change Switch: [0042:Target Method MAP]-OFF Set
    <>
: END Case


The other fork statements should be quite easy to understand...except the fifth one. Well, we know that 5 is the number for "Decision Key," which will cause the spell effect to occur.

But before we can do anything with the spell, take a closer look at SpellX and SpellY...that's right, they are in tile coordinates, but it's in relation to THE UPPER-LEFT CORNER OF THE SCREEN! Oh no! How do we change it to actualy map coordinates?

Well, what if...we somehow found out the map coordinates of the upper-left corner of the screen? Then, we could simply ADD the SpellX and SpellY to the upper-left corner's map coodinates! But how do we do that?

Since I'm lazy, I'll just copy my explanation from my previous tutorial. First of all, we need to store the hero's curent SceneX and SceneY in two temporary variables:

RPG Maker 2000 Code:

<>Variable Ch:[0009:TempX] Set, Hero Pics X
<>Variable Ch:[0010:TempY] Set, Hero Pics Y


This will give you the location of the center of the hero's feet, which is 8 pixels to the left and 16 pixels below the upper-left corner of the tile. So...to properly convert this into coordinates, we must first subtract these extraneous values from the temporary variables:

RPG Maker 2000 Code:

<>Variable Ch:[0009:TempX] -, 8
<>Variable Ch:[0010:TempY] -, 16


Finally, divide the two variables by 16 (each tile in RM2K is 16x16) to obtain the hero's coordinates reletive to the upper-left corner of the screen:

RPG Maker 2000 Code:

<>Variable Ch:[0009:TempX] /, 16
<>Variable Ch:[0010:TempY] /, 16


So...now we have this information, but how do we use it? Well, we need to know the coordinates of the tile in the upper-left corner of the current screen, right? So, if we know the hero's screen position, we can get that tile's coordinates by subtracting the hero's actual coordinates by his screen coordinates!

RPG Maker 2000 Code:

<>Variable Ch:[0029:ScreenLeftX] Set, Hero X pos
<>Variable Ch:[0030:ScreenTopY] Set, Hero Y pos
<>Variable Ch:[0029:ScreenLeftX] -, Var.[0009:TempX] val.
<>Variable Ch:[0030:ScreenTopY] -, Var.[0010:TempY] val.


Finally, you have to add the screen coodinates to the coodinates of the upper-left corner:

RPG Maker 2000 Code:

    <>Variable Ch:[0007:SpellX] +, Var.[0001:HeroX]val.
    <>Variable Ch:[0008:SpellY] +, Var.[0002:HeroY]val.


And there's your basic targetting code! The Insert Spell Effect Here is just as it says - the actualy effect ot the spell (battle animations, etc.) goes here.



Making a Enemy Targetting System (that targets enemies instead of tiles)



You are probably saying, "Oh no! Not another mammoth-sized section!" That was definitely longe than I expected. It's probably even worthy of its own tutorial...

But no fears! This section of the tutorial is much much shorter! Yes, I am serious.

Target Enemy is somewhat different from Target Map because this targetting system allows you to select

Anyway, here's the code for "Spellgiver," which, as you may remember, initiates the targetting:

RPG Maker 2000 Code:

<>Enter Password: [0006:Temp]
<>Set Screen Tone:[R050,G050,B050,S100],0.5sec(W)

<>Variable Ch:[0007:SpellX] Set, 0

<>Variable Ch:[0009:TempX] Set, Enemy1 PicX
<>Variable Ch:[0010:TempX] Set, Enemy1 PicY

<>Show Picture: 16, Targetting, (V[0009],V[0010])
<>Change Switch:[0042:Target Method ENEMY]-ON Set


I think that the code should be quite easy to understand. We basically initialized the targetting cursor to the location of the first enemy on the map. In addition, you still have to add a new page to this event and set it to "Switch [0042:Target Method ENEMY]-ON" so that this event doesn't run again while the player is trying to choose his/her target.

So, just as in the targetting event, you need another AUTO START event (you could just make this the second page of your Spellgiver event if you want) that activates when Switch [Target Event ENEMY] is ON. Put the following code in there:

RPG Maker 2000 Code:

<>Enter Password: [0006:Temp]
<>FORK Optn:Varbl[0006:Temp]-1
    <>Variable Ch:[0008:SpellY] -, 1

    <>FORK Optn:Varbl[0007:SpellX]--1
        <>Variable Ch:[0007:SpellX] Set, [# of enemies that you have minus 1]
        <>
    : END Case
    <>FORK Optn:Varbl[0007:SpellX]-[# of enemies that you have]
        <>Variable Ch:[0007:SpellX] Set, 0
        <>
    : END Case

    <>FORK Optn:Varbl[0007:SpellX]-0
        <>Variable Ch:[0009:SpellX] Set, Enemy1 PicX
        <>Variable Ch:[0010:SpellX] Set, Enemy1 PicX
        <>
    : END Case
    <>Note: Repeat this for every enemy.

    <>Move Picture: 16, (V[0009],V[0010]),0.3sec(W)

    <>
: END Case


As you can see, we are using SpellX to store which enemy the targetting cursor is on. The first bit of code (with the FORK statements) makes sure that the target doesn't, say, move to Enemy #8 when there's only seven enemies. Afterwards, the event simply uses a few FORK statements to check which enemy is currently selected (by checking the value of SpellX), and moving the hand cursor to the appropriate enemy.

You could (and I would recommend that you do) use another variable for this instead of SpellX. It makes the next part easier (well...one checkmark easier :P).

So...let's go on:


RPG Maker 2000 Code:

<>Enter Password: [0006:Temp]
<>FORK Optn:Varbl[0006:Temp]-2
    <>Variable Ch:[0008:SpellY] -, 1
    <>Insert Italicized Code Segment (from above) here.
    <>
: END Case
<>FORK Optn:Varbl[0006:Temp]-3
    <>Variable Ch:[0008:SpellY] +, 1
    <>Insert Italicized Code Segment (from above) here.
    <>
: END Case
<>FORK Optn:Varbl[0006:Temp]-4
    <>Variable Ch:[0008:SpellY] +, 1
    <>Insert Italicized Code Segment (from above) here.
    <>
: END Case
<>FORK Optn:Varbl[0006:Temp]-5
    <>Set Screen Tone:(R100,G100,B100,S100),0.5sec
    <>Erase Picture: 16

    <>NOTE: =====================================================
    <>NOTE: Insert Spell Effect Here!
    <>NOTE: =====================================================


    <>Change Switch: [0042:Target Method ENEMY]-OFF Set
    <>
: END Case
<>FORK Optn:Varbl[0006:Temp]-6
    <>Set Screen Tone:(R100,G100,B100,S100),0.5sec
    <>Erase Picture: 16
    <>Change Switch: [0042:Target Method ENEMY]-OFF Set
    <>
: END Case


The rest is pretty easy to understand. See? I told you that it won't be as long.



Target Map Spell Effects: Instant-Effect

Um...yes. Instant-effect spells basically show an animation of the spell and immediately damage the enemy without any delay. The basic spell effect code is quite simple: a Show Animation command, and the same collision detection code that we used in projectiles:

RPG Maker 2000 Code:

<>Setup Event's Place: Animation Event, (V[0007:SpellX],V[0008:SpellY])
<>Show Battle Animation: Bomb, Animation Event(W)

<>Variable Ch:[0003:WatchX] Set, Enemy1 X pos
<>Variable Ch:[0004:WatchY] Set, Enemy1 Y pos
<>FORK Optn:Varbl[0007:SpellX]-V[0003:WatchX] Equivl
    <>FORK Optn:Varbl[0008:SpellY]-V[0004:WatchY] Equivl
        <>Damage Enemy: Enemy1
        <>Play Sound Effect: Damage2
        <>Change Switch:[0003:PrjtStraightON]-OFF Set
        <>
    : END Case
    <>
: END Case
<>Note:Repeat for every enemy on the map.


That's right, we've reintroduced the Animation Event (RandomHitEvent) from the Instant-Effect Spells tutorial. The event is positioned at SpellX and SpellY so that the battle animation can be shown in the right place.

The rest is the basic enemy collision code. The FORK statements check whether the enemy is in the same place as the spell, and if he/she is, then damage galore!

This obviously doesn't make very much sense. I mean, obviously the player won't waste MP targetting random squares, so won't it be better to use the enemy targetting system? Righto-



Target Enemy Spell Effects: Instant-Effect

So, let's make the same thing, except with the more sensible Target Enemy System! We can emulate Seiken Densetsu now! Yay! This is actually much easier to implement than the Target Map effects:

RPG Maker 2000 Code:

<>Setup Event's Place: Animation Event, (V[0007:SpellX],V[0008:SpellY])
<>Show Battle Animation: Bomb, Animation Event(W)

<>Variable Ch:[0003:WatchX] Set, Enemy1 X pos
<>Variable Ch:[0004:WatchY] Set, Enemy1 Y pos

<>FORK Optn:Varbl[0007:SpellX]-0
    <>Show Battle Anim.: Thunder Effect, Enemy1
    <>Damage Enemy: Enemy1
    <>
: END Case

<>Note:Repeat for every enemy on the map.


That's right :). All that we had to do is to detect which enemy SpellX pointed to, and then damage him/her. There's no need for coordinate comparisons! Yay!

Ahem.



Target Map Spell Effects: Delayed-Effect Spells

You are probably thinking, "This is easy. I can just use the regular damage code and add a wait statement to it!" Right?

Well, not exactly. Look closely at your targetting and damage event. Did you notice that they are Auto Start events (if you made them Parallel Process, then you haven't been following directions :P)? Well, that would make the delay pointless, as enemies cannot move during the delay, which defeats the purpose of this spell.

So...as you can probably guess, we need to turn on another PARALLEL PROCESS event, which DOES allow enemies to move while the meteor is landing. So, this would be the effect code:

RPG Maker 2000 Code:

<>Setup Event's Place: Animation Event, (V[0007:SpellX],V[0008:SpellY])
<>Play Sound Effect: Flame4
<>Change Switch: [0055:Target Delay Switch]-ON Set


Not much to explain hee, except that you position the animation event (make sure that it's passible) and turn on a switch, which will trigger the parallel process.

Now, let's add a new page to this event and make it Parallel Process. Have it activate when Target Delay Switch is ON, and put the following code in this page:

RPG Maker 2000 Code:

<>Note: This can be however long you want it to be.
<>Wait 1.0s
<>Show Battle Animation: Bomb, Animation Event

<>Variable Ch:[0003:WatchX] Set, Enemy1 X pos
<>Variable Ch:[0004:WatchY] Set, Enemy1 Y pos
<>FORK Optn:Varbl[0007:SpellX]-V[0003:WatchX] Equivl
    <>FORK Optn:Varbl[0008:SpellY]-V[0004:WatchY] Equivl
        <>Damage Enemy: Enemy1
        <>Play Sound Effect: Damage2
        <>Change Switch:[0003:PrjtStraightON]-OFF Set
        <>
    : END Case
    <>
: END Case
<>Note:Repeat for every enemy on the map.


So...basically, your wait event, and then the animation and the damage. This should be very familiar by now.

You can also add radial damage to the spell to make it more effective and more "useful". To do that, just replace this code with the Radial Damage Code from my ABS Tutorial Part 3 or 4. Alternatively, you can look at the sample project - it contains a sample spell that shows you how to do this.



Target Map Spell Effects: Continuous-Effect Spells

These spells remain on the map long after you cast them, and will continuously damage any enemy that stands on it (kind of like a firewall). The flame will usually disappear after a certain amount of time.

Firewalls are actually quite easy to implement. however, you will need another event (for the actual spell), a switch (to activate the spell), and a variable (to keep track of time).

The effect code for firewalls is very simple:

RPG Maker 2000 Code:

<>Variable Ch:[0006:Temp] Set, 0
<>Play SE: Flame2

<>Setup Event's Place: Cont. Damage Event, (V[0007:SpellX],V[0008:SpellY])
<>Change Switch:[0056:Target Cont. Switch]-ON Set


So, basically, we set the new event that we've created (which I've named Cont. Damage Event) to the tile that we've targetted, and turn ON "the switch." MWAHAHAHAHA.

Sorry.

Anyways, we'll put the actual damage code INSIDE the continuous damage switch. So, double click that event, check the Switch checkbox, and change the condition to "Target Cont. Switch is ON." The event should contain the following code:


RPG Maker 2000 Code:

<>Variable Ch:[0058:Count] +, 1

<>Variable Ch:[0003:WatchX] Set, Enemy1 X pos
<>Variable Ch:[0004:WatchY] Set, Enemy1 Y pos
<>FORK Optn:Varbl[0007:SpellX]-V[0003:WatchX] Equivl
    <>FORK Optn:Varbl[0008:SpellY]-V[0004:WatchY] Equivl
        <>Damage Enemy: Enemy1
        <>Play Sound Effect: Damage2
        <>
    : END Case
    <>
: END Case
<>Note:Repeat for every enemy on the map.

<>Wait: 0.2s.
<>FORK Optn:Varbl[0058:Count]-20abov
    <>Change Switch:[0056:Target Cont. Switch]-OFF Set
    <>
: END Case
<>


What we are basically doing is increasing the "Count" variable by one every time the event runs. After the familiar enemy damage code, we have a wait statement, which makes the event wait 0.2 seconds before trying to damage the enemy again. Also, when the count reaches 20 (20 x 0.2 sec = 4 sec elapsed), the switch will be turned off, and the spell will collapse.

You can also add firewalls to projectiles in the same way. I've included the coding in the demo project if you need it.



Target Enemy Spell Effects: Continuous-Effect Spells

Making these spells target enemy is a bit different. Although the "Cont. Damage Event" code is still the same, we need to make a few modifications to the Spell Effects:

RPG Maker 2000 Code:

<>FORK Optn:Varbl[0007:SpellX]-0
    <>Variable Ch:[0007:SpellX] Set, Enemy1 X pos
    <>Variable Ch:[0008:SpellY] Set, Enemy1 Y pos
    <>
: ELSE Case
    <>FORK Optn:Varbl[0007:SpellX]-1
        <>Variable Ch:[0007:SpellX] Set, Enemy2 X pos
        <>Variable Ch:[0008:SpellY] Set, Enemy2 Y pos
        <>
    : ELSE Case
        <>Note: Repeat for every enemy on the map.
        <>
    :END Case
    <>
:END Case

<>Variable Ch:[0006:Temp] Set, 0
<>Play SE: Flame2

<>Setup Event's Place: Cont. Damage Event, (V[0007:SpellX],V[0008:SpellY])
<>Change Switch:[0056:Target Cont. Switch]-ON Set


As you can see, because continuous spells are coordinate-based, you need to convert enemy numbers to actual map coordinates. So...the first bit of code detects what enemy the cursor is pointing to, and reset SpellX and SpellY to their coordinates.

Make sure to use Nested FORKs if you are using SpellX! Otherwise, you'll have problems if the first enemy is targetted and is on, say, tile (1, 1)!


That's really all for this tutorial. I would highly recommend that you download the sample project and look at its coding, especially if you couldn't understand something. You can even take code from the sample project if you want.

The sample project can be found here: http://staff.whahay.net/AzureFenrir/Tutorial/ABSDemo.zip