Button Cast Plugin

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
Button Cast v1.10


by Gilgamar


Description


Adds the ability to cast skills instantly during active turn battle by pressing a button.


Now on GitHub!


Demo Project Zip File v1.10



Playable Demo v1.10


How it Works


- This plugin requires Yanfly's Core, Battle Engine, and ATB System plugins.


- Skills are bound to keys in actor notetags.


- While the actor's ATB meter is filling press an assigned key to cast a skill instantly.


Strategies


- Can enable instant cast by setting ATB Charge Gauge to 0 in Yanfly's ATB parameters.


- Set rubberband to false in ATB parameters and increase enemy agi for slower ATB buildup. 


Progress


- Added automatic switching of system and button cast key bindings.


- Added MOBA mode as an extension script.


- Added skill passives which can be used to call a common event immediately upon button press.


- Passive skills do not interrupt ATB and can be used to charge MP/TP/ATB or anything you can get away with in a common event!


- Full targeting system implemented.


- Supports multi-actor button casting for full keyboard support minus important keys.


- Checks if user has learned skill, plays buzzer if not.


- Checks if user status prevents casting.


Future Plans


- Menu skill key assignments.


- True passive skills which will process immediately on every ATB tick without requiring button press for use in regenerative abilities.


- Feedback and suggestions appreciated!


Changelog

Next Version:
Menu key assignments and skill bindings

Version 1.10:
Faster key checking
Fixed passive skills
Removed a few rogue globals
checkKeysActor() is now used to check one actor's keys
checkKeysBattlers() is now used to check all battlers' keys
Changed processCommonEvent() to forceCommonEvent() with improvements

Version 1.09:
Revised code with jshint
Moved MOBA mode to extension script
Moved Key Management to extension script
Changed console.log() to debug() with ability to suppress output
Fixed a bug where actor has no keys checkActorKeys() would crash
Fixed a bug where battleEnd was not being checked between queued actors

Version 1.08:
Added MOBA mode
Each actor has a separate key list and no longer needs to share keys
Fixed a bug when more than one battler queued processActionSequence() cleared wrong battler
Fixed a bug where battler actions cleared before checking if action valid
Fixed help file

Version 1.07:
Now with non-interrupting button casts! No more ATB reset
Moved processing into BattleManager.update() from BattleManager.updateATBTicks()
Using phases to control battle flow during button cast operations

Version 1.06:
Added passive skills (experimental)
Added skill notetag
Passive skills execute their common events immediately without taking a turn
Fixed a bug where checkButtonCast() would crash if an actor had no keys assigned
Automatically corrects key names when parsing notetags
Automatically swaps system keys with button cast keys to preserve original bindings
Added actor notetag
Removed parameters and previous actor notetag
Added some Input and utility functions

Version 1.05:
Support for multiple actors using same key
Grouped button cast functions under BattleManager instead of global
Added debug statements at each phase of button cast
Redirected on cancel functions to ensure skill and atb reset correctly
Notetags for actor key assignments
Changed checkInput() to use isTriggered() so debouncing is no longer required
Fixed help section and added key naming reference
Cleaned up code and various bugfixes

Version 1.04:
Target selection for allies and enemies
Fixed sprite not moving back if button cast canceled
Added nearly full keyboard support excluding keys that shouldn't be altered
Renamed runSkill() to checkButtonCast()
Improved code efficiency by debouncing checkButtonCast()
Checks if user has status effects to prevent casting while sleep/dead etc
Improved source code formatting and added references at the end of script

Version 1.03:
Enemy target selection after using button cast

Version 1.02:
Can now button cast with multiple actors!
Assign keys to actors in parameter

Version 1.01:
Buttons not activated unless skill assigned
Skill assignments now stored in Gilgamar.ButtonCast.keyList for easier access
Added a,s,d keys
Choose actor in parameter
Simplified checkInput() function for scalability
runSkill() function checks if user has skill and plays buzzer sound if not
Cool down timer to prevent overlapping sound effects

Version 1.00:
Single actor button cast!



Terms of Use and Credits


- Free for commercial and non commercial use.


- Credit Gilgamar if you use this plugin.


- Credit Yanfly for ATB system.


Thanks


- BucketsOfRP for coming up with the idea and testing the script
 
Last edited by a moderator:

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
Version 1.06b is ready for beta testing! Nearing 1000 lines of code!
 
Last edited by a moderator:

BucketsOfRP

Veteran
Veteran
Joined
Feb 15, 2016
Messages
13
Reaction score
1
First Language
Polish
Primarily Uses
I'd say, I did not expect this, but you totally nailed what I asked for!


I'll be running some extensive tests after the 22nd to make sure everything works fine and dandy. For now, I can only say you did a great job!


Hm... of the top of my head - only one thing bugs me. Currently the actors that can be selected are restricted to the first 4. If the user would have a bigger party, the system would be incompatible with that. While for some games, 4 actors are enough (and more than enough in my case at least...) swapping party members could be an issue here. 


Just saying that working on the possibility of assigning more actors  AND having them share keys for skills as an option is something that could be a direction for future updates.


Aside from that - I've got only praises. 
 

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
Note tags would address the issue of having more than 4 actors since key assignments could be set in the editor for each actor created.


Another way to do key assignments could be based on party position. How many actors are allowed in the battle screen? if we're limited to four then it still works but this way swapping characters wouldn't affect the key assignments as it would be tied to party position. Granted we would have to adjust skill bindings if they change. An in game menu to set the skill bindings would be ideal and possibly my next big undertaking. 


Having a single key bound to multiple actors shouldn't be too hard to do. Currently the script doesn't check that and it would likely break my code. I would have to queue the actors and have them perform actions for the next few ticks, there could be some issues with timing though since I'm not sure how to stop the ticker. 


Keep the ideas coming. I'd also like to hear more about your plans for implementing the script as that would help me determine the best approach to future updates.
 
Last edited by a moderator:

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
Another idea I had for a feature that could be optional would be charging button casts. I could borrow Yanfly's charge meter for that and have it so after you press the skill key you have to keep pressing it repeatedly to fill up the charge meter before it will go off and if you don't press fast enough the meter will cool down. If it goes back to 0 it will cancel the button cast (possibly at the cost of MP or TP as penatly). I saw in other threads someone was looking for a charging skill meter and this would be similar and possibly address that need.
 

BucketsOfRP

Veteran
Veteran
Joined
Feb 15, 2016
Messages
13
Reaction score
1
First Language
Polish
Primarily Uses
My idea for the game would probably not help here right now, since the functionality I needed is already provided by the script. If you are interested however, I'll put it down here:

It's a rather simple idea in a way. We have only one character fighting enemies in ATB.


However, our character loads his ATB very, very very slowly. The idea is that we have a set amount of MP (that only barely increases with levels). We use Instant button casts to fight off enemies while we have MP. When the ATB fills up, we have several options to choose from:


- Do a Major damage move.


- Recover HP 


- Recover all MP.


So as we gain power, battles can end before we manage to get our ATB to full OR be strategic because we have to save MP to counter enemy moves (with ATB interrupts or by destroying summoned smaller enemies that are threats, etc.) or just going for Burst strats. That was the gist of it.



Anyway, if you were to fix based on party position... This would require a lot of planning and will be prone to bugs. I'll try to help soon with that.


I'm trying to make a function right now that checks actor Notes for buttons and skills and based on that would pass arguments to your script. Its far from ready for now, but the moment you get your plugin to a stable version, I'll try putting it in. That way we could just put <Actor GButton Skill> X Y Where X is button and Y is skill ID. And that would basically fix the problem.  It will load the database, check what each actor has in the box and based on that will give the correct amount of buttons and assigned skills to chosen actor regardless of position. 


That will wait till after 22nd though. Especially that my RegEx's are kinda newbish, so it will take me some time to get it to work. 
 

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
Well I just figured out note tags. I also had to brush up on my regexp and it took me quite a while to get it working. I'm sure it could use some fine tuning though. The worst part though was implementing multi-actor key bindings. This is really toying with the state machine and I might have to redefine some of Yanfly's code to check the correct sequencing and not interrupt my button cast queuing. I got it sorta working as it is but it's really hackish code and not very neat, tidy or flexible. I'm pretty sure it's got a dozen undiscovered bugs also due to the complex sequence of events going on and the stuff behind the scenes that I have no control over at the moment.


This is a very rough draft of v1.5, let's called it v1.5a.

