Class-Actor-Skill Hybrid?

Started by shintashi, October 06, 2011, 09:46:57 pm

Previous topic - Next topic

shintashi

October 06, 2011, 09:46:57 pm Last Edit: October 06, 2011, 09:51:34 pm by shintashi
I'm working on something right now that is a thingamabob that actors can have (and maybe some NPCs or enemies), that is basically a meta skill container that has the following attributes


attr_accessor :id                       # technique ID
 attr_accessor :name                     # e.g. Black Magic, Dodge, Rifles
 attr_accessor :multiplier               # e.g x1, x2, ...x9, etc.
 attr_accessor :exp                      # total exp earned
 attr_accessor :physical                 # true or false
 attr_accessor :magical                  # true or false
 attr_accessor :level                    # level
 attr_accessor :skills                   # skills/options from main
 attr_accessor :description              # help window description
 



Essentially it's a container for multiple "single action" skills (like fire, mass fire, ice, greater ice, etc.), but it also has levels and experience points, allowing players to buy up levels in it. The multiplier is the cost multiplier for buying each level. For example, learning "weapons" might have a much higher cost than "swords", because it includes swords.

The mess I have so far is as follows, and I'm aware it won't work. I'd like some help fixing the most obvious mistakes and get a clunky version working before I mess with it further. One of the problems I'm foreseeing is not knowing how to subordinate it to actors, so that each actor's version is unique to them.




#==============================================================================
# ** Game_Technique
#------------------------------------------------------------------------------
#  This class handles the Techniques. It's used within the Game_Actors class
#  ($game_actors) and refers to the Technique class.
#==============================================================================

class Game_Technique
 #--------------------------------------------------------------------------
 # * Public Instance Variables
 #--------------------------------------------------------------------------
 attr_accessor :id                       # technique ID
 attr_accessor :name                     # e.g. Black Magic, Dodge, Rifles
 attr_accessor :multiplier               # e.g x1, x2, ...x9, etc.
 attr_accessor :exp                      # total exp earned
 attr_accessor :physical                 # true or false
 attr_accessor :magical                  # true or false
 attr_accessor :level                    # level
 attr_accessor :skills                   # skills, spells, merits, flaws
 attr_accessor :description              # help window description
 
 #--------------------------------------------------------------------------
 # * Object Initialization
 #     tech_id : tech ID
 #--------------------------------------------------------------------------
 def initialize(tech_id)
   super()
   setup(tech_id)
 end
 #--------------------------------------------------------------------------
 # * Setup
 #     tech_id : tech ID
 #--------------------------------------------------------------------------
 def setup(tech_id)
   tech = $game_technique[tech_id] #this isn't going to work - needs actor
   @tech_id = tech_id
   @name = tech.name
   @level = tech.initial_level
   @exp_list = Array.new(101)
   make_exp_list
   @exp = @exp_list[@level]
   @skills = []
 end
 #--------------------------------------------------------------------------
 # * Get Tech ID
 #--------------------------------------------------------------------------
 def id
   return @tech_id
 end
 #--------------------------------------------------------------------------
 # * Get Tech Multiplier # needs revision to 0 + ...0.1+ 0.2 +x9...etc.
 #--------------------------------------------------------------------------
 def multiplier
   return @multiplier
 end
 #--------------------------------------------------------------------------
 # * Get Index
 #--------------------------------------------------------------------------
 def index
   return @data[self.index]
 end
 #--------------------------------------------------------------------------
 # * Calculate EXP
 #--------------------------------------------------------------------------
   def make_exp_list
   tech = $data_technique[@tech_id]
   @exp_list[1] = 0
   for i in 2..100
     if i > tech.final_level
       @exp_list[i] = 0
     else
@exp_list[i] = @tech.multiplier *(i * 0.5) * (i + 1)
     end
   end
 end
 #--------------------------------------------------------------------------
 # * Get EXP String
 #--------------------------------------------------------------------------
 def exp_s
   return @exp_list[@level+1] > 0 ? @exp.to_s : "-------"
 end
 #--------------------------------------------------------------------------
 # * Get Next Level EXP String
 #--------------------------------------------------------------------------
 def next_exp_s
   return @exp_list[@level+1] > 0 ? @exp_list[@level+1].to_s : "-------"
 end
 #--------------------------------------------------------------------------
 # * Get Until Next Level EXP String
 #--------------------------------------------------------------------------
 def next_rest_exp_s
   return @exp_list[@level+1] > 0 ?
     (@exp_list[@level+1] - @exp).to_s : "-------"
 end
 #--------------------------------------------------------------------------
 # * Change EXP
 #     exp : new EXP
 #--------------------------------------------------------------------------
 def exp=(exp)
   @exp = [[exp, 99999].min, 0].max
   # Level up
   while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0
     @level += 1
#====================================================================      
# NEEDS HEAVY REVISION CF SKILL WINDOW
     # Learn skill
     for j in $data_classes[@class_id].learnings
       if j.level == @level
         learn_skill(j.skill_id)
       end
     end
   end
#====================================================================    
   # Level down
   while @exp < @exp_list[@level]
     @level -= 1
   end
 end
 #--------------------------------------------------------------------------
 # * Change Level
 #     level : new level
 #--------------------------------------------------------------------------
 def level=(level)
   # Check up and down limits - NEEDS REVISION
   level = [[level, $data_actors[@actor_id].final_level].min, 1].max
   # Change EXP
   self.exp = @exp_list[level]
 end
 #--------------------------------------------------------------------------
 # * Learn Skill
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def learn_skill(skill_id)
   if skill_id > 0 and not skill_learn?(skill_id)
     @skills.push(skill_id)
     @skills.sort!
   end
 end
 #--------------------------------------------------------------------------
 # * Forget Skill
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def forget_skill(skill_id)
   @skills.delete(skill_id)
 end
 #--------------------------------------------------------------------------
 # * Determine if Finished Learning Skill
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def skill_learn?(skill_id)
   return @skills.include?(skill_id)
 end
 #--------------------------------------------------------------------------
 # * Determine if Skill can be Used
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def skill_can_use?(skill_id)
   if not skill_learn?(skill_id)
     return false
   end
   return super
 end
 #--------------------------------------------------------------------------
 # * Change Name #comes in handy when creating custom techniques
 #     name : new name
 #--------------------------------------------------------------------------
 def name=(name)
   @name = name
 end
   #--------------------------------------------------------------------------
 # * Change Description #comes in handy when creating custom techniques
 #     description : new description
 #--------------------------------------------------------------------------
 def description=(description)
   @description = description
 end
end





I envision calling parts of it by saying something like


p $game_actors[11].tech[4].name
p $game_actors[11].tech[4].level


with

p $game_actors[11].tech[4]


looking similar but smaller than what is normally spat out when you type something like


p $game_actors[11]




and have yet to figure out the window interface, since I originally came up with this idea with a mouse in mind and clicking on an expand icon for details in a list, similar to a text based linear skill tree or list. For now, I just want the thing to exist, and worry about interfacing and windows later.


shintashi

October 07, 2011, 12:08:44 am #1 Last Edit: October 07, 2011, 12:50:10 am by shintashi
I've revised some stuff as seen below, it still doesn't work, but I've been thinking of it sort of like a hash. I wanted some stock techniques that could be built into the system, but then you would have the option of developing your own. While that's the main point - inventing your own class abilities, the idea that some basic functions exist seems paramount.


#==============================================================================
# ** Game_Technique
#------------------------------------------------------------------------------
#  This class handles the Techniques. It's used within the Game_Actors class
#  ($game_actors) and refers to the Technique class.
#==============================================================================

class Game_Technique
 #--------------------------------------------------------------------------
 # * Public Instance Variables
 #--------------------------------------------------------------------------
 attr_accessor :id                       # technique ID
 attr_accessor :name                     # e.g. Black Magic, Dodge, Rifles
 attr_accessor :multiplier               # e.g x1, x2, ...x9, etc.
 attr_accessor :exp                      # total exp earned
 attr_accessor :physical                 # true or false
 attr_accessor :magical                  # true or false
 attr_accessor :level                    # level
 attr_accessor :skills                   # skills, spells, merits, flaws
 attr_accessor :description              # help window description
 
 #--------------------------------------------------------------------------
 # * Stock Techniques
 #     tech_id : tech ID
 #--------------------------------------------------------------------------
 $game_technique[0].name = "Endurance" # Hit Points
 $game_technique[1].name = "Dodge"     # Dodge
 $game_technique[2].name = "Melee"     # Attack
 $game_technique[3].name = "Willforce" # Spell Points
 #--------------------------------------------------------------------------
 # * Object Initialization
 #     tech_id : tech ID
 #--------------------------------------------------------------------------
 def initialize(tech_id)
   super()
   setup(tech_id)
 end
 #--------------------------------------------------------------------------
 # * Setup
 #     tech_id : tech ID
 #--------------------------------------------------------------------------
 def setup(tech_id)
   tech = $game_technique[tech_id] #this isn't going to work - needs actor
   @tech_id = tech_id
   @name = tech.name
   @level = 0
   @multiplier = multiplier              
   @physical = false                
   @magical = false
   @description = ""              
   @exp_list = Array.new(101)
   make_exp_list
   @exp = @exp_list[@level]
   @skills = []
 end
 #--------------------------------------------------------------------------
 # * Get Tech ID
 #--------------------------------------------------------------------------
 def id
   return @tech_id
 end
 #--------------------------------------------------------------------------
 # * Get Tech Multiplier # needs revision to 0 + ...0.1+ 0.2 +x9...etc.
 #--------------------------------------------------------------------------
 def multiplier
   #i = self.id
   #n = 0 + (tech[i].skill[1].power + tech[i].skill[2].power * 0.1)
   #n = 0 + skill[1].power + skill[2].power + skill[3].power
   #return n
   return @multiplier
 end
 #--------------------------------------------------------------------------
 # * Get Index
 #--------------------------------------------------------------------------
 def index
   return @data[self.index]
 end
 #--------------------------------------------------------------------------
 # * Calculate EXP
 #--------------------------------------------------------------------------
   def make_exp_list
   tech = $data_technique[@tech_id]
   @exp_list[1] = 0
   for i in 2..100
     if i > tech.final_level
       @exp_list[i] = 0
     else
@exp_list[i] = @tech.multiplier *(i * 0.5) * (i + 1)
     end
   end
 end
 #--------------------------------------------------------------------------
 # * Get EXP String
 #--------------------------------------------------------------------------
 def exp_s
   return @exp_list[@level+1] > 0 ? @exp.to_s : "-------"
 end
 #--------------------------------------------------------------------------
 # * Get Next Level EXP String
 #--------------------------------------------------------------------------
 def next_exp_s
   return @exp_list[@level+1] > 0 ? @exp_list[@level+1].to_s : "-------"
 end
 #--------------------------------------------------------------------------
 # * Get Until Next Level EXP String
 #--------------------------------------------------------------------------
 def next_rest_exp_s
   return @exp_list[@level+1] > 0 ?
     (@exp_list[@level+1] - @exp).to_s : "-------"
 end
 #--------------------------------------------------------------------------
 # * Change EXP
 #     exp : new EXP
 #--------------------------------------------------------------------------
 def exp=(exp)
   @exp = [[exp, 99999].min, 0].max
   # Level up
   while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0
     @level += 1
#====================================================================      
# NEEDS HEAVY REVISION CF SKILL WINDOW
     # Learn skill
     for j in $data_classes[@class_id].learnings
       if j.level == @level
         learn_skill(j.skill_id)
       end
     end
   end
#====================================================================    
   # Level down
   while @exp < @exp_list[@level]
     @level -= 1
   end
 end
 #--------------------------------------------------------------------------
 # * Change Level
 #     level : new level
 #--------------------------------------------------------------------------
 def level=(level)
   # Check up and down limits - NEEDS REVISION
   level = [[level, $data_actors[@actor_id].final_level].min, 1].max
   # Change EXP
   self.exp = @exp_list[level]
 end
 #--------------------------------------------------------------------------
 # * Learn Skill
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def learn_skill(skill_id)
   if skill_id > 0 and not skill_learn?(skill_id)
     @skills.push(skill_id)
     @skills.sort!
   end
 end
 #--------------------------------------------------------------------------
 # * Forget Skill
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def forget_skill(skill_id)
   @skills.delete(skill_id)
 end
 #--------------------------------------------------------------------------
 # * Determine if Finished Learning Skill
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def skill_learn?(skill_id)
   return @skills.include?(skill_id)
 end
 #--------------------------------------------------------------------------
 # * Determine if Skill can be Used
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def skill_can_use?(skill_id)
   if not skill_learn?(skill_id)
     return false
   end
   return super
 end
 #--------------------------------------------------------------------------
 # * Change Name #comes in handy when creating custom techniques
 #     name : new name
 #--------------------------------------------------------------------------
 def name=(name)
   @name = name
 end
   #--------------------------------------------------------------------------
 # * Change Description #comes in handy when creating custom techniques
 #     description : new description
 #--------------------------------------------------------------------------
 def description=(description)
   @description = description
 end
