Skip to content
Permalink
master
Go to file
 
 
Cannot retrieve contributors at this time
4479 lines (4152 sloc) 140 KB
//=============================================================================
// QABS
//=============================================================================
var Imported = Imported || {};
if (!Imported.QMovement || !QPlus.versionCheck(Imported.QMovement, '1.4.0')) {
alert('Error: QABS requires QMovement 1.4.0 or newer to work.');
throw new Error('Error: QABS requires QMovement 1.4.0 or newer to work.');
}
Imported.QABS = '1.7.0';
//=============================================================================
/*:
* @plugindesc <QABS>
* Action Battle System for QMovement
* @version 1.7.0
* @author Quxios | Version 1.7.0
* @site https://quxios.github.io/
* @updateurl https://quxios.github.io/data/pluginsMin.json
*
* @repo https://github.com/quxios/QABS
*
* @requires QMovement
*
* @video TODO
*
* @param Attack Settings
*
* @param Quick Target
* @parent Attack Settings
* @desc Ground target skills will instantly cast at mouse location
* @type Boolean
* @default false
*
* @param Lock when Targeting
* @parent Attack Settings
* @desc Player can't move when using Ground / Select targeting skills
* @type Boolean
* @on Can't Move
* @off Can Move
* @default false
*
* @param Aim with Mouse
* @parent Attack Settings
* @desc All actions will be used towards your mouse location
* @type Boolean
* @on Towards mouse
* @off Towards player direction
* @default false
*
* @param Aim with Analog
* @parent Attack Settings
* @desc All actions will be used towards right analog stick when using a
* gamepad.
* @type Boolean
* @on Towards right analog
* @off Towards player direction
* @default false
*
* @param Move Resistance Rate Stat
* @parent Attack Settings
* @desc Which stat to use for Move Resistance Rate
* Default: xparam(1) // This is Evasion
* @default xparam(1)
*
* @param Loot Settings
*
* @param Loot Decay
* @parent Loot Settings
* @desc How long until the loot disappears, in frames.
* @type Number
* @min 1
* @default 600
*
* @param AoE Loot
* @parent Loot Settings
* @desc Collect nearby loot or pick up one at a time.
* @type Boolean
* @default true
*
* @param Loot Touch Trigger
* @parent Loot Settings
* @desc Pick up loot on player touch
* @type Boolean
* @default false
*
* @param Gold Icon
* @parent Loot Settings
* @desc Icon Index to display for gold loot
* Default: 314
* @default 314
*
* @param Level Animation
* @parent Loot Settings
* @desc The animation ID to play on level up.
* Default: 52
* @type Animation
* @default 52
*
* @param Enemy AI
*
* @param AI Default Sight Range
* @parent Enemy AI
* @desc Default range for enemies to go after player, in pixels
* Default: 240
* @type Number
* @min 1
* @default 240
*
* @param AI Action Wait
* @parent Enemy AI
* @desc How many frames to wait before running AI for next skill
* Default: 30
* @min 1
* @default 30
*
* @param AI Uses QSight
* @parent Enemy AI
* @desc Set to true or false if AI should use QSight
* May decrease performance
* @type Boolean
* @default true
*
* @param AI uses QPathfind
* @parent Enemy AI
* @desc Set to true or false if AI should use QPathfind
* May decrease performance
* @type Boolean
* @default true
*
* @param Default Skills
* @type Struct<SkillKey>[]
* @default []
*
* @help
* ============================================================================
* ## About
* ============================================================================
* A collider based action battle system for QMovement. *Note* This is not
* your simple rpg maker action battle system. Using this plugin you can
* create more advance like action games.
*
* For a demo visit the steamwork shop or Github repo
* - http://steamcommunity.com/sharedfiles/filedetails/?id=952886994
* - https://github.com/quxios/QMV-ABS-Demo
*
* **_Plugin files in the repo are always kept up to date_**
* ============================================================================
* ## Is this for you?
* ============================================================================
* First, this is a very complex action battle system. If you're looking for
* something that you can spend less than an hour to set up then this plugin
* is not for you.
*
* To make full use of this plugin you need to know how to properly use and
* setup QMovement. If you don't know what that plugin is or what colliders
* are then again, this plugin is not for you.
*
* There are a lot of actions for skill sequences so you can create some pretty
* crazy skills. Learning how to use the actions may take awhile since there
* are a lot of actions, and maybe more to come.
*
* Enemies have a very basic AI. If you want to create more AI styles, you
* will need to know how to JS and create a plugin / extend this plugin.
* ============================================================================
* ## Skill Keys
* ============================================================================
* **Default Skill keys**
* ----------------------------------------------------------------------------
* For the player to be able to use a skill from a hotkey, you will first need
* to create a skill key in the plugin parameter `Default Skills`.
*
* ![Skill Keys](https://quxios.github.io/imgs/qabs/skillKeys.png)
*
* When creating a skill key you have 4 parameters:
*
* - #### Keyboard Input:
* * The keyboard input that will trigger this skill, set this to `mouse1` for
* left click, and `mouse2` for right click.
* - #### Gamepad Input:
* * The gamepad input that will trigger this skill.
* - #### Rebind:
* * If this is true, the skill that's assigned to this skill key can be
* reassigned.
* - #### Skill Id:
* * The skill that this skill key will use when triggered.
*
* **_Note_** for input values those are the button values; `ok`, `cancel`, ect. Or
* if you're using an input plugin, use their value. For example in QInput you can
* use the `#A` for the a key or `#tab` for tab, ect.
*
* **_Note_** that rebind doesn't do much as this doesn't have a rebinding feature.
* But the ground work is there so it can easily be created for an addon.
*
* **_Note_** that the `Skill Key Number` is the number next to the skill key you created.
* `Skill Key Number` will be referenced later.
*
* ![Skill Keys](https://quxios.github.io/imgs/qabs/skillKeysNumber.png)
*
* ----------------------------------------------------------------------------
* **Class Skill keys**
* ----------------------------------------------------------------------------
* You can change the players skill keys based on their class by adding the notetag:
* ~~~
* <skillKeys>
* [SKILL KEY NUMBER]: [SKILL ID] [REBIND?]
* </skillKeys>
* ~~~
* - #### SKILL KEY NUMBER:
* * The skill key that you want to change
* - #### SKILL ID:
* * The skill to assign to this skill key number
* - #### REBIND?:
* * Set to true or false if this can be reassigned
*
* If the skill key that you are trying to change has its `Rebind` value set to false,
* nothing will happen since it can't be reassigned.
*
* **_Important!_** make sure the skill key you are trying to set is created in the
* plugin parameters `Default Skills`. If it's not, the game will have an error.
*
* Example:
* ~~~
* <skillKeys>
* 1: 2
* 3: 15
* 4: 16
* </skillKeys>
* ~~~
* Class Skill keys will replace the default skill keys. So if you set up skill
* keys 1 through 9 in the parameters and a class changes the skills for skill
* keys 1, 3, 4. The over all skill keys will be, 1, 3, 4 from the class and
* the rest are from the default values.
*
* ----------------------------------------------------------------------------
* **Weapon Skill keys**
* ----------------------------------------------------------------------------
* Weapons can also change the skill keys. For example you might want to change
* the main attack to use a range skill if the player has a bow equipped! To do
* this you use a similar tag as the class, but in the weapon
* ~~~
* <skillKeys>
* [SKILL KEY NUMBER]: [SKILL ID]
* </skillKeys>
* ~~~
* - #### SKILL KEY NUMBER:
* * The skill key that you want to change
* - #### SKILL ID:
* * The skill to assign to this skill key number
*
* **_Important!_** make sure the skill key you are trying to set is created in the
* plugin parameters `Default Skills`. If it's not, the game will have an error.
*
* Example:
* ~~~
* <skillKeys>
* 1: 3
* </skillKeys>
* ~~~
* Weapon skill keys take top priority, so they will replace both class keys
* and the default keys! This example will replace skill key 1 with the skill
* id 3
*
* ----------------------------------------------------------------------------
* **Override Skill keys**
* ----------------------------------------------------------------------------
* You can manually override a skill key with a plugin command. Override skill keys
* take priority over weapon, class and default skill keys.
*
* Plugin command:
* ~~~
* qabs override SKILLKEYNUMBER SKILLID
* ~~~
* - #### SKILLKEYNUMBER:
* * The skill key that you want to change
* - #### SKILLID:
* * The skill to assign to this skill key number. Set to -1 if you want to
* remove this override
*
* **_Important!_** make sure the skill key you are trying to set is created in the
* plugin parameters `Default Skills`. If it's not, the game will have an error.
*
* **_Note_** that the player still needs to know the skill to be able to use it.
* Assigning it won't let him use it if he doesn't know it.
*
* Example:
* ~~~
* qabs override 1 3
* ~~~
* Will override skill key 1 and assign the skill with id 3. To remove this
* override later on use the plugin command:
* ~~~
* qabs override 1 -1
* ~~~
*
* ============================================================================
* ## Skills
* ============================================================================
* **Skill Settings**
* ----------------------------------------------------------------------------
* Each skill should have a skill settings tag. This tag can change the settings
* for the skills cooldown, through, and other effects. The tag is:
* ~~~
* <absSettings>
* [SETTINGS]: [VALUE]
* </absSettings>
* ~~~
* Here's a list of all the settings:
* ~~~
* collider: [SHAPE], [WIDTH], [HEIGHT]
* collides: [STRING]
* cooldown: [NUMBER]
* infront: [TRUE or FALSE]
* rotate: [TRUE or FALSE]
* through: [0, 1, 2 or 3]
* throughTerrain: [LIST OF TERRAINS IT CAN GO THROUGH]
* groundtarget: [NUMBER]
* selecttarget: [NUMBER]
* ~~~
* - #### collider:
* * Set this to the collider this skill will use. See QMovement help for details
* on colliders.
* * Default: The users collider
* * Format is: `shape, width, height`
* - #### collides:
* * Set this to which collider type to check for against skill hit. If you
* want to use a custom collider, use the `<colliders></colliders>` tag
* * Default: collision
* - #### cooldown:
* * Set to the number of frames until you can use this skill again.
* * Default: 0
* - #### infront:
* * Set to true or false. When true, the collider will appear in front of the user.
* When false the collider will be centered on the user.
* * Default: false
* - #### rotate:
* * Set to true or false. When true, the collider will rotate based on the users
* direction when skill is starting. Default: false
* - #### through:
* * Set to 0, 1, 2, or 3. Default: 0
* - 0: Goes through events and tiles
* - 1: Goes through tiles but stops when it hits an event
* - 2: Goes through events but stops when it hits a tile
* - 3: Stops when it hits an event or tile
* - #### throughTerrain:
* * Set to a list of tile terrains it can go through, separate each terrain with a comma
* - #### groundtarget:
* * Set to the max distance, in pixels, for the ground target. If value is 0 ground
* targeting will not be used.
* * Default: 0
* - #### selecttarget:
* * Set to the max distance, in pixels, for the select target. If value is 0 select
* targeting will not be used.
* * Default: 0
* ----------------------------------------------------------------------------
* **Skill Sequence**
* ----------------------------------------------------------------------------
* When a skill is used, it's sequence will run. You will need to configure
* a sequence to tell the skill what it should do or it won't do anything.
*
* This can be done with the notetag:
* ~~~
* <absSequence>
* [ACTION]
* </absSequence>
* ~~~
* There are a bunch of actions. Each action needs to be on a different line.
*
* Here's a list of all the actions:
* ~~~
* user casting [TRUE or FALSE]
* user lock
* user unlock
* user speed [INC or DEC] [VALUE]
* user move [FORWARD or BACKWARD] [DIST] [WAIT? TRUE or FALSE]
* user moveHere [WAIT? TRUE or FALSE]
* user jump [FORWARD or BACKWARD] [DIST] [WAIT? TRUE or FALSE]
* user jumpHere [WAIT? TRUE or FALSE]
* user teleport
* user setDirection [DIR]
* user directionFix [TRUE or FALSE]
* user pose [POSE NAME] [WAIT? TRUE or FALSE]
* user forceSkill [SKILL ID] [ANGLE OFFSET IN DEGREES]
* user animation [ANIMATION ID]
* user qaudio [NAME] [QAUDIO OPTIONS]
* store
* move [FORWARD or BACKWARD] [DIST] [DURATION] [WAIT? TRUE or FALSE]
* moveToStored [DURATION] [WAIT? TRUE or FALSE]
* wave [FORWARD or BACKWARD] [AMPLITUDE] [HARM] [DIST] [DURATION] [WAIT? TRUE or FALSE]
* waveToStored [AMPLITUDE] [HARM] [DURATION] [WAIT? TRUE or FALSE]
* trigger
* adjustAim
* wait [DURATION]
* picture [FILE NAME] [ROTATABLE? TRUE or FALSE] [BASE DIRECTION]
* trail [FILE NAME] [ROTATABLE? TRUE or FALSE] [BASE DIRECTION]
* collider [SHOW or HIDE]
* animation [ANIMATION ID]
* se [NAME] [VOLUME] [PITCH] [PAN]
* qaudio [NAME] [QAUDIO OPTIONS]
* forceSkill [SKILL ID] [ANGLE OFFSET IN DEGREES]
* globalLock
* globalUnlock
* ~~~
* - #### user casting [TRUE or FALSE]
* * Set the user casting state. If the user is casting, this skill can be
* ended early if they get hit with a skill that has `user cancel` in it's
* `absOnDamage`
*
* - #### user lock
* * Locks the users movement. The user can't move or use any actions until
* `user unlock` is called.
* * `user unlock` is called automatically after every skill ends to ensure
* the user can move again if the skill ended.
*
* - #### user unlock
* * Unlocks the users movement. The user is unlocked if it was locked and can
* move and use actions again.
* * `user unlock` is called automatically after every skill ends to ensure
* the user can move again if the skill ended.
*
* - #### user speed [INC or DEC] [VALUE]
* * Changes the users move speed.
* * INC or DEC:
* - Set to `inc` to increase movespeed
* - Set to `dec` to decrease move speed
* * VALUE: Set to a number to inc or dec the movespeed by.
*
* - #### user move [FORWARD or BACKWARD] [DIST] [WAIT? TRUE or FALSE]
* * The user will move forward or backwards by X distance.
* * FORWARD or BACKWARD:
* - Set to `forward` to move towards the direction the user is facing
* - Set to `backward` to move towards the opposite direction the user is facing
* * DIST: Set to the distance the user should move, in pixels
* * WAIT: Set to `true` or `false`. If true the sequencer will wait until the move
* is complete before going to the next action
*
* - #### user moveHere [WAIT? TRUE or FALSE]
* * The user will move to the skills current location
* * WAIT: Set to `true` or `false`. If true the sequencer will wait until the move
* is complete before going to the next action
*
* - #### user jump [FORWARD or BACKWARD] [DIST] [WAIT? TRUE or FALSE]
* * The user will jump forward or backwards by X distance.
* * FORWARD or BACKWARD:
* - Set to `forward` to jump towards the direction the user is facing
* - Set to `backward` to jump towards the opposite direction the user is facing
* * DIST: Set to the distance the user should jump, in pixels
* * WAIT: Set to `true` or `false`. If true the sequencer will wait until the jump
* is complete before going to the next action
*
* - #### user jumpHere [WAIT? TRUE or FALSE]
* * The user will jump to the skills current location
* * WAIT: Set to `true` or `false`. If true the sequencer will wait until the jump
* is complete before going to the next action
*
* - #### user teleport
* * The user will be placed at the skills current location. Similar to an
* event transfer command.
*
* - #### user setDirection [DIR]
* * Change the users direction
* * DIR: Set to: 2, 4, 6 or 8. For diagonals; 1, 3, 7, or 9
*
* - #### user directionFix [TRUE or FALSE]
* * Sets the users direction fix.
* * TRUE or FALSE: Set to `true` or `false`. When true the users direction can't change
*
* - #### user pose [POSE NAME] [WAIT? TRUE or FALSE]
* * **_Requires QSprite plugin_**
* * If the user is a QSprite, it will play the pose
* * POSE NAME: The pose to play
* * WAIT: Set to `true` or `false`. If true the sequencer will wait until the pose
* is done playing before going to the next action
*
* - #### user forceSkill [SKILL ID] [ANGLE OFFSET IN DEGREES]
* * Forces the user to use a skill.
* * SKILL ID: The ID of the skill to use
* * ANGLE OFFSET: Lets you offset the angle, in degrees, that this skill be used
* towards. This is optional and can be left out.
* - Default: 0
*
* - #### user animation [ANIMATION ID]
* * Plays an animation on the user
* * ANIMATION ID: The ID of the animation to play
*
* - #### user qaudio [NAME] [QAUDIO OPTIONS]
* * **_Requires QAudio plugin_**
* * Binds a QAudio to the user
* * NAME: The name of the audio file to use
* * QAUDIO OPTIONS: any of the QAudio options besides; xX, yY, bindToCHARAID.
* View QAudio help for more details
*
* - #### store
* * Stores the skills current location. This location value is used when
* the actions `moveToStored` or 'waveToStored' are used.
*
* - #### move [FORWARD or BACKWARD] [DIST] [DURATION] [WAIT? TRUE or FALSE]
* * Moves the skill forward or backwards by X dist in Y frames
* * FORWARD or BACKWARD:
* - Set to `forward` to move towards the direction the skill is currently moving
* - Set to `backward` to move towards the opposite direction the skill is current moving
* * DIST: The distance you want the skill to move, in pixels.
* * DURATION: How long should it take to complete this move, in frames.
* * WAIT: Set to `true` or `false`. If true the sequencer will wait until the skill
* is done moving before going to the next action
*
* - #### moveToStored [DURATION] [WAIT? TRUE or FALSE]
* * Moves the skill to the stored position
* * DURATION: How long should it take to complete this move, in frames.
* * WAIT: Set to `true` or `false`. If true the sequencer will wait until the skill
* is done moving before going to the next action
*
* - #### wave [FORWARD or BACKWARD] [AMPLITUDE] [HARM] [DIST] [DURATION] [WAIT? TRUE or FALSE]
*
* - #### waveToStored [AMPLITUDE] [HARM] [DURATION] [WAIT? TRUE or FALSE]
*
* - #### trigger
* * Activates the skill at it's current location
*
* - #### adjustAim
* * Recalculates the direction the skill should move. This is only works
* when the skill is used from an enemy.
*
* - #### wait [DURATION]
* * The sequencer will wait before moving to the next action
* * DURATION: How long should the wait last, in frames
*
* - #### picture [FILE NAME] [ROTATABLE? TRUE or FALSE] [BASE DIRECTION]
* * Bind a picture to the skill
* * FILE NAME: The file name of the picture. Should be located in the
* Pictures folder. For an animated picture it should have the format:
* - %[COLS-SPEED]
* - COLS: The number of slices in the picture
* - SPEED: The time to wait between frames
* * ROTATABLE: Set to `true` or `false`. If true the picture will rotate based
* on the direction the skill is moving
* * BASE DIRECTION: The direction the skill is facing by default. The directions
* should be 2, 4, 6, or 8
*
* - #### trail [FILE NAME] [ROTATABLE? TRUE or FALSE] [BASE DIRECTION]
* * Binds a picture that stretches from the user to the skills position
* * FILE NAME: The file name of the picture. Should be located in the
* Pictures folder.
* * ROTATABLE: Set to `true` or `false`. If true the picture will rotate based
* on the direction the skill is moving
* * BASE DIRECTION: The direction the skill is facing by default. The directions
* should be 2, 4, 6, or 8
*
* - #### collider [SHOW or HIDE]
* * Shows the skills collider
* * SHOW or HIDE:
* - Set to `show` to show the skills collider
* - Set to `hide` to hide the skills collider
*
* - #### animation [ANIMATION ID]
* * Play an animation at the skills current location
* * ANIMATION ID: The ID of the animation to play
*
* - #### se [NAME] [VOLUME] [PITCH] [PAN]
* * Play an se
* * NAME: The name of the SE to play
* * VOLUME: The volume of the SE, default: 90
* * PITCH: The pitch of the SE, default: 100
* * PAN: The pan of the SE, default: 0
*
* - #### qaudio [NAME] [QAUDIO OPTIONS]
* * Play a qAudio at the skills location
* * NAME: The name of the audio file
* * QAUDIO OPTIONS: Visit the QAudio help for information. The options
* are the same from the plugin commands. x, y, bindTo options will not work.
*
* - #### forceSkill [SKILL ID] [ANGLE OFFSET]
* * Force a skill at the skills current location
* * SKILL ID: The ID of the skill to use
* * ANGLE OFFSET: Lets you offset the angle, in degrees, this skill be used towards.
* This is optional and can be left out.
*
* - #### globalLock
* * Locks all characters movement
*
* - #### globalUnlock
* * Unlocks all characters movement
*
* ----------------------------------------------------------------------------
* **Skill On Damage**
* ----------------------------------------------------------------------------
* Whenever a skill hits a target you can run another sequence. This is done
* by using the notetag:
* ~~~
* <absOnDamage>
* [ACTION]
* </absOnDamage>
* ~~~
* There are a few actions you can add here:
* ~~~
* target move [TOWARDS or AWAY or INTO] [DIST]
* target jump [TOWARDS or AWAY or INTO] [DIST]
* target pose [POSE]
* target cancel
* target qaudio [NAME] [QAUDIO OPTIONS]
* user forceSkill [SKILL ID] [ANGLE OFFSET IN DEGREES]
* animationTarget [0 or 1]
* ~~~
* - #### target move [TOWARDS or AWAY or INTO] [DIST]
* * The target will move X distance.
* * TOWARDS or AWAY or INTO:
* - Set to `towards` to move towards the user of the skill
* - Set to `away` to move away from the user of the skill
* - Set to `into` to move towards the skill center
* * DIST: Set to the distance the target should move, in pixels
*
* - #### target jump [TOWARDS or AWAY or INTO] [DIST]
* * The target will jump X distance.
* * TOWARDS or AWAY or INTO:
* - Set to `towards` to jump towards the user of the skill
* - Set to `away` to jump away from the user of the skill
* - Set to `into` to jump towards the skill position
* * DIST: Set to the distance the target should jump, in pixels
*
* - #### target pose [POSE]
* * **_Requires QSprite plugin_**
* * If the target is a QSprite, it will play the pose
* * POSE NAME: The pose to play
*
* - #### target cancel
* * If the target is `casting`, it will cancel the skill
*
* - #### target qaudio [NAME] [QAUDIO OPTIONS]
* * **_Requires QAudio plugin_**
* * Binds a QAudio to the target
* * NAME: The name of the audio file to use
* * QAUDIO OPTIONS: any of the QAudio options besides; xX, yY, bindToCHARAID.
* View QAudio help for more details
*
* - #### user forceSkill [SKILL ID] [ANGLE OFFSET IN DEGREES]
* * Forces the user to use a skill.
* * SKILL ID: The ID of the skill to use
* * ANGLE OFFSET: Lets you offset the angle, in degrees, that this skill be used
* towards. This is optional and can be left out.
* - Default: 0
*
* - #### animationTarget [0 or 1]
* * Sets where to play the skill animation
* * 0 or 1:
* - When 0, the animation will play at the current location.
* Animation will only play once if the skill hit multiple targets
* - When 1, the animation will play on the target
* Animation will play on all targets it hits
*
* ============================================================================
* ## Enemies
* ============================================================================
* **Event**
* ----------------------------------------------------------------------------
* To mark an event as an enemy, add the notetag to the event
* ~~~
* <enemy:X>
* ~~~
* Where X is the ID of the enemy in the database.
*
* ----------------------------------------------------------------------------
* **Enemy Database**
* ----------------------------------------------------------------------------
* #### To set the enemies respawn time
* ~~~
* <respawn:X>
* ~~~
* - X: How long until it respawns, in frames.
*
* #### To change the team of the enemy
* ~~~
* <team:X>
* ~~~
* Set X to the team number
* - 0: Neutral
* - 1: Player team
* - 2: Enemy team
* - 3+ can also be used
*
* **_Note_** teams don't do much because there is no team based AI
*
* #### To set an Enemies AI type
* ~~~
* <AIType:TYPE>
* ~~~
* - TYPE: The AI type, set this to `none` to disable AI.
*
* **_Note_** There's only 1 type of AI, so for now that AI is only to disable AI
*
* #### To set it's AI range
* ~~~
* <range:X>
* ~~~
* - X: The range in pixels
*
* #### To disable damage popups on this enemy
* ~~~
* <noPopup>
* ~~~
*
* #### To add an offset to the popup's y use:
* ~~~
* <popupOY:Y>
* ~~~
* - Y: The y offset in pixels, can be negative
*
* #### To keep the event around after it dies
* ~~~
* <dontErase>
* ~~~
*
* #### To run some JS when the enemy dies
* ~~~
* <onDeath>
* javascript code
* </onDeath>
* ~~~
*
* #### To auto gain the enemies loot
* ~~~
* <autoLoot>
* ~~~
*
* ============================================================================
* ## Disabling QABS
* ============================================================================
* You can disable the QABS or disable certain events with a plugin command.
*
* #### To disable the QABS for everything use the plugin command
* ~~~
* qabs disable
* ~~~
*
* #### To re-enable use the plugin command:
* ~~~
* qabs enable
* ~~~
*
* #### To disable certain event(s) use the plugin command
* ~~~
* qabs disable [LIST OF CHARAIDS TO DISABLE]
* ~~~
* - CHARAID: The character identifier.
* * For events: EVENTID, eEVENTID, eventEVENTID or this for the event that
* called this (replace EVENTID with a number)
*
* Where each CHARAID is separated with a space. CHARAID can only be for events.
*
* #### Example:
* ~~~
* qabs disable event1 e2 4
* ~~~
* Will disable events 1, 2 and 4. Used different types of CHARAIDs as an example
* but you can use whichever one you like
*
* #### To re-enable event(s) use the plugin command
* ~~~
* qabs enable [LIST OF CHARAIDS TO DISABLE]
* ~~~
*
* **_Note_** that disabling ABS doesn't remove it from the event, it just "pauses"
* it until it's re-enabled.
*
* ============================================================================
* ## States
* ============================================================================
* To have a state affect the characters move speed use:
* ~~~
* <moveSpeed:X>
* ~~~
* Set X to the value to modify the move speed by. Can be negative.
*
* To disable a characters actions, use the following notetag. When disabled
* the character can't use any skills until the state is removed.
* ~~~
* <stun>
*
* ~~~
* ============================================================================
* ## Popups
* ============================================================================
* All of the popups are powered with the QPopup plugin. If you want to change
* any styles of the popups you can edit their presets in that plugins parameters
* or using the plugin commands from the QPopup plugin.
*
* The following are the qPopup presets this ABS uses:
* - QABS-LEVEL
* - QABS-EXP
* - QABS-ITEM
* - QABS-MISSED
* - QABS-DMG
* - QABS-DMG-CRIT
* - QABS-HEAL
* - QABS-HEAL-CRIT
* - QABS-MP
* - QABS-MP-CRIT
*
* ============================================================================
* ## Showcase
* ============================================================================
* This section is for user created stuff. If you created a video, game, tutorial,
* or an addon for QABS feel free to send me a link and I'll showcase it here!
*
* ============================================================================
* ## Links
* ============================================================================
* Formated Help:
*
* https://quxios.github.io/plugins/QABS
*
* RPGMakerWebs:
*
* http://forums.rpgmakerweb.com/index.php?threads/qplugins.73023/
*
* Terms of use:
*
* https://github.com/quxios/QMV-Master-Demo/blob/master/readme.md
*
* Like my plugins? Support me on Patreon!
*
* https://www.patreon.com/quxios
*
* @tags QM-Addon, ABS, Battle
*/
/*~struct~SkillKey:
* @param Keyboard Input
* @desc Set to which keyboard input to use for this skill
* @default
*
* @param Gamepad Input
* @desc Set to which gamepad input to use for this skill
* @default
*
* @param Rebind
* @desc Can this skill be reassigned?
* @type Boolean
* @on Yes
* @off No
* @default true
*
* @param Skill Id
* @desc Which skill does this skill use
* @type skill
* @default
*/
//=============================================================================
//=============================================================================
// QABS Static Class
function QABS() {
throw new Error('This is a static class');
}
(function() {
var _PARAMS = QPlus.getParams('<QABS>', {
'Default Skills': []
});
QABS.quickTarget = _PARAMS['Quick Target'];
QABS.lockTargeting = _PARAMS['Lock when Targeting'];
QABS.towardsMouse = _PARAMS['Aim with Mouse'];
QABS.towardsAnalog = _PARAMS['Aim with Analog']
QABS.radianAtks = QMovement.offGrid;
QABS.lootDecay = _PARAMS['Loot Decay'];
QABS.aoeLoot = _PARAMS['AoE Loot'];
QABS.lootTrigger = _PARAMS['Loot Touch Trigger'] ? 2 : 0;
QABS.goldIcon = _PARAMS['Gold Icon'];
QABS.levelAni = _PARAMS['Level Animation'];
QABS.showDmg = _PARAMS['Show Damage'];
QABS.mrst = _PARAMS['Move Resistance Rate Stat'];
QABS.aiLength = _PARAMS['AI Default Sight Range'];
QABS.aiWait = _PARAMS['AI Action Wait'];
QABS.aiSight = _PARAMS['AI Uses QSight'];
QABS.aiPathfind = _PARAMS['AI uses QPathfind'];
QABS.getDefaultSkillKeys = function() {
var obj = {};
var skills = _PARAMS['Default Skills'];
for (var i = 0; i < skills.length; i++) {
var skill = skills[i];
obj[i + 1] = {
input: [skill['Keyboard Input'].trim(), skill['Gamepad Input'].trim()],
rebind: skill.Rebind,
skillId: skill['Skill Id']
}
}
return obj;
};
QABS.skillKey = QABS.getDefaultSkillKeys();
QABS.stringToSkillKeyObj = function(string) {
var obj = QPlus.stringToObj(string);
for (var key in obj) {
var data = String(obj[key]).split(' ').filter(function(i) {
return i !== '';
}).map(function(i) {
return i.trim();
});
var skillId = Number(data[0]) || 0;
var rebind = data[1] === 'true';
var msg;
if (skillId && !$dataSkills[skillId]) {
msg = 'ERROR: Attempted to apply a Skill Id that does not exist in database.\n';
msg += 'Skill Key Number: ' + key;
alert(msg);
delete obj[key];
continue;
}
if (!QABS.skillKey[key]) {
msg = 'ERROR: Attempted to apply a skill key that has not been setup ';
msg += 'in the plugin parameters.\n';
msg += 'Skill Key Number: ' + key;
alert(msg);
delete obj[key];
continue;
}
obj[key] = {
input: QABS.skillKey[key].input.clone(),
skillId: skillId,
rebind: rebind
}
}
return obj;
};
QABS._skillSettings = {};
QABS.getSkillSettings = function(skill) {
if (!this._skillSettings.hasOwnProperty(skill.id)) {
var settings = skill.qmeta.absSettings;
this._skillSettings[skill.id] = {
cooldown: 0,
through: 0,
groundTarget: false,
selectTarget: false,
throughTerrain: []
}
if (settings) {
// TODO change this, hate how it looks
settings = QPlus.stringToObj(settings);
Object.assign(settings, {
cooldown: Number(settings.cooldown) || 0,
through: Number(settings.through) || 0,
groundTarget: settings.groundtarget && !settings.selecttarget,
selectTarget: !settings.groundtarget && settings.selecttarget,
throughTerrain: settings.throughTerrain || ''
});
if (settings.throughTerrain.constructor !== Array) {
settings.throughTerrain = [settings.throughTerrain];
}
if (settings.groundtarget) var range = Number(settings.groundtarget);
if (settings.selecttarget) var range = Number(settings.selecttarget);
settings.range = range || 0;
this._skillSettings[skill.id] = settings;
}
}
return this._skillSettings[skill.id];
};
QABS._skillSequence = {};
QABS.getSkillSequence = function(skill) {
if (!this._skillSequence.hasOwnProperty(skill.id)) {
var settings = skill.qmeta.absSequence;
this._skillSequence[skill.id] = [];
if (settings) {
settings = settings.split('\n');
var actions = [];
for (var i = 0; i < settings.length; i++) {
if (settings[i].trim() !== '') {
actions.push(settings[i].trim());
}
}
actions.push('collider hide');
actions.push('user unlock');
actions.push('user casting false');
this._skillSequence[skill.id] = actions;
}
}
return this._skillSequence[skill.id].clone();
};
QABS._skillOnDamage = {};
QABS.getSkillOnDamage = function(skill) {
if (!this._skillOnDamage.hasOwnProperty(skill.id)) {
var settings = skill.qmeta.absOnDamage;
var actions = [];
actions.push('animation 0');
if (settings) {
settings = settings.split('\n');
for (var i = 0; i < settings.length; i++) {
if (settings[i].trim() !== '') {
actions.push(settings[i].trim());
}
}
}
this._skillOnDamage[skill.id] = actions;
}
return this._skillOnDamage[skill.id].clone();
};
QABS._weaponSkills = {};
QABS.weaponSkills = function(id) {
if (!this._weaponSkills[id]) {
var skills = $dataWeapons[id].qmeta.skillKeys || $dataWeapons[id].qmeta.absSkills;
this._weaponSkills[id] = {};
if (skills) {
this._weaponSkills[id] = this.stringToSkillKeyObj(skills);
}
}
return this._weaponSkills[id];
};
QABS._aiRange = {};
QABS.getAIRange = function(skill) {
if (!this._aiRange.hasOwnProperty(skill.id)) {
this._aiRange[skill.id] = this.calcAIRange(skill);
}
return this._aiRange[skill.id];
};
QABS.calcAIRange = function(skill) {
var settings = this.getSkillSettings(skill);
if (settings.range) {
return settings.range;
}
var actions = this.getSkillSequence(skill);
var currDist = 0;
var stored = 0;
var maxDist = 0;
actions.forEach(function(action) {
var move = /^(?:move|wave) (.*)/i.exec(action);
if (move) {
move = move[1].trim().split(' ');
if (move[0] === 'forward') {
currDist += Number(move[1]) || 0;
} else {
currDist -= Number(move[1]) || 0;
}
maxDist = Math.max(currDist, maxDist);
}
var store = /^store/i.exec(action);
if (store) {
stored = currDist;
}
var toStore = /^(?:move|wave)ToStored/i.exec(action);
if (toStore) {
currDist = stored;
maxDist = Math.max(currDist, maxDist);
}
var userForce = /^user forceSkill (.*)/i.exec(action);
if (userForce) {
userForce = Number(userForce[1].trim().split(' ')[0]);
var dist2 = QABS.getAIRange($dataSkills[userForce]);
maxDist = Math.max(dist2, maxDist);
}
var skillForce = /^forceSkill (.*)/i.exec(action);
if (skillForce) {
skillForce = Number(skillForce[1].trim().split(' ')[0]);
var dist3 = QABS.getAIRange($dataSkills[skillForce]);
dist3 += currDist;
maxDist = Math.max(dist3, maxDist);
}
});
return maxDist;
};
})();
//-----------------------------------------------------------------------------
// QABS Manager Static Class
function QABSManager() {
throw new Error('This is a static class');
}
(function() {
QABSManager.clear = function() {
this._animations = [];
this._pictures = [];
this._mapId = $gameMap._mapId;
};
QABSManager.getTargets = function(item, self) {
return ColliderManager.getCharactersNear(item.collider, function(chara) {
if (typeof chara.battler !== 'function' || !chara.battler()) return false;
if (chara.battler().isDeathStateAffected()) return false;
if (chara.isFriendly(self) && [1, 2, 3, 4, 5, 6].contains(item.data.scope)) {
return false;
}
if (!chara.isFriendly(self) && [7, 8, 9, 10].contains(item.data.scope)) {
return false;
}
if (item.data.scope === 11 && chara !== self) return false;
var type = item.settings.collides || 'collision';
return item.collider.intersects(chara.collider(type));
});
};
QABSManager.bestAction = function(userId) {
var chara = QPlus.getCharacter(userId);
if (!chara.battler()) return null;
var targets;
var skills = chara.usableSkills().filter(function(skillId) {
if (!skillId) return false;
targets = QABSManager.skillWillHit(skillId, userId);
if (targets && targets.length > 0) {
return true;
}
return false;
})
if (skills.length === 0) return null;
return skills[Math.floor(Math.random() * skills.length)];
};
QABSManager.skillWillHit = function(skillId, userId) {
var skill = $dataSkills[skillId];
var chara = QPlus.getCharacter(userId);
var settings = QABS.getSkillSettings(skill);
var collider = chara.collider('collision');
var skillCollider = chara.makeSkillCollider(settings);
var w1 = settings.collider[1] || chara.collider('collision').width;
var h1 = settings.collider[2] || chara.collider('collision').height;
var x1 = chara.cx() - w1 / 2;
var y1 = chara.cy() - h1 / 2;
var targets = [];
var aiRange = QABS.getAIRange(skill);
if (aiRange > 0) {
var r1 = aiRange * 2;
range = new Circle_Collider(w1 + r1, h1 + r1);
range.moveTo(x1 - r1 / 2, y1 - r1 / 2);
targets = this.getTargets({
settings: settings,
data: skill,
collider: range
}, chara);
ColliderManager.draw(range, QABS.aiWait / 2);
} else {
targets = this.getTargets({
settings: settings,
data: skill,
collider: skillCollider
}, chara);
ColliderManager.draw(skillCollider, QABS.aiWait / 2);
}
return targets;
};
QABSManager.startAction = function(self, targets, item) {
if (!item.animationTarget || targets.length === 0) {
this.startAnimation(item.data.animationId, item.collider.center.x, item.collider.center.y);
}
self._agro.placeInCombat();
var action = new Game_ABSAction(self.battler(), true);
action.setSkill(item.data.id);
for (var i = 0; i < targets.length; i++) {
if (item.animationTarget === 1) {
var x = targets[i].cx();
var y = targets[i].cy();
this.startAnimation(item.data.animationId, x, y);
}
action.absApply(targets[i].battler());
targets[i].addAgro(self.charaId(), item.data);
}
action.applyGlobal();
};
QABSManager.startPopup = function(type, options) {
if (!Imported.QPopup) return;
var preset = $gameSystem.qPopupPreset(type);
Object.assign(options, {
style: preset.style,
transitions: preset.transitions
})
if (!options.duration) options.duration = 80;
if (!options.transitions) {
var start = options.duration - 30;
var end = start + 30;
var fadeout = start + ' 30 fadeout';
var slideup = '0 ' + end + ' slideup 24';
options.transitions = [fadeout, slideup];
}
return QPopup.start(options);
};
QABSManager._animations = [];
QABSManager.startAnimation = function(id, x, y) {
var scene = SceneManager._scene;
if (scene.constructor !== Scene_Map) return;
if (id < 0) id = 1;
if (id <= 0) return;
var animation = $dataAnimations[id];
var temp = new Sprite_MapAnimation(animation);
temp.move(x, y);
this._animations.push(temp);
scene._spriteset._tilemap.addChild(temp);
};
QABSManager.removeAnimation = function(sprite) {
var scene = SceneManager._scene;
if (scene.constructor !== Scene_Map) return;
var i = this._animations.indexOf(sprite);
if (i < 0) return;
this._animations[i] = null;
this._animations.splice(i, 1);
scene._spriteset._tilemap.removeChild(sprite);
};
QABSManager._pictures = [];
QABSManager.addPicture = function(sprite) {
var scene = SceneManager._scene;
if (scene.constructor !== Scene_Map) return;
this._pictures.push(sprite);
scene._spriteset._tilemap.addChild(sprite);
};
QABSManager.removePicture = function(sprite) {
var scene = SceneManager._scene;
if (scene.constructor !== Scene_Map) return;
var i = this._pictures.indexOf(sprite);
if (i < 0) return;
this._pictures[i] = null;
this._pictures.splice(i, 1);
scene._spriteset._tilemap.removeChild(sprite);
};
QABSManager.createItem = function(x, y, itemId, type) {
var loot = new Game_Loot(x, y);
var data = $dataItems;
if (type === 1) data = $dataWeapons;
if (type === 2) data = $dataArmors;
loot.setItem(data[itemId]);
return loot;
};
QABSManager.createGold = function(x, y, value) {
var loot = new Game_Loot(x, y);
loot.setGold(value);
return loot;
};
QABSManager._freeEventIds = [];
QABSManager.addEvent = function(event) {
var id = this._freeEventIds.unshift() || 0;
if (!id || $gameMap._events[id]) {
id = $gameMap._events.length;
}
event._eventId = id;
$gameMap._events[id] = event;
if (!event._noSprite) {
var scene = SceneManager._scene;
if (scene === Scene_Map) {
var spriteset = scene._spriteset;
var sprite = new Sprite_Character(event);
spriteset._characterSprites.push(sprite);
spriteset._tilemap.addChild(sprite);
}
}
};
QABSManager.removeEvent = function(event) {
var id = event._eventId;
if (!id || !$gameMap._events[id]) return;
event.removeColliders();
if (!event._noSprite) {
var scene = SceneManager._scene;
if (scene === Scene_Map) {
var spriteset = scene._spriteset;
var spriteCharas = spriteset._characterSprites;
for (var i = 0; i < spriteCharas.length; i++) {
if (spriteCharas[i] && spriteCharas[i]._character === event) {
spriteset._tilemap.removeChild(spriteCharas[i]);
spriteCharas.splice(i, 1);
break;
}
}
}
}
$gameMap._events[id].clearABS();
$gameMap._events[id] = null;
this._freeEventIds.push(id);
};
QABSManager.preloadSkill = function(skill) {
var aniId = skill.animationId;
aniId = aniId < 0 ? 1 : aniId;
var ani = $dataAnimations[aniId];
if (ani) {
ImageManager.loadAnimation(ani.animation1Name, ani.animation1Hue);
ImageManager.loadAnimation(ani.animation2Name, ani.animation2Hue);
}
var sequence = QABS.getSkillSequence(skill);
for (var i = 0; i < sequence.length; i++) {
var action = sequence[i];
var ani = /^animation (.*)/i.exec(action);
var pic = /^picture (.*)/i.exec(action);
var forced = /forceSkill (\d+)/i.exec(action);
if (ani) {
ani = ani[1].trim();
ani = $dataAnimations[ani];
if (ani) {
ImageManager.loadAnimation(ani.animation1Name, ani.animation1Hue);
ImageManager.loadAnimation(ani.animation2Name, ani.animation2Hue);
}
}
if (pic) {
pic = QPlus.makeArgs(pic[1])[0];
ImageManager.loadPicture(pic);
}
if (forced) {
var forcedSkill = $dataSkills[Number(forced[1])];
if (forcedSkill) this.preloadSkill(forcedSkill);
}
}
};
})();
//-----------------------------------------------------------------------------
// Skill_Sequencer
function Skill_Sequencer() {
this.initialize.apply(this, arguments);
}
(function() {
Skill_Sequencer.prototype.initialize = function(character, skill) {
this._character = character;
this._skill = skill;
};
Skill_Sequencer.prototype.startAction = function(action) {
var cmd = action.shift().toLowerCase();
switch (cmd) {
case 'user': {
this.startUserAction(action);
break;
}
case 'store': {
this.actionStore();
break;
}
case 'move': {
this.actionMove(action);
break;
}
case 'movetostored': {
this.actionMoveToStored(action);
break;
}
case 'wave': {
this.actionWave(action);
break;
}
case 'wavetostored': {
this.actionWaveToStored(action);
break;
}
case 'damage':
case 'trigger': {
this.actionTrigger(action);
break;
}
case 'adjustaim': {
this.actionAdjustAim(action);
break;
}
case 'wait': {
this.actionWait(action);
break;
}
case 'picture': {
this.actionPicture(action);
break;
}
case 'trail': {
this.actionTrail(action);
break;
}
case 'collider': {
this.actionCollider(action);
break;
}
case 'animation': {
this.actionAnimation(action);
break;
}
case 'se': {
this.actionSE(action);
break;
}
case 'qaudio': {
this.actionQAudio(action);
break;
}
case 'forceskill': {
this.actionForceSkill(action);
break;
}
case 'globallock': {
$gameMap.globalLock(null, 0, 1);
break;
}
case 'globalunlock': {
$gameMap.globalUnlock(null, 0, 0);
break;
}
}
};
Skill_Sequencer.prototype.startUserAction = function(action) {
var cmd = action.shift().toLowerCase();
switch (cmd) {
case 'casting': {
this.userCasting(action);
break;
}
case 'lock': {
this.userLock();
break;
}
case 'unlock': {
this.userUnlock();
break;
}
case 'speed': {
this.userSpeed(action);
break;
}
case 'move': {
this.userMove(action);
break;
}
case 'movehere': {
this.userMoveHere(action);
break;
}
case 'jump': {
this.userJump(action);
break;
}
case 'jumphere': {
this.userJumpHere(action);
break;
}
case 'teleport': {
this.userTeleport();
break;
}
case 'setdirection': {
this.userSetDirection(action);
break;
}
case 'directionfix': {
this.userDirectionFix(action);
break;
}
case 'pose': {
this.userPose(action);
break;
}
case 'forceskill': {
this.userForceSkill(action);
break;
}
case 'animation': {
this.userAnimation(action);
break;
}
case 'qaudio': {
this.userQAudio(action);
break;
}
}
};
Skill_Sequencer.prototype.startOnDamageAction = function(action, targets) {
var cmd = action.shift().toLowerCase();
switch (cmd) {
case 'target': {
this.startOnDamageTargetAction(action, targets);
break;
}
case 'user': {
this.startOnDamageUserAction(action, targets);
break;
}
case 'animationtarget': {
this._skill.animationTarget = Number(action[1]) || 0;
break;
}
}
};
Skill_Sequencer.prototype.startOnDamageTargetAction = function(action, targets) {
var cmd = action.shift().toLowerCase();
switch (cmd) {
case 'move': {
this.targetMove(action, targets);
break;
}
case 'jump': {
this.targetJump(action, targets);
break;
}
case 'pose': {
this.targetPose(action, targets);
break;
}
case 'cancel': {
this.targetCancel(action, targets);
break;
}
case 'qaudio': {
this.targetQAudio(action, targets);
break;
}
}
};
Skill_Sequencer.prototype.startOnDamageUserAction = function(action, targets) {
var cmd = action.shift().toLowerCase();
switch (cmd) {
case 'forceskill': {
this.userForceSkill(action);
break;
}
}
};
Skill_Sequencer.prototype.userCasting = function(action) {
if (!this._skill.forced) {
this._character._casting = action[0] === 'true' ? this._skill : false;
}
};
Skill_Sequencer.prototype.userLock = function() {
var i = this._character._skillLocked.indexOf(this._skill);
if (i >= 0) return;
this._character._skillLocked.push(this._skill);
};
Skill_Sequencer.prototype.userUnlock = function() {
var i = this._character._skillLocked.indexOf(this._skill);
if (i >= 0) {
this._character._skillLocked.splice(i, 1);
}
};
Skill_Sequencer.prototype.userSpeed = function(action) {
var amt = Number(action[1]) || 1;
var spd = this._character.moveSpeed();
if (action[0] === 'inc') {
this._character.setMoveSpeed(spd + amt);
} else if (action[0] === 'dec') {
this._character.setMoveSpeed(spd - amt);
}
};
Skill_Sequencer.prototype.userMove = function(action) {
var dist = Number(action[1]) || this._character.moveTiles();
var route = {
list: [],
repeat: false,
skippable: true,
wait: false
}
var radian = oldRadian = this._character._radian;
if (action[0] === 'backward') {
radian -= Math.PI;
}
route.list.push({
code: Game_Character.ROUTE_SCRIPT,
parameters: ['qmove2(' + radian + ',' + dist + ')']
});
if (action[0] === 'backward') {
route.list.unshift({
code: Game_Character.ROUTE_DIR_FIX_OFF
});
route.list.push({
code: this._character.isDirectionFixed() ?
Game_Character.ROUTE_DIR_FIX_ON : Game_Character.ROUTE_DIR_FIX_OFF
});
}
route.list.push({
code: Game_Character.ROUTE_END
});
this._character.forceMoveRoute(route);
this._character.updateRoutineMove();
this._waitForUserMove = action[2] ? action[2] === 'true' : false;
};
Skill_Sequencer.prototype.userMoveHere = function(action) {
var center = this._character.centerWithCollider(this._skill.collider);
var final = this._character.adjustPosition(center.x, center.y);
var dx = final.x - this._character.px;
var dy = final.y - this._character.py;
var radian = Math.atan2(dy, dx);
var dist = Math.sqrt(dx * dx + dy * dy);
var route = {
list: [],
repeat: false,
skippable: true,
wait: false
}
route.list.push({
code: Game_Character.ROUTE_SCRIPT,
parameters: ['qmove2(' + radian + ',' + dist + ')']
});
route.list.push({
code: Game_Character.ROUTE_END
});
this._character.forceMoveRoute(route);
this._character.updateRoutineMove();
this._waitForUserMove = action[0] ? action[0] === 'true' : false;
};
Skill_Sequencer.prototype.userJump = function(action) {
var dist = Number(action[1]) || 0;
var x1 = this._character.px;
var y1 = this._character.py;
var radian = oldRadian = this._character._radian;
if (action[0] === 'backward') {
radian -= Math.PI;
}
var x2 = x1 + Math.cos(radian) * dist;
var y2 = y1 + Math.sin(radian) * dist;
var final = this._character.adjustPosition(x2, y2);
var dx = final.x - x1;
var dy = final.y - y1;
var lastDirectionFix = this._character.isDirectionFixed();
if (action[0] === 'backward') {
this._character.setDirectionFix(true);
}
this._character.pixelJump(dx, dy);
this._character.setDirectionFix(lastDirectionFix);
this._character.setRadian(oldRadian);
this._waitForUserJump = action[2] ? action[2] === 'true' : false;
};
Skill_Sequencer.prototype.userJumpHere = function(action) {
var center = this._character.centerWithCollider(this._skill.collider);
var final = this._character.adjustPosition(center.x, center.y);
var dx = final.x - this._character.px;
var dy = final.y - this._character.py;
this._character.pixelJump(dx, dy);
this._waitForUserJump = action[0] ? action[0] === 'true' : false;
};
Skill_Sequencer.prototype.userTeleport = function() {
var x1 = this._skill.collider.x;
var y1 = this._skill.collider.y;
this._character.setPixelPosition(x1, y1);
};
Skill_Sequencer.prototype.userSetDirection = function(action) {
var dir = Number(action[0]);
if (dir) {
this._character.setDirection(dir);
}
};
Skill_Sequencer.prototype.userDirectionFix = function(action) {
this._character.setDirectionFix(action[0] === 'true');
};
Skill_Sequencer.prototype.userPose = function(action) {
if (Imported.QSprite) {
this._character.playPose(action[0]);
this._waitForUserPose = action[1] === 'true';
}
};
Skill_Sequencer.prototype.userForceSkill = function(action) {
var id = Number(action[0]);
var angleOffset = Number(action[1]);
var radian = this._character._radian;
if (angleOffset) {
radian += angleOffset * Math.PI / 180;
}
var skill = this._character.forceSkill(id, true);
skill.radian = radian;
skill._target = this._skill._target;
};
Skill_Sequencer.prototype.userAnimation = function(action) {
var id = Number(action[0]);
var x = this._character.cx();
var y = this._character.cy();
QABSManager.startAnimation(id, x, y);
};
Skill_Sequencer.prototype.userQAudio = function(action) {
if (!Imported.QAudio) return;
var id = Game_Interpreter.prototype.getUniqueQAudioId.call();
var name = action[0];
var loop = !!QPlus.getArg(action, /^loop$/i);
var dontPan = !!QPlus.getArg(action, /^noPan$/i);
var fadein = QPlus.getArg(action, /^fadein(\d+)/i);
var type = QPlus.getArg(action, /^(bgm|bgs|me|se)$/i) || 'bgm';
type = type.toLowerCase();
var max = QPlus.getArg(action, /^max(\d+)/i);
if (max === null) {
max = 90;
}
max = Number(max) / 100;
var radius = QPlus.getArg(action, /^radius(\d+)/i);
if (radius === null) {
radius = 5;
}
var audio = {
name: name,
volume: 100,
pitch: 0,
pan: 0
}
AudioManager.playQAudio(id, audio, {
type: type,
loop: loop,
maxVolume: Number(max),
radius: Number(radius),
bindTo: this._character.charaId(),
doPan: !dontPan,
fadeIn: Number(fadein) || 0
});
};
Skill_Sequencer.prototype.actionStore = function() {
this._stored = new Point(this._skill.collider.x, this._skill.collider.y);
};
Skill_Sequencer.prototype.actionMove = function(action) {
var dir = action[0];
var distance = Number(action[1]);
var duration = Number(action[2]);
ColliderManager.draw(this._skill.collider, duration);
var radian = this._skill.radian;
if (dir === 'backward') {
radian -= Math.PI;
}
radian += radian < 0 ? Math.PI * 2 : 0;
this._waitForMove = action[3] === 'true';
this.setSkillRadian(Number(radian));
this.actionMoveSkill(distance, duration);
};
Skill_Sequencer.prototype.actionMoveToStored = function(action) {
if (this._stored) {
var x1 = this._skill.collider.x;
var y1 = this._skill.collider.y;
var x2 = this._stored.x;
var y2 = this._stored.y;
var dx = x2 - x1;
var dy = y2 - y1;
var dist = Math.sqrt(dx * dx + dy * dy);
this._skill.radian = Math.atan2(y2 - y1, x2 - x1);
this._skill.radian += this._skill.radian < 0 ? Math.PI * 2 : 0;
this.actionMove(['forward', dist, action[0], action[1]]);
}
};
Skill_Sequencer.prototype.actionWave = function(action) {
var dir = action[0];
var amp = Number(action[1]);
var harm = Number(action[2]);
var distance = Number(action[3]);
var duration = Number(action[4]);
ColliderManager.draw(this._skill.collider, duration);
var radian = this._skill.radian;
if (dir === 'backward') {
radian -= Math.PI;
}
radian += radian < 0 ? Math.PI * 2 : 0;
this.setSkillRadian(Number(radian));
this.actionWaveSkill(amp, harm, distance, duration);
this._waitForMove = action[5] === "true";
};
Skill_Sequencer.prototype.actionWaveToStored = function(action) {
if (this._stored) {
var x1 = this._skill.collider.x;
var y1 = this._skill.collider.y;
var x2 = this._stored.x;
var y2 = this._stored.y;
var dx = x2 - x1;
var dy = y2 - y1;
var dist = Math.sqrt(dx * dx + dy * dy);
this._skill.radian = Math.atan2(dy, dx);
this.actionWave(['forward', action[0], action[1], dist, action[2], action[3]]);
}
};
Skill_Sequencer.prototype.actionTrigger = function() {
this._skill.targets = QABSManager.getTargets(this._skill, this._character);
this.updateSkillDamage();
};
Skill_Sequencer.prototype.actionAdjustAim = function() {
if (!this._skill._target) return;
var x1 = this._skill.collider.x;
var y1 = this._skill.collider.y;
var forward = this._skill._target.forwardV();
var dt = Math.randomInt(5) || 1;
var x2 = this._skill._target.px + forward.x * dt;
var y2 = this._skill._target.py + forward.y * dt;
var dx = x2 - x1;
var dy = y2 - y1;
this._skill.radian = Math.atan2(dy, dx);
};
Skill_Sequencer.prototype.actionWait = function(action) {
var duration = Number(action[0]);
ColliderManager.draw(this._skill.collider, duration);
this._waitCount = duration;
};
Skill_Sequencer.prototype.actionPicture = function(action) {
this._skill.picture = new Sprite_SkillPicture();
this._skill.picture.bitmap = ImageManager.loadPicture(action[0]);
this._skill.picture.rotatable = action[1] === 'true';
this._skill.picture.originDirection = Number(action[2]);
this._skill.picture.z = 3;
this._skill.picture.anchor.x = 0.5;
this._skill.picture.anchor.y = 0.5;
var isAnimated = /%\[(\d+)-(\d+)\]/.exec(action[0]);
if (isAnimated) {
var frames = Number(isAnimated[1]);
var speed = Number(isAnimated[2]);
this._skill.picture.setupAnim(frames, speed);
}
this.setSkillPictureRadian(this._skill.picture, this._skill.radian);
var x = this._skill.collider.center.x;
var y = this._skill.collider.center.y;
this._skill.picture.move(x, y);
this._skill.picture.bitmap.addLoadListener(function() {
QABSManager.addPicture(this);
}.bind(this._skill.picture));
};
Skill_Sequencer.prototype.actionTrail = function(action) {
this._skill.trail = new Sprite_SkillTrail();
this._skill.trail.bitmap = ImageManager.loadPicture(action[0]);
this._skill.trail.move(0, 0, Graphics.width, Graphics.height);
this._skill.trail.rotatable = action[1] === 'true';
this._skill.trail.originDirection = Number(action[2]);
this._skill.trail.z = 3;
this.setSkillPictureRadian(this._skill.trail, this._skill.radian);
var x = this._skill.collider.center.x;
var y = this._skill.collider.center.y;
this._skill.trail.startX = x;
this._skill.trail.startY = y;
this._skill.trail.bitmap.addLoadListener(function() {
var w = this.bitmap.width;
var h = this.bitmap.height;
this.move(x, y, w, h);
QABSManager.addPicture(this);
}.bind(this._skill.trail));
};
Skill_Sequencer.prototype.actionCollider = function(action) {
var display = action[0];
if (display === 'show') {
this._skill.pictureCollider = new Sprite_SkillCollider(this._skill.collider);
QABSManager.addPicture(this._skill.pictureCollider);
} else if (display === 'hide' && this._skill.pictureCollider) {
QABSManager.removePicture(this._skill.pictureCollider);
this._skill.pictureCollider = null;
}
};
Skill_Sequencer.prototype.actionAnimation = function(action) {
var id = Number(action[0]);
var x = this._skill.collider.center.x;
var y = this._skill.collider.center.y;
QABSManager.startAnimation(id, x, y);
};
Skill_Sequencer.prototype.actionSE = function(action) {
var se = {};
se.name = action[0];
se.volume = Number(action[1]) || 90;
se.pitch = Number(action[2]) || 100;
se.pan = Number(action[3]) || 0;
AudioManager.playSe(se);
};
Skill_Sequencer.prototype.actionQAudio = function(action) {
if (!Imported.QAudio) return;
var x = this._skill.collider.center.x;
var y = this._skill.collider.center.x;
var id = Game_Interpreter.prototype.getUniqueQAudioId.call();
var name = action[0];
var loop = !!QPlus.getArg(action, /^loop$/i);
var dontPan = !!QPlus.getArg(action, /^noPan$/i);
var fadein = QPlus.getArg(action, /^fadein(\d+)/i);
var type = QPlus.getArg(action, /^(bgm|bgs|me|se)$/i) || 'bgm';
type = type.toLowerCase();
var max = QPlus.getArg(action, /^max(\d+)/i);
if (max === null) {
max = 90;
}
max = Number(max) / 100;
var radius = QPlus.getArg(action, /^radius(\d+)/i);
if (radius === null) {
radius = 5;
}
var audio = {
name: name,
volume: 100,
pitch: 0,
pan: 0
}
AudioManager.playQAudio(id, audio, {
type: type,
loop: loop,
maxVolume: Number(max),
radius: Number(radius),
x: x / QMovement.tileSize,
y: y / QMovement.tileSize,
doPan: !dontPan,
fadeIn: Number(fadein) || 0
});
};
Skill_Sequencer.prototype.actionForceSkill = function(action) {
var id = Number(action[0]);
var angleOffset = Number(action[1]);
var radian = this._skill.radian;
if (angleOffset) {
radian += angleOffset * Math.PI / 180;
}
var center = this._skill.collider.center;
var skill = this._character.makeSkill(id);
var w = skill.collider.width;
var h = skill.collider.height;
skill.collider.moveTo(center.x - w / 2, center.y - w / 2);
skill.radian = radian;
skill._target = this._skill._target;
this._character._activeSkills.push(skill);
this._character._skillCooldowns[id] = skill.settings.cooldown;
};
Skill_Sequencer.prototype.actionMoveSkill = function(distance, duration) {
var instant = duration === 0;
if (duration <= 0) duration = 1;
this._skill.newX = this._skill.collider.x + Math.round(distance * Math.cos(this._skill.radian));
this._skill.newY = this._skill.collider.y + Math.round(distance * Math.sin(this._skill.radian));
this._skill.speed = Math.abs(distance / duration);
this._skill.speedX = Math.abs(this._skill.speed * Math.cos(this._skill.radian));
this._skill.speedY = Math.abs(this._skill.speed * Math.sin(this._skill.radian));
this._skill.moving = true;
if (instant) {
this.updateSkillPosition();
}
};
Skill_Sequencer.prototype.actionWaveSkill = function(amp, harmonics, distance, duration) {
this._skill.amp = amp;
this._skill.distance = distance;
this._skill.waveLength = harmonics * Math.PI;
this._skill.waveSpeed = this._skill.waveLength / duration;
this._skill.theta = 0;
this._skill.xi = this._skill.collider.x;
this._skill.yi = this._skill.collider.y;
this._skill.waving = true;
this._skill.moving = true;
};
Skill_Sequencer.prototype.targetMove = function(action, targets) {
var dist = Number(action[1]) || this._character.moveTiles();
for (var i = 0; i < targets.length; i++) {
var dist2 = dist - dist * eval('targets[i].battler().' + QABS.mrst);
if (dist2 <= 0) return;
var dx = targets[i].cx() - this._character.cx();
var dy = targets[i].cy() - this._character.cy();
var radian = Math.atan2(dy, dx);
radian += radian < 0 ? Math.PI * 2 : 0;
if (action[0] === 'towards') {
radian += Math.PI;
} else if (action[0] === 'into' || action[0] === 'towardsSkill') {
var dxi = this._skill.collider.center.x - targets[i].cx();
var dyi = this._skill.collider.center.y - targets[i].cy();
radian = Math.atan2(dyi, dxi);
dist2 = Math.min(dist2, Math.sqrt(dxi * dxi + dyi * dyi));
} else if (action[0] === 'awayFromSkill') {
var dxi = targets[i].cx() - this._skill.collider.center.x;
var dyi = targets[i].cy() - this._skill.collider.center.y;
radian = Math.atan2(dyi, dxi);
}
var route = {
list: [],
repeat: false,
skippable: true,
wait: false
}
route.list.push({
code: Game_Character.ROUTE_DIR_FIX_ON
});
route.list.push({
code: Game_Character.ROUTE_SCRIPT,
parameters: ['qmove2(' + radian + ',' + dist + ')']
});
if (!targets[i].isDirectionFixed()) {
route.list.push({
code: Game_Character.ROUTE_DIR_FIX_OFF
});
}
route.list.push({
code: Game_Character.ROUTE_SCRIPT,
parameters: ['this.setRadian(' + targets[i]._radian + ')']
});
route.list.push({
code: Game_Character.ROUTE_END
});
targets[i].forceMoveRoute(route);
targets[i].updateRoutineMove();
}
};
Skill_Sequencer.prototype.targetJump = function(action, targets) {
var dist = Number(action[1]) || 0;
for (var i = 0; i < targets.length; i++) {
var dist2 = dist - dist * eval('targets[i].battler().' + QABS.mrst);
if (dist2 <= 0) return;
var dx = targets[i].cx() - this._character.cx();
var dy = targets[i].cy() - this._character.cy();
var radian = Math.atan2(dy, dx);
radian += radian < 0 ? Math.PI * 2 : 0;
if (action[0] === 'towards') {
radian += Math.PI;
} else if (action[0] === 'into' || action[0] === 'towardsSkill') {
var dxi = this._skill.collider.center.x - targets[i].cx();
var dyi = this._skill.collider.center.y - targets[i].cy();
radian = Math.atan2(dyi, dxi);
dist2 = Math.min(dist2, Math.sqrt(dxi * dxi + dyi * dyi));
} else if (action[0] === 'awayFromSkill') {
var dxi = targets[i].cx() - this._skill.collider.center.x;
var dyi = targets[i].cy() - this._skill.collider.center.y;
radian = Math.atan2(dyi, dxi);
dist2 = Math.min(dist2, Math.sqrt(dxi * dxi + dyi * dyi));
}
var x1 = targets[i].px;
var y1 = targets[i].py;
var x2 = x1 + Math.round(dist2 * Math.cos(radian));
var y2 = y1 + Math.round(dist2 * Math.sin(radian));
var final = targets[i].adjustPosition(x2, y2);
dx = final.x - x1;
dy = final.y - y1;
var lastDirectionFix = targets[i].isDirectionFixed();
var prevRadian = targets[i]._radian;
targets[i].setDirectionFix(true);
targets[i].pixelJump(dx, dy);
targets[i].setDirectionFix(lastDirectionFix);
targets[i].setRadian(prevRadian);
}
};
Skill_Sequencer.prototype.targetPose = function(action, targets) {
var pose = action[0];
if (Imported.QSprite) {
for (var i = 0; i < targets.length; i++) {
targets[i].playPose(pose);
}
}
};
Skill_Sequencer.prototype.targetCancel = function(action, targets) {
for (var i = 0; i < targets.length; i++) {
if (targets[i]._casting) {
targets[i]._casting.break = true;
}
}
};
Skill_Sequencer.prototype.targetQAudio = function(action, targets) {
if (!Imported.QAudio) return;
var id = Game_Interpreter.prototype.getUniqueQAudioId.call();
var name = action[0];
var loop = !!QPlus.getArg(action, /^loop$/i);
var dontPan = !!QPlus.getArg(action, /^noPan$/i);
var fadein = QPlus.getArg(action, /^fadein(\d+)/i);
var type = QPlus.getArg(action, /^(bgm|bgs|me|se)$/i) || 'bgm';
type = type.toLowerCase();
var max = QPlus.getArg(action, /^max(\d+)/i);
if (max === null) {
max = 90;
}
max = Number(max) / 100;
var radius = QPlus.getArg(action, /^radius(\d+)/i);
if (radius === null) {
radius = 5;
}
var audio = {
name: name,
volume: 100,
pitch: 0,
pan: 0
}
for (var i = 0; i < targets.length; i++) {
AudioManager.playQAudio(id, audio, {
type: type,
loop: loop,
maxVolume: Number(max),
radius: Number(radius),
bindTo: targets[i].charaId(),
doPan: !dontPan,
fadeIn: Number(fadein) || 0
});
};
};
Skill_Sequencer.prototype.setSkillRadian = function(radian) {
var rotate = this._skill.settings.rotate === true;
this._skill.radian = radian;
this._skill.collider.setRadian(Math.PI / 2 + radian);
if (this._skill.picture) {
this.setSkillPictureRadian(this._skill.picture, this._skill.radian);
}
};
Skill_Sequencer.prototype.setSkillPictureRadian = function(picture, radian) {
if (!picture.rotatable) return;
var originDirection = picture.originDirection;
var originRadian = this._character.directionToRadian(originDirection);
picture.rotation = originRadian + radian;
};
Skill_Sequencer.prototype.canSkillMove = function() {
var collided = false;
var through = this._skill.settings.through;
var targets = QABSManager.getTargets(this._skill, this._character);
if (targets.length > 0) {
for (var i = targets.length - 1; i >= 0; i--) {
if (!this._skill.targetsHit.contains(targets[i].charaId())) {
this._skill.targetsHit.push(targets[i].charaId());
} else {
targets.splice(i, 1);
}
}
if (targets.length > 0) {
this._skill.targets = targets;
if (through === 1 || through === 3) {
collided = true;
// TODO select the nearest target
this._skill.targets = [targets[0]];
}
this.updateSkillDamage();
}
}
if (collided) return false;
var edge = this._skill.collider.gridEdge();
var maxW = $gameMap.width();
var maxH = $gameMap.height();
if (!$gameMap.isLoopHorizontal()) {
if (edge.x2 < 0 || edge.x1 >= maxW) return false;
}
if (!$gameMap.isLoopVertical()) {
if (edge.y2 < 0 || edge.y1 >= maxH) return false;
}
if (through === 2 || through === 3) {
ColliderManager.getCollidersNear(this._skill.collider, function(collider) {
if (collider === this.collider) return false;
if (this.settings.throughTerrain.contains(collider.terrain)) {
return false;
}
if (this.collider.intersects(collider)) {
collided = true;
return 'break';
}
}.bind(this._skill));
}
if (through === 1 || through === 3) {
ColliderManager.getCharactersNear(this._skill.collider, function(chara) {
if (chara === this._character || chara.isThrough() || !chara.isNormalPriority()) return false;
if (chara.isLoot || chara._erased || chara.isDead) return false;
if (this._skill.collider.intersects(chara.collider('collision'))) {
collided = true;
return 'break';
}
}.bind(this));
}
return !collided;
};
Skill_Sequencer.prototype.isWaiting = function() {
return this._waitCount > 0 || this._waitForMove ||
this._waitForUserMove || this._waitForUserJump ||
this._waitForUserJump || this._waitForUserPose;
};
Skill_Sequencer.prototype.onBreak = function() {
var i = this._character._skillLocked.indexOf(this._skill);
if (i >= 0) {
this._character._skillLocked.splice(i, 1);
}
this._character._casting = false;
this.onEnd();
};
Skill_Sequencer.prototype.onEnd = function() {
this._skill.collider.kill = true;
QABSManager.removePicture(this._skill.picture);
QABSManager.removePicture(this._skill.trail);
QABSManager.removePicture(this._skill.pictureCollider);
var i = this._character._activeSkills.indexOf(this._skill);
this._character._activeSkills.splice(i, 1);
};
Skill_Sequencer.prototype.update = function() {
if (this._skill.break || this._character.battler().isStunned()) {
return this.onBreak();
}
if (this._skill.moving) {
this.updateSkillPosition();
}
if (!this.isWaiting()) {
this.updateSequence();
} else {
this.updateWait();
}
};
Skill_Sequencer.prototype.updateWait = function() {
if (this._waitCount > 0) {
this._waitCount--;
}
if (this._waitForUserMove && !this._character.isMoving()) {
this._waitForUserMove = false;
}
if (this._waitForUserJump && !this._character.isJumping()) {
this._waitForUserJump = false;
}
if (this._waitForUserPose && !this._character._posePlaying) {
this._waitForUserPose = false;
}
};
Skill_Sequencer.prototype.updateSequence = function() {
var sequence = this._skill.sequence;
while (sequence.length !== 0) {
var action = QPlus.makeArgs(sequence.shift());
this.startAction(action);
if (this.isWaiting()) {
break;
}
}
if (this._skill.sequence.length === 0 && !this._skill.moving) {
return this.onEnd();
}
};
Skill_Sequencer.prototype.updateSkillDamage = function() {
var targets = this._skill.targets;
for (var i = 0; i < this._skill.ondmg.length; i++) {
var action = this._skill.ondmg[i].split(' ');
this.startOnDamageAction(action, targets);
}
QABSManager.startAction(this._character, targets, this._skill);
};
Skill_Sequencer.prototype.updateSkillPosition = function() {
if (this._skill.waving) {
return this.updateSkillWavePosition();
}
var collider = this._skill.collider;
var x1 = collider.x;
var x2 = this._skill.newX;
var y1 = collider.y;
var y2 = this._skill.newY;
if (x1 < x2) x1 = Math.min(x1 + this._skill.speedX, x2);
if (x1 > x2) x1 = Math.max(x1 - this._skill.speedX, x2);
if (y1 < y2) y1 = Math.min(y1 + this._skill.speedY, y2);
if (y1 > y2) y1 = Math.max(y1 - this._skill.speedY, y2);
collider.moveTo(x1, y1);
var x3 = collider.center.x;
var y3 = collider.center.y;
if (this._skill.picture) {
this._skill.picture.move(x3, y3);
}
if (this._skill.trail) {
var x4 = this._skill.trail.startX;
var y4 = this._skill.trail.startY;
var x5 = x4 - x3;
var y5 = y4 - y3;
var dist = Math.sqrt(x5 * x5 + y5 * y5);
var radian = this._skill.trail.rotation;
var w = this._skill.trail.bitmap.width;
var h = this._skill.trail.bitmap.height;
var ox = w * Math.sin(radian);
var oy = (h / 2) * -Math.cos(radian);
x4 += dist * -Math.cos(radian) + ox;
y4 += dist * -Math.sin(radian) + oy;
this._skill.trail.move(x4, y4, dist, h);
}
if (!this.canSkillMove() || (x1 === x2 && y1 === y2)) {
this._skill.targetsHit = [];
this._skill.moving = false;
this._waitForMove = false;
}
};
Skill_Sequencer.prototype.updateSkillWavePosition = function() {
var collider = this._skill.collider;
var x1 = this._skill.xi;
var y1 = this._skill.yi;
var x2 = (this._skill.theta / this._skill.waveLength * this._skill.distance);
var y2 = this._skill.amp * -Math.sin(this._skill.theta);
var h = Math.sqrt(y2 * y2 + x2 * x2);
var radian = Math.atan2(y2, x2);
radian += this._skill.radian;
var x3 = h * Math.cos(radian);
var y3 = h * Math.sin(radian);
collider.moveTo(x1 + x3, y1 + y3);
var x4 = collider.center.x;
var y4 = collider.center.y;
if (this._skill.picture) {
this._skill.picture.move(x4, y4);
}
if (!this.canSkillMove() || this._skill.theta >= this._skill.waveLength) {
this._skill.targetsHit = [];
this._skill.waving = false;
this._skill.moving = false;
this._waitForMove = false;
}
this._skill.theta += this._skill.waveSpeed;
};
})();
//-----------------------------------------------------------------------------
// Game_Interpreter
(function() {
var Alias_Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
if (command.toLowerCase() === 'qabs') {
return this.qABSCommand(QPlus.makeArgs(args));
}
Alias_Game_Interpreter_pluginCommand.call(this, command, args);
};
Game_Interpreter.prototype.qABSCommand = function(args) {
var cmd = args.shift().toLowerCase();
if (cmd === 'disable' || cmd === 'enable') {
if (args.length === 0) {
$gameSystem._absEnabled = cmd === 'enable';
} else {
for (var i = 0; i < args.length; i++) {
var chara = QPlus.getCharacter(args[i]);
if (chara.constructor === Game_Event) {
var id = chara.eventId();
var mapId = chara._mapId;
if (cmd === 'enable') {
$gameSystem.enableEnemy(mapId, id);
} else {
$gameSystem.disableEnemy(mapId, id);
}
}
}
}
return;
}
if (cmd === 'override') {
var key = Number(args.shift());
var skillId = Number(args.shift());
if (skillId === -1) {
skillId = null;
}
$gameSystem.changeABSOverrideSkill(key, skillId);
return;
}
};
})();
//-----------------------------------------------------------------------------
// Game_System
(function() {
var Alias_Game_System_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function() {
Alias_Game_System_initialize.call(this);
this._absKeys = QABS.getDefaultSkillKeys();
this._absClassKeys = {};
this._absWeaponKeys = {};
this._absOverrideKeys = {};
this._absEnabled = true;
this._disabledEnemies = {};
this.checkAbsMouse();
};
Game_System.prototype.disableEnemy = function(mapId, eventId) {
if (!this._disabledEnemies[mapId]) {
this._disabledEnemies[mapId] = [];
}
this._disabledEnemies[mapId][eventId] = true;
};
Game_System.prototype.enableEnemy = function(mapId, eventId) {
if (!this._disabledEnemies[mapId]) {
this._disabledEnemies[mapId] = [];
}
this._disabledEnemies[mapId][eventId] = false;
};
Game_System.prototype.isDisabled = function(mapId, eventId) {
if (!this._disabledEnemies[mapId]) {
return false;
}
return this._disabledEnemies[mapId][eventId] || !this._absEnabled;
};
Game_System.prototype.loadClassABSKeys = function() {
if (!$gameParty.leader()) return;
var playerClass = $gameParty.leader().currentClass();
var classKeys = /<skillKeys>([\s\S]*)<\/skillKeys>/i.exec(playerClass.note);
if (classKeys && classKeys[1].trim() !== '') {
this._absClassKeys = QABS.stringToSkillKeyObj(classKeys[1]);
this.resetABSKeys();
}
};
Game_System.prototype.resetABSKeys = function() {
this._absKeys = QABS.getDefaultSkillKeys();
for (var key in this._absKeys) {
Object.assign(
this._absKeys[key],
this._absClassKeys[key] || {},
this._absWeaponKeys[key] || {},
this._absOverrideKeys[key] || {}
);
}
this.preloadAllSkills();
this.checkAbsMouse();
};
Game_System.prototype.absKeys = function() {
return this._absKeys;
};
Game_System.prototype.changeABSOverrideSkill = function(skillNumber, skillId, forced) {
var absKeys = this.absKeys();
var override = this._absOverrideKeys;
if (!absKeys[skillNumber]) return;
if (!forced && !absKeys[skillNumber].rebind) return;
if (!override[skillNumber]) {
override[skillNumber] = {};
}
if (skillId !== null) {
if (skillId > 0) {
for (var key in absKeys) {
if (absKeys[key].skillId === skillId) {
if (!override[key]) {
override[key] = {};
}
override[key].skillId = null;
}
}
}
override[skillNumber].skillId = skillId;
} else {
delete override[skillNumber].skillId;
}
this.resetABSKeys();
};
Game_System.prototype.changeABSWeaponSkills = function(skillSet) {
this._absWeaponKeys = skillSet;
this.resetABSKeys();
};
Game_System.prototype.changeABSSkillInput = function(skillNumber, input) {
var absKeys = this.absKeys();
var override = this._absOverrideKeys;
if (!absKeys[skillNumber]) return;
if (!override[skillNumber]) {
override[skillNumber] = {};
}
for (var key in absKeys) {
var i = absKeys[key].input.indexOf(input);
if (i !== -1) {
if (!override[key]) {
override[key] = {
input: absKeys[key].input.clone()
};
}
override[key].input.splice(i, 1);
break;
}
}
var i = /^\$/.test(input) ? 1 : 0;
override[skillNumber].input[i] = input;
this.checkAbsMouse();
};
Game_System.prototype.preloadAllSkills = function() {
var absKeys = this.absKeys();
for (var key in absKeys) {
var skill = $dataSkills[absKeys[key].skillId];
if (skill) QABSManager.preloadSkill(skill);
}
};
Game_System.prototype.anyAbsMouse = function() {
return this._absMouse1;
};
Game_System.prototype.anyAbsMouse2 = function() {
return this._absMouse2;
};
Game_System.prototype.checkAbsMouse = function() {
this._absMouse1 = false;
this._absMouse2 = false;
var keys = this.absKeys();
for (var key in keys) {
if (keys[key].input[0] === 'mouse1') {
this._absMouse1 = true;
}
if (keys[key].input[0] === 'mouse2') {
this._absMouse2 = true;
}
}
};
var Alias_Game_System_onBeforeSave = Game_System.prototype.onBeforeSave;
Game_System.prototype.onBeforeSave = function() {
Alias_Game_System_onBeforeSave.call(this);
$gameMap.compressBattlers();
QABS._needsUncompress = true;
};
var Alias_Game_System_onAfterLoad = Game_System.prototype.onAfterLoad;
Game_System.prototype.onAfterLoad = function() {
Alias_Game_System_onAfterLoad.call(this);
QABS._needsUncompress = true;
};
})();
//-----------------------------------------------------------------------------
// Game_Map
(function() {
var Alias_Game_Map_setup = Game_Map.prototype.setup;
Game_Map.prototype.setup = function(mapId) {
Alias_Game_Map_setup.call(this, mapId);
if (mapId !== QABSManager._mapId) {
QABSManager.clear();
}
};
var Alias_Game_Map_update = Game_Map.prototype.update;
Game_Map.prototype.update = function(sceneActive) {
Alias_Game_Map_update.call(this, sceneActive);
if (QABS._needsUncompress) {
this.uncompressBattlers();
QABS._needsUncompress = false;
}
};
Game_Map.prototype.compressBattlers = function() {
for (var i = 0; i < this.events().length; i++) {
if (this.events()[i]._battler) {
var oldRespawn = this.events()[i]._respawn;
this.events()[i].clearABS();
this.events()[i]._battler = null;
this.events()[i]._respawn = oldRespawn;
}
if (this.events()[i].constructor === Game_Loot) {
QABSManager.removePicture(this.events()[i]._itemIcon);
QABSManager.removeEvent(this.events()[i]);
}
}
$gamePlayer.clearABS();
QABSManager.clear();
};
Game_Map.prototype.uncompressBattlers = function() {
for (var i = 0; i < this.events().length; i++) {
if (this.events()[i]._respawn >= 0) {
var wasDead = true;
var oldRespawn = this.events()[i]._respawn;
}
this.events()[i].setupBattler();
if (wasDead) {
this.events()[i].clearABS();
this.events()[i]._battler = null;
this.events()[i]._respawn = oldRespawn;
}
}
// TODO setup player?
};
})();
//-----------------------------------------------------------------------------
// Game_Action
function Game_ABSAction() {
this.initialize.apply(this, arguments);
}
(function() {
Game_ABSAction.prototype = Object.create(Game_Action.prototype);
Game_ABSAction.prototype.constructor = Game_ABSAction;
Game_ABSAction.prototype.setSubject = function(subject) {
Game_Action.prototype.setSubject.call(this, subject);
this._realSubject = subject;
};
Game_ABSAction.prototype.subject = function() {
return this._realSubject;
};
Game_ABSAction.prototype.absApply = function(target) {
var result = target.result();
this._realSubject.clearResult();
result.clear();
result.physical = this.isPhysical();
result.drain = this.isDrain();
if (this.item().damage.type > 0) {
result.critical = (Math.random() < this.itemCri(target));
var value = this.makeDamageValue(target, result.critical);
this.executeDamage(target, value);
target.startDamagePopup();
}
this.item().effects.forEach(function(effect) {
this.applyItemEffect(target, effect);
}, this);
this.applyItemUserEffect(target);
};
var Alias_Game_ActionResult_clear = Game_ActionResult.prototype.clear;
Game_ActionResult.prototype.clear = function() {
Alias_Game_ActionResult_clear.call(this);
this.damageIcon = null;
};
})();
//-----------------------------------------------------------------------------
// Game_BattlerBase
(function() {
var Alias_Game_BattlerBase_resetStateCounts = Game_BattlerBase.prototype.resetStateCounts;
Game_BattlerBase.prototype.resetStateCounts = function(stateId) {
Alias_Game_BattlerBase_resetStateCounts.call(this, stateId);
this._stateSteps[stateId] = $dataStates[stateId].stepsToRemove || 0;
};
var Alias_Game_BattlerBase_addNewState = Game_BattlerBase.prototype.addNewState;
Game_BattlerBase.prototype.addNewState = function(stateId) {
Alias_Game_BattlerBase_addNewState.call(this, stateId);
if ($dataStates[stateId].meta.moveSpeed) {
this._moveSpeed += Number($dataStates[stateId].meta.moveSpeed) || 0;
}
if ($dataStates[stateId].meta.stun) {
this._isStunned++;
}
};
})();
//-----------------------------------------------------------------------------
// Game_Battler
(function() {
var Alias_Game_Battler_initMembers = Game_Battler.prototype.initMembers;
Game_Battler.prototype.initMembers = function() {
Alias_Game_Battler_initMembers.call(this);
this._isStunned = 0;
this._moveSpeed = 0;
this._damageQueue = [];
};
var Alias_Game_Battler_startDamagePopup = Game_Battler.prototype.startDamagePopup;
Game_Battler.prototype.startDamagePopup = function() {
this._damageQueue.push(Object.assign({}, this._result));
Alias_Game_Battler_startDamagePopup.call(this);
};
Game_Battler.prototype.updateABS = function() {
var states = this.states();
for (var i = 0; i < states.length; i++) {
this.updateStateSteps(states[i]);
}
//this.showAddedStates(); //Currently does nothing, so no need to run it
//this.showRemovedStates(); //Currently does nothing, so no need to run it
};
Game_Battler.prototype.stepsForTurn = function() {
return 60;
};
Game_Battler.prototype.updateStateSteps = function(state) {
if (!state.removeByWalking) return;
if (this._stateSteps[state.id] >= 0) {
if (this._stateSteps[state.id] % this.stepsForTurn() === 0) {
this.onTurnEnd();
this.result().damageIcon = $dataStates[state.id].iconIndex;
this.startDamagePopup();
if (this._stateSteps[state.id] === 0) this.removeState(state.id);
}
this._stateSteps[state.id]--;
}
};
Game_Battler.prototype.showAddedStates = function() {
// TODO
this.result().addedStateObjects().forEach(function(state) {
// does nothing
}, this);
};
Game_Battler.prototype.showRemovedStates = function() {
// TODO
this.result().removedStateObjects().forEach(function(state) {
// Popup that state was removed?
}, this);
};
var Alias_Game_Battler_removeState = Game_Battler.prototype.removeState;
Game_Battler.prototype.removeState = function(stateId) {
if (this.isStateAffected(stateId)) {
if ($dataStates[stateId].meta.moveSpeed) {
this._moveSpeed -= Number($dataStates[stateId].meta.moveSpeed) || 0;
}
if ($dataStates[stateId].meta.stun) {
this._isStunned--;
}
}
Alias_Game_Battler_removeState.call(this, stateId);
};
Game_Battler.prototype.moveSpeed = function() {
return this._moveSpeed;
};
Game_Battler.prototype.isStunned = function() {
return this._isStunned > 0;
};
})();
//-----------------------------------------------------------------------------
// Game_Actor
(function() {
var Alias_Game_Actor_setup = Game_Actor.prototype.setup;
Game_Actor.prototype.setup = function(actorId) {
Alias_Game_Actor_setup.call(this, actorId);
var meta = this.actor().qmeta;
this._popupOY = Number(meta.popupOY) || 0;
};
var Alias_Game_Actor_changeClass = Game_Actor.prototype.changeClass;
Game_Actor.prototype.changeClass = function(classId, keepExp) {
Alias_Game_Actor_changeClass.call(this, classId, keepExp);
if (this === $gameParty.leader()) $gameSystem.loadClassABSKeys();
};
Game_Actor.prototype.initWeaponSkills = function() {
var equips = this._equips;
for (var i = 0; i < equips.length; i++) {
if (equips[i].object()) {
var equipId = equips[i].object().baseItemId || equips[i].object().id;
if (equips[i].isWeapon() && equipId) {
this.changeWeaponSkill(equipId);
}
}
}
};
var Alias_Game_Actor_changeEquip = Game_Actor.prototype.changeEquip;
Game_Actor.prototype.changeEquip = function(slotId, item) {
if (this !== $gameParty.leader()) {
return Alias_Game_Actor_changeEquip.call(this, slotId, item);
}
var equips = this._equips;
var oldId, newId = 0;
var wasWeapon;
if (equips[slotId] && equips[slotId].object()) {
oldId = equips[slotId].object().baseItemId || equips[slotId].object().id;
wasWeapon = equips[slotId].isWeapon();
}
Alias_Game_Actor_changeEquip.call(this, slotId, item);
if (equips[slotId] && equips[slotId].object()) {
newId = equips[slotId].object().baseItemId || equips[slotId].object().id;
}
if (newId && newId !== oldId && equips[slotId].isWeapon()) {
this.changeWeaponSkill(newId);
} else if (wasWeapon) {
this.changeWeaponSkill(0);
}
};
Game_Actor.prototype.changeWeaponSkill = function(id) {
if (this !== $gameParty.leader()) return;
var weaponSkills;
if (!$dataWeapons[id]) {
weaponSkills = {};
} else {
weaponSkills = QABS.weaponSkills(id);
}
$gameSystem.changeABSWeaponSkills(weaponSkills);
};
Game_Actor.prototype.displayLevelUp = function(newSkills) {
QABSManager.startPopup('QABS-LEVEL', {
x: $gamePlayer.cx(),
y: $gamePlayer.cy(),
string: 'Level Up!'
})
QABSManager.startAnimation(QABS.levelAnimation, $gamePlayer.cx(), $gamePlayer.cy());
};
Game_Actor.prototype.onPlayerWalk = function() {
this.clearResult();
this.checkFloorEffect();
};
Game_Actor.prototype.updateStateSteps = function(state) {
Game_Battler.prototype.updateStateSteps.call(this, state);
};
Game_Actor.prototype.showAddedStates = function() {
Game_Battler.prototype.showAddedStates.call(this);
};
Game_Actor.prototype.showRemovedStates = function() {
Game_Battler.prototype.showRemovedStates.call(this);
};
Game_Actor.prototype.resetStateCounts = function(stateId) {
Game_Battler.prototype.resetStateCounts.call(this, stateId);
};
Game_Actor.prototype.stepsForTurn = function() {
return Game_Battler.prototype.stepsForTurn.call(this);
};
})();
//-----------------------------------------------------------------------------
// Game_Enemy
(function() {
var Alias_Game_Enemy_setup = Game_Enemy.prototype.setup;
Game_Enemy.prototype.setup = function(enemyId, x, y) {
Alias_Game_Enemy_setup.call(this, enemyId, x, y);
var meta = this.enemy().qmeta;
this._aiType = (meta.AIType || 'simple').toLowerCase();
this._aiRange = Number(meta.range) || 0;
this._noPopup = !!meta.noPopup;
this._popupOY = Number(meta.popupOY) || 0;
this._onDeath = meta.onDeath || '';
this._dontErase = !!meta.dontErase;
this._team = Number(meta.team || 2);
};
Game_Enemy.prototype.clearStates = function() {
Game_Battler.prototype.clearStates.call(this);
this._stateSteps = {};
};
Game_Enemy.prototype.eraseState = function(stateId) {
Game_Battler.prototype.eraseState.call(this, stateId);
delete this._stateSteps[stateId];
};
})();
//-----------------------------------------------------------------------------
// Game_CharacterAgro
function Game_CharacterAgro() {
this.initialize.apply(this, arguments);
}
(function() {
Game_CharacterAgro.agroTimer = 300;
Game_CharacterAgro.prototype.initialize = function(charaId) {
this._charaId = charaId;
this.clear();
};
Game_CharacterAgro.prototype.clear = function() {
this._agrod = 0;
this._points = {};
this._tick = {};
this._total = 0;
this._highest = null;
this._recalcHighest = false;
};
Game_CharacterAgro.prototype.has = function(charaId) {
return !!this._points[charaId];
};
Game_CharacterAgro.prototype.inCombat = function() {
return this._agrod > 0 || this._total > 0;
};
Game_CharacterAgro.prototype.character = function() {
return QPlus.getCharacter(this._charaId) || null;
};
Game_CharacterAgro.prototype.highest = function() {
if (this._recalcHighest) {
this.calcHighest();
}
return this._highest;
};
Game_CharacterAgro.prototype.add = function(charaId, amount) {
this._points[charaId] = this._points[charaId] ? this._points[charaId] + amount : amount;
this._tick[charaId] = Game_CharacterAgro.agroTimer;
var points = this._points[charaId];
this._total += amount;
this._recalcHighest = true;
};
Game_CharacterAgro.prototype.remove = function(charaId) {
this._total -= this._points[charaId] || 0;
delete this._points[charaId];
delete this._tick[charaId];
this._recalcHighest = true;
};
Game_CharacterAgro.prototype.placeInCombat = function() {
this._agro = Game_CharacterAgro.agroTimer;
};
Game_CharacterAgro.prototype.calcHighest = function() {
var highest = 0;
var highestId = null;
for (var charaId in this._points) {
if (this._points[charaId] > highest) {
highest = this._points[charaId];
highestId = charaId;
}
}
this._highest = highestId ? QPlus.getCharacter(highestId) : null;
this._recalcHighest = false;
};
Game_CharacterAgro.prototype.update = function() {
for (var charaId in this._tick) {
this._tick[charaId] = this._tick[charaId] - 1;
if (this._tick[charaId] === 0) {
this.remove(charaId);
}
}
if (this._agro > 0) this._agro--;
};
})();
//-----------------------------------------------------------------------------
// Game_CharacterBase
(function() {
Game_CharacterBase.prototype.battler = function() {
return null;
};
Game_CharacterBase.prototype.clearABS = function() {
if (this._activeSkills && this._activeSkills.length > 0) {
this.clearSkills();
}
this.clearAgro();
this._activeSkills = [];
this._skillCooldowns = {};
this._casting = null;
this._skillLocked = [];
};
Game_CharacterBase.prototype.clearSkills = function() {
for (var i = this._activeSkills.length - 1; i >= 0; i--) {
var skill = this._activeSkills[i];
QABSManager.removePicture(skill.picture);
QABSManager.removePicture(skill.trail);
QABSManager.removePicture(skill.pictureCollider);
this._activeSkills.splice(i, 1);
}
};
Game_CharacterBase.prototype.team = function() {
return 0;
};
Game_CharacterBase.prototype.isFriendly = function(target) {
return target.team() === this.team();
};
Game_CharacterBase.prototype.inCombat = function() {
if (!this.battler()) return false;
return this._inCombat;
};
Game_CharacterBase.prototype.isCasting = function() {
if (this._casting) {
if (this._casting.break) {
this._casting = null;
return false;
}
return true;
}
return false;
};
var Alias_Game_CharacterBase_canMove = Game_CharacterBase.prototype.canMove;
Game_CharacterBase.prototype.canMove = function() {
if (this.battler()) {
if (this._skillLocked.length > 0) return false;
if (this.battler().isStunned()) return false;
}
if (this.realMoveSpeed() <= 0) return false;
return Alias_Game_CharacterBase_canMove.call(this);
};
Game_CharacterBase.prototype.canInputSkill = function(fromEvent) {
if (this._globalLocked > 0) return false;
if (!fromEvent && $gameMap.isEventRunning()) return false;
if (!$gameSystem._absEnabled) return false;
if (!this.battler()) return false;
if (this.battler().isDead()) return false;
if (this.battler().isStunned()) return false;
if (this.isCasting()) return false;
if (this._skillLocked.length > 0) return false;
return true;
};
Game_CharacterBase.prototype.canUseSkill = function(id) {
var skill = $dataSkills[id];
return this.usableSkills().contains(id) && this.battler().canPaySkillCost(skill);
};
Game_CharacterBase.prototype.usableSkills = function() {
return [];
};
var Alias_Game_CharacterBase_realMoveSpeed = Game_CharacterBase.prototype.realMoveSpeed;
Game_CharacterBase.prototype.realMoveSpeed = function() {
var value = Alias_Game_CharacterBase_realMoveSpeed.call(this);
if (this.battler()) {
value += this.battler().moveSpeed();
}
return value;
};
Game_CharacterBase.prototype.inCombat = function() {
if (!this._agro) return false;
return this._agro.inCombat();
};
Game_CharacterBase.prototype.addAgro = function(from, skill) {
var chara = QPlus.getCharacter(from);
if (!chara || chara === this || !chara._agro) {
return;
}
if (this.isFriendly(chara) || !this._agro) {
return;
}
var amt = skill ? skill.agroPoints || 1 : 1;
this._agro.add(from, amt);
};
Game_CharacterBase.prototype.removeAgro = function(from) {
if (!this._agro) {
return;
}
this._agro.remove(from);
};
Game_CharacterBase.prototype.clearAgro = function() {
if (this._agro) {
var agrod = this._agro._agrodList;
for (var charaId in agrod) {
var chara = QPlus.getCharacter(charaId);
if (chara) chara.removeAgro(this.charaId());
}
this._agro.clear();
} else {
this._agro = new Game_CharacterAgro(this.charaId());
}
};
Game_CharacterBase.prototype.bestTarget = function() {
if (!this._agro) {
return null;
}
return this._agro.highest();
};
var Alias_Game_CharacterBase_update = Game_CharacterBase.prototype.update;
Game_CharacterBase.prototype.update = function() {
Alias_Game_CharacterBase_update.call(this);
if (this.battler() && $gameSystem._absEnabled) this.updateABS();
};
Game_CharacterBase.prototype.updateABS = function() {
if (this.battler().isDead()) {
if (!this._isDead) {
this.onDeath();
}
return;
}
this._agro.update();
this.updateSkills();
this.battler().updateABS();
};
Game_CharacterBase.prototype.onDeath = function() {
// Placeholder method, overwritten in Game_Player and Game_Event
};
Game_CharacterBase.prototype.updateSkills = function() {
if (this._groundTargeting) this.updateTargeting();
if (this._activeSkills.length > 0) this.updateSkillSequence();
this.updateSkillCooldowns();
};
Game_CharacterBase.prototype.updateTargeting = function() {
return this.onTargetingEnd();
};
Game_CharacterBase.prototype.updateSkillSequence = function() {
for (var i = this._activeSkills.length - 1; i >= 0; i--) {
this._activeSkills[i].sequencer.update();
}
};
Game_CharacterBase.prototype.updateSkillCooldowns = function() {
for (var id in this._skillCooldowns) {
if (this._skillCooldowns[id] === 0) {
delete this._skillCooldowns[id];
} else {
this._skillCooldowns[id]--;
}
}
};
Game_CharacterBase.prototype.onTargetingEnd = function() {
var skill = this._groundTargeting;
this.battler().paySkillCost(skill.data);
this._activeSkills.push(skill);
this._skillCooldowns[skill.id] = skill.settings.cooldown;
ColliderManager.draw(skill.collider, skill.sequence.length + 60);
this.onTargetingCancel();
};
Game_CharacterBase.prototype.onTargetingCancel = function() {
QABSManager.removePicture(this._groundTargeting.picture);
this._groundTargeting.targeting.kill = true;
this._groundTargeting = null;
this._selectTargeting = null;
};
Game_CharacterBase.prototype.useSkill = function(skillId, fromEvent) {
if (!this.canInputSkill(fromEvent)) return null;
if (!this.canUseSkill(skillId)) return null;
if (this._groundTargeting) {
this.onTargetingCancel();
}
var skill = this.forceSkill(skillId);
if (!this._groundTargeting) {
this.battler().paySkillCost($dataSkills[skillId]);
}
return skill;
};
Game_CharacterBase.prototype.beforeSkill = function(skill) {
// Runs before the skills sequence and collider are made
var before = skill.data.qmeta.beforeSkill || '';
if (before !== '') {
try {
eval(before);
} catch (e) {
console.error('Error with `beforeSkill` meta inside skill ' + skill.data.id, e);
}
}
};
Game_CharacterBase.prototype.forceSkill = function(skillId, forced) {
var skill = this.makeSkill(skillId, forced);
if (skill.settings.groundTarget || skill.settings.selectTarget) {
return this.makeTargetingSkill(skill);
}
this._activeSkills.push(skill);
this._skillCooldowns[skillId] = skill.settings.cooldown;
ColliderManager.draw(skill.collider, skill.sequence.length + 60);
return skill;
};
Game_CharacterBase.prototype.makeSkill = function(skillId, forced) {
var data = $dataSkills[skillId];
var skill = {
id: skillId,
data: data,
settings: QABS.getSkillSettings(data),
sequence: QABS.getSkillSequence(data),
ondmg: QABS.getSkillOnDamage(data),
radian: this._radian,
targetsHit: [],
forced: forced
}
this.beforeSkill(skill);
skill.sequencer = new Skill_Sequencer(this, skill);
skill.collider = this.makeSkillCollider(skill.settings);
return skill;
};
Game_CharacterBase.prototype.makeSkillCollider = function(settings) {
var w1 = this.collider('collision').width;
var h1 = this.collider('collision').height;
settings.collider = settings.collider || ['box', w1, h1];
var collider = ColliderManager.convertToCollider(settings.collider);
var infront = settings.infront === true;
var rotate = settings.rotate === true;
if (rotate) {
if (QABS.radianAtks) {
collider.rotate(Math.PI / 2 + this._radian);
} else {
collider.rotate(Math.PI / 2 + this.directionToRadian(this._direction));
}
}
var x1 = this.cx() - collider.center.x;
var y1 = this.cy() - collider.center.y;
if (infront) {
var w2 = collider.width;
var h2 = collider.height;
var radian;
if (QABS.radianAtks) {
radian = this._radian;
} else {
radian = this.directionToRadian(this._direction);
}
var w3 = Math.cos(radian) * w1 / 2 + Math.cos(radian) * w2 / 2;
var h3 = Math.sin(radian) * h1 / 2 + Math.sin(radian) * h2 / 2;
x1 += w3;
y1 += h3;
}
collider.moveTo(x1, y1);
return collider;
};
Game_CharacterBase.prototype.makeTargetingSkill = function(skill) {
this._groundTargeting = skill;
this._selectTargeting = this.constructor === Game_Event ? true : skill.settings.selectTarget;
var collider = skill.collider;
var diameter = skill.settings.range * 2;
skill.targeting = new Circle_Collider(diameter, diameter);
skill.targeting.moveTo(this.cx() - diameter / 2, this.cy() - diameter / 2);
ColliderManager.draw(skill.targeting, -1);
skill.collider = skill.targeting;
skill.targets = QABSManager.getTargets(skill, this);
skill.collider = collider;
skill.picture = new Sprite_SkillCollider(skill.collider);
if (this._selectTargeting) {
if (skill.targets.length === 0) {
return this.onTargetingCancel();
}
skill.collider.color = '#00ff00';
skill.index = 0;
}
QABSManager.addPicture(skill.picture);
return skill;
};
})();
//-----------------------------------------------------------------------------
// Game_Player
(function() {
var Alias_Game_Player_refresh = Game_Player.prototype.refresh;
Game_Player.prototype.refresh = function() {
Alias_Game_Player_refresh.call(this);
if (this.battler() && this._battlerId !== this.battler()._actorId) {
this.setupBattler();
}
};
Game_Player.prototype.battler = function() {
return this.actor();
};
Game_Player.prototype.setupBattler = function() {
if (!this.battler()) return;
this.clearABS();
this._battlerId = this.battler()._actorId;
this.battler()._charaId = 0;
$gameSystem.loadClassABSKeys();
$gameSystem.changeABSWeaponSkills({});
this.battler().initWeaponSkills();
this._isDead = false;
};
Game_Player.prototype.team = function() {
return 1;
};
var Alias_Game_Player_performTransfer = Game_Player.prototype.performTransfer;
Game_Player.prototype.performTransfer = function() {
if (this.isTransferring()) {
if (this._newMapId !== $gameMap.mapId() || this._needsMapReload) {
if (this._agro) this._agro.clear();
}
}
Alias_Game_Player_performTransfer.call(this);
};
var Alias_Game_Player_canMove = Game_Player.prototype.canMove;
Game_Player.prototype.canMove = function() {
if (QABS.lockTargeting && this._groundTargeting) return false;
return Alias_Game_Player_canMove.call(this);
};
Game_Player.prototype.canInput = function() {
if ($gameMap.isEventRunning() || $gameMessage.isBusy()) {
return false;
}
return this.canInputSkill() && !this._groundTargeting;
};
Game_Player.prototype.usableSkills = function() {
return this.battler().skills().filter(function(skill) {
return !this._skillCooldowns[skill.id];
}, this).map(function(skill) {
return skill.id;
});
};
Game_Player.prototype.onDeath = function() {
this.clearABS();
this._isDead = true;
SceneManager.goto(Scene_Gameover);
};
var Alias_Game_Player_onPositionChange = Game_Player.prototype.onPositionChange;
Game_Player.prototype.onPositionChange = function() {
Alias_Game_Player_onPositionChange.call(this);
if (this._groundTargeting && !QABS.lockTargeting) {
this.onTargetingCancel();
}
};
var Alias_Game_Player_collidesWithEvent = Game_Player.prototype.collidesWithEvent;
Game_Player.prototype.collidesWithEvent = function(event, type) {
if (event.constructor === Game_Loot) {
return event.collider('interaction').intersects(this.collider(type));
}
return Alias_Game_Player_collidesWithEvent.call(this, event, type);
};
Game_Player.prototype.updateABS = function() {
if (this._isDead) return;
if (this.battler() && this.canInput()) this.updateABSInput();
Game_CharacterBase.prototype.updateABS.call(this);
if (this._battlerId !== this.actor()._actorId) {
this.clearABS();
this.setupBattler();
}
};
Game_Player.prototype.updateABSInput = function() {
var absKeys = $gameSystem.absKeys();
for (var key in absKeys) {
if (!absKeys[key]) continue;
var inputs = absKeys[key].input;
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
if (Input.isTriggered(input) || Input.isPressed(input)) {
Input.stopPropagation();
this.useSkill(absKeys[key].skillId);
break;
}
if (input === 'mouse1' && (TouchInput.isTriggered() || TouchInput.isPressed()) && this.canClick()) {
TouchInput.stopPropagation();
this.useSkill(absKeys[key].skillId);
break;
}
if (input === 'mouse2' && TouchInput.isCancelled() && this.canClick()) {
TouchInput.stopPropagation();
this.useSkill(absKeys[key].skillId);
break;
}
}
}
};
Game_Player.prototype.updateTargeting = function() {
return this._selectTargeting ? this.updateSelectTargeting() : this.updateGroundTargeting();
};
Game_Player.prototype.updateSelectTargeting = function() {
// TODO add mouse support
if (Input.isTriggered('pageup')) {
Input.stopPropagation();
this._groundTargeting.index++;
this.updateSkillTarget();
}
if (Input.isTriggered('pagedown')) {
Input.stopPropagation();
this._groundTargeting.index--;
this.updateSkillTarget();
}
if (Input.isTriggered('ok')) {
Input.stopPropagation();
this.onTargetingEnd();
}
if (Input.isTriggered('escape') || TouchInput.isCancelled()) {
TouchInput.stopPropagation();
Input.stopPropagation();
this.onTargetingCancel();
}
};
Game_Player.prototype.updateSkillTarget = function() {
var skill = this._groundTargeting;
if (skill.index < 0) skill.index = skill.targets.length - 1;
if (skill.index >= skill.targets.length) skill.index = 0;
var target = skill.targets[skill.index];
var w = skill.collider.width;
var h = skill.collider.height;
var x = target.cx() - w / 2;
var y = target.cy() - h / 2;
skill.collider.moveTo(x, y);
};
Game_Player.prototype.updateGroundTargeting = function() {
this.updateGroundTargetingPosition();
if (Input.isTriggered('escape') || TouchInput.isCancelled()) {
TouchInput.stopPropagation();
Input.stopPropagation();
this.onTargetingCancel();
}
if (Input.isTriggered('ok') || (this.canClick() && TouchInput.isTriggered()) ||
QABS.quickTarget) {
if (!this._groundTargeting.isOk) {
TouchInput.stopPropagation();
Input.stopPropagation();
this.onTargetingCancel();
} else {
this.onTargetingEnd();
}
}
};
Game_Player.prototype.updateGroundTargetingPosition = function() {
var skill = this._groundTargeting;
var w = skill.collider.width;
var h = skill.collider.height;
if (Imported.QInput && Input.preferGamepad()) {
var x1 = skill.collider.center.x;
var y1 = skill.collider.center.y;
x1 += Input._dirAxesB.x * 5;
y1 += Input._dirAxesB.y * 5;
} else {
var x1 = $gameMap.canvasToMapPX(TouchInput.x);
var y1 = $gameMap.canvasToMapPY(TouchInput.y);
}
var x2 = x1 - w / 2;
var y2 = y1 - h / 2;
this.setRadian(Math.atan2(y1 - this.cy(), x1 - this.cx()));
skill.radian = this._radian;
skill.collider.moveTo(x2, y2);
var dx = Math.abs(this.cx() - x2 - w / 2);
var dy = Math.abs(this.cy() - y2 - h / 2);
var distance = Math.sqrt(dx * dx + dy * dy);
skill.isOk = distance <= skill.settings.range;
skill.collider.color = skill.isOk ? '#00ff00' : '#ff0000';
};
Game_Player.prototype.beforeSkill = function(skill) {
var meta = skill.data.qmeta;
var isGamepad = Imported.QInput && Input.preferGamepad();
if (!meta.dontTurn) {
if (isGamepad && QABS.towardsAnalog) {
var horz = Input._dirAxesB.x;
var vert = Input._dirAxesB.y;
if (horz !== 0 || vert !== 0) {
this.setRadian(Math.atan2(vert, horz));
skill.radian = this._radian;
}
} else if (!isGamepad && QABS.towardsMouse) {
var x1 = $gameMap.canvasToMapPX(TouchInput.x);
var y1 = $gameMap.canvasToMapPY(TouchInput.y);
var x2 = this.cx();
var y2 = this.cy();
this.setRadian(Math.atan2(y1 - y2, x1 - x2));
skill.radian = this._radian;
}
}
if (meta.towardsMove) {
var radian;
if (isGamepad) {
var horz = Input._dirAxesA.x;
var vert = Input._dirAxesA.y;
if (horz === 0 && vert === 0) {
radian = skill.radian;
} else {
radian = Math.atan2(vert, horz);
}
} else {
var direction = QMovement.diagonal ? Input.dir8 : Input.dir4;
if (direction === 0) {
radian = skill.radian;
} else {
radian = this.directionToRadian(direction);
}
}
skill.radian = radian;
}
Game_CharacterBase.prototype.beforeSkill.call(this, skill);
};
Game_Player.prototype.makeTargetingSkill = function(skill) {
Game_CharacterBase.prototype.makeTargetingSkill.call(this, skill);
if (this._selectTargeting) {
this.updateSkillTarget();
}
};
var Alias_Game_Player_requestMouseMove = Game_Player.prototype.requestMouseMove;
Game_Player.prototype.requestMouseMove = function() {
if ($gameSystem.anyAbsMouse()) return this.clearMouseMove();
if (this._groundTargeting) return this.clearMouseMove();
Alias_Game_Player_requestMouseMove.call(this);
};
})();
//-----------------------------------------------------------------------------
// Game_Event
(function() {
var Alias_Game_Event_initialize = Game_Event.prototype.initialize;
Game_Event.prototype.initialize = function(mapId, eventId) {
Alias_Game_Event_initialize.call(this, mapId, eventId);
this.setupBattler();
};
Game_Event.prototype.battler = function() {
return this._battler;
};
Game_Event.prototype.setupBattler = function() {
var foe = /<enemy:([0-9]*?)>/i.exec(this.notes());
if (foe) {
this.clearABS();
this._battlerId = Number(foe[1]);
this._battler = new Game_Enemy(this._battlerId, 0, 0);
this._battler._charaId = this.charaId();
this._skillList = [];
this._aiType = this._battler._aiType;
this._aiRange = this._battler._aiRange || QABS.aiLength;
this._aiWait = 0;
this._aiPathfind = Imported.QPathfind && QABS.aiPathfind && this.validAI();
this._aiSight = Imported.QSight && QABS.aiSight && this.validAI();
if (this._aiSight) {
this.setupSight({
shape: 'circle',
range: this._aiRange / QMovement.tileSize,
handler: 'AI',
targetId: '0'
});
}
var actions = this._battler.enemy().actions;
for (var i = 0; i < actions.length; i++) {
this._skillList.push(actions[i].skillId);
}
this._respawn = -1;
this._onDeath = this._battler._onDeath;
this._noPopup = this._battler._noPopup;
this._dontErase = this._battler._dontErase;
this._team = this._battler._team;
this._isDead = false;
}
};
var Alias_Game_Event_comments = Game_Event.prototype.comments;
Game_Event.prototype.comments = function(withNotes) {
var comments = Alias_Game_Event_comments.call(this, withNotes);
if (!this._aiSight) return comments;
var range = this._aiRange / QMovement.tileSize;
return comments + '<sight:circle,' + range + ', AI, 0>';
};
Game_Event.prototype.canSeeThroughChara = function(chara) {
if (typeof chara.team === 'function' && chara.team() === this.team()) {
return true;
} else if (this._isDead || (typeof chara.battler === 'function' && chara.battler() && chara.battler().isDead())) {
return true;
}
return Game_CharacterBase.prototype.canSeeThroughChara.call(this, chara);
};
Game_Event.prototype.disableEnemy = function() {
$gameSystem.disableEnemy(this._mapId, this._eventId);
this.clearABS();
this._battler = null;
};
Game_Event.prototype.team = function() {
return this._battler ? this._team : 0;
};
Game_Event.prototype.usableSkills = function() {
if (!this._battler) return [];
return this._skillList.filter(function(skillId) {
return !this._skillCooldowns[skillId];
}, this);
};
var Alias_Game_Event_bestTarget = Game_Event.prototype.bestTarget;
Game_Event.prototype.bestTarget = function() {
var best = Alias_Game_Event_bestTarget.call(this);
if (!best && this.team() === 2) {
return $gamePlayer;
}
return best;
};
Game_Event.prototype.updateABS = function() {
if ($gameSystem.isDisabled(this._mapId, this._eventId)) return;
Game_CharacterBase.prototype.updateABS.call(this);
if (this.page() && !this._isDead && this.isNearTheScreen() && this.validAI()) {
return this.updateAI(this._aiType);
}
if (this._respawn >= 0) {
this.updateRespawn();
}
};
Game_Event.prototype.validAI = function() {
// if added new AI types, expand here with its name so the
// updateAI will run
return this._aiType === "simple";
};
Game_Event.prototype.updateAI = function(type) {
if (type === 'simple') {
return this.updateAISimple();
}
// to add more AI types, alias this function
// and do something similar to above
};
Game_Event.prototype.updateAISimple = function() {
var bestTarget = this.bestTarget();
if (!bestTarget) return;
var targetId = bestTarget.charaId();
if (!this.AISimpleInRange(bestTarget)) return;
this.AISimpleAction(bestTarget, this.AISimpleGetAction(bestTarget));
};
Game_Event.prototype.removeAgro = function(charaId) {
if (!this._agro) return;
Game_CharacterBase.prototype.removeAgro.call(this, charaId);
if (!this.inCombat() && !this._endWait) {
this.endCombat();
}
};
Game_Event.prototype.AISimpleInRange = function(bestTarget) {
var targetId = bestTarget.charaId();
if (this.isTargetInRange(bestTarget)) {
this._agro.placeInCombat();
if (!this._agro.has(targetId)) {
this._aiWait = QABS.aiWait;
this.addAgro(targetId);
if (this._aiPathfind) {
this.clearPathfind();
}
}
if (this._endWait) {
this.removeWaitListener(this._endWait);
this._endWait = null;
}
return true;
} else {
if (this._agro.has(targetId)) {
if (this._aiPathfind) {
this.clearPathfind();
}
this._endWait = this.wait(90).then(function() {
this._endWait = null;
this.endCombat();
}.bind(this));
this.removeAgro(targetId);
}
if (this._endWait && this.canMove()) {
this.moveTowardCharacter(bestTarget);
}
return false;
}
return false;
};
Game_Event.prototype.AISimpleGetAction = function(bestTarget) {
var bestAction = null;
if (this._aiWait >= QABS.aiWait) {
this.turnTowardCharacter(bestTarget);
bestAction = QABSManager.bestAction(this.charaId());
this._aiWait = 0;
} else {
this._aiWait++;
}
return bestAction;
};
Game_Event.prototype.AISimpleAction = function(bestTarget, bestAction) {
if (bestAction) {
var skill = this.useSkill(bestAction);
if (skill) skill._target = bestTarget;
} else if (this.canMove()) {
if (this._aiPathfind) {
var dx = bestTarget.cx() - this.cx();
var dy = bestTarget.cy() - this.cy();
var mw = this.collider('collision').width + bestTarget.collider('collision').width;
var mh = this.collider('collision').height + bestTarget.collider('collision').height;
if (Math.abs(dx) <= mw && Math.abs(dy) <= mh) {
this.clearPathfind();
this.moveTowardCharacter(bestTarget);
} else {
this.initChase(bestTarget.charaId());
}
} else {
this.moveTowardCharacter(bestTarget);
}
}
};
Game_Event.prototype.isTargetInRange = function(target) {
if (!target) return false;
if (this._aiSight) {
var prev = this._sight.range;
if (this.inCombat()) {
this._sight.range = this._aiRange + QMovement.tileSize * 3;
} else {
this._sight.range = this._aiRange;
}
this._sight.range /= QMovement.tileSize;
if (prev !== this._sight.range) {
if (this._sight.base) {
this._sight.base.kill = true;
this._sight.base.id = 'sightOld' + this.charaId();
}
this._sight.base = null;
this._sight.reshape = true;
}
if (this._sight.targetId !== target.charaId()) {
delete this._sight.cache.charas[this._sight.targetId];
this._sight.targetId = target.charaId();
this._sight.reshape = true;
}
if (this._sight.reshape) {
this.updateSight();
}
var key = [this._mapId, this._eventId, this._sight.handler];
return $gameSelfSwitches.value(key);
}
var dx = Math.abs(target.cx() - this.cx());
var dy = Math.abs(target.cy() - this.cy());
var range = this._aiRange + (this.inCombat() ? 96 : 0);
return dx <= range && dy <= range;
};
Game_Event.prototype.updateRespawn = function() {
if (this._respawn === 0) {
this.respawn();
} else {
this._respawn--;
}
};
Game_Event.prototype.respawn = function() {
this._erased = false;
this.refresh();
this.findRespawnLocation();
this.setupBattler();
};
Game_Event.prototype.endCombat = function() {
if (this._aiPathfind) {
this.clearPathfind();
}
this.clearAgro();
if (this._aiPathfind || Imported.QPathfind) {
var x = this.event().x * QMovement.tileSize;
var y = this.event().y * QMovement.tileSize;
this.initPathfind(x, y, {
smart: 1,
adjustEnd: true
});
} else {
this.findRespawnLocation();
}
this.refresh();
};
Game_Event.prototype.findRespawnLocation = function() {
var x = this.event().x * QMovement.tileSize;
var y = this.event().y * QMovement.tileSize;
if (this.canPixelPass(x, y, 5)) {
this.setPixelPosition(x, y);
this.straighten();
this.refreshBushDepth();
return;
}
var dist = Math.min(this.collider('collision').width, this.collider('collision').height);
dist = Math.max(dist / 2, this.moveTiles());
var open = [x + ',' + y];
var closed = [];
var current;
var x2;
var y2;
while (open.length) {
current = open.shift();
closed.push(current);
current = current.split(',').map(Number);
var passed;
for (var i = 1; i < 5; i++) {
var dir = i * 2;
x2 = Math.round($gameMap.roundPXWithDirection(current[0], dir, dist));
y2 = Math.round($gameMap.roundPYWithDirection(current[1], dir, dist));
if (this.canPixelPass(x2, y2, 5)) {
passed = true;
break;
}
var key = x2 + ',' + y2;
if (!closed.contains(key) && !open.contains(key)) {
open.push(key);
}
}
if (passed) break;
}
this.setPixelPosition(x2, y2);
this.straighten();
this.refreshBushDepth();
};
Game_Event.prototype.onDeath = function() {
if (this._onDeath) {
try {
eval(this._onDeath);
} catch (e) {
var id = this.battler()._enemyId;
console.error('Error with `onDeath` meta inside enemy ' + id, e);
}
}
if (this._agro.has(0)) {
var exp = this.battler().exp();
$gamePlayer.battler().gainExp(exp);
if (exp > 0) {
QABSManager.startPopup('QABS-EXP', {
x: $gamePlayer.cx(), y: $gamePlayer.cy(),
string: 'Exp: ' + exp
});
}
this.setupLoot();
}
this.clearABS();
this._respawn = Number(this.battler().enemy().meta.respawn) || -1;
this._isDead = true;
if (!this._dontErase) this.erase();
};
Game_Event.prototype.setupLoot = function() {
var x, y;
var loot = [];
this.battler().makeDropItems().forEach(function(item) {
x = this.x + (Math.random() / 2) - (Math.random() / 2);
y = this.y + (Math.random() / 2) - (Math.random() / 2);
var type = 0;
if (DataManager.isWeapon(item)) type = 1;
if (DataManager.isArmor(item)) type = 2;
loot.push(QABSManager.createItem(x, y, item.id, type));
}.bind(this));
if (this.battler().gold() > 0) {
x = this.x + (Math.random() / 2) - (Math.random() / 2);
y = this.y + (Math.random() / 2) - (Math.random() / 2);
loot.push(QABSManager.createGold(x, y, this.battler().gold()));
}
if (this.battler().enemy().meta.autoLoot) {
var prevAoeLoot = QABS.aoeLoot;
QABS.aoeLoot = false;
loot.forEach(function(loot) {
loot.collectDrops();
});
}
};
Game_Event.prototype.onTargetingEnd = function() {
var skill = this._groundTargeting;
var target = skill.targets[Math.floor(Math.random() * skill.targets.length)];
var w = skill.collider.width;
var h = skill.collider.height;
var x = target.cx() - w / 2;
var y = target.cy() - h / 2;
skill.collider.moveTo(x, y);
skill.picture.move(x + w / 2, y + h / 2);
Game_CharacterBase.prototype.onTargetingEnd.call(this);
};
})();
//-----------------------------------------------------------------------------
// Game_Loot
function Game_Loot() {
this.initialize.apply(this, arguments);
}
(function() {
Game_Loot.prototype = Object.create(Game_Event.prototype);
Game_Loot.prototype.constructor = Game_Loot;
Game_Loot.prototype.initialize = function(x, y) {
Game_Character.prototype.initialize.call(this);
this.isLoot = true;
this._decay = QABS.lootDecay;
this._eventId = -1;
this._gold = null;
this._loot = null;
this._noSprite = true;
this.locate(x, y);
QABSManager.addEvent(this);
this.refresh();
};
Game_Loot.prototype.event = function() {
return {
note: ''
}
};
Game_Loot.prototype.shiftY = function() {
return 0;
};
Game_Loot.prototype.setGold = function(value) {
this._gold = value;
this.setIcon(QABS.goldIcon);
};
Game_Loot.prototype.setItem = function(item) {
this._loot = item;
this.setIcon(item.iconIndex);
};
Game_Loot.prototype.setIcon = function(iconIndex) {
this._iconIndex = iconIndex;
this._itemIcon = new Sprite_Icon(iconIndex);
this._itemIcon.move(this._px, this._py);
this._itemIcon.z = 1;
this._itemIcon._isFixed = true;
QABSManager.addPicture(this._itemIcon);
};
Game_Loot.prototype.page = function() {
if (!this._lootPage) {
this._lootPage = {
conditions: {
actorId: 1, actorValid: false,
itemId: 1, itemValid: false,
selfSwitchCh: 'A', selfSwitchValid: false,
switch1Id: 1, switch1Valid: false,
switch2Id: 1, switch2Valid: false,
variable1Id: 1, variable1Valid: false, variableValue: 0
},
image: {
characterIndex: 0, characterName: '',
direction: 2, pattern: 1, tileId: 0
},
moveRoute: {
list: [{ code: 0, parameters: [] }],
repeat: false, skippable: false, wait: false
},
list: [],
directionFix: false,
moveFrequency: 4,
moveSpeed: 3,
moveType: 0,
priorityType: 0,
stepAnime: false,
through: true,
trigger: QABS.lootTrigger,
walkAnime: true
};
this._lootPage.list = [];
this._lootPage.list.push({
code: 355,
indent: 0,
parameters: ['this.character().collectDrops();']
});
this._lootPage.list.push({
code: 0,
indent: 0,
parameters: [0]
});
}
return this._lootPage;
};
Game_Loot.prototype.findProperPageIndex = function() {
return 0;
};
Game_Loot.prototype.collectDrops = function() {
if (QABS.aoeLoot) {
return this.aoeCollect();
}
if (this._loot) $gameParty.gainItem(this._loot, 1);
if (this._gold) $gameParty.gainGold(this._gold);
var string = this._gold ? String(this._gold) : this._loot.name;
if (this._iconIndex) {
string = '\\I[' + this._iconIndex + ']' + string;
}
QABSManager.startPopup('QABS-ITEM', {
x: this.cx(), y: this.cy(),
string: string
});
this.erase();
QABSManager.removeEvent(this);
QABSManager.removePicture(this._itemIcon);
};
Game_Loot.prototype.aoeCollect = function() {
var loot = ColliderManager.getCharactersNear(this.collider(), function(chara) {
return chara.constructor === Game_Loot &&
chara.collider().intersects(this.collider());
}.bind(this));
var x = this.cx();
var y = this.cy();
var totalLoot = [];
var totalGold = 0;
var i;
for (i = 0; i < loot.length; i++) {
if (loot[i]._loot) totalLoot.push(loot[i]._loot);
if (loot[i]._gold) totalGold += loot[i]._gold;
QABSManager.removeEvent(loot[i]);
QABSManager.removePicture(loot[i]._itemIcon);
}
var display = {};
for (i = 0; i < totalLoot.length; i++) {
var item = totalLoot[i];
$gameParty.gainItem(item, 1);
display[item.name] = display[item.name] || {};
display[item.name].iconIndex = item.iconIndex;
display[item.name].total = display[item.name].total + 1 || 1;
}
for (var name in display) {
var iconIndex = display[name].iconIndex;
var string = 'x' + display[name].total + ' ' + name;
if (iconIndex) {
string = '\\I[' + iconIndex + ']' + string;
}
QABSManager.startPopup('QABS-ITEM', {
x: x, y: y,
string: string
});
y += 22;
}
if (totalGold > 0) {
$gameParty.gainGold(totalGold);
var string = String(totalGold);
if (QABS.goldIcon) {
string = '\\I[' + QABS.goldIcon + ']' + string;
}
QABSManager.startPopup('QABS-ITEM', {
x: x, y: y,
string: string
});
}
};
Game_Loot.prototype.update = function() {
if (this._decay <= 0) {
this.erase();
QABSManager.removeEvent(this);
QABSManager.removePicture(this._itemIcon);
return;
}
this._decay--;
};
Game_Loot.prototype.defaultColliderConfig = function() {
return 'box,48,48,-8,-8';
};
Game_Loot.prototype.castsShadow = function() {
return false;
};
})();
//-----------------------------------------------------------------------------
// Scene_Map
(function() {
var Alias_Scene_Map_initialize = Scene_Map.prototype.initialize;
Scene_Map.prototype.initialize = function() {
Alias_Scene_Map_initialize.call(this);
$gameSystem.preloadAllSkills();
};
var Alias_Scene_Map_isMenuCalled = Scene_Map.prototype.isMenuCalled;
Scene_Map.prototype.isMenuCalled = function() {
if ($gameSystem.anyAbsMouse2()) return Input.isTriggered('menu');
return Alias_Scene_Map_isMenuCalled(this);
};
})();
//-----------------------------------------------------------------------------
// Sprite_Character
(function() {
var Alias_Sprite_Character_initMembers = Sprite_Character.prototype.initMembers;
Sprite_Character.prototype.initMembers = function() {
Alias_Sprite_Character_initMembers.call(this);
this.createStateSprite();
};
Sprite_Character.prototype.createStateSprite = function() {
this._stateSprite = new Sprite_StateOverlay();
this.addChild(this._stateSprite);
};
var Alias_Sprite_Character_update = Sprite_Character.prototype.update;
Sprite_Character.prototype.update = function() {
Alias_Sprite_Character_update.call(this);
if (this._character) this.updateBattler();
if (this._battler) this.updateDamagePopup();
};
Sprite_Character.prototype.updateDamagePopup = function() {
this.setupDamagePopup();
};
Sprite_Character.prototype.updateBattler = function() {
if (this._battler !== this._character.battler()) {
this.setBattler(this._character.battler());
}
};
Sprite_Character.prototype.setBattler = function(battler) {
this._battler = battler;
this._stateSprite.setup(this._battler);
};
Sprite_Character.prototype.setupDamagePopup = function() {
if (!Imported.QPopup || this._character._noPopup) return;
if (this._battler._damageQueue.length > 0) {
var string;
var fill = '#ffffff';
var result = this._battler._damageQueue.shift();
var type = 'DMG';
if (result.missed || result.evaded) {
string = 'Missed';
type = 'MISSED';
} else if (result.hpAffected) {
var dmg = result.hpDamage;
string = String(Math.abs(dmg));
if (dmg >= 0) {
type = 'DMG';
} else {
type = 'HEAL';
}
} else if (result.mpDamage) {
string = String(result.mpDamage);
type = 'MP';
}
if (!string && string !== '0') return;
var iconIndex = result.damageIcon;
if (iconIndex) {
string = '\\I[' + iconIndex + ']' + string;
}
if (result.critical) {
type += '-CRIT';
}
QABSManager.startPopup('QABS-' + type, {
string: string,
oy: this._battler._popupOY,
bindTo: this._character.charaId(),
duration: 80
});
this._battler.clearDamagePopup();
this._battler.clearResult();
}
};
})();
//-----------------------------------------------------------------------------
// Sprite_Icon
function Sprite_Icon() {
this.initialize.apply(this, arguments);
}
(function() {
Sprite_Icon.prototype = Object.create(Sprite.prototype);
Sprite_Icon.prototype.constructor = Sprite_Icon;
Sprite_Icon.prototype.initialize = function(index, sheet, w, h) {
Sprite.prototype.initialize.call(this);
this._iconIndex = index;
this._iconSheet = sheet || 'IconSet';
this._iconW = w || 32;
this._iconH = h || 32;
this._realX = this.x;
this._realY = this.y;
this._isFixed = false;
this.setBitmap();
};
Sprite_Icon.prototype.setBitmap = function() {
this.bitmap = ImageManager.loadSystem(this._iconSheet);
var pw = this._iconW;
var ph = this._iconH;
var sx = this._iconIndex % 16 * pw;
var sy = Math.floor(this._iconIndex / 16) * ph;
this.setFrame(sx, sy, pw, ph);
};
Sprite_Icon.prototype.update = function() {
Sprite.prototype.update.call(this);
if (this._isFixed) this.updatePosition();
};
Sprite_Icon.prototype.updatePosition = function() {
this.x = this._realX;
this.x -= $gameMap.displayX() * QMovement.tileSize;
this.y = this._realY;
this.y -= $gameMap.displayY() * QMovement.tileSize;
};
Sprite_Icon.prototype.move = function(x, y) {
Sprite.prototype.move.call(this, x, y);
this._realX = x;
this._realY = y;
this.updatePosition();
};
})();
//-----------------------------------------------------------------------------
// Sprite_SkillPicture
function Sprite_SkillPicture() {
this.initialize.apply(this, arguments);
}
(function() {
Sprite_SkillPicture.prototype = Object.create(Sprite.prototype);
Sprite_SkillPicture.prototype.constructor = Sprite_SkillPicture;
Sprite_SkillPicture.prototype.initialize = function() {
Sprite.prototype.initialize.call(this);
this._maxFrames = 1;
this._speed = 0;
this._isAnimated = false;
this._tick = 0;
this._frameI = 0;
this._lastFrameI = null;
this._realX = this.x;
this._realY = this.y;
};
Sprite_SkillPicture.prototype.setupAnim = function(frames, speed) {
this._isAnimated = true;
this._maxFrames = frames;
this._speed = speed;
};
Sprite_SkillPicture.prototype.update = function() {
Sprite.prototype.update.call(this);
this.updatePosition();
if (this._isAnimated) this.updateAnimation();
this.updateFrame();
};
Sprite_SkillPicture.prototype.updatePosition = function() {
this.x = this._realX;
this.x -= $gameMap.displayX() * QMovement.tileSize;
this.y = this._realY;
this.y -= $gameMap.displayY() * QMovement.tileSize;
};
Sprite_SkillPicture.prototype.updateAnimation = function() {
if (this._tick % this._speed === 0) {
this._frameI = (this._frameI + 1) % this._maxFrames;
}
this._tick = (this._tick + 1) % this._speed;
};
Sprite_SkillPicture.prototype.updateFrame = function() {
if (this._lastFrameI !== null) {
if (this._lastFrameI === this._frameI) return;
}
var i = this._frameI;
var pw = this.bitmap.width / this._maxFrames;
var ph = this.bitmap.height;
var sx = i * pw;
this.setFrame(sx, 0, pw, ph);
this._lastFrameI = i;
};
Sprite_SkillPicture.prototype.move = function(x, y) {
Sprite.prototype.move.call(this, x, y);
this._realX = x;
this._realY = y;
this.updatePosition();
};
})();
//-----------------------------------------------------------------------------
// Sprite_SkillTrail
function Sprite_SkillTrail() {
this.initialize.apply(this, arguments);
}
(function() {
Sprite_SkillTrail.prototype = Object.create(TilingSprite.prototype);
Sprite_SkillTrail.prototype.constructor = Sprite_SkillTrail;
Sprite_SkillTrail.prototype.initialize = function() {
TilingSprite.prototype.initialize.call(this);
this._realX = this.x;
this._realY = this.y;
};
Sprite_SkillTrail.prototype.update = function() {
TilingSprite.prototype.update.call(this);
this.updatePosition();
};
Sprite_SkillTrail.prototype.updatePosition = function() {
this.x = this._realX;
this.x -= $gameMap.displayX() * QMovement.tileSize;
this.y = this._realY;
this.y -= $gameMap.displayY() * QMovement.tileSize;
};
Sprite_SkillTrail.prototype.move = function(x, y, width, height) {
TilingSprite.prototype.move.call(this, x, y, width, height);
this._realX = x;
this._realY = y;
this.updatePosition();
};
})();
//-----------------------------------------------------------------------------
// Sprite_MapAnimation
function Sprite_MapAnimation() {
this.initialize.apply(this, arguments);
}
(function() {
Sprite_MapAnimation.prototype = Object.create(Sprite_Base.prototype);
Sprite_MapAnimation.prototype.constructor = Sprite_MapAnimation;
Sprite_MapAnimation.prototype.initialize = function(animation) {
Sprite_Base.prototype.initialize.call(this);
this.z = 8;
this._realX = this.x;
this._realY = this.y;
this._animation = animation;
this._hasStarted = false;
};
Sprite_MapAnimation.prototype.update = function() {
Sprite_Base.prototype.update.call(this);
this.updatePosition();
if (!this._hasStarted && this.parent) {
this.startAnimation(this._animation, false, 0);
this._hasStarted = true;
}
if (this._hasStarted && !this.isAnimationPlaying()) {
QABSManager.removeAnimation(this);
}
};
Sprite_MapAnimation.prototype.updatePosition = function() {
this.x = this._realX;
this.x -= $gameMap.displayX() * QMovement.tileSize;
this.y = this._realY;
this.y -= $gameMap.displayY() * QMovement.tileSize;
};
Sprite_MapAnimation.prototype.move = function(x, y) {
Sprite_Base.prototype.move.call(this, x, y);
this._realX = x;
this._realY = y;
this.updatePosition();
};
})();
//-----------------------------------------------------------------------------
// Sprite_SkillCollider
function Sprite_SkillCollider() {
this.initialize.apply(this, arguments);
}
(function() {
Sprite_SkillCollider.prototype = Object.create(Sprite_Collider.prototype);
Sprite_SkillCollider.prototype.constructor = Sprite_SkillCollider;
Sprite_SkillCollider.prototype.initialize = function(collider) {
Sprite_Collider.prototype.initialize.call(this, collider, -1);
this.z = 2;
this.alpha = 0.4;
this.anchor.x = 0.5;
this.anchor.y = 0.5;
this._frameCount = 0;
};
Sprite_SkillCollider.prototype.update = function() {
Sprite_Collider.prototype.update.call(this);
this.updateAnimation();
};
Sprite_SkillCollider.prototype.updateAnimation = function() {
this._frameCount++;
if (this._frameCount > 30) {
this.alpha += 0.2 / 30;
this.scale.x += 0.1 / 30;
this.scale.y = this.scale.x;
if (this._frameCount === 60) this._frameCount = 0;
} else {
this.alpha -= 0.2 / 30;
this.scale.x -= 0.1 / 30;
this.scale.y = this.scale.x;
}
};
})();
//-----------------------------------------------------------------------------
// Spriteset_Map
(function() {
var Alias_Spriteset_Map_createLowerLayer = Spriteset_Map.prototype.createLowerLayer;
Spriteset_Map.prototype.createLowerLayer = function() {
Alias_Spriteset_Map_createLowerLayer.call(this);
this._pictures = [];
this._tempAnimations = [];
};
Spriteset_Map.prototype.addPictures = function() {
this._pictures = QABSManager._pictures;
if (this._pictures.length === 0) return;
for (var i = 0; i < this._pictures.length; i++) {
if (this.children.indexOf(this._pictures[i]) !== -1) continue;
this._tilemap.addChild(this._pictures[i]);
}
};
Spriteset_Map.prototype.addAnimations = function() {
this._tempAnimations = QABSManager._animations;
if (this._tempAnimations.length === 0) return;
for (var i = 0; i < this._tempAnimations.length; i++) {
if (this.children.indexOf(this._tempAnimations[i]) !== -1) continue;
this._tilemap.addChild(this._tempAnimations[i]);
if (this._tempAnimations[i].isAnimationPlaying()) {
for (var j = 0; j < this._tempAnimations[i]._animationSprites.length; j++) {
this._tilemap.addChild(this._tempAnimations[i]._animationSprites[j]);
}
}
}
};
var Alias_Spriteset_Map_updateTilemap = Spriteset_Map.prototype.updateTilemap;
Spriteset_Map.prototype.updateTilemap = function() {
Alias_Spriteset_Map_updateTilemap.call(this);
if (this._pictures !== QABSManager._pictures) this.addPictures();
if (this._tempAnimations !== QABSManager._animations) this.addAnimations();
};
})();
You can’t perform that action at this time.