Overworld combat attacks?

They wouldn’t need one. The front tile check from my last post does the Attack collision’s job for the enemy. It’s built from This Event and self variables the same way your hit section is, so every copy of the enemy you place carries its own and there’s nothing extra to duplicate.

Here’s the basic attack with it, so you can see where it sits in the page. Until I know what decides when an enemy attacks, this one swings whenever you’re on the tile in front of it and its cooldown is done. SV: Atk Cooldown, SV: Front X, SV: Front Y, SV: Front Dir, SV: Target X and SV: Target Y are new self variables, set up the same way as your others. Parts in parentheses are your existing contents, unchanged:

(your setup branch, unchanged except for the Moveset line below)
(your attack logic, unchanged)
◆If: SV: Atk Cooldown > 0
  ◆Control Variables: #0XXX SV: Atk Cooldown -= 1
◆End
◆If: SV: Atk Cooldown = 0
  ◆Control Variables: #0XXX SV: Front X = Map X of This Event
  ◆Control Variables: #0XXX SV: Front Y = Map Y of This Event
  ◆Control Variables: #0XXX SV: Front Dir = Direction of This Event
  ◆If: SV: Front Dir = 2
    ◆Control Variables: #0XXX SV: Front Y += 1
  ◆End
  ◆If: SV: Front Dir = 4
    ◆Control Variables: #0XXX SV: Front X -= 1
  ◆End
  ◆If: SV: Front Dir = 6
    ◆Control Variables: #0XXX SV: Front X += 1
  ◆End
  ◆If: SV: Front Dir = 8
    ◆Control Variables: #0XXX SV: Front Y -= 1
  ◆End
  ◆Control Variables: #0XXX SV: Target X = Map X of Player
  ◆Control Variables: #0XXX SV: Target Y = Map Y of Player
  ◆If: SV: Front X = SV: Target X
    ◆If: SV: Front Y = SV: Target Y
      (whatever sound or flash you want when the player gets hit)
      ◆Control Variables: #0232 SV: Damage = SV: This Event ATK
      ◆Control Variables: #0232 SV: Damage *= 100
      ◆Control Variables: #0233 SV: Def Calc = Player DEF
      ◆Control Variables: #0233 SV: Def Calc += 100
      ◆Control Variables: #0232 SV: Damage /= SV: Def Calc
      ◆Control Variables: #0XXX Player HP -= SV: Damage
      ◆Control Variables: #0XXX SV: Atk Cooldown = 60
    ◆End
  ◆End
◆End
(your hit section, unchanged)
(your HP 0 check, unchanged)

60 is about a second between swings. Each copy counts its own cooldown, so every enemy on the map keeps its own timing.

Which moves a copy gets can come from your setup the same way its stats do. One more line in each ENEMY FORM branch:

◆If: ENEMY FORM = 3
  ◆Control Variables: #0189 SV: This event HP = 100
  ◆Control Variables: #0XXX SV: This Event ATK = 20
  ◆Control Variables: #0XXX SV: This Event DEF = 20
  ◆Control Variables: #0XXX SV: Moveset = 3
◆End

The speed boost and ram would go right under the basic attack, inside an If: SV: Moveset = 3.

A traveling move like your S blast could skip the event too, by pushing SV: Front X and Y one more tile ahead every few frames and checking the player each time. The only part events can’t do is let you watch it fly. Events can’t create new events during play, so a visible blast would mean placing a hitbox event for each enemy.

What decides when an enemy attacks, and should enemy hits knock the player back?

I think I would like the enemy to attack when the player is within one tile of them, but with a quick pause of like 5 frames before it happens, so the player has a chance to get away if they get too close, if that makes sense.

I do see what you mean about the front tile check-I’m referring to the visual of the Attack Collision moving out of the player and touching the enemy to damage them. Can the enemies have those visuals too?

That works with a windup timer, the same shape as your ActionTimer. When you’re on any of the four tiles next to the enemy and its cooldown is done, it turns to face you, holds still, and counts down 5 frames. When the count hits 0 it swings, and the damage only lands if you’re still next to it. Map X and Y switch to the new tile the moment a step starts, so starting a step away before the count runs out is enough to dodge.

For the visuals, yes, and it doesn’t need one per enemy. A swing is only on screen for a few frames, so every copy can share one event and take turns with it. A switch marks it as in use, and if two enemies swing at the same moment, the second one still does its damage, just without the slide.

Setting up the shared event, once per battle map:

  1. Make a new event called Enemy Swing, anywhere out of the way on the map
  2. Leave its image blank, the route sets it
  3. Options: Through ON. Priority: Above characters, so it draws over the player
  4. Make a new switch called Enemy Swing Busy, and turn it OFF wherever your battle starts in case a swing ever gets cut off by a map transfer

This replaces the basic attack block from my last post, in the same spot. SV: Windup and SV: Distance are new self variables, and Swing X, Swing Y and Swing Dir can be normal variables since they’re only used right there. The Front and Target self variables from last time aren’t needed for this one. Parts in parentheses are your existing contents, unchanged:

(your setup branch, unchanged)
(your attack logic, unchanged)
◆If: SV: Atk Cooldown > 0
  ◆Control Variables: #0XXX SV: Atk Cooldown -= 1
◆End
◆If: SV: Windup > 0
  ◆Control Variables: #0XXX SV: Windup -= 1
  ◆If: SV: Windup = 0
    ◆Control Variables: #0XXX Swing X = Map X of This Event
    ◆Control Variables: #0XXX Swing Y = Map Y of This Event
    ◆Control Variables: #0XXX Swing Dir = Direction of This Event
    ◆If: Enemy Swing Busy is OFF
      ◆Control Switches: #0XXX Enemy Swing Busy = ON
      ◆If: Swing Dir = 2
        ◆Set Event Location: Enemy Swing, ({Swing X},{Swing Y}), Down
      ◆End
      ◆If: Swing Dir = 4
        ◆Set Event Location: Enemy Swing, ({Swing X},{Swing Y}), Left
      ◆End
      ◆If: Swing Dir = 6
        ◆Set Event Location: Enemy Swing, ({Swing X},{Swing Y}), Right
      ◆End
      ◆If: Swing Dir = 8
        ◆Set Event Location: Enemy Swing, ({Swing X},{Swing Y}), Up
      ◆End
      ◆Set Movement Route: Enemy Swing (Skip)
        : Image: (your enemy swing graphic)
        : Speed: 6
        : Transparent OFF
        : 1 Step Forward
        : Wait: 6 frames
        : Transparent ON
        : Switch OFF: #0XXX Enemy Swing Busy
    ◆End
    ◆Control Variables: #0XXX SV: Distance = Math.abs($gamePlayer.x - this.character(0).x) + Math.abs($gamePlayer.y - this.character(0).y)
    ◆If: SV: Distance = 1
      (whatever sound or flash you want when the player gets hit)
      ◆Control Variables: #0232 SV: Damage = SV: This Event ATK
      ◆Control Variables: #0232 SV: Damage *= 100
      ◆Control Variables: #0233 SV: Def Calc = Player DEF
      ◆Control Variables: #0233 SV: Def Calc += 100
      ◆Control Variables: #0232 SV: Damage /= SV: Def Calc
      ◆Control Variables: #0XXX Player HP -= SV: Damage
    ◆End
    ◆Control Variables: #0XXX SV: Atk Cooldown = 60
  ◆End
: Else
  ◆If: SV: Atk Cooldown = 0
    ◆Control Variables: #0XXX SV: Distance = Math.abs($gamePlayer.x - this.character(0).x) + Math.abs($gamePlayer.y - this.character(0).y)
    ◆If: SV: Distance = 1
      ◆Script: this.character(0).turnTowardPlayer();
      ◆Set Movement Route: This Event
        : Wait: 5 frames
      ◆Control Variables: #0XXX SV: Windup = 5
    ◆End
  ◆End
