Szibes

Veteran
Veteran
Joined
Mar 5, 2021
Messages
30
Reaction score
5
First Language
Polish
Primarily Uses
RMVXA
Is there a way to change how Crystal Engine Extra Stats work, so that state notetag will add flat value to a stat instead of multiplying it?

Extra Stats script:
Ruby:
#==============================================================================
# Crystal Engine - Extra Stats
#------------------------------------------------------------------------------
# Current Version: 1.06
#==============================================================================
$imported ||= {}
$imported["CE-ExtraStats"] = true
=begin
This script allows for you to have additional stats for your battler. Those are
viewable on the default status screen for your convinece. To use them in damage
formulas use xstat.(stat abriviation).
-------------------------------------------------------------------------------
Notetags:
Actor Notes
<xstat> # Sets the xstat formulas up. This takes precidence over the class formula
stat => formula, # Be sure to put a collon on the stats.
</xstat_end> # The formula can be any valid ruby exprssion that returns a number.
<state_xstat: stat x%> # Sets the specified stat to be multiplied by x%
Class Notes
<xstat> # Sets the xstat formulas up.
stat => formula, # Be sure to put a collon on the stats.
</xstat_end> # The formula can be any valid ruby exprssion that returns a number.
<state_xstat: stat x%> # Sets the specified stat to be multiplied by x%
Skill Notes
<xstat growth: stat x> # Changes the specified stat by x
Item Notes
<xstat growth: stat x> # Changes the specified stat by x
Weapon Notes
<weapon_xstat: stat +x> # Sets the specified stat to be modified by x
<state_xstat: stat x%> # Sets the specified stat to be multiplied by x%
Armor Notes
<weapon_xstat: stat +x> # Sets the specified stat to be modified by x
<state_xstat: stat x%> # Sets the specified stat to be multiplied by x%
Enemy Notes
<xstat> # Sets the xstat formulas up. This takes precidence over the class formula
stat => formula, # Be sure to put a collon on the stats.
</xstat_end> # The formula can be any valid ruby exprssion that returns a number.
<state_xstat: stat x%> # Sets the specified stat to be multiplied by x%
State Notes
<state_xstat: stat x%> # Sets the specified stat to be multiplied by x%
-------------------------------------------------------------------------------
Script Calls:
change_xstat(actor_id, stat, value) # Alter the specified stat by the specifed
# value. Can be either positive or negative.
=end
module CRYSTAL
  module XSTAT
   
    STATS = [:str,:sta,:spi]
   
    #Default xstat formulas for ACTORS
    DEFAULT_LEVEL_FORMULA = {
      :str => '23 + ((level * 70) / 128)',
      :sta => '24 + ((level * 48) / 128)',
      :spi => '20 + ((level * 57) / 128)',
      }
   
    #Default xstat formulas for ENEMIES    
    DEFAULT_FOR_ENEMIES = {
    :str => 'database_param(2)',
    :sta => 'param(3) * 2',
    :spi => 'mat',
    }
   
    TERMS = {
    :str => "STR",
    :sta => "STA",
    :spi => "SPI",
    }
   
    STAT_MIN = {
    :str => 1,
    :sta => 1,
    :spi => 1,
    }
   
    STAT_MAX = {
    :str => 99,
    :sta => 99,
    :spi => 99,
    }
   
  end
end
#==============================================================================
# Editing beyond this point may cause stone, zombie, mist frenzy, and/or toad,
# so edit at your own risk.
#==============================================================================
#==============================================================================
# ** RPG::BaseItem
#------------------------------------------------------------------------------
#  Superclass of actor, class, skill, item, weapon, armor, enemy, and state.
#==============================================================================