Code:
/*=============================================================================
 * Gilgamar - ButtonCast
 * By Gilgamar
 * G_ButtonCast.js
 * Version: 1.05a
 * Free for commercial and non commercial use.
 *=============================================================================*/

 var Imported = Imported || {};
 Imported.G_ButtonCast = true;

/*:
 * @plugindesc v1.05a Adds ability to instantly cast skills with button.
 * @author Gilgamar
 *
 * @param ---Top Row---
 * @default
 *
 * @param Key ~
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key 1
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key 2
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key 3
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key 4
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key 5
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key 6
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key 7
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key 8
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key 9
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key 0
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key -
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key =
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param ---2nd Row---
 * @default
 *
 * @param Key Q (PageUp)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key W (PageDown)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key E
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key R
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key T
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Y
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key U
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key I
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key O
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key P
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key [
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key ]
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key \
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param ---3rd Row---
 * @default
 *
 * @param Key A
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key S
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key D
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key F
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key G
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key H
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key J
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key K
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key L
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key ;
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key "
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Enter (OK)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param ---4th Row---
 * @default
 *
 * @param Key Shift (Dash)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Z (OK)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key X (Cancel)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key C
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key V
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key B
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key N
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key M
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key ,
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key .
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key /
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param ---Misc---
 * @default
 *
 * @param Key Space (OK)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Left (Left)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Up (Up)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Right (Right)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Down (Down)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Insert (Cancel)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Delete
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Home
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key End
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Page Up (PageUp)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key Page Down (PageDown)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param ---NumPad---
 * @default
 *
 * @param Key NumPad 0 (Cancel)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad 1
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad 2 (Down)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad 3
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad 4 (Left)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad 5
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad 6 (Right)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad 7
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad 8 (Up)
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad 9
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad .
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad +
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad -
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad *
 * @desc ID of skill to bind to key
 * @default 0
 *
 * @param Key NumPad /
 * @desc ID of skill to bind to key
 * @default 0
 */

/* ============================================================================
 * Changelog
 * ============================================================================
 * Next Version:
 * - Menu key assignments and skill bindings
 *
 * Version 1.05a (Current):
 * - Support for multiple actors using same key (experimental)
 * - Notetags for actor key assignments
 *
 * Version 1.04:
 * - Target selection for allies and enemies
 * - Fixed sprite not moving back if button cast canceled
 * - Added nearly full keyboard support excluding keys that shouldn't be altered
 * - Renamed runSkill() to checkButtonCast()
 * - Improved code efficiency by debouncing checkButtonCast()
 * - Checks if user has status effects to prevent casting while sleep/dead etc
 * - Improved source code formatting and added references at the end of script
 *
 * Version 1.03:
 * - Enemy target selection after using button cast
 *
 * Version 1.02:
 * - Can now button cast with multiple actors!
 * - Assign keys to actors in parameter
 *
 * Version 1.01:
 * - Buttons not activated unless skill assigned
 * - Skill assignments now stored in ButtonCast.keyList for easier access
 * - Added a,s,d keys
 * - Choose actor in parameter
 * - Simplified checkInput() function for scalability
 * - runSkill() function checks if user has skill and plays buzzer sound if not
 * - Cool down timer to prevent overlapping sound effects
 *
 * Version 1.00:
 * - Single actor button cast!
 */