◆End
(your hit section, unchanged)
(your HP 0 check, unchanged)

The turn is a Script line instead of Turn toward Player in the route because a forced route waits for the enemy to finish the step it’s on, the same delay the knockback had. An enemy that just walked up to you could still be mid step, and the route version could leave it swinging the way it was walking.

5 frames is about a twelfth of a second, so if it ends up too quick to dodge, raise the 5 in SV: Windup = 5 and the Wait under it together.

One catch if you have more than one battle map. The enemy’s commands find Enemy Swing by its event ID, so on any map you copy enemies to, Enemy Swing needs that same ID. The ID shows at the top of the event window.

Ok, I’m following so far.

There’s only one battle map that this all takes place on, and the only transfers that take place are when the player enters and leaves.

I’m hesitant about the idea that there can only be one Enemy Swing onscreen at a time. The nature of the maps means that the player is often surrounded by quite a few enemies at once. Is there anything that can be done about this, with a plugin perhaps?

If this is getting a bit too murky without the visual element, I can give you my discord and screenshare the complete process in action so far.

Yes, and it doesn’t need a plugin. Since there’s only the one battle map, you can place four Enemy Swing events and have each swing grab whichever one is free. An enemy only swings from one of the four tiles touching you, so four covers being boxed in on every side. If a fifth ever overlaps while all four are busy, it still does its damage, just without the slide.

The picking goes in one common event, so the enemy page stays short and every copy shares it.

  1. Rename Enemy Swing to Enemy Swing 1, then copy and paste it three times and name those Enemy Swing 2, 3 and 4
  2. Rename the Enemy Swing Busy switch to Enemy Swing 1 Busy and make Enemy Swing 2 Busy, 3 Busy and 4 Busy. All four go OFF where the battle starts
  3. Database > Common Events, make a new one called ENEMY SWING with Trigger: None, and put this in it:
◆If: Enemy Swing 1 Busy is OFF
  ◆Control Switches: #0XXX Enemy Swing 1 Busy = ON
  ◆If: Swing Dir = 2
    ◆Set Event Location: Enemy Swing 1, ({Swing X},{Swing Y}), Down
  ◆End
  ◆If: Swing Dir = 4
    ◆Set Event Location: Enemy Swing 1, ({Swing X},{Swing Y}), Left
  ◆End
  ◆If: Swing Dir = 6
    ◆Set Event Location: Enemy Swing 1, ({Swing X},{Swing Y}), Right
  ◆End
  ◆If: Swing Dir = 8
    ◆Set Event Location: Enemy Swing 1, ({Swing X},{Swing Y}), Up
  ◆End
  ◆Set Movement Route: Enemy Swing 1 (Skip)
    : Image: (your enemy swing graphic)
    : Speed: 6
    : Transparent OFF
    : 1 Step Forward
    : Wait: 6 frames
    : Transparent ON
    : Switch OFF: #0XXX Enemy Swing 1 Busy
  ◆Exit Event Processing
◆End
◆If: Enemy Swing 2 Busy is OFF
  ◆Control Switches: #0XXX Enemy Swing 2 Busy = ON
  ◆If: Swing Dir = 2
    ◆Set Event Location: Enemy Swing 2, ({Swing X},{Swing Y}), Down
  ◆End
  ◆If: Swing Dir = 4
    ◆Set Event Location: Enemy Swing 2, ({Swing X},{Swing Y}), Left
  ◆End
  ◆If: Swing Dir = 6
    ◆Set Event Location: Enemy Swing 2, ({Swing X},{Swing Y}), Right
  ◆End
  ◆If: Swing Dir = 8
    ◆Set Event Location: Enemy Swing 2, ({Swing X},{Swing Y}), Up
  ◆End
  ◆Set Movement Route: Enemy Swing 2 (Skip)
    : Image: (your enemy swing graphic)
    : Speed: 6
    : Transparent OFF
    : 1 Step Forward
    : Wait: 6 frames
    : Transparent ON
    : Switch OFF: #0XXX Enemy Swing 2 Busy
  ◆Exit Event Processing
◆End
◆If: Enemy Swing 3 Busy is OFF
  ◆Control Switches: #0XXX Enemy Swing 3 Busy = ON
  ◆If: Swing Dir = 2
    ◆Set Event Location: Enemy Swing 3, ({Swing X},{Swing Y}), Down
  ◆End
  ◆If: Swing Dir = 4
    ◆Set Event Location: Enemy Swing 3, ({Swing X},{Swing Y}), Left
  ◆End
  ◆If: Swing Dir = 6
    ◆Set Event Location: Enemy Swing 3, ({Swing X},{Swing Y}), Right
  ◆End
  ◆If: Swing Dir = 8
    ◆Set Event Location: Enemy Swing 3, ({Swing X},{Swing Y}), Up
  ◆End
  ◆Set Movement Route: Enemy Swing 3 (Skip)
    : Image: (your enemy swing graphic)
    : Speed: 6
    : Transparent OFF
    : 1 Step Forward
    : Wait: 6 frames
    : Transparent ON
    : Switch OFF: #0XXX Enemy Swing 3 Busy
  ◆Exit Event Processing
◆End
◆If: Enemy Swing 4 Busy is OFF
  ◆Control Switches: #0XXX Enemy Swing 4 Busy = ON
  ◆If: Swing Dir = 2
    ◆Set Event Location: Enemy Swing 4, ({Swing X},{Swing Y}), Down
  ◆End
  ◆If: Swing Dir = 4
    ◆Set Event Location: Enemy Swing 4, ({Swing X},{Swing Y}), Left
  ◆End
  ◆If: Swing Dir = 6
    ◆Set Event Location: Enemy Swing 4, ({Swing X},{Swing Y}), Right
  ◆End
  ◆If: Swing Dir = 8
    ◆Set Event Location: Enemy Swing 4, ({Swing X},{Swing Y}), Up
  ◆End
  ◆Set Movement Route: Enemy Swing 4 (Skip)
    : Image: (your enemy swing graphic)
    : Speed: 6
    : Transparent OFF
    : 1 Step Forward
    : Wait: 6 frames
    : Transparent ON
    : Switch OFF: #0XXX Enemy Swing 4 Busy
  ◆Exit Event Processing
◆End

Exit Event Processing only ends the common event, not the enemy that called it, so it just stops the slots after it from also firing.

In the enemy, the If: Enemy Swing Busy is OFF block comes out of the swing and the Common Event line goes in its place. Here’s the swing with that change. Parts in parentheses are unchanged:

◆If: SV: Windup > 0
  ◆Control Variables: #0XXX SV: Windup -= 1
  ◆If: SV: Windup = 0
    ◆Control Variables: #0XXX Swing X = Map X of This Event
    ◆Control Variables: #0XXX Swing Y = Map Y of This Event
    ◆Control Variables: #0XXX Swing Dir = Direction of This Event
    ◆Common Event: ENEMY SWING
    ◆Control Variables: #0XXX SV: Distance = Math.abs($gamePlayer.x - this.character(0).x) + Math.abs($gamePlayer.y - this.character(0).y)
    ◆If: SV: Distance = 1
      (your hit on the player, unchanged)
    ◆End
    ◆Control Variables: #0XXX SV: Atk Cooldown = 60
  ◆End
: Else
  (your windup start, unchanged)
◆End

On the plugin side, Galv’s Event Spawner MZ can copy an event onto the map during play, so there’d be no cap at all. I’d try the four first though, since it works with what you’ve already got.

