Jump to content
New account registrations are disabed. This website is now an archive. Read more here.
  • 0
Heretic86

XP Script - Heretic's Idiot Ruby / RGSS Questions...

Question

Am I getting annoying yet?

 

Okay, trying to create a new def that updates itself. Mostly for debug purposes, displaying variable values in a Sprite on the screen so I can watch them realtime. I got the graphics working so dont need to mess with that, just need to know how to run a continual update without hitting Stack Level Too Deep. It appears that an update cant self reference.

 

What is the best way to create a new anything that can self update?

 

(edit: Changed thread title to be more accurate)

Edited by Heretic86

Share this post


Link to post
Share on other sites

Recommended Posts

  • 0
I want to check X and Y positions in an array

@move_list = [ [1,2], [1,3], [2,3], [2,4] ]

 

I dont think I can just do "if @move_list.include? [X,Y]

Well then you should've tried because you actually can. Don't forget brackets around [X,Y] though.

@move_list.include?([X,Y])

Share this post


Link to post
Share on other sites
  • 0

Well then you should've tried because you actually can. Don't forget brackets around [X,Y] though.

@move_list.include?([X,Y])

 

Got it. @move_list[0].to_a[3].to_a.include(X,Y) or something like that

 

Stoopid multidimensional arrays, grr!

 

---

 

Ok, next one.

 

GSUB! (Not the Destructive one) just good old fashion @event.gsub.name(wtf?)

 

@event.name.gsub(/\\cat_actor\[([0-9]+)\]/i) {@caterpillar_actor = $1 }

 

Could someone explain what the hell the rest of that stuff in the argument is, as well as the {@var = $huh}

Share this post


Link to post
Share on other sites
  • 0
Got it. @move_list[0].to_a[3].to_a.include(X,Y) or something like that

Errrrrrr... no. Dunno what you're trying to achieve with such a command but I hardly doubt it will accomplish anything.

 

/\\cat_actor\[([0-9]+)\]/i

This is a Regexp (regular expression). I suggest you see some official Ruby documentation to fully understand its syntax, however what this one exactly means is: any expression featuring "\", then "cat_actor", then "[", then a number with any amount of digits (character between 0 and 9 with the symbol +), then "]". So what gsub does with this one is look whether the given string fits that description or not. For example "\cat_actor[01]" is a suitable candidate.

As to the $1, it gets a little more tricky. You can see in the Regexp that the number is surrounded by brackets. This means that if the string fits the Regexp, gsub will capture the value between brackets (for instance the number), and put it into $1. This vaue is then assigned to the variable @caterpillar_actor. So, in short, this line is checking a String (wherever it might come from) against a pattern, and if the pattern is matched, it captures the number that was specified in said String for further use.

Share this post


Link to post
Share on other sites
  • 0

Blah, ran into a nasty bug.

 

How to I determine where (hoping x, y coordinates) an event is trying to move to WITHOUT using @direction? @direction is not always 100% guaranteed to be where an Event is expected to step, such as Direction Fix, or "1 Step Backwards"?

 

Nevermind. I was misinterpreting the original script. I thought d was Direction of the Sprite (which isnt always guaranteed), it does seem to work right after all, after a little tweaking...

 

---

 

None the less every answer leads to a new question. I came across another command I looked up and tried to use with arrays, just for printing em out, but after reading the Ruby information on it, I am still confused.

 

LIST. I came across @move_route.list[@move_route_index] and it works for that, but not what I was trying to make it do... Can someone kindly explain .LIST a little better??

Edited by Heretic86

Share this post


Link to post
Share on other sites
  • 0

How do I call Spriteset_Map defs Globally?

 

I tried $spriteset_map.new_def but it comes back undefined...

 

I get the whole idea behind Globals and Scope, still not 100% on how to refer to those classes globally...

Share this post


Link to post
Share on other sites
  • 0
I get the whole idea behind Globals and Scope, still not 100% on how to refer to those classes globally...

That's the point, Spriteset_Map objects are never referenced by global variables in RMXP's standard scripts, they are created by Scene_Map. So what you need to do is set :spriteset_map as an attr_reader in the Scene_Map class, and call:

$game_map.spriteset_map

Share this post


Link to post
Share on other sites
  • 0

You're not understanding the differences between instance and static objects. In RMXP, all the global variables are INSTANCES of the the classes, meaning you can create 100 of them if you wish and they are all different objects.

 

actor1 = Game_Actor.new(1)
actor2 = Game_Actor.new(2)
actor3 = Game_Actor.new(3)

 

Each one of them is a Game_Actor, yet they are all different, and are referenced by different objects.

 

