[XP] Consume MP in combat by all actions

Started by gerrtunk, July 14, 2011, 01:32:48 pm

Previous topic - Next topic

gerrtunk

July 14, 2011, 01:32:48 pm Last Edit: July 27, 2011, 07:17:46 pm by ForeverZer0
Consume MP in combat by all actions
Authors: gerrtunk,gerkrt
Version: 1.5
Type: Battle Add-on
Key Term: Battle Add-on



Introduction
This script can make that when you execute any actions in combat
your MP is consumed in a system like  Final Fantasy: The Four Heroes
of Light.


Features
Can be configurated in a large number of options (actors, classes, equipment,
skill or item used, fixed value and event variables).


Screenshots
No.


Demo
No.


Script

Spoiler: ShowHide



#==============================================================================
# Consume MP in combat by all actions
# By gerkrt/gerrtunk, sournote103(idea)
# Version: 2.1
# License: GPL, credits
# Date: 16/05/2011
# For the latests updates or bugs fixes of this script check here:
# http://usuarios.multimania.es/kisap/english_list.html
#==============================================================================

=begin

---------INTRODUCTION----------

This script can make that when you execute any actions in combat
your MP is consumed based in a large number of options (actors, classes, equipment,
skill or item used, fixed value and event variables) like for example in Final Fantasy: The Four Heroes
of Light.

--------INSTRUCTIONS------------

Exist 6 actions with his own identificative code to use:
:attack
:defend
:escape
:skill
:item
:general

General is a general default configurationthats applied always, when you are doing
any action.

You can configure how many and how will be reduced the MP based in these options
that use these codes:

:actors
:classes
:weapons
:shields
:helmets
:armors
:accesories
:variables
:fixed

Plus these two that are used only when using a skill or item:

:skill
:item

In each of these configuration lists, you will put what actor id, or class id,etc
(the id is the value in the database) modify that action and how they do that.
The program sums all the values of the list each time and independently, so you
can have a armor that sums to attack and item, but reduces defense, and does nothing
with the rest, for example, and make other things also.


You dont have to use all of them anyway.

This is a sample configuration, that you have to add anytime you want to configure
any of that options.

id of X(armor, helmet, actor...) => [type(+ or %), value(normal or decimal)],
55 => [2, 0.50],

Each configuration can work in two ways:

If the first value is 1: it will add to the actual sp the value you put
If the value is 2, it will apply a % based changue, so if you write 0.50 for
example it will be reduced to 50% and 1.50 150%.

Note that you can make negative things using negative numbers, but it will never
reduce beyond 0 or 1%.

For configuring you only to have to add each time:
55 => [2, 0.50],
Where 55 is the id of the actor, weapon or armor or whatever, 2 the type to use,
and 0.50 or 50 the value to use.

Note that in :variables the code is different because the value is in the event
variable: 55 => [2], 2 is the type. Also when you are using in % the event
variables its values will be divided by 100, so it became decimals compatible with
the rest. If var 55 was 25, it will be 0.25.

:fixed is different also, it add a value based only on the action and nothing more,
so you dont need the id, but it use the normal way of + or %.
:fixed => [1, 40]

Finally, first is summed the normal value, and later applied the % value. They
way the formula works it sums all the % and normals values before suming nothing.

Also the skill reduces the sp in the normal way first, and later using this script.

----SYNTAX NOTES----
 Actions = {
 
   :attack => { # Attack config
       :weapons => {
         1 => [1, -150],
         2 => [2, 0.50]
       },
       
       :armors => {
         13 => [1, -150],
         2 => [2, 0.50]
       },
       
       :shields => {
         1 => [2, 0.50]
       },
       
       :fixed => [1, 40]
         
   }, # End of attack config
   
To add new option for attack, you have to include it before the last } with the ,
that makrs the end of any action, like defense or item too.

To add a new option like this:

      :helmets => {
         1 => [2, 0.50]
       },
       
       
Do this:
   :attack => { # Attack config
       :weapons => {
         1 => [1, -150],
         2 => [2, 0.50]
       },
       
       :armors => {
         13 => [1, -150],
         2 => [2, 0.50]
       },
       
       :shields => {
         1 => [2, 0.50]
       },
       
      :helmets => {
         1 => [2, 0.50]
       },

       :fixed => [1, 40]
         
   }, # End of attack config
   
So the the option have a , at the end of the {}
To include effects for each id, you have to add a new line each time, adding
a coma at the end. Note that each id have to be unique.

         id,    type, effect
      :helmets => {
         1 => [2, 0.50],
         2 => [2, 0.50],
         3 => [2, 0.50]
       },

=end

module Wep

 Actions = { # Actions start
 
 
   :attack => { # Attack config
       :weapons => {
         1 => [1, -150],
         2 => [2, 0.50]
       },
       
       :armors => {
         13 => [1, -150],
         2 => [2, 0.50]
       },
       
       :shields => {
         1 => [2, 0.50]
       },
       
       :fixed => [1, 40]
         
   }, # End of attack config
   
   :defense => { # Defense config
       :weapons => {
         1 => [1, -150],
         2 => [2, 0.50]
       },
       
       :armors => {
         13 => [1, -150],
         2 => [2, 0.50]
       },
       
       :shields => {
         1 => [2, 0.50]
       },
       
       :actors => {
         1 => [1, -150],
         2 => [2, 0.50]
       },
       
       :classes => {
         1 => [1, -150],
         2 => [2, 0.50]
       },
       
       :variables => {
         1 => [1],
         2 => [2]
       },
       
       :fixed => [1, 40]
         
   },# End of defend config
 
   
   :escape => {# Escape config
         
   },# End of escape config
   
   
   :item => {# Item config
         
   },# End of item config
   
   
   :skill => {# Skill config
         
   },# End of skill config
   
   
   :general => {# General config
       :actors => {
         1 => [2, 1.0],
         2 => [2, 1.50]
       },
       
       :classes => {
         4 => [1, -150],
         2 => [2, 1.50]
       }
         
   },  # End of general config

 } # End of action
 
 
 
 # 6 accions
 # iteres segons el codi,sumant tot, i executant segons el subcodi, i rula be
 # hiperfacil!
 
 
 # fer que lo de accions usi codi dels hashes, hipersimple aleshores
 # tu pases :defend i amb aixo, extreu de un hash de acciones, la bona, i ale
 def self.test(action_type, actor, extra=false)
   v = 0
   r = 0.0
   #actor.sp = 24
   
   # Sum the desired action
   for key, arr  in Actions[action_type] # + Actions[:general]
    #p key, arr
     # Set id of the item or whatever based in key used. Make needed checks.
     if key == :weapons and actor.weapon_id != 0
       id = actor.weapon_id
     elsif key == :shields and actor.armor1_id != 0
       id = actor.armor1_id
     elsif key == :helmets and actor.armor2_id != 0
       id = actor.armor2_id
     elsif key == :armors and actor.armor3_id != 0
       id = actor.armor3_id
     elsif key == :accesories and actor.armor4_id != 0
       id = actor.armor4_id
     elsif key == :actors
       id = actor.actor_id
     elsif key == :classes
       id = actor.class_id
     elsif key == :items
       id = extra
     elsif key == :skills
       id = extra
     elsif key == :fixed
         if arr[0] == 1
            v += arr[1]
         else
            r += arr[1]
         end
         next
     elsif key == :variables
       # If variables, iterate in subarray
       for key2, val in arr
         #p key, val
         if val[0] == 1
           
            v += $game_variables[key2]
            #p 'var v', v
         else
           
            r += ($game_variables[key2].to_f / 100)
            #p 'var r', r, ($game_variables[key2].to_f / 100), key2, $game_variables[key2]
         end
       end
       next
     else
       next
     end
     
     #p arr, id
     # Each time check if value exist and extract it
     if arr[id] != nil
       
         if arr[id][0] == 1
            v += arr[id][1]
         else
            r += arr[id][1]
         end
         #p 'c', v, r
     end

   end
   
   # Sum the general option always
   for key, arr  in Actions[:general]
    #p key, arr
     # Set id of the item or whatever based in key used. Make needed checks.
     if key == :weapons and actor.weapon_id != 0
       id = actor.weapon_id
     elsif key == :shields and actor.armor1_id != 0
       id = actor.armor1_id
     elsif key == :helmets and actor.armor2_id != 0
       id = actor.armor2_id
     elsif key == :armors and actor.armor3_id != 0
       id = actor.armor3_id
     elsif key == :accesories and actor.armor4_id != 0
       id = actor.armor4_id
     elsif key == :actors
       id = actor.actor_id
     elsif key == :classes
       id = actor.class_id
     elsif key == :items
       id = extra
     elsif key == :skills
       id = extra
     elsif key == :variables
       # If variables, iterate in subarray
       for key2, val in arr
         #p key, val
         if val[0] == 1
           
            v += $game_variables[key2]
            #p 'var v', v
         else
           
            r += ($game_variables[key2].to_f / 100)
            #p 'var r', r, ($game_variables[key2].to_f / 100), key2, $game_variables[key2]
         end
       end
       next
     else
       next
     end
     
     #p arr, id
     # Each time check if value exist and extract it
     if arr[id] != nil
       
         if arr[id][0] == 1
            v += arr[id][1]
         else
            r += arr[id][1]
         end
         #p 'c', v, r
     end

   end
   
   #p 'valfin', v, r
   
    # Reduce actor sp
    #p actor.sp
   
    actor.sp= actor.sp + v
    actor.sp= actor.sp * (1.0 + r).to_i
    #actor.sp= actor.sp.to_i
   
    #actor.sp = 9999 if actor.sp > 9999
    #p 'final', actor.sp
    # comprova q r no sigui negatiu
  end
 
       
 