I might actually grab that plugin, if it’s well-suited for this sort of thing. I’d rather not depend on four for the whole development time; I don’t know what new moves or battle styles may or may not end up going in down the line, and I’d rather remove the Swing limit early rather than have to go back and fix the enemies to add more Swings. I’ll go see about downloading it right now. Do you know enough about that plugin to advise on how it would work?

It should fit well enough. It copies events from a map you set aside for templates onto the current map during play, and a copy can delete itself when it’s done. So every swing makes its own Enemy Swing, slides it, and removes it, with no cap on how many are out at once.

Setting it up:

  1. Make a new map just for templates, something like SPAWN. The player never goes there, it only holds events to copy
  2. In the Plugin Manager, set Galv’s Spawn Map Id to that map’s ID. The game throws an error on startup until this is set
  3. On the SPAWN map, make an event called Enemy Swing as the first event, so it’s ID 1
  4. Image: your swing graphic. Options: Through ON, Direction Fix OFF. Priority: Above characters. Trigger: Parallel. Then these commands:
◆Set Movement Route: This Event (Skip, Wait)
  : Speed: 6
  : 1 Step Forward
  : Wait: 6 frames
◆Script: Galv.SPAWN.unspawn(this);

The Script line is what deletes the copy, so it needs to stay last.

Your enemy already calls ENEMY SWING, so the enemy itself doesn’t change. Delete everything inside the common event and put one Script command in its place, with all three of these lines in the same box:

◆Script: const e = this.character(0);
         Galv.SPAWN.event(1, 'xy', [e.x, e.y], 'all', false);
         $gameMap.event($gameMap._lastSpawnEventId).setDirection(e.direction());

Inside a common event, this.character(0) is whichever enemy called it. So the copy spawns on that enemy’s tile, facing the same way, and its 1 Step Forward goes the way the enemy is swinging. The 1 is the template’s event ID on the SPAWN map, ‘all’ lets it spawn on a tile the enemy is already standing on, and false keeps the copies temporary so none of them get saved with the map.

The four Enemy Swing events, the four Busy switches and the lines that turn them OFF at battle start can all go. The Swing X, Swing Y and Swing Dir lines in the enemy aren’t used anymore either, so those can come out whenever.

Alright, I think everything is set up for that!

Just to be certain that I don’t mess anything up, would it be too much to ask for the complete code block with all of the changes so far?

Here’s the whole enemy page top to bottom with everything from this thread in it. Parts in parentheses are things I haven’t seen or that haven’t changed since you got them working, so leave those as they are. Anywhere it says (your number), keep the stats you already have.

◆If: Self Switch (your setup switch) is OFF
  (your appearance setup, unchanged)
  ◆If: ENEMY FORM = 1
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 2
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 3
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 4
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 5
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 6
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 7
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 8
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 9
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 10
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 11
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 12
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 13
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆If: ENEMY FORM = 14
    ◆Control Variables: #0189 SV: This event HP = (your number)
    ◆Control Variables: #0XXX SV: This Event ATK = (your number)
    ◆Control Variables: #0XXX SV: This Event DEF = (your number)
  ◆End
  ◆Control Self Switch: (your setup switch) = ON
◆End
(your attack logic, unchanged)
◆If: SV: Atk Cooldown > 0
  ◆Control Variables: #0XXX SV: Atk Cooldown -= 1
◆End
◆If: SV: Windup > 0
  ◆Control Variables: #0XXX SV: Windup -= 1
  ◆If: SV: Windup = 0
    ◆Common Event: ENEMY SWING
    ◆Control Variables: #0XXX SV: Distance = Math.abs($gamePlayer.x - this.character(0).x) + Math.abs($gamePlayer.y - this.character(0).y)
    ◆If: SV: Distance = 1
      (whatever sound or flash you want when the player gets hit)
      ◆Control Variables: #0232 SV: Damage = SV: This Event ATK
      ◆Control Variables: #0232 SV: Damage *= 100
      ◆Control Variables: #0233 SV: Def Calc = Player DEF
      ◆Control Variables: #0233 SV: Def Calc += 100
      ◆Control Variables: #0232 SV: Damage /= SV: Def Calc
      ◆Control Variables: #0XXX Player HP -= SV: Damage
    ◆End
    ◆Control Variables: #0XXX SV: Atk Cooldown = 60
  ◆End
: Else
  ◆If: SV: Atk Cooldown = 0
    ◆Control Variables: #0XXX SV: Distance = Math.abs($gamePlayer.x - this.character(0).x) + Math.abs($gamePlayer.y - this.character(0).y)
    ◆If: SV: Distance = 1
      ◆Script: this.character(0).turnTowardPlayer();
      ◆Set Movement Route: This Event
        : Wait: 5 frames
      ◆Control Variables: #0XXX SV: Windup = 5
    ◆End
  ◆End
◆End
◆If: ATTACKING is ON
  ◆If: Self Switch B is OFF
    ◆Control Variables: #0192 SV: AtkCol X = Map X of Attack collision
    ◆Control Variables: #0193 SV: AtkCol Y = Map Y of Attack collision
    ◆If: ATTACK TYPE = 2
      ◆Control Variables: #0192 SV: AtkCol X = Map X of Player
      ◆Control Variables: #0193 SV: AtkCol Y = Map Y of Player
      ◆Control Variables: #0221 Hit Dir = Direction of Player
      ◆If: Hit Dir = 2
        ◆Control Variables: #0193 SV: AtkCol Y += 1
      ◆End
      ◆If: Hit Dir = 4
        ◆Control Variables: #0192 SV: AtkCol X -= 1
      ◆End
      ◆If: Hit Dir = 6
        ◆Control Variables: #0192 SV: AtkCol X += 1
      ◆End
      ◆If: Hit Dir = 8
        ◆Control Variables: #0193 SV: AtkCol Y -= 1
      ◆End
    ◆End
    ◆Control Variables: #0194 SV: My X = Map X of This Event
    ◆Control Variables: #0195 SV: My Y = Map Y of This Event
    ◆Control Variables: #0232 SV: Damage = Player ATK
    ◆Control Variables: #0232 SV: Damage *= Move Power
    ◆Control Variables: #0233 SV: Def Calc = SV: This Event DEF
    ◆Control Variables: #0233 SV: Def Calc += 100
    ◆Control Variables: #0232 SV: Damage /= SV: Def Calc
    ◆If: ATTACK TYPE = 4
      ◆Control Variables: #0189 SV: This event HP -= SV: Damage
      ◆Play SE: Blow1 (90, 150, 0)
      ◆Set Movement Route: This Event
        : Blend Mode: Additive
        : Wait: 30 frames
        : Blend Mode: Normal
      ◆Control Self Switch: B = ON
    ◆End
    ◆If: SV: AtkCol X = SV: My X
      ◆If: SV: AtkCol Y = SV: My Y
        ◆If: ATTACK TYPE = 0
          ◆Common Event: DAMAGE SFX
          ◆Common Event: SCREENSHAKE SMALL
          ◆Control Variables: #0189 SV: This event HP -= SV: Damage
          ◆Control Variables: #0194 SV: My X = Math.round(this.character(0)._realX)
          ◆Control Variables: #0195 SV: My Y = Math.round(this.character(0)._realY)
          ◆Set Event Location: This Event, ({SV: My X},{SV: My Y})
          ◆Set Movement Route: This Event (Skip, Wait)
            : Speed: 6
            : Turn toward Player
            : 1 Step Backward
            : 1 Step Backward
            : Speed: 4
        ◆End
        ◆If: ATTACK TYPE = 1
          ◆Control Variables: #0194 SV: My X = Math.round(this.character(0)._realX)
          ◆Control Variables: #0195 SV: My Y = Math.round(this.character(0)._realY)
          ◆Set Event Location: This Event, ({SV: My X},{SV: My Y})
          ◆Set Movement Route: This Event (Skip, Wait)
            : Blend Mode: Normal
            : Speed: 5
            : Turn toward Player
            : SE: Blow5 (80, 100, 0)
            : 1 Step Backward
            : Speed: 4
            : Wait: 5 frames
            : Blend Mode: Normal
        ◆End
        ◆If: ATTACK TYPE = 2
          ◆Control Variables: #0189 SV: This event HP -= SV: Damage
          ◆Control Variables: #0194 SV: My X = Math.round(this.character(0)._realX)
          ◆Control Variables: #0195 SV: My Y = Math.round(this.character(0)._realY)
          ◆Set Event Location: This Event, ({SV: My X},{SV: My Y})
          ◆Set Movement Route: This Event (Skip, Wait)
            (your ram knockback route, unchanged)
        ◆End
        ◆If: ATTACK TYPE = 3
          ◆Common Event: DAMAGE SFX
          ◆Control Variables: #0189 SV: This event HP -= SV: Damage
          ◆Set Movement Route: This Event (Wait)
            : Blend Mode: Additive
            : Wait: 30 frames
            : Blend Mode: Normal
        ◆End
        ◆If: ATTACK TYPE = 5
          ◆Common Event: DAMAGE SFX
          ◆Control Variables: #0189 SV: This event HP -= SV: Damage
          ◆Set Movement Route: This Event
            : Blend Mode: Additive
            : Wait: 30 frames
            : Blend Mode: Normal
        ◆End
        ◆If: ATTACK TYPE ≠ 1
          ◆If: ATTACK TYPE ≠ 3
            ◆Control Self Switch: B = ON
          ◆End
        ◆End
      ◆End
    ◆End
  ◆End