end




Well, I did some testing, and ended up testing it with a hash in the script editor...

$game_technique = {}
$game_technique[0] = ["Endurance", 1, 0, true, false, 0, [1, 2], "Hit Point Bonus"]


and was able to use an event to produce answers to all parts of my hash.

p $game_technique[0][0]
p $game_technique[0][1]
p $game_technique[0][2]
p $game_technique[0][3]
p $game_technique[0][4]
p $game_technique[0][5]
p $game_technique[0][6][0]
p $game_technique[0][6][1]
p $game_technique[0][7]


My concern is 1. getting the info inside the game actors, and 2. doing this all preferably without a hash (which I don't currently know how to do).

KK20

If you want to get these stored into the actors, you obviously are going to have to edit class Actor. Make an array that stores the ID numbers. If you're going to define every skill at each ID value, use 'case'.

Of course, I can't think like you so I'm just throwing out ideas.

-waits for someone to start bashing about your programming-

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

October 07, 2011, 09:57:44 am #3 Last Edit: October 07, 2011, 09:59:03 am by shintashi
I was beginning to think id have to stick it in actor about 2-3am this morning, while mulling over this message to myself in my scrap notes:


$game_actor[n].tech[m][a][b][c]

n = actor number
m = technique number
a = technique attribute
b = skill number (assumes a = technique's "skill list")
c = skill attribute (assumes b = skill number)

I'm thinking skill list should probably be either the 1st, the second, or the last number, to avoid confusion. If it's the first, it will be zero, $game_actor[n].tech[m][0][skill_id][skill_attribute], but as a matter of form, perhaps name should come first.

if I prided myself in my programming skills I don't think I would be so quick to ask for help on this part of the project. Actually, statements like that are why I post so seldom in this forum.

Twb6543

This is similar to the goal I have for my script (VX), I currently haven't updated the topic recently but I have made progress on fulfilling the ultimate goal for it. You may wish to take a look at the non-updated script it might give you a few ideas on how to manage skills.

Script
If you put a million monkeys at a million keyboards, one of them will eventually write a Java program.
The rest of them will write Perl programs.

shintashi

Quote from: Twb6543 on October 07, 2011, 10:45:52 am
This is similar to the goal I have for my script (VX), I currently haven't updated the topic recently but I have made progress on fulfilling the ultimate goal for it. You may wish to take a look at the non-updated script it might give you a few ideas on how to manage skills.

Script


while the script structures are different in VX, I did see some similarities for sure. We both have level at around 100 and have experience ranges and options. Right now I'm trying to figure out how to create both standardized "stock" techniques plus open, editable techniques. While I only envisioned each actor having between 2 and 4 main techniques with a lot of overlap (e.g. dodge) bringing each to about 5-10, the total number of techniques in the game was probably under 20.

I'm pretty certain now I should make the the techniques a part of the actor class, in some shape or form, rather than creating a new $data_techniques file.

ForeverZer0

class Game_Actor

  attr_accessor :techniques

  alias tech_init initialize(id)
  def initialize(id)
    @techniques = Game_Technique.new
    tech_init(id)
  end
end


I can't remember the exact args that go with Game_Actor, but you get the idea.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

KK20

I've played around with your script a bit. I did have to make a few edits to "Game_Techniques" because of the errors in initializing.
Spoiler: ShowHide
#==============================================================================
# ** Game_Technique
#------------------------------------------------------------------------------
#  This class handles the Techniques. It's used within the Game_Actors class
#  ($game_actors) and refers to the Technique class.
#==============================================================================

class Game_Technique
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :id                       # technique ID
  attr_accessor :name                     # e.g. Black Magic, Dodge, Rifles
  attr_accessor :multiplier               # e.g x1, x2, ...x9, etc.
  attr_accessor :exp                      # total exp earned
  attr_accessor :physical                 # true or false
  attr_accessor :magical                  # true or false
  attr_accessor :level                    # level
  attr_accessor :skills                   # skills, spells, merits, flaws
  attr_accessor :description              # help window description
 
  #--------------------------------------------------------------------------
  # * Stock Techniques
  #     tech_id : tech ID
  #--------------------------------------------------------------------------
  def techniques_data(id)
    # return [name, mult, exp, physical?, magical?, level, skills, desc]
    case id
    when 0 then return ["Endurance", 1, 0, true, false, 0, [1, 2], "Hit Point Bonus"]
    end
  end
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     tech_id : tech ID
  #--------------------------------------------------------------------------
  def initialize(tech_id)
    tech = techniques_data(tech_id)
    @tech_id = tech_id
    @name = tech[0]
    @level = tech[5]
    @multiplier = tech[1]               
    @physical = tech[3]                 
    @magical = tech[4]
    @description = tech[7]             
    @exp_list = Array.new(101)
    make_exp_list
    @exp = tech[2]
    @skills = []
    tech[6].each{|id|
      @skills.push(id)
    }
    @skills.sort!
  end
  #--------------------------------------------------------------------------
  # * Get Tech ID
  #--------------------------------------------------------------------------
  def id
    return @tech_id
  end
  #--------------------------------------------------------------------------
  # * Get Tech Multiplier # needs revision to 0 + ...0.1+ 0.2 +x9...etc.
  #--------------------------------------------------------------------------
  def multiplier
    #i = self.id
    #n = 0 + (tech[i].skill[1].power + tech[i].skill[2].power * 0.1)
    #n = 0 + skill[1].power + skill[2].power + skill[3].power
    #return n
    return @multiplier
  end
  #--------------------------------------------------------------------------
  # * Get Index
  #--------------------------------------------------------------------------
  def index
    return @data[self.index]
  end
  #--------------------------------------------------------------------------
  # * Calculate EXP
  #--------------------------------------------------------------------------
    def make_exp_list
    @exp_list[1] = 0
    for i in 2..100
      @exp_list[i] = @exp_list[i-1] + (@multiplier * (i / 2) * (i + 1))
    end
  end
  #--------------------------------------------------------------------------
  # * Get EXP String
  #--------------------------------------------------------------------------
  def exp_s
    return @exp_list[@level+1] > 0 ? @exp.to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Get Next Level EXP String
  #--------------------------------------------------------------------------
  def next_exp_s
    return @exp_list[@level+1] > 0 ? @exp_list[@level+1].to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Get Until Next Level EXP String
  #--------------------------------------------------------------------------
  def next_rest_exp_s
    return @exp_list[@level+1] > 0 ?
      (@exp_list[@level+1] - @exp).to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Change EXP
  #     exp : new EXP
  #--------------------------------------------------------------------------
  def exp=(exp)
    @exp = [[exp, 99999].min, 0].max
    # Level up
    while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0
      @level += 1
#====================================================================     
# NEEDS HEAVY REVISION CF SKILL WINDOW
      # Learn skill
      for j in $data_classes[@class_id].learnings
        if j.level == @level
          learn_skill(j.skill_id)
        end
      end
    end
#====================================================================   
    # Level down
    while @exp < @exp_list[@level]
      @level -= 1
    end
  end
  #--------------------------------------------------------------------------
  # * Change Level
  #     level : new level
  #--------------------------------------------------------------------------
  def level=(level)
    # Check up and down limits - NEEDS REVISION
    level = [[level, $data_actors[@actor_id].final_level].min, 1].max
    # Change EXP
    self.exp = @exp_list[level]
  end
  #--------------------------------------------------------------------------
  # * Learn Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def learn_skill(skill_id)
    if skill_id > 0 and not skill_learn?(skill_id)
      @skills.push(skill_id)
      @skills.sort!
    end
  end
  #--------------------------------------------------------------------------
  # * Forget Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def forget_skill(skill_id)
    @skills.delete(skill_id)
  end
  #--------------------------------------------------------------------------
  # * Determine if Finished Learning Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def skill_learn?(skill_id)
    return @skills.include?(skill_id)
  end
  #--------------------------------------------------------------------------
  # * Determine if Skill can be Used
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def skill_can_use?(skill_id)
    if not skill_learn?(skill_id)
      return false
    end
    return super
  end
end
#===============================================================================
# Class Game_Actor
#===============================================================================
class Game_Actor < Game_Battler
  attr_accessor :techniques
 
  alias initialize_techniques initialize
  def initialize(actor_id)
    @techniques = []
    initialize_techniques(actor_id)
  end
 
  alias setup_techniques setup
  def setup(actor_id)
    setup_techniques(actor_id)
    # How will you determine what techniques the character starts with?
  end
 
  # Adds the specified technique to the @techniques array
  def add_tech(tech_id)
    return if @techniques[tech_id] != nil # stops if tech is already possessed
    @techniques[tech_id] = Game_Technique.new(tech_id)
  end

end
Keep me updated on what you want fixed.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

Quote from: KK20 on October 07, 2011, 03:15:54 pm
I've played around with your script a bit. I did have to make a few edits to "Game_Techniques" because of the errors in initializing.
Spoiler: ShowHide
#==============================================================================
# ** Game_Technique
#------------------------------------------------------------------------------
#  This class handles the Techniques. It's used within the Game_Actors class
#  ($game_actors) and refers to the Technique class.
#==============================================================================

class Game_Technique
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :id                       # technique ID
  attr_accessor :name                     # e.g. Black Magic, Dodge, Rifles
  attr_accessor :multiplier               # e.g x1, x2, ...x9, etc.
  attr_accessor :exp                      # total exp earned
  attr_accessor :physical                 # true or false
  attr_accessor :magical                  # true or false
  attr_accessor :level                    # level
  attr_accessor :skills                   # skills, spells, merits, flaws
  attr_accessor :description              # help window description
 
  #--------------------------------------------------------------------------
  # * Stock Techniques
  #     tech_id : tech ID
  #--------------------------------------------------------------------------
  def techniques_data(id)
    # return [name, mult, exp, physical?, magical?, level, skills, desc]
    case id
    when 0 then return ["Endurance", 1, 0, true, false, 0, [1, 2], "Hit Point Bonus"]
    end
  end
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     tech_id : tech ID
  #--------------------------------------------------------------------------
  def initialize(tech_id)
    tech = techniques_data(tech_id)
    @tech_id = tech_id
    @name = tech[0]
    @level = tech[5]
    @multiplier = tech[1]               
    @physical = tech[3]                 
    @magical = tech[4]
    @description = tech[7]             
    @exp_list = Array.new(101)
    make_exp_list
    @exp = tech[2]
    @skills = []
    tech[6].each{|id|
      @skills.push(id)
    }
    @skills.sort!
  end
  #--------------------------------------------------------------------------
  # * Get Tech ID
  #--------------------------------------------------------------------------
  def id
    return @tech_id
  end
  #--------------------------------------------------------------------------
  # * Get Tech Multiplier # needs revision to 0 + ...0.1+ 0.2 +x9...etc.
  #--------------------------------------------------------------------------
  def multiplier
    #i = self.id
    #n = 0 + (tech[i].skill[1].power + tech[i].skill[2].power * 0.1)
    #n = 0 + skill[1].power + skill[2].power + skill[3].power
    #return n
    return @multiplier
  end
  #--------------------------------------------------------------------------
  # * Get Index
  #--------------------------------------------------------------------------
  def index
    return @data[self.index]
  end
  #--------------------------------------------------------------------------
  # * Calculate EXP
  #--------------------------------------------------------------------------
    def make_exp_list
    @exp_list[1] = 0
    for i in 2..100
      @exp_list[i] = @exp_list[i-1] + (@multiplier * (i / 2) * (i + 1))
    end
  end
  #--------------------------------------------------------------------------
  # * Get EXP String
  #--------------------------------------------------------------------------
  def exp_s
    return @exp_list[@level+1] > 0 ? @exp.to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Get Next Level EXP String
  #--------------------------------------------------------------------------
  def next_exp_s
    return @exp_list[@level+1] > 0 ? @exp_list[@level+1].to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Get Until Next Level EXP String
  #--------------------------------------------------------------------------
  def next_rest_exp_s
    return @exp_list[@level+1] > 0 ?
      (@exp_list[@level+1] - @exp).to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Change EXP
  #     exp : new EXP
  #--------------------------------------------------------------------------
  def exp=(exp)
    @exp = [[exp, 99999].min, 0].max
    # Level up
    while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0
      @level += 1
#====================================================================     
# NEEDS HEAVY REVISION CF SKILL WINDOW
      # Learn skill
      for j in $data_classes[@class_id].learnings
        if j.level == @level
          learn_skill(j.skill_id)
        end
      end
    end
#====================================================================   
    # Level down
    while @exp < @exp_list[@level]
      @level -= 1
    end
  end
  #--------------------------------------------------------------------------
  # * Change Level
  #     level : new level
  #--------------------------------------------------------------------------
  def level=(level)
    # Check up and down limits - NEEDS REVISION
    level = [[level, $data_actors[@actor_id].final_level].min, 1].max
    # Change EXP
    self.exp = @exp_list[level]
  end
  #--------------------------------------------------------------------------
  # * Learn Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def learn_skill(skill_id)
    if skill_id > 0 and not skill_learn?(skill_id)
      @skills.push(skill_id)
      @skills.sort!
    end
  end
  #--------------------------------------------------------------------------
  # * Forget Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def forget_skill(skill_id)
    @skills.delete(skill_id)
  end
  #--------------------------------------------------------------------------
  # * Determine if Finished Learning Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def skill_learn?(skill_id)
    return @skills.include?(skill_id)
  end
  #--------------------------------------------------------------------------
  # * Determine if Skill can be Used
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def skill_can_use?(skill_id)
    if not skill_learn?(skill_id)
      return false
    end
    return super
  end
end
#===============================================================================
# Class Game_Actor
#===============================================================================
class Game_Actor < Game_Battler
  attr_accessor :techniques
 
  alias initialize_techniques initialize
  def initialize(actor_id)
    @techniques = []
    initialize_techniques(actor_id)
  end
 
  alias setup_techniques setup
  def setup(actor_id)
    setup_techniques(actor_id)
    # How will you determine what techniques the character starts with?
  end
 
  # Adds the specified technique to the @techniques array
  def add_tech(tech_id)
    return if @techniques[tech_id] != nil # stops if tech is already possessed
    @techniques[tech_id] = Game_Technique.new(tech_id)
  end

end
Keep me updated on what you want fixed.


That's F*ing brilliant actually. My main concern is whether the skill list should be id=1 or id=some other number. In your version, likely based on my hash, you have it as 6, with description as 7. I guess 0 should be name because that makes the most sense, but I'm beginning to think skills should be "1", because there's a lot of derived values after that.

in order, its basically skills.power added together = multiplier, then multiplier determines experience chart, then experience chart determines level. the other attributes - magic/physical/description are useful but not critical. I don't think the computer cares which order they appear in, but if sorted by a number, I'm guessing

?: ID Number
0: name
1: skills []
2: multiplier
3: experience total
4: level
5/6/7: magic/physical/description

KK20

When calling back the data for your techniques (name, skills, level, exp, etc), it doesn't have to be values in an array. What I mean is, taking the edit I made, you don't have to go $game_actors[1].techniques[0][0] to get the name (actually that'd cause an error). You just use $game_actors[1].techniques[0].name and "Endurance" should be the result.

Because of that, it doesn't matter how you set up your technique data. Granted, it is preferable to order your values based on importance, but it's not necessary.

Also, I added in class "Game_Actors" a method called 'add_tech(tech_id)'. If you do a script call like $game_actors[1].add_tech(0), it will add the technique with the ID value of 0 (Endurance in this case). @tech_id will equal parameter tech_id, and does not need to be part of your setup array. It can be called the same way as I stated at the top of this post.

What's next? :naughty:

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

October 08, 2011, 12:28:49 pm #10 Last Edit: October 08, 2011, 12:32:39 pm by shintashi
Quote from: KK20 on October 08, 2011, 12:51:57 am
When calling back the data for your techniques (name, skills, level, exp, etc), it doesn't have to be values in an array. What I mean is, taking the edit I made, you don't have to go $game_actors[1].techniques[0][0] to get the name (actually that'd cause an error). You just use $game_actors[1].techniques[0].name and "Endurance" should be the result.

Because of that, it doesn't matter how you set up your technique data. Granted, it is preferable to order your values based on importance, but it's not necessary.

Also, I added in class "Game_Actors" a method called 'add_tech(tech_id)'. If you do a script call like $game_actors[1].add_tech(0), it will add the technique with the ID value of 0 (Endurance in this case). @tech_id will equal parameter tech_id, and does not need to be part of your setup array. It can be called the same way as I stated at the top of this post.

What's next? :naughty:


this:


 #--------------------------------------------------------------------------
 # * Get Tech Multiplier # needs revision to 0 + ...0.1+ 0.2 +x9...etc.
 #--------------------------------------------------------------------------
 def multiplier
   for i in 0..tech.skills.length
   n = 0 + (tech.skills[i].power * 0.1)
   end
   return n
 end


clearly doesn't work but I hope it illustrates enough to be fixed. Basically add up all the technique's skills' power values together and divide by 10. I basically suck at for loops with gaps. like if I had an array that pulled from a list of 26 variables (a..z), and the list was called my_variables, and my array was something like my_array = [a,m,x], I don't know how to add a + m + x , without adding the rest of the alphabet, or literally typing my_array[a] + my_array[m] + my_array
  • ... which means if I wanted to add b, or n, or get rid of x, I would be screwed.

KK20

Spoiler: ShowHide
#==============================================================================
# ** Game_Technique
#------------------------------------------------------------------------------
#  This class handles the Techniques. It's used within the Game_Actors class
#  ($game_actors) and refers to the Technique class.
#==============================================================================

class Game_Technique
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :id                       # technique ID
  attr_accessor :name                     # e.g. Black Magic, Dodge, Rifles
  attr_accessor :multiplier               # e.g x1, x2, ...x9, etc.
  attr_accessor :exp                      # total exp earned
  attr_accessor :physical                 # true or false
  attr_accessor :magical                  # true or false
  attr_accessor :level                    # level
  attr_accessor :skills                   # skills, spells, merits, flaws
  attr_accessor :description              # help window description
 
  #--------------------------------------------------------------------------
  # * Stock Techniques
  #     tech_id : tech ID
  #--------------------------------------------------------------------------
  def techniques_data(id)
    # return [name, mult, exp, physical?, magical?, level, skills, desc]
    case id
    when 0 then return ["Endurance", 1, 0, true, false, 0, [1, 2], "Hit Point Bonus"]
    end
  end
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     tech_id : tech ID
  #--------------------------------------------------------------------------
  def initialize(tech_id)
    tech = techniques_data(tech_id)
    @tech_id = tech_id
    @name = tech[0]
    @level = tech[5]               
    @physical = tech[3]                 
    @magical = tech[4]
    @description = tech[7]             
    @skills = []
    tech[6].each{|id|
      @skills.push(id)
    }
    @skills.sort!
    @multiplier = get_multi
    @exp_list = Array.new(101)
    make_exp_list
    @exp = tech[2]
  end
  #--------------------------------------------------------------------------
  # * Get Tech ID
  #--------------------------------------------------------------------------
  def id
    return @tech_id
  end
  #--------------------------------------------------------------------------
  # * Get Tech Multiplier # needs revision to 0 + ...0.1+ 0.2 +x9...etc.
  #--------------------------------------------------------------------------
  def get_multi
    m = 0
    @skills.each{|i|
      m += $data_skills[i].power.abs
    }
    return m/10
  end
  #--------------------------------------------------------------------------
  # * Get Index
  #--------------------------------------------------------------------------
  def index
    return @data[self.index]
  end
  #--------------------------------------------------------------------------
  # * Calculate EXP
  #--------------------------------------------------------------------------
    def make_exp_list
    @exp_list[1] = 0
    for i in 2..100
      @exp_list[i] = @exp_list[i-1] + (@multiplier * (i / 2) * (i + 1))
    end
  end
  #--------------------------------------------------------------------------
  # * Get EXP String
  #--------------------------------------------------------------------------
  def exp_s
    return @exp_list[@level+1] > 0 ? @exp.to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Get Next Level EXP String
  #--------------------------------------------------------------------------
  def next_exp_s
    return @exp_list[@level+1] > 0 ? @exp_list[@level+1].to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Get Until Next Level EXP String
  #--------------------------------------------------------------------------
  def next_rest_exp_s
    return @exp_list[@level+1] > 0 ?
      (@exp_list[@level+1] - @exp).to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Change EXP
  #     exp : new EXP
  #--------------------------------------------------------------------------
  def exp=(exp)
    @exp = [[exp, 99999].min, 0].max
    # Level up
    while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0
      @level += 1
#====================================================================     
# NEEDS HEAVY REVISION CF SKILL WINDOW
      # Learn skill
      for j in $data_classes[@class_id].learnings
        if j.level == @level
          learn_skill(j.skill_id)
        end
      end
    end
#====================================================================   
    # Level down
    while @exp < @exp_list[@level]
      @level -= 1
    end
  end
  #--------------------------------------------------------------------------
  # * Change Level
  #     level : new level
  #--------------------------------------------------------------------------
  def level=(level)
    # Check up and down limits - NEEDS REVISION
    level = [[level, $data_actors[@actor_id].final_level].min, 1].max
    # Change EXP
    self.exp = @exp_list[level]
  end
  #--------------------------------------------------------------------------
  # * Learn Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def learn_skill(skill_id)
    if skill_id > 0 and not skill_learn?(skill_id)
      @skills.push(skill_id)
      @skills.sort!
    end
  end
  #--------------------------------------------------------------------------
  # * Forget Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def forget_skill(skill_id)
    @skills.delete(skill_id)
  end
  #--------------------------------------------------------------------------
  # * Determine if Finished Learning Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def skill_learn?(skill_id)
    return @skills.include?(skill_id)
  end
  #--------------------------------------------------------------------------
  # * Determine if Skill can be Used
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def skill_can_use?(skill_id)
    if not skill_learn?(skill_id)
      return false
    end
    return super
  end
end
#===============================================================================
# class Game_Actor
#===============================================================================
class Game_Actor < Game_Battler
  attr_accessor :techniques
 
  alias initialize_techniques initialize
  def initialize(actor_id)
    @techniques = []
    initialize_techniques(actor_id)
  end
 
  alias setup_techniques setup
  def setup(actor_id)
    setup_techniques(actor_id)
    # How will you determine what techniques the character starts with?
  end
 
  # Adds the specified technique to the @techniques array
  def add_tech(tech_id)
    return if @techniques[tech_id] != nil # stops if tech is already possessed
    @techniques[tech_id] = Game_Technique.new(tech_id)
  end

end
I had to change the method name 'def multiplier' to 'def get_multi'. It is entirely possible to just move the contents of that method and put it into 'def initialize' but I wasn't sure if you wanted to, say, add more skills into the technique later on. Tested with Heal and Greater Heal (powers of 150 and 300) and it returned 45.

Also had to shift things around a bit in 'def initialize'.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

October 08, 2011, 09:13:44 pm #12 Last Edit: October 08, 2011, 09:33:53 pm by shintashi
Here's a happy screenshot showing pretty much what I hoped would happen if the script started working
Spoiler: ShowHide


I'm especially impressed that the experience table exists. I haven't tested leveling the technique yet, or seeing if two characters can have the same technique, but so far, it looks great.



Quote from: KK20 on October 08, 2011, 02:10:28 pm
Spoiler: ShowHide
#==============================================================================
# ** Game_Technique
#------------------------------------------------------------------------------
#  This class handles the Techniques. It's used within the Game_Actors class
#  ($game_actors) and refers to the Technique class.
#==============================================================================

class Game_Technique
 #--------------------------------------------------------------------------
 # * Public Instance Variables
 #--------------------------------------------------------------------------
 attr_accessor :id                       # technique ID
 attr_accessor :name                     # e.g. Black Magic, Dodge, Rifles
 attr_accessor :multiplier               # e.g x1, x2, ...x9, etc.
 attr_accessor :exp                      # total exp earned
 attr_accessor :physical                 # true or false
 attr_accessor :magical                  # true or false
 attr_accessor :level                    # level
 attr_accessor :skills                   # skills, spells, merits, flaws
 attr_accessor :description              # help window description
 
 #--------------------------------------------------------------------------
 # * Stock Techniques
 #     tech_id : tech ID
 #--------------------------------------------------------------------------
 def techniques_data(id)
   # return [name, mult, exp, physical?, magical?, level, skills, desc]
   case id
   when 0 then return ["Endurance", 1, 0, true, false, 0, [1, 2], "Hit Point Bonus"]
   end
 end
 #--------------------------------------------------------------------------
 # * Object Initialization
 #     tech_id : tech ID
 #--------------------------------------------------------------------------
 def initialize(tech_id)
   tech = techniques_data(tech_id)
   @tech_id = tech_id
   @name = tech[0]
   @level = tech[5]              
   @physical = tech[3]                
   @magical = tech[4]
   @description = tech[7]            
   @skills = []
   tech[6].each{|id|
     @skills.push(id)
   }
   @skills.sort!
   @multiplier = get_multi
   @exp_list = Array.new(101)
   make_exp_list
   @exp = tech[2]
 end
 #--------------------------------------------------------------------------
 # * Get Tech ID
 #--------------------------------------------------------------------------
 def id
   return @tech_id
 end
 #--------------------------------------------------------------------------
 # * Get Tech Multiplier # needs revision to 0 + ...0.1+ 0.2 +x9...etc.
 #--------------------------------------------------------------------------
 def get_multi
   m = 0
   @skills.each{|i|
     m += $data_skills[i].power.abs
   }
   return m/10
 end
 #--------------------------------------------------------------------------
 # * Get Index
 #--------------------------------------------------------------------------
 def index
   return @data[self.index]
 end
 #--------------------------------------------------------------------------
 # * Calculate EXP
 #--------------------------------------------------------------------------
   def make_exp_list
   @exp_list[1] = 0
   for i in 2..100
     @exp_list[i] = @exp_list[i-1] + (@multiplier * (i / 2) * (i + 1))
   end
 end
 #--------------------------------------------------------------------------
 # * Get EXP String
 #--------------------------------------------------------------------------
 def exp_s
   return @exp_list[@level+1] > 0 ? @exp.to_s : "-------"
 end
 #--------------------------------------------------------------------------
 # * Get Next Level EXP String
 #--------------------------------------------------------------------------
 def next_exp_s
   return @exp_list[@level+1] > 0 ? @exp_list[@level+1].to_s : "-------"
 end
 #--------------------------------------------------------------------------
 # * Get Until Next Level EXP String
 #--------------------------------------------------------------------------
 def next_rest_exp_s
   return @exp_list[@level+1] > 0 ?
     (@exp_list[@level+1] - @exp).to_s : "-------"
 end
 #--------------------------------------------------------------------------
 # * Change EXP
 #     exp : new EXP
 #--------------------------------------------------------------------------
 def exp=(exp)
   @exp = [[exp, 99999].min, 0].max
   # Level up
   while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0
     @level += 1
#====================================================================      
# NEEDS HEAVY REVISION CF SKILL WINDOW
     # Learn skill
     for j in $data_classes[@class_id].learnings
       if j.level == @level
         learn_skill(j.skill_id)
       end
     end
   end
#====================================================================    
   # Level down
   while @exp < @exp_list[@level]
     @level -= 1
   end
 end
 #--------------------------------------------------------------------------
 # * Change Level
 #     level : new level
 #--------------------------------------------------------------------------
 def level=(level)
   # Check up and down limits - NEEDS REVISION
   level = [[level, $data_actors[@actor_id].final_level].min, 1].max
   # Change EXP
   self.exp = @exp_list[level]
 end
 #--------------------------------------------------------------------------
 # * Learn Skill
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def learn_skill(skill_id)
   if skill_id > 0 and not skill_learn?(skill_id)
     @skills.push(skill_id)
     @skills.sort!
   end
 end
 #--------------------------------------------------------------------------
 # * Forget Skill
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def forget_skill(skill_id)
   @skills.delete(skill_id)
 end
 #--------------------------------------------------------------------------
 # * Determine if Finished Learning Skill
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def skill_learn?(skill_id)
   return @skills.include?(skill_id)
 end
 #--------------------------------------------------------------------------
 # * Determine if Skill can be Used
 #     skill_id : skill ID
 #--------------------------------------------------------------------------
 def skill_can_use?(skill_id)
   if not skill_learn?(skill_id)
     return false
   end
   return super
 end
end
#===============================================================================
# class Game_Actor
#===============================================================================
class Game_Actor < Game_Battler
 attr_accessor :techniques
 
 alias initialize_techniques initialize
 def initialize(actor_id)
   @techniques = []
   initialize_techniques(actor_id)
 end
 
 alias setup_techniques setup
 def setup(actor_id)
   setup_techniques(actor_id)
   # How will you determine what techniques the character starts with?
 end
 
 # Adds the specified technique to the @techniques array
 def add_tech(tech_id)
   return if @techniques[tech_id] != nil # stops if tech is already possessed
   @techniques[tech_id] = Game_Technique.new(tech_id)
 end

end
I had to change the method name 'def multiplier' to 'def get_multi'. It is entirely possible to just move the contents of that method and put it into 'def initialize' but I wasn't sure if you wanted to, say, add more skills into the technique later on. Tested with Heal and Greater Heal (powers of 150 and 300) and it returned 45.

Also had to shift things around a bit in 'def initialize'.


the stuff labled game actor... can that stuff go into the game actor, or does it have to go above main?

Also, I see you guys use "alias" a lot. What's it for?

in answer to the question "How will you determine what techniques the character starts with?" I planned on using events to grant specific techniques based on player choices during a phase called "character creation". Stock techniques include stuff like black and white magic, melee, dodge, endurance, willpower, and later some thief stuff.

KK20

You can put 'Game_Actor' in its own, separate space, as long as it is below RPG Maker's default 'Game_Actor' and above 'Main'.

There are some guides that explain what alias does, but I'll try to explain it.
class Something
 
  def method_one
    print ("a")
  end
 
  alias copy_of_method_one method_one
  # Essentially means this below:
  # def copy_of_method_one
  #   print("a")
  # end
 
  # You should know that if you define a method that already exists, you are
  # rewriting the method. That's why we made a copy of the original method
  # right before we're about to change it.
  def method_one
    print ("b")
    copy_of_method_one
  end
 
end
If you were to somehow call 'Something.method_one' you would get two pop-up windows, the first saying "b" and the next saying "a". alias means "make an exact copy of the method".

Looking forward to the next reply.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

So I made some small modifications, shown below:

Spoiler: ShowHide


#==============================================================================
# ** Game_Technique
#------------------------------------------------------------------------------
#  This class handles the Techniques. It's used within the Game_Actors class
#  ($game_actors) and refers to the Technique class.
#==============================================================================
#==============================================================================
# ** Game_Technique
#------------------------------------------------------------------------------
#  This class handles the Techniques. It's used within the Game_Actors class
#  ($game_actors) and refers to the Technique class.
#==============================================================================

class Game_Technique
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :id                       # technique ID
  attr_accessor :name                     # e.g. Black Magic, Dodge, Rifles
  attr_accessor :multiplier               # e.g x1, x2, ...x9, etc.
  attr_accessor :exp                      # total exp earned
  attr_accessor :physical                 # true or false
  attr_accessor :magical                  # true or false
  attr_accessor :level                    # level
  attr_accessor :skills                   # skills, spells, merits, flaws
  attr_accessor :description              # help window description
 
  #--------------------------------------------------------------------------
  # * Stock Techniques
  #     tech_id : tech ID
  #--------------------------------------------------------------------------
  def techniques_data(id)
    # return [name, mult, exp, physical?, magical?, level, skills, desc]
    case id
    when 0 then return ["Endurance", 1, 0, true, false, 0, [1, 2, 10], "Hit Point Bonus"]
    end
  end
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     tech_id : tech ID
  #--------------------------------------------------------------------------
  def initialize(tech_id)
    tech = techniques_data(tech_id)
    @tech_id = tech_id
    @name = tech[0]
    @level = tech[5]               
    @physical = tech[3]                 
    @magical = tech[4]
    @description = tech[7]             
    @skills = []
    tech[6].each{|id|
      @skills.push(id)
    }
    @skills.sort!
    @multiplier = get_multi
    @exp_list = Array.new(100)
    make_exp_list
    @exp = tech[2]
  end
  #--------------------------------------------------------------------------
  # * Get Tech ID
  #--------------------------------------------------------------------------
  def id
    return @tech_id
  end
  #--------------------------------------------------------------------------
  # * Get Tech Multiplier # needs revision to 0 + ...0.1+ 0.2 +x9...etc.
  #--------------------------------------------------------------------------
  def get_multi
    m = 0
    @skills.each{|i|
      m += $data_skills[i].power
    }
    n = [1, m/10].max
    return n
  end
  #--------------------------------------------------------------------------
  # * Get Index
  #--------------------------------------------------------------------------
  def index
    return @data[self.index]
  end
  #--------------------------------------------------------------------------
  # * Calculate EXP
  #--------------------------------------------------------------------------
    def make_exp_list
    @exp_list[0] = 0
    for i in 1..99
      @exp_list[i] = Integer(0 + (@multiplier * ((i / 2.0) * (i + 1))))
    end
  end
  #--------------------------------------------------------------------------
  # * Get EXP String
  #--------------------------------------------------------------------------
  def exp_s
    return @exp_list[@level+1] > 0 ? @exp.to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Get Next Level EXP String
  #--------------------------------------------------------------------------
  def next_exp_s
    return @exp_list[@level+1] > 0 ? @exp_list[@level+1].to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Get Until Next Level EXP String
  #--------------------------------------------------------------------------
  def next_rest_exp_s
    return @exp_list[@level+1] > 0 ?
      (@exp_list[@level+1] - @exp).to_s : "-------"
  end
  #--------------------------------------------------------------------------
  # * Change EXP
  #     exp : new EXP
  #--------------------------------------------------------------------------
  def exp=(exp)
    @exp = [[exp, 999999].min, 0].max
    # Level up
    while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0
      @level += 1
#====================================================================     
# NEEDS HEAVY REVISION CF SKILL WINDOW
      # Learn skill
      for j in $data_classes[@class_id].learnings
        if j.level == @level
          learn_skill(j.skill_id)
        end
      end
    end
#====================================================================   
    # Level down
    while @exp < @exp_list[@level]
      @level -= 1
    end
  end
  #--------------------------------------------------------------------------
  # * Change Level
  #     level : new level
  #--------------------------------------------------------------------------
  def level=(level)
    # Check up and down limits - NEEDS REVISION
    level = [[level, $data_actors[@actor_id].final_level].min, 1].max
    # Change EXP
    self.exp = @exp_list[level]
  end
  #--------------------------------------------------------------------------
  # * Learn Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def learn_skill(skill_id)
    if skill_id > 0 and not skill_learn?(skill_id)
      @skills.push(skill_id)
      @skills.sort!
    end
  end
  #--------------------------------------------------------------------------
  # * Forget Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def forget_skill(skill_id)
    @skills.delete(skill_id)
  end
  #--------------------------------------------------------------------------
  # * Determine if Finished Learning Skill
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def skill_learn?(skill_id)
    return @skills.include?(skill_id)
  end
  #--------------------------------------------------------------------------
  # * Determine if Skill can be Used
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def skill_can_use?(skill_id)
    if not skill_learn?(skill_id)
      return false
    end
    return super
  end
end



mainly in the multiplier and experience point system. I dropped my array from 0-100 to 0-99, and started experience point requirements at level 1. The idea is you can have a technique listed, showing you can 'learn it', but you don't know anything about it.  Also took out the absolute value for skill.power, because I wanted some "skills" to act as placeholders for flaws that reduce costs, like vows of poverty or costs permanent [mana/hp/levels/etc.]. Also set the minimum multiplier at x1, so no amount of flaws could reduce raising levels to 0.

Well it's a bit after midnight, so the alias thing is a bit over my head right now, but im happy to have received some guidance. There's not a lot of books on this programming language in my area.

Twb6543

An alias makes a copy of a definition and changes the name of it, this is so you can rewrite the definition without causing errors or just to add something to it...

QuickExamples: ShowHide


# define the Definition to copy
# This method defines a fruit as an array containing "Apple"
def Fruit
  return ["Apple"]
end

call Fruit # Returns ["Apple"]

alias :oldFruit :Fruit
def Fruit
  return ["Apple","Banana"]
end

call Fruit # Returns ["Apple","Banana"]
call oldFruit # Returns ["Apple"]

# Here I show how you can use aliases to add to a definition
# This adds 1 to cost
def costadd1
  @@cost += 1
end

call costadd1 # @@cost + 1

alias :costadd1old :costadd1
def costadd1
  @@cost += 2
  costadd1old # Calls old method
end

# Same as this
=begin
def costadd1
  @@cost += 2
  @@cost += 1 # Calls old method
end
=end

call costadd1 # @@cost + 2 then @@cost + 1
                   # Same as @@cost + 3

call costadd1old # @@cost + 1

If you put a million monkeys at a million keyboards, one of them will eventually write a Java program.
The rest of them will write Perl programs.

shintashi

October 09, 2011, 03:23:32 pm #16 Last Edit: October 09, 2011, 03:34:11 pm by shintashi
I think I get what an Alias does - it protects the original...

So I began testing the script and made an exp fairy event to level up one of the techniques to see if
#1 would it gain experience points?
#2 would a second technique retain it's separate identity?
#3 would the technique gain a level, given enough experience points?

Well, what happened is #1 and #2 worked, and then #3 crashed on the following lines:


#====================================================================      
# NEEDS HEAVY REVISION CF SKILL WINDOW
     # Learn skill
     for j in $data_classes[@class_id].learnings
       if j.level == @level
         learn_skill(j.skill_id)
       end
     end
   end
#====================================================================  


Which wasn't surprising at all, actually. So I took it out

And this is the resulting success:
Spoiler: ShowHide



Now the idea of having the "for i/j" thing was originally to allow people to have something like "black magic" final fantasy 4. So when you get to a certain technique level, you unlock a new spell, and again at a higher level, and so on, just like the actors do with their skill list. I haven't figured out how to set that up yet, but would presume it's a small table or array, that assigns a "level" to zero or more of your technique's skills.

Originally I thought this would only be useful for spells or "secret ninja techniques" etc., but I realize now throwing in some delayed flaws might also be interesting. For example, having some skills in your list simply act as placeholders for common events that inflict insanity, aging, or whatever, would be great for high powered Black Magic.  

For now, it doesn't matter what the skills do, just that there's an optional "level attainment" list for them. I was thinking of exploiting some existing part of skills, like their element checkbox would be the fastest way to say "this skill/spell can have a level", or slightly more complex,
have three elements, like
.power x2 = level
.power x4 = level
.power x8 = level
or whatever. Then with that mechanism in place, I could actually create a "learn powerful spell early" option that would jack up the total skill multiplier.

So if something had a power of 20, and a multiplier of x2, it might be attainable at level 40, but you could have a "learn[skill_id] early" option that allows you to learn it at 20th level. I think the only problem is the complexity of the array. The simplest way to do it is to apply it to all skills, the second simplest is to have a single "skill", or a small list (like three), that reduce levels by something like 4,8, and 32 levels respectively, for a single chosen skill.

I do like the idea of 3 elements determining level attainment, but I'm pretty intimidated by the mess of being able to choose which skill is getting the discount, because it would look something like

game_actor[i].technique[a].skill[x]
game_actor[i].technique[a].skill[y][z]


Where x is the spell (like Meteo), y is the discount (like "learn 8 levels sooner"), and z refers back to Meteo.
Edit: maybe I can create an 8th category called "addendum" or "auxiliary" that's basically a junk array that after the computer checks existing skills, does additional calculations for certain skills and stores it. like which skills are discounted, what special trainers are needed, etc.

shintashi

Two Questions:

if I didn't want the Game_Actor part of this program to be separated using aliases, What would it look like inside game_actor?

and where you said


  alias setup_techniques setup
  def setup(actor_id)
    setup_techniques(actor_id)
    # How will you determine what techniques the character starts with?
  end


is "setup_techniques(actor_id)" a new method for creating a preexisting list? like


def  setup_techniques(actor_id)
n = $data_actors[@actor_id]
case n
    when 0
       return n.techniques = [0,11,13]
    when 1
       return n.techniques = [1,3]
    when 2
       return n.techniques = [0,5,8]
    when 3
       return n.techniques = [0,2,6]
    #etc.
end

end




KK20

Spoiler: ShowHide
class Game_Actor < Game_Battler
  attr_accessor :techniques
 
  def initialize(actor_id)
    @techniques = []
    super()
    setup(actor_id)
  end
 
  def setup(actor_id)
    actor = $data_actors[actor_id]
    @actor_id = actor_id
    @name = actor.name
    @character_name = actor.character_name
    @character_hue = actor.character_hue
    @battler_name = actor.battler_name
    @battler_hue = actor.battler_hue
    @class_id = actor.class_id
    @weapon_id = actor.weapon_id
    @armor1_id = actor.armor1_id
    @armor2_id = actor.armor2_id
    @armor3_id = actor.armor3_id
    @armor4_id = actor.armor4_id
    @level = actor.initial_level
    @exp_list = Array.new(101)
    make_exp_list
    @exp = @exp_list[@level]
    @skills = []
    @hp = maxhp
    @sp = maxsp
    @states = []
    @states_turn = {}
    @maxhp_plus = 0
    @maxsp_plus = 0
    @str_plus = 0
    @dex_plus = 0
    @agi_plus = 0
    @int_plus = 0
    # Learn skill
    for i in 1..@level
      for j in $data_classes[@class_id].learnings
        if j.level == i
          learn_skill(j.skill_id)
        end
      end
    end
    # Update auto state
    update_auto_state(nil, $data_armors[@armor1_id])
    update_auto_state(nil, $data_armors[@armor2_id])
    update_auto_state(nil, $data_armors[@armor3_id])
    update_auto_state(nil, $data_armors[@armor4_id])
  end
end
That 'setup_techniques' was a placeholder. In all actuality, you can delete the 'alias' and 'def setup' and nothing would change. I just wasn't sure how you would initialize what techniques your actors started out with--hence, I put that there for a later time to edit.

Think of alias as the process of mitosis in biology: you start with one cell which becomes two, identical cells. Both of these cells, however, cannot have the same name, so you name one cell Bob and the other Bill. Now translate that metaphor into programming.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

October 11, 2011, 05:23:54 pm #19 Last Edit: October 11, 2011, 05:30:44 pm by shintashi
Quote from: KK20 on October 11, 2011, 01:04:06 pm
Spoiler: ShowHide
class Game_Actor < Game_Battler
 attr_accessor :techniques
 
 def initialize(actor_id)
   @techniques = []
   super()
   setup(actor_id)
 end
 
 def setup(actor_id)
   actor = $data_actors[actor_id]
   @actor_id = actor_id
   @name = actor.name
   @character_name = actor.character_name
   @character_hue = actor.character_hue
   @battler_name = actor.battler_name
   @battler_hue = actor.battler_hue
   @class_id = actor.class_id
   @weapon_id = actor.weapon_id
   @armor1_id = actor.armor1_id
   @armor2_id = actor.armor2_id
   @armor3_id = actor.armor3_id
   @armor4_id = actor.armor4_id
   @level = actor.initial_level
   @exp_list = Array.new(101)
   make_exp_list
   @exp = @exp_list[@level]
   @skills = []
   @hp = maxhp
   @sp = maxsp
   @states = []
   @states_turn = {}
   @maxhp_plus = 0
   @maxsp_plus = 0
   @str_plus = 0
   @dex_plus = 0
   @agi_plus = 0
   @int_plus = 0
   # Learn skill
   for i in 1..@level
     for j in $data_classes[@class_id].learnings
       if j.level == i
         learn_skill(j.skill_id)
       end
     end
   end
   # Update auto state
   update_auto_state(nil, $data_armors[@armor1_id])
   update_auto_state(nil, $data_armors[@armor2_id])
   update_auto_state(nil, $data_armors[@armor3_id])
   update_auto_state(nil, $data_armors[@armor4_id])
 end
end
That 'setup_techniques' was a placeholder. In all actuality, you can delete the 'alias' and 'def setup' and nothing would change. I just wasn't sure how you would initialize what techniques your actors started out with--hence, I put that there for a later time to edit.

Think of alias as the process of mitosis in biology: you start with one cell which becomes two, identical cells. Both of these cells, however, cannot have the same name, so you name one cell Bob and the other Bill. Now translate that metaphor into programming.


Ok, I think I got it to transfer without crashing. I made a dummy holder for


 #--------------------------------------------------------------------------
 # * Setup Techniques for Stock Classes
 #--------------------------------------------------------------------------
 def setup_techniques(actor_id)
 # do nothing for now
 end




And now I'm going to test having the techniques actually do something to the actor, for the first time.

I've chosen "Swords" as my first target, the idea is if your actor gains this technique, they should gain access to the sword list of usable weapons.

If that works, I'm going to see if I can create a thing that depending on my 'swords' level, determines how many on the sword list I've learned. If it works, I can use similar ideas for knives, guns, and possibly spells.

KK20

October 11, 2011, 05:46:41 pm #20 Last Edit: October 11, 2011, 05:51:03 pm by KK20
Haha oh no. 'def setup_techniques' isn't another method; it's an alias for 'def setup'. What I meant as a placeholder was this:
alias setup_techniques setup
def setup(actor_id)
  setup_techniques(actor_id) # Actor.setup(actor_id)
  # This was where I was gonna edit/add stuff, inside this area. Right here where this comment is at.
end
Unless you actually deleted 'alias setup_techniques setup' and 'def setup' in class Game_Actor, your fix will cause an error for setting up your game actors.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

October 11, 2011, 06:03:26 pm #21 Last Edit: October 11, 2011, 06:05:34 pm by shintashi
Ahh, that makes more sense then. it seemed like it was just hanging out, and when I moved it into Game Actor, it didn't seem to have a place.

meanwhile, I ran into a serious problem with equipping characters:

$data_classes[i].weapon_set.push(1)

is based on classes. So if I had two fighters, and one had gained sword access, the other would also have sword access.

Quote
module RPG
 class Class
   def initialize
     @id = 0
     @name = ""
     @position = 0
    @weapon_set = []
     @armor_set = []
     @element_ranks = Table.new(1)
     @state_ranks = Table.new(1)
     @learnings = []
   end
   attr_accessor :id
   attr_accessor :name
   attr_accessor :position
   attr_accessor :weapon_set
   attr_accessor :armor_set
   attr_accessor :element_ranks
   attr_accessor :state_ranks
   attr_accessor :learnings
 end
end


Since the purpose of techniques is to more or less create custom classes from within the actor, changing classes shouldn't be the way to do it. Instead I need to find a way to tell the computer "if is actor" to skip the regular class $data_classes[ i ].weapon_set and go to some 'new and improved' game_actor[ i ].weapon_set, which inherits all the base weapons from the actor's base class (which might be zero), but then has more (or less) of them.

is that even possible? And why do I feel like Alias is a way to do it?

KK20

Just make each actor be its own unique class? Or do you plan to still have the option to change classes?

Anyways, yes, you're right that if you push a weapon into the $data_classes, you affect EVERY instance of any actor that may be of that class type. If you want to make weapons actor-specific, there might be a script for that already. Otherwise, you will have to edit a portion of the other RMXP default scripts (like the Equip_Windows).

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

October 11, 2011, 06:45:58 pm #23 Last Edit: October 11, 2011, 07:14:58 pm by shintashi
Quote from: KK20 on October 11, 2011, 06:27:30 pm
Just make each actor be its own unique class? Or do you plan to still have the option to change classes?

Anyways, yes, you're right that if you push a weapon into the $data_classes, you affect EVERY instance of any actor that may be of that class type. If you want to make weapons actor-specific, there might be a script for that already. Otherwise, you will have to edit a portion of the other RMXP default scripts (like the Equip_Windows).


so I added an attr_accessor for weapon set in game_actor, then made one of these:


 def weapon_set
 weapons = $data_classes[2].weapon_set
 return weapons
 end


And had an event display my actor's weapon_set, and it displayed the numbered array I expected, which is a good thing. Next, I think I need to change "classes[2]" to whatever my class is, then I can change these:


   if item.is_a?(RPG::Weapon)
     # If included among equippable weapons in current class
     if $data_classes[@class_id].weapon_set.include?(item.id)
       return true
     end
   end

...
   # Add equippable weapons
   if @equip_type == 0
     weapon_set = $data_classes[@actor.class_id].weapon_set
     for i in 1...$data_weapons.size
       if $game_party.weapon_number(i) > 0 and weapon_set.include?(i)
         @data.push($data_weapons[i])
       end
     end
   end


Edit:

Game_Actor

  def weapon_set
  weapons = $data_classes[self.class_id].weapon_set
  return weapons
  end




Game_Actor

   if item.is_a?(RPG::Weapon)
      # If included among equippable weapons in current class
      if @weapon_set.include?(item.id)
        return true
      end
    end

...

Window_EquipItem

if @equip_type == 0
      weapon_set = @actor.weapon_set
      for i in 1...$data_weapons.size
        if $game_party.weapon_number(i) > 0 and weapon_set.include?(i)
          @data.push($data_weapons[i])
        end
      end
    end


And I think that wraps up putting in the 'base' weapons, now I just need to figure out how to edit that list.

KK20

October 11, 2011, 07:16:06 pm #24 Last Edit: October 11, 2011, 07:35:43 pm by KK20
Got it:
Spoiler: ShowHide
class Game_Actor < Game_Battler
  attr_accessor :techniques
  attr_accessor :unique_weapon
  attr_accessor :unique_armor
 
  alias initialize_techniques initialize
  def initialize(actor_id)
    @techniques = []
    @unique_weapon = []
    @unique_armor = []
    initialize_techniques(actor_id)
  end
 
  alias call_actor_setup setup
  def setup(actor_id)
    call_actor_setup(actor_id)
    $data_classes[@class_id].weapon_set.each{|w|
      @unique_weapon.push(w)
    }
    $data_classes[@class_id].armor_set.each{|a|
      @unique_armor.push(a)
    }
  end
 
  # Adds the specified technique to the @techniques array
  def add_tech(tech_id)
    return if @techniques[tech_id] != nil # stops if tech is already possessed
    @techniques[tech_id] = Game_Technique.new(tech_id)
  end


  #--------------------------------------------------------------------------
  # * Determine if Equippable
  #     item : item
  #--------------------------------------------------------------------------
  def equippable?(item)
    # If weapon
    if item.is_a?(RPG::Weapon)
      # If included among equippable weapons in current class
      if @unique_weapon.include?(item.id)
        return true
      end
    end
    # If armor
    if item.is_a?(RPG::Armor)
      # If included among equippable armor in current class
      if @unique_armor.include?(item.id)
        return true
      end
    end
    return false
  end
 
end
#===============================================================================
# Modified Equip Window: Shows the proper equips actor can equip
#===============================================================================
class Window_EquipItem < Window_Selectable
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    # Add equippable weapons
    if @equip_type == 0
      weapon_set = @actor.unique_weapon
      for i in 1...$data_weapons.size
        if $game_party.weapon_number(i) > 0 and weapon_set.include?(i)
          @data.push($data_weapons[i])
        end
      end
    end
    # Add equippable armor
    if @equip_type != 0
      armor_set = @actor.unique_armor
      for i in 1...$data_armors.size
        if $game_party.armor_number(i) > 0 and armor_set.include?(i)
          if $data_armors[i].kind == @equip_type-1
            @data.push($data_armors[i])
          end
        end
      end
    end
    # Add blank page
    @data.push(nil)
    # Make a bit map and draw all items
    @item_max = @data.size
    self.contents = Bitmap.new(width - 32, row_max * 32)
    for i in 0...@item_max-1
      draw_item(i)
    end
  end
end
Tested it a bit. Seemed fine. Also possible to use $game_actors[id].unique_weapon.push(id) to add new items.

Edit: Ninja'd
Edit 2: Wait...you said you needed to find a way to add onto the base. In that case, no ninja. I've provided that.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

Unique?  for now I was just trying to expand the existing array using something similar to your add_tech... and my version failed.


# * Custom Weapon Set
  #--------------------------------------------------------------------------
  def weapon_set
  weapons = $data_classes[self.class_id].weapon_set
  return weapons
  end

  #--------------------------------------------------------------------------
  # * Add Weapons *doesn't currently work*
  #--------------------------------------------------------------------------
  def add_weapon(weapon_id)
    return if @weapon_set[weapon_id] != nil
    @weapon_set.push[weapon_id]
  end


weapon_set by itself works, but I don't know how to add new weapons to that set. I modified this line:
 
@weapon_set[weapon_id] = weapon_set.new(weapon_id)


Because I couldn't get it to work, I think its because Game_Technique is its own class, and weapon_set isn't. I wanted to use something like it because your add_tech() thing kicks ass.

KK20

Through testing, I found out that even if you did something like @weapon_set = $data_classes[@class_id].weapon_set and then did @weapon_set.push(100), it would still push 100 as a usable weapon to any actor who shared the same class. As such, I only took the array values from $data_classes[@class_id].weapon_set by using a ".each{}" and stored those values into @unique_weapon. The reason I called it Unique is because only this specific actor has access to this list of weapons. When I did @unique_weapon.push(100)--along with all the modifications I added--only that specific actor was capable of equipping weapon 100. I even had other party members who were the same class and they couldn't equip weapon 100.

Just use my add-on I wrote, and then press CTRL+H to change the names of 'unique_weapon' and 'unique_armor' to whatever you want it to be (I'm guessing 'weapon_set' and 'armor_set').

If you want to make a custom method to add weapons/armors that don't duplicate, do something like:
def add_weapon(id)
    return if @unique_weapon.include?(id)
    @unique_weapon.push(id)
    @unique_weapon.sort!
  end

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

I was impressed  8)

I used your thingymabob w/minimal changes and it worked:


  #--------------------------------------------------------------------------
  # * Add Weapons
  #--------------------------------------------------------------------------
  def add_weapon(weapon_id)
    return if @weapon_set.include?(weapon_id)
    @weapon_set.push(weapon_id)
    @weapon_set.sort!
  end



ForeverZer0

You need to initialize it as a clone of $data_whatever, and it will not add to every actor of the same class.
So, instead of doing something like this:

@unique_weapons = []
$data_weapons.each {|w| @unique_weapons.push(w) }


You can simply initialize is it for each actor like this:

@unique_weapons = $data_weapons.clone

I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

shintashi

October 12, 2011, 12:46:12 pm #29 Last Edit: October 12, 2011, 12:54:20 pm by shintashi
Quote from: ForeverZer0 on October 11, 2011, 08:54:46 pm
You need to initialize it as a clone of $data_whatever, and it will not add to every actor of the same class.
So, instead of doing something like this:

@unique_weapons = []
$data_weapons.each {|w| @unique_weapons.push(w) }


You can simply initialize is it for each actor like this:

@unique_weapons = $data_weapons.clone



I don't understand how you got that to work, but

You illustrate a solid point - I just checked and when I have actors of the same class, and give an actor a new weapon, all other actors of that class get the weapon. This makes absolutely no sense to me, since the weapon should be added to an actor's file, not the class file. I don't understand why this is.

starting off with checking two characters of the same class:

p $game_actors[2].weapon_set



p $game_actors[3].weapon_set


and then doing this:


$game_actors[2].add_weapon(35)


Should not have any effect on the weapon_set of actor 3, but it does.

ForeverZer0

You're saying it still adds to both when you do the clone method?
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

KK20

@weapon_set = $data_classes[@class_id].weapon_set.clone
It looks like this, right? I just did that right now and it worked.

Thanks for that 'clone' tip. It actually helped me out with my current project. :P

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

Quote from: KK20 on October 12, 2011, 02:06:21 pm
@weapon_set = $data_classes[@class_id].weapon_set.clone
It looks like this, right? I just did that right now and it worked.

Thanks for that 'clone' tip. It actually helped me out with my current project. :P


Ahah!

what I was doing was this

    @weapon_set = $data_classes[self.class_id].weapon_set.clone


instead of this

    @weapon_set = $data_classes[@class_id].weapon_set.clone


and so whenever i tested it, neither actor equipment changed upon adding.

then I tried this

@weapon_set = $data_weapons.clone

and that didn't work out too well at all.

KK20

Really? That first line (self.class_id) shouldn't have done anything. Just tested it--no errors.
And the $data_weapons was just an example, not a fix for the script. $data_weapons is something completely different.

Will be gone for a few hours. Try and find a list of what you want done next when I get back; I'm bored.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

ok so I got to sticking the weapons into the actor list based on their techniques,  and this is what I've got:


  #--------------------------------------------------------------------------
  # * Add Techniques
  #--------------------------------------------------------------------------
  def add_tech(tech_id)
    return if @techniques[tech_id] != nil # stops if tech is already possessed
    @techniques[tech_id] = Game_Technique.new(tech_id)
    my_id = tech_id
    weapon_tech(my_id) #this is new
  end
  #--------------------------------------------------------------------------
  # * Custom Weapon Set - technique interface w/ add weapon
  #--------------------------------------------------------------------------
  def weapon_tech(var)
   m = @techniques[var].skills
    if m.include?(6)
      a =  $data_skills[6].str_f
      z =  $data_skills[6].dex_f
          (a..z).step(1) do |n|
        add_weapon(n)
        end
     
    else
      return
   end
  end


Here's how it works:
When a character receives a new technique, the computer checks if that technique comes with weapon proficiencies like swords.

The way I created weapon proficiencies is by creating skills titled stuff like "swords", "axes", "guns", etc. And then exploited the str_f (starting number) and dex_f (end number) to get my number range. The number range is a section of the weapon list. For example, swords might be 1-4, spears 5-8, and axes 9-12. So if my skill was called Swords, I would set str_f to 1, and dex_f to 4, and then my script:


      a =  $data_skills[6].str_f
      z =  $data_skills[6].dex_f
          (a..z).step(1) do |n|
        add_weapon(n)
        end


adds each of these weapons. What I need to know how to do is change that "6", in here:


    if m.include?(6)
      a =  $data_skills[6].str_f
      z =  $data_skills[6].dex_f


into some kind of variable like "i", so it can check not just for skill #6 (which is only swords), but a short list of skills, like 6,7,8,9,10, and maybe some stuff out of order that might come later, like 62 (giant robot weapons?), 63 (joke weapons?), and so on. I just don't know how to turn


if m.include?(6)
      a =  $data_skills[6].str_f
      z =  $data_skills[6].dex_f


into something like


if m.include?([6,7,8,9,10,11,62,63])
      a =  $data_skills[[6,7,8,9,10,11,62,63]].str_f
      z =  $data_skills[[6,7,8,9,10,11,62,63]].dex_f


KK20

Loops. 'nuff said.
Spoiler: ShowHide
  #--------------------------------------------------------------------------
  # * Add Techniques
  #--------------------------------------------------------------------------
  def add_tech(tech_id)
    return if @techniques[tech_id] != nil # stops if tech is already possessed
    @techniques[tech_id] = Game_Technique.new(tech_id)
    weapon_tech(tech_id)
  end
  #--------------------------------------------------------------------------
  # * Custom Weapon Set - technique interface w/ add weapon
  #--------------------------------------------------------------------------
  def weapon_tech(id)
    skills = @techniques[id].skills
    skills.each{|s|
      if [6,7,8,9,10,11,62,63].include?(s)
        a =  $data_skills[s].str_f
        z =  $data_skills[s].dex_f
        for n in a..z
          add_weapon(n)
        end
      end
    }
    p(@weapon_set)
  end
For your array of [6,7,8,9,10,11,62,63], I'm hoping you make that more user-friendly. Unless this script is solely yours...in that case, knock yourself out.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

I originally intended on only having a handful of weapon ranges, and tossed in the ones in the 60s for good measure, in case I added new ones.

I originally thought of making "classes" for the sole purpose of ripping off their weapon sets.

My next task is getting the levels of techniques to count toward attack bonuses. So if you have a level 30 sword, that's +30 to hit. Once "sword" works, I can start proof checking some other aspects, like "swords/level", which turns into "spells/level", since I don't want level 1 characters summoning "bahamut" and casting "meteo", in FF terms.

shintashi

ok, so I've got these techniques that allow me to use weapons, but the techniques also have levels. What I would like to do, is something like the following pseudocode in the Game Battler:


#if using Swords... get technique level
If: wielding $data_weapons[1..4]
Check if @actor.techniques[var].skills[var] includes "6"
If true
attack_skill = @actor.techniques[var].level
else
attack_skill = 0
end

#if using Spears... get technique level
If: wielding $data_weapons[5..8]
Check if @actor.techniques[var].skills[var] includes "7"
If true
attack_skill = @actor.techniques[var].level
else
attack_skill = 0
end

#if using Axes... get technique level
If: wielding $data_weapons[5..8]
Check if @actor.techniques[var].skills[var] includes "9"
If true
attack_skill = @actor.techniques[var].level
else
attack_skill = 0
end


Basically, if I have a Technique that teaches some weapons,

and I'm attacking,

The computer checks my current equipped weapon id,

and then compares that with a small table of weapons:

[weapon id's][skill id]
[1-4]..........[6]
[5-8]..........[7]
[11-12].......[8]
[13-16].......[9]
[17-20].......[10]
[21-24].......[11]

alternatively, I realized that if you have a given weapon id, you probably have the skill related,
so what we really need to do is check to see which technique you have that has the skill id in it's array.

and most importantly, if you have more than one techniques with the same skill id (like 6 for swords),
then stick these technique.levels in an array, sort, and use the highest level.

This somehow seems easier...  :???:

shintashi

This is what I've got so far,


for i in 0.. @actor.techniques.size
a = @actor.techniques[i].skills
if a.include?(6)
sword_skills <<  @actor.techniques[i].level
else
return
end
end


and then I need some kind of sort 'sword_skills' array, which can then be sorted, and then the highest number becomes attack_skill.  :D

shintashi

October 23, 2011, 07:04:31 pm #39 Last Edit: October 23, 2011, 07:19:51 pm by shintashi
well I've messed with it some more, and as usual, ran into some nil errors:


 #--------------------------------------------------------------------------
 # * Get Hit Rate
 #--------------------------------------------------------------------------
 def hit
    if self.is_a?(Game_Actor)
      sword_skills = [] # blank array
      if self.techniques.size == 0
        sword_skills << 0
      else
       for i in 0.. self.techniques.size
          a = self.techniques[i].skills
          p a
          if a.include?(6)
            sword_skills << self.techniques[i].level
          else
            return
          end
        end
      end
     
    n = 1 + sword_skills.max
   #n = 100
   #p self.techniques #works
   else  
   n = 100
   end
   for i in @states
     n *= $data_states[i].hit_rate / 100.0
   end
   return Integer(n)
 end


basically the line it dies on is

 
         a = self.techniques[i].skills


which is odd because I can usually get self.techniques[0,1,2,3..].skills or whatever to print.

edit: I've been getting weird results lately:

like "p self.techniques.size" spitting out 3 or 5 when my actor only has 1 technique.

ForeverZer0

Don't us a "return" nested in a loop. Use the word "next" to skip to the next iteration, or "break" if you want to exit the loop. If you are using the method as an iterator (which you're not in that example), you would use the "yield" keyword, not "return".

From what you have posted, it could be a few things, not all of which can be determined by the code. The "return" thing I just mentioned could easily be the cause, but some other things such as what the values of your techniques are and how they initialized.

I mean nothing bad by this, but I want to point out that your coding is very sloppy. Having your code poorly structured can make debugging a nightmare. My best suggestion would be to stop where you are, go back and see how you might structure it a bit better, and implement it. Having done so, you will be surprised how many less problems you have, and how much easier the ones you do get will be to find. I'm not suggesting that you start over, but I see many cases where it would benefit you greatly to subclass something or handle data differently that would make everything much easier to control.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

shintashi

I majored in Religious Studies, and have 0 classes in programming, I can't even tell the difference between sloppy and not. This month has been pretty good for me - I started using indents.

Meanwhile, I got a really weird semifunctional result with this one:


#--------------------------------------------------------------------------
  # * Get Hit Rate
  #--------------------------------------------------------------------------
  def hit
     if self.is_a?(Game_Actor)
       sword_skills = [] # blank array
       if self.techniques.size == 0
         sword_skills << 0
       else
        for m in 0..self.techniques.size
          p self.techniques[2] #prints normal data...3 times?
          a = self.techniques[2].skills
           if a.include?(6)
             sword_skills << self.techniques[2].level
           else
             return
           end
         end
       end
       
     n = 1 + sword_skills.max
    #n = 100
    #p self.techniques #works
    else   
    n = 100
    end
    for i in @states
      n *= $data_states[i].hit_rate / 100.0
    end
    return Integer(n)
  end


What I don't get, is why it prints 3 times when I only have one technique, and why I can't get the for loop to

1. check all techniques for skill number 6,
2. add technique to the sword_skill array
3. get the highest listed skill in sword_skill
4. use that highest skill level as the basis for my "hit"

like say I have $game_actor[2].technique[2].skill[6]... that means my actor has a technique that has "swords" as a skill.
That technique (technique[2]) has a level: $game_actor[2].technique[2].level

shintashi

ok so i took out the for loop.


 #--------------------------------------------------------------------------
 # * Get Hit Rate
 #--------------------------------------------------------------------------
 def hit
    if self.is_a?(Game_Actor)
      sword_skills = []
     
      if self.techniques.size == 0
        sword_skills << 0
      else
       a = self.techniques[2].skills
         if a.include?(6)
           sword_skills << self.techniques[2].level
         else
           return
         end
      end
    n = 1 + sword_skills.max
   else  
     n = 100
   end
   for i in @states
     n *= $data_states[i].hit_rate / 100.0
   end
   return Integer(n)
 end


This script works fine. The only problem is, if my actor has a different technique that also has swords, this script will not detect it.

i need to
first; check all the actor's techniques
second: check each technique for all skills
third: compare all these skills to an integer
four: if that integer is the same, get the technique skill level
five: put the skill level in a temporary array
six: get the highest skill level in the array
seven: use the highest skill level as my "hit" score in battle.


ForeverZer0

I have never taken a programming class myself, and have never been to college, so that is not an excuse to not learn it.
To be quite honest, the sloppiness and disorganization is the problem with your script. No one starts out scripting as a master, I have made some very unorganized scripts myself. That is why I am telling you from experience, you are going to continue to have numerous problems until you look into cleaning it up a bit, plus it would help others understand enough to help you better.

Did you try removing the "return" from the for..end loop before just removing the loop altogether?
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

shintashi

October 23, 2011, 10:12:52 pm #44 Last Edit: October 23, 2011, 10:21:41 pm by shintashi
Quote from: ForeverZer0 on October 23, 2011, 09:20:28 pm
I have never taken a programming class myself, and have never been to college, so that is not an excuse to not learn it.
To be quite honest, the sloppiness and disorganization is the problem with your script. No one starts out scripting as a master, I have made some very unorganized scripts myself. That is why I am telling you from experience, you are going to continue to have numerous problems until you look into cleaning it up a bit, plus it would help others understand enough to help you better.

Did you try removing the "return" from the for..end loop before just removing the loop altogether?


yep


 def hit
    if self.is_a?(Game_Actor)
      sword_skills = []
      for i in 0.. self.techniques.size
        if self.techniques.size == 0
          sword_skills << 0
        else
         a = self.techniques[i].skills
           if a.include?(6)
             sword_skills << self.techniques[i].level
           else
             next
           end
         end
       end


but I get a undefined method 'skills' for niNilClass referring to this:

         a = self.techniques[i].skills


Which I have no idea how to get around.


I'm hoping to turn a working version of this into a method I can apply to any weapon,

i.e, something like:


def weapon_range
weapon = ($data_weapons[@weapon_id] / 4.0)
return weapon.ceil
end
...

when 1
weapon_check(6)
when 2
weapon_check(7)
when 3
weapon_check(7)

...

def weapon_check(num)
if self.is_a?(Game_Actor)
   for i in 0.. self.techniques.size
      a =self.techniques[i].skills
      if a.include?(num)
         weapon_skills <<  self.techniques[i].level
      else
        next
      end
   end
  end
end


ForeverZer0

Your looking in the wrong place. Find where "technique" is created, and find out why it is setting one of them to nil.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

shintashi

October 23, 2011, 10:23:59 pm #46 Last Edit: October 23, 2011, 10:51:42 pm by shintashi
Quote from: ForeverZer0 on October 23, 2011, 10:21:26 pm
Your looking in the wrong place. Find where "technique" is created, and find out why it is setting one of them to nil.


by 'setting one of them' to nil, do you mean techniques or techniques[n].skills? It detects techniques, but I'm having difficulty detecting the skills.

edit: here's the section where skills are added:

Quote
 def initialize(tech_id)
   tech = techniques_data(tech_id)
   @tech_id = tech_id
   @name = tech[0]
   @level = tech[5]              
   @physical = tech[3]                
   @magical = tech[4]
   @description = tech[7]            
   @skills = []
   tech[6].each{|id|
     @skills.push(id)
   }
   @skills.sort!                      

   @multiplier = get_multi
   @exp_list = Array.new(100)
   make_exp_list
   @exp = tech[2]
 end


i have the @actor getting the attack skill here:


$game_actors[2].add_tech(2)


which refers to this in Game_Actor


  def add_tech(tech_id)
    return if @techniques[tech_id] != nil # stops if tech is already possessed
    @techniques[tech_id] = Game_Technique.new(tech_id)
    my_id = tech_id
    weapon_tech(my_id)
  end

ForeverZer0

Juts insert a "p tech[6]" and "p tech[5]" there, and make sure they are okay. If not, look through the "techniques_data" method and see why they are not.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

shintashi

Quote from: ForeverZer0 on October 23, 2011, 10:51:24 pm
Juts insert a "p tech[6]" and "p tech[5]" there, and make sure they are okay. If not, look through the "techniques_data" method and see why they are not.


i get nil and nil, whereas p techniques[0] and p techniques[2], produce nil, and this:

Spoiler: ShowHide




before the next line produces the same undefined method 'skills' for niNilClass


shintashi

I've realized I don't need "self" as part of battler, so I did some reorganizing,


         if @techniques.size == 0
           sword_skills << 0
         else
           for i in 0...@techniques.size
            p @techniques[i]
            a = @techniques[i].skills
            if a.include?(6)
              sword_skills << @techniques[i].level
            else
              next
            end
          end         
        end
 


but I noticed the result is almost identical, and unexplainable.

p @techniques[i]


also produces "nil" which naturally leads to crash on nil.skills. I was about to do something amazing related to picking out what little data I could and then slamming down the the program's throat, as it were, but the whole self/@ thing messed up my train of thought... I'll keep trying though.

shintashi

October 23, 2011, 11:59:41 pm #50 Last Edit: October 24, 2011, 12:04:45 am by shintashi
this appears to have worked, but I'm not sure...


 def hit
    if self.is_a?(Game_Actor)
      sword_skills = []
     
        if @techniques.size == 0
          sword_skills << 0
        else
         for i in 0...@techniques.size
           
            if @techniques[i] == nil
              p "nope"
              next
            else
             p @techniques[i]
             a = @techniques[i].skills
               if a.include?(6)
                 sword_skills << @techniques[i].level
               else
                 next
               end #if include
               
           end #if tech = nil
           
         end #for i in 0
         
       end # if tech size
 
    n = 1 + sword_skills.max
   else  
     n = 100
   end # if is actor
   
   for i in @states
     n *= $data_states[i].hit_rate / 100.0
   end
   return Integer(n)
 end


I will have test it with multiple levels and multiple characters with swords before determining if it's actually functional... unless I've made some kind of obvious error.

edit: tried it with multiple actors, seems to work, but posts "nope" twice before posting techniques. Not sure why it gets two nils first, but it gets them for all actors.

shintashi

Update:

So I broke "Get Hit Rate" into three parts, and for the most part, it works, although if for some reason your actor has a technique (in other words, the technique array isn't blank), and you are for some crazy reason wielding a weapon you don't have a technique for, it crashes where it says  "weapon_skills << @techniques[ i ].level"

Spoiler: ShowHide


  #--------------------------------------------------------------------------
  # * Get Hit Rate I: Weapon Range
  #--------------------------------------------------------------------------
  def weapon_range
    if self.is_a?(Game_Actor)
      weapon = @weapon_id / 4.0
      return weapon.ceil
    else
      return 0
    end
  end
  #--------------------------------------------------------------------------
  # * Get Hit Rate II: Weapon Check
  #--------------------------------------------------------------------------
  def weapon_check(num)
       if self.is_a?(Game_Actor)
       weapon_skills = []
         if @techniques.size == 0
           weapon_skills << 0
           p weapon_skills
         else
          for i in 0...@techniques.size
             if @techniques[i] == nil
               next
             else
              a = @techniques[i].skills
                if a.include?(num)
                  weapon_skills << @techniques[i].level
                  p weapon_skills
                else
                  next
                end #if include
            end #if tech = nil
          end #for i in 0
        end # if tech size
p weapon_skills       
     n = 1 + weapon_skills.max
    else   
      n = 100
    end # if is actor
    #check for states
    for i in @states
      n *= $data_states[i].hit_rate / 100.0
    end
    return Integer(n)
  end
  #--------------------------------------------------------------------------
  # * Get Hit Rate III: Hit
  #--------------------------------------------------------------------------
  def hit
    case weapon_range
      when 0 #unarmed - will be revised later
        n = 100 #default for monsters for now... add when -1 or something later
      when 1 #swords (lists like this one will be expanded)
        weapon_check(6)
      when 2 #spears
        weapon_check(7)
      when 3 #axes
        weapon_check(8)
      when 4 #knives
        weapon_check(9)
      when 5 #bows
        weapon_check(10)
      when 6 #guns
        weapon_check(11)
      when 7 #maces
        weapon_check(12)
      when 8 #rods (canes, staves etc.)
        weapon_check(13)
      when 9 #asian blades (katana, wakazashi, zatoichi, shikomezui)
        weapon_check(14)
      when 10 #mecha blades
        weapon_check(15)
      end
    end




I think I can fix that, but it will have to wait till the morning.

KK20

October 24, 2011, 03:14:53 am #52 Last Edit: October 24, 2011, 03:28:59 am by KK20
$game_actors[1].add_tech(0) #=> Aluxes gets technique with ID 0 (last time I checked, this was Endurance).
p $game_actors[1].techniques #=> DOES NOT DISPLAY an array with 0 in it. It will print out the whole technique array you have set up in Game_Technique.
'for index in 0.. @techniques.size' followed with '@techniques[index]' will be wrong. The way I have set up @techniques in Game_Actors is that the index value of the technique is located at the index value within @techniques. So if you added techniques 0, 1, and 5, '@techniques.size = 3'. @techniques[0] and @techniques[1] exist. But what the hell would @techniques[2] be? @techniques[2] is nil.

Use @techniques.each{|tech| #CODE HERE# } instead.

Edit: Upon further realization, if there is a gap between tech IDs, 'each' still runs through them. Nothing like a 'next if tech.nil?' can't fix.
Further Edit: Okay, so @techniques.size would include the nils as well...forget everything I said. Just use what I said directly above ^^^^.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

Quote from: KK20 on October 24, 2011, 03:14:53 am
$game_actors[1].add_tech(0) #=> Aluxes gets technique with ID 0 (last time I checked, this was Endurance).
p $game_actors[1].techniques #=> DOES NOT DISPLAY an array with 0 in it. It will print out the whole technique array you have set up in Game_Technique.
'for index in 0.. @techniques.size' followed with '@techniques[index]' will be wrong. The way I have set up @techniques in Game_Actors is that the index value of the technique is located at the index value within @techniques. So if you added techniques 0, 1, and 5, '@techniques.size = 3'. @techniques[0] and @techniques[1] exist. But what the hell would @techniques[2] be? @techniques[2] is nil.

Use @techniques.each{|tech| #CODE HERE# } instead.

Edit: Upon further realization, if there is a gap between tech IDs, 'each' still runs through them. Nothing like a 'next if tech.nil?' can't fix.
Further Edit: Okay, so @techniques.size would include the nils as well...forget everything I said. Just use what I said directly above ^^^^.


That would explain it actually. Since we created stock techniques as a starting framework for "beginners", they would be assigning id numbers like 2 or 6 to their first techniques. Endurance is definitely tech 0, since it's going to be the "get more hit points" technique.

here's the stock list so far:


when 0 then return ["Endurance", 1, 0, true, false, 0, [1], "Hit Point Bonus"]
    when 1 then return ["Dodge", 1, 0, true, false, 0, [3], "Avoid Attack"]
    when 2 then return ["Swords", 1, 0, true, false, 0, [6], "Use Swords"]
    when 3 then return ["Willpower", 1, 0, false, true, 0, [2], "Spell Point Bonus"]
    when 4 then return ["White Magic", 1, 0, false, true, 0, [35,36,37], "Protection and Healing"]
    when 5 then return ["Black Magic", 1, 0, false, true, 0, [38,39,40], "War and Death"]
    when 6 then return ["Stealth", 1, 0, true, false, 0, [32], "Avoid Detection"]
    when 7 then return ["Perception", 1, 0, false, true, 0, [30], "Percieve Reality"]
    when 8 then return ["Guns", 1, 0, true, false, 0, [11], "Use Guns"]
    when 9 then return ["Block", 1, 0, true, false, 0, [13], "Block Attacks Unarmed"]
    when 10 then return ["Parry", 1, 0, true, false, 0, [14], "Block Attacks With Weapon"] 


numbers may change later, but for now the goal is get at least ONE tech to do something. Two questions:
first question:
how does next if tech.nil? differ from


if @techniques[i] == nil
               next


second question:
if we used that copy class weapons thing for actors like Aluxes,


    @weapon_set = $data_classes[@class_id].weapon_set.clone


how can we "auto fill" some techniques, so when the battler says "hey you can use this weapon... but uh... you don't have a technique for it.. here ya go... you get tech[6 or whatever] at level 0... happy hunting"

shintashi

October 24, 2011, 02:07:32 pm #54 Last Edit: October 24, 2011, 02:33:04 pm by shintashi
here's something I came up with called the grandfather clause:


 #--------------------------------------------------------------------------
 # * Get Hit Rate IV: Grandfather Clause - adds techs for weapons you have
 #--------------------------------------------------------------------------
 def grandfather_tech
   case @grandfather
     when 0 #unarmed - will be revised later
       next
     when 6 #swords
       #$game_actors[2].add_tech(0)
       #self.add_tech(0)
       add_tech(2)
     when 7 #spears
       add_tech(11)
     when 8 #axes
       add_tech(12)
     when 9 #knives
       add_tech(13)
     when 10 #bows
       add_tech(14)
     when 11 #guns
       add_tech(8)
     when 12 #maces
       add_tech(15)
     when 13 #rods
       add_tech(16)
     when 14 #asian blades
       add_tech(17)
     when 36 #mecha blades
       add_tech(18)
     end
   end



I don't know if it works yet, because I'm still deciding on which line to implement it in, but basically, when you are checking to see if player has "tech" related to their existing wielded weapons, if no technique comes up, you get an adjoining technique with levels. This is tweaky because at some point someone's going to make a kensai who can only wield one kind of weapon, and that should only be worth like 0.2 to their skill multiplier.

I was thinking of on the fly skill allocation, or a dumping bucket. All said, I don't want 40+ "skills" dedicated just to weapon proficiencies. Maybe I can make an "exotic" or "specialist" skill that's worth some points, but I don't see how I'm going to get around the "now everyone with specialist has access to that weapon".

Edit: Wait,

what if I ninja it by creating a special skill that has access to all skills, but not really? like a skill the program checks for to see if you have a 'special' weapon, or special weapons, and then if you have a technique with the "special weapon" skill, it includes that as a viable option for whatever weapon you have, and gets it's level from the technique with "special weapon' skill.

This works perfectly as long as a character only has one special weapon, but I think an array option for the technique has to be checked to see which special weapon it is.

This way, the computer would first check to see if you had a generic stock skill that matched in one of your techniques, plus the special weapon category. if the special weapon category existed, it would then check THAT skills @special category - probably a short list of array options for addenum, just like this. Much like "level" the number would be unique to the @actor with THAT technique,

thus, if Aluxes is game actor 1, "special" is skill #42 (life, universe, and everything, etc.) and "Blademaster" is a technique[21], we might have
$game_actor.techniques[21].level
$game_actor.techniques[21].skills[42]
$game_actor.techniques[21].addendum[nil,nil,2]

with the third slot of "addendum" being which weapon in the $data_weapons list to check against, and if that's the same as the weapon they are wielding - then blamo, add $game_actor.techniques[21].level to the weapon_skills array for determining hit bonus.  :???: 

KK20

There is no difference. It's a matter of one line of code versus two. '== nil' is the same as '.nil?'.

For that, you will have to make another method to check that. Get the class's useable weapons, run through all the possible techniques you have that have the skill required to use that weapon, then use that technique's ID in method 'add_tech'. It's probably best that this new method is called in two spots: when the actor is initialized (aka under def setup) and rewriting or aliasing class change.

Since you posted something while I was typing this up, what you have there seems to work, assuming that you don't want this script to be easily customizable. And the use of 'next' only applies to loops. If you want 'case 0' to do nothing, you don't have to write anything.

And you lost me with all of your explanation stuff below.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

shintashi

it appears to work:

start to finish it looks like this:

Spoiler: ShowHide


#--------------------------------------------------------------------------
  # * Get Hit Rate I: Weapon Range
  #--------------------------------------------------------------------------
  def weapon_range
    if self.is_a?(Game_Actor)
      weapon = @weapon_id / 4.0
      return weapon.ceil
    else
      return 0
    end
  end
  #--------------------------------------------------------------------------
  # * Get Hit Rate II: Weapon Check
  #--------------------------------------------------------------------------
  def weapon_check(num)
       if self.is_a?(Game_Actor)
       weapon_skills = []
       @grandfather = num
         if @techniques.size == 0
           weapon_skills << 0
         else
          for i in 0...@techniques.size
             if @techniques[i] == nil
               next
             else
              a = @techniques[i].skills
                if a.include?(num)
                  weapon_skills << @techniques[i].level
                  p weapon_skills
                else
                  grandfather_tech
                  weapon_skills << @techniques[i].level
                  next
                end #if include
            end #if tech = nil
          end #for i in 0
        end # if tech size
     n = 10 + weapon_skills.max #change to other number later
    else   
      n = 100
    end # if is actor
    #check for states
    for i in @states
      n *= $data_states[i].hit_rate / 100.0
    end
    return Integer(n)
  end
  #--------------------------------------------------------------------------
  # * Get Hit Rate III: Hit
  #--------------------------------------------------------------------------
  def hit
    case weapon_range
      when 0 #unarmed - will be revised later
        n = 100 #default for monsters for now... add when -1 or something later
      when 1 #swords (lists like this one will be expanded)
        weapon_check(6)
      when 2 #spears
        weapon_check(7)
      when 3 #axes
        weapon_check(8)
      when 4 #knives
        weapon_check(9)
      when 5 #bows
        weapon_check(10)
      when 6 #guns
        weapon_check(11)
      when 7 #maces
        weapon_check(12)
      when 8 #rods (canes, staves etc.)
        weapon_check(13)
      when 9 #asian blades (katana, wakazashi, zatoichi, shikomezui)
        weapon_check(14)
      when 10 #mecha blades
        weapon_check(36)
      end
    end
  #--------------------------------------------------------------------------
  # * Get Hit Rate IV: Grandfather Clause - adds techs for weapons you have
  #--------------------------------------------------------------------------
  def grandfather_tech
    case @grandfather
      when 0 #unarmed - will be revised later
        next #may crash
      when 6 #swords
        #$game_actors[2].add_tech(0)
        #self.add_tech(0)
        add_tech(2)
      when 7 #spears
        add_tech(11)
      when 8 #axes
        add_tech(12)
      when 9 #knives
        add_tech(13)
      when 10 #bows
        add_tech(14)
      when 11 #guns
        add_tech(8)
      when 12 #maces
        add_tech(15)
      when 13 #rods
        add_tech(16)
      when 14 #asian blades
        add_tech(17)
      when 36 #mecha blades
        add_tech(18)
      end
    end





I'll come back to this @addendum and specialist stuff later - I have a feeling it will be useful when setting up the level ranges for martial arts and spell acquisition (i.e. how to stop a level 1 character from summoning Bahamut). For now, I need to integrate "dodge" and "hit" together with the Strategy bar in battle.

shintashi

So I've integrated Dodge and Hit together, with the strategy bar system also built into it:


in Game_Battler 1
Spoiler: ShowHide


#--------------------------------------------------------------------------
  # * Get Base Dodge
  #--------------------------------------------------------------------------
  def dodge_check
       if self.is_a?(Game_Actor)
       dodge_skills = []
         if @techniques.size == 0
           dodge_skills << 0
         else
          for i in 0...@techniques.size
             if @techniques[i] == nil
               next
             else
              a = @techniques[i].skills
                if a.include?(3)
                  dodge_skills << @techniques[i].level
                else
                  dodge_skills << 0
                  next
                end #if include
            end #if tech = nil
          end #for i in 0
        end # if tech size
     player_dodge = 0 + dodge_skills.max
     if player_dodge < self.agi
      b_dodge = self.agi - player_dodge
      n = player_dodge + Integer(b_dodge / 3)
    else
      n = player_dodge # dodge higher than agility?
    end
  else   
      n = Integer(self.agi / 3)
    end # if is actor
    return Integer(n)
  end





and in Game_Battler 3
Spoiler: ShowHide


  #--------------------------------------------------------------------------
  # * Applying Normal Attack Effects
  #     attacker.hit : battler vs. self.dodge_check
  #--------------------------------------------------------------------------
  def attack_effect(attacker)
    # Clear critical flag
    self.critical = false
    # First hit detection: high finesse (dodge) vs. low uke (hit)
    if attacker.is_a?(Game_Actor)
       if attacker.hit > self.dodge_check
        bonus_dodge = attacker.hit - self.dodge_check
        dynamic_bonus = bonus_dodge + 10 #enemies don't have strat_bars (+agg)
        dynamic_dodge = self.dodge_check + rand(dynamic_bonus)
        static_hit = attacker.hit - attacker.uke
        hit_result = (dynamic_dodge < static_hit)
      else
        bonus_hit = self.dodge_check - attacker.hit
        dynamic_bonus = bonus_hit - attacker.uke + 10
        dynamic_hit = attacker.hit + rand(dynamic_bonus)
        hit_result = (self.dodge_check < dynamic_hit)
      end
    else
      if attacker.hit > self.dodge_check
        bonus_dodge = attacker.hit - self.dodge_check
        dynamic_bonus = bonus_dodge + self.agg + 10
        dynamic_dodge = self.dodge_check + rand(dynamic_bonus)
        hit_result = (dynamic_dodge < attacker.hit)
      else
        bonus_hit = self.dodge_check - attacker.hit
        dynamic_bonus = bonus_hit + 10 #enemies don't hav strat_bars (-uke)
        dynamic_hit = attacker.hit + rand(dynamic_bonus)
        hit_result = (self.dodge_check < dynamic_hit)
      end
    end
    # If hit occurs
    if hit_result == true
      # Calculate basic damage



right now it favors the actors who use strategy and favors creatures with high stats because they can default a stat at 1/3rd for their dodge skill. I'm still integrating other parts of the strategy bar, after which, I think I'll tackle hit points, then spell points (which should be a clone of hit point script), and then @addendum

which will probably be something like
@addendum = [[spell_order], [martial_order], specialist, nil, nil, nil,...]

since so far i've only confirmed unique weapons, spell levels, and martial arts levels.

shintashi

I've integrated critical hit and strategy bars together, and got a nice clean 2000+ damage when critical hit was level 94. I'm using a multi-technique script, that for now works with one attribute,

Spoiler: ShowHide


  #--------------------------------------------------------------------------
  # * Get Base Critical/other Int based Techniques
  #--------------------------------------------------------------------------
  # critical = int_check(34); perception = int_check(??)
  def int_check(num)
       if self.is_a?(Game_Actor)
       int_skills = []
         if @techniques.size == 0
           int_skills << 0
         else
          for i in 0...@techniques.size
             if @techniques[i] == nil
               next
             else
              a = @techniques[i].skills
                if a.include?(num) #replace with 34 to make "critical"
                  int_skills << @techniques[i].level
                else
                  int_skills << 0
                  next
                end #if include
            end #if tech = nil
          end #for i in 0
        end # if tech size
        player_int = 0 + int_skills.max
        if player_int < self.int
          b_int = self.int - player_int
          n = player_int + Integer(b_int / 3)
        else
          n = player_int # example: critical higher than intellect?
        end
      else
      n = Integer(self.int / 3) #10 intellect is average, 3% critical
    end # if is actor
    return Integer(n)
  end




This is in conjunction with this in part 3 of battler:

Spoiler: ShowHide


# Calculate critical damage *Plus Timing*
      if self.damage > 0
        critical_hit = attacker.int_check(34)
        if attacker.is_a?(Game_Actor)
          if rand(100) < (critical_hit + attacker.spd)
            self.damage *= (1 + Integer(critical_hit / 10))
            self.critical = true
          end
        else
          if rand(100) < critical_hit #vs. danger sense/solo/precog.?
            self.damage *= (1 + Integer(critical_hit /10))
            self.critical = true
          end
        end
          # Guard correction #replace this with parry or "defend other" options
        if self.guarding?
          self.damage /= 2
        end
      end



I've also started messing around with "size" as in sprites vs. dragons or giant robots. At first I was going to rewrite hit points so @actor.stamina X @actor.endurance = hit points, but I realized the actors have no stamina, which puts us at @actor.str x @actor.endurance, but then I realized monsters have no endurance, so my dilemma looks like this:

@actor.sta x @actor.end = hp
@enemy.sta x @enemy.end = hp

@actor.??? x @actor.end = hp
@enemy.??? x @enemy.??? = hp


of course, I can just assign monsters hit points, and use physical defense and magical defense and strength as the defaults for Stamina, but that seems oddly more quirky than assigning them a single new attribute to handle all of those factors.

I figure by taking the target's base strength and giving them a "size", they can have stamina that won't directly correlate 1:1.