An example of a static object in RMXP would be the Graphics module and its methods. As you can see you do not need to create an instance of it (actually you can't) to reference its methods.

 

Graphics.update
my_number = Graphics.frame_count

 

You can mix instance methods and static methods in the same classes, but it is important to remember that a static member of a class has nothing to do with any instance member of the same class. As far as the static method is concerned, all the instance variables are undefined.

 

Use the "self" keyword (or the name of the class) before a method name to make it static:

 

class Game_Map

 def self.print_something(something)
   p something
 end

 def Game_Map.say_hello
   p 'Hello!'
 end
end

Game_Map.say_something('Some unimportant text')
Game_Map.say_hello

 

The following will not work though, because the static method is unaware of the class's instances:

 

class MyClass

 def initailize
   @instance_var = 4
 end

 def self.print_var
   p @instance_var  #  <---- DOES NOT WORK
 end
end

Share this post


Link to post
Share on other sites
  • 0

So would something like this work?

 


 def is_a_foo?(arg)
   return if arg == "foo"
 end

 def make_instances
   for i in 0..instance_attributes.size
  instance_1 = "foo"
  instance_2 = "bar"
   end
 end

 def do_stuff_with_instances(instance_arg)
   if self.is_a_foo(instance_arg)
  do something to foo
   else
  do something else with bar
   end
 end

 

Am I understanding this correctly?

 

Was trying to do something I thought would be really simple. Write a script, all by myself, that would allow events to fade like we can fade the screen, or fog, or other fade-able things. Started digging, trying to think of what to reference, then reading thru Game_Events, being a sub class (due to Super?) of Game_Character (which I thought would work), then started looking at Game_Events, and forgot that Events can have PAGES, and each @page gets totally different properties, so each page is instanced. That is, if I understand it correctly. Instancing being two sprites are on screen. One is a guy, one is a girl, so trying to access a property or method of bra_size for the guy character will result in nil. Ok, bad example...

 

Ugh! I wanted to take a crack at something simpler! Maybe somebody has a suggestion of something to try (even if it has already been done) that is appropriate for my inadequate skill level?

 

I really appreciate you guys helping me out! I feel like a troll, trying to read tutorials that dont fully click, not fully familiar with the language syntax (regexp == nightmare!), and Im trying to contribute things to help everyone (scripts, graphics, questions, etc). Even what I feel is a ton of stupid questions I think others that are trying to learn may be asking similar questions.

 

So, seriously, thank you guys for your patience!

Share this post


Link to post
Share on other sites
  • 0

Hey Hey! Guess what? I got that Event Fade script working! Now I can make events fade in and out like you can Fog! Tell me people wouldnt want to use that! I'll post it here before anywhere else to let you guys read through it, hopefully test it out and tell me if I wrote it correctly, or if there was anything I did that I should have done differently.

 

 

# Heretic's Object Fade v1.0
#
# Super simple to use.  Put above Main somewhere. 
# Pretty much anywhere between Scene_Debug and Main should be fine
# In the Editor, in Edit Events, go to Set Move Route, and hit Script
# in that window, enter "fade_event(255, 20)" without the quotes
# and adjust 255 for Not Transparent to 0 for Fully Invisible
# the second number is the number of Frames for the Transition
# Set as module to make function available to several classes
# Player is NOT the same as Event
module Fade
 #--------------------------------------------------------------------------
 # * Fade Event - (Opacity 0 to 255, Duration in Frames)
 #--------------------------------------------------------------------------

 def fade_event(arg_opacity_target, arg_opacity_duration)
   if $DEBUG
  if arg_opacity_target.nil? or arg_opacity_duration.nil?
    print "fade_event(opacity, duration) expects Two Arguments\n"
    return
  elsif not arg_opacity_target.is_a? Numeric
    print "\"", arg_opacity_target, "\" is not an Number!\n",
		  "Both Arguments should be Numbers!\n\n",
		  "I.E. fade_event(255,20)"
    return
  elsif not arg_opacity_duration.is_a? Numeric
    print "\"", arg_opacity_duration, "\" is not an Number!\n",
		  "Both Arguments should be Numbers!\n\n",
		  "I.E. fade_event(255,20)"
    return
  elsif arg_opacity_target < 0 or arg_opacity_target > 255
    print "\"", arg_opacity_target, "\" Opacity Out of Range\n",
		  "Valid Range: 0 - 255"
  elsif arg_opacity_duration < 0
    print "\"", arg_opacity_target, "\" Duration Out of Range\n",
		  "Valid Range: Any Positive Number or 0"
  end
   end

   self.opacity_target = arg_opacity_target * 1.0
   self.opacity_duration = arg_opacity_duration
   if self.opacity_duration == 0
  self.opacity = self.opacity_target.clone
   end
 end
#-----------------------------------------------------------------------------
#  * Change Event Opacity
#-----------------------------------------------------------------------------

 def change_event_opacity
   # Manage change in Event Opacity Level
   if @opacity_duration >= 1
  d = @opacity_duration
  @opacity = (@opacity * (d - 1) + @opacity_target) / d
  @opacity_duration -= 1
   end
 end

end
class Game_Event < Game_Character
 # Make the functions inside the Module available to both Events and Characters
 include Fade
end
#==============================================================================
# ** Game_Character
#------------------------------------------------------------------------------
class Game_Character

 attr_accessor	 :opacity_target
 attr_accessor	 :opacity_duration

 unless self.method_defined?('fade_events_initialize')
   alias fade_events_initialize initialize
 end

 def initialize
   # Initilaize Original First
   fade_events_initialize
   # Added Properties
   @opacity_target = 255
   @opacity_duration = 0
 end
 # IF the method hasn't been defined yet
 unless self.method_defined?('fade_events_update')
   alias fade_events_update update
 end

 # Redefine Updater
 def update
   # Run Original First
   fade_events_update
   if @opacity_duration >= 1
  # Manages the Events Current Opacity
  change_event_opacity
   end
 end
 # Make the functions inside the Module available to both Events and Players
 include Fade
end


 

Share this post


Link to post
Share on other sites
  • 0

OMFG I disappear for a while and miss all the good ruby discussions Q_Q

 

It is probably wiser not to use symbol syntax, more to avoid creating a bad habit than being wrong. Ruby symbols are basically the name of an object, whether it be a method, instance variable, string, or constant. The context of what these objects actually are is ignored, so if you had a a method labeled :mySymbol and a class named :mySymbol, they will both have the same object ID, which COULD lead to possible problems in extremely rare cases.

 

For example:

 

class SymbolTest
 SymbolTest = 4
end

def SymbolTest
end

 

All three of these objects have the same object_id, even though one is a class, another is a method, and the other is a constant in a class with the same name.

 

Hmmm, I always thought classes were supposed to be Constants (first letter uppercase) and methods were instances (first letter lowercase)

 

Also, class SymbolTest != SymbolTest::SymbolTest -> they may share the same symbol; but both have very different scope and thus different object_ids

 

As for class SymbolTest/def SymbolTest -- can anyone really expect declaring a method and class in the same scope with the EXACT same name (as a constant) do to what they want? I really don't think using symbols in these kinds of cases is a bad habit at all.

 

If one is really that paranoid, all you need is a little bit of paranoid programming:

class Whatever
 def initialize
 end

 alias_method :new_initialize :initialize
end

 

now ruby knows you are specifically referring to a method, and not anything else... but as I said, you shouldn't have 2 (different) objects in the same scope with the same name (I know you know that a class/method definition are simply instances of the class and method object) -- THAT is bad practice, and as long as you don't do that, an alias can only reference what's available in the scope (unless you fully qualify the object)

 

i.e.

module RPG
 class Sprite < ::Sprite # `::` preceding `Sprite` references global scope, outside of RPG
 end
end

 

c:\test>more test.rb
class SymbolTest
	SymbolTest = 4
end

def SymbolTest
	puts "hello, World!"
end

puts "SymbolTest::SymbolTest -> #{SymbolTest::SymbolTest.object_id}"
puts "SymbolTest -> #{SymbolTest.object_id}"
puts SymbolTest

c:\test>ruby test.rb
SymbolTest::SymbolTest -> 9
SymbolTest -> 22251492
SymbolTest

 

declaring a method with the same name as the class (in the same scope) really screws with things...where's my "Hello, World!"?

What's interesting though, is just found out now, if you were to declare a method with the same name as a class in the same scope, but have it take parameters, you can reference both uniquely...but, that's still not the best idea IMO.

 

Well then you should've tried because you actually can. Don't forget brackets around [X,Y] though.

@move_list.include?([X,Y])

 

Brackets are optional in ruby, so

@move_list.include? [X,Y]

would actually work. Not a big deal, but usually the ruby community uses brackets for multiple parameters

Something.do_something(1, 2, 3)

and no brackets for single parameter

method_defined? :do_something

 

But that's all personal preference anyways.

 

Hey Hey! Guess what? I got that Event Fade script working! Now I can make events fade in and out like you can Fog! Tell me people wouldnt want to use that! I'll post it here before anywhere else to let you guys read through it, hopefully test it out and tell me if I wrote it correctly, or if there was anything I did that I should have done differently.

 

 

# Heretic's Object Fade v1.0
#
# Super simple to use.  Put above Main somewhere.
# Pretty much anywhere between Scene_Debug and Main should be fine
# In the Editor, in Edit Events, go to Set Move Route, and hit Script
# in that window, enter "fade_event(255, 20)" without the quotes
# and adjust 255 for Not Transparent to 0 for Fully Invisible
# the second number is the number of Frames for the Transition
# Set as module to make function available to several classes
# Player is NOT the same as Event
module Fade
 #--------------------------------------------------------------------------
 # * Fade Event - (Opacity 0 to 255, Duration in Frames)
 #--------------------------------------------------------------------------

 def fade_event(arg_opacity_target, arg_opacity_duration)
if $DEBUG
  if arg_opacity_target.nil? or arg_opacity_duration.nil?
	print "fade_event(opacity, duration) expects Two Arguments\n"
	return
  elsif not arg_opacity_target.is_a? Numeric
	print "\"", arg_opacity_target, "\" is not an Number!\n",
		  "Both Arguments should be Numbers!\n\n",
		  "I.E. fade_event(255,20)"
	return
  elsif not arg_opacity_duration.is_a? Numeric
	print "\"", arg_opacity_duration, "\" is not an Number!\n",
		  "Both Arguments should be Numbers!\n\n",
		  "I.E. fade_event(255,20)"
	return
  elsif arg_opacity_target < 0 or arg_opacity_target > 255
	print "\"", arg_opacity_target, "\" Opacity Out of Range\n",
		  "Valid Range: 0 - 255"
  elsif arg_opacity_duration < 0
	print "\"", arg_opacity_target, "\" Duration Out of Range\n",
		  "Valid Range: Any Positive Number or 0"
  end
end

self.opacity_target = arg_opacity_target * 1.0
self.opacity_duration = arg_opacity_duration
if self.opacity_duration == 0
  self.opacity = self.opacity_target.clone
end
 end
#-----------------------------------------------------------------------------
#  * Change Event Opacity
#-----------------------------------------------------------------------------

 def change_event_opacity
# Manage change in Event Opacity Level
if @opacity_duration >= 1
  d = @opacity_duration
  @opacity = (@opacity * (d - 1) + @opacity_target) / d
  @opacity_duration -= 1
end
 end

end
class Game_Event < Game_Character
 # Make the functions inside the Module available to both Events and Characters
 include Fade
end
#==============================================================================
# ** Game_Character
#------------------------------------------------------------------------------
class Game_Character

 attr_accessor	 :opacity_target
 attr_accessor	 :opacity_duration

 unless self.method_defined?('fade_events_initialize')
alias fade_events_initialize initialize
 end

 def initialize
# Initilaize Original First
fade_events_initialize
# Added Properties
@opacity_target = 255
@opacity_duration = 0
 end
 # IF the method hasn't been defined yet
 unless self.method_defined?('fade_events_update')
alias fade_events_update update
 end

 # Redefine Updater
 def update
# Run Original First
fade_events_update
if @opacity_duration >= 1
  # Manages the Events Current Opacity
  change_event_opacity
end
 end
 # Make the functions inside the Module available to both Events and Players
 include Fade
end


 

 

Looks good at the moment, if it works -- even better.

 

However, just so you know, you shouldn't have to include the Fade module in Game_Event and Game_Character... Game_Event inherits from Game_Character, and thus would inherit the included methods from the Fade module. In fact, since both Game_Player and Game_Event just inherit from Game_Character, you could just define the methods from the Fade module, RIGHT in the Game_Character event. But, that depends on what plans you may have for that module...

 

either way, you should just chop out this part:

class Game_Event < Game_Character
include Fade
end

that's redundant, IMO.

 

Here's an example:


irb(main):001:0> module A
irb(main):002:1> def test
irb(main):003:2> puts "hello, world!"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> class B
irb(main):007:1> end
=> nil
irb(main):008:0> class C < B
irb(main):009:1> end
=> nil
irb(main):010:0> class B
irb(main):011:1> include A
irb(main):012:1> end
=> B
irb(main):013:0> C.new.test
hello, world!
=> nil
irb(main):014:0> B.new.test
hello, world!
=> nil

 

It doesn't matter what order they are defined in either. Only the one include is necessary.

 

EDIT:

 

I dunno if anyone explained @move_route.list, but:

 

@move_route is an instance of the RPG::MoveRoute class

 

module RPG
 class MoveRoute
   def initialize
     @repeat = true
     @skippable = false
     @list = [RPG::MoveCommand.new]
   end
   attr_accessor :repeat
   attr_accessor :skippable
   attr_accessor :list
 end
end

 

and RPG::MoveRoute#list (@move_route.list) is an instance of an array, which elements are (or at least should always be) instances of RPG::MoveCommand

 

module RPG
 class MoveCommand(code = 0, parameters = [])
   def initialize
     @code = code
     @parameters = parameters
   end
   attr_accessor :code
   attr_accessor :parameters
 end
end

 

Both of those code snippets were from the RPG Maker XP help manual, if you want some more details you can check them out.

Share this post


Link to post
Share on other sites
  • 0

Im still struggling to understand apparently. Either that or Hulu has done too much Drain Bamage and Alex Baldwin and Eliza Dushku are going to come slurp out the gooey mess that now occupies my cranial cavity with straws, since, of course, they are aliens and like nothing more than rotten gooey mushy hulu rotted brains.

 

Im trying to add a "Feature" that includes methods defined in a different script entirely and run in Interpreter, and incorporate some of those options into the script I am working on, without touching the other script. I figure a reasonable goal. And I keep running into the same problems. Trying to access a method from that other class, and run into Private Method errors.

 

As was stated earlier, I am failing to understand the instance and static objects apparently.

 

So trying to think of it this way:

 

blue = Color.new(0,0,255) # Instance of Color

 

but...

 

class Foo

def bar

print "bar"

end

end

 

Should always be accessable, right? I mean if literally that was the code, accessing the instance, the instance may or may not exist, and could have very different properties, thus, off limits? but going into class Foo, and actually running that code, that is considered static, right? If not, why not?

 

How is that Corpus Collosum Soup?

Share this post


Link to post
Share on other sites
  • 0

*ahem* *dusts off brain*

 

Let's see if I can help explain this. It seems you are just a little confused with how things work. I'll try not to get into the technical implementation of ruby, as that would probably be much more confusing...

 

But here's what you need to understand:

 

Class

- a blueprint/definition/template (whichever is easiest to understand) of an object

- these are static, i.e. They do not change!

 

Object

- an instance of a class

- these are not static, i.e. They change state!

 

obj_var = ClassName.new

 

What happens (basically)?

1. class ClassName is loaded into memory

2. Memory address of class ClassName is assigned to obj_var

3. Constructor method of ClassName is called (this would be your def initialize, invoked by the .new method)

 

so, obj_var holds the location of an INSTANCE of the class ClassName in memory.

 

You can look at their relationship EXACTLY like that of a house:

To make a house, you need blueprints (well, you should have some AT LEAST); ClassName would be those blueprints. Then, those blueprints can be used to construct the house or even many different houses. obj_var would be the house. The houses can be changed, etc. while the blueprints remain the same.

 

the actual house is an instance of those blueprints.

 

however, when it comes to object oriented programming; we can still DO stuff with the static classes:

class Test
 def instance_method_a
   print "Hello, world!"
 end

 def self.static_method_a
   print "Hello, world!"
 end
end
test = Test.new
test.instance_method_a
# "Hello, world!" is displayed
Text.static_method_a
# "Hello, world!" is displayed
test.static_method_a
# Undefined method error
Test.instance_method_a
# Undefined method error

 

So what's the difference? The difference, is the SCOPE of the method. instance_method_a, has an "instance" scope, meaning it can ONLY be invoked from an INSTANCE (Test.new) of Test. "static_method_a" has class scope, meaning it can ONLY be invoked from the class itself (STATIC).

 

So, in your example:

 

class Foo is static

def bar is an instance-scope method

 

Foo.bar will not work.

Foo.new is static, and returns an instance of Foo

Foo.new.bar would work

or f = Foo.new

f.bar would work

 

Or, this could be another example:

class Foo
 @@static_bar = 5

 def self.static_bar=(value)
   @@static_bar = value
 end

 def self.static_bar
   return @@static_bar
 end

 def initialize
   @instance_bar = 5
 end

 def instance_bar=(value)
   @instance_bar = value
 end

 def instance_bar
   return @instance_bar
 end
end

 

variables with @@ preceding them are class scope variables, therefore they are STATIC.

 

Foo.static_bar

=> 5

Foo.static_bar = 10

Foo.static_bar

=> 10

f = Foo.new

f2 = Foo.new

f.instance_bar = 25

f.instance_bar

=> 25

f2.instance_bar

=> 5

 

static_bar can only be referenced from the class

instance_bar can only be referenced from an instance of the class, and every instance will have it's own instance_bar (and potentially different values for instance_bar).

 

As to what you are trying to do... well, I'm not really sure what it is you are doing, so this might not help; BUT

 

if you need to access methods from within interpreter, you have 2 options: work within interpreter

class Interpreter
 # add some stuff
end

 

and it can still exist in a separate script.

class Test
 def a
   print "a"
 end
end

class Test
 def b
   print "b"
 end
end

 

t = Test.new

t.a

=> "a"

t.b

=> "b"

 

Ruby has open classes, so the interpreter just thinks of Test as one single class.

 

So, if you need the interpreter to do something other than what it does, just make a separate script that adds something to interpreter (I am assuming, by interpreter, you mean class Interpreter in the default classes).

 

However, if you only need access to the interpreter's methods, and don't need to change the functionality; all you need to do is use an instance of Interpreter:

 

interpreter = Interpreter.new
interpreter.some_method

 

or something...

 

Do you mind sharing what it is you want to do?

Share this post


Link to post
Share on other sites
  • 0

Hmm, forums were ofline when I was trying to read your response.

 

Hopefully a quick question. I have a part of a script where I am moving events around without using the Event Editor commands. But I would like those Move Events (in @move_route) to respond to "Wait for Move's Completion". Right now, wait just immediately says it is done. Is it something like event.move_route_forcing or event.move_route_waiting? Just want to know what property or method I need to call...

Share this post


Link to post
Share on other sites
  • 0

To be honest, I just reformatted my PC and haven't put any RPG Maker back on it yet (eventually I will, I totally forgot to back up those installers xD), and I am not familiar with programming against event movements...

 

my guess is one of these might help:

 

module RPG
 class MoveRoute
   def initialize
     @repeat = true
     @skippable = false
     @list = [RPG::MoveCommand.new]
   end
   attr_accessor :repeat
   attr_accessor :skippable
   attr_accessor :list
 end
end

module RPG
 class MoveCommand(code = 0, parameters = [])
   def initialize
     @code = code
     @parameters = parameters
   end
   attr_accessor :code
   attr_accessor :parameters
 end
end

 

More information on these classes are in the help manual (luckily, I could easily find the help manual online)

 

You're gonna have to mess around with some of the default stuff, until you can find some clues (or maybe someone else knows offhand?)

 

.... Hmmm, wait... Is "Wait for move completion" an event command or checkbox somewhere?

 

Hmmm, either way, I'm not the best one to ask about Events. I hate events.

 

You should probably read through the Interpreter class (to learn how normal events handle the "Wait for move completion" the default scripts are well commented IMO), read through the Game_Event, read Sprite_Event. Also, the Help manual has ALL the documentation necessary for the Default data classes. I would look at any RPG::Event* classes in there.

 

Once you learn how the Event's work, inside and out, programming with/against them should be duck soup.

Share this post


Link to post
Share on other sites
  • 0

Wait for move's completion is a bit bugged, or more accurately its a bit misleading.

 

The problem is it is not "Wait for THIS Move's Completion". Zeriab wrote a script that allows you to make scripted "Wait for Completions" where you can specify the ID of the event or player.

 

If I'm not mistaken it was a part of the Interpreter bug fix script he wrote.

Share this post


Link to post
Share on other sites
  • 0

Edit, Ok, got the whole Move Route thing figured out now, I think... Bit of a quirk with "Jumping", seems to crash for me. Undefined method for .abs, but now I cant recreate it! Go figure!

 

Edit #2 Ok got that bug squashed. Was iterating thru an array, and forgot to change [0] to .

Edited by Heretic86

Share this post


Link to post
Share on other sites
  • 0

EDIT: (was originally a double post because post size exceeded limit, due to code originally in the first one, ok I gotta not start commenting on forums now! new_post = true)

 

Nevermind. I got something working! Im proud of myself, even though compared to what you pros can do, its absolutely nothing!

 

That was kind of a pain in the ass. The command codes were not the same as the Interpreter Codes.

 

---

 

Edit 2:

 

Having trouble with this line

 

route_to_player.list.unshift(RPG::MoveCommand.new(29, speed)) if code != 0 and speed != nil

 

Players speed is recorded (1..6) and I cant seem to implement a Speed Change period, other than to super slow. Code executes fine, but characters all walk super slow. Was also thinking it was (speed * 8) or (speed * 32) but no workie jerkie for daddy waddy!

 

and what does this line mean exactly?

 

@actors << event

Edited by Heretic86

Share this post


Link to post
Share on other sites
  • 0

module RPG
 class MoveCommand(code = 0, parameters = [])
def initialize
  @code = code
  @parameters = parameters
end
attr_accessor :code
attr_accessor :parameters
 end
end

 

The second argument is supposed to be an array. So it you want to set speed to 4, your command would be more like:

RPG::MoveCommand.new(29, [4])

 

The "<<" operator is the same as the "push" command for an array.

 

array = [1, 2, 3]
array.push(4)

#  [1, 2, 3, 4]

array << 5

#  [1, 2, 3, 4, 5]

Edited by ForeverZer0

Share this post


Link to post
Share on other sites
  • 0

Kind of off topic from code, but is there a point of rewriting, fixing bugs, and adding additional features to the point where I can call it my own?

Edited by Heretic86

Share this post


Link to post
Share on other sites
  • 0

Kind of off topic from code, but is there a point of rewriting, fixing bugs, and adding additional features to the point where I can call it my own?

As long as you use outside sources, no matter how little code you took from there, you have to credit them. You can call it your own only if you rewrite the whole system from scratch.

Share this post


Link to post
Share on other sites
  • 0

I figured that due credit was a given. Just figuring that since I've done so many modifications to another script, I might be allowed to call it Heretic's Caterpillar instead of Zeriab, who of course would get credit, and if he'd ever show his ugly mug, I'd definitely ask for permission.

 

Ok, back to stupid question time. What the hell is the SDK for, and why so many versions of it?

Share this post


Link to post
Share on other sites
  • 0

Ok, color me stupid, but Im stumped again. /suprise

 

Trying to understand passability bits. Found the source fine. Im trying to work in way of redetermining passability so that the Player can pass thru Cat Actors UNLESS the Cat Actor is standing on a tile (or event tile) that should not be passable using new properties. Cat Actors can pretty much move anywhere, but by doing so, I dont want them to allow the player to exploit them to let

the player go where the Passability Bits say they shouldnt... I dont think I am doing it right...

 

 

  #--------------------------------------------------------------------------
 # * Determine if Passable
 #	 x		  : x-coordinate
 #	 y		  : y-coordinate
 #	 d		  : direction (0,2,4,6,8,10)
 #				  *  0,10 = determine if all directions are impassable
 #	 self_event : Self (If event is determined passable)
 #--------------------------------------------------------------------------
 def passable?(x, y, d, self_event = nil)
   # If coordinates given are outside of the map
   unless valid?(x, y)
  # impassable
  return false
   end
   # Change direction (0,2,4,6,8,10) to obstacle bit (0,1,2,4,8,0)
   bit = (1 << (d / 2 - 1)) & 0x0f
   # Loop in all events
   for event in events.values
  # If tiles other than self are consistent with coordinates
  if event.tile_id >= 0 and event != self_event and
	 event.x == x and event.y == y and not event.through and
	 not (Game_Caterpillar::PASS_SOLID_ACTORS and
	 $game_system.caterpillar.cat_actor_in_party?(event))
    # If obstacle bit is set
    if @passages[event.tile_id] & bit != 0
	  # impassable
	  return false
    # If obstacle bit is set in all directions
    elsif @passages[event.tile_id] & 0x0f == 0x0f
	  # impassable
	  return false
    # If priorities other than that are 0
    elsif @priorities[event.tile_id] == 0
	  # passable
	  return true
    end
  end
   end
   # Loop searches in order from top of layer
   for i in [2, 1, 0]
  # Get tile ID
  tile_id = data[x, y, i]
  # Tile ID acquistion failure
  if tile_id == nil
    # impassable
    return false
  # If obstacle bit is set
  elsif @passages[tile_id] & bit != 0
    # impassable
    return false
  # If obstacle bit is set in all directions
  elsif @passages[tile_id] & 0x0f == 0x0f
    # impassable
    return false
  # If priorities other than that are 0
  elsif @priorities[tile_id] == 0
    # passable
    return true
  end
   end
   # passable
   return true
 end

 

Share this post


Link to post
Share on other sites
  • 0

I am totally stumped!

 

I've been trying to wrap my head around this one bug for two days! Easiest way to describe the bug is to SHOW you.

 

http://www.775.net/~...tnotworking.exe

 

Easier to explain this bug from in game than posting on a forum...

 

Do you think you can help me out?

Edited by Heretic86

Share this post


Link to post
Share on other sites
  • 0

Ok, color me stupid, but Im stumped again. /suprise

 

Trying to understand passability bits. Found the source fine. Im trying to work in way of redetermining passability so that the Player can pass thru Cat Actors UNLESS the Cat Actor is standing on a tile (or event tile) that should not be passable using new properties. Cat Actors can pretty much move anywhere, but by doing so, I dont want them to allow the player to exploit them to let

the player go where the Passability Bits say they shouldnt... I dont think I am doing it right...

 

 

  #--------------------------------------------------------------------------
 # * Determine if Passable
 #	 x		  : x-coordinate
 #	 y		  : y-coordinate
 #	 d		  : direction (0,2,4,6,8,10)
 #				  *  0,10 = determine if all directions are impassable
 #	 self_event : Self (If event is determined passable)
 #--------------------------------------------------------------------------
 def passable?(x, y, d, self_event = nil)
# If coordinates given are outside of the map
unless valid?(x, y)
  # impassable
  return false
end
# Change direction (0,2,4,6,8,10) to obstacle bit (0,1,2,4,8,0)
bit = (1 << (d / 2 - 1)) & 0x0f
# Loop in all events
for event in events.values
  # If tiles other than self are consistent with coordinates
  if event.tile_id >= 0 and event != self_event and
	 event.x == x and event.y == y and not event.through and
	 not (Game_Caterpillar::PASS_SOLID_ACTORS and
	 $game_system.caterpillar.cat_actor_in_party?(event))
	# If obstacle bit is set
	if @passages[event.tile_id] & bit != 0
	  # impassable
	  return false
	# If obstacle bit is set in all directions
	elsif @passages[event.tile_id] & 0x0f == 0x0f
	  # impassable
	  return false
	# If priorities other than that are 0
	elsif @priorities[event.tile_id] == 0
	  # passable
	  return true
	end
  end
end
# Loop searches in order from top of layer
for i in [2, 1, 0]
  # Get tile ID
  tile_id = data[x, y, i]
  # Tile ID acquistion failure
  if tile_id == nil
	# impassable
	return false
  # If obstacle bit is set
  elsif @passages[tile_id] & bit != 0
	# impassable
	return false
  # If obstacle bit is set in all directions
  elsif @passages[tile_id] & 0x0f == 0x0f
	# impassable
	return false
  # If priorities other than that are 0
  elsif @priorities[tile_id] == 0
	# passable
	return true
  end
end
# passable
return true
 end

 

 

This all makes me think that rather than trying to rewrite everything from scratch, you'd better just treat your followers as events, so they would already process passability and stuff like that by themselves.

Share this post


Link to post
Share on other sites
  • 0

This all makes me think that rather than trying to rewrite everything from scratch, you'd better just treat your followers as events, so they would already process passability and stuff like that by themselves.

 

Then other NPC events can just walk thru them which looks "bad" to me. Besides, Im learning something useful!

Share this post


Link to post
Share on other sites
  • 0
Then other NPC events can just walk thru them

 

Of course not! Unless explicitly you set those events to "Through", they're impassable like any other events.

Share this post


Link to post
Share on other sites
  • 0

I must be missing what you are getting at. Normally, the Player cant walk thru the Cat Actors unless the Cat Actors have a Through flag, and NPC Events are dependant on either itself or one or the other event having a Through flag to pass Through, which totally defeats the purpose of the feature I am stuck on.

Share this post


Link to post
Share on other sites
  • 0

Ok, that was a pain in the you know where, but finally got that worked out. The part of the code I pasted earlier wasnt the code I needed to modify, it was in class Game_Character, and appears to only affect the player, so way easier to make my adjustment there. But hey, it was ALL worth it because I was able to learn from my mistakes! Yay!

 

One weird thing, if you put down a Event Tile Bridge over Water, and mark it as Through, the Player can NOT walk over the Bridge any more! Appears to be excluded from passability calculations if event.through flag is on. Just a quirk...

 

I know I need to clean up the code a lot, and improve the commenting, but heres what I got so far...

 

Release Candidate 2 (appears to be "bug free")

 

#==============================================================================
#
#	  HERETIC's CATERPILLAR SCRIPT
#	  V1.90
#	  March 3rd, 2012
#
#  CORE code came from Zeriab, ver 1.0, but this is so heavily modified
#  I have no choice but to call it my own, excluding Zeriab's code of course
#  which I used as a Base.  I dont think Zeriab supports
#  his original Caterpillar Script any more.
#
#  Please let me know of any bugs on [url="http://www.rmxpunlimited.net"]http://www.rmxpunlimited.net[/url]
#
# Zeriab
# 1.0
# 2008-08-16
#------------------------------------------------------------------------------
# This script creates a caterpillar of the party members by using events.
#------------------------------------------------------------------------------
# Paste this script just above main.
#
# Put \cat_actor[3] in the name of an event and it will be considered the event
# for the actor with id 3. The name could for example be "Cyrus\cat_actor[3]"
#
# The switch number specified with CATERPILLAR_ACTIVE_SWITCH (default is 23) is
# used to determine whether the events should be positioned in the caterpillar
# or not. Then the switch is off they are just like any other event.
#
# Heretic V1.85
#
# This script also includes Flat Sprite Fix, Fade Events, and Interpreter Bugfix
#
# New Caterpillar Options:
#
#  - Dead Actors Dont Walk
#  - Pass Solid Actors  (Feature originally concepted by Modern Algebra at RMRK.net
#  - Auto Orient To Player
#  - Developer Error Reporting
# 
# New Caterpillar Functions (Run these from a Script Window)
#
#  - delete_last_move # Erases the very last step a player takes
#  - move_pop		 # Erases a move from the end of the move list
#  - force_walk	   # Forces ALL Cat Actors to have Walk Animations
#  - cat_to_player    # Causes ALL Cat Actors to Walk to the Player's Position
#  - orient_to_player # Orients ALL Cat Actors to the Player's Direction
#
# New Properties
#
#  - \off_map		 # Allows Events to go Off Map (not Off Screen) with Through Enabled
#					 #   -  Name an event "foo\off_map" and set Through
#					 #   -   to ON to allow them to go Off Map
#
#  - $walk_off_map    # True or False - Allows PLAYER and Active Cat Actors OFF MAP
#					 #   -  Could be a switch, but Im lazy
#					 #   -  Use by setting it in a Script
#					 #   -  $walk_off_map = true  OR $walk_off_map = false
#
# New Z-Index Features
#
#  def scren_z was Rewritten to fix numerous bugs and include new options
#
#  - Cat Actors stack so they are on top of Events not flagged as "ALWAYS ON TOP"
#  - Cat Actors Stack Correctly.  IE Player 1 has the highest Z-Index
#	 then Actor 2, Actor 3, and Actor 4
#    This means when all the Party Members are Stacked up, Player 1 is on top
#    followed by each sequential actor
#
#
#  Z-INDEX CONTROLS - Use Event Names or Run Scripts
#
#  (Thank You kellessdee!  This would not have been possible without
#   your help!)
#
#  - \z_flat [integer (optional)]
#  # Causes Events to render as Flat instead of "Standing Up"
#    -  Name an Event "foo\z_flat" to render "Flat On Ground"
#    -  Optional - Name an Event "foo\z_flat[32]" and Change the Number
#		 for more specific control over the Event's Z-Index
# 
#
#  - \z_add[integer]
#  # Allows for things like Shadows in Doorways
#    -  Name an Event "bar\z_add[32]" and Change the Number
#    -  It is pretty much the same as \z_flat but Auto Adds 32 to the Events Z-Index
#
#  ---  EVENT FADING ---
#
#  Now Events can Fade In and Out!
#
#  - Pretty easy.  Run a Script from the Event Editor Window
#  - Just put in "fade_event(opacity, duration)"
#  - Opacity is a Range from 0 to 255
#  - Duration is How Many Frames to take to get to that Opacity
#  - Example: fade_event(128,20) will fade to Half Opaque in One Second
#  - fade_event(0,40) will make an Event go Invisible in Two Seconds
#  - fade_event(255,10) will make an Event appear Solid in Half a Second
#  - RMXP Uses 20 Frames Per Second.
#
#  Additional Features:
#
#  Because there are TWO places you can enter Scripts, I tried to set up
#   a couple of Error Messages (optional) in case you call a Script
#   from the wrong window.  I also shortened up the names of Script Commands
#   so you dont have to put $game_thing.foo_bar.script, all you have to do
#   is just run "<script_name>" from the Script window.  Excluding
#   the extra characters there...
#
#==============================================================================
class Game_Caterpillar

 CATERPILLAR_PAUSE_SWITCH = 22	 # Use for Cutscenes and Interacting with Cat Actors
 CATERPILLAR_ACTIVE_SWITCH = 23    # Caterpillar is ON or OFF
 DEAD_ACTORS_DONT_WALK = 24	    # Self Explanitory, only works with Caterpillar ON
 PASS_SOLID_ACTORS = true		  # Player can walk thru Cat Actor Events regardless of Through or not
 AUTO_ORIENT_TO_PLAYER = true	  # Changes Cat Actors to match Player Direction when sent to a New Map
 REMOVE_VISIBLE_ACTORS = false	 # Erases Events that are Removed from the Party
 DISPLAY_DEVELOPER_ERRORS = true   # Shows Error Messages without Crashing (Doesnt appear in Release Games)

 # MAX_ACTORS Removed due to Incompatability with PASS_SOLID_ACTORS
 # @move_list was used to determine Moving Event Passability
 # Option was replaced by $game_party.actors.size - 1 for the current size
 # of the Caterpillar is the number of Active Party Members
 # Thus, this option is no longer needed, allows for UNLIMITED Cat Actors
 # (well, within reason, above 32, expect a ton of problems)
 #
 # MAX_ACTORS = 4				 

 #----------------------------------------------------------------------------
 # * Initialize the caterpillar
 #----------------------------------------------------------------------------
 def initialize
   @actors = []
   @actor_id_to_event = {}
   @move_list = []
 end

 #----------------------------------------------------------------------------
 # * Clear the caterpillar data
 #----------------------------------------------------------------------------
 def clear
   @actors.clear
   @actor_id_to_event.clear
   @move_list.clear
 end

 #----------------------------------------------------------------------------
 # * Clear the Move data, Leave the Actors
 #----------------------------------------------------------------------------
 def clear_moves
   @move_list.clear
 end

 #----------------------------------------------------------------------------
 #				    *** BEGIN MANUAL COMMANDS ***
 #----------------------------------------------------------------------------

 #----------------------------------------------------------------------------
 # * Deletes Players Last Recorded Movement for Caterpillar
 # ---------------------------------------------------------------------------

 # Call this command Manually - "delete_last_move"
 #
 #   - Useful for Backstepping All Actors
 #	  without making Caterpillar look "Unnatural"
 #	  ** See DEMO for Example - Demo still Under Construction

 def del_last_move
   @move_list.delete_at(0)
 end

 #----------------------------------------------------------------------------
 # * Remove the Last Move Event off of @move_list Array
 #----------------------------------------------------------------------------

 # Call this command Manually - "move_pop" in a Script
 #   - Useful when Player can swap Actors by talking to them
 def move_pop
   @move_list.pop
 end

 # There is ONE MORE Manual Command "force_walk", see below

 #----------------------------------------------------------------------------
 #				    *** END MANUAL COMMANDS ***
 #----------------------------------------------------------------------------

 #----------------------------------------------------------------------------
 # * Checks of Target Location is occupied by a Caterpillar Actor
 #----------------------------------------------------------------------------

 # Used for Checking Passability of Moving Events into Caterpillar
 def in_move_list?(x, y, d)
   # Get new coordinates
   new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
   new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)

   # if Coordinates Event is trying to move to are ANYWHERE in the Move List
   for i in [email="0...@move_list.size"]0...@move_list.size[/email]
  move_command = @move_list[i].to_a
  # If the Target Coordinates are included in move_command
  if move_command[1].to_a.include? [new_x, new_y]
    return true
  end
   end
   # Return false since it is not found in the @move_list
   return false
 end

 #----------------------------------------------------------------------------
 # * Displays Error Messages to Developers for Missing Events
 #----------------------------------------------------------------------------

 def check_missing
   # Go through each actor that's possible present in the caterpillar
   #   1 is used instead of 0 to exclude the First Character
   #   First Character is handled by Game_Player, not Caterpillar
   for i in 1...$game_party.actors.size
  # Set Event to its corresponding Actor, regardless of Event ID
  event = @actor_id_to_event[$game_party.actors[i].id]
  # If Event for that Cat Actor Exists
  if not event.nil?
    # If we have set ALL the Cat Actors correctly, then quit iterating (faster)
    if $check_missing_array.include? $game_party.actors[i].id and $check_missing_array.size == ($game_party.actors.size - 1)
	  $check_missing_needs_to_run = false
    else
	  # If we havent added that Character to the Array yet
	  if not $check_missing_array.include? $game_party.actors[i].id
	    $check_missing_array.push($game_party.actors[i].id)
	  end
    end	 
  else
    # Messages for Game Development, Hidden During actual play, but Dead Walk Feature is Disabled
    # If playing from the Editor, not Game and DEVELOPER ERRORS are On
    if $DEBUG == true and Game_Caterpillar::DISPLAY_DEVELOPER_ERRORS == true and $missing_error_displayed != true
	  # Provide useful information to the person working on the Map
	  print "WARNING: Missing a Cat Actor Event for Character: ", $game_party.actors[i].name, " on\n",
		    "Map Name: ", $game_map.name, "  Map ID: ", $game_map.map_id
	  print "WARNING: To fix this, just create an event and name it \"Char_Name\\cat_actor[",$game_party.actors[i].id, "]\" on\n this Map.  Need Actor Events on EVERY MAP that Character can go."
	  $missing_error_displayed = true
    end
    # Resets Flags as if this completed without errors, expect buggy walking
    $check_missing_needs_to_run = false
  end
   end
 end

 #----------------------------------------------------------------------------
 # * Resets on New Maps to Display Errors again
 #----------------------------------------------------------------------------

 def check_missing_reset
   $check_missing_array.clear
   $check_missing_needs_to_run = true
   $missing_error_displayed = false
 end

 #----------------------------------------------------------------------------
 #				    *** BEGIN DEAD WALK ANIMATION ***
 #----------------------------------------------------------------------------
 #----------------------------------------------------------------------------
 # * Resets the Actors Walk Flag to their original Event Flags, Player to True
 #----------------------------------------------------------------------------

 # Only changes ONCE so you can still use events to set Chars to Non Walking
 #   - Is called when Caterpillar Pause is turned ON, done once
 #   - Useful for Cutscenes where Characters MIGHT be Dead

 def walk_reset
   $game_player.walk_anime = true
   $walk_has_been_reset = true
   $walk_has_been_set = false

   for event in @actors
  # Resets each Event to Original Walk Animation Flags
  event.walk_anime = event.last_walk_anime
   end
 end

 #----------------------------------------------------------------------------
 # * Sets all actors to Walk Animation, regardless of Sprite or Dead
 #---------------------------------------------------------------------------- 
 # Call this command Manually - "force_walk"
 #
 #   - This Resets if the Caterpillar is Changed, moved to New Map,
 #	  Refreshed, or Teleported

 def force_walk
   # Sets the Player to have a Walk Animation
   $game_player.walk_anime = true

   # Loop thru @actors
   for event in @actors
  # Set that Event Walk Animation to True
  event.walk_anime = true
   end
 end


 #----------------------------------------------------------------------------
 # * Sets the Walk Animation for Player and Cat Actors based on actor.dead?
 #----------------------------------------------------------------------------

 def dead_walk_animation
   # If the right switches are ON and OFF
   if $game_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH] and
   $game_switches[Game_Caterpillar::DEAD_ACTORS_DONT_WALK] and
   !$game_switches[Game_Caterpillar::CATERPILLAR_PAUSE_SWITCH]

  # Go through each actor that's possible present in the caterpillar
  #   1 is used instead of 0 to exclude the First Character
  #   First Character is handled by Game_Player, not Caterpillar
  for i in 1...$game_party.actors.size
    # Set Event to its corresponding Actor, regardless of Event ID
    event = @actor_id_to_event[$game_party.actors[i].id]
    # If Event for that Cat Actor Exists
    if not event.nil?
	  # Set Walk Animation to True if Alive and False if Dead
	  event.walk_anime = $game_party.actors[i].dead? ? false : true

	  # If we have set ALL the Cat Actors correctly, then quit iterating (faster)
	  if $walk_reset_array.include? $game_party.actors[i].id and $walk_reset_array.size == ($game_party.actors.size - 1)
	    $game_player.walk_anime = $game_party.actors[0].dead? ? false : true
	    $walk_has_been_reset = false
	    $walk_has_been_set = true
	  else
	    # If we havent added that Character to the Array yet
	    if not $walk_reset_array.include? $game_party.actors[i].id
		  $walk_reset_array.push($game_party.actors[i].id)
	    end
	  end	 
    else
	  # Resets Flags as if this completed without errors
	  # Expect Walk Animations to not be in Sync with Actors Dead State...
	  $walk_has_been_reset = false
	  $walk_has_been_set = true
    end
  end
   end
 end

 #----------------------------------------------------------------------------
 # * Orients Cat Actors to Player's Direction
 #----------------------------------------------------------------------------
 # Used when transported to a different Map

 def orient_to_player
   # For each Event in Actors, which holds ALL Caterpillar Actor Events
   for event in @actors
  # If that Event's Character is in the Party
  if cat_actor_in_party?(event)
    # Determine if we need to use the Player's Temp Direction instead of Direction
    if $game_temp.player_new_direction != 0 and ($game_temp.transition_processing == true or $use_player_temp_direction == true)
    #if ($game_temp.transition_processing == true and $game_temp.player_new_direction != 0) or ($use_player_temp_direction == true and $game_temp.player_new_direction != 0)
	  # If the Event doesn't have a Direction Fix Flag
	  unless event.direction_fix
	  # Set Direction to match the Player's TEMP Direction
	    event.direction = $game_temp.player_new_direction
	  end
    else
	  # If the Event doesn't have a Direction Fix Flag
	  unless event.direction_fix
	    # Set Direction to match the Player's Direction
	    event.direction = $game_player.direction
	  end
    end
  end
   end
   # If the Player has been Transferred and Not Fade
   $use_player_temp_direction = false
 end

 #----------------------------------------------------------------------------
 # * Determines whether or not an Event is in the Active Party
 #----------------------------------------------------------------------------

 def cat_actor_in_party?(event)
   # If that Event corresponding Actor is in the Game Party
   return @actors.include? (event)
 end

 #----------------------------------------------------------------------------
 # * Determines whether an Event is flagged as a Cat Actor, not Party Depeandant
 #----------------------------------------------------------------------------
 def is_cat_actor?(event)
   # If Event has a @caterpillar_actor property (Only Cat Actors get this...)
   return true if not event.caterpillar_actor.nil?
 end

 #----------------------------------------------------------------------------
 # * Add an actor event to the caterpillar
 #----------------------------------------------------------------------------
 def add_actor(event, actor_id)
   # Holds Actor IDs
   @actor_id_to_event[actor_id] = event
   # Clear any Recorded Move Events from the Player
   event.move_list.clear
   # If this Event (Cat Actor) is added (dont add twice)
   added = false
   # For each Actor in the active Game Party, excluding the First Actor - Doesnt need a Cat Actor, - 1 excludes Non Active Party Cat Actors
   for i in 1..$game_party.actors.size - 1
  # New Variable
  actor = $game_party.actors[i]
  # If Event's Cat Actor ID matches the Actor ID in the Database
  if actor.id == actor_id
    # Push on to @actors
    @actors << event
    # If the Caterpillar is not Paused (like Cutscenes, allows logical step progression)
    if !$game_switches[CATERPILLAR_PAUSE_SWITCH]
	  # Snap the Event to the Players Location - Looks sort of "unnatural"
	  event.moveto($game_player.x, $game_player.y)
    end
    # Record the Events Original Walk Anime Setting (Anime = Animation)
    event.last_walk_anime = event.walk_anime
    # Record that this Actor has already been added - Used with Duplicates
    added = true
  end
   end
   # If the option is enabled to erase non Active Party Actors from the Caterpillar, and not Paused
   if remove_visible_actors? && !added && $game_switches[CATERPILLAR_ACTIVE_SWITCH]
  # Then erase the Event
  event.erase
   end
 end

 #----------------------------------------------------------------------------
 # * Check if visible actors should be removed
 #----------------------------------------------------------------------------
 def remove_visible_actors?
   if REMOVE_VISIBLE_ACTORS.is_a?(Integer)
  return $game_switches[REMOVE_VISIBLE_ACTORS]
   else
  return REMOVE_VISIBLE_ACTORS
   end
 end

 #----------------------------------------------------------------------------
 # * If the game player has been "center". I.E. teleported somewhere.
 #----------------------------------------------------------------------------
 def center
   # Check if the caterpillar is active
   return unless $game_switches[CATERPILLAR_ACTIVE_SWITCH]
   # Clear the move_llist
   @move_list.clear
   # Refresh the caterpillar
   update
   # Move the actors to the new place
   for event in @actors
  event.moveto($game_player.x, $game_player.y)
  event.move_list.clear
   end

   if Game_Caterpillar::AUTO_ORIENT_TO_PLAYER == true
  # Sets a Flag that says we need to use the Player's Temp Direction, not the Current Direction
  $use_player_temp_direction = true
  # Orients Cat Actors in Party to match the Player's Direction
  orient_to_player
   end

   if Game_Caterpillar::DISPLAY_DEVELOPER_ERRORS == true
  # New Map - Check for Duplicates Again
  $duplicates_checked = false

  for event in $game_map.events.values
    # Excludes Player Event and Start Event, I think...
    if event.is_a?(Game_Event)
	  # used with Error Reporting
	  event.check_duplicates
    end
  end
   end
 end

 #----------------------------------------------------------------------------
 # * Refresh the caterpillar. (Use sparingly)
 #----------------------------------------------------------------------------
 def refresh
   # Check if the caterpillar is active
   return unless $game_switches[CATERPILLAR_ACTIVE_SWITCH]
   if !$game_switches[CATERPILLAR_PAUSE_SWITCH]   
  # Clear the data
  clear
   end

   # Check each event
   for event in $game_map.events.values
  if event.is_a?(Game_Event)
    event.check_caterpillar
  end
   end
   if !$game_switches[CATERPILLAR_PAUSE_SWITCH]
  # Center the events around the player
  center
   end

   # Update the caterpillar, Graphics for Events changed to the Characters
   update
 end

 #----------------------------------------------------------------------------
 # * Register a player move
 #----------------------------------------------------------------------------
 def register_player_move(move_speed, *args)
   # Check if the caterpillar is active
   return unless $game_switches[CATERPILLAR_ACTIVE_SWITCH] && !$game_switches[CATERPILLAR_PAUSE_SWITCH]
   # Array holds Actors that have their Animations Set for that Step
   $walk_reset_array.clear
   # If Game Switch for DEAD_ACTORS_DONT_WALK is On
   if $game_switches[DEAD_ACTORS_DONT_WALK]
  # Sets flag to set the Actors Walk Animation
  $walk_has_been_set = false
   end

   # Add the new command
   @move_list.unshift([move_speed, args])
   # Append the new moves to the caterpillar events
   update_actor_movement
   # Check if the last command should be removed
   if @move_list.size > $game_party.actors.size
  # Remove the last move command
  @move_list.pop
   end

   if $cat_forced_to_through
  # Just for the Actors in the Active Party, not all Cat Actors
  for actor in @actors
    # Reset Cat Actors "Through" to Original State
    actor.reset_cat_through
  end
  # Turn this option off to prevent resetting every step
  $cat_forced_to_through = false
   end
 end

 #----------------------------------------------------------------------------
 # * Updates the actors movement.
 #----------------------------------------------------------------------------
 def update_actor_movement
   # For each Actor in the Caterpillar
   for i in [email="0...@actors.size"]0...@actors.size[/email]
  # If there is a command in @move_list that hasnt been exectued
  if i + 1 < @move_list.size
    # Set the Command to the Command stored in @move_list, which was set by the Player's Movements
    command = @move_list[i + 1]
    # Sets Actor to an Iteration of Actors in @actors
    actor = @actors[i]
    # Prepends Command to that Events (Actors) @move_list - Prepend means Array = [2,3,4] - Array.unshift(foo) => Array [foo,2,3,4]
    actor.move_list.unshift(command[1])
    # Set Actor Move Speed to Players Recorded Move Speed at that spot
    actor.move_speed = command[0]
  end
   end
 end

 #----------------------------------------------------------------------------
 # * Create a Forced Route to Player from @move_list
 #----------------------------------------------------------------------------

 def create_path_to_player(move_list, max)
   # Dont bother if nothing there   
   return if !move_list
   # Make a New RPG::MoveRoute 
   route_to_player = RPG::MoveRoute.new
   # Required Parameters - I guess these could be optional later
   route_to_player.repeat = false
   route_to_player.skippable = false
   # For every item in move_list
   for i in 0...move_list.size
  # Sets a Default - Not Returned if Code is 0
  code = 0
  # If the current iteration is less than that Actors Max Movements we want them to move
  if i <= max
    # Generate Codes based on move_list recorded action
    command = move_list[i].to_a[1].to_a[0]
    # See Game_Character 2 for Command Codes - Allow for 8 Direction Movement	 
    code = 1 if command == 'move_down'
    code = 2 if command == 'move_left'
    code = 3 if command == 'move_right'
    code = 4 if command == 'move_up'
    code = 5 if command == 'move_lower_left'
    code = 6 if command == 'move_lower_right'
    code = 7 if command == 'move_upper_left'
    code = 8 if command == 'move_upper_right'
    code = 14 if command == 'jump'
    code = 29 if command == 'speed' # Change speed - Not sure how to implement
    # if code 14 (jumping), we need two more parameters for the Interpreter
    if code == 14 or code == 29
	  # Parameter is the Jump Target Array and Speed Parameters
	  parameter = move_list[i].to_a[1].to_a[1]
    end
  end
  # Put the Recorded Movement as the First Element of the Move Command
  route_to_player.list.unshift(RPG::MoveCommand.new(code, parameter)) if code != 0
   end
   # Returns a Valid RPG::MoveCommand to send to the Interpreter
   return route_to_player
 end


 #----------------------------------------------------------------------------
 # * Calls All Cat Actors to the Player's current Position
 #----------------------------------------------------------------------------

 # This call is useful for only moving the active Cat Actors to the Player
 # without trying to determine who is in the party and move via Eventing Movements
 # - Useful when trying to group up the entire party to one position
 #    such as beaming up, or riding up an elevator...

 # This allows use of "Wait for Move's Completion"

 def cat_to_player
   # For each Actor in the Caterpillar
   for i in [email="0...@actors.size"]0...@actors.size[/email]
  # Set the Command to the Command stored in @move_list, which was set by the Player's Movements
  command = @move_list[i]
  # Sets Actor to an Iteration of Actors in @actors
  actor = @actors[i]
  # Actors cant move Through Players - Turn Through On for this Actor (a.k.a. Event)
  actor.set_cat_through
  # Makes Actor complete the move_list and end up on the Player, Stacked
  actor.force_move_route (create_path_to_player(@move_list, i))
  # Set Actor Move Speed to Players Recorded Move Speed at that spot
  actor.move_speed = command[0] if @move_list[i]
   end

   # Clear the Move List since we just executed the whole thing.
   @move_list.clear
 end

 #----------------------------------------------------------------------------
 # * Update the caterpillar.
 #----------------------------------------------------------------------------
 def update
   # Check if the caterpillar is active
   return unless $game_switches[CATERPILLAR_ACTIVE_SWITCH]
   # old_actors is used to Erase those Cat Actors with Option
   old_actors = @actors
   # Reset @actors to Empty Array
   @actors = []

   # Go through each actor that's possible present in the caterpillar
   for i in 1...$game_party.actors.size
  # Figure out which Event corresponds to which Character
  event = @actor_id_to_event[$game_party.actors[i].id]
  # If the Event doesn't exist, or is not in the @actors Array
  unless event.nil? or @actors.include? event
    # Add that Event to the @actors Array for determining corresponding later
    @actors << event
    # Unerase Events if the OPTION is Enabled
    event.unerase if remove_visible_actors?
    # Changes the Events Graphic to that of the corresponding Actors
    event.character_name = $game_party.actors[i].character_name
  end
   end

   # If this OPTION is Enabled
   if remove_visible_actors?
  # Go through the old actors to see if any should be erased
  for actor in old_actors
    unless @actors.include?(actor)
	  actor.erase
    end
  end
   end
 end

 #----------------------------------------------------------------------------
 # * Unerase all erased actor events
 #----------------------------------------------------------------------------
 def unerase_all
   for event in @actor_id_to_event.values
  event.unerase
   end
 end

 #----------------------------------------------------------------------------
 # * Erase actor events not in the party
 #----------------------------------------------------------------------------
 def erase_non_party_events
   for event in @actor_id_to_event.values
  event.erase unless @actors.include?(event)
   end
 end