class RPG::BaseItem
  #--------------------------------------------------------------------------
  # * Extra Stat Formula
  #--------------------------------------------------------------------------
  def xstat_formula(stat)
    return @xstat[stat] if @xstat && @xstat[stat]
    @xstat ||= {}
    xstats_defining = false
    @note.split(/[\r\n]+/).each do |line|
      case line
      when /<XSTAT>/i
        xstats_defining = true
      when /<\/XSTAT_END>/i
        xstats_defining = false
      when /#{stat} => '(.*)',/i
        next unless xstats_defining
        @xstat[stat] = $1.to_s
      end
    end
    if is_a?(RPG::Actor) || is_a?(RPG::Class)
      @xstat[stat] ||= CRYSTAL::XSTAT::DEFAULT_LEVEL_FORMULA[stat]
    else
      @xstat[stat] ||= CRYSTAL::XSTAT::DEFAULT_FOR_ENEMIES[stat]
    end
    return @xstat[stat]
  end
  #--------------------------------------------------------------------------
  # * Extra Stat Modifier
  #--------------------------------------------------------------------------
  def xstat_modifier(stat)
    @note =~ /<STATE_XSTAT: #{stat} (\d+)([%%])>/i ? $1.to_i * 0.01 : 1.00
  end
end
#==============================================================================
# ** RPG::UsableItem
#------------------------------------------------------------------------------
#  The Superclass of Skill and Item.
#==============================================================================

class RPG::UsableItem < RPG::BaseItem
  #--------------------------------------------------------------------------
  # * Extra Stat Growth
  #--------------------------------------------------------------------------
  def xstat_growth(stat)
    @note =~ /<XSTAT GROWTH: #{stat} (\d+)>/i ? $1.to_i : 0
  end
end
#==============================================================================
# ** RPG::EquipItem
#------------------------------------------------------------------------------
#  A superclass of weapons and armor.
#==============================================================================

class RPG::EquipItem < RPG::BaseItem
  #--------------------------------------------------------------------------
  # * Extra Stat Change
  #--------------------------------------------------------------------------
  def xstat_change(stat)
    @note =~ /<WEAPON_XSTAT: #{stat} ([\+\-]\d+)>/i ? $1.to_i : 0
  end
end
#==============================================================================
# ** Xstats
#------------------------------------------------------------------------------
#  This class handles the player's extra stats.
#==============================================================================

class Xstats
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(battler)
    @battler = battler
  end
  #--------------------------------------------------------------------------
  # * Define the Stats
  #--------------------------------------------------------------------------
  CRYSTAL::XSTAT::STATS.each do |sym|
    define_method(:"#{sym}") do
      @battler.eval_stat(sym)
    end
  end
end
#==============================================================================
# ** Game_BattlerBase
#------------------------------------------------------------------------------
#  This base class handles battlers. It mainly contains methods for calculating
# parameters. It is used as a super class of the Game_Battler class.
#==============================================================================

class Game_BattlerBase
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :xstat_plus               # Additions to the xstats
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  alias init_ce_extra_stats initialize
  def initialize
    init_ce_extra_stats
    @xstat_plus = {}
    CRYSTAL::XSTAT::STATS.each do |stat|
      @xstat_plus[stat] = 0
    end
  end
  #--------------------------------------------------------------------------
  # * Extra Stats Object
  #--------------------------------------------------------------------------
  def xstat
    Xstats.new(self)
  end
  #--------------------------------------------------------------------------
  # * Extra Stats Object
  #--------------------------------------------------------------------------
  def eval_stat(sym)
    if actor?
      if actor.xstat_formula(sym) == CRYSTAL::XSTAT::DEFAULT_LEVEL_FORMULA[sym]
        stat = eval(self.class.xstat_formula(sym))
      else
        stat = eval(actor.xstat_formula(sym))
      end
      equips.compact.each do |equip|
        stat += equip.xstat_change(sym)
      end
      stat += @xstat_plus[sym]
      equips.compact.each do |equip|
        stat *= equip.xstat_modifier(sym)
      end
      stat *= actor.xstat_modifier(sym)
      stat *= self.class.xstat_modifier(sym)
    elsif enemy?
      if $imported["CE-EnemyClasses"]
        if enemy.xstat_formula(sym) == CRYSTAL::XSTAT::DEFAULT_FOR_ENEMIES[sym]
          stat = eval(self.class.xstat_formula(sym))
        end
      end
      stat ||= eval(enemy.xstat_formula(sym))
      if $imported["CE-EnemyEquips"]
        equips.compact.each do |equip|
          stat += equip.xstat_change(sym)
        end
        stat += @xstat_plus[sym]
        equips.compact.each do |equip|
          stat *= equip.xstat_modifier(sym)
        end
      end
      stat *= enemy.xstat_modifier(sym)
      stat *= self.class.xstat_modifier(sym) if $imported["CE-EnemyClasses"]
    end
    states.each do |state|
      stat *= state.xstat_modifier(sym)
    end
    return [[CRYSTAL::XSTAT::STAT_MIN[sym], stat.round].max, CRYSTAL::XSTAT::STAT_MAX[sym]].min
  end
