Jump to content
Lecode

Ace GTBS Add-on: Customisable AOE

Recommended Posts

Introduction
(Sorry for my bad english)
I waited the final version of the sublime GTBS to start one of my projects.
But I noticed that the version offered too little personalization on areas of spells and simple attacks.
So I tried to improve the management.
So for those interested:
This script gives you the ability to fully configure AOE of skills, weapons
and monsters attacks. It's also improve line skills.
 
N.B: All criticism of the code is welcome.
 
Features
-Customisable AOE for skills, weapons and monsters simple attack
-Different area from the direction of the attacker.
-Independent "line" skill
-AI is not disturbed and takes full advantage of areas.
 
Screens
130712104019148257.png
-----
130712104126501235.png
-----
130712104216389268.png
-----
130712104303141572.jpg
 
Configuration
-->To create an AOE.
Firstly you must choose the desired use of the AOE. You can set an AOE for
the up, down, right and left directions; and a general AOE. ( See the screen above )
A general AOE applies to any direction of the user.
Now, puts the tags in skill's not box:
 

You want a general AOE:
<g_aoe: string>     => For General AOE
You want an AOE Which changes according to caster directions :
<r_aoe: string>     => AOE for right direction
<l_aoe: string>     => AOE for left direction
<u_aoe: string>     
<d_aoe: string>
 

Then, to create an area of ​​effect, it's simple:
Imagine a skill that effect on a square area, like this:
130712112541605701.png
---
You need to know the x and y of all red cells in relation with the center. The center is the origin. X = 0 and Y = 0.
Then, when you know all x and y of the cells that will form the area, you can edit the tags.
You must write your area of ​​effect in tabular form, whith couple of x and y.
In the notetags, x and y meeans respectivly x and y of the cursor. So, [x,y] means the cell of the cursor.
So, to write the first cell : [x-1,y+1]. See the picture bellow.
And ect.
130712112839718559.png
 
You can make special AOE, like in the screen where the acor 1 is linked all the time.
Example:
 

<g_aoe: [  [x,y],[$game_actors[1].x,$game_actors[1].y] ]>
 ## [x,y] is the cursor cell

 
 
So you can do an skill that hit an spesific battler or an specific case.( But regardless of the scope.)
If you put [2,1], the skill will always hit the cell(x=2,y=1) on the map.
And don't forget to put [x,y] in the tag to add the cursor cell in the AOE and remain that all cells must be write between [     ].
Like this =>          <r_aoe:   [x,y],[x-1,y]   ]>
 
2-Monster an weapons AOE
For this first version, weapons and monsters do not have their own own AOE.
Just put this tags to use the AOE of a skill.
 

<AOE_skill: skill_id>
 


 
Script ( Place it below all GTBS scripts )
Version 1.1

#################################################################################
### ACE GTBS ADD-ON: Customisable AOE V.1.1
### By Lecode
### 07 12, 2013
###############################
# Version 1.0
#  -customisable AOE for skills, weapons and monsters simple attack
#  -Different area from the directions of the attacker.
#  -Independent "line" skill
#  -AI is not disturbed and takes full advantage of areas.
# Know Bugs or disfonctionment:
#  -Apparently the AI application does not calculate new areas on its first use only.
#
# Version 1.1 ( 07 , 14, 2013 )
#  -Fixed an epic bug o.o
#################################################################################
# This script gives you the ability to fully configure area effects of skills,weapons
# and monsters attacks.
#
#=== HOW TO CONFIGURE AN AOE ?? =====
# Firstly you must choose the desired use of the AOE. You can set an AOE for
# the up, down, right and left directions; and a general AOE.
# A general AOE applies to any direction of the user.
# Now, puts the tags in skill's not box:
=begin
<g_aoe: string>     => For General AOE
<r_aoe: string>     => Right AOE
<l_aoe: string>     => Left AOE
<u_aoe: string>     
<d_aoe: string>
=end
# So, to create an area of ​​effect, it's simple:
# Imagine a skill that effect on a square area, like this:
=begin
aaa
aoa      o = center of the cursor
aaa
=end
# You need to know the x and y of all "a" cells in relation with the cell "O"
# So, the first cell "a" have: x = -1 and y = 1.
# Then, when you know all x and y of the cells that will form the area, you can put the tags.
# You must write your area of ​​effect in tabular form, whith couple of x and y.
# In the notetags, x and y meean respectivly x and y of the sursor. [x,y] means cursor cell.
# So, to write the first cell : [x-1,y+1]
# And ect.
#
# Finaly we have:
#<g_aoe: [   [x,y+1],[x,y-1],[x-1,y],[x-1,y+1],[x-1,y-1],[x+1,y],[x+1,y+1],[x+1,y-1]    ]>
#
# Note that all cells must be write between [     ].

#=== FOR WEAPONS AND MONSTERS ATTACK ?? =====
# For this first version, weapons and monsters do not have their own own AOE.
# Just put this tags to use the AOE of a skill.
# <AOE_skill: skill_id>
#=======================================================================================================

module Lecode_CostumeAOE

GENERAL_AOE = /<g_aoe: (.*)>/i
RIGHT_AOE = /<r_aoe: (.*)>/i
LEFT_AOE = /<l_aoe: (.*)>/i
UP_AOE = /<u_aoe: (.*)>/i
DOWN_AOE = /<d_aoe: (.*)>/i


Default_AOE_skill_forweapons = 1
Default_AOE_skill_forenemies_simple_atk = 1
end # module

class Scene_Battle_TBS < Scene_Base
#-------------------------------------------------------------------------
#  update_window_skill
#-------------------------------------------------------------------------
def update_window_skill
@windows[Win_Skill].update #update should be called normally but it isnt
@windows[Win_Status].hide
#@windows[Win_Skill].call_update_help
if Input.trigger?(Input::
Sound.play_cancel
close_window_skill
actor_menu_open
elsif Input.trigger?(Input::C)
# Get currently selected data on the skill window
@spell = @windows[Win_Skill].skill
$game_system.current_skill = @spell.id
if @spell and @active_battler.skill_can_use?(@spell)
# Play decision SE
Sound.play_decision
# Set action
@active_battler.current_action.set_skill(@spell.id)
# Make skill window invisible
close_window_skill
@cursor.range = draw_ranges(@active_battler,5)  ;   update_target_cursor
@cursor.mode = TBS_Cursor::Skill
else # If it can't be used
@spell = nil
$game_system.current_skill = Lecode_CostumeAOE::Default_AOE_skill_forweapons
Sound.play_buzzer
end
end
end

#----------------------------------------------------------------------------
# Performs the skill action that was determined previously, by AI
#----------------------------------------------------------------------------
def process_skill
action = @active_battler.current_action
@spell = @active_battler.current_action.item
$game_system.current_skill = @spell.id
@wait_count = 5
@cursor.moveto(action.position)
@cursor.range = draw_ranges(@active_battler, 5) ;    update_target_cursor

if @ATB_Active and GTBS::skill_wait(@spell.id)[0] > 0
setup_skill_wait
else
@active_battler.skill_cast = nil
#@active_battler.mp -= @active_battler.calc_mp_cost(@spell)
@active_battler.use_item(@spell)
@active_battler.count_skill_usage(@spell)
@targets = get_targets
@active_battler.current_action.set_skill(@spell.id)
#@animation1 = 0 #@active_battler.animation1
#@animation2 = [@spell.animation_id]
process_action
end
end

#----------------------------------------------------------------------------
# Perform attack that was determined previously by AI
#----------------------------------------------------------------------------
def process_attack
if @active_battler.is_a?(Game_Actor)
$game_system.current_skill = @active_battler.weapons[0].cloned_aoe_skill
else
$game_system.current_skill = @active_battler.cloned_aoe_skill_for_atk
end
@cursor.moveto( @active_battler.current_action.position)
@cursor.range = draw_ranges(@active_battler, 7) ;   update_target_cursor
@targets = get_targets
@active_battler.perf_action = true
process_action
end
 
#----------------------------------------------------------------------------
# Cursor phase selection
#----------------------------------------------------------------------------
def cursor_active_selection
update_cursor
update_target_cursor
return if
case @cursor.mode
when TBS_Cursor::Item
update_cursor_item
when TBS_Cursor::Skill
update_cursor_skill
when TBS_Cursor::Attack
if @active_battler.weapons[0] != nil
$game_system.current_skill = @active_battler.weapons[0].cloned_aoe_skill
else
$game_system.current_skill = Lecode_CostumeAOE::Default_AOE_skill_forweapons
end
cursor_use_attack
when TBS_Cursor::Move
cursor_use_move
else# No_Select
cursor_no_select
end
end

end#class

class RPG::Skill < RPG::UsableItem
attr_accessor :general_aoe
attr_accessor :right_aoe
attr_accessor :left_aoe
attr_accessor :up_aoe
attr_accessor :down_aoe
attr_accessor :use_general_aoe

def initialise_lecode_caoe
@general_aoe = "[[x,y]]"
@right_aoe = "[[x,y]]"
@left_aoe = "[[x,y]]"
@up_aoe = "[[x,y]]"
@down_aoe = "[[x,y]]"
@use_general_aoe = true
@test_value = []
self.note.split(/[\r\n]+/).each { |line|
case line
when Lecode_CostumeAOE::GENERAL_AOE
@general_aoe = $1.to_s
when Lecode_CostumeAOE::RIGHT_AOE
@use_general_aoe = false
@right_aoe = $1.to_s
when Lecode_CostumeAOE::LEFT_AOE
@use_general_aoe = false
@left_aoe = $1.to_s
when Lecode_CostumeAOE::UP_AOE
@use_general_aoe = false
@up_aoe = $1.to_s
when Lecode_CostumeAOE::DOWN_AOE
@use_general_aoe = false
@down_aoe = $1.to_s
else
end
}

end
end

class RPG::Weapon < RPG::EquipItem
attr_accessor :cloned_aoe_skill
def cloned_aoe_skill
self.note =~ /<AOE_skill:[ ](\d+)?>/i
id = $1.to_i
if id == "" or id == nil or id == 0
id = Lecode_CostumeAOE::Default_AOE_skill_forweapons
end
return id
end#def
end#class

class Game_Enemy < Game_Battler#class RPG::Enemy
attr_accessor :cloned_aoe_skill_for_atk
def cloned_aoe_skill_for_atk
self.note =~ /<AOE_skill:[ ](\d+)?>/i
id = $1.to_i
if id == "" or id == nil or id == 0
id = Lecode_CostumeAOE::Default_AOE_skill_forenemies_simple_atk
end
return id
end#def
end#class


module DataManager
#--------------------------------------------------------------------------
# * Load Database
#--------------------------------------------------------------------------
class <<self; alias load_database_caoe load_database; end
def self.load_database
load_database_caoe
load_database_caoe_notetag
end
def self.load_database_caoe_notetag
for obj in $data_skills
next if obj.nil?
obj.initialise_lecode_caoe
end
end  
end


class TBS_Cursor < POS
#--------------------------------------------------------------------------------------------------------------
#* calc_pos_spell
#  use to draw area of effect for spell or weapon attack
#-------------------------------------------------------------------------------------------------------------
def calculate_aoe( range_max, range_min, x = @x, y = @y, v_range_aoe = 0, dd, user_pos,hit_caster) # mod MGC

skill = $data_skills[$game_system.current_skill]
result = []
if skill.use_general_aoe
#result = eval(skill.general_aoe)
check = eval(skill.general_aoe)
for i in 0..range_max
it = range_max - i  
#test all couples (it, oy) like: 0 <= it+oy <= range_max
for oy in 0..i
next if it+oy < range_min
for ux, uy in check
result.push([ux, uy]) if valid_new_aoe_pos(ux, uy, x , y, v_range_aoe) and not result.include?([ux, uy]) # mod MGC
end
end
end
else#general_aoe ?
if dd == 2 # bas
check = eval(skill.down_aoe)
for i in 0..range_max
it = range_max - i  
#test all couples (it, oy) like: 0 <= it+oy <= range_max
for oy in 0..i
next if it+oy < range_min
for ux, uy in check
result.push([ux, uy]) if valid_new_aoe_pos(ux, uy, x , y, v_range_aoe) and not result.include?([ux, uy]) # mod MGC
end
end
end
elsif dd == 4 # gauche
check = eval(skill.left_aoe)
for i in 0..range_max
it = range_max - i  
#test all couples (it, oy) like: 0 <= it+oy <= range_max
for oy in 0..i
next if it+oy < range_min
for ux, uy in check
result.push([ux, uy]) if valid_new_aoe_pos(ux, uy, x , y, v_range_aoe) and not result.include?([ux, uy]) # mod MGC
end
end
end
elsif dd == 6 # droite
check = eval(skill.right_aoe)
for i in 0..range_max
it = range_max - i  
#test all couples (it, oy) like: 0 <= it+oy <= range_max
for oy in 0..i
next if it+oy < range_min
for ux, uy in check
result.push([ux, uy]) if valid_new_aoe_pos(ux, uy, x , y, v_range_aoe) and not result.include?([ux, uy]) # mod MGC
end
end
end
elsif dd == 8 # haut
check = eval(skill.up_aoe)
for i in 0..range_max
it = range_max - i  
#test all couples (it, oy) like: 0 <= it+oy <= range_max
for oy in 0..i
next if it+oy < range_min
for ux, uy in check
result.push([ux, uy]) if valid_new_aoe_pos(ux, uy, x , y, v_range_aoe) and not result.include?([ux, uy]) # mod MGC
end
end
end
end#direction
end#use_general_aoe
result -= user_pos if hit_caster == false
return result
$game_system.current_weapon = 0


end#def
end#class cursor



class Game_Battler < Game_BattlerBase
 
def target_zone(move_pos = self.pos, act_pos = current_action.position, type = nil)
return [] unless type.is_a?(Array) and type[0] != nil
line, field, range, exclude_caster, v_range_aoe = type
x = act_pos[0]; y = act_pos[1]
dd = get_direction(POS.new(move_pos[0], move_pos[1]), POS.new(act_pos[0], act_pos[1]))
user = self.id
kind_user = ""
kind_user = "actor" if self.is_a?(Game_Actor)
hit_caster = false if exclude_caster
user_pos = self.positions(move_pos[0],move_pos[1])
result = $tbs_cursor.calculate_aoe( field, 0,  act_pos[0], act_pos[1], v_range_aoe, dd, user_pos, hit_caster)

return result
$game_system.current_weapon = 0
end#def
end#class

#--------------------------------------------------------------------------
# Game System
#--------------------------------------------------------------------------
class Game_System
  #--------------------------------------------------------------------------
  attr_accessor :current_skill
  attr_accessor :current_weapon
  attr_accessor :direction
alias lecode_caoe_ini initialize
def initialize
lecode_caoe_ini
@current_skill = 1
@current_weapon = 0
@direction = 0
end
end

 

Credit

-GubiD

-Lecode

Edited by lecode
  • Like 2

Share this post


Link to post
Share on other sites

Sweet. It's pretty much what I needed since I'm working on a GTBS ace project too.

Share this post


Link to post
Share on other sites

More people need to see this. You should Show GubiD. See if he will include this in any future release of GTBS.  

Share this post


Link to post
Share on other sites

I really do not want to impose.
But over time there will be another add-ons, and this script will not go unnoticed on a list, I think

Share this post


Link to post
Share on other sites

This script is not unnoticed for sure :D. It just people might want to wait first after the release of gtbs2. Some because they want the script to stable first. (Even through beta sometimes first release contain bugs). Some because they plan it for next project. Since they already have another battle system implemented in their current game. So the lack of post is because still few people try this script.

Edited by estriole

Share this post


Link to post
Share on other sites

Heya! I'm using GTBS2.3 and I was playing with your script. I was enjoying the add-on, but I ran into a few problems.

I'm making a 2 player battle simulator for my friends and I to play with. I have some states that takes control away from the players and they go auto for a turn or few.(Fear state when they usually run and sometimes attack. Berserk state where they attack only caring about damage.)

When the AI takes control of the actors(party or enemy) 3 things can happen that are not good.

1. It can take up to 3-5 times the amount of time it takes to decide a turn.

2. The AI appears to change, can and will attack open spaces. Which is something I cannot do while controlling them.

3. I get the following error

Script ' ACE GTBS ADD-ON: Customisable AOE V1.1' line135:
NoMethodError Occurred.
line 135: undefined method 'cloned_aoe_skill' for nil:NilClass

I Believe it has something to do with the Enemy Actors.

 

 

**EDIT**

 

I found 2 more problems.

 

I was trying to make a spear weapon with 2 range. With the ability to attack the tile next to him and the ability to attack that tile and the tile behind that.(line)

I configured a skill to do exactly that and it works exactly as I wanted. I then I add '<AOE_skill: 139>' to my spear and go to test the weapon. Turns out weapons don't have the exclude caster feature so the actor hits himself if he doesn't want to stab through.

Is there another way I can create this effect?

 

The last problem I found is with the directional targeting of large units. With large units(2x2 tiles, 3x3 tiles, etc.) it thinks some facing directions are others.

This is an example:(Lets hope it doesn't distort too much)

oouuqoo

oouqqoo

ppaaaqq

ppaaaqq

pdaaaqq

oodddoo

 

a = actor(this is a 3x3 large actor)

u = Up facing directional attack.

d = Down facing directional attack.

p = Left facing directional attack.

q = Right facing directional attack.

o = Open/empty tile.(I tested it with the spear skill and a cone skill)

Mostly seems to be up and left.

Edited by Pumpkin87

Share this post


Link to post
Share on other sites

Hi there,! I just recently got RPGMaker VXace and was working with GTBS.  I was directed here by another user.

 

I really like your script, first off!  I managed to create a skill that I really wanted to use.

 

Secondly, I think the up/down directions are reversed.

 

I just swapped the definition of the code here:

 

UP_AOE = /<u_aoe: (.*)>/i
DOWN_AOE
= /<d_aoe: (.*)>/i

 

with 

 

UP_AOE = /<d_aoe: (.*)>/i

DOWN_AOE = /<u_aoe: (.*)>/i

 

as a quick get around.

 

Again, thank you so much for this script!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
Top ArrowTop Arrow Highlighted