Unlimited Battle Event Page Conditions for XP - Community Dev Project

Started by Heretic86, January 20, 2014, 10:36:35 pm

Previous topic - Next topic

Heretic86

This thread is not intended for a Script Publication.  Its intended for Development.

Another thread (to be linked) will be offered for Script Publication and support of the Script.

---

I thought this would be a fun idea for the community.  The script, even in its current form, is intended to allow for for Additional Conditions for Battle Event Pages to run.  The thing is, it ALL works with Scripts, so it wont be that easy for Non Scripters to use. 

This is where you come into play.

The current Battle Conditions only allow for a limited number of things to be checked.  But to do addional checks, it will be useful for Non Scripters to make simplified calls.  For example: item_in_inventory?(item_id) as a Condition.  I want to expand this to allow for easy way to do lots of easy to call checks.  all_enemies_dead?  enemy_has_state?(state_id) Things like that.  Sky is the limit.

I also tried to make this fairly easy for newer Scripters to read and understand whats going on here, so Im trying to stick with the Default Code Style and provide good documentation.  Im sure we can condense the code to be very very very short, but that comes at the expense of being understood by newer Scripters, especially when there is little to no comments for whats going on in the code.

I havent seen too many scripts that make any changes to "setup_battle_event" at all.  There will probably be a few that do, and in its original form this replaces "setup_battle_event" to allow for the extra Conditions, so this may cause some compatability issues with those scripts. Compatability is part of getting this script going.  High compatability and functionality.

So go ahead and mess with, add stuff, change stuff around as you see fit.  It shouldnt be a very big project.  You can add in a couple things here and there if you'd like if thats all you feel like doing.  Im trying this as a Community Project just to see how well we work together.

So heres the Original Script:
Spoiler: ShowHide
#=============================================================================
#
#           Unlimited Battle Page Conditions
#           Authors: Heretic
#           Version 1.0
#           Monday, January 20th, 2014
#
#-----------------------------------------------------------------------------
#
#  ---   OVERVIEW   ---
#
#  This script will allow you to add an Unlimited Number of Page Conditions
#  for Battle Events by using Comments as a Condition on each Battle Page
#
#  ---   IMPORTANT!   ---
#
#  The Conditions that you put in to the Comment MUST be able to evaluate
#  to true / false!
#
#  What this means is that a Condition of var = 1 will run, but not evaluate
#  to true, so it wont ever be recognized as a valid condition.  By placing
#  a Condition of "if var == 1" will return true, which makes it valid when
#  the proper conditions are met.
#
#  ---   USAGE   ---
#
#  Create a Condition by making a Comment ANYWHERE on a Battle Event Page
#  with "condition:" followed by your Scripted Condition in the Comment.
#
#  Example #1: 
#
#  @>Comment:  condition:  if $foo == $bar
#
#
#  Comment Conditions will run Eval for ALL of the contents for each Comment
#  all at once.  This allows you to have a Multi Line Condition.
#
#  Example #2: 
#
#  @>Comment:  condition:  if ($foo == $bar and
#                             $lorem == $ipsum)
#
#
#  Comments run as Scripts just like a Script Event, so you can put anything
#  into the Script.  Loops, Iterations, Create Variables, Self Switches, etc.
#
#  Example #3   
#
#  @>Comment:  condition:  result = false
#                          for actor in $game_party.actors
#                            if actor.weapon_id == 12
#                              result = true
#                            end
#                          end
#                          return true if result == true
#
#
#  Each Comment Condition you add will add another Condition to check before
#  the Battle Event Page can be run.  This allows you to add as many Conditions
#  as you want.  THERE IS NO LIMIT.  Each Comment Condition is considered as
#  its own Condition.
#
#  Example #4: 
#
#  @>Comment:  condition:  $game_party.actors[0].hp == $game_party.actors[0].maxhp
#  @>Comment:  condition:  $game_party.actors[0].id == 2
#
#  In the above example, BOTH Conditions MUST BE MET for the Battle Event Page
#  to be considered Valid and thus run.
#
#
#  You can use OR Statements inside of a single Comment Condition allowing for
#  greater flexibility of Battle Page Conditions.
#
#  Examle #5:
#
#  @>Comment: condition: if $foo == $bar OR $lorem == $ipsum
#
#
#  ANY Sript Logic can be used provided it fits in the comment.  Its all
#  evaluated the same way.
#
#  ---   BATTLE EVENTING   ---
#
#  Battle Eventing has a Menu for a few things already.  Such as checking to
#  make sure a certain Switch is on before running the Battle Event Page.  You
#  can now use a Comment Condition to check if a certain Switch is OFF before
#  running a Battle Event Page.
#
#  Battle Event also uses what is called SPAN.
#
#  SPAN controls when and how many times to run a Battle Event Page.
#
#  Span:   Battle - Page runs ONCE per the entire Battle
#  Turn:   Page runs ONCE per Turn, even if conditions are still met.
#  Moment: Runs when Conditions are met, and continues to run as long as
#          those conditions are met.
#
#  Comment Conditions are EXTREMELY USEFUL for allowing a Span Moment Page
#  to STOP RUNNING.  It allows you to run the Page once.  Like a specific
#  enemy has a State of "Immune to Fire", run some dialogue once, then
#  use some variable to set that the page has run already.  You could use
#  a Switch, or even any other variable like @this_page_ran = true, and set
#  that as a Condition.
#
#  Example #6
#
#  @>Comment:  condition:  if $game_troop.enemies[0].states.include?(12)
#                            @this_new_var_for_page_ran = true
#                          else
#                            unless @this_new_var_for_page_ran
#                              @this_new_var_for_page_ran = false
#                            end
#                          end
#  @>Comment:  condition:  if @this_new_var_for_page_ran != true
#  @>Text:  "Don't cast Fire on him!  He is now Immune to Fire!"
#
#  ---   COMMAND LIST   ---
#
#  I'd like to make this as easy as possible for people to use.  So to do that
#  these list of Commands should make adding Comment Conditions easier.
#
#  Example of Command:
#
#  - item_in_inventory?(item_id)

#  @>Comment  condition: # If Party has a Potion in their Inventory
#                        if item_in_inventory(1)
#
#
#  Command List
#  - item_in_inventory?(item_id)
#
#-----------------------------------------------------------------------------



class Scene_Battle
  #--------------------------------------------------------------------------
  # * Battle Event Setup
  #
  #   - Replacement for default XP Battle System setup_battle_event
  #   - Any Script Conflicts would most likely come from this method
  #--------------------------------------------------------------------------
  def setup_battle_event
    # If battle event is running
    if $game_system.battle_interpreter.running?
      return
    end
    # Search for all battle event pages
    for index in 0...$data_troops[@troop_id].pages.size
      # Get event pages
      page = $data_troops[@troop_id].pages[index]
      # Make event conditions possible for reference with c
      c = page.condition
     
      # New Code for checking extra Conditions in Comments of Battle Page
      page_condition_valid = has_page_condition?(page)
     
      # This code is mostly default with the addition of "page_condition_valid"
     
      # Go to next page if no conditions are appointed
      unless c.turn_valid or c.enemy_valid or
             c.actor_valid or c.switch_valid or
             page_condition_valid
        next
      end
     
      # Default code
     
      # Go to next page if action has been completed
      if $game_temp.battle_event_flags[index]
        next
      end
      # Confirm turn conditions
      if c.turn_valid
        n = $game_temp.battle_turn
        a = c.turn_a
        b = c.turn_b
        if (b == 0 and n != a) or
           (b > 0 and (n < 1 or n < a or n % b != a % b))
          next
        end
      end
      # Confirm enemy conditions
      if c.enemy_valid
        enemy = $game_troop.enemies[c.enemy_index]
        if enemy == nil or enemy.hp * 100.0 / enemy.maxhp > c.enemy_hp
          next
        end
      end
      # Confirm actor conditions
      if c.actor_valid
        actor = $game_actors[c.actor_id]
        if actor == nil or actor.hp * 100.0 / actor.maxhp > c.actor_hp
          next
        end
      end
      # Confirm switch conditions
      if c.switch_valid
        if $game_switches[c.switch_id] == false
          next
        end
      end
     
      # This small block is also all that was added to the Default code
     
      # Confirm Page Condition (if Additional Page Condition exists)
      if page_condition_valid
        # If running the extra Page Condition returns false (which is default)
        if eval_page_conditions(page) == false
          # Go to next Battle Event Page if one exists and skip processing this
          next
        end
      end
     
      # The rest of the code in this method is Default
     
      # Set up event
      $game_system.battle_interpreter.setup(page.list, 0)
      # If this page span is [battle] or [turn]
      if page.span <= 1
        # Set action completed flag
        $game_temp.battle_event_flags[index] = true
      end
      return
    end
  end
  #--------------------------------------------------------------------------
  # * Has Page Condition (Comment Conditions  I.E. "condition: (var1 == var2)
  #   page : Battle Event Page
  #
  #   This checks for the existence of any Page Conditions.  It returns
  #   true if it finds at least one condition, then stops.  If any conditions
  #   are in Comments, then it uses another method to check for ALL of the
  #   conditions on the page passed in via the argument.
  #
  #   This is NEW CODE and should not cause any Script Conflicts.
  #--------------------------------------------------------------------------
  def has_page_condition?(page)
    # For each Battle Event Command on this Battle Page
    for command in page.list
      # If Command is First Line of a Comment
      if command.code == 108
        # Check each Commment if it has "condition:" as String
        command.parameters[0].gsub(/^condition:(.*)/i){$1}
        # found a Battle Condition in a Comment
        return true if $1 != nil
      end
    end
    # Default - No Valid Battle Page Conditions in Comment Commands found
    return false
  end
  #--------------------------------------------------------------------------
  # * Eval Page Conditions
  #   - Finds ALL Page Conditions in Comments, then Evaluates them
  #
  #   NOTE: Conditions MUST be able to return a Value
  #         $foo = "Bar" will not return anything, thus evals to False
  #         if $foo == "Bar" will return either True or False
  #
  #   This code will check to enusre ALL of the Comment Conditions on a
  #   Battle Event Page are met.  If you have Two Conditions, both must
  #   eval to True for an Event Page to be considered "valid".  Each Comment
  #   Condition is considered as a Separate Condition.  Everything in the
  #   Comment Box is evaluated all at once, so you can create temporary
  #   variables, Loops, OR statements, etc as long as it is all contained
  #   in ONE Comment.  IE "if $foo == $bar OR actor_id == 2".  Complex
  #   scripts may adversely affect performance.
  #
  #   This is NEW CODE and should not cause any Script Conflicts.
  #
  #--------------------------------------------------------------------------
  def eval_page_conditions(page)
    # For each Battle Event Command on this Battle Page
    for i in 0...page.list.size
      # Get Command
      command = page.list[i]
      # If Command is First Line of a Comment
      if command.code == 108
        # Check each Commment if it has "condition:" as String
        command.parameters[0].gsub(/^condition:(.*)/i){$1}
        # If Battle Condition in a Comment
        if $1 != nil
          # Remember the Condition
          condition = $1
          # Check for more lines in the Comment to Eval all at once
          while (page.list[i + 1] and page.list[i + 1].code == 408)
            # Advance Counter
            i += 1
            # Add Next Line of Comment (code 408) to Condition to eval
            condition += "\n" + page.list[i].parameters[0]
          end
          # Evaluate Page Conditions for EACH Comment
          if eval(condition)
            # Remains True as long as ALL Comment Conditions are met
            passed = true
          else
            # If Any Conditions in Comments Eval to False then Page is False
            return false
          end
        end
      end
    end
    # If All Comment Conditions on this Page are met, this variable will exist
    return true if passed
    # Default
    return false
  end

 
  #--------------------------------------------------------------------------#
  # **  Custom Commands for Easy Checks for Conditional Switches             #
  #                                                                          #
  #             ALL METHODS MUST RETURN TRUE OR FALSE                        #
  #--------------------------------------------------------------------------#

  #--------------------------------------------------------------------------
  # * Item In Inventory
  #     item_id : Item Id from Database
  #
  #   Example: 1 is a Potion
  #            # If Party has a Potion in the Inventory
  #            item_in_inventory?(1)
  #
  #            2 is a High Potion
  #            # If Party has a High Potion in the Inventory
  #            item_in_inventory?(2)
  #
  #  This is an Example Script.  It could be accomplished by copying and
  #  pasting the one "return true if ..." line of code.  I provided this
  #  because it makes it easy for us to script easier condition checks
  #  for others that may use this script.
  #--------------------------------------------------------------------------
  def item_in_inventory?(item_id)
    # If Item is in Inventry, return True
    return true if $game_party.item_number(item_id) > 0
    # Default
    return false
  end
end


What ever you think should be changed, lets change it.  Maybe a VX / Ace version?  Maybe better documentation?  Maybe compatability issue fixes?  What do you think you could add to make this experiment better?

(I'll update this post with contributed changes.)
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

LiTTleDRAgo

instead rewriting it, why don't you use reject! instead?

*code deleted*


note: code is not tested


edit : nevermind, I was reading your post half asleep, haven't found any solution without overwriting the method

Heretic86

I prefer not to overwrite methods, but I'll do it if there is no alternative, and in such a way that it doesnt affect compatability.

Quick question for people: do you know of any scripts (excluding this one) that either Alias or Redefine "def setup_battle_event"?

Is anyone interested in this, either as just a Script, or as a Community Project?
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)