: Else
  ◆Control Self Switch: B = OFF
◆End
(your HP 0 check, unchanged)

The ENEMY SWING common event and the Enemy Swing template on the SPAWN map, for reference:

ENEMY SWING (Common Event, Trigger: None)
◆Script: const e = this.character(0);
         Galv.SPAWN.event(1, 'xy', [e.x, e.y], 'all', false);
         $gameMap.event($gameMap._lastSpawnEventId).setDirection(e.direction());

Enemy Swing (SPAWN map, event 1, Parallel, Through ON, Direction Fix OFF, Above characters)
◆Set Movement Route: This Event (Skip, Wait)
  : Speed: 6
  : 1 Step Forward
  : Wait: 6 frames
◆Script: Galv.SPAWN.unspawn(this);

If you shortened the type 3 flash when you sped up its hits, keep your number there instead of 30.

If any Loop Test or Hit Test lines from the freeze hunt are still in the page, they can come out, along with the Swing X, Swing Y and Swing Dir lines if those are still there.

The SV: Moveset line from earlier isn’t in here since nothing reads it yet. It’ll come back when the enemies get more than the basic attack.

Ok, I’ll get on implementing that then.

Just to make sure I’ve gotten what I’m after across correctly, I’ll recap it in detail one more time;

This tweaked event will allow an enemy to utilize the Basic, Special A, and Special S actions of whatever Form they would grant the player? Like, if an enemy grants the Speed Form when it is on your side, that means the enemy will be able to use the Speed actions (the speed increase and the Ram) when they are not on your side?

Not yet. The page as it stands gives every enemy the basic attack, which is the windup, the swing and the damage on you. That piece is the same no matter which form an enemy grants, so every enemy shares it. The Speed form’s boost and ram aren’t in there yet.

Those get added under the basic attack, one block per form, and SV: Moveset is what decides which block an enemy runs. It comes back as one line in each ENEMY FORM setup branch, set to the form that enemy grants, so an enemy that grants the Speed form gets SV: Moveset = 3. One that doesn’t grant a form gets 0 and only ever uses the basic attack. The page would end up shaped like this:

(your basic attack, unchanged)
◆If: SV: Moveset = 3
  (Speed form boost)
  (Speed form ram)
◆End
◆If: SV: Moveset = (the next form)
  (that form's A and S moves)
◆End
(your hit section, unchanged)

Each move still gets written from the enemy’s side like the basic swing was, since the player versions run on ATTACKING and the Attack collision.

Before I write the Speed ones, when should an enemy use its A or S move instead of walking up and swinging? What I’d probably do is boost when you’re within a few tiles and the boost’s cooldown is done, and ram when you’re lined up with it in the same row or column within 4 tiles. And should the ram knock you back or just do damage? A push on the player would need its own Autorun like RECOIL.

Ok, I think I’m getting it.

And I think the enemy should randomly decide to use their special moves if
-they’re under Half HP
-the Cooldown for either move isn’t still running
-they roll a random number and it decides between Basic and Special 1 or 2
-they are twice as likely to select special 2 (the attack) rather than special 1 (the stat boost)

I also think that enemies shouldn’t get access to the screen-wide attack discussed earlier because it would be irritating to deal with for the player. They should all get the generic attack for Basic.

I’m gonna go and thoroughly test the player’s moves before I continue, I don’t wanna find out there’s a bug that I have to go and fix in the enemy later. I’ll report any issues back to you.

Real quick, how would I go about raising a stat by a percentage? Like if the variable for Attack is 75, how could I raise it by 50%? It’s impossible to split 75 in half after all, and even so, in case stats change later, I’d rather not say “subtract 37”

For the percentage, multiply first and divide last, the same trick as the damage formula:

◆Control Variables: #0XXX Player ATK *= 150
◆Control Variables: #0XXX Player ATK /= 100

150 is the 100 you already have plus the 50 you’re adding, so 25% up would be 125 and 50% down would be 50. Control Variables rounds down, so 75 comes out as 112.

If it’s a boost that wears off, I’d save the original before raising it and copy it back after, rather than dividing back down. The rounding means 112 divided back down comes out as 74 instead of 75:

◆Control Variables: #0XXX Player ATK Base = Player ATK
◆Control Variables: #0XXX Player ATK *= 150
◆Control Variables: #0XXX Player ATK /= 100

When it wears off:

◆Control Variables: #0XXX Player ATK = Player ATK Base

The enemy’s boost works the same way with SV: This Event ATK and a self variable for the base.

Sounds good on the specials, and all of that works with Control Variables set to Random. One thing to decide while you’re testing is how often the roll should land on a special at all compared to the basic attack, like 1 in 3 or 1 in 4.

I’ve been testing the moves thoroughly as I said, and every single issue I found I wrote down here, I thought it would be quicker than going point by point. Feel free to take your time, lol.

1-Form 7’s S Attack can be cut off midway by doing it’s Z attack or shield. Then the player freezes, and won’t unfreeze until arrow buttons are pressed. That S Attack blasts the Attack Collision out in front of the player, and it remains in place for a few seconds before despawning. At the same time, the player hops in place quickly-this is what is advanced by pressing arrow buttons.

1.5-A similar issue is that Form 2’s S attack can be cut off midway by doing it’s Z attack or shield. In this case the player is SUPPOSED to be frozen in place for a few seconds until the Attack Collision fades, but performing another action allows them to move immediately.

2-Sometimes, enemies pause in place for a moment (I think after the first tile) while being knocked back by Form 4’s S Attack, instead of being smoothly taken back with it. That S Attack blasts the Attack Collision across the whole map with Through On, knocking enemies in its path back with it.

3-Sometimes there was a moment’s pause before any knockback with the Form 3 Ram. This was inconsistent. Maybe it’s caused by tile shenanigans with other enemies “blocking the tiles?”

4-Form 1 and 2’s S attack do damage before the Attack Collision even appears. They are attack type 5. Both of those S Attacks blast the Attack Collision out in front of the player a little bit, after a quick charge up. (A hop for 1, and a step back for 2)

5-Form 6’s S Attack disappeared too quickly upon hitting enemies-then if I remember correctly, I changed its priority to be above other characters, and now it doesn’t hit them at all, it just avoids them. That S Attack spawns the Attack Collision and has it randomly move around the map on its own for a while.

6-Form 8’s S Attack only does damage one time per enemy, and then the enemies aren’t hurt by it even if they walk back over it, until it is placed down again. That S Attack places the Attack Collision down in place as a trap for enemies to walk over.

7-Form 6’s unique Basic only hits the enemy once. Does it need to turn off Attacking in between swings for it to register each time? That form’s Basic Attack does 3 blasts instead of 1 per Z pressed.

8-I moved the Form 8 basic attack (the screen-wide attack) back to the Parallel Process attack handler since having it in the Autorun handler made all enemies and the player freeze until it was done. But that’s brought back the issue of “if the player presses Z twice then the attack will hang until they press an arrow key.” Is there a middle ground?

9-If you use the shield and an enemy is standing right in front of you, they might get stuck inside the shield.

10-The player has to wait for the Basic attack to move all the way and turn transparent again before using it again, and cannot mash Z. I want the player to be able to mash Z for all but forms 4, 6, 8.

11-Sometimes, enemies will fly off to the side of the player, I think this is caused by them walking into the side of Attack Collision while it’s moving.

1 and 1.5. Your parallel keeps reading Z and X while an S attack runs in its handler, so nothing stops them from starting on top of it. I’d wrap the shield, the S trigger, and the Form 4, 6 and 8 basics in a check on both switches, so none of them can start while anything else is running:

◆If: MOVEMENT ATTACK is OFF
  ◆If: ATTACKING is OFF
    (your shield, unchanged)
  ◆End
◆End

Same two checks around each of the others. That relies on every S attack turning MOVEMENT ATTACK OFF as its very last line, after everything it waits on, so the Form 2 freeze holds until the fade is done. The normal punch gets its own version in 10 so it can still be mashed.

2 and 3. I’m wondering if these are the same thing. The enemy page runs top to bottom, so if an enemy is partway through a Wait in your attack logic when a hit arrives, the hit check further down doesn’t run until that finishes, and the knockback starts late. That would explain it being inconsistent, since it depends on what each enemy happened to be doing. Is there a Wait command, or a Set Movement Route on This Event with Wait ticked, anywhere in the attack logic at the top of the page? A screenshot of that part would help, it’s the one piece of the page I haven’t seen.

On the blocking idea, the knockback routes have Skip If Cannot Move on, so another enemy in the way makes it stop short rather than wait. For 2 I’d also check that Form 4’s branch in the enemy has the two snap lines and the Set Event Location above its route like the punch does. Without them, a hit that lands mid step waits for that step to finish first, which is the same pause the punch had before the snap went in.

  1. If ATTACKING goes ON and the collision gets placed before the charge up, it’s live but invisible while the hop or step back plays, so an enemy on that tile takes the hit before the blast shows. I’d move both down to right above the blast route, so the collision just follows you during the charge up:
◆Control Variables: #0197 ATTACK TYPE = 5
(your Move Power line, unchanged)
(your charge up, unchanged)
◆Control Variables: AtkX = Map X of Player
◆Control Variables: AtkY = Map Y of Player
◆Control Variables: AtkDir = Direction of Player
(your four AtkDir branches, unchanged)
◆Control Switches: #0181 ATTACKING = ON
◆Set Movement Route: Attack collision (Skip, Wait)
  (your blast route, unchanged)
◆Control Switches: #0181 ATTACKING = OFF
◆Control Switches: #0182 MOVEMENT ATTACK = OFF

If the charge up is RecoilGo turning ON, the parallel doesn’t wait for it on its own, so a Wait for however long the hop or step takes goes right after it. If the order already looks like this, a screenshot of Form 1’s S block would help.

  1. Is Through still ticked on whatever’s doing the wandering? An event without Through gets blocked by every other event no matter its priority. Priority only changes whether it bumps into the player. So Move at Random keeps picking directions that aren’t blocked, which would look like it’s avoiding them. Also, is it the real Attack collision wandering or a copy from the spawner? The enemies only check the real one, so a copy would never hit anything.
  2. Enemies only re arm when ATTACKING goes OFF, and the trap holds it ON the whole time it’s down, so each one gets hit once. What I’d do is number the hits. A Hit Count variable goes up whenever an attack wants to hit again, and each enemy remembers the last number it got hit by in SV: Last Hit. ATTACKING going OFF still re arms everything like before, so the attacks that already work don’t change.

For the trap, the new block at the top re arms an enemy whenever it’s off the trap’s tile, so walking back on hits again. It needs the trap to have its own ATTACK TYPE number, so if it’s sharing one with another attack, give it a new one and copy that attack’s branch for it.

This is the whole hit section with Hit Count in, plus the knockback change for 11. SV: Last Hit is a new self variable, Hit Count is a normal one, and Self Switch B isn’t used anymore, so that letter’s free again. Parts in parentheses are unchanged:

◆If: ATTACKING is ON
  ◆If: ATTACK TYPE = (your trap's type)
    ◆Control Variables: #0192 SV: AtkCol X = Map X of Attack collision
    ◆Control Variables: #0193 SV: AtkCol Y = Map Y of Attack collision
    ◆Control Variables: #0194 SV: My X = Map X of This Event
    ◆Control Variables: #0195 SV: My Y = Map Y of This Event
    ◆If: SV: AtkCol X ≠ SV: My X
      ◆Control Variables: #0XXX SV: Last Hit = -1
    ◆End
    ◆If: SV: AtkCol Y ≠ SV: My Y
      ◆Control Variables: #0XXX SV: Last Hit = -1
    ◆End
  ◆End
  ◆If: SV: Last Hit ≠ Hit Count
    ◆Control Variables: #0192 SV: AtkCol X = Map X of Attack collision
    ◆Control Variables: #0193 SV: AtkCol Y = Map Y of Attack collision
    (your ATTACK TYPE = 2 position block, unchanged)
    ◆Control Variables: #0194 SV: My X = Map X of This Event
    ◆Control Variables: #0195 SV: My Y = Map Y of This Event
    (your five damage lines, unchanged)
    ◆If: ATTACK TYPE = 4
      ◆Control Variables: #0189 SV: This event HP -= SV: Damage
      ◆Play SE: Blow1 (90, 150, 0)
      ◆Set Movement Route: This Event
        : Blend Mode: Additive
        : Wait: 30 frames
        : Blend Mode: Normal
      ◆Control Variables: #0XXX SV: Last Hit = Hit Count
    ◆End
    ◆If: SV: AtkCol X = SV: My X
      ◆If: SV: AtkCol Y = SV: My Y
        ◆If: ATTACK TYPE = 0
          ◆Common Event: DAMAGE SFX
          ◆Common Event: SCREENSHAKE SMALL
          ◆Control Variables: #0189 SV: This event HP -= SV: Damage
          ◆Control Variables: #0194 SV: My X = Math.round(this.character(0)._realX)
          ◆Control Variables: #0195 SV: My Y = Math.round(this.character(0)._realY)
          ◆Set Event Location: This Event, ({SV: My X},{SV: My Y})
          ◆Script: this.character(0).setDirection(10 - $gameMap.event(XX).direction());
          ◆Set Movement Route: This Event (Skip, Wait)
            : Speed: 6
            : 1 Step Backward
            : 1 Step Backward
            : Speed: 4
        ◆End
        ◆If: ATTACK TYPE = 1
          ◆Control Variables: #0194 SV: My X = Math.round(this.character(0)._realX)
          ◆Control Variables: #0195 SV: My Y = Math.round(this.character(0)._realY)
          ◆Set Event Location: This Event, ({SV: My X},{SV: My Y})
          ◆Script: this.character(0).setDirection(10 - $gameMap.event(XX).direction());
          ◆Set Movement Route: This Event (Skip, Wait)
            : Blend Mode: Normal
            : Speed: 5
            : SE: Blow5 (80, 100, 0)
            : 1 Step Backward
            : Speed: 4
            : Wait: 5 frames
            : Blend Mode: Normal
        ◆End
        (your ATTACK TYPE = 2 branch, unchanged)
        (your ATTACK TYPE = 3 branch, unchanged)
        (your ATTACK TYPE = 5 branch, unchanged)
        (your trap's branch, unchanged)
        ◆If: ATTACK TYPE ≠ 1
          ◆If: ATTACK TYPE ≠ 3
            ◆Control Variables: #0XXX SV: Last Hit = Hit Count
          ◆End
        ◆End
      ◆End
    ◆End
  ◆End
: Else
  ◆Control Variables: #0XXX SV: Last Hit = -1
◆End
  1. No, with Hit Count in, the triple blast just needs one line between blasts:
(blast 1, unchanged)
◆Control Variables: #0XXX Hit Count += 1
(blast 2, unchanged)
◆Control Variables: #0XXX Hit Count += 1
(blast 3, unchanged)

Turning ATTACKING off in between would re arm the enemies too, but the collision’s follow logic would grab it for that frame.

  1. Form 8’s basic goes inside the same two checks from 1, so a second press while it’s running gets ignored. If it still hangs after that, I’m wondering if there’s a Set Movement Route on the Player with Wait ticked inside it. TurnInPlace only lets Player routes from a parallel move along while an arrow is held, which would match it clearing when you press one. If that route is just there as a pause, a plain Wait command does the same job without touching the Player.
  2. Is there something behind the enemy when it gets stuck, like a wall or another enemy? The bounce has Skip If Cannot Move on, so with no room it stays on the shield tile, and since the shield checks again every pass, it keeps getting bounced in place. What would you want to happen when there’s no room behind it? Take damage, slide to the side, or just stay pinned until the shield drops?
  3. The punch route has Wait on, so the parallel sits there until the swing is done and never sees the next press. Taking the Wait off and handing ATTACKING OFF to a timer, the same shape as your ActionTimer, frees it up. Each press also bumps Hit Count, so every swing can land. This goes at the top of the parallel with your other timers:
◆If: Punch Timer > 0
  ◆Control Variables: #0XXX Punch Timer -= 1
  ◆If: Punch Timer = 0
    ◆Control Switches: #0181 ATTACKING = OFF
  ◆End
◆End

And the punch, inside whatever form check it sits in now:

◆If: MOVEMENT ATTACK is OFF
  ◆If: Script: Input.isTriggered("ok") && (!$gameSwitches.value(181) || $gameVariables.value(XXX) > 0)
    ◆Control Switches: #0181 ATTACKING = ON
    ◆Control Variables: #0197 ATTACK TYPE = 0
    (your Move Power line, unchanged)
    ◆Control Variables: #0XXX Hit Count += 1
    ◆Play SE: Blow1
    ◆Control Variables: AtkX = Map X of Player
    ◆Control Variables: AtkY = Map Y of Player
    ◆Control Variables: AtkDir = Direction of Player
    ◆If: AtkDir = 2
      ◆Set Event Location: Attack collision, ({AtkX},{AtkY}), Down
    ◆End
    ◆If: AtkDir = 4
      ◆Set Event Location: Attack collision, ({AtkX},{AtkY}), Left
    ◆End
    ◆If: AtkDir = 6
      ◆Set Event Location: Attack collision, ({AtkX},{AtkY}), Right
    ◆End
    ◆If: AtkDir = 8
      ◆Set Event Location: Attack collision, ({AtkX},{AtkY}), Up
    ◆End
    ◆Set Movement Route: Attack collision (Skip)
      (your punch route, unchanged)
    ◆Control Variables: #0XXX Punch Timer = 15
  ◆End
◆End

The Script reads as Z pressed, and either nothing is running or the only thing running is a punch. XXX in it is Punch Timer’s variable ID. 15 is a guess at how long your punch route takes. It needs to be a little longer than the route so the Transparent ON at the end runs before ATTACKING turns OFF, so raise it if the collision ever stays visible after a punch. If Transparent ON is in a separate route after the punch right now, move it to the end of this one.

  1. I think it’s the Turn toward Player in the knockback. It picks up or down whenever the enemy is as far above or below you as it is left or right, so on a left or right swing, an enemy that walks into the side of the collision can get pushed up or down instead. The hit section in 6 swaps it in the punch and shield branches for a Script line that turns the enemy to face back along the hit, so Step Backward carries it the way the collision was moving. 10 minus a direction is its opposite, and XX is the Attack collision’s event ID.

1/1.5-. I put Forms 1, 2, 3, and 7 in their own switch called PREVENTER that’s turned on upon pressing S, and turned off upon the Movement Attack Handler turning itself off. They work now!

2/3-. The enemy attack logic isn’t in the enemies yet, I wanted to finish testing the attacks first (that’s what this is).
Form 4’s S Attack is very long range, but I can put a brief pause before the blast to allow any other attack’s damage events to finish, if that would help. The thing is, the Form 4 S Attack was hitting enemies that hadn’t just been hit.
Form 4’s branch in the enemy corresponds to Attack Type 5. It does have the (math round this character to My X and Y) lines and (set event location to My X and Y) line.

4-. From what I can see, the collision is not placed in front of the player before the charge up, it’s blasted out in front of them like Basic.

5-. Won’t turning Through on for the Attack Collision’s wandering mean it will go out of bounds just as likely as it will stay within the map’s accessible areas? It is also the original Attack Collision; the enemies’ one isn’t functional yet, since I wanted to make sure all attacks worked perfectly before applying them to enemies.

6 and 7-. An important thing I’d like to clarify first is, does the Trap need a new Attack Type for this? At the moment it’s Attack Type 3 which is defined already, but if I should duplicate it and make an Attack Type 6 for this, that’s ok.

8-There was one of those, the player just waited for one frame. Not sure why that’s there, but I just replaced it with a regular Wait and now it functions as I intended!

9-That is indeed the issue. Maybe it’s fine as it is, then. It incentivizes not getting cornered.

10-. It didn’t work. Here’s all of the code, because I don’t know what would have gone wrong.

11-. I don’t know what is being said here sorry. Are you saying that once point 6 is resolved, this will resolve itself?

Nice work on PREVENTER, and glad 8 is sorted. Fair call on 9 too.

2 and 3. With no attack logic in the enemies yet, that rules out what I was thinking, so I’d like to see the two branches these land in. The type 5 branch has changed since my copy, so a screenshot of that whole branch would help. For the ram, I’d like the knockback route inside the type 2 branch, since that’s the one part of it I’ve never seen. I wouldn’t add the pause before Form 4’s blast yet.

  1. That rules out my guess there too. A screenshot of Form 1’s S block, from the S press down to MOVEMENT ATTACK OFF, would let me see where early damage could be coming from.
  2. Right, Through ignores walls too. It can’t leave the edge of the map, but it’ll cross anything inside it. What I’d do is keep Through off just for the wander, so walls stop it. Since it can’t step onto an enemy’s tile that way, the enemies would check for it on the tiles next to them instead. That needs its own ATTACK TYPE, so I’ve used 7. In the wander block, ATTACK TYPE = 0 becomes 7, and the route gets Through OFF first and Through ON last:
◆Control Variables: #0197 ATTACK TYPE = 7
(the rest of the block, unchanged down to the route)
◆Set Movement Route: Attack collision (Wait)
  : Through OFF
  (your wander route, unchanged)
  : Through ON

Then in the enemy, inside the If: SV: Last Hit ≠ Hit Count, next to the ATTACK TYPE = 4 block:

◆If: ATTACK TYPE = 7
  ◆Control Variables: #0XXX SV: Distance = Math.abs($gameMap.event(XX).x - this.character(0).x) + Math.abs($gameMap.event(XX).y - this.character(0).y)
  ◆If: SV: Distance ≤ 1
    ◆Common Event: DAMAGE SFX
    ◆Control Variables: #0189 SV: This event HP -= SV: Damage
    ◆Set Movement Route: This Event
      : Blend Mode: Additive
      : Wait: 30 frames
      : Blend Mode: Normal
    ◆Control Variables: #0XXX SV: Last Hit = Hit Count
  ◆End
◆End

SV: Distance is the same self variable the enemy’s basic attack uses, and XX is the Attack collision’s event ID, the number at the top of its event window. This hits each enemy once per wander.

6 and 7. Yes, I’d give the trap its own type 6. Copy your type 3 branch, change the copy’s condition to 6, set the trap’s ATTACK TYPE to 6, and put 6 in the re arm block at the top of the hit section. That keeps your other type 3 attack the way it is. For 7, it’s the Hit Count += 1 between blasts from my last post.

  1. The route still has Wait ticked. It shows as (Wait) after Attack collision in your second screenshot. That parks the parallel until the swing finishes, so it never sees the next press, and Punch Timer only gets set after the swing is already over. Untick Wait for Completion on that route, and tick Skip If Cannot Move while you’re in there. Then Punch Timer = 15 runs the moment you press Z like it’s meant to.

Two quick checks while you’re in there. The end of your Script line is cut off in the screenshot, so make sure it finishes with $gameVariables.value(241) > 0), since 241 is your Punch Timer. Also, each enemy only takes the extra swings if the Hit Count version of the hit section from my last post is in. That’s what lets a new swing land while ATTACKING stays ON.

The ShieldX and ShieldY lines aren’t doing anything in this block, so they can stay or go.

  1. No, it’s separate, but the fix is already in the hit section code from my last post. When an enemy gets punched, its knockback turns it to face you, then steps it backward. If the enemy is diagonal to you, it can only face up, down, left or right, so it faces up or down, and stepping backward pushes it up or down instead of the way you punched. The Script line in the type 0 and type 1 branches replaces that turn. It points the enemy the opposite way from the Attack collision, so stepping backward pushes it the same way your punch was going. XX in that line is the Attack collision’s event ID.

2/3-Here is the Attack Type 5 Branch, referenced by Form 4’s S Attack, (there are more steps)

and the Attack Type 2 Branch, referenced by Form 3’s S Attack.

The other branch is below (there are also more steps)

4-Here is Form 1’s S Attack,

and here is Form 2’s S Attack.

5-This is the time to reference your first response in regards to 6 and 7 right? I’ll make a duplicate of the enemy and start adding it now.

6/7-I duplicated Attack Type 3, made it 6, and placed it right below Attack Type 4, directly above the (If ATKCol X and Y = My X and Y) lines.

10-This is indeed mashable now! You say that in order for the damage calculations to function, then this is the moment to add the Hit Count code from 6 and 7?

11-Do you think you could repost that script line, and where exactly I need to put it? And should 2 and 5 also get it the line, since they knock back too, until a wall or another enemy is bumped into?

I’m sorry this is moving slowly, I’m trying not to get overwhelmed or make mistakes since this was another really big chunk of questions.

2 and 3. I think your blocking guess was right, and I had it wrong last time. With Skip on, each Step Backward that can’t move still takes a frame to get skipped, and those branches have a lot of them. So an enemy with another enemy right behind it stands there burning through steps, then carries on with whatever’s left once the other one moves. On the ram, that’s the pause before anything happens. On Form 4, it’s an enemy pushed into one the blast hasn’t reached yet, so it waits until that one gets hit and moves.

Since you want them to stop at a wall or another enemy, I’d swap the long list of steps for a loop that takes one step at a time and stops the first time a step doesn’t move it. It’s in the type 2 and type 5 branches below. SV: KB X and SV: KB Y are two new self variables. One difference to know about: enemies will now fly until they actually hit something, instead of stopping after however many Step Backward lines there were.

  1. The collision’s Map X and Y jump to the next tile the moment a step starts, so an enemy right in front gets hit on the first frame of the blast, while the collision is still mostly under you. The two AtkCol lines at the top of the hit section below read its position from where it’s actually drawn, rounded, so a hit lands once it’s more than halfway into the enemy’s tile. That applies to every attack that uses the Attack collision, so the punch and the rest will line up with the visuals better too.

For both Form 1 and Form 2, I’d also move ATTACKING = ON down to right above the Set Movement Route: Attack collision. Right now it’s ON during the charge up, and on Form 2 the collision sits live and invisible on the tile you step back from.

  1. Yes, the hit section goes in first, and the type 7 block lives inside it. It’s already in the full version below. Making a copy of the enemy first is a good idea.

6 and 7. Close, it just needs to move. Type 4 sits outside the position check because it hits everything on the map at once. The trap should only hit what’s on its tile, so its branch goes inside If: SV: AtkCol Y = SV: My Y, next to type 3. Where it is now, it would hit every enemy on the map over and over. It’s in the right spot in the full version below.

  1. Nice! Yes, this is the time. The full hit section below is that code with everything else from this post in it. Your type 2 and type 5 branches each end with Control Self Switch: B = ON, and those lines go away, since the ≠ 1 and ≠ 3 check at the bottom marks the hit for them now.
  2. Here’s the line:
this.character(0).setDirection(10 - $gameMap.event(63).direction());

It goes as a Script command right after the Set Event Location: This Event in a branch, and the Turn toward Player comes out of that branch’s route. I’ve used 63 because that’s the number your Form 2 route uses for the Attack collision, so swap it if that’s a different event. 5 should get it too, since it’s pushed by the collision. 2 doesn’t need it. The ram only hits the tile straight in front of you, so Turn toward Player already points the right way. In the full version below, it’s in types 0, 1 and 5.

Here’s the whole hit section with all of it in, so you can swap the old one out in one go. SV: Last Hit, SV: KB X and SV: KB Y are new self variables, and Self Switch B isn’t used anymore. Parts in parentheses are your existing contents, unchanged:

◆If: ATTACKING is ON
  ◆If: ATTACK TYPE = 6
    ◆Control Variables: #0192 SV: AtkCol X = Map X of Attack collision
    ◆Control Variables: #0193 SV: AtkCol Y = Map Y of Attack collision
    ◆Control Variables: #0194 SV: My X = Map X of This Event
    ◆Control Variables: #0195 SV: My Y = Map Y of This Event
    ◆If: SV: AtkCol X ≠ SV: My X
      ◆Control Variables: #0XXX SV: Last Hit = -1
    ◆End
    ◆If: SV: AtkCol Y ≠ SV: My Y
      ◆Control Variables: #0XXX SV: Last Hit = -1
    ◆End
  ◆End
  ◆If: SV: Last Hit ≠ Hit Count
    ◆Control Variables: #0192 SV: AtkCol X = Math.round($gameMap.event(63)._realX)
    ◆Control Variables: #0193 SV: AtkCol Y = Math.round($gameMap.event(63)._realY)
    ◆If: ATTACK TYPE = 2
      ◆Control Variables: #0192 SV: AtkCol X = Map X of Player
      ◆Control Variables: #0193 SV: AtkCol Y = Map Y of Player
      ◆Control Variables: #0221 Hit Dir = Direction of Player
      ◆If: Hit Dir = 2
        ◆Control Variables: #0193 SV: AtkCol Y += 1
      ◆End
      ◆If: Hit Dir = 4
        ◆Control Variables: #0192 SV: AtkCol X -= 1
      ◆End
      ◆If: Hit Dir = 6
        ◆Control Variables: #0192 SV: AtkCol X += 1
      ◆End
      ◆If: Hit Dir = 8
        ◆Control Variables: #0193 SV: AtkCol Y -= 1
      ◆End
    ◆End
    ◆Control Variables: #0194 SV: My X = Map X of This Event
    ◆Control Variables: #0195 SV: My Y = Map Y of This Event
    ◆Control Variables: #0232 SV: Damage = Player ATK
    ◆Control Variables: #0232 SV: Damage *= Move Power
    ◆Control Variables: #0233 SV: Def Calc = SV: This Event DEF
    ◆Control Variables: #0233 SV: Def Calc += 100
    ◆Control Variables: #0232 SV: Damage /= SV: Def Calc
    ◆If: ATTACK TYPE = 4
      ◆Control Variables: #0189 SV: This event HP -= SV: Damage
      ◆Play SE: Blow1 (90, 150, 0)
      ◆Set Movement Route: This Event
        : Blend Mode: Additive
        : Wait: 30 frames
        : Blend Mode: Normal
      ◆Control Variables: #0XXX SV: Last Hit = Hit Count
    ◆End
    ◆If: ATTACK TYPE = 7
      ◆Control Variables: #0XXX SV: Distance = Math.abs($gameMap.event(63).x - this.character(0).x) + Math.abs($gameMap.event(63).y - this.character(0).y)
      ◆If: SV: Distance ≤ 1
        ◆Common Event: DAMAGE SFX
        ◆Control Variables: #0189 SV: This event HP -= SV: Damage
        ◆Set Movement Route: This Event
          : Blend Mode: Additive
          : Wait: 30 frames
          : Blend Mode: Normal
        ◆Control Variables: #0XXX SV: Last Hit = Hit Count
      ◆End
    ◆End
    ◆If: SV: AtkCol X = SV: My X
      ◆If: SV: AtkCol Y = SV: My Y
        ◆If: ATTACK TYPE = 0
          ◆Common Event: DAMAGE SFX
          ◆Common Event: SCREENSHAKE SMALL
          ◆Control Variables: #0189 SV: This event HP -= SV: Damage
          ◆Control Variables: #0194 SV: My X = Math.round(this.character(0)._realX)
          ◆Control Variables: #0195 SV: My Y = Math.round(this.character(0)._realY)
          ◆Set Event Location: This Event, ({SV: My X},{SV: My Y})
          ◆Script: this.character(0).setDirection(10 - $gameMap.event(63).direction());
          ◆Set Movement Route: This Event (Skip, Wait)
            : Speed: 6
            : 1 Step Backward
            : 1 Step Backward
            : Speed: 4
        ◆End
        ◆If: ATTACK TYPE = 1
          ◆Control Variables: #0194 SV: My X = Math.round(this.character(0)._realX)
          ◆Control Variables: #0195 SV: My Y = Math.round(this.character(0)._realY)
          ◆Set Event Location: This Event, ({SV: My X},{SV: My Y})
          ◆Script: this.character(0).setDirection(10 - $gameMap.event(63).direction());
          ◆Set Movement Route: This Event (Skip, Wait)
            : Blend Mode: Normal
            : Speed: 5
            : SE: Blow5 (80, 100, 0)
            : 1 Step Backward
            : Speed: 4
            : Wait: 5 frames
            : Blend Mode: Normal
        ◆End
        ◆If: ATTACK TYPE = 2
          ◆Control Variables: #0189 SV: This event HP -= SV: Damage
          ◆Control Variables: #0194 SV: My X = Math.round(this.character(0)._realX)
          ◆Control Variables: #0195 SV: My Y = Math.round(this.character(0)._realY)
          ◆Set Event Location: This Event, ({SV: My X},{SV: My Y})
          ◆Set Movement Route: This Event (Skip, Wait)
            : Blend Mode: Additive
            : Speed: 5
            : Turn toward Player
            : SE: Maris Haven SFX/Fighting/BSFX BLASTAWAY
          ◆Loop
            ◆Control Variables: #0194 SV: My X = Map X of This Event
            ◆Control Variables: #0195 SV: My Y = Map Y of This Event
            ◆Set Movement Route: This Event (Skip, Wait)
              : 1 Step Backward
            ◆Control Variables: #0XXX SV: KB X = Map X of This Event
            ◆Control Variables: #0XXX SV: KB Y = Map Y of This Event
            ◆If: SV: KB X = SV: My X
              ◆If: SV: KB Y = SV: My Y
                ◆Break Loop
              ◆End
            ◆End
          ◆Repeat Above
          ◆Set Movement Route: This Event (Skip, Wait)
            : Blend Mode: Normal
            : Speed: 4
            : Wait: 5 frames
        ◆End
        (your ATTACK TYPE = 3 branch, unchanged)
        ◆If: ATTACK TYPE = 5
          ◆Control Variables: #0189 SV: This event HP -= SV: Damage
          ◆Control Variables: #0194 SV: My X = Math.round(this.character(0)._realX)
          ◆Control Variables: #0195 SV: My Y = Math.round(this.character(0)._realY)
          ◆Set Event Location: This Event, ({SV: My X},{SV: My Y})
          ◆Script: this.character(0).setDirection(10 - $gameMap.event(63).direction());
          ◆Set Movement Route: This Event (Skip, Wait)
            : Blend Mode: Additive
            : Speed: 5
            : SE: Maris Haven SFX/Fighting/BSFX BLASTAWAY
          ◆Loop
            ◆Control Variables: #0194 SV: My X = Map X of This Event
            ◆Control Variables: #0195 SV: My Y = Map Y of This Event
            ◆Set Movement Route: This Event (Skip, Wait)
              : 1 Step Backward
            ◆Control Variables: #0XXX SV: KB X = Map X of This Event
            ◆Control Variables: #0XXX SV: KB Y = Map Y of This Event
            ◆If: SV: KB X = SV: My X
              ◆If: SV: KB Y = SV: My Y
                ◆Break Loop
              ◆End
            ◆End
          ◆Repeat Above
          ◆Set Movement Route: This Event (Skip, Wait)
            : Blend Mode: Normal
            : Speed: 4
            : Wait: 5 frames
        ◆End
        (your ATTACK TYPE = 6 branch, the copy of type 3, moved here)
        ◆If: ATTACK TYPE ≠ 1
          ◆If: ATTACK TYPE ≠ 3
            ◆Control Variables: #0242 Hit Count... 

Sorry, the last lines of that block got cut. Here’s the end of the hit section, starting from the guard:

        ◆If: ATTACK TYPE ≠ 1
          ◆If: ATTACK TYPE ≠ 3
            ◆Control Variables: #0XXX SV: Last Hit = Hit Count
          ◆End
        ◆End
      ◆End
    ◆End
  ◆End
: Else
  ◆Control Variables: #0XXX SV: Last Hit = -1
◆End