ModAlg Composite Characters - Variable for Hue

Status
Not open for further replies.

HexMozart88

The Master of Random Garbage
Veteran
Joined
May 15, 2016
Messages
1,879
Reaction score
3,349
First Language
English
Primarily Uses
RMVXA
Recently, we've been working with Modern Algebra's Composite Character script, but we noticed one thing and that's the fact that it doesn't take variables as arguments. Only integers. I tried to work with it a bit, and I'm stumped. If someone could make a patch that can make it so that you can input variables as the hue value, that'd be lovely. Thanks in advance.
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,573
Reaction score
6,503
First Language
Indonesian
Primarily Uses
RMVXA
Theoretically, it shouldn't be too hard. But since I can only look at the script and the instruction, I'm not sure what do you mean by hue.

Are you referring to this config in particular?
Code:
#    \cc["filename", i0, h0, o255, z0, r0]
#    \cf["filename", i0, h0, o255, z0, r0]
Or this?
Code:
#      \cf["BackHair1", 3, z-1, h105, r1]
#        This will set it so that the fourth face graphic in the "BackHair1" 
#       faceset will have its hue changed by 105 degrees and then drawn onto 
#       the actor's face graphic. Since it's z is -1, it will be drawn below 
#       anything with a higher z value, including the default face. It's r-code 
#       is 1, so if the actor equips anything else that has an r-code of 1, 
#       this graphic will not show up at all. Since the opacity is not set, it 
#       defaults to 255.
Or both?
 

TheKeeper

Veteran
Veteran
Joined
Dec 23, 2016
Messages
111
Reaction score
24
First Language
English
Primarily Uses
RMVXA
Heyla! I'm Hex's partner in the game we're working on that makes use of this script! I'm going to go with both configs, here, as we may end up using them both in our game.
 

HexMozart88

The Master of Random Garbage
Veteran
Joined
May 15, 2016
Messages
1,879
Reaction score
3,349
First Language
English
Primarily Uses
RMVXA
Currently the main priority is "\add_a12_cc" because we're using it in an event right now, but we're likely going to need the two others.
 

TheKeeper

Veteran
Veteran
Joined
Dec 23, 2016
Messages
111
Reaction score
24
First Language
English
Primarily Uses
RMVXA
So I found out that by changing line 287, which reads as

Ruby:
def self.interpret_composite_graphic_string(string, cg = MA_Composite_Graphic.new("", 0, 0, 255, 0, 0))
to

Ruby:
def self.interpret_composite_graphic_string(string, cg = MA_Composite_Graphic.new("", 0, $game_variables[41], 255, 0, 0))
I can get it to see the hue setting as whatever variable 41 is set to. How can I set this up so that I can use any variable, not just variable 41?

=====EDIT 1=====

All right. So, I did this:

$variable = (0..100)

]def self.interpret_composite_graphic_string(string, cg = MA_Composite_Graphic.new("", 0, $game_variables[$variable], 255, 0, 0))

But now I'm getting an error that says it can't convert an array into an integer. The line it points to is 452 and is the following:

bitmap.hue_change(cg.hue) if cg.hue != 0

So, I'm wondering if there's a way to convert an integer into an array?
 
Last edited:

Roninator2

Gamer
Veteran
Joined
May 22, 2016
Messages
2,649
Reaction score
562
First Language
English
Primarily Uses
RMVXA
You went too far.

The line you had working is fine, but if you want to change the variable as you play the game, that would not make sense.
You are supposed to use a variable for a set purpose not a temporary solution. If a temporary solution then use a variable for multiple settings, but then you will likely run into issues with that.
To allow the variable to be changed without going into the code like on the line you posted, you can use a module.
Ruby:
module Thisisme
    module Maybeilikeasecondone
        Constant_value = 1 # number used for the variable $game_variables[1]
    end
end
to set this up
Ruby:
def self.interpret_composite_graphic_string(string, cg = MA_Composite_Graphic.new("", 0, $game_variables[Thisisme::Maybeilikeasecondone::Constant_value], 255, 0, 0))
Then the code doesn't have to be changed just the number in the module. But this number is set before you start the game and doesn't change.
 

HexMozart88

The Master of Random Garbage
Veteran
Joined
May 15, 2016
Messages
1,879
Reaction score
3,349
First Language
English
Primarily Uses
RMVXA
The issue here is that we need to use multiple variables, not just one. We're using it for a character generator and multiple things need to be changed (hair, eyes, clothing, etc.)

Edit: All of the hue bars in this image are what we're using it for.
Screenshot (333).png
 

TheKeeper

Veteran
Veteran
Joined
Dec 23, 2016
Messages
111
Reaction score
24
First Language
English
Primarily Uses
RMVXA
So I found I could just do this:

def self.interpret_composite_graphic_string(string, cg = MA_Composite_Graphic.new("", 0, $game_variables[0]..$game_variables[1000], 255, 0, 0))

But I still get the error that tells me that an array can't be converted to an integer. I'm guessing that instead of trying to convert the array into an integer, I need to find the integer and convert it into an array. I'm just not sure of two things: 1) how to convert an integer into an array, and 2) what integer needs to be turned into an array.

Be honest: Am I on the right track, or do I need to start over fresh to figure out how to make this work? As Hex pointed out, each variable is tied to the hue of a particular layer type. There's a variable connected to the hue bar for the hair, one connected to the hue bar for the eyes, and one connected to the hue bar for the jumpsuit. I need to set this up so that we can use as many different variables for as many different hue bars as we need for our game. It's driving me crazy that, right now, we can only tell it to use one variable, when I need to be able to tell it to use multiple variables. Hell, if there's a way to just straight up tell it to use variables x, y, and z, I'd settle for that. I just don't know how to do it.

======EDIT 1======

All right, so I recalled the OR operator, and tried this:

def self.interpret_composite_graphic_string(string, cg = MA_Composite_Graphic.new("", 0, $game_variables[41] || $game_variables[51] || $game_variables[50], 255, 0, 0))

So, the idea is that I want it to see variable 41, variable 50, and variable 51 as an appropriate argument for Hue. Now, I can get it to see variable 41, but when I have the second hair layer set to variable 50, it just nopes and reads variable 41. When I use the && operator, it wants me to put in all the variables for the Hue, so that won't work. What am I missing?
 
Last edited:

Another Fen

Veteran
Veteran
Joined
Jan 23, 2013
Messages
564
Reaction score
274
First Language
German
Primarily Uses
Hey there,

You have some right ideas here, but overall I don't think the location is ideal.

You can replace a static number with a variable, but keep in mind that will only use the value of the variable at the moment that command is executed. If you want to change the system so it continuously updates depending on the variable, you probably have to make deeper changes to it.
You can of course also draw from multiple different variables, but you have to structure your code to make it clear when to use which variable.

Not sure if my rambling makes sense here, overall Ruby code should not work that different from an event system:
A possible NPC would give the player potions:
Change Items: Add [Potion] * 5

You can use a variable instead, but it will still only change the players inventory once:
Change Items: Add [Potion] * Variable 0001

You can draw from different variables if you want:
Control Variables: Variable 0001 = 5
Control Variables: Variable 0002 = 7
Control Variables: Variable 0003 = 8

Conditional Branch: Actor1's name is Gerald
__ Change Items: Add [Potion] * Variable 0001
Else
__ Conditional Branch: Actor1's name is Erik
__ __ Change Items: Add [Potion] * Variable 0002
__ Else
__ __ Change Items: Add [Potion] * Variable 0003
__ Branch End

Branch End

How many potions would this NPC give you?
Control Variables: Variable 0001 = 5
Control Variables: Variable 0002 = 7
Control Variables: Variable 0003 = 8

Change Items: Add [Potion] * Variable 0001 OR Variable 0002 OR Variable 0003


So I found out that by changing line 287, which reads as [...] I can get it to see the hue setting as whatever variable 41 is set to.
First, I can't test things right now so I could be wrong here... ^^

The script as a whole seems to be set up so notetags of each actor and equipment entry are only read once when they are first used for a composite graphic.
This means that in your example, if you start a new game and immediately set up variable 41 then the hue change should work for your character. If you "touch" the actor in any way before that point then the graphic should be set in stone and subsequent changes to variable 41 should do nothing. The same problem would probably arise if you later return to the title screen through the menu and start a new game.

So in short, changing line 287 in order to use one variable value should work somehow, but it might become a problem later if you don't set variable 41 early enough.

As an alternate suggestion, it seems you can add custom composite graphics to your actor after the fact with a script command (The 1 in the second line is the actors database ID, :character can be replaced with :face depending on what you want to work with):
cg = MA_Composite_Graphic.new("", 0, 0, 255, 0, 0)
$game_actors[1].macgve_add_cg(:character, cg)



(Though there might be a small bug if you add a composite graphic this way, return to the title menu and start a new game, the added composite graphic might still be present if I'm not mistaken)




So, the idea is that I want it to see variable 41, variable 50, and variable 51 as an appropriate argument for Hue.
In this case you'd still have to specify when you want to use which of these variables in your code, using the information available. One possibility would be to tie that decision to the string that is supposed to be evaluated.
For example, you could extend the start of the method a bit:
Code:
def self.interpret_composite_graphic_string(string, cg = MA_Composite_Graphic.new("", 0, 0, 255, 0, 0))
  if string.include?("v41")
    cg.hue = $game_variables[41]
  elsif string.include?("v50")
    cg.hue = $game_variables[50]
  else
    cg.hue = $game_variables[51]
  end

  # ... Rest of the method

end
(Edit: Code incomplete, see next post)
In this example you would use variable 41 for every composite graphic tag where you added v41 as a parameter in the square brackets, variable 50 where you added v50 and variable 51 for all the others. You can use other information to determine the variable of course, but you can't trust the game to figure out the right variable on its own.

The way the || operator works is "use the first value if it's anything other than false or nil, otherwise use the second value".
Apart from true/false statements the operator is commonly used to create a fallback option. Since nil is the initial value of all variables and can be considered a placeholder for "not existent", you often see statements like
something.list || []
which translates to "use somethings list or an empty array if no list exists (yet)".

In the case of your variables, variable 41 should always have a valid value (including 0), so any "fallback options" would never apply.



(I hope this text does make sense and is somehow helpful, still a bit tired... =) )
 
Last edited:

TheKeeper

Veteran
Veteran
Joined
Dec 23, 2016
Messages
111
Reaction score
24
First Language
English
Primarily Uses
RMVXA
Hey there,

You have some right ideas here, but overall I don't think the location is ideal.

You can replace a static number with a variable, but keep in mind that will only use the value of the variable at the moment that command is executed. If you want to change the system so it continuously updates depending on the variable, you probably have to make deeper changes to it.
You can of course also draw from multiple different variables, but you have to structure your code to make it clear when to use which variable.

Not sure if my rambling makes sense here, overall Ruby code should not work that different from an event system:
A possible NPC would give the player potions:
Change Items: Add [Potion] * 5

You can use a variable instead, but it will still only change the players inventory once:
Change Items: Add [Potion] * Variable 0001

You can draw from different variables if you want:
Control Variables: Variable 0001 = 5
Control Variables: Variable 0002 = 7
Control Variables: Variable 0003 = 8

Conditional Branch: Actor1's name is Gerald
__ Change Items: Add [Potion] * Variable 0001
Else
__ Conditional Branch: Actor1's name is Erik
__ __ Change Items: Add [Potion] * Variable 0002
__ Else
__ __ Change Items: Add [Potion] * Variable 0003
__ Branch End

Branch End

How many potions would this NPC give you?
Control Variables: Variable 0001 = 5
Control Variables: Variable 0002 = 7
Control Variables: Variable 0003 = 8

Change Items: Add [Potion] * Variable 0001 OR Variable 0002 OR Variable 0003



First, I can't test things right now so I could be wrong here... ^^

The script as a whole seems to be set up so notetags of each actor and equipment entry are only read once when they are first used for a composite graphic.
This means that in your example, if you start a new game and immediately set up variable 41 then the hue change should work for your character. If you "touch" the actor in any way before that point then the graphic should be set in stone and subsequent changes to variable 41 should do nothing. The same problem would probably arise if you later return to the title screen through the menu and start a new game.

So in short, changing line 287 in order to use one variable value should work somehow, but it might become a problem later if you don't set variable 41 early enough.

As an alternate suggestion, it seems you can add custom composite graphics to your actor after the fact with a script command (The 1 in the second line is the actors database ID, the 0 is the type of the composite graphic if needed):
cg = MA_Composite_Graphic.new("", 0, 0, 255, 0, 0)
$game_actors[1].macgve_add_cg(0, cg)



(Though there might be a small bug if you add a composite graphic this way, return to the title menu and start a new game, the added composite graphic might still be present if I'm not mistaken)




In this case you'd still have to specify when you want to use which of these variables in your code, using the information available. One possibility would be to tie that decision to the string that is supposed to be evaluated.
For example, you could extend the start of the method a bit:
Code:
def self.interpret_composite_graphic_string(string, cg = MA_Composite_Graphic.new("", 0, 0, 255, 0, 0))
  if string.include?("v41")
    cg.hue = $game_variables[41]
  elsif string.include?("v50")
    cg.hue = $game_variables[50]
  else
    cg.hue = $game_variables[51]
  end

  # ... Rest of the method

end
In this example you would use variable 41 for every composite graphic tag where you added v41 as a parameter in the square brackets, variable 50 where you added v50 and variable 51 for all the others. You can use other information to determine the variable of course, but you can't trust the game to figure out the right variable on its own.

The way the || operator works is "use the first value if it's anything other than false or nil, otherwise use the second value".
Apart from true/false statements the operator is commonly used to create a fallback option. Since nil is the initial value of all variables and can be considered a placeholder for "not existent", you often see statements like
something.list || []
which translates to "use somethings list or an empty array if no list exists (yet)".

In the case of your variables, variable 41 should always have a valid value (including 0), so any "fallback options" would never apply.



(I hope this text does make sense and is somehow helpful, still a bit tired... =) )

Heyla!

First of all, thank you, so much, for the reply! I am in literal tears trying to figure this whole thing out! So I tried your suggestion:

Code:
def self.interpret_composite_graphic_string(string, cg = MA_Composite_Graphic.new("", 0, 0, 255, 0, 0))
  if string.include?("v41")
    cg.hue = $game_variables[41]
  elsif string.include?("v50")
    cg.hue = $game_variables[50]
  else
    cg.hue = $game_variables[51]
  end

  # ... Rest of the method

end
And I'm now getting the following error: 1584740817902.png

Here is a screenshot of how I put the code in:

1584740904374.png

Here's a screenshot of the event:

1584740937999.png

Where did I make the mistake?
 

Another Fen

Veteran
Veteran
Joined
Jan 23, 2013
Messages
564
Reaction score
274
First Language
German
Primarily Uses
You were right, the error was on my end (again) I fear...
I forgot that the method works with either a MA_Composite_Graphic object or a Hash. Which makes the example code a bit more bloated: :)
Code:
if cg.is_a?(Hash)
  if string.include?("v41")
    cg[:hue] = $game_variables[41]
  elsif string.include?("v50")
    cg[:hue] = $game_variables[50]
  else
    cg[:hue] = $game_variables[51]
  end
elsif cg.is_a?(MA_Composite_Graphic)
  if string.include?("v41")
    cg.hue = $game_variables[41]
  elsif string.include?("v50")
    cg.hue = $game_variables[50]
  else
    cg.hue = $game_variables[51]
  end
end
Although I would still not really recommend using this approach, even though it happens to work here. The main reason being that if touching the actor early (for example by checking their stats before setting the variable) can break the hue change, chances are that if that was to happen in a few months it might be a headache searching for the exact culprit.

If you want to set the hue later I'd still recommend the script command from the previous section over this.

(Sorry for not testing my suggestions, don't have the RPGMaker installed on this PC yet)
 
Last edited:

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,573
Reaction score
6,503
First Language
Indonesian
Primarily Uses
RMVXA
So, the idea is that I want it to see variable 41, variable 50, and variable 51 as an appropriate argument for Hue.
I still don't get this idea.
Hue is a scalar value, it's a single integer value.
If you, say, want to use 3 game variables. 41, 50, and 51.

The value of variable 41 = 100
The value of variable 50 = 30
The value of variable 51 = 90

How is the end result going to be?
 

TheKeeper

Veteran
Veteran
Joined
Dec 23, 2016
Messages
111
Reaction score
24
First Language
English
Primarily Uses
RMVXA
You were right, the error was on my end (again) I fear...
I forgot that the method works with either a MA_Composite_Graphic object or a Hash. Which makes the example code a bit more boated: :)
Code:
if cg.is_a?(Hash)
if string.include?("v41")
cg[:hue] = $game_variables[41]
elsif string.include?("v50")
cg[:hue] = $game_variables[50]
else
cg[:hue] = $game_variables[51]
end
elsif cg.is_a?(MA_Composite_Graphic)
if string.include?("v41")
cg.hue = $game_variables[41]
elsif string.include?("v50")
cg.hue = $game_variables[50]
else
cg.hue = $game_variables[51]
end
end
Although I would still not really recommend using this approach, even though it happens to work here. The main reason being that if touching the actor early (for example by checking their stats before setting the variable) can break the hue change, chances are that if that was to happen in a few months it might be a headache searching for the exact culprit.

If you want to set the hue later I'd still recommend the script command from the previous section over this.

(Sorry for not testing my suggestions, don't have the RPGMaker installed on this PC yet)
Okay, first, your new code works like a charm! The hue changes are going into effect for the hue bars associated with those variables. Yay! Thank you, so much!

Second, I'll admit that I didn't quite understand how to implement your initial suggestion. You said that one is a better fix for what we're trying to do? How does it work?

I still don't get this idea.
Hue is a scalar value, it's a single integer value.
If you, say, want to use 3 game variables. 41, 50, and 51.

The value of variable 41 = 100
The value of variable 50 = 30
The value of variable 51 = 90

How is the end result going to be?
The end result would be the following:

Hue for the hair layer would be whatever color associated with 100
Hue for the jumpsuit layer would be whatever color associated with 30
Hue for the eyes layer would be whatever color associated with 90
 

Another Fen

Veteran
Veteran
Joined
Jan 23, 2013
Messages
564
Reaction score
274
First Language
German
Primarily Uses
Second, I'll admit that I didn't quite understand how to implement your initial suggestion.
Might be because I messed that one up too... Fixed the code above. =)

The script command would be an option to use instead of a comment, which would allow you to use Ruby code for all parameters you need without modifying the original script.

So you could replace this comment for example...
\add_a12_cc["male bun", i0, v41]

...with a script command:
cg = MA_Composite_Graphic.new("male bun", 0, $game_variables[41], 255, 0, 0)
$game_actors[12].macgve_add_cg(:character, cg)


or if you prefer to use a Hash (allows you to skip the rest of the parameters):
cg = { :filename => "male bun", :index => 0, :hue => $game_variables[41] }
$game_actors[12].macgve_add_cg(:character, cg)




Although I originally assumed you would need to use the variable option in the notebox of an actor or item in the database. If you are using event comments to add more parts after the variable has already been set then my concerns about these tags being translated too early should not apply.

The code from my last post is a bit simplified, which also means that the code will recognize a "v41" or "v50" when it's part of the filename. If you want to properly stick with the script solution you may want to instead mimic Modern Algebras approach here, which would only require one additional line per type and allow for any variable to be used instead of just 3:

string.sub!(/["'](.+)["']/) { cg[:filename] = $1; "" } # Filename: ""
string.sub!(/[Zz](-?\d+)/) { cg[:z] = $1.to_i; "" } # Z: 0
string.sub!(/[Hh](\d+)/) { cg[:hue] = $1.to_i; "" } # Hue: 0
string.sub!(/[Oo](\d+)/) { cg[:opacity] = $1.to_i; "" } # Opacity: 255
string.sub!(/[Rr](\d+)/) { cg[:rcode] = $1.to_i; "" } # R-Code: 0
string.sub!(/[Vv](\d+)/) { cg[:hue] = $game_variables[$1.to_i]; "" } # Hue by Variable
string.sub!(/[Ii]?(\d+)/) { cg[:index] = $1.to_i; "" } # Index: 0


(The same change would have to be done for the MA_Composite_Graphic version in the same method)

string.sub! works here by searching the string for a pattern (in the added case a 'V' or 'v' followed by one or more (+) digits (\d)), using the found digits as the variable index and finally deleting the found sequence (replacing with "") so it does not interfere with the following patterns.
 
Last edited:

TheKeeper

Veteran
Veteran
Joined
Dec 23, 2016
Messages
111
Reaction score
24
First Language
English
Primarily Uses
RMVXA
Oh! I see! That makes a whole lot more sense, now! Thank you!

=====EDIT 1=====

Went in and tried it with the unmodified script, and you're right! It worked like a charm! That really was the simplest solution, and gives us much more flexibility! Thank you, so much!

=====EDIT 2=====

So I also tried the script with the code that allowed for the use of any variables for the hue, and that worked, too! This is what I put for the code:

Ruby:
    def self.interpret_composite_graphic_string(string, cg = MA_Composite_Graphic.new("", 0, 0, 255, 0, 0))
      if cg.is_a?(Hash)
        string.sub!(/["'](.+)["']/) { cg[:filename] = $1;    "" } # Filename: ""
        string.sub!(/[Zz](-?\d+)/) { cg[:z] = $1.to_i;       "" } # Z:         0
        string.sub!(/[Hh](\d+)/)   { cg[:hue] = $1.to_i;     "" } # Hue:       0
        string.sub!(/[Vv](\d+)/)   { cg[:hue] = $game_variables[$1.to_i]; "" } # Hue by Variable
        string.sub!(/[Oo](\d+)/)   { cg[:opacity] = $1.to_i; "" } # Opacity: 255
        string.sub!(/[Rr](\d+)/)   { cg[:rcode] = $1.to_i;   "" } # R-Code:    0
        string.sub!(/[Ii]?(\d+)/)  { cg[:index] = $1.to_i;   "" } # Index:     0
      elsif cg.is_a?(MA_Composite_Graphic)
        string.sub!(/["'](.+)["']/) { cg.filename = $1;     "" }  # Filename: ""
        string.sub!(/[Zz](-?\d+)/)  { cg.z = $1.to_i;       "" }  # Z:         0
        string.sub!(/[Hh](\d+)/)    { cg.hue = $1.to_i;     "" }  # Hue:       0
        string.sub!(/[Vv](\d+)/)    { cg.hue = $game_variables[$1.to_i]; "" } # Hue by Variable
        string.sub!(/[Oo](\d+)/)    { cg.opacity = $1.to_i; "" }  # Opacity: 255
        string.sub!(/[Rr](\d+)/)    { cg.rcode = $1.to_i;   "" }  # R-Code:    0
        string.sub!(/[Ii]?(\d+)/)   { cg.index = $1.to_i;   "" }  # Index:     0
      end
      cg
    end
  end
Thank you, so much, for giving us so many different ways to approach the issue!
 
Last edited:

Touchfuzzy

Rantagonist
Staff member
Lead Eagle
Joined
Feb 28, 2012
Messages
7,280
Reaction score
8,858
First Language
English
Primarily Uses
RMMZ

This thread is being closed, due to being solved. If for some reason you would like this thread re-opened, please report this post and leave a message why. Thank you.

 
Status
Not open for further replies.

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Just finished composing a boss battle theme!
Scripted a multi-variable weather system that randomizes wind speed, cloudiness, rain, fogginess, etc, while attempting to realistically account for interactions between them (e.g. wind speed affects fogginess, cloudiness affects rain, etc), the current weather pattern, and the player's biome e.g. swamp, beach, etc. Now I "just" have to tie visuals and sounds to the variables so stuff actually happens...
I'm having a headache balancing the combat using flat defense so I'm gonna use percentual armor, in this pic, Simon has 16 on Defense which means all the incoming damage will be reduced by 16% this will ease my burden a bit.
!Have a nice day everybody¡
SO glad they patched outer worlds for switch! I can finally play it! Weird that other peeps are still having issues. I know it was really chugging on my lite when it first came out.

Forum statistics

Threads
105,556
Messages
1,014,638
Members
137,236
Latest member
Crowned_gaming_youtube
Top