if (Imported.YEP_X_BattleSysATB) {

//=============================================================================
// Parameters
//=============================================================================

var parameters = PluginManager.parameters('G_ButtonCast');
// console.log(parameters)
var ButtonCast = {};

ButtonCast.keyList = {
        tilde: Number(parameters['Key ~']),
            1: Number(parameters['Key 1']),
            2: Number(parameters['Key 2']),
            3: Number(parameters['Key 3']),
            4: Number(parameters['Key 4']),
            5: Number(parameters['Key 5']),
            6: Number(parameters['Key 6']),
            7: Number(parameters['Key 7']),
            8: Number(parameters['Key 8']),
            9: Number(parameters['Key 9']),
            0: Number(parameters['Key 0']),
        minus: Number(parameters['Key -']),
        equal: Number(parameters['Key =']),

            q: Number(parameters['Key Q (PageUp)']),
            w: Number(parameters['Key W (PageDown)']),
            e: Number(parameters['Key E']),
            r: Number(parameters['Key R']),
            t: Number(parameters['Key T']),
            y: Number(parameters['Key Y']),
            u: Number(parameters['Key U']),
            i: Number(parameters['Key I']),
            o: Number(parameters['Key O']),
            p: Number(parameters['Key P']),
    foreBrack: Number(parameters['Key [']),
    backBrack: Number(parameters['Key ]']),
    backSlash: Number(parameters['Key \\']),

            a: Number(parameters['Key A']),
            s: Number(parameters['Key S']),
            d: Number(parameters['Key D']),
            f: Number(parameters['Key F']),
            g: Number(parameters['Key G']),
            h: Number(parameters['Key H']),
            j: Number(parameters['Key J']),
            k: Number(parameters['Key K']),
            l: Number(parameters['Key L']),
    semicolon: Number(parameters['Key ;']),
        quote: Number(parameters['Key "']),
        enter: Number(parameters['Key Enter (OK)']),

     keyShift: Number(parameters['Key Shift (Dash)']),
            z: Number(parameters['Key Z (OK)']),
            x: Number(parameters['Key X (Cancel)']),
            c: Number(parameters['Key C']),
            v: Number(parameters['Key V']),
            b: Number(parameters['Key B']),
            n: Number(parameters['Key N']),
            m: Number(parameters['Key M']),
        comma: Number(parameters['Key ,']),
       period: Number(parameters['Key .']),
    foreSlash: Number(parameters['Key /']),

        space: Number(parameters['Key Space (OK)']),
      dirLeft: Number(parameters['Key Left (Left)']),
        dirUp: Number(parameters['Key Up (Up)']),
     dirRight: Number(parameters['Key Right (Right)']),
      dirDown: Number(parameters['Key Down (Down)']),
          ins: Number(parameters['Key Insert (Cancel)']),
          del: Number(parameters['Key Delete']),
         home: Number(parameters['Key Home']),
          end: Number(parameters['Key End']),
       pageUp: Number(parameters['Key Page Up (PageUp)']),
     pageDown: Number(parameters['Key Page Down (PageDown)']),

         num0: Number(parameters['Key NumPad 0 (Cancel)']),
         num1: Number(parameters['Key NumPad 1']),
         num2: Number(parameters['Key NumPad 2 (Down)']),
         num3: Number(parameters['Key NumPad 3']),
         num4: Number(parameters['Key NumPad 4 (Left)']),
         num5: Number(parameters['Key NumPad 5']),
         num6: Number(parameters['Key NumPad 6 (Right)']),
         num7: Number(parameters['Key NumPad 7']),
         num8: Number(parameters['Key NumPad 8 (Up)']),
         num9: Number(parameters['Key NumPad 9']),
    numPeriod: Number(parameters['Key NumPad .']),
      numPlus: Number(parameters['Key NumPad +']),
     numMinus: Number(parameters['Key NumPad -']),
     numTimes: Number(parameters['Key NumPad *']),
    numDivide: Number(parameters['Key NumPad /'])
}

//=============================================================================
// Input Key Mapper
//=============================================================================

    if (ButtonCast.keyList['tilde'] !== 0) Input.keyMapper[192]     = 'tilde';
    if (ButtonCast.keyList['1'] !== 0) Input.keyMapper[49]          = '1';
    if (ButtonCast.keyList['2'] !== 0) Input.keyMapper[50]          = '2';
    if (ButtonCast.keyList['3'] !== 0) Input.keyMapper[51]          = '3';
    if (ButtonCast.keyList['4'] !== 0) Input.keyMapper[52]          = '4';
    if (ButtonCast.keyList['5'] !== 0) Input.keyMapper[53]          = '5';
    if (ButtonCast.keyList['6'] !== 0) Input.keyMapper[54]          = '6';
    if (ButtonCast.keyList['7'] !== 0) Input.keyMapper[55]          = '7';
    if (ButtonCast.keyList['8'] !== 0) Input.keyMapper[56]          = '8';
    if (ButtonCast.keyList['9'] !== 0) Input.keyMapper[57]          = '9';
    if (ButtonCast.keyList['0'] !== 0) Input.keyMapper[48]          = '0';
    if (ButtonCast.keyList['minus'] !== 0) Input.keyMapper[189]     = 'minus';
    if (ButtonCast.keyList['equal'] !== 0) Input.keyMapper[187]     = 'equal';

    if (ButtonCast.keyList['q'] !== 0) Input.keyMapper[81]          = 'q';
    if (ButtonCast.keyList['w'] !== 0) Input.keyMapper[87]          = 'w';
    if (ButtonCast.keyList['e'] !== 0) Input.keyMapper[69]          = 'e';
    if (ButtonCast.keyList['r'] !== 0) Input.keyMapper[82]          = 'r';
    if (ButtonCast.keyList['t'] !== 0) Input.keyMapper[84]          = 't';
    if (ButtonCast.keyList['y'] !== 0) Input.keyMapper[89]          = 'y';
    if (ButtonCast.keyList['u'] !== 0) Input.keyMapper[85]          = 'u';
    if (ButtonCast.keyList['i'] !== 0) Input.keyMapper[73]          = 'i';
    if (ButtonCast.keyList['o'] !== 0) Input.keyMapper[79]          = 'o';
    if (ButtonCast.keyList['p'] !== 0) Input.keyMapper[80]          = 'p';
    if (ButtonCast.keyList['foreBrack'] !== 0) Input.keyMapper[219] = 'foreBrack';
    if (ButtonCast.keyList['backBrack'] !== 0) Input.keyMapper[221] = 'backBrack';
    if (ButtonCast.keyList['backSlash'] !== 0) Input.keyMapper[220] = 'backSlash';

    if (ButtonCast.keyList['a'] !== 0) Input.keyMapper[65]          = 'a';
    if (ButtonCast.keyList['s'] !== 0) Input.keyMapper[83]          = 's';
    if (ButtonCast.keyList['d'] !== 0) Input.keyMapper[68]          = 'd';
    if (ButtonCast.keyList['f'] !== 0) Input.keyMapper[70]          = 'f';
    if (ButtonCast.keyList['g'] !== 0) Input.keyMapper[71]          = 'g';
    if (ButtonCast.keyList['h'] !== 0) Input.keyMapper[72]          = 'h';
    if (ButtonCast.keyList['j'] !== 0) Input.keyMapper[74]          = 'j';
    if (ButtonCast.keyList['k'] !== 0) Input.keyMapper[75]          = 'k';
    if (ButtonCast.keyList['l'] !== 0) Input.keyMapper[76]          = 'l';
    if (ButtonCast.keyList['semicolon'] !== 0) Input.keyMapper[186] = 'semicolon';
    if (ButtonCast.keyList['quote'] !== 0) Input.keyMapper[222]     = 'quote';
    if (ButtonCast.keyList['enter'] !== 0) Input.keyMapper[13]      = 'enter';

    if (ButtonCast.keyList['keyShift'] !== 0) Input.keyMapper[16]   = 'keyShift';
    if (ButtonCast.keyList['z'] !== 0) Input.keyMapper[90]          = 'z';
    if (ButtonCast.keyList['x'] !== 0) Input.keyMapper[88]          = 'x';
    if (ButtonCast.keyList['c'] !== 0) Input.keyMapper[67]          = 'c';
    if (ButtonCast.keyList['v'] !== 0) Input.keyMapper[86]          = 'v';
    if (ButtonCast.keyList['b'] !== 0) Input.keyMapper[66]          = 'b';
    if (ButtonCast.keyList['n'] !== 0) Input.keyMapper[78]          = 'n';
    if (ButtonCast.keyList['m'] !== 0) Input.keyMapper[77]          = 'm';
    if (ButtonCast.keyList['comma'] !== 0) Input.keyMapper[188]     = 'comma';
    if (ButtonCast.keyList['period'] !== 0) Input.keyMapper[190]    = 'period';
    if (ButtonCast.keyList['foreSlash'] !== 0) Input.keyMapper[191] = 'foreSlash';

    if (ButtonCast.keyList['space'] !== 0) Input.keyMapper[32]     = 'space';
    if (ButtonCast.keyList['dirLeft'] !== 0) Input.keyMapper[37]   = 'dirLeft';
    if (ButtonCast.keyList['dirUp'] !== 0) Input.keyMapper[38]     = 'dirUp';
    if (ButtonCast.keyList['dirRight'] !== 0) Input.keyMapper[39]  = 'dirRight';
    if (ButtonCast.keyList['dirDown'] !== 0) Input.keyMapper[40]   = 'dirDown';
    if (ButtonCast.keyList['ins'] !== 0) Input.keyMapper[45]       = 'ins';
    if (ButtonCast.keyList['del'] !== 0)Input.keyMapper[46]        = 'del';
    if (ButtonCast.keyList['home'] !== 0)Input.keyMapper[36]       = 'home';
    if (ButtonCast.keyList['end'] !== 0)Input.keyMapper[35]        = 'end';
    if (ButtonCast.keyList['pageUp'] !== 0) Input.keyMapper[33]    = 'pageUp';
    if (ButtonCast.keyList['pageDown'] !== 0) Input.keyMapper[34]  = 'pageDown';

    if (ButtonCast.keyList['num0'] !== 0) Input.keyMapper[96]      = 'num0';
    if (ButtonCast.keyList['num1'] !== 0)Input.keyMapper[97]       = 'num1';
    if (ButtonCast.keyList['num2'] !== 0) Input.keyMapper[98]      = 'num2';
    if (ButtonCast.keyList['num3'] !== 0)Input.keyMapper[99]       = 'num3';
    if (ButtonCast.keyList['num4'] !== 0) Input.keyMapper[100]     = 'num4';
    if (ButtonCast.keyList['num5'] !== 0)Input.keyMapper[101]      = 'num5';
    if (ButtonCast.keyList['num6'] !== 0) Input.keyMapper[102]     = 'num6';
    if (ButtonCast.keyList['num7'] !== 0)Input.keyMapper[103]      = 'num7';
    if (ButtonCast.keyList['num8'] !== 0) Input.keyMapper[104]     = 'num8';
    if (ButtonCast.keyList['num9'] !== 0)Input.keyMapper[105]      = 'num9';
    if (ButtonCast.keyList['numPeriod'] !== 0)Input.keyMapper[110] = 'numPeriod';
    if (ButtonCast.keyList['numPlus'] !== 0)Input.keyMapper[107]   = 'numPlus';
    if (ButtonCast.keyList['numMinus'] !== 0)Input.keyMapper[109]  = 'numMinus';
    if (ButtonCast.keyList['numTimes'] !== 0)Input.keyMapper[106]  = 'numTimes';
    if (ButtonCast.keyList['numDivide'] !== 0)Input.keyMapper[111] = 'numDivide';


ButtonCast.keysActor = {};

//=============================================================================
// Notetags
//=============================================================================

ButtonCast.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
DataManager.isDatabaseLoaded = function() {
    if (!ButtonCast.DataManager_isDatabaseLoaded.call(this)) return false;
    DataManager.processBUTTONCASTNotetags1($dataActors);
    // DataManager.processBUTTONCASTNotetags2($dataSkills);
    return true;
};

DataManager.processBUTTONCASTNotetags1 = function(group) {
    var note1 = /<(?:BUTTONCAST KEYS):[ ](.+)>/i;
    for (var n = 1; n < group.length; n++){
        var obj = group[n];
        var notedata = obj.note.split(/[\r\n]+/);
        for (var i = 0; i < notedata.length; i++) {
            var line = notedata[i];
            if (line.match(note1)) {
                keys = RegExp.$1.trim().toLowerCase().split(' ').map(String)
                ButtonCast.keysActor[n] = keys
            }
        }
    }
};

//=============================================================================
// Plugin Commands
//=============================================================================

// var aliasPluginCommand = Game_Interpreter.prototype.pluginCommand;
// Game_Interpreter.prototype.pluginCommand = function(command, args) {
//     aliasPluginCommand.call(this, command, args);
//     if (command == 'ButtonCast') {
//         switch (args[0]) {
//             case 'init':
//                 break;
//         }
//     }
// }

//=============================================================================
// ButtonCast Functions
//=============================================================================

function checkInput() {
    for (var k in ButtonCast.keyList){
        if (Input.isPressed(String(k))) return k;
    }
    return null;
}

function checkButtonCast(k) {
    // Cool down timer for checkButtonCast() prevents consecutive function calls
    BattleManager['buttonCastCooldown'] = 10;

    // Multi actor keys - Multiple actors can use same key
    var battlers = [];
    for (var i in ButtonCast.keysActor){
        // Check if key assigned to battler
        if (ButtonCast.keysActor[i].indexOf(k) > -1){
            var actor = $gameActors.actor(i);
            if (actor.isBattleMember()) {
                battlers.push(actor);
            }
        }
    }

    // console.log(battlers)

    // Check if battler can take action
    var queuedBattlers = [];
    battlers.forEach(function(battler){
        if (!battler) return;                     // This should never happen but just in case
        if (battler.isATBCharging()) return;      // Action already queued
        if (!battler.canInput()) return;          // Check this in case of status effects

        console.log(battler.name(), 'checking')
        var skillId = ButtonCast.keyList[k];
        // Check if battler has skill
        if (!battler.isLearnedSkill(skillId)){
            SoundManager.playBuzzer();
            return;
        }
        // console.log(skillId);

        // battler.spriteStepForward();
        // battler.requestMotionRefresh();
        battler.makeActions();
        battler.forceAction(skillId);

        // console.log(battler)
        queuedBattlers.push(battler);
    });
    return queuedBattlers;
}

function prepareButtonCast(battler){
    console.log(battler.name(), 'preparing')
    BattleManager._actorIndex = battler.index();    // Prepare battler for action
    BattleManager.actor().spriteStepForward();
    BattleManager.actor().setActionState('inputting');
    BattleManager.actor().requestMotionRefresh();
    // console.log(battler)
    SceneManager._scene.onSelectAction()

    BattleManager.playATBReadySound();
    battler.setupATBCharge();
    battler.setATBCharge(battler.atbChargeDenom()); // Set charge to max

}

function executeButtonCast(battler){
    console.log(battler.name(), 'executing')
    action = battler._actions[0];
    if (!action) return;
    if (!action.isValid()){
        // Player canceled action
        BattleManager.actor().spriteStepBack();
        BattleManager.actor().setActionState('waiting');
        BattleManager.actor().requestMotionRefresh();
    }
    battler.setATBCharge(battler.atbChargeDenom()); // Set charge to max
}

//=============================================================================
// Yanfly Overrides
//=============================================================================

BattleManager.updateATBTicks = function() {
    if (!SceneManager._scene.isAnyInputWindowActive()){
        // Check if button cast needs execution (4)
        if (this.buttonCastBattler) {
            executeButtonCast(this.buttonCastBattler);
            this.buttonCastBattler = undefined;
        }

        // Check for user input (1)
        k = checkInput();
        // Check for button cast (2)
        if (this.buttonCastCooldown) {
            this.buttonCastCooldown -= 1;
        } else {
            if (k) this['queuedBattlers'] = checkButtonCast(k);
        }
        // Check for button cast battlers (3)
        var battlers = this.queuedBattlers || [];
        if (battlers.length > 0) {
            this['buttonCastBattler'] = battlers.shift();
            prepareButtonCast(this.buttonCastBattler);
        }
    }

    // Yanfly code below
    this._atbTicks += 1 * this.tickRate();
    if (this._atbTicks < this._atbFullTurn) return;
    $gameTroop.increaseTurn();
    this._atbTicks = 0;
    if (this.isTurnBased()) {
      this.endTurn();
    } else {
      this.endTurn();
    }
};

//=============================================================================
// Debugging and References
//=============================================================================

// Game_Battler.prototype.forceAction = function(skillId, targetIndex) {
//     this.clearActions();
//     var action = new Game_Action(this, true);
//     action.setSkill(skillId);
//     if (targetIndex === -2) {
//         action.setTarget(this._lastTargetIndex);
//     } else if (targetIndex === -1) {
//         action.decideRandomTarget();
//     } else {
//         action.setTarget(targetIndex);
//     }
//     this._actions.push(action);
// };
//
// BattleManager.inputtingAction = function() {
//     return this.actor() ? this.actor().inputtingAction() : null;
// };
//
// // Yanfly's
// BattleManager.startATBInput = function(battler) {
//     if (battler.isDead()) return;
//     battler.makeActions();
//     if (battler.isEnemy()) {
//       battler.setupATBCharge();
//       if (Yanfly.Param.ATBFlashEnemy) battler.requestEffect('whiten');
//       var chargedBattler = this.getChargedATBBattler();
//       if (chargedBattler) this.startATBAction(chargedBattler);
//     } else if (battler.canInput()) {
//       this._actorIndex = battler.index();
//       this.playATBReadySound();
//       battler.setActionState('inputting');
//       battler.spriteStepForward();
//       this._phase = 'input';
//     } else if (battler.isConfused()) {
//       battler.makeConfusionActions();
//       battler.setupATBCharge();
//     } else {
//       battler.makeAutoBattleActions();
//       battler.setupATBCharge();
//     }
// };
//
// // Yanfly's
// BattleManager.startATBAction = function(battler) {
//     this._subject = battler;
//     battler.onTurnStart();
//     var action = this._subject.currentAction();
//     if (action && action.isValid()) {
//       this.startAction();
//     } else {
//       this.endAction();
//     }
// };
//

// Some reason this doesn't work properly unless I redeclare it here.
Scene_Battle.prototype.onSelectAction = function() {
    var action = BattleManager.inputtingAction();
    // console.log(action)
    this._skillWindow.hide();
    this._itemWindow.hide();
    if (!action.needsSelection()) {
        this.selectNextCommand();
    } else if (action.isForOpponent()) {
        this.selectEnemySelection();
    } else {
        this.selectActorSelection();
    }
};

BattleManager.selectNextCommand = function() {
    do {
        if (!this.actor() || !this.actor().selectNextCommand()) {
            this.changeActor(this._actorIndex + 1, 'waiting');
            if (this._actorIndex >= $gameParty.size()) {
                this.startTurn();
                break;
            }
        }
    } while (!this.actor().canInput());
};

Yanfly.ATB.BattleManager_selectNextCommand = BattleManager.selectNextCommand;
BattleManager.selectNextCommand = function() {
    if (this.isATB()) {
      if (!this.actor()) return this.setATBPhase();
      this.resetNonPartyActorATB();
      this.actor().setupATBCharge();
      this.actor().spriteStepBack();
      this.actor().requestMotionRefresh();
      this._actorIndex = undefined;
      var chargedBattler = this.getChargedATBBattler();
      if (chargedBattler) {
        this.startATBAction(chargedBattler);
      } else {
        this.setATBPhase();
      }
    } else {
      Yanfly.ATB.BattleManager_selectNextCommand.call(this);
    }
};

//=============================================================================
// Item Scope
//=============================================================================
/*
 * 0  : None
 * 1  : 1 Enemy
 * 2  : All Enemies
 * 3  : 1 Random Enemy
 * 4  : 2 Random Enemies
 * 5  : 3 Random Enemies
 * 6  : 4 Random Enemies
 * 7  : 1 Ally
 * 8  : All Allies
 * 9  : 1 Ally (Dead)
 * 10 : All Allies (Dead)
 * 11 : The User
 */

};
 
Last edited by a moderator:

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
Latest script version 1.05a added! It has support for multiple actors to use the same key and actor notetags. Actors can now 'safely' cancel targeting when button casting (please test this heavily to make sure). Other things that need testing are various status ailments, switching party members, different types of targeting, etc. I've re-implemented the ATB charging since it can be tuned using Yanfly's parameters (if you want 0 charge time I'm sure it must be possible, haven't tested yet). I've tried to keep things as compatible as possible with Yanfly's ATB and possibly other plugins so please test.
 

BucketsOfRP

Veteran
Veteran
Joined
Feb 15, 2016
Messages
13
Reaction score
1
First Language
Polish
Primarily Uses
Oi, great news.


So, first bug - Help is not showing in the Plugin Manager, might be a syntax error somewhere there. 


....and second bug is that I added <ButtonCast Keys a> to Harold's notebox and yet he does nothing. I made sure he has the skills and can use it, but he's not casting it at all. 


The previous version worked, so I assume something is wrong with the Notebox now. Or I simply did something wrong. 


- Plugin is set to ON


- Key A is set to "10".


- Actor has <ButtonCast Keys a> (also tried later with an A);


- Actor has the skill and skill type. 


- Nothing happens in combat.


- Tried both in Battle Test and Play test.
 

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
It's probably the regexp. Probably need an OR in there might be expecting multiple key assignments. The help not coming up was a missing * between the parameter section and help section.


There's a missing semicolor in the notetag.  Try, <ButtonCast Keys: a>. I probably need to change the help file as I bet I forgot to show the semicolon.
 
Last edited by a moderator:

BucketsOfRP

Veteran
Veteran
Joined
Feb 15, 2016
Messages
13
Reaction score
1
First Language
Polish
Primarily Uses
Alright, adding the missing * fixed the help file. Adding the missing ":" also helped.


So the problem we have here now is this - only the FIRST button assigned will work. The later buttons for some reason when pressed give the BUZZER and no skill fires.


Also - for some reason using any skill makes it CHARGE as if you just queue it into the ATB. The ATB gauge drains after the action. (This is basically not the functionality the system requires to work. It needs to not drain the gauge nor charge actions. OR have the actions charge but give control over whether it charges the skill and for how long)


Additionally - using a skill that costs more MP than you have will cast it anyway and set your MP to a negative value. The value returns to 0 afterwards but the skill can be used AGAIN even at 0 MP.


Yeah... weird, cause your previous version before Notetag control had all the right functionality.


On a side note - The targetting system works flawlessly - you could lock it in. 
 

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
So I fixed all those issues and more. I decided to leave the ATB charging feature alone since you can control that in Yanfly's plugin by setting Charge Gauge to 0. This offers more compatibility and flexibility to the plugin. On the other hand, now all actions are cast instantly including during turn input. So maybe I will look into adding a setting in the plugin for just the button cast charger.


I changed forceAction to setAction so it no longer consumes TP/MP beyond 0 and I added action.isValid() to ensure the user cannot cast the skill if they do not meet the requirements (such as MP/TP).



I changed isPressed to isTriggered on the checkInput() function so I no longer need to debounce checkButtonCast().


I fixed the help file and added a key name reference.


I cleaned up the code and added debugging output to the developer console (press F8 in game).


I'm working on a playable demo next. For now I'll update the script to v1.05 as most bugs are fixed.
 

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
I'm not sure how I missed your comment about  <Actor GButton Skill> X Y . I read everything else in that post but I really like this idea. Right now it's a bit pesky to bounce back and forth between the actor page and the parameters. I often forget which keys are assigned to which actor when trying to assign skills to keys so having it all in one place makes sense. 


The working demo is really cool too. It totally show-cases your game idea. I can send you it in private if your not ready to share your idea to the world yet. 


I have the enemy with high hp, the players ATB is slow to charge (set Yanfly ATB rubberbanding to false and give high agi to enemies). This way if enemy agi is 4x player they will attack 4x per turn. 


The players have 4 button cast skills. The top two player have TP based skills, the bottom two players have MP based skills. Everyone has TP recovery and MP<>TP Swap. Group skill key tilde causes everyone to guard, if enemy can have a warn skill for a big attack this could be fun. TP recovery skill can only be used at turn end but MP<>TP Swap can be cast using the 4th skill key. I had to use a common event to create MP<>TP Swap. 


I want to add a few 100 TP skills for heavy turn based damage. The TP meter charges by enemy damage only but I set the clamp higher (15,30) so you get more TP per hit. This is configured in Yanfly's Enhanced TP plugin. 


I think it wouldn't be too hard to have a charging ATB skill with nothing more than a common event and an inline script to update the atb value by x amount. So the button charging could be implemented as I mentioned earlier. I might try this soon. 


If you wanted to work together on a game this could be fun. I have nothing but free time but a lack of ideas.
 
Last edited by a moderator:

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
Script Update v1.05.1

/*=============================================================================
* Gilgamar - ButtonCast
* By Gilgamar
* G_ButtonCast.js
* Version: 1.05.1
* Free for commercial and non commercial use.
*=============================================================================*/

var Imported = Imported || {};
Imported.G_ButtonCast = true;

/*:
* @plugindesc v1.05.1 Adds ability to instantly cast skills with button.
* @author Gilgamar
*
* @param ---Top Row---
* @default
*
* @param Key ~
* @desc ID of skill to bind to key
* @default 0
*
* @param Key 1
* @desc ID of skill to bind to key
* @default 0
*
* @param Key 2
* @desc ID of skill to bind to key
* @default 0
*
* @param Key 3
* @desc ID of skill to bind to key
* @default 0
*
* @param Key 4
* @desc ID of skill to bind to key
* @default 0
*
* @param Key 5
* @desc ID of skill to bind to key
* @default 0
*
* @param Key 6
* @desc ID of skill to bind to key
* @default 0
*
* @param Key 7
* @desc ID of skill to bind to key
* @default 0
*
* @param Key 8
* @desc ID of skill to bind to key
* @default 0
*
* @param Key 9
* @desc ID of skill to bind to key
* @default 0
*
* @param Key 0
* @desc ID of skill to bind to key
* @default 0
*
* @param Key -
* @desc ID of skill to bind to key
* @default 0
*
* @param Key =
* @desc ID of skill to bind to key
* @default 0
*
* @param ---2nd Row---
* @default
*
* @param Key Q (PageUp)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key W (PageDown)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key E
* @desc ID of skill to bind to key
* @default 0
*
* @param Key R
* @desc ID of skill to bind to key
* @default 0
*
* @param Key T
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Y
* @desc ID of skill to bind to key
* @default 0
*
* @param Key U
* @desc ID of skill to bind to key
* @default 0
*
* @param Key I
* @desc ID of skill to bind to key
* @default 0
*
* @param Key O
* @desc ID of skill to bind to key
* @default 0
*
* @param Key P
* @desc ID of skill to bind to key
* @default 0
*
* @param Key [
* @desc ID of skill to bind to key
* @default 0
*
* @param Key ]
* @desc ID of skill to bind to key
* @default 0
*
* @param Key \
* @desc ID of skill to bind to key
* @default 0
*
* @param ---3rd Row---
* @default
*
* @param Key A
* @desc ID of skill to bind to key
* @default 0
*
* @param Key S
* @desc ID of skill to bind to key
* @default 0
*
* @param Key D
* @desc ID of skill to bind to key
* @default 0
*
* @param Key F
* @desc ID of skill to bind to key
* @default 0
*
* @param Key G
* @desc ID of skill to bind to key
* @default 0
*
* @param Key H
* @desc ID of skill to bind to key
* @default 0
*
* @param Key J
* @desc ID of skill to bind to key
* @default 0
*
* @param Key K
* @desc ID of skill to bind to key
* @default 0
*
* @param Key L
* @desc ID of skill to bind to key
* @default 0
*
* @param Key ;
* @desc ID of skill to bind to key
* @default 0
*
* @param Key "
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Enter (OK)
* @desc ID of skill to bind to key
* @default 0
*
* @param ---4th Row---
* @default
*
* @param Key Shift (Dash)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Z (OK)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key X (Cancel)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key C
* @desc ID of skill to bind to key
* @default 0
*
* @param Key V
* @desc ID of skill to bind to key
* @default 0
*
* @param Key B
* @desc ID of skill to bind to key
* @default 0
*
* @param Key N
* @desc ID of skill to bind to key
* @default 0
*
* @param Key M
* @desc ID of skill to bind to key
* @default 0
*
* @param Key ,
* @desc ID of skill to bind to key
* @default 0
*
* @param Key .
* @desc ID of skill to bind to key
* @default 0
*
* @param Key /
* @desc ID of skill to bind to key
* @default 0
*
* @param ---Misc---
* @default
*
* @param Key Space (OK)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Left (Left)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Up (Up)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Right (Right)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Down (Down)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Insert (Cancel)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Delete
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Home
* @desc ID of skill to bind to key
* @default 0
*
* @param Key End
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Page Up (PageUp)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key Page Down (PageDown)
* @desc ID of skill to bind to key
* @default 0
*
* @param ---NumPad---
* @default
*
* @param Key NumPad 0 (Cancel)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad 1
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad 2 (Down)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad 3
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad 4 (Left)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad 5
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad 6 (Right)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad 7
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad 8 (Up)
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad 9
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad .
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad +
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad -
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad *
* @desc ID of skill to bind to key
* @default 0
*
* @param Key NumPad /
* @desc ID of skill to bind to key
* @default 0
*
* @help
* ============================================================================
* Introduction
* ============================================================================
* This plugin modifies Yanfly's ATB system to support button cast
*
* Skills are assigned to keys using the plugin parameter list
* Keys are assigned to actors using actor notetags, for example:
* <ButtonCast Keys: num1 q keyShift>
*
* For a full list of key names see the Key Names section below
*
* When a skill key is pressed, the actor or actors assigned to the key will
* perform the skill bound to the key in sequence so long as they have learned
* the skill and are not under status effects that would otherwise prevent them
* from using the skill
*
* ============================================================================
* Changelog
* ============================================================================
* Next Version:
* - Menu key assignments and skill bindings
*
* Version 1.05.1:
* - Fixed a bug where checkButtonCast() would crash if an actor had no keys assigned
* - Added actor notetag <ButtonCast Key: keyName:skillId>
*
* Version 1.05:
* - Support for multiple actors using same key
* - Grouped button cast functions under BattleManager instead of global
* - Added debug statements at each phase of button cast
* - Redirected on cancel functions to ensure skill and atb reset correctly
* - Notetags for actor key assignments
* - Changed checkInput() to use isTriggered() so debouncing is no longer required
* - Fixed help section and added key naming reference
* - Cleaned up code and various bugfixes
*
* Version 1.04:
* - Target selection for allies and enemies
* - Fixed sprite not moving back if button cast canceled
* - Added nearly full keyboard support excluding keys that shouldn't be altered
* - Renamed runSkill() to checkButtonCast()
* - Improved code efficiency by debouncing checkButtonCast()
* - Checks if user has status effects to prevent casting while sleep/dead etc
* - Improved source code formatting and added references at the end of script
*
* Version 1.03:
* - Enemy target selection after using button cast
*
* Version 1.02:
* - Can now button cast with multiple actors!
* - Assign keys to actors in parameter
*
* Version 1.01:
* - Buttons not activated unless skill assigned
* - Skill assignments now stored in ButtonCast.keyList for easier access
* - Added a,s,d keys
* - Choose actor in parameter
* - Simplified checkInput() function for scalability
* - runSkill() function checks if user has skill and plays buzzer sound if not
* - Cool down timer to prevent overlapping sound effects
*
* Version 1.00:
* - Single actor button cast!
*
* ============================================================================
* Key Names
* ============================================================================
* NAME: KEY
* tilde: ['Key ~']
* 1: ['Key 1']
* 2: ['Key 2']
* 3: ['Key 3']
* 4: ['Key 4']
* 5: ['Key 5']
* 6: ['Key 6']
* 7: ['Key 7']
* 8: ['Key 8']
* 9: ['Key 9']
* 0: ['Key 0']
* minus: ['Key -']
* equal: ['Key =']
*
* NAME: KEY
* q: ['Key Q']
* w: ['Key W']
* e: ['Key E']
* r: ['Key R']
* t: ['Key T']
* y: ['Key Y']
* u: ['Key U']
* i: ['Key I']
* o: ['Key O']
* p: ['Key P']
* foreBrack: ['Key [']
* backBrack: ['Key ]']
* backSlash: ['Key \']
*
* NAME: KEY
* a: ['Key A']
* s: ['Key S']
* d: ['Key D']
* f: ['Key F']
* g: ['Key G']
* h: ['Key H']
* j: ['Key J']
* k: ['Key K']
* l: ['Key L']
* semicolon: ['Key ;']
* quote: ['Key "']
* enter: ['Key Enter']
*
* NAME: KEY
* keyShift: ['Key Shift']
* z: ['Key Z']
* x: ['Key X']
* c: ['Key C']
* v: ['Key V']
* b: ['Key B']
* n: ['Key N']
* m: ['Key M']
* comma: ['Key ,']
* period: ['Key .']
* foreSlash: ['Key /']
*
* NAME: KEY
* space: ['Key Space']
* dirLeft: ['Key Left']
* dirUp: ['Key Up']
* dirRight: ['Key Right']
* dirDown: ['Key Down']
* ins: ['Key Insert']
* del: ['Key Delete']
* home: ['Key Home']
* end: ['Key End']
* pageUp: ['Key Page Up']
* pageDown: ['Key Page Down']
*
* NAME: KEY
* num0: ['Key NumPad 0']
* num1: ['Key NumPad 1']
* num2: ['Key NumPad 2']
* num3: ['Key NumPad 3']
* num4: ['Key NumPad 4']
* num5: ['Key NumPad 5']
* num6: ['Key NumPad 6']
* num7: ['Key NumPad 7']
* num8: ['Key NumPad 8']
* num9: ['Key NumPad 9']
* numPeriod: ['Key NumPad .']
* numPlus: ['Key NumPad +']
* numMinus: ['Key NumPad -']
* numTimes: ['Key NumPad *']
* numDivide: ['Key NumPad /']
*
*/

