Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Alignment Modifiers
#1
"The Alignment Modifier"
Mister C Major
May 1 2007

This is a locked, single-post thread from Creation Asylum. Archived here to prevent its loss.
No support is given. If you are the owner of the thread, please contact administration.


Hello everyone,

This time I will be uploading a small system which I developed that can add a great deal of game play (and even replay value!) into your game. I call it, "The Alignment Modifier". The system entails the following; dependant if your character uses physical (attack) or magic (skills), their alignment modifier gets shifted making them more attuned with their physical/magical abilities, by doing so, one can have a preset list of skills which a character can learn if their physically or magically affiliated, one can even determine which classes he has the option of evolving to. This system can relate to Secret of Mana 2 involving class changing, and Knights of the Republic involving Light/Dark Side skills.

In this post I will only show the steps to making the alignment modifier, as well as the way to visually represent it. I will not add the scripts to affect Skill and Class Changing just yet since this post has already reached an absurd size.

Before we can begin with the code, we are going to need to alter some of the default RMXP Script. We are first going to look at the Game_Actor Class.
Since we are adding another attribute to each of our Actors (Party Characters Defined in the Hero page of the Database), we are going to have to add the following to our list of attr_readers. Note that it must read "attr_accessor: alignment" and not "attr_reader: alignment" since we will be manipulating the alignment mathematically, not just reading it.


Code:
attr_accessor: alignment



Next we will need to add a method controlling the max and min values of our alignment attribute. The method can be added anywhere within the class, I like to add any custom methods right below my initialize method. This method states that the class variable @alignment can not exceed 500 or fall below -500. If the variable does fall below -500, it will be reversed back to -500, the same applies if the variable exceeds 500, it will reverse to 500.
Code:
def alignment
  @alignment = [[@alignment, -500].max, 500].min
end




Lastly also need to make one adjustment to the method setup within the same class. Just simply add the line @alignment = 0, into the method setup. preferably next to all the other class variables being initialized.
Code:
def setup(actor_id)




Each character now has an Alignment Modifier which can be edited by the following, $game_party.actors[actor_id].alignment. For example, the following will increase Arshes' alignment by 100.

Code:
@game_party.actors[0] += 100




Code Explanation
The code is rather short and doesn't require much explanation. From here on we can simply manipulate the alignment modifier of any character, meaning we are now able to create much more advanced functions needing an alignment modifier. The values -500 and 500 that I chose are simple the min and max of my alignment. The values can be 0 to 1000, -100 to 100, or even 0 to 9999. i chose the values -500 and 500 to make it easier for me to tell how far my character's alignment is towards the Physical, and Magical (Magical being -500, and Physical being 500), and having a high number such as 500 will make my player need to spend some time tuning his characters. With an average amount of 5 attacks per battle, 100 battle will be necessary to perfectly attune his character to either alignment, assuming he starts the character at 0.


Visually Representing the Alignment Modifier

[Image: alignmentexampledp1.png]
The four bars that are colored yellow is the only thing that interests us right now. What is being shown is four characters all with unique values for their alignment modifiers, Arshes has approximately 500, Dorothy and Felix 250, and Gloria with -250. The code to do this is partly complex because it requires you to keep track of a few variables at any givin time but I'll try my best to explain it. First I have to give credit to SephirothSpawn for teaching me the basics of "gradient bars."

Here is the code JUST FOR THE ALIGNMENT BARS, first add on a few things to the Window_MenuStatus Class.

Code:
class Window_MenuStatus < Window_Base
  def refresh
    draw_alignment_bar(x+208, y+70,actor.alignment, 152, 6,Color.new(255,255,0, 255), Color.new(188,188,0, 255))  #The x and y coordinates, and the values for the colors can be edited
  end


then add in this method into the Window_Base class,