end
#==============================================================================
# ** Game_Battler
#------------------------------------------------------------------------------
#  A battler class with methods for sprites and actions added. This class
# is used as a super class of the Game_Actor class and Game_Enemy class.
#==============================================================================

class Game_Battler < Game_BattlerBase
  #--------------------------------------------------------------------------
  # * Apply Effect of Skill/Item
  #--------------------------------------------------------------------------
  alias item_apply_ce_extra_stats item_apply
  def item_apply(user, item)
    item_apply_ce_extra_stats(user, item)
    if @result.hit?
      CRYSTAL::XSTAT::STATS.each do |stat|
        @xstat_plus[stat] += item.xstat_growth(stat)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Test Skill/Item Application
  #    Used to determine, for example, if a character is already fully healed
  #   and so cannot recover anymore.
  #--------------------------------------------------------------------------
  alias item_test_ce_extra_stats item_test
  def item_test(user, item)
    CRYSTAL::XSTAT::STATS.each do |stat|
      max = CRYSTAL::XSTAT::STAT_MAX[stat]
      return true if item.xstat_growth(stat) > 0 && eval_stat(stat) < max
    end
    return item_test_ce_extra_stats(user, item)
  end
end
#==============================================================================
# ** Game_Interpreter
#------------------------------------------------------------------------------
#  An interpreter for executing event commands. This class is used within the
# Game_Map, Game_Troop, and Game_Event classes.
#==============================================================================

class Game_Interpreter
  #--------------------------------------------------------------------------
  # * Modify an Extra Stat
  #--------------------------------------------------------------------------
  def change_xstat(id, stat, value)
    $game_actors[id].xstat_plus[stat] += value
  end
end
#==============================================================================
# ** Window_Base
#------------------------------------------------------------------------------
#  This is a super class of all windows within the game.
#==============================================================================

class Window_Base < Window
  #--------------------------------------------------------------------------
  # * Draw Parameters
  #--------------------------------------------------------------------------
  def draw_actor_xstat(actor, x, y, stat)
    change_color(system_color)
    draw_text(x, y, 120, line_height, CRYSTAL::XSTAT::TERMS[stat])
    change_color(normal_color)
    draw_text(x + 120, y, 36, line_height, eval("actor.xstat.#{stat}"), 2)
  end
end
#==============================================================================
# ** Window_Status
#------------------------------------------------------------------------------
#  This window displays full status specs on the status screen.
#==============================================================================

class Window_Status < Window_Selectable
  #--------------------------------------------------------------------------
  # * Draw Block 3
  #--------------------------------------------------------------------------
  def draw_block3(y)
    draw_parameters(0, y)
    draw_equipments(344, y)
    draw_xstat_parameters(172, y)
  end
  #--------------------------------------------------------------------------
  # * Draw Extra Stats
  #--------------------------------------------------------------------------
  def draw_xstat_parameters(x, y)
    dy = 0
    CRYSTAL::XSTAT::STATS.each do |stat|
      draw_actor_xstat(@actor, x, y + dy, stat)
      dy += line_height
    end
  end
end
#==============================================================================
#
# ▼ End of File
#
#==============================================================================
 

Roninator2

Gamer
Veteran
Joined
May 22, 2016
Messages
3,510
Reaction score
847
First Language
English
Primarily Uses
RMVXA
Are you referring to <xstat growth: stat x>?
because there are two note tags for stats. Add and percent.
<weapon_xstat: stat +x> # Sets the specified stat to be modified by x
<state_xstat: stat x%> # Sets the specified stat to be multiplied by x%
My bad, I thought I read that as two tags for weapons.