end
module Fade_Events

 # This module can be a Standalone without the Caterpillar Script
 # I'll release this as its own script when I am done with the Caterpillar
 #  on rmxpunlimited.net
 # But if you are too eager, you need to grab the relevant defs from
 # class Game_Character, attr opacity_target, attr opacity_duration
 # and include Fade_Events line


 #--------------------------------------------------------------------------
 # * Fade Event - (Opacity 0 to 255, Duration in Frames)
 #--------------------------------------------------------------------------

 def fade_event(arg_opacity_target, arg_opacity_duration)
   # If Error Reporting is On and not a Release Game
   if $DEBUG and Game_Caterpillar::DISPLAY_DEVELOPER_ERRORS
  if arg_opacity_target.nil? or arg_opacity_duration.nil?
    print "fade_event(opacity, duration) expects Two Arguments\n"
    return
  elsif not arg_opacity_target.is_a? Numeric
    print "\"", arg_opacity_target, "\" is not an Number!\n",
		  "Both Arguments should be Numbers!\n\n",
		  "I.E. fade_event(255,20)"
    return
  elsif not arg_opacity_duration.is_a? Numeric
    print "\"", arg_opacity_duration, "\" is not an Number!\n",
		  "Both Arguments should be Numbers!\n\n",
		  "I.E. fade_event(255,20)"
    return
  elsif arg_opacity_target < 0 or arg_opacity_target > 255
    print "\"", arg_opacity_target, "\" Opacity Out of Range\n",
		  "Valid Range: 0 - 255"
  elsif arg_opacity_duration < 0
    print "\"", arg_opacity_target, "\" Duration Out of Range\n",
		  "Valid Range: Any Positive Number or 0"
  end
   end
   # Set New Opacity
   self.opacity_target = arg_opacity_target * 1.0
   # Set Opacity Change Duration
   self.opacity_duration = arg_opacity_duration
   # If End of Change Opacity Duration
   if self.opacity_duration == 0
  # Set Current Opacity to the Change To Opacity
  self.opacity = self.opacity_target.clone
   end
 end
#-----------------------------------------------------------------------------
#  * Change Event Opacity
#-----------------------------------------------------------------------------

 def change_event_opacity
   # Manage change in Event Opacity Level
   if @opacity_duration >= 1
  # Create New Variable
  d = @opacity_duration
  # Calculate Opacity Change
  @opacity = (@opacity * (d - 1) + @opacity_target) / d
  # Count Down to 0 to end Opacity Change
  @opacity_duration -= 1
   end
 end

end # End Module Definition
class Game_Character

 attr_accessor	  :direction		   # Used for orienting Cat Actors to Player
 attr_reader	    :caterpillar_actor   # Used for quick checking is_cat_actor and is in the party
 attr_accessor	  :move_route		  # Used for Interpreter Bugfix (built in)
 attr_accessor	  :opacity_target	  # Used with EVENT FADE Option
 attr_accessor	  :opacity_duration    # Used with EVENT FADE Option
 # Make the functions inside the Module available to this class
 include Fade_Events

 #----------------------------------------------------------------------------
 # * Event Fade Initialize
 #----------------------------------------------------------------------------
 unless self.method_defined?('fade_events_initialize')
   alias fade_events_initialize initialize
 end

 def initialize
   # Initilaize Original First
   fade_events_initialize
   # Added Properties for Fade
   @opacity_target = 255
   @opacity_duration = 0
 end


 #----------------------------------------------------------------------------
 # * Event Fade Update
 #----------------------------------------------------------------------------

 # IF the method hasn't been defined yet
 unless self.method_defined?('fade_events_update')
   alias fade_events_update update
 end

 # Redefine Updater
 def update
   # Run Original First
   fade_events_update
   if @opacity_duration >= 1
  # Manages the Events Current Opacity
  change_event_opacity
   end
 end

 #----------------------------------------------------------------------------
 # Event and Player Movement Passable
 #----------------------------------------------------------------------------

 # Check if alias for method already defined
 unless self.method_defined?('heretic_event_passable?')
   # Create Alias of Def for Def adjustment without full reDEFinition
   alias heretic_event_passable? passable?
 end

 def passable?(x, y, d)
   # If Global Variable $walk_off_map is turned on
   if $walk_off_map == true
  # If Player or Active Caterpillar Actor (in the party) trying to move Off Map
  if self.is_a?(Game_Player) or ($game_system.caterpillar.is_cat_actor?(self) and $game_system.caterpillar.cat_actor_in_party?(self))
    # Allows OFF MAP Player and Cat Actor Walking
    return true
  end
   end
   # If Event is NOT the Player - Player and Cat Actors are allowed to move In and Out of the @move_list, or where the Cat Actors will step next
   if not self.is_a?(Game_Player)
  # Returns FALSE if the Event is trying to move into Caterpillar
  if !$game_system.caterpillar.is_cat_actor?(self) or !$game_system.caterpillar.cat_actor_in_party?(self)
    # If the Event (including Player) has a @move_route (not the same as @move_list, that is for Cat Actors
    if not @move_route.nil?
	  # If Event is trying to move to a position occupied by the Cat Actors
	  if $game_system.caterpillar.in_move_list?(x, y, d) and not self.through
	    # That Movement is NOT Passable by the Event
	    return false
	  end
    end
  end
   end

   # If that event has Through Checked, and is allowed to go OFF MAP (Set by Name \off_map
   if @through and @allowed_off_map
  # Return Passability as True -  Acts like a "Super Through"
  return true
   end
   #--------------------------------------------------------------------------
   # * Determine if Passable
   #	 x : x-coordinate
   #	 y : y-coordinate
   #	 d : direction (0,2,4,6,8)
   #		 * 0 = Determines if all directions are impassable (for jumping)
   #--------------------------------------------------------------------------

   # Returns Cat Actor Modified Original Passability

   # This needed to be modified and the part that needed adjusting was
   #  too deeply buried in nesting so most of this is actually just
   #  the original code with a few lines changed to check for Cat Actors

   # Get new coordinates
   new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
   new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
   # If coordinates are outside of map
   unless $game_map.valid?(new_x, new_y)
  # impassable
  return false
   end
   # If through is ON
   if @through
  # passable
  return true
   end
   # If unable to leave first move tile in designated direction
   unless $game_map.passable?(x, y, d, self)
  # impassable
  return false
   end
   # If unable to enter move tile in designated direction
   unless $game_map.passable?(new_x, new_y, 10 - d)
  # impassable
  return false
   end
   # Loop all events
   for event in $game_map.events.values
  # If event coordinates are consistent with move destination
  if event.x == new_x and event.y == new_y
    # If through is OFF
    unless event.through
	  # If self is event not a Player
	  if self != $game_player
	    # impassable
	    return false
	  end
	  # With self as the player and partner graphic as character
	  if event.character_name != ""
	    unless $game_system.caterpillar.cat_actor_in_party?(event) and
		  Game_Caterpillar::PASS_SOLID_ACTORS and
		  ((!$game_switches[Game_Caterpillar::CATERPILLAR_PAUSE_SWITCH] and
		  $game_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH]) or
		  !$game_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH])
		  # impassable
		  return false
	    end
	  end
    end
  end
   end
   # If player coordinates are consistent with move destination
   if $game_player.x == new_x and $game_player.y == new_y
  # If through is OFF
  unless $game_player.through
    # If your own graphic is the character
    if @character_name != ""
	  # impassable
	  return false
    end
  end
   end
   # passable
   return true
 end