Code:
def draw_alignment_bar(x, y, alignment, width, height, bar_color, end_color)  #The color values can be edited
  for i in 1..height
    self.contents.fill_rect(x + i, y + height - i, width, 1, Color.new(50, 50, 50, 255))  #The color values can be edited
  end
  for i in 1..(height - 2)
    r = - 100 / (height - 2 + 1) * i + 100
    g = - 100 / (height - 2 + 1) * i + 100
    b = - 100 / (height - 2 + 1) * i + 100
    a = 255
    self.contents.fill_rect(x + i + 2, y + height - 1 - i, width-2, 1, Color.new(r, b, g, a))
  end
  if alignment>=0
    flag=true
  else
    alignment = -alignment
  end
  for i in 1..( (alignment / 1000.to_f) * width - 3)
    for j in 1..(height - 2)
      r = bar_color.red * (width - i) / width + end_color.red * i / width
      g = bar_color.green * (width - i) / width + end_color.green * i / width
      b = bar_color.blue * (width - i) / width + end_color.blue * i / width
      a = bar_color.alpha * (width - i) / width + end_color.alpha * i / width
      if flag == true
        self.contents.fill_rect(x + width / 2 + 2 + i + j, y + height - 1 - j, 1, 1, Color.new(r, g, b, a))
      else
        self.contents.fill_rect(x + width / 2 + 2 - i + j, y + height - 1 - j, 1, 1, Color.new(r, g, b, a))
      end
    end
  end
end



Code Explanation

This is where the difficulty sets in...this method can be split up into two different sections,

the one that draws the bar and shades in the background of the bar (empty bar),
Code:
for i in 1..height
  self.contents.fill_rect(x + i, y + height - i, width, 1, Color.new(50, 50, 50, 255))  #The color values can be edited
end
for i in 1..(height - 2)
  r = - 100 / (height - 2 + 1) * i + 100
  g = - 100 / (height - 2 + 1) * i + 100
  b = - 100 / (height - 2 + 1) * i + 100
  a = 255
  self.contents.fill_rect(x + i + 2, y + height - 1 - i, width-2, 1, Color.new(r, b, g, a))
end



and the code that draws in the yellow bar,
Code:
if alignment>=0
  flag=true
else
  alignment = -alignment
end
for i in 1..( (alignment / 1000.to_f) * width - 3)
  for j in 1..(height - 2)
    r = bar_color.red * (width - i) / width + end_color.red * i / width
    g = bar_color.green * (width - i) / width + end_color.green * i / width
    b = bar_color.blue * (width - i) / width + end_color.blue * i / width
    a = bar_color.alpha * (width - i) / width + end_color.alpha * i / width
    if flag == true
      self.contents.fill_rect(x + width / 2 + 2 + i + j, y + height - 1 - j, 1, 1, Color.new(r, g, b, a))
    else
      self.contents.fill_rect(x + width / 2 + 2 - i + j, y + height - 1 - j, 1, 1, Color.new(r, g, b, a))
    end
  end
end




Note, notice how the x, y, width, height, the bar_color, and the end_color a few of the colors are defined with the function is called in the Window_MenuStatus Class. The x and y coordinates will not change the presentation of the bar, only its coordinate location so we wont worry about explaining x and y at this time.


We will first explain the first code, the empty bar (also known as the frame).

The following code draws the frame of the bar. Lets go through the steps together, lets let x = 0, y = 0, height = 6 and width = 30. So, as shown by the code, it will produce the following,
Code:
for i in 1..height
  self.contents.fill_rect(x + i, y + height - i, width, 1, Color.new(50, 50, 50, 255))  #The color values can be edited
end



at i = 1, we will get a rectangle at the coordinate (1,5), 30 pixels wide, and 1 pixel high, with a grayish color;
at i = 2, we will get a rectangle at the coordinate (2,4), 30 pixels wide, and 1 pixel high, with a grayish color;
at i = 3, we will get a rectangle at the coordinate (3,3), 30 pixels wide, and 1 pixel high, with a grayish color;
at i = 4, we will get a rectangle at the coordinate (4,2), 30 pixels wide, and 1 pixel high, with a grayish color; and
at i = 5, we will get a rectangle at the coordinate (5,1), 30 pixels wide, and 1 pixel high, with a grayish color.

You will get an image looking like the following,
[Image: barxc5.png]

Now for the next for function, notice how the i has changed its starting and ending number, from 1 to height, to 1 to height - 2, the width is 2 pixels shorter, the x coordinate is shifted right by 2, the y coordinate has shifted up by 1, and there are only 4 instances of i. From this comparison we are able to get a very good picture
Code:
for i in 1..(height - 2)
  r = - 100 / (height - 2 + 1) * i + 100
  g = - 100 / (height - 2 + 1) * i + 100
  b = - 100 / (height - 2 + 1) * i + 100
  a = 255
  self.contents.fill_rect(x + i + 2, y + height - 1 - i, width-2, 1, Color.new(r, b, g, a))
end


