Main Menu
  • Welcome to The RPG Maker Resource Kit.

[solved]difficulty passing actor to next window?

Started by shintashi, January 16, 2011, 05:44:07 AM

0 Members and 1 Guest are viewing this topic.

shintashi

At this point I'm trying to pass the correct actor into window 5 (below), and display their skills, but while it can recognize that I am identifying Actor 1, or Actor 2 when pressing the space bar, it still loads the skillset of Actor 1.

Here's what I'm using to try to pass the actor from window 4 (my select actor program) to window 5 (select skill program):


if Input.trigger?(Input::C)
  if @window_4.active == true
  #load actor # into game actor slot 
$windex = $game_party.actors[@window_4.index].id
  p $windex #prints actor's id number
  $win4_actor = true
@window_4.visible = false
@window_4.active = false
@window_5.visible = true
@window_5.active = true
end
end




basically the info from window 4 (which actor was selected) is passing successfully to "print", but isn't passing to window 5. It always thinks I'm selecting actor 1.



class Window_5 < Window_Selectable # < Window_Base
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     actor : actor
  #--------------------------------------------------------------------------
  def initialize
    super(0, 0, 440, 380)
    self.contents = Bitmap.new(width-32, height-32)
    @column_max = 2
    refresh
    self.index = 0
  end
   def skill
    return @data[self.index]
  end
   
   def refresh
#this is the broken section... I think
actor = $win4_actor == false ? $game_party.actors[0] : $game_party.actors[$windex]
@actor = actor
     
  @data = []
    for i in 0...@actor.skills.size #how many skills does actor have?
      skill = $data_skills[@actor.skills[i]]
 
      if skill != nil #if skill doesn't exist
        @data.push(skill) #skip to next skill
      end
    end
 

    # If item count is not 0, make a bit map and draw all items
    @item_max = @data.size
if @item_max > 0
      self.contents = Bitmap.new(width - 32, row_max * 32)
      for i in 0...@item_max
        draw_item(i)
       end
    end
  end

 
 
  def draw_item(index)
    skill = @data[index]
    if @actor.skill_can_use?(skill.id)
      self.contents.font.color = normal_color
    else
      self.contents.font.color = disabled_color
    end
   

    x = 4 + index % 2 * (158 + 32) #288 +32
    y = index / 2 * 32
    rect = Rect.new(x, y, self.width / @column_max - 32, 32)
    self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
    bitmap = RPG::Cache.icon(skill.icon_name)
    opacity = self.contents.font.color == normal_color ? 255 : 128
    self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
    self.contents.draw_text(x + 28, y, 164, 32, skill.name, 0)
      end
end


edit: I should mention the program was originally designed and tested for 1 actor, so this is a modification to the original, which is why it might not work.

modern algebra

It's kind of hard to read without the default indenting, but I can see at least two potential problems - the first is: when and where do you call the refresh method of Window_5? The only place I see is the initialize method. Maybe you aren't sharing the whole code, but you will need to call the refresh method somewhere - maybe right before making it visible and active. In order to work, it needs to run.

Secondly you are saving the ID of the actor into $windex, not his or her party index. Yet, in the refresh method you are going through $game_party.actors. That won't do. In order for it to work, you need to either replace:


$windex = $game_party.actors[@window_4.index].id


with:

$windex = @window_4.index

OR replace:

actor = $win4_actor == false ? $game_party.actors[0] : $game_party.actors[$windex]

with:

actor = $win4_actor == false ? $game_party.actors[0] : $game_actors[$windex]


Just for the record, I don't like the way you are using global variables (like $win4_actor and $windex) - it's very difficult to track what values are likely to be in them and it seems like you are just using them to avoid passing any arguments. As a simple little guide: http://c2.com/cgi/wiki?GlobalVariablesAreBad

It would be far easier to follow if, instead of using global variables here there and everywhere, you just did something like this:


  def refresh (party_index = 0)
#this is the broken section... I think
actor = $game_party.actors[party_index]
@actor = actor
     
  @data = []
    for i in 0...@actor.skills.size #how many skills does actor have?
      skill = $data_skills[@actor.skills[i]]

      if skill != nil #if skill doesn't exist
        @data.push(skill) #skip to next skill
      end
    end


    # If item count is not 0, make a bit map and draw all items
    @item_max = @data.size
if @item_max > 0
      self.contents = Bitmap.new(width - 32, row_max * 32)
      for i in 0...@item_max
        draw_item(i)
       end
    end
  end


and, in the first part, did this:


if Input.trigger?(Input::C)
  if @window_4.active == true
  #load actor # into game actor slot
@window_4.visible = false
@window_4.active = false
@window_5.refresh (@window_4.index)
@window_5.visible = true
@window_5.active = true
end
end


Global variables make code confusing, difficult to debug, and make it hard to know when or where they are being updated. They should be used sparingly, if at all.

shintashi

#2
Quote from: modern algebra on January 16, 2011, 05:03:29 PM
It's kind of hard to read without the default indenting, but I can see at least two potential problems - the first is: when and where do you call the refresh method of Window_5? The only place I see is the initialize method. Maybe you aren't sharing the whole code, but you will need to call the refresh method somewhere - maybe right before making it visible and active. In order to work, it needs to run.

  if @window_4.active == true
  $win4_actor = true
@window_4.visible = false
@window_4.active = false
@window_5.visible = true
@window_5.active = true
$windex = @window_4.index
  @window_5.refresh


Apologies on the lack of refresh, it was something I added late last night, but the problem you solved:

QuoteSecondly you are saving the ID of the actor into $windex, not his or her party index. Yet, in the refresh method you are going through $game_party.actors. That won't do. In order for it to work, you need to either replace:


$windex = $game_party.actors[@window_4.index].id


with:

$windex = @window_4.index

Fixed that. I also didn't realize my "aluxes" backup actor (used for testing actor numbers out of sequence, since his number in my game is 9, and my main actors are 0 and 1, I use Aluxes to avoid confusing indexes) was also the same class as my primary actor, since I swapped class #1, when I fixed that, it became easier to tell.

Quote
Just for the record, I don't like the way you are using global variables (like $win4_actor and $windex) - it's very difficult to track what values are likely to be in them and it seems like you are just using them to avoid passing any arguments. As a simple little guide: http://c2.com/cgi/wiki?GlobalVariablesAreBad

Global variables make code confusing, difficult to debug, and make it hard to know when or where they are being updated. They should be used sparingly, if at all.

I agree. I hardly ever used a global variable in Flash, but when I'm learning a new programming language, I sometimes use them when I'm going for a 'work damnit!' answer to several hours of failures. The order in which I learned programming languages might explain the problem:
hypercard>qbasic>html/javascript>c>actionscript>java>ruby

i.e. I've seen lots of code and don't understand a damn thing.

Jaffer

Quote from: shintashi on January 16, 2011, 06:23:28 PM
I agree. I hardly ever used a global variable in Flash, but when I'm learning a new programming language, I sometimes use them when I'm going for a 'work damnit!' answer to several hours of failures. The order in which I learned programming languages might explain the problem:
hypercard>qbasic>html/javascript>c>actionscript>java>ruby

i.e. I've seen lots of code and don't understand a damn thing.
That's probably the issue.
I'd suggest reading/applying concepts in irb before trying to make an entire project.  I'm not familiar with the differences in RMXP and RMVX, but I would suggest the following -
For your first scripts, when you're designing them, think about the following: does RM have anything remotely like this already?  Is what I'm doing deep down just a modification of something RM does?  If so, how helpful will their source code be?
Pay attention to when they call refresh methods, how they pass actors from window to window, and how they use attr_accessor/reader methods.  I would much rather see you just set actor to an attr_reader than use a global variable to indicate which you're referring to!

Also, if you know that many languages but are still having issues, you should think about just sitting down with one language, really learning it -- not just the syntax, but the logic behind it, and after really learning two languages, you could pick a new one up in a few weeks.  Just make sure you have a Ruby reference ready in case you can't quite remember something, and have the RM Help File open and double check how you're using the API.