end
class Game_Player < Game_Character

 attr_accessor	  :walk_anime	    # Walking Animation - Used for Dead Dont Walk

 unless self.method_defined?('zeriab_caterpillar_game_player_center')
   alias_method(:zeriab_caterpillar_game_player_center, :center)
 end
 # If Alias has already been defined, dont redefine, prevents STACK OVERFLOW
 unless self.method_defined?('heretic_player_passable?')
   alias heretic_player_passable? passable?
 end

 #----------------------------------------------------------------------------
 # * Redefines passable used by Player to allow going thru Cat Actors and OFF MAP
 #----------------------------------------------------------------------------

 def passable?(*args)
   # If Global Variable $walk_off_map is set
   if $walk_off_map == true
  # Return Passable as True when trying to move ANYWHERE, acts like "Super Through"
  # PLAYER ONLY
  return true
   end

   return heretic_player_passable?(*args)
 end
 #----------------------------------------------------------------------------
 # * Tests for Tile Conditions to Deny Passability
 #----------------------------------------------------------------------------

 def location_tile_passable?(x, y, d)
   result = true
   # Checks passability using Bits FLIP THE BIT
   if not $game_map.tile_passable?(x, y, d, true)# or
   #not $game_map.tile_passable?($game_player.x, $game_player.y, d)
  result = false
   end
   return result
 end

 #----------------------------------------------------------------------------
 # * Tests for Tile Event Conditions to deny passability
 #----------------------------------------------------------------------------

 def location_event_passable?(x, y, d, event)
 end

 #----------------------------------------------------------------------------
 # * When the player is centered (i.e. teleported somewhere)
 #----------------------------------------------------------------------------
 def center(*args)
   zeriab_caterpillar_game_player_center(*args)
   $game_system.caterpillar.center

   if Game_Caterpillar::DISPLAY_DEVELOPER_ERRORS
  # Enables Displaying Error Messages for Missing Caterpillar Actors
  $game_system.caterpillar.check_missing_reset
   end
 end

 #----------------------------------------------------------------------------
 # * Just Informational to not call "cat_to_player" from "Set Move Route"
 #----------------------------------------------------------------------------


 def cat_to_player
   if $DEBUG and Game_Caterpillar::DISPLAY_DEVELOPER_ERRORS == true
  print "Call from Event Editor -> Scripts, instead of\nEvent Editor -> Set Move Route -> Scripts"
   end
 end

 #----------------------------------------------------------------------------
 # * Generate registration of player moves to the caterpillar code
 #----------------------------------------------------------------------------

 # Constants - DO NOT EDIT

 MOVE_METHODS = ['move_down', 'move_left', 'move_right', 'move_up',
			  'move_lower_left', 'move_lower_right', 'move_upper_left',
			  'move_upper_right', 'jump']

 # Go through each method
 for method in MOVE_METHODS
   # Create the script for the specific method
   PROG = <<_END_
 def #{method}(*args)
   x,y = self.x, self.y
   super(*args)
   unless self.x == x && self.y == y
  $game_system.caterpillar.register_player_move(@move_speed, '#{method}', args, [self.x, self.y])
   end
 end