at i = 1, we have a rectangle at coordinate (3,4), 28 pixels wide, 1 pixel high, with the color (80, 80,80,255),
at i = 2, we have a rectangle at coordinate (4,3), 28 pixels wide, 1 pixel high, with the color (60, 60, 60, 255),
at i = 3, we have a rectangle at coordinate (5,2), 28 pixels wide, 1 pixel high, with the color (40, 40, 40,255),
at i = 4, we have a rectangle at coordinate (6,1), 28 pixels wide, 1 pixel high, with teh color (20, 20, 20,255), giving you a horizontal gradient.
[Image: emptybaryh4.png]
The equation r = -100 / (height - 2 +1) * i +100 is just a fancy way of saying, "I want my gradient to decrease evenly." The drawable lines, height - 2, gives us 4, however we dont want the last line i = 4 to have a value of 0; there fore we added the plus 1, and the hundred just manipulates where the starting point will be at. Try experimenting by changing the -100 to another negative value and the 100 to any positive value.

Lastly the yellow bar, and the most complicated. Lets start with the following code,
Code:
for i in 1..( (alignment / 1000.to_f) * width - 3)
  for j in 1..(height - 2)
    r = bar_color.red * (width - i) / width + end_color.red * i / width
    g = bar_color.green * (width - i) / width + end_color.green * i / width
    b = bar_color.blue * (width - i) / width + end_color.blue * i / width
    a = bar_color.alpha * (width - i) / width + end_color.alpha * i / width
    if flag == true
      self.contents.fill_rect(x + width / 2 + 2 + i + j, y + height - 1 - j, 1, 1, Color.new(r, g, b, a))
    else
      self.contents.fill_rect(x + width / 2 + 2 - i + j, y + height - 1 - j, 1, 1, Color.new(r, g, b, a))
    end
  end
end


What the Yellow bar represents (as well as the red and blue bars) is a percentage. Dependant on the percentage of two numbers, the bar is filled part way, this can be approached two ways, this way is hopefully the simpler of the two.. If there is 50%, the bar is filled 50%. This is accomplished by the first line. Since my alignment is between -500 and positive 500, the total base is 1000. The total horizontal colored area is going to be the percantage times the width minus two, the minus two takes effect by not counting the pixel on the left and the right which acts as a black border.

Code:
for i in 1..( (alignment / 1000.to_f) * width - 2)


Now, since this gradient operates diagnally one pixel at a time, for every i, there must be (height - 2) j (four). Something to note, since the coloring of alignment doesn't begin at an end point, we must pass a flag, to let the script now if the alignment is coloring left, or right, or in our case, if the alignment is negative or positive. If positive, the flag is passed as true, and the first statement is ran notice that the only difference between the two statements is the change from a plus to a minus sign in front of the "i".
Code:
if alignment>=0
  flag=true
else
  alignment = -alignment
end


if flag == true
  self.contents.fill_rect(x + width / 2 + 2 + i + j, y + height - 1 - j, 1, 1, Color.new(r, g, b, a))
else
  self.contents.fill_rect(x + width / 2 + 2 - i + j, y + height - 1 - j, 1, 1, Color.new(r, g, b, a))
end



Lets calculate a few pixels to provide as an example, let x = 0, y = 0, width = 10, height = 6,bar_color= Color.new (255,255,0,255), end_color = (100,100,0,255).
For i = 1, and j = 1, x = 4, y = 4, Color(240, 240, 0, 255),
for i = 1, and j = 2, x = 5, y = 3, Color(240, 240, 0, 255),
for i = 1, and j = 3, x = 6, y = 2, Color(240, 240, 0, 255),
for i = 1, and j = 4, x = 7, y = 1, Color(240, 240, 0, 255),
For i = 2, and j = 1, x = 5, y = 4, Color(224, 224, 0, 255),
for i = 2, and j = 2, x = 6, y = 3, Color(224, 224, 0, 255),
for i = 2, and j = 3, x = 7, y = 2, Color(224, 224, 0, 255),
for i = 2, and j = 4, x = 8, y = 1, Color(224, 224, 0, 255), so we will get the following,
(Pic no longer exists)

Ok, so if you were able to understand all that, you would have no problems editing this code to fit any needs you might have, but if you're not that adept with code, or just plain lazy, just follow the copy past instructions below and I'll explain just the basics of what you would need to change.



The Alignment Modifier Code


Compatability

Unless your game no longer used the Game_Actor, Game_Battle, or the Window_Base Class, this script should work.

I hope I didnt forget anything, please enjoy, and as always, if you find any problems or have any recommendations on how else I should word my posts to help teach it better, please let me know.
Happy Coding!
}




Users browsing this thread: