[XP] Weapon Skill Atrributes

Started by Griver03, June 24, 2011, 05:11:13 pm

Previous topic - Next topic

Griver03

ok i wonder if its possible to make an weapon skill system like final fantasy xi have ?

Exampel:
Warrior
White Mage
Samurai
its called "Combat Skill Ratings" on the page.

its selfexplaining i think.
even without the levelcap and levl system its a great idea i thought.
only the classification system would be nice too !
eg. just a,b,c,d,e for the power % of weapons and maybe armors too ?!

thx
My most wanted games...



gerrtunk

Im doing this.

I dont get how the caps works, im doing groups of armors and that each class or actor have its owns ratings with they, then, that ratings modify the attack damage.

Im doing the same with skills and skill damage and with general defense based in armors groups.

gerrtunk

Test this script and tell me if it works or not, and any  suggerence:

#==============================================================================
# Effectivity ratings for skills, defenses and attacks
# By gerkrt/gerrtunk
# Version: 1
# License: GPL, credits
# Date: 09/07/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 gives a lost option expanded from 2k3, where you could create
elements for equipment that defined it general effectivity in a scale of rates.

Now you can set it for classes also, and for skills too.

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

You have to define two things:
-Group armors, skills... by a name.
-Make skills, weapons scale ratings.

 
  Weapons_groups = {
   
    'Great Axe' => [1, 10],
    'Bow' => [[4,5]]
  }

'Group name' => ['weapon_id1, weapon_id2, etc],

  Weapons_skills_ratings  = {
    'Great Axe' => [0.10, 0.20],
    'Bow' => [20, 40, 60, 80]
  }
 
'Group name' => ['rate for rating1, for 2, etc],

  Classes_ratings = {
   1 => {
     'Great Axe' => 1,
     'Bow' => 1,
     'Base' => 2,
     'Mag' => 2
    },
   
   2 => {
     'Mag' => 2
    },
  }
 
Then you have to add to classes ratings or actors ratings the group name with
the rating index value:

'Group name' => rate index,

The index number extract the values you store in Weapons_skills_ratings, like if
it used the 'A', 'B', etc, but with numbers. This works in the natural order, but
using a -1 index: it starts with index 0, 1, 2, 3, 4, etc. You can customitze each
scale at your will, in power or number of entries.

Then the value in the rating is multiplied with the damage. If there are values
of actor and class, first these two are multiplied, and then with the damage.

This means that a 0.10 is a 10% and a 1.4 a 140%

Note that if you put a invalid index in  classes or actors ratings
it will give you a error.

The other things are pretty straightforward from here, they just use the same
methods and vocablury but for others things: skills, defense, actors, etc.

# Set the mode used by the script: 'Both' classes and and actors, 'Only classes'
# and 'Only actors'.
Use_class_actors = 'Both'

=end




module Wep
  # Set the mode used by the script: 'Both' classes and and actors, 'Only classes'
  # and 'Only actors'.
  Use_class_actors = 'Both'
 
 
  Weapons_groups = {
                   
    'Great Axe' => [1, 10],
    'Bow' => [[4,5]]
  }
 
  Weapons_skills_ratings  = {
    'Great Axe' => [0.10, 0.20],
    'Bow' => [20, 40, 60, 80]
  }
 
  Skills_groups = {
                   
    'Mag' => [7],
  }
 
  Skills_skills_ratings  = {
    'Mag' => [0.10, 0.20],
  }
 
 
  Armors_groups = {
                   
    'Base' => [13],
    'Test' => [1]
  }
 
  Armors_skills_ratings  = {
    'Base' => [0.10, 0.20, 0.50],
    'Test'=> [0.10, 0.13, 0.50]
   
  }

  Classes_ratings = {
   1 => {
     'Great Axe' => 1,
     'Bow' => 1,
     'Base' => 2,
     'Mag' => 1,
     'Test' => 1
    }
 
  }
 
   Actors_ratings = {
   1 => {
     'Great Axe' => 0,
     'Bow' => 1,
    }
 
  }
   
end


class Game_Actor

  #--------------------------------------------------------------------------
  # * Attack Rate
  #-------------------------------------------------------------------------- 
  def attack_rate
    # Search mark
    encounter = false
    class_val = 0
    actor_val = 0
    val = 0
   
    # Search if equipped weapons have rate
    for key,  value in Wep::Weapons_groups
      if value.include?(self.weapon_id)
        encounter = true
        # Class rate
        if Wep::Classes_ratings[self.class_id] != nil and Wep::Classes_ratings[@class_id][key] != nil
          rate = Wep::Classes_ratings[self.class_id][key]
          #p 'rate', rate
          class_val = Wep::Weapons_skills_ratings[key][rate]
          #p 'classval', class_val
         
        end
       
        if Wep::Actors_ratings[@actor_id] != nil and Wep::Actors_ratings[@actor_id][key] != nil
          # Actor rate
          rate = Wep::Actors_ratings[@actor_id][key]
          actor_val = Wep::Weapons_skills_ratings[key][rate]
        end
      end
    end
   

    # Check mode
    if Wep::Use_class_actors == 'Both'
      if actor_val == 0
        val = class_val
      elsif class_val == 0
        val = actor_val
      else
        val = class_val * actor_val
      end
      #p 'bo', val
    elsif Wep::Use_class_actors == 'Only classes'
      val = class_val
      #p'clas'
    else
      val = actor_val
    end
   
    # Make default if no value used
    val = 1.00 if encounter == false
    #p val, class_val, actor_val
    return val
  end

  #--------------------------------------------------------------------------
  # * Skill Rate
  #--------------------------------------------------------------------------
  def skill_rate(skill_id)
    # Search mark
    encounter = false
    class_val = 0
    actor_val = 0
    val = 0
   
    # Search if equipped weapons have rate
    for key,  value in Wep::Skills_groups
      if value.include?(skill_id)
        #p 'encounter', Wep::Classes_ratings[self.class_id], Wep::Classes_ratings[self.class_id][key]
        encounter = true
        # Class rate
        if Wep::Classes_ratings[self.class_id] != nil and Wep::Classes_ratings[@class_id][key] != nil
          rate = Wep::Classes_ratings[self.class_id][key]
          #p 'rate', rate,Wep::Skills_skills_ratings[key], key
          class_val = Wep::Skills_skills_ratings[key][rate]
         
          #p 'classval', class_val
         
        end
       
        if Wep::Actors_ratings[@actor_id] != nil and Wep::Actors_ratings[@actor_id][key] != nil
          # Actor rate
          rate = Wep::Actors_ratings[@actor_id][key]
          actor_val = Wep::Skills_skills_ratings[key][rate]
        end
      end
    end
   

    # Check mode
    if Wep::Use_class_actors == 'Both'
      if actor_val == 0
        val = class_val
      elsif class_val == 0
        val = actor_val
      else
        val = class_val * actor_val
      end
      #p 'bo', val
    elsif Wep::Use_class_actors == 'Only classes'
      val = class_val
      #p'clas'
    else
      val = actor_val
    end
   
    # Make default if no value used
    val = 1.00 if encounter == false
    #p val, class_val, actor_val
    return val
  end
   
 
  #--------------------------------------------------------------------------
  # * Defend Rate
  #--------------------------------------------------------------------------
  def defend_rate
    # Search mark
    encounter = false
    class_val = 0
    actor_val = 0
    val = 0
    arm_arr = [@armor1_id,@armor2_id,@armor3_id,@armor4_id ]
   
    for arm_id in arm_arr
      # Search if equipped weapons have rate
      for key,  value in Wep::Armors_groups
        if value.include?(arm_id)       
          encounter = true
          # Class rate
          if Wep::Classes_ratings[self.class_id] != nil and Wep::Classes_ratings[self.class_id][key] != nil
            rate = Wep::Classes_ratings[self.class_id][key] and Wep::Classes_ratings[@class_id][key] != nil
            #p 'rate', rate
            class_val += Wep::Armors_skills_ratings[key][rate]
            #p 'classval', class_val
           
          end
         
          if Wep::Actors_ratings[@actor_id] != nil and Wep::Actors_ratings[@actor_id][key] != nil
            # Actor rate
            rate = Wep::Actors_ratings[@actor_id][key]
            #p rate
            actor_val += Wep::Armors_skills_ratings[key][rate]
          end
        end
      end
     
    end
    # Check mode
    if Wep::Use_class_actors == 'Both'
      if actor_val == 0
        val = class_val
      elsif class_val == 0
        val = actor_val
      else
        val = class_val * actor_val
      end
      #p 'both'
    elsif Wep::Use_class_actors == 'Only classes'
      val = class_val
      #p'clas'
    else
      val = actor_val
    end
   
    # Make default if no value used
    val = 1.00 if encounter == false
    #p val, class_val, actor_val
    return val
  end
 
 
 
end


class Game_Battler
 
  #--------------------------------------------------------------------------
  # * Apply Skill Effects
  #     user  : the one using skills (battler)
  #     skill : skill
  #--------------------------------------------------------------------------
  def skill_effect(user, skill)
    # Clear critical flag
    self.critical = false
    # 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
     
      # Rating correction only for actors
      if user.is_a? Game_Actor
       self.damage *= user.skill_rate(skill.id)
       self.damage = self.damage.to_i
      end
      # Rating defensive correction only for actors
      if self.is_a? Game_Actor
       self.damage *= self.defend_rate
       self.damage = self.damage.to_i
      end
     
      # 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

  #--------------------------------------------------------------------------
  # * Applying Normal Attack Effects
  #     attacker : battler
  #--------------------------------------------------------------------------
  def attack_effect(attacker)
    # Clear critical flag
    self.critical = false
    # 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
      # Rating correction only for actors
      if attacker.is_a? Game_Actor
       self.damage *= attacker.attack_rate
       self.damage = self.damage.to_i
      end
      # Rating defensive correction only for actors
      if self.is_a? Game_Actor
       self.damage *= self.defend_rate
       self.damage = self.damage.to_i
      end
      # 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

 
end

Griver03

oh thanks a lot ill test it and let you tommorow know how it works !
My most wanted games...



Griver03

http://www.mediafire.com/?smsyz0582vsssd5
here is my bugreport, i added pictures from the erros and included a txt with the bugs !
but it looks good as far, nice work  :naughty:
My most wanted games...



gerrtunk

This is strange, i cant generate your bugs. I changue to lancer, equip axe, and attack, and dont give me any problems.

I added this to the classes config:


  Classes_ratings = {
   1 => {
     'Great Axe' => 1,
     'Bow' => 1,
     'Base' => 2,
     'Mag' => 2
    },
   2 => {
     'Great Axe' => 1,
     'Bow' => 1,
     'Base' => 2,
     'Mag' => 2
    }
   
  }


Tested the same and still works. What are you doing, exactly? and whats the diffrence beyond these two:
Ok if i cjange the class i get an error when attacking at line 189 ! (PIC1)
When i add a second class to test i get an error at attacking at line 168 (PIC2)

you talk about adding a class in config?

The only classes, etc, works, i tested now it.


Griver03

hmm strange...
i tested it with a blank project so this is a bit weird, ill test it again and make sure that i dont do anything wrong ^^
but like i said ithis script is awsome  :naughty:
My most wanted games...



Griver03

its strange...
when i change my class and go in battle it crashes when i attack the enemy.
when i have class 1 its working fine
when i coose class 2 it crashes
when i change class 2 and back to class 1 it works again...
its always in this area:

  # Check mode
    if Wep::Use_class_actors == 'Both'
      if actor_val == 0
        val = class_val
      elsif class_val == 0
        val = actor_val
      else
        val = class_val * actor_val

it comes at the both and at the only class option.
and its not a incompability with an other script i tested it in a blank project.
i can upload a demo where i only past the script and add a second class in the script,
it will crash when it comes to attack with class 2.

sry for my bad english -.-
My most wanted games...