_END_
   # Run the script
   eval(PROG)
 end
end
class Module
 # Prevent adding the method again should it already be present.
 unless self.method_defined?('attr_sec_accessor')
   def attr_sec_accessor(sym, default = 0)
  attr_writer sym
  attr_sec_reader sym, default
   end

   def attr_sec_reader(sym, default = 0)
  sym = sym.id2name
  string = "def #{sym};" +
		   "  @#{sym} = #{default}  if @#{sym}.nil?;" +
		   "  @#{sym};" +
		   "end;"
  module_eval(string)
   end
 end
end
class Game_System
 attr_sec_accessor :caterpillar, 'Game_Caterpillar.new'
end
class Game_Actor
 attr_reader  :actor_id   # Actor ID in the Database - Leave Open for Script Development
end
class Game_Event < Game_Character
 #----------------------------------------------------------------------------
 # * Attributes
 #----------------------------------------------------------------------------

 attr_sec_accessor  :move_list, '[]'    # Cat Actors Move List
 attr_accessor	  :move_speed		 # Player Move Speed
 attr_accessor	  :walk_anime		 # Walking Animation Bool
 attr_accessor	  :last_walk_anime    # Last Walking Animation Bool - Dead Dont Walk
 attr_accessor	  :through		    # Default Walk Through
 attr_writer	    :set_cat_through    # Turns Through On and saves Original State
 attr_writer	    :reset_cat_through  # Resets Through to Original State
 attr_writer	    :character_name	 # Used changing Event Graphics to the Actors
 attr_reader	    :allowed_off_map    # Event Propterty set by Event Name \off_map
 attr_reader	    :direction_fix	  # Used with Auto Orient

 #----------------------------------------------------------------------------
 # * Aliases
 #----------------------------------------------------------------------------
 unless self.method_defined?('zeriab_caterpillar_game_event_passable?')
   alias zeriab_caterpillar_game_event_initialize :initialize
   alias zeriab_caterpillar_game_event_passable?  :passable?
   if Module.constants.include?('SDK')
  alias zeriab_caterpillar_game_event_update_movement  :update_movement
   else
  alias zeriab_caterpillar_game_event_update  :update
   end
 end

 #----------------------------------------------------------------------------
 # Object Initialization
 #----------------------------------------------------------------------------
 def initialize(map_id, event, *args)
   # Gives Events an @allowed_off_map Property to allow them to venture off the Map
   check_allowed_off_map(event)
   # Used with Party Members that need to have Walk Animation Reset to Event Original Settings
   $walk_reset_array = []
   # Used for Displaying Errors about Missing Cat Actors
   $check_missing_array = []
   # Used for checking for Duplicate Cat Actors
   $duplicates_array = []
   # Check for Events with \z_flat or \z_add[int] flags to render them correctly
   flat_sprite_check(event)
   # Default update
   zeriab_caterpillar_game_event_initialize(map_id, event, *args)
   # Check if the caterpillar is active
   return unless $game_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH]
   # Check for caterpillar actor denomination
   check_caterpillar
 end

 #----------------------------------------------------------------------------
 # * Sets an Event to Temporarily have a Through Property - Dont Call Manually
 #----------------------------------------------------------------------------

 def set_cat_through
   # Store the Original Property so we can revert back to it later
   @original_through = self.through if @original_through.nil?
   # Set that event to a Through flag so can walk Through the Player
   # Player can walk thru events, but events cant walk thru the Player
   self.through = true
   # Allows a Reset to Original State if this is true, happens on Next Player Movement
   $cat_forced_to_through = true
 end
 #----------------------------------------------------------------------------
 # * Resets an Event back to its Original Through Property - Dont Call Manually
 #----------------------------------------------------------------------------

 def reset_cat_through
   # Resets the Event back to its Original Through State
   self.through = @original_through if not @original_through.nil?
 end

 #--------------------------------------------------------------------------
 # * Determine Coordinate Match
 #--------------------------------------------------------------------------
 def pos?(x, y)
   # Returns True if X and Y args match the @X and @Y properties
   return (@x == x and @y == y)
 end

 #--------------------------------------------------------------------------
 # * Sets the Cat Actor and Player Walk Animations ON and OFF for each step
 #--------------------------------------------------------------------------
 def set_dead_animation
   # Resets Caterpillar Actor Walk Animation to Default of Event
   if $game_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH]
  if $walk_has_been_reset != true and
    $game_switches[Game_Caterpillar::CATERPILLAR_PAUSE_SWITCH]
	  # Resets the Player and Caterpillar Actors to Default Walk Flags
	  $game_system.caterpillar.walk_reset
  elsif $walk_has_been_set != true and
    !$game_switches[Game_Caterpillar::CATERPILLAR_PAUSE_SWITCH]
	  # Checks for Dead Actors once for each Player Step
	  $game_system.caterpillar.dead_walk_animation
  end
   end 
 end

 #----------------------------------------------------------------------------
 # * Redefine screen_z for Caterpillar
 #----------------------------------------------------------------------------
 unless method_defined?(:caterpillar_screen_z)
   alias :caterpillar_screen_z :screen_z
 end   

 def screen_z (height = 0)

   if @always_on_top
  # Caterpillar Actors Z-Index based on their Index in the Party
  # 0 - on top, 3-on bottom, for Caterpillar Actors, still on top of everything else

  # If Event is tagged as being a Caterpillar Actor
  if @caterpillar_actor
    # Gets the Actors Position in the Game Party
    actor_index = $game_actors[@caterpillar_actor].index
    # If Cat Actor Event's Actor is in the Party, otherwise nil
    if actor_index
	  # Allows Events to be Above Always On Top Characters
	  return 998 - actor_index
    end
  else
    # 999, unconditional
    return 999
  end
   end

   # if Event has a @caterpillar Flag
   if @caterpillar_actor
  # Caterpillar Actors based on their Index in the Party
  # 0 - on top, 3-on bottom
  actor_index = $game_actors[@caterpillar_actor].index
    # If Cat Actor Events Actor is in the Party, otherwise nil
  if actor_index
    # Original Screen Z + 32 (Cat Actors always Render as Tall Sprites) minus position in party
    return caterpillar_screen_z + 32 - actor_index
  end
   end
   # This adds the feature of adjusting an events Z-Index on the fly

   # \z_flat[int]
   if not @z_flat.nil? and [email="!@always_on_top"]!@always_on_top[/email]
  return (@real_y - $game_map.display_y + 3) / 4 + @z_flat
   end
   # \z_add[int]
   if not @z_add.nil? and [email="!@always_on_top"]!@always_on_top[/email]
  return (@real_y - $game_map.display_y + 3) / 4 + 32 + @z_add
   end

   # If tile
   if @tile_id > 0
  # Add tile priority * 32
  return (@real_y - $game_map.display_y + 3) / 4 + 32 + $game_map.priorities[@tile_id] * 32
   # If character
   else
  # Calculates Original Screen-Z adjusted for Party Size so Party is Always On Top
  return (@real_y - $game_map.display_y + 3) / 4 + 32 + (height > 32 ? 31 - $game_party.actors.size : 0)
   end
 end

 #----------------------------------------------------------------------------
 #  * Check for caterpillar actor denomination
 #----------------------------------------------------------------------------
 def check_caterpillar
   # Check for caterpillar actor denomination (Last is used if more present)
   @event.name.gsub(/\\cat_actor\[([0-9]+)\]/i) [email="{@caterpillar_actor"]{@caterpillar_actor[/email] = $1 }
   # Check if an valid denomination is found.
   if @caterpillar_actor.is_a?(String)
  @caterpillar_actor = @caterpillar_actor.to_i
  if $data_actors[@caterpillar_actor].nil?
    @caterpillar_actor = nil
  else
    $game_system.caterpillar.add_actor(self, @caterpillar_actor)
  end
   end
 end
 #----------------------------------------------------------------------------
 #  * Check Each Event for a \z_flat  or \z_add flag
 #----------------------------------------------------------------------------

 def flat_sprite_check(event)
   # Options
   #
   # "Name\z_flat"
   # "Name\z_flat[32]" for characters manual adjustments, for whatever reason
   # "Name\z_add[32]" for characters higher than 32 pixels high
   event.name.gsub(/\\z_flat\[([-]?[0-9]+)\]|\\z_flat/i) [email="{@z_flat"]{@z_flat[/email] = $1.to_i }
   return if @z_flat   

   event.name.gsub(/\\z_add\[([-]?[0-9]+)\]/i) [email="{@z_add"]{@z_add[/email] = $1.to_i }
   return if @z_add
 end

 #----------------------------------------------------------------------------
 #  * Check for Duplicate Cat Actors which causes Problems with the Caterpillar
 #----------------------------------------------------------------------------

 def check_duplicates
   if $duplicates_checked != true and Game_Caterpillar::DISPLAY_DEVELOPER_ERRORS

  # Initialize - Resets to Uninitialized at end of check
  #  - Else, Increment
  $check_caterpillar_events_checked = ($check_caterpillar_events_checked.nil?) ? 1 : $check_caterpillar_events_checked + 1
  # If Just initialized, reset the Arrays used
  if $check_caterpillar_events_checked == 1
    # Holds ONLY Duplicated Events for Error Display
    $duplicated_events = []
    # Holds ALL Cat Actors - Duplicates Not Added, used for checking if Duplicates Exist
    $duplicates_array = []
    # Advises of Multiple Duplicates - Integer for Cat Actor
    error_displayed = nil
  end

  # If the Event is a Cat Actor
  if @caterpillar_actor
    # Iterate thru the Array for checking Subarrays
    for i in 0...$duplicates_array.size
	  # If the Array that holds ALL Cat Actors already has that Cat Actor in it
	  if $duplicates_array[i].include? (@caterpillar_actor)
	    # If the Array that holds ONLY Duplicates doesnt have this in it yet
	    if not $duplicated_events.include? ([@caterpillar_actor, @event])
		  # Then Add it to the Array for Error Display
		  $duplicated_events.push($duplicates_array[i])
	    end
	    # If the Array that holds ONLY Duplicates doesnt have this in it yet
	    #   We want to provide the person using this script with information
	    #   on which two events are duplicates
	    #   so Original AND Duplicate are Needed for Displaying Useful Errors
	    #   this is for the ORIGINAL
	    if not $duplicated_events.include? ([@caterpillar_actor, @event])
		  # Then Add it to the Array also for Error Display
		  $duplicated_events.push([@caterpillar_actor, @event])
	    end
	  end
    end
    # Even if it is a Duplicate Event, push that on to the All Cat Actors array that is checked against
    $duplicates_array.push([@caterpillar_actor, @event])
  end
  # If the Increment Counter is the same as the Total of Game Events
  # Then all Events have been checked for Duplicates, then display the Duplicates
  if $check_caterpillar_events_checked == $game_map.events.size
    # If there were any Duplicates (shows minimum of TWO)
    if not $duplicated_events.empty?
	  # Iterate thru EVERY Duplicate Cat Actor
	  for i in 0...$duplicated_events.size
	    # Just easier to type - Temporary Variable
	    dup_event = $duplicated_events[i].to_a[1]
	    dup_actor_id = $duplicated_events[i].to_a[0].to_i
	    dup_name = $game_actors[dup_actor_id].name
	    # If Initial Warning for that Cat Actor Duplicate hasnt been displayed yet
	    if error_displayed.nil? or error_displayed != $duplicated_events[i].to_a[0] # to_a[0] is the Cat Actors ID
		  # Advise there are Duplicates for THIS Cat Actor
		  print "WARNING: Caterpillar has detected\nDuplicate Cat Actors\nfor Cat Actor: ", $duplicated_events[i].to_a[0], " Name: ", dup_name, "\n\n",
			    "Duplicates move to the Players Position, but\nare NOT a part of the Caterpillar.\nThey Might cause your game to Freeze\nunder certain circumstances.\n\n",
			    "Map Name: ", $game_map.name, "   Map ID: ", $game_map.map_id
		  error_displayed = $duplicated_events[i].to_a[0]
	    end
	    # Display the Useful Data to the Mapper / Developer about which Two Events are Cat Duplicates
	    print "Duplicate Cat Actor: ", $duplicated_events[i].to_a[0], "\n",
			  "Event ID: ", dup_event.id, "\n",
			  " - MAP Name: ", $game_map.name, "\n",
			  " - Actor Name: ", dup_name, "\n",
			  " - Event Name: ", dup_event.name, "\n",
			  " - X: ", dup_event.x, "\n",
			  " - Y: ", dup_event.y

	  end
    end 
    # Reset the Global Arrays and Variables (Global so not Event Properties, and can be run outside this Class)
    $duplicated_events = []
    $duplicates_array = []	  
    $check_caterpillar_events_checked = nil
    # Everything in this Def runs when this is set to False, Reset in "center"
    $duplicates_checked = true
  end
   end
 end

 #----------------------------------------------------------------------------
 # * Set Events with \off_map in Name to go OFF MAP with THROUGH
 #----------------------------------------------------------------------------
 def check_allowed_off_map(event)
   # Check ALL Events if that Event should be allowed to go Off the Map
   # Enable by adding \off_map to Event Name.  IE "Bird\off_map"
   # Not Dependant on Caterpillar
   #
   # NOTE: "THROUGH" MUST BE ENABLED TO ALLOW OFF MAP!!!
   event.name.gsub (/\\[Oo][Ff][Ff]\_[Mm][Aa][Pp]/) [email="{@allowed_off_map"]{@allowed_off_map[/email] = true}
 end

 #---------------------------------------------------------------------------
 # Check passability
 #---------------------------------------------------------------------------
 def passable?(*args)
   if @caterpillar_actor.nil? || move_list.empty? ||
   !$game_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH]
  return zeriab_caterpillar_game_event_passable?(*args)
   else
  return true
   end
   return result
 end

 #---------------------------------------------------------------------------
 #
 #    SDK and Non-SDK stuff
 #
 #---------------------------------------------------------------------------

 if Module.constants.include?('SDK')
   #-------------------------------------------------------------------------
   # * Update Movement - SDK Version
   #-------------------------------------------------------------------------
   def update_movement
  # Return if Conditions Not Met
  if @caterpillar_actor.nil? || move_list.empty? ||
	 !$game_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH]
    return zeriab_caterpillar_game_event_update_movement
  end
  # Interrupt if not stopping
  if jumping? or moving?
    return
  end

  # If the option for Dead Actors Dont Walk, do update Here
  if $game_switches[Game_Caterpillar::DEAD_ACTORS_DONT_WALK]
    # Sets the Animation for Cat Actors EVERY STEP (Due to Poison on Map)
    set_dead_animation
  end

  # If the Developer Display Errors Option is enabled
  if Game_Caterpillar::DISPLAY_DEVELOPER_ERRORS and $check_missing_needs_to_run == true
    # Sets the Animation for Cat Actors
    $game_system.caterpillar.check_missing
  end

  # Retrive the command
  command = move_list[0]
  # Call the command
  method(command[0]).call(*command[1])
  # Make sure the x and y are right in the end
  @x, @y = *command[2]
  # Remove the command
  move_list.pop
   end
 else # Non-SDK version
   #-------------------------------------------------------------------------
   # * Update Movement - Non SDK Version
   #-------------------------------------------------------------------------
   def update
  # Interrupt if not stopping
  no_move = jumping? or moving?

  # If the option for Dead Actors Dont Walk, do update Here
  if $game_switches[Game_Caterpillar::DEAD_ACTORS_DONT_WALK]
    # Sets the Animation for Cat Actors EVERY STEP (Due to Poison on Map)
    set_dead_animation
  end

  # If the Developer Display Errors Option is enabled
  if Game_Caterpillar::DISPLAY_DEVELOPER_ERRORS and $check_missing_needs_to_run == true
    # Sets the Animation for Cat Actors
    $game_system.caterpillar.check_missing
  end	 
  # Update
  zeriab_caterpillar_game_event_update
  # Check if it should return
  if $game_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH] &&
	 @caterpillar_actor != nil && !move_list.empty? && !no_move
    # Retrive the command
    command = move_list[0]
    # Call the command
    method(command[0]).call(*command[1])
    # Make sure the x and y are right in the end
    @x, @y = *command[2]
    # Remove the command
    move_list.pop
  end
   end
 end

 #---------------------------------------------------------------------------
 # * Bring back an erased event
 #---------------------------------------------------------------------------
 def unerase
   @erased = false
   refresh
 end