end

class Scene_Battle
 #--------------------------------------------------------------------------
 # * Frame Update (party command phase: escape)
 #--------------------------------------------------------------------------
 def update_phase2_escape
   
   # Calculate enemy agility average
   enemies_agi = 0
   enemies_number = 0
   for enemy in $game_troop.enemies
     if enemy.exist?
       enemies_agi += enemy.agi
       enemies_number += 1
     end
   end
   if enemies_number > 0
     enemies_agi /= enemies_number
   end
   # Calculate actor agility average
   actors_agi = 0
   actors_number = 0
   for actor in $game_party.actors
     if actor.exist?
       actors_agi += actor.agi
       actors_number += 1
       Wep.test (:escape, actor)
     end
   end
   if actors_number > 0
     actors_agi /= actors_number
   end
   # Determine if escape is successful
   success = rand(100) < 50 * actors_agi / enemies_agi
   # If escape is successful
   if success
     # Play escape SE
     $game_system.se_play($data_system.escape_se)
     # Return to BGM before battle started
     $game_system.bgm_play($game_temp.map_bgm)
     # Battle ends
     battle_end(1)
   # If escape is failure
   else
     # Clear all party member actions
     $game_party.clear_actions
     # Start main phase
     start_phase4
   end
 end
 
   #--------------------------------------------------------------------------
 # * Make Basic Action Results
 #--------------------------------------------------------------------------
 def make_basic_action_result
   # If attack
   if @active_battler.current_action.basic == 0
     # Set anaimation ID
     @animation1_id = @active_battler.animation1_id
     @animation2_id = @active_battler.animation2_id
     # If action battler is enemy
     if @active_battler.is_a?(Game_Enemy)
       if @active_battler.restriction == 3
         target = $game_troop.random_target_enemy
       elsif @active_battler.restriction == 2
         target = $game_party.random_target_actor
       else
         index = @active_battler.current_action.target_index
         target = $game_party.smooth_target_actor(index)
       end
     end
     # If action battler is actor
     if @active_battler.is_a?(Game_Actor)
       if @active_battler.restriction == 3
         target = $game_party.random_target_actor
       elsif @active_battler.restriction == 2
         target = $game_troop.random_target_enemy
       else
         index = @active_battler.current_action.target_index
         target = $game_troop.smooth_target_enemy(index)
       end
     end
     # Set array of targeted battlers
     @target_battlers = [target]
     # Apply normal attack results
     for target in @target_battlers
       target.attack_effect(@active_battler)
     end
     return
   end
   # If guard
   if @active_battler.current_action.basic == 1
     # Display "Guard" in help window
     @help_window.set_text($data_system.words.guard, 1)
     # Reduce MP if is a MP consumer and a actor
     if @active_battler.is_a? Game_Actor
          Wep.test (:defense, @active_battler)
     end
   
     
     return
   end
   # If escape
   if @active_battler.is_a?(Game_Enemy) and
      @active_battler.current_action.basic == 2
     # Display "Escape" in help window
     @help_window.set_text("Escape", 1)
     # Escape
     @active_battler.escape
     return
   end
   # If doing nothing
   if @active_battler.current_action.basic == 3
     # Clear battler being forced into action
     $game_temp.forcing_battler = nil
     # Shift to step 1
     @phase4_step = 1
     return
   end
 end
end


class Game_Actor
 attr_reader :actor_id
 attr_reader :class_id
end

