I am planning to make a CMS & a CBS over the summer, but i know very little about scripting, and as all the tutorials don't explain far enough to really help me I was wondering if anyone was willing to let me look at some work that they did, I will use any level of confidentiality you require, so that i can examine it and get a feel for how to do it myself.
Some specific topics i need help with are:
CMS
-Horizontal menu, as in [option1][option2]...[optionN]
-basic menu selection with a horizontal menu, i pretty much have it for vertical...
-how to make menu selections without text, like having the sprites for each character instead of text for the menu selections.
CBS
-player positioning
-HP/SP bars and all their options
-how to edit battle formulas
-how to make a moving battle (possibly, may not use it)
-much more stats
-I would like to eventually make a system similar to the Djinni/Summon/Standby system from golden sun, so if you have any hints/suggestions as to how to get this mechanic working it would be greatly appreciated.
A big thanks in advance to anyone who decides to help.
I would also appreciate if you could link me to some games that aren't encrypted and use CMS/CBS that I could look at, because I can't find any.
*bump*
WOW. So I guess no-one wants to help me out...On a side note I would like to add that once I do learn how to script I will use my new skills to help others with CBS's and CMS's so please help me learn how to do them!
I'll see what I can do.
First, here is a CMS with horizontal text. I don't know who made it, I wish I did. It actually has a bug in it that I found, but that shouldn't inhibit your ability to learn from it.
1& 2:
class Scene_Menu
def initialize(menu_index = 0)
@menu_index = menu_index
end
def main
s1 = $data_system.words.item
s2 = " Abilities"
s3 = " Equip"
s4 = " Status"
s5 = " Save"
s6 = " Quests"
s7 = " Exit"
@dummy_window = Window_Base.new(0, 0, 640, 60)
@command_window = Menu_Command.new(640, [s1, s2, s3, s4, s5, s6, s7])
@command_window.index = @menu_index
@command_window.width = 700
@command_window.height = 500
if $game_party.actors.size == 0
@command_window.disable_item(0)
@command_window.disable_item(1)
@command_window.disable_item(2)
@command_window.disable_item(3)
end
if $game_system.save_disabled
@command_window.disable_item(4)
end
#-------- Edits -----------------------------------------------------------------
# Position status window next to commands
@status_window = Window_MenuStatus.new
@status_window.x = 0
@status_window.y = 60
# Position play time next to commands and below status
@playtime_window = Window_PlayTime.new
@playtime_window.x = 480
@playtime_window.y = 75
@steps_window = Window_Steps.new
@steps_window.x = 480
@steps_window.y = 175
@gold_window = Window_Gold.new
@gold_window.x = 480
@gold_window.y = 275
@map_window = Window_Map.new
@map_window.x = 480
@map_window.y = 375
#-------- /Edits -----------------------------------------------------------------
Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
@command_window.dispose
@playtime_window.dispose
@steps_window.dispose
@gold_window.dispose
@map_window.dispose
@status_window.dispose
@dummy_window.dispose
end
def update
@dummy_window.update
@command_window.update
@playtime_window.update
@steps_window.update
@gold_window.update
@status_window.update
if @command_window.active
update_command
return
end
if @status_window.active
update_status
return
end
end
def update_command
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
$scene = Scene_Map.new
return
end
if Input.trigger?(Input::C)
if $game_party.actors.size == 0 and @command_window.index < 4
$game_system.se_play($data_system.buzzer_se)
return
end
case @command_window.index
when 0 # ????
# ?? SE ???
$game_system.se_play($data_system.decision_se)
# ???????????
$scene = Scene_Item.new
when 1 # ???
# ?? SE ???
$game_system.se_play($data_system.decision_se)
# ???????????????????
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 2 # ??
# ?? SE ???
$game_system.se_play($data_system.decision_se)
# ???????????????????
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 3 # ?????
# ?? SE ???
$game_system.se_play($data_system.decision_se)
# ???????????????????
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 4 # ???
# ????????
if $game_system.save_disabled
# ??? SE ???
$game_system.se_play($data_system.buzzer_se)
return
end
# ?? SE ???
$game_system.se_play($data_system.decision_se)
# ??????????
$scene = Scene_Save.new
when 5
$game_system.se_play($data_system.decision_se)
$scene = Scene_Quest.new
when 6 # ?????
# Play Sound Effect
$game_system.se_play($data_system.decision_se)
# Exit Scene
$scene = Scene_End.new
end
return
end
end
#--------------------------------------------------------------------------
# ? ?????? (???????????????????)
#--------------------------------------------------------------------------
def update_status
# B ??????????
if Input.trigger?(Input::B)
# ????? SE ???
$game_system.se_play($data_system.cancel_se)
# ??????????????????
@command_window.active = true
@status_window.active = false
@status_window.index = -1
return
end
# C ??????????
if Input.trigger?(Input::C)
# ???????????????????
case @command_window.index
when 1 # ???
# ???????????? 2 ?????
if $game_party.actors[@status_window.index].restriction >= 2
# ??? SE ???
$game_system.se_play($data_system.buzzer_se)
return
end
# ?? SE ???
$game_system.se_play($data_system.decision_se)
# ??????????
$scene = Scene_Skill.new(@status_window.index)
when 2 # ??
# ?? SE ???
$game_system.se_play($data_system.decision_se)
# ?????????
$scene = Scene_Equip.new(@status_window.index)
when 3 # ?????
# ?? SE ???
$game_system.se_play($data_system.decision_se)
# ????????????
$scene = Scene_Status.new(@status_window.index)
end
return
end
end
end
#==============================================================================
class Window_MenuStatus < Window_Selectable
def initialize
super(0, 0, 480, 480 - 59)
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.font.name = $fontface# "Main" window font
self.contents.font.size = $fontsize
refresh
self.active = false
self.index = -1
end
def refresh
self.contents.clear
@item_max = 4#$game_party.actors.size
@column_max = 4#$game_party.actors.size
for i in 0...$game_party.actors.size
actor = $game_party.actors[i]
x = self.contents.width / 4 * i + 5
y = 0
row_width = self.contents.width / 4 - 10
row_space = self.contents.font.size
# Colorize
self.contents.fill_rect(x - 5, y, self.contents.width / 4, self.contents.height, Color.new(255, 255, 255, 20 * i))
# Draw name
self.contents.font.size += 2
self.contents.draw_text(x, y, row_width, row_space + 2, actor.name)
self.contents.font.size -= 2
# Draw stats
self.contents.font.color = system_color
self.contents.draw_text(x + 0, 145, 56, 32, "Experience")
self.contents.font.color = normal_color
self.contents.draw_text(x, 6 + y + 6 * row_space, row_width, row_space, actor.exp.to_s, 2)
#draw a character
draw_actor_graphic(actor, x + 10, 70)
# draw hp
self.contents.font.color = system_color
self.contents.draw_text(x + 0, 64, 32, 32, "Health")
self.contents.font.color = actor.hp == 0 ? knockout_color :
actor.hp <= actor.maxhp / 4 ? crisis_color : normal_color
self.contents.draw_text(x - 15, 85, 48, 32, actor.hp.to_s, 2)
self.contents.font.color = normal_color
self.contents.draw_text(x + 35, 85, 12, 32, "/", 1)
self.contents.draw_text(x + 50 , 85, 48, 32, actor.maxhp.to_s)
#draw sp
self.contents.font.color = system_color
self.contents.draw_text(x + 0, 100, 32, 32, "Mana")
self.contents.font.color = actor.sp == 0 ? knockout_color :
actor.sp <= actor.maxsp / 4 ? crisis_color : normal_color
self.contents.draw_text(x - 15, 120, 48, 32, actor.sp.to_s, 2)
self.contents.font.color = normal_color
self.contents.draw_text(x + 35, 120, 12, 32, "/", 1)
self.contents.draw_text(x + 50, 120, 48, 32, actor.maxsp.to_s)
#hp and sp
end
# Draw battlers over colorized.
for i in 0...$game_party.actors.size
actor = $game_party.actors[i]
x = self.contents.width / 4 * i
y = 0
row_width = self.contents.width / 4 - 10
row_space = self.contents.font.size
actor_battler = RPG::Cache.battler(actor.battler_name, actor.battler_hue)
battler_y = 6 + y + 6 * row_space
self.contents.blt(x, [battler_y, self.contents.height - actor_battler.height].max, actor_battler, Rect.new(0, 0, actor_battler.width, self.contents.height - battler_y))
end
end
def update_cursor_rect
if @index < 0
self.cursor_rect.empty
else
x = self.contents.width / 4 * @index
row_width = self.contents.width / 4
self.cursor_rect.set(x, 0, row_width, self.contents.height)
end
end
end
And here is the horizontal thingy
#=================================================
# ?¡ Menu_Selectable
#------------------------------------------------------------------------------
#
#=================================================
class Menu_Selectable < Window_Base
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
attr_reader :index # ƒJ?[ƒ\ƒ‹ˆÊ'u
attr_reader :help_window # ƒwƒ‹ƒvƒEƒBƒ"ƒhƒE
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def initialize(x, y, width, height)
super(x, y, width, height)
@item_max = 1
@column_max = 1
@index = -1
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def index=(index)
@index = index
# ƒwƒ‹ƒvƒeƒLƒXƒg,ð?X?V (update_help ,ÍŒp?³?æ,Å'è‹`,³,ê,é)
if self.active and @help_window != nil
update_help
end
# ƒJ?[ƒ\ƒ‹,Ì‹éŒ`,ð?X?V
update_cursor_rect
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def row_max
return (@item_max + @column_max - 1) / @column_max
end
#--------------------------------------------------------
#--------------------------------------------------------------------------
def top_row
return self.oy / 32
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def top_row=(row)
# When a row is below 0, it is changed to 0.
if row < 0
row = 0
end
if row > row_max - 1
row = row_max - 1
end
self.oy = row * 32
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def page_row_max
return (self.height - 32) / 32
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def page_item_max
return page_row_max * @column_max
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def help_window=(help_window)
@help_window = help_window
if self.active and @help_window != nil
update_help
end
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def update_cursor_rect
if @index < 0
self.cursor_rect.empty
return
end
row = @index / @column_max
if row < self.top_row
self.top_row = row
end
if row > self.top_row + (self.page_row_max - 1)
self.top_row = row - (self.page_row_max - 1)
end
cursor_width = self.width / @column_max - 32
x = @index % @column_max * (cursor_width + 32)
y = @index / @column_max * 86
self.cursor_rect.set(y, x, 86, 32)
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def update
super
if self.active and @item_max > 0 and @index >= 0
if Input.repeat?(Input::RIGHT)
if (@column_max == 1 and Input.trigger?(Input::LEFT)) or
@index < @item_max - @column_max
$game_system.se_play($data_system.cursor_se)
@index = (@index + @column_max) % @item_max
end
end
if Input.repeat?(Input::LEFT)
if (@column_max == 1 and Input.trigger?(Input::UP)) or
@index >= @column_max
$game_system.se_play($data_system.cursor_se)
@index = (@index - @column_max + @item_max) % @item_max
end
end
if Input.repeat?(Input::RIGHT)
if @column_max >= 2 and @index < @item_max - 1
$game_system.se_play($data_system.cursor_se)
@index += 1
end
end
if Input.repeat?(Input::LEFT)
if @column_max >= 2 and @index > 0
$game_system.se_play($data_system.cursor_se)
@index -= 1
end
end
if Input.repeat?(Input::R)
if self.top_row + (self.page_row_max - 1) < (self.row_max - 1)
$game_system.se_play($data_system.cursor_se)
@index = [@index + self.page_item_max, @item_max - 1].min
self.top_row += self.page_row_max
end
end
if Input.repeat?(Input::L)
if self.top_row > 0
$game_system.se_play($data_system.cursor_se)
@index = [@index - self.page_item_max, 0].max
self.top_row -= self.page_row_max
end
end
end
if self.active and @help_window != nil
update_help
end
update_cursor_rect
end
end
#================================================= =============================
# ?¡ Menu_Command
#------------------------------------------------------------------------------
# ?@ For horizontal selection
#================================================= =============================
class Menu_Command < Menu_Selectable
#--------------------------------------------------------------------------
# ?œ Object Initialization
# width : Window Width
# commands : Command String Layout
#--------------------------------------------------------------------------
def initialize(width, commands)
# The height of the window is calculated from the number of commands.
super(0, 0, 700, 500)
@item_max = commands.size
@commands = commands
self.contents = Bitmap.new(width - 32, @item_max * 32)
self.contents.font.name = "Arial"
self.contents.font.size = 24
self.back_opacity = 0
refresh
self.index = 0
end
#--------------------------------------------------------------------------
# ?œ Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
for i in 0...@item_max
draw_item(i, normal_color)
end
end
#--------------------------------------------------------------------------
# ?œ Item Drawing
# index : Item Number
# color : Item Color
#--------------------------------------------------------------------------
def draw_item(index, color)
self.contents.font.color = color
rect = Rect.new(86*index, 5, self.contents.width - 8, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
self.contents.draw_text(rect, @commands[index])
end
#--------------------------------------------------------------------------
# ?œ Disable Item
# index : Item Number
#--------------------------------------------------------------------------
def disable_item(index)
draw_item(index, disabled_color)
end
end
3. Menu selections without text? I suggest you take a look at the default Window_MenuStatus. The basics of it is use Window_Selectable instead of Window_Command. You will probably have to change the method update_cursor_rect. Window_Selectable can be hard to understand for a beginner: if you need help with figuring it out, just ask. I am sure Zeriab or myself will be able to answer your questions.
CBS
The best way to figure out CBSes is to look at existing ones, but meh:
1. Look at this script: NASVBS (http://rmrk.net/index.php/topic,16450.0.html)
Pretty much the only thing this script does is change the position of the battler. In fact, not just pretty much, entirely.
2. Done with the bitmap method fill_rect. Particularly: self.contents.fill_rect (x,y,width,height,colour). A good thing to look at is this:
#=====================================
#Gradient Bars with customizable lengths, thicknesses, types and Colors
#By AcedentProne
#=====================================
def draw_normal_barz(x, y, type, length, thick, e1, e2, c1 = Color.new(153,238,153,255), c2 = Color.new(0,0,0,255))
if type == "horizontal"
width = length
height = thick
self.contents.fill_rect(x-1, y - 1, width+2, height + 3, Color.new(255, 255, 255, 255))
self.contents.fill_rect(x, y, width, height + 1, Color.new(0, 0, 0, 255))
w = width * e1 / e2
for i in 0..height
r = c1.red + (c2.red - c1.red) * (height -i)/height + 0 * i/height
g = c1.green + (c2.green - c1.green) * (height -i)/height + 0 * i/height
b = c1.blue + (c2.blue - c1.blue) * (height -i)/height + 0 * i/height
a = c1.alpha + (c2.alpha - c1.alpha)* (height -i)/height + 255 * i/height
self.contents.fill_rect(x, y+i, w, 1, Color.new(r, g, b, a))
end
elsif type == "vertical"
width = thick
height = length
self.contents.fill_rect(x-1, y - 1, width+3, height + 2, Color.new(255, 255, 255, 255))
self.contents.fill_rect(x, y, width+1, height , Color.new(0, 0, 0, 255))
h = height * e1 / e2
for i in 0..width
r = c1.red + (c2.red - c1.red) * (width -i)/width + 0 * i/width
g = c1.green + (c2.green - c1.green) * (width -i)/width + 0 * i/width
b = c1.blue + (c2.blue - c1.blue) * (width -i)/width + 0 * i/width
a = c1.alpha + (c2.alpha - c1.alpha)* (width -i)/width + 255 * i/width
self.contents.fill_rect(x+i, y, 1, h, Color.new(r, g, b, a))
end
end
end
def draw_actor_barz(actor,x, y, type, length, thick, e1, e2, c1 = Color.new(255,0,0,255), c2 = Color.new(0,0,0,255))
if type == "horizontal"
width = length
height = thick
self.contents.fill_rect(x-1, y - 1, width+2, height + 3, Color.new(255, 255, 255, 255))
self.contents.fill_rect(x, y, width, height + 1, Color.new(0, 0, 0, 255))
w = width * e1 / e2
for i in 0..height
r = c1.red + (c2.red - c1.red) * (height -i)/height + 0 * i/height
g = c1.green + (c2.green - c1.green) * (height -i)/height + 0 * i/height
b = c1.blue + (c2.blue - c1.blue) * (height -i)/height + 0 * i/height
a = c1.alpha + (c2.alpha - c1.alpha)* (height -i)/height + 255 * i/height
self.contents.fill_rect(x, y+i, w, 1, Color.new(r, g, b, a))
end
elsif type == "vertical"
width = thick
height = length
self.contents.fill_rect(x-1, y - 1, width+3, height + 2, Color.new(255, 255, 255, 255))
self.contents.fill_rect(x, y, width+1, height , Color.new(0, 0, 0, 255))
h = height * e1 / e2
for i in 0..width
r = c1.red + (c2.red - c1.red) * (width -i)/width + 0 * i/width
g = c1.green + (c2.green - c1.green) * (width -i)/width + 0 * i/width
b = c1.blue + (c2.blue - c1.blue) * (width -i)/width + 0 * i/width
a = c1.alpha + (c2.alpha - c1.alpha)* (width -i)/width + 255 * i/width
self.contents.fill_rect(x+i, y, 1, h, Color.new(r, g, b, a))
end
end
That's by Acedent_Prone and it is a gradient bar script.
3. Editing battle formulas is very easy if you are making your own CBS since you have to make them yourself. Many things have stats attached to them, for example $game_actors[1].atk is the physical attack of the first actor in the database. The RMXP help file is really good to take a look at (at least if you have the paid for version) It has lots of good reference material for what classes contain what methods and accessible variables, etc...
4. Don't know what you mean.
5. To make new stats, take a look at this script: Luck Script, by Falcon (http://rmrk.net/index.php/topic,15237.0.html)
6. not sure what it is, as I've never played Golden Sun.
I doubt that as a beginning scripter, much of that was comprehensible. CMSes are much easier than CBSes, so if you plan to make both you are better off starting with CMSes, and getting used to that. Take a few requests if you like in the Simple Script Shop (http://rmrk.net/index.php/topic,17670.0.html) before you move on to a CBS. Also, Rune wrote a good tutorial (http://rmrk.net/index.php/topic,18197.0.html) recently which should cover the basics of making a CMS if you're unsure how to.