end
class Game_Map
 #-----------------
 #    Aliases
 #----------------
 unless self.method_defined?('zeriab_caterpillar_game_map_setup')
   alias zeriab_caterpillar_game_map_setup :setup
 end

 #---------------------------------------------------------------------------
 # * Transfer Player
 #---------------------------------------------------------------------------
 def setup(*args)
   $game_system.caterpillar.clear
   zeriab_caterpillar_game_map_setup(*args)
   if Game_Caterpillar::AUTO_ORIENT_TO_PLAYER == true
  $game_system.caterpillar.orient_to_player
  #$game_temp.player_new_direction = 0	 
   end
 end

 #---------------------------------------------------------------------------
 # * Returns an Array of Events that are at X, Y Coordinates
 #---------------------------------------------------------------------------

 def events_at_xy(x, y)
   # Holds a list of All Events at X, Y Coordinates
   result = []
   for event in $game_map.events.values
  result.push(event) if event.pos?(x, y)
   end

   # Return the list of All Events at ARG Coordinates
   return result
 end

 #---------------------------------------------------------------------------
 # * Player vs Tile Under Caterpillar Passability
 #---------------------------------------------------------------------------

 def tile_passable?(x, y, d, flip = nil)
   # If coordinates given are outside of the map
   unless valid?(x, y)
  # impassable
  return false
   end
   # Sets the Direction Bit to the other direction
   # IE - if the Player is facing down, we want to know
   #  about that tile's UP Passability, not DOWN, thus FLIP
   if not flip.nil?
  if d == 2
    d = 8
  elsif d == 4
    d = 6
  elsif d == 6
    d = 4
  elsif d == 8
    d = 2
  end
   end

   # Change direction (0,2,4,6,8,10) to obstacle bit (0,1,2,4,8,0)
   bit = (1 << (d / 2 - 1)) & 0x0f

   # Layers 3, 2, and 1 in that order
   for i in [2, 1, 0]
  # Get tile ID
  tile_id = data[x, y, i]
  # Tile ID acquistion failure
  if tile_id == nil
    # impassable
    return false
  # If obstacle bit is set
  elsif @passages[tile_id] & bit != 0
    # impassable
    return false
  # If obstacle bit is set in all directions
  elsif @passages[tile_id] & 0x0f == 0x0f
    # impassable
    return false
  # If priorities other than that are 0
  elsif @priorities[tile_id] == 0
    # passable
    return true
  end
   end

 end # End Def

 #---------------------------------------------------------------------------
 # * Event Tile Passability
 #---------------------------------------------------------------------------

 def tile_event_passable?(x, y, d, event, flip = nil)

   #flip = nil
   if not flip.nil?
  d = 8 if d == 2
  d = 6 if d == 4
  d = 4 if d == 6
  d = 2 if d == 8
   end

   # Change direction (0,2,4,6,8,10) to obstacle bit (0,1,2,4,8,0)
   bit = (1 << (d / 2 - 1)) & 0x0f

   if event.tile_id > 0
  # If obstacle bit is set in all directions
  if @passages[event.tile_id] & 0x0f == 0x0f
    print "obstacle bit in all directions so false"
    # impassable
    return false	 
  # If obstacle bit is set
  elsif @passages[event.tile_id] & bit != 0
    print "obstacle bit is set at ", (@passages[event.tile_id] & bit).inspect
    # impassable
    return false
  # If priorities other than that are 0
  elsif @priorities[event.tile_id] == 0
    # passable
    return true
  end
   end

 end # End Def