class Game_Battler
 
 #--------------------------------------------------------------------------
 # * Applying Normal Attack Effects
 #     attacker : battler
 #--------------------------------------------------------------------------
 def attack_effect(attacker)
   # Clear critical flag
   self.critical = false
     # Reduce MP if is a MP consumer and a actor
     if attacker.is_a? Game_Actor
         Wep.test(:attack, attacker)
     end
   # First hit detection
   hit_result = (rand(100) < attacker.hit)
   # If hit occurs
   if hit_result == true

     # Calculate basic damage
     atk = [attacker.atk - self.pdef / 2, 0].max
     self.damage = atk * (20 + attacker.str) / 20
     # Element correction
     self.damage *= elements_correct(attacker.element_set)
     self.damage /= 100
     # If damage value is strictly positive
     if self.damage > 0
       # Critical correction
       if rand(100) < 4 * attacker.dex / self.agi
         self.damage *= 2
         self.critical = true
       end
       # Guard correction
       if self.guarding?
         self.damage /= 2
       end
     end
     # Dispersion
     if self.damage.abs > 0
       amp = [self.damage.abs * 15 / 100, 1].max
       self.damage += rand(amp+1) + rand(amp+1) - amp
     end
     # Second hit detection
     eva = 8 * self.agi / attacker.dex + self.eva
     hit = self.damage < 0 ? 100 : 100 - eva
     hit = self.cant_evade? ? 100 : hit
     hit_result = (rand(100) < hit)
   end
   # If hit occurs
   if hit_result == true
     # State Removed by Shock
     remove_states_shock
     # Substract damage from HP
     self.hp -= self.damage
     # State change
     @state_changed = false
     states_plus(attacker.plus_state_set)
     states_minus(attacker.minus_state_set)
   # When missing
   else
     # Set damage to "Miss"
     self.damage = "Miss"
     # Clear critical flag
     self.critical = false
   end
   # End Method
   return true
 end
 
 #--------------------------------------------------------------------------
 # * Apply Skill Effects
 #     user  : the one using skills (battler)
 #     skill : skill
 #--------------------------------------------------------------------------
 def skill_effect(user, skill)
   # Clear critical flag
   self.critical = false
     # Reduce MP if is a MP consumer and a actor
     if self.is_a? Game_Actor
          Wep.test(:skill, self, skill)
     end
   # If skill scope is for ally with 1 or more HP, and your own HP = 0,
   # or skill scope is for ally with 0, and your own HP = 1 or more
   if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or
      ((skill.scope == 5 or skill.scope == 6) and self.hp >= 1)
     # End Method
     return false
   end
   # Clear effective flag
   effective = false
   # Set effective flag if common ID is effective
   effective |= skill.common_event_id > 0
   # First hit detection
   hit = skill.hit
   if skill.atk_f > 0
     hit *= user.hit / 100
   end
   hit_result = (rand(100) < hit)
   # Set effective flag if skill is uncertain
   effective |= hit < 100
   # If hit occurs
   if hit_result == true

   
     # Calculate power
     power = skill.power + user.atk * skill.atk_f / 100
     if power > 0
       power -= self.pdef * skill.pdef_f / 200
       power -= self.mdef * skill.mdef_f / 200
       power = [power, 0].max
     end
     # Calculate rate
     rate = 20
     rate += (user.str * skill.str_f / 100)
     rate += (user.dex * skill.dex_f / 100)
     rate += (user.agi * skill.agi_f / 100)
     rate += (user.int * skill.int_f / 100)
     # Calculate basic damage
     self.damage = power * rate / 20
     # Element correction
     self.damage *= elements_correct(skill.element_set)
     self.damage /= 100
     # If damage value is strictly positive
     if self.damage > 0
       # Guard correction
       if self.guarding?
         self.damage /= 2
       end
     end
     # Dispersion
     if skill.variance > 0 and self.damage.abs > 0
       amp = [self.damage.abs * skill.variance / 100, 1].max
       self.damage += rand(amp+1) + rand(amp+1) - amp
     end
     # Second hit detection
     eva = 8 * self.agi / user.dex + self.eva
     hit = self.damage < 0 ? 100 : 100 - eva * skill.eva_f / 100
     hit = self.cant_evade? ? 100 : hit
     hit_result = (rand(100) < hit)
     # Set effective flag if skill is uncertain
     effective |= hit < 100
   end
   # If hit occurs
   if hit_result == true
     # If physical attack has power other than 0
     if skill.power != 0 and skill.atk_f > 0
       # State Removed by Shock
       remove_states_shock
       # Set to effective flag
       effective = true
     end
     # Substract damage from HP
     last_hp = self.hp
     self.hp -= self.damage
     effective |= self.hp != last_hp
     # State change
     @state_changed = false
     effective |= states_plus(skill.plus_state_set)
     effective |= states_minus(skill.minus_state_set)
     # If power is 0
     if skill.power == 0
       # Set damage to an empty string
       self.damage = ""
       # If state is unchanged
       unless @state_changed
         # Set damage to "Miss"
         self.damage = "Miss"
       end
     end
   # If miss occurs
   else
     # Set damage to "Miss"
     self.damage = "Miss"
   end
   # If not in battle
   unless $game_temp.in_battle
     # Set damage to nil
     self.damage = nil
   end
   # End Method
   return effective
 end

 #--------------------------------------------------------------------------
 # * Application of Item Effects
 #     item : item
 #--------------------------------------------------------------------------
 def item_effect(item)
   # Clear critical flag
   self.critical = false
   Wep.test(:item, self, item)
   # If item scope is for ally with 1 or more HP, and your own HP = 0,
   # or item scope is for ally with 0 HP, and your own HP = 1 or more
   if ((item.scope == 3 or item.scope == 4) and self.hp == 0) or
      ((item.scope == 5 or item.scope == 6) and self.hp >= 1)
     # End Method
     return false
   end
   # Clear effective flag
   effective = false
   # Set effective flag if common ID is effective
   effective |= item.common_event_id > 0
   # Determine hit
   hit_result = (rand(100) < item.hit)
   # Set effective flag is skill is uncertain
   effective |= item.hit < 100
   # If hit occurs
   if hit_result == true
     
     
     # Calculate amount of recovery
     recover_hp = maxhp * item.recover_hp_rate / 100 + item.recover_hp
     recover_sp = maxsp * item.recover_sp_rate / 100 + item.recover_sp
     if recover_hp < 0
       recover_hp += self.pdef * item.pdef_f / 20
       recover_hp += self.mdef * item.mdef_f / 20
       recover_hp = [recover_hp, 0].min
     end
     # Element correction
     recover_hp *= elements_correct(item.element_set)
     recover_hp /= 100
     recover_sp *= elements_correct(item.element_set)
     recover_sp /= 100
     # Dispersion
     if item.variance > 0 and recover_hp.abs > 0
       amp = [recover_hp.abs * item.variance / 100, 1].max
       recover_hp += rand(amp+1) + rand(amp+1) - amp
     end
     if item.variance > 0 and recover_sp.abs > 0
       amp = [recover_sp.abs * item.variance / 100, 1].max
       recover_sp += rand(amp+1) + rand(amp+1) - amp
     end
     # If recovery code is negative
     if recover_hp < 0
       # Guard correction
       if self.guarding?
         recover_hp /= 2
       end
     end
     # Set damage value and reverse HP recovery amount
     self.damage = -recover_hp
     # HP and SP recovery
     last_hp = self.hp
     last_sp = self.sp
     self.hp += recover_hp
     self.sp += recover_sp
     effective |= self.hp != last_hp
     effective |= self.sp != last_sp
     # State change
     @state_changed = false
     effective |= states_plus(item.plus_state_set)
     effective |= states_minus(item.minus_state_set)
     # If parameter value increase is effective
     if item.parameter_type > 0 and item.parameter_points != 0
       # Branch by parameter
       case item.parameter_type
       when 1  # Max HP
         @maxhp_plus += item.parameter_points
       when 2  # Max SP
         @maxsp_plus += item.parameter_points
       when 3  # Strength
         @str_plus += item.parameter_points
       when 4  # Dexterity
         @dex_plus += item.parameter_points
       when 5  # Agility
         @agi_plus += item.parameter_points
       when 6  # Intelligence
         @int_plus += item.parameter_points
       end
       # Set to effective flag
       effective = true
     end
     # If HP recovery rate and recovery amount are 0
     if item.recover_hp_rate == 0 and item.recover_hp == 0
       # Set damage to empty string
       self.damage = ""
       # If SP recovery rate / recovery amount are 0, and parameter increase
       # value is ineffective.
       if item.recover_sp_rate == 0 and item.recover_sp == 0 and
          (item.parameter_type == 0 or item.parameter_points == 0)
         # If state is unchanged
         unless @state_changed
           # Set damage to "Miss"
           self.damage = "Miss"
         end
       end
     end
   # If miss occurs
   else
     # Set damage to "Miss"
     self.damage = "Miss"
   end
   # If not in battle
   unless $game_temp.in_battle
     # Set damage to nil
     self.damage = nil
   end
   # End Method
   return effective
 end
 
end






Instructions
In the script.


Compatibility
Maybe any other addon.


Credits and Thanks
No.


Author's Notes

I will add more things when i need them in my projects(or i have time), so it will be updated. Again, feedback, bugs,retc, i will listen.