if (Imported.YEP_X_BattleSysATB) {

//=============================================================================
// Parameters
//=============================================================================

var parameters = PluginManager.parameters('G_ButtonCast');
// console.log(parameters)
var ButtonCast = {};

ButtonCast.keyList = {
tilde: Number(parameters['Key ~']),
1: Number(parameters['Key 1']),
2: Number(parameters['Key 2']),
3: Number(parameters['Key 3']),
4: Number(parameters['Key 4']),
5: Number(parameters['Key 5']),
6: Number(parameters['Key 6']),
7: Number(parameters['Key 7']),
8: Number(parameters['Key 8']),
9: Number(parameters['Key 9']),
0: Number(parameters['Key 0']),
minus: Number(parameters['Key -']),
equal: Number(parameters['Key =']),

q: Number(parameters['Key Q (PageUp)']),
w: Number(parameters['Key W (PageDown)']),
e: Number(parameters['Key E']),
r: Number(parameters['Key R']),
t: Number(parameters['Key T']),
y: Number(parameters['Key Y']),
u: Number(parameters['Key U']),
i: Number(parameters['Key I']),
o: Number(parameters['Key O']),
p: Number(parameters['Key P']),
foreBrack: Number(parameters['Key [']),
backBrack: Number(parameters['Key ]']),
backSlash: Number(parameters['Key \\']),

a: Number(parameters['Key A']),
s: Number(parameters['Key S']),
d: Number(parameters['Key D']),
f: Number(parameters['Key F']),
g: Number(parameters['Key G']),
h: Number(parameters['Key H']),
j: Number(parameters['Key J']),
k: Number(parameters['Key K']),
l: Number(parameters['Key L']),
semicolon: Number(parameters['Key ;']),
quote: Number(parameters['Key "']),
enter: Number(parameters['Key Enter (OK)']),

keyShift: Number(parameters['Key Shift (Dash)']),
z: Number(parameters['Key Z (OK)']),
x: Number(parameters['Key X (Cancel)']),
c: Number(parameters['Key C']),
v: Number(parameters['Key V']),
b: Number(parameters['Key B']),
n: Number(parameters['Key N']),
m: Number(parameters['Key M']),
comma: Number(parameters['Key ,']),
period: Number(parameters['Key .']),
foreSlash: Number(parameters['Key /']),

space: Number(parameters['Key Space (OK)']),
dirLeft: Number(parameters['Key Left (Left)']),
dirUp: Number(parameters['Key Up (Up)']),
dirRight: Number(parameters['Key Right (Right)']),
dirDown: Number(parameters['Key Down (Down)']),
ins: Number(parameters['Key Insert (Cancel)']),
del: Number(parameters['Key Delete']),
home: Number(parameters['Key Home']),
end: Number(parameters['Key End']),
pageUp: Number(parameters['Key Page Up (PageUp)']),
pageDown: Number(parameters['Key Page Down (PageDown)']),

num0: Number(parameters['Key NumPad 0 (Cancel)']),
num1: Number(parameters['Key NumPad 1']),
num2: Number(parameters['Key NumPad 2 (Down)']),
num3: Number(parameters['Key NumPad 3']),
num4: Number(parameters['Key NumPad 4 (Left)']),
num5: Number(parameters['Key NumPad 5']),
num6: Number(parameters['Key NumPad 6 (Right)']),
num7: Number(parameters['Key NumPad 7']),
num8: Number(parameters['Key NumPad 8 (Up)']),
num9: Number(parameters['Key NumPad 9']),
numPeriod: Number(parameters['Key NumPad .']),
numPlus: Number(parameters['Key NumPad +']),
numMinus: Number(parameters['Key NumPad -']),
numTimes: Number(parameters['Key NumPad *']),
numDivide: Number(parameters['Key NumPad /'])
}

//=============================================================================
// Input Key Mapper
//=============================================================================
{
if (ButtonCast.keyList['tilde'] !== 0) Input.keyMapper[192] = 'tilde';
if (ButtonCast.keyList['1'] !== 0) Input.keyMapper[49] = '1';
if (ButtonCast.keyList['2'] !== 0) Input.keyMapper[50] = '2';
if (ButtonCast.keyList['3'] !== 0) Input.keyMapper[51] = '3';
if (ButtonCast.keyList['4'] !== 0) Input.keyMapper[52] = '4';
if (ButtonCast.keyList['5'] !== 0) Input.keyMapper[53] = '5';
if (ButtonCast.keyList['6'] !== 0) Input.keyMapper[54] = '6';
if (ButtonCast.keyList['7'] !== 0) Input.keyMapper[55] = '7';
if (ButtonCast.keyList['8'] !== 0) Input.keyMapper[56] = '8';
if (ButtonCast.keyList['9'] !== 0) Input.keyMapper[57] = '9';
if (ButtonCast.keyList['0'] !== 0) Input.keyMapper[48] = '0';
if (ButtonCast.keyList['minus'] !== 0) Input.keyMapper[189] = 'minus';
if (ButtonCast.keyList['equal'] !== 0) Input.keyMapper[187] = 'equal';

if (ButtonCast.keyList['q'] !== 0) Input.keyMapper[81] = 'q';
if (ButtonCast.keyList['w'] !== 0) Input.keyMapper[87] = 'w';
if (ButtonCast.keyList['e'] !== 0) Input.keyMapper[69] = 'e';
if (ButtonCast.keyList['r'] !== 0) Input.keyMapper[82] = 'r';
if (ButtonCast.keyList['t'] !== 0) Input.keyMapper[84] = 't';
if (ButtonCast.keyList['y'] !== 0) Input.keyMapper[89] = 'y';
if (ButtonCast.keyList['u'] !== 0) Input.keyMapper[85] = 'u';
if (ButtonCast.keyList['i'] !== 0) Input.keyMapper[73] = 'i';
if (ButtonCast.keyList['o'] !== 0) Input.keyMapper[79] = 'o';
if (ButtonCast.keyList['p'] !== 0) Input.keyMapper[80] = 'p';
if (ButtonCast.keyList['foreBrack'] !== 0) Input.keyMapper[219] = 'foreBrack';
if (ButtonCast.keyList['backBrack'] !== 0) Input.keyMapper[221] = 'backBrack';
if (ButtonCast.keyList['backSlash'] !== 0) Input.keyMapper[220] = 'backSlash';

if (ButtonCast.keyList['a'] !== 0) Input.keyMapper[65] = 'a';
if (ButtonCast.keyList['s'] !== 0) Input.keyMapper[83] = 's';
if (ButtonCast.keyList['d'] !== 0) Input.keyMapper[68] = 'd';
if (ButtonCast.keyList['f'] !== 0) Input.keyMapper[70] = 'f';
if (ButtonCast.keyList['g'] !== 0) Input.keyMapper[71] = 'g';
if (ButtonCast.keyList['h'] !== 0) Input.keyMapper[72] = 'h';
if (ButtonCast.keyList['j'] !== 0) Input.keyMapper[74] = 'j';
if (ButtonCast.keyList['k'] !== 0) Input.keyMapper[75] = 'k';
if (ButtonCast.keyList['l'] !== 0) Input.keyMapper[76] = 'l';
if (ButtonCast.keyList['semicolon'] !== 0) Input.keyMapper[186] = 'semicolon';
if (ButtonCast.keyList['quote'] !== 0) Input.keyMapper[222] = 'quote';
if (ButtonCast.keyList['enter'] !== 0) Input.keyMapper[13] = 'enter';

if (ButtonCast.keyList['keyShift'] !== 0) Input.keyMapper[16] = 'keyShift';
if (ButtonCast.keyList['z'] !== 0) Input.keyMapper[90] = 'z';
if (ButtonCast.keyList['x'] !== 0) Input.keyMapper[88] = 'x';
if (ButtonCast.keyList['c'] !== 0) Input.keyMapper[67] = 'c';
if (ButtonCast.keyList['v'] !== 0) Input.keyMapper[86] = 'v';
if (ButtonCast.keyList['b'] !== 0) Input.keyMapper[66] = 'b';
if (ButtonCast.keyList['n'] !== 0) Input.keyMapper[78] = 'n';
if (ButtonCast.keyList['m'] !== 0) Input.keyMapper[77] = 'm';
if (ButtonCast.keyList['comma'] !== 0) Input.keyMapper[188] = 'comma';
if (ButtonCast.keyList['period'] !== 0) Input.keyMapper[190] = 'period';
if (ButtonCast.keyList['foreSlash'] !== 0) Input.keyMapper[191] = 'foreSlash';

if (ButtonCast.keyList['space'] !== 0) Input.keyMapper[32] = 'space';
if (ButtonCast.keyList['dirLeft'] !== 0) Input.keyMapper[37] = 'dirLeft';
if (ButtonCast.keyList['dirUp'] !== 0) Input.keyMapper[38] = 'dirUp';
if (ButtonCast.keyList['dirRight'] !== 0) Input.keyMapper[39] = 'dirRight';
if (ButtonCast.keyList['dirDown'] !== 0) Input.keyMapper[40] = 'dirDown';
if (ButtonCast.keyList['ins'] !== 0) Input.keyMapper[45] = 'ins';
if (ButtonCast.keyList['del'] !== 0) Input.keyMapper[46] = 'del';
if (ButtonCast.keyList['home'] !== 0) Input.keyMapper[36] = 'home';
if (ButtonCast.keyList['end'] !== 0) Input.keyMapper[35] = 'end';
if (ButtonCast.keyList['pageUp'] !== 0) Input.keyMapper[33] = 'pageUp';
if (ButtonCast.keyList['pageDown'] !== 0) Input.keyMapper[34] = 'pageDown';

if (ButtonCast.keyList['num0'] !== 0) Input.keyMapper[96] = 'num0';
if (ButtonCast.keyList['num1'] !== 0) Input.keyMapper[97] = 'num1';
if (ButtonCast.keyList['num2'] !== 0) Input.keyMapper[98] = 'num2';
if (ButtonCast.keyList['num3'] !== 0) Input.keyMapper[99] = 'num3';
if (ButtonCast.keyList['num4'] !== 0) Input.keyMapper[100] = 'num4';
if (ButtonCast.keyList['num5'] !== 0) Input.keyMapper[101] = 'num5';
if (ButtonCast.keyList['num6'] !== 0) Input.keyMapper[102] = 'num6';
if (ButtonCast.keyList['num7'] !== 0) Input.keyMapper[103] = 'num7';
if (ButtonCast.keyList['num8'] !== 0) Input.keyMapper[104] = 'num8';
if (ButtonCast.keyList['num9'] !== 0) Input.keyMapper[105] = 'num9';
if (ButtonCast.keyList['numPeriod'] !== 0) Input.keyMapper[110] = 'numPeriod';
if (ButtonCast.keyList['numPlus'] !== 0) Input.keyMapper[107] = 'numPlus';
if (ButtonCast.keyList['numMinus'] !== 0) Input.keyMapper[109] = 'numMinus';
if (ButtonCast.keyList['numTimes'] !== 0) Input.keyMapper[106] = 'numTimes';
if (ButtonCast.keyList['numDivide'] !== 0) Input.keyMapper[111] = 'numDivide';
}

ButtonCast.keysActor = [];

//=============================================================================
// Notetags
//=============================================================================

ButtonCast.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
DataManager.isDatabaseLoaded = function() {
if (!ButtonCast.DataManager_isDatabaseLoaded.call(this)) return false;
DataManager.processBUTTONCASTNotetags1($dataActors);
// DataManager.processBUTTONCASTNotetags2($dataSkills);
return true;
};

DataManager.processBUTTONCASTNotetags1 = function(group) {
// Old way of matching button cast keys
var note2 = /<(?:BUTTONCAST KEYS):[ ](.+)>/i;
for (var n = 1; n < group.length; n++) {
var obj = group[n];
var notedata = obj.note.split(/[\r\n]+/);
for (var i = 0; i < notedata.length; i++) {
var line = notedata;
if (line.match(note2)) {
keys = RegExp.$1.trim().toLowerCase().split(' ').map(String)
ButtonCast.keysActor[n] = keys
}
}
}

// <ButtonCast Key: keyName : skillId>
var note1 = /<(?:BUTTONCAST KEY):[ ](.+):(\d+)>/i;
for (var n = 1; n < group.length; n++) {
// console.log($dataActors[n].name)
ButtonCast.keysActor[n] = [];
var obj = group[n];
var notedata = obj.note.split(/[\r\n]+/);
// console.log(notedata)
for (var i = 0; i < notedata.length; i++) {
var line = notedata;
if (line.match(note1)) {
var keyName = String(RegExp.$1.trim().toLowerCase().split(' '))
var skillId = parseInt(RegExp.$2)
// console.log(keyName, skillId)
// Assign skillId to key
for (k in ButtonCast.keyList) {
if (k.toLowerCase() == keyName.toLowerCase()) {
ButtonCast.keyList[k] = skillId;
}
}
ButtonCast.keysActor[n].push(keyName);
}
}
}
// console.log(ButtonCast.keysActor)
};

//=============================================================================
// Plugin Commands
//=============================================================================
//
// var aliasPluginCommand = Game_Interpreter.prototype.pluginCommand;
// Game_Interpreter.prototype.pluginCommand = function(command, args) {
// aliasPluginCommand.call(this, command, args);
// if (command == 'ButtonCast') {
// switch (args[0]) {
// case 'init':
// break;
// }
// }
// }

//=============================================================================
// ButtonCast Functions
//=============================================================================

// Checks if key is pressed
// Called from BattleManager.checkButtonCast
BattleManager.checkInput = function(args) {
for (var k in args) {
if (Input.isTriggered(String(k))) return k;
}
return null;
};

// Checks inputs and skill bindings to see if actor can button cast
// Called from BattleManager.updateATBTicks
BattleManager.checkButtonCast = function() {
var k = this.checkInput(ButtonCast.keyList)
if (!k) return; // Check if input is valid

var battlers = [];
for (var i = 1; i < ButtonCast.keysActor.length; i++) {
// Check if key assigned to battler
if (ButtonCast.keysActor.length === 0) continue; // Actor has no keys assigned
if (ButtonCast.keysActor.indexOf(k) > -1) {
var actor = $gameActors.actor(i);
if (actor.isBattleMember()) battlers.push(actor);
}
}
// console.log(battlers)

// Check if battler can take action
for (var i = 0; i < battlers.length; i++){
battler = battlers;
if (battler.isATBCharging()) continue; // Action already queued
if (!battler.canInput()) continue; // Check in case of status effects

console.log('Check Skill', battler.name())
var skillId = ButtonCast.keyList[k];

if (!battler.isLearnedSkill(skillId)) { // Check if battler has skill
SoundManager.playBuzzer();
continue;
}

console.log('Skill:', skillId);
console.log('');

battler.clearActions();
var action = new Game_Action(battler);
action.setSkill(skillId);
if (!action.isValid()) continue; // Check if action is valid
battler._actions.push(action);
this.buttonCastBattlers.push(battler);
}
};

// Prepare the actor for action and target selection
// Called from BattleManager.updateATBTicks
BattleManager.prepareButtonCast = function() {
this.buttonCastBattler = this.buttonCastBattlers.shift();
var battler = this.buttonCastBattler;
console.log('Prepare Action', battler.name());
console.log('');
this.playATBReadySound();
battler.spriteStepForward();
battler.requestMotionRefresh();
battler.setATBSpeed(this.atbTarget());
battler.setupATBCharge();
this.statusUpdateATB();
this._actorIndex = battler.index();

var action = this.inputtingAction();
if (action.needsSelection()) {
console.log('Select Target', battler.name());
console.log('');
SceneManager._scene.onSelectAction();
}
}

// Reset battler atb and actions
// Called from Scene_Battle.onActorCancel and Scene_Battle.onEnemyCancel
BattleManager.cancelButtonCast = function(){
battler = this.buttonCastBattler;
console.log('Cancel Selection', battler.name())
console.log('');
battler.spriteStepBack();
battler.requestMotionRefresh();
}

//=============================================================================
// Yanfly Overrides
//=============================================================================

BattleManager.buttonCastBattlers = [];
ButtonCast.BattleManager_updateATBTicks = BattleManager.updateATBTicks
BattleManager.updateATBTicks = function() {
if (SceneManager._scene.isAnyInputWindowActive()) return;
this.buttonCastBattler = undefined;
if (this.buttonCastBattlers.length === 0) this.checkButtonCast();
if (this.buttonCastBattlers.length > 0) return this.prepareButtonCast();
ButtonCast.BattleManager_updateATBTicks.call(this);
};

// if (this.seCooldown) this.seCooldown -= 1;

//=============================================================================
// Debugging and References
//=============================================================================

// Some of this code from Yanfly's BattleEngine v1.32
ButtonCast.Scene_Battle_onActorCancel = Scene_Battle.prototype.onActorCancel
Scene_Battle.prototype.onActorCancel = function() {
if (eval(Yanfly.Param.BECSelectHelp)) this._helpWindow.hide();
this._helpWindow.clear();
if (BattleManager.buttonCastBattler) {
this._actorWindow.hide();
BattleManager.cancelButtonCast();
} else {
ButtonCast.Scene_Battle_onActorCancel.call(this);
}
BattleManager.stopAllSelection();
BattleManager.clearInputtingAction();
};

// Some of this code from Yanfly's BattleEngine v1.32
ButtonCast.Scene_Battle_onEnemyCancel = Scene_Battle.prototype.onEnemyCancel
Scene_Battle.prototype.onEnemyCancel = function() {
if (eval(Yanfly.Param.BECSelectHelp)) this._helpWindow.hide();
this._helpWindow.clear();
if (BattleManager.buttonCastBattler) {
this._enemyWindow.hide();
BattleManager.cancelButtonCast();
} else {
ButtonCast.Scene_Battle_onEnemyCancel.call(this);
}
BattleManager.stopAllSelection();
BattleManager.clearInputtingAction();
};

// Window_BattleEnemy.prototype.select = function(index) {
// Window_Selectable.prototype.select.call(this, index);
// $gameTroop.select(this.enemy());
// if(BattleManager.buttonCastBattler) console.log(this.enemy().name());
// };


}; // Leave this alone