end # End Class
class Game_Switches
 #------------------
 #    Aliases
 #------------------
 unless self.method_defined?('zeriab_caterpillar_game_switches_setter')
   alias zeriab_caterpillar_game_switches_setter :[]=
 end
 #------------------
 #    Setter
 #------------------
 def []=(switch_id, value, *args)
   zeriab_caterpillar_game_switches_setter(switch_id, value, *args)
   if switch_id == Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH
  $game_system.caterpillar.refresh
   elsif switch_id == Game_Caterpillar::REMOVE_VISIBLE_ACTORS
  if value
    $game_system.caterpillar.erase_non_party_events
  else
    $game_system.caterpillar.unerase_all
  end
   end
 end
end
class Interpreter
 #------------------
 #	 Aliases
 #------------------
 unless self.method_defined?('zeriab_caterpillar_interpreter_command_129')
   alias zeriab_caterpillar_interpreter_command_129 :command_129
   alias zeriab_caterpillar_interpreter_command_322 :command_322
   alias heretic_caterpillar_interpreter_command_201 :command_201
 end

 #----------------------------------------------------------------------------
 # * Change Party Member
 #----------------------------------------------------------------------------
 def command_129
   result = zeriab_caterpillar_interpreter_command_129
   $game_system.caterpillar.refresh
   return result
 end

 #----------------------------------------------------------------------------
 # * Change Actor Graphic
 #----------------------------------------------------------------------------
 def command_322
   result = zeriab_caterpillar_interpreter_command_322
   $game_system.caterpillar.update
   return result
 end
 #--------------------------------------------------------------------------
 # * INTERPRETER BUGFIX
 #--------------------------------------------------------------------------
 #--------------------------------------------------------------------------
 # * Frame Update
 #--------------------------------------------------------------------------
 # Full Redefinition - Not Aliased!!!
 def update
   # Initialize loop count
   @loop_count = 0
   # Loop
   loop do
  # Add 1 to loop count
  @loop_count += 1
  # If 100 event commands ran
  if @loop_count > 100
    # Call Graphics.update for freeze prevention
    Graphics.update
    @loop_count = 0
  end
  # If map is different than event startup time
  if $game_map.map_id != @map_id
    # Change event ID to 0
    @event_id = 0
  end
  # If a child interpreter exists
  if @child_interpreter != nil
    # Update child interpreter
    @child_interpreter.update
    # If child interpreter is finished running
    unless @child_interpreter.running?
	  # Delete child interpreter
	  @child_interpreter = nil
    end
    # If child interpreter still exists
    if @child_interpreter != nil
	  return
    end
  end
  # If waiting for message to end
  if @message_waiting
    return
  end
  # If waiting for move to end
  if @move_route_waiting
    # If player is forcing move route
    if $game_player.move_route_forcing
	  return
    end
    # Loop (map events)
    for event in $game_map.events.values
	  # If this event is forcing but not repeating move route
#One Line of Code needed to be fixed.  Added "and not event.move_route.repeat"
	  if event.move_route_forcing and not event.move_route.repeat
	    return
	  end
    end
    # Clear move end waiting flag
    @move_route_waiting = false
  end
  # If waiting for button input
  if @button_input_variable_id > 0
    # Run button input processing
    input_button
    return
  end
  # If waiting
  if @wait_count > 0
    # Decrease wait count
    @wait_count -= 1
    return
  end
  # If an action forcing battler exists
  if $game_temp.forcing_battler != nil
    return
  end
  # If a call flag is set for each type of screen
  if $game_temp.battle_calling or
	 $game_temp.shop_calling or
	 $game_temp.name_calling or
	 $game_temp.menu_calling or
	 $game_temp.save_calling or
	 $game_temp.gameover
    return
  end
  # If list of event commands is empty
  if @list == nil
    # If main map event
    if @main
	  # Set up starting event
	  setup_starting_event
    end
    # If nothing was set up
    if @list == nil
	  return
    end
  end
  # If return value is false when trying to execute event command
  if execute_command == false
    return
  end
  # Advance index
  @index += 1
   end
 end
end

 #----------------------------------------------------------------------------
 # * Game Event
 #----------------------------------------------------------------------------
class Game_Event

 if Interpreter.method_defined? ('pathfind')
   # Adds same definition of pathfind to Interpreter to Game_Event, simpler for non coders
   def pathfind(x, y, *args)
  args[0] = @event.id if args[0] == nil
  args[1] = 0 if args[1] == nil
  # Add a simpler call for using as a script call
  Pathfind.new(Node.new(x, y), *args)
   end
 else
   def pathfind(*args)
  if $DEBUG and Game_Caterpillar::DISPLAY_DEVELOPER_ERRORS == true
    print "Pathfind Script Not Installed"
  end
   end
 end
 # Tell Mappers this script call isnt available here
 def cat_to_player
   if $DEBUG and Game_Caterpillar::DISPLAY_DEVELOPER_ERRORS == true
  print "Call from Event Editor -> Scripts, instead of\nEvent Editor -> Set Move Route -> Scripts"
   end
 end
end
class Interpreter
 # Executed in Game_Caterpillar - Including here allows cmd to be run from
 # Event Editor -> Scripts and fit on the same line

 def fade_event(opacity, duration)
   if $DEBUG and Game_Caterpillar::DISPLAY_DEVELOPER_ERRORS == true
  print "Please call \"fade_event\" from\n",
	    "\"Edit Event\" -> \"Set Move Route\" -> Scripts Window\n",
	    "instead of \n\"Edit Event\" -> Scripts Window"
   end
 end

 # Moves the whole Caterpillar to the Players position, then Clears Move Route
 def cat_to_player
   $game_system.caterpillar.cat_to_player
 end
 # Pops the last Move off, use for preventing Character Overlap
 def move_pop
   $game_system.caterpillar.move_pop
 end
 # Turns all Cat Actors to the same direction as the Player - Useful during Transport
 def orient_to_player
   $game_system.caterpillar.orient_to_player
 end
 # Forces all Cat Actors to have a Walk Animation, regardless if Dead or Not
 #  - Use with Dead_Dont_Walk GAME SWITCH OFF
 def force_walk
   $game_system.caterpillar.force_walk
 end
 # Deletes a move you dont want the rest of the Caterpillar to Follow
 def delete_last_move
   $game_system.caterpillar.del_last_move
 end
end

 

 

You dont have to test it, but I am proud of it!

Share this post


Link to post
Share on other sites
  • 0

Alright. Im doing pretty good. Stumped again. Trying to pull out the need for the SDK for ONE feature that seems to have needed it. $game_map.name. Comes up as NIL without the SDK. But I cant find where it is defined in the SDK. How can I work around that?

Share this post


Link to post
Share on other sites
  • 0

Game_Map does not feature the map name because it's never actually used in-game, only for referencement in the project, you have to look for it inside Data_Mapinfos.rxdata.

class Game_Map
 def name
   data = load_data("Data/MapInfos.rxdata")
   return data[@map_id]
 end
end

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...