Today’s state is also a bit on the simple side, but it opens the developer up to all kinds of extra things. I present to you Hurricane.
What does it do?
When this state is active, all enemies take damage at the end of the caster’s turn. While this example state is designed to only be usable by an actor, so it will only deal damage to enemies, it is possible to modify it quite easily to make enemies capable of using it as well. The state is applied to the caster, by using a skill. At the end of each of the caster’s turns (including the one he used to apply the state), a storm causes damage to all enemies. I also included an extra effect, that with a 60% chance, a bolt of lightning will also strike a random alive enemy after the wind effect.
What do I need?
For this effect, we only need a couple of animations, a skill, and the usual plugins. The meat of what we’re doing is on the custom state, with the actual skill being just a vessel being used to apply the state to the caster.
Above, you can see our skill. It is important that it targets the user, and doesn’t do damage itself. Our action sequence is a little different:
<setup action> eval: user.turns = 0 //This eval is used later to insure the hurricane effect only goes off once per turn display action camera focus: user zoom: 250%, 30 wait: 30 motion chant: user cast animation: user animation wait: 12 motion spell: user wait: 15 </setup action> <Target Action> clear battle log eval: SceneManager._scene._logWindow._lines.push('A storm is brewing...' + '<CENTER>'); eval: SceneManager._scene._logWindow.refresh(); //These two eval codes cause the battle log to show text for the skill. wait: 60 motion item: user action effect: user wait: 60 reset zoom wait: 30 </Target Action> <Finish Action> reset camera reset zoom clear battle log </Finish Action>
The skill itself doesn’t use an animation, and the sequence is brief, showing only some text and slight motion to the character using it.
Next we have our state. This is applied to the actor who casts the above skill on himself. This state is removed after combat, but I did not include a ‘remove after x turns’. This was because I didn’t want the turn counter to show on the state, so the user didn’t know how many turns it would last. The code allows between 4 and 6 turns of storming before being removed.
And here is the copy paste code for this state:
<Custom Apply Effect> target.hurricaneDmg = 200 + (target.mat * 4) //The base damage for the effect target.hurricaneTurns = Math.floor((Math.random() * 4) +3) //The length of time the effect will last </Custom Apply Effect> <Custom Turn Start Effect> user.turns = 0 //We're using user.turns to make sure the hurricane effect doesn't happen more than once per turn //This is in case some sort of effect gives him two actions in a turn </Custom Turn Start Effect> <Custom Turn End Effect> if (user.turns == 0) { var extraFramesToWaitFor = 15; var ele = 7 //The element for the wind effect var animFrames = ($dataAnimations[94].frames.length * 4) + 1 + extraFramesToWaitFor; var waitSeconds = (animFrames/60) * 1000; $gameScreen.startTint([-120,-120,-120,60], 20); $gameTroop.members()[0].startAnimation(94, false, 0); if ((Math.random()*100) > 60){ var strike = true //A strike has happened var extra = 120 //This extra value is used to add to the end of the timeout to make the damage show properly }else{ //No strike has occurred. var strike = false var extra = 0 } //The setTimeout function below is used to make the damage popup after the animation finishes //This makes the code look confusing, but should be fine as long as you copy-paste it setTimeout(function () { for (i = 0; i < $gameTroop.members().length; i++) { //This for loop is finding valid enemy targets for the hurricane damage if (!$gameTroop.members()[i].isDead()){ //For each alive enemy found, deal hurricane damage. var total = Math.floor((user.hurricaneDmg * ((Math.random()*40+80)/100)) * $gameTroop.members()[i].elementRate(ele)) $gameTroop.members()[i].gainHp(-total); $gameTroop.members()[i].startDamagePopup(); $gameTroop.members()[i].performDamage(); if ($gameTroop.members()[i].isDead()) { $gameTroop.members()[i].performCollapse(); } BattleManager.checkBattleEnd(); } } var target = false if (strike == true) { while (target == false) { var rnd = Math.floor(Math.random() * $gameTroop.members().length) var enemy = $gameTroop.members() if (!enemy[rnd].isDead()){ //find a random alive enemy to hit with lightning enemy[rnd].startAnimation(172, false, 0); target = true } if ($gameTroop.isAllDead()) { target = true } } setTimeout(function () { if (!enemy[rnd].isDead()){ //Deal damage to enemy struck by lightning var total2 = Math.floor((user.hurricaneDmg * ((Math.random()*40+80)/100)) * enemy[rnd].elementRate(4)) enemy[rnd].gainHp(-total2); enemy[rnd].startDamagePopup(); enemy[rnd].performDamage(); if (enemy[rnd].isDead()) { enemy[rnd].performCollapse(); } BattleManager.checkBattleEnd(); } $gameScreen.startTint([0,0,0,0], 30); setTimeout(function () { for (i = 0; i < $gameTroop.members().length; i++){ $gameTroop.members()[i].performActionEnd() } }, 180); }, 1200); } if (!strike){ $gameScreen.startTint([0,0,0,0], 30); setTimeout(function () { for (i = 0; i < $gameTroop.members().length; i++){ $gameTroop.members()[i].performActionEnd() } }, 180); } }, waitSeconds); BattleManager._logWindow._waitCount += (animFrames + extra + 30); user.turns = 1 //This is used to insure the effect doesn't happen more than once per turn user.hurricaneTurns = user.hurricaneTurns -1 //lower the turn counter for the state } if (user.hurricaneTurns == 0) { //remove the state if the turn counter is 0 user.removeState(195) } </Custom Turn End Effect> <Custom Remove Effect> //If the state is removed at battle-end, remove the turn value user.hurricaneTurns = undefined </Custom Remove Effect>
Also, remember that you will need to change the animation numbers and the stateId for this to work in your project.
While this effect itself is pretty neat, you can use the framework for this state effect to make states that cause animations before showing the damage. The best part about this implementation is that states made in this way can show a full animation, as if a skill had been used, without forcing an action on the user, which can mess with turn order in a CTB or ATB system.
How does it look?
That’s all for this update folks.
-Ramza