Fixes bug where checkButtonCast() crashes if an actor has no key assignments 


Added new actor notetag format <ButtonCast Key: keyName:skillId>
 
Last edited by a moderator:

BucketsOfRP

Veteran
Veteran
Joined
Feb 15, 2016
Messages
13
Reaction score
1
First Language
Polish
Primarily Uses
Oi, you can have the demo out - I'd rather it benefit everyone who needs it.


I'll make sure to check your update once I come back from work. 


And, I'd love to work on a game together. The more, the merrier.
 

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
While trying to think of a solution for creating a button based ATB charging skill I came up with a really eloquent solution that opens the door to a whole number of possibilities.In essence, I've created passive skills.


All we do is put <ButtonCast Skill: passive> in the skill notetag which identifies it as passive. Then in effect we add a common event. Now when my checkButtonCast function runs it determines if the skill is passive and if so it's going to run the common event instead of processing the action.


Now in the common event I can do stuff like charge the ATB gauge up. But who knows what else we can do with passive skills, it's got a lot of potential for using button events in battle.
 
Last edited by a moderator:

gilgamar

Veteran
Veteran
Joined
Jan 28, 2016
Messages
132
Reaction score
59
First Language
English
Primarily Uses
 * Version 1.06a:
 * - Added passive skills (experimental)
 * - Added skill notetag <ButtonCast Skill: passive>
 * - Passive skills execute their common events immediately without taking a turn
 * - Fixed a bug where checkButtonCast() would crash if an actor had no keys assigned
 * - Automatically corrects key names when parsing notetags
 * - Automatically swaps system keys with button cast keys to preserve original bindings
 * - Added actor notetag <ButtonCast Key: keyName:skillId>
 * - Removed parameters and previous actor notetag


This version is still in the works as passive skills are very buggy and experimental.
 

RogdagoR

Veteran
Veteran
Joined
Oct 1, 2015
Messages
134
Reaction score
32
First Language
Italian
Does this work also with CTB? I'm looking for a plugin where i can set 4-5 keys for skills, 1 key for items and 1 for "guard"(that i will use for skip turn), and those keys are the same for each actor, since they have theyr turn order given by CTB.


Also looks cool if you can do a menu for bind skills.
 

aramouta

Villager
Member
Joined
Jan 20, 2019
Messages
16
Reaction score
3
First Language
arabic
Primarily Uses
RMMV
Can you Upload the Demo please, the link is dead...
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Are we allowed to post about non-RPG Maker games? And, if so, would any of you be interested in a short, proof of concept type non-euclidian puzzle game?
I should realize that error was produced by a outdated version of MZ so that's why it pop up like that
Ami
i can't wait to drink some ice after struggling with my illness in 9 days. 9 days is really bad for me,i can't focus with my shop and even can't do something with my project
How many hours have you got in mz so far?

A bit of a "sparkle" update to the lower portion of the world map. :LZSexcite:

Forum statistics

Threads
105,883
Messages
1,017,232
Members
137,607
Latest member
Maddo
Top