or perhaps <state_xstat: stat x%>?

Where are you using the note tag?
 
Last edited:

Szibes

Veteran
Veteran
Joined
Mar 5, 2021
Messages
30
Reaction score
5
First Language
Polish
Primarily Uses
RMVXA
<state_xstat: stat x%>
Which goes in to state notes.
<weapon_xstat: stat +x> works only for weapons and armor.
<xstat growth: stat x> is permament increase.
 

Roninator2

Gamer
Veteran
Joined
May 22, 2016
Messages
3,510
Reaction score
847
First Language
English
Primarily Uses
RMVXA
Try this *untested
Ruby:
class RPG::BaseItem
  #--------------------------------------------------------------------------
  # * Extra Stat Growth
  #--------------------------------------------------------------------------
  def xstat_add(stat)
    @note =~ /<XSTAT ADD: #{stat} (\d+)>/i ? $1.to_i : 0
  end
end
class Game_BattlerBase
  #--------------------------------------------------------------------------
  # * Extra Stats Object
  #--------------------------------------------------------------------------
  def eval_stat(sym)
    if actor?
      if actor.xstat_formula(sym) == CRYSTAL::XSTAT::DEFAULT_LEVEL_FORMULA[sym]
        stat = eval(self.class.xstat_formula(sym))
      else
        stat = eval(actor.xstat_formula(sym))
      end
      equips.compact.each do |equip|
        stat += equip.xstat_change(sym)
      end
      stat += @xstat_plus[sym]
      equips.compact.each do |equip|
        stat *= equip.xstat_modifier(sym)
      end
      stat *= actor.xstat_modifier(sym)
      stat *= self.class.xstat_modifier(sym)
    elsif enemy?
      if $imported["CE-EnemyClasses"]
        if enemy.xstat_formula(sym) == CRYSTAL::XSTAT::DEFAULT_FOR_ENEMIES[sym]
          stat = eval(self.class.xstat_formula(sym))
        end
      end
      stat ||= eval(enemy.xstat_formula(sym))
      if $imported["CE-EnemyEquips"]
        equips.compact.each do |equip|
          stat += equip.xstat_change(sym)
        end
        stat += @xstat_plus[sym]
        equips.compact.each do |equip|
          stat *= equip.xstat_modifier(sym)
        end
      end
      stat *= enemy.xstat_modifier(sym)
      stat *= self.class.xstat_modifier(sym) if $imported["CE-EnemyClasses"]
    end
    states.each do |state|
      stat *= state.xstat_modifier(sym)
      stat += state.xstat_add(sym)
    end
    return [[CRYSTAL::XSTAT::STAT_MIN[sym], stat.round].max, CRYSTAL::XSTAT::STAT_MAX[sym]].min
  end
end
 

Szibes

Veteran
Veteran
Joined
Mar 5, 2021
Messages
30
Reaction score
5
First Language
Polish
Primarily Uses
RMVXA
Sorry for not responding immediately, I forgot about it. Sorry.
Tested it and it works. It can only add values, but I wasn't looking for a way to lower these stats, so I have no problem with this.
Thank you so much!
 

Latest Profile Posts

Been playing through Skies of Arcadia again, and it really makes me wanna see someone try to implement how ship battles were done in the game into RPG Maker (or really just in general).
split.png
split view of both versions of the pocket city you traverse through. there's differences like areas only being accessible in one version of Autumn Bay. or events that only happen in one or the other.
theortically if there were a developer who spied on people's game playthroughs and changed things in real time to make it harder for them, what might be said game developer's motivation?
Hi everyone! Enjoying this nice long weekend. How are you all doing? :)
I just successfully tested having events check if specific actors are in a particular party slot and then changing image to match. This will let me make scenes take into account who is in the party at the time and arrange them accordingly - this is important since I'll have extra actors beyond current party. The script used is the same from MV and is compatible with my current core plugin setup in MZ. Thank goodness.

Forum statistics

Threads
118,433
Messages
1,115,916
Members
155,391
Latest member
dndrself
Top