Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

KyoWatch VX 1.0.1.1

KyoWatch XP / VX
Version: 1.0.1.1
By: Kyonides
alias Kyonides-Arkanthos, Shadowball

Introduction

It allows the player to set a clock, configure a calendar (made of simple text sprites for now), so the player may think the game has its own clock for calculating when any event might happen and it may not be affected by the OS clock / calendar at all and even so the data will
look realistic. Well, the clock on the menu screen will show its hands once the clock is set. It should show / update the current time correctly.

Features
<Post a bulleted list of features here. This section is optional.>
  • Digital Clock
  • Analog Clock
  • Calendar with correct data about dates (including leap year calculation)

[*]Can set the time from event via script call

Screenshots

For later, but you can download the demo and the script in a separate file if you like.

Demo

http://www.mediafire.com/?sharekey=ac292e67d6ccc98200d27174b47c6657c42aadd10fc9ba8af1940a51b339e393

Script

Code:
#   KyoWatch VX

#   v 1.0.1.0 - 12.27.2009

#   v 1.0.0.1 - 12.22.2009

#   by Kyonides-Arkanthos alias Kyonides, Shadowball

 

#   Plug and Play script

 

#   Basic Instructions

 

#   If $game_kyowatch.no_reset is false, you may set the clock and setup the

#   calendar options. Otherwise you will hear a Buzzer telling you the clock

#   settings cannot be modified.

 

#   You may create a script call like this one

#

#   $game_kyowatch.no_reset = true

#

#   to prevent the player to change the clock / calendar settings at any time.

 

#   YearRangeMIN and YearRangeMAX are the minimal and maximal limits for the

#   current year settings. Any other value is unavailable but you may modify

#   these Constants at will before you play the game.

 

#   KyoX and KyoY are the default values for the clock graphic X and Y

#   coordinates. You may also change this values as needed.

 

#   The rest of the script, except for the Constants for the graphic filenames,

#   should stay as it is. I mean, you should leave the rest of the script alone

#   especially if you are no scripter. This will prevent any malfunctioning

#   from ever happening.

 

#   For any bugs you may contact me at anytime by sending a PM or an email.

 

class Object

  def par?

    return true  if self % 2 == 0

    return false if self % 2 != 0

  end

end

# Module where you can setup the values for the pictures you want

# to load during the game while running the Watch script

module KyoVocab

  KyoX, KyoY = 200, 168

  YearRangeMIN = 1990

  YearRangeMAX = 2020

    PokeballSh   = 'pokeballbg'

    KyoClock     = 'clock'     # 

    KyoMin       = 'clockmin'  # Clock minute hand

    KyoHour      = 'clockhour' # Clock hour hand

  KyoWatchBack = 'watchback'

  KyoSun       = 'sun'

  KyoMoon      = 'full_moon'

  KyoDay       = { 'AM' => [6,7,8,9,10,11], 'PM' => [1,2,3,4,5,12] }

  KyoDayFullNames = { 

      nil => '---------', 0 => 'Sunday',    1 => 'Monday',  

      2 => 'Tuesday',     3 => 'Wednesday', 4 => 'Thursday',

      5 => 'Friday',      6 => 'Saturday'

    }

  KyoDayPartialNames = {

      nil => '---', 0 => 'SUN', 1 => 'MON', 2 => 'TUE',

      3 => 'WED',   4 => 'THU', 5 => 'FRI', 6 => 'SAT'

    }

  KyoMonthFullNames = { 0 => '----------',

       1 => 'January',  2 => 'February',  3 => 'March',

       4 => 'April',    5 => 'May',       6 => 'June',

       7 => 'July',     8 => 'August',    9 => 'September',

      10 => 'October', 11 => 'November', 12 => 'December'

    }

  KyoMonthPartialNames = { 0 => '---',

       1 => 'JAN',  2 => 'FEB',  3 => 'MAR',

       4 => 'APR',  5 => 'MAY',  6 => 'JUN',

       7 => 'JUL',  8 => 'AUG',  9 => 'SEP',

      10 => 'OCT', 11 => 'NOV', 12 => 'DEC'

    }

  REGYEAR  = [nil,31,28,31,30,31,30,31,31,30,31,30,31]

  LEAPYEAR = [nil,31,29,31,30,31,30,31,31,30,31,30,31]

  REGYEARMOD  = {

    1 => 0, 2 => 3, 3 => 3, 4 => 6, 5 => 1, 6 => 4,

    7 => 6, 8 => 2, 9 => 5, 10=> 0, 11=> 3, 12=> 5

    }

  LEAPYEARMOD = {

    1 => 0, 2 => 3, 3 => 4, 4 => 0, 5 => 2, 6 => 5,

    7 => 0, 8 => 3, 9 => 6, 10=> 1, 11=> 4, 12=> 6

    }

end

 

class Game_Player

  def refresh # Do not show a character based on the party leader

    @character_name  = 'Trainers'

    @character_index = 2

  end

end

 

class Game_KyoWatch

  include KyoVocab

  attr_accessor :kyoclock, :time_now, :frame_count, :no_clocktime

  attr_accessor :year, :mon, :day, :hour, :min, :full_mnames

  attr_accessor :no_reset, :disable_24H, :weekday, :month_name

  def initialize

    @kyoclock = [YearRangeMIN,1,1,12,0,'??',0]

    @time_now = []

    @frame_count = 0

    @no_clocktime = true

    @full_mnames = false

    @no_reset    = false

    @disable_24H = true # Disable 24 Hours Format

    @weekday    = KyoDayPartialNames

    @month_name = KyoMonthPartialNames

  end

  

  def update_clock

    @total_sec = (Graphics.frame_count-@frame_count) / Graphics.frame_rate

    m    = @total_sec / 60 % 60

    h    = @total_sec / 60 / 60 % 24

    d    = @total_sec / 60 / 60 / 24 % 30

    mon  = @total_sec / 60 / 60 / 24 / 30 % 12

    year = @total_sec / 60 / 60 / 24 / 30 / 12

    total_min    = @kyoclock[4] + m

    total_hours  = @kyoclock[3] + h + (total_min / 60)

    total_days   = @kyoclock[2] + d + (total_hours / 24)

    total_months = @kyoclock[1] + mon + (total_days / 30)

    total_years  = @kyoclock[0] + year + (total_months / 12)

    @min  = total_min % 60

    @hour = total_hours % 24

    max = !leap?(total_years) ? REGYEAR[total_months] : LEAPYEAR[total_months]

    @day  = total_days % max

    @mon  = total_months % 12

    @year = total_years

    meridian_indicator(@hour, @min)

    @time_now = [@year, @mon, @day, @hour, @min, @kyoclock[5], @kyoclock[6]]

  end

  

  def leap?(year)

    year % 4 == 0 && year % 100 != 0 || year % 400 == 0

  end

  

  def day_name(year, month, daynum)

    @y = year-1

    @a = (@y % 7)

    @b = (  (@y/4) - ( 3*( ( (@y/100)+1 ) /4 ) )  ) % 7

    @mod = REGYEARMOD[month]  if !leap?(year)

    @mod = LEAPYEARMOD[month] if leap?(year)

    @d = daynum % 7

    @day_name = (@a + @b + @mod + @d) % 7

    return @day_name

  end

  

  def minutes

    return @time_now[4]

  end

  

  def hours

    hour = @disable_24H ? @time_now[3]%12 : @time_now[3]

    hour = 12 if @disable_24H and @time_now[3]%12 == 0

    return hour

  end

  

  def meridian_indicator(hour, min)

    @kyoclock[5] = 'AM' if hour >=  0 and min >= 0

    @kyoclock[5] = 'PM' if hour >= 12 and min >= 0

  end

  

  def set_time(values={})

    values = {:year  => @kyoclock[0],

              :month => @kyoclock[1],

              :day   => @kyoclock[2],

              :hour  => @kyoclock[3],

              :min   => @kyoclock[4],}.merge(values)

    @kyoclock[6] = day_name(values[:year], values[:month], values[:day])

    meridian_indicator(@kyoclock[3], @kyoclock[4])

    @frame_count = Graphics.frame_count

  end

end

 

class Sprite_KyoPicture < Sprite # Class to show a picture that may rotate

  def initialize(name, center=true, viewport=nil)

    @viewport = Viewport.new(0,0,544,416) if viewport == nil

    @viewport = viewport if viewport != nil

    super(@viewport)

    self.bitmap = Cache.picture(name)

    @width = self.bitmap.width/2

    self.x, self.y, self.z = 0, 0, 1000

    self.ox, self.oy = @width, @width if center

    self.ox, self.oy = 0, 0 if !center

  end

  

  def update(value)

    if Input.trigger?(Input::UP) or Input.repeat?(Input::UP)

      self.angle -= value

        elsif Input.trigger?(Input::DOWN) or Input.repeat?(Input::DOWN)

      self.angle += value

        end

  end

  

  def rotate(value)

    self.angle -= value

  end

  

  def refresh(name,x=0,y=0,center=true)

    self.bitmap = Cache.picture(name)

    @width = self.bitmap.width/2

    self.x, self.y, self.z = x, y, 1000

    self.ox, self.oy = @width, @width if center

    self.ox, self.oy = 0, 0 if !center

  end

end

 

class Sprite_PlayTime < Sprite # Just A PlayTime Script

  def initialize(x=0,y=0)

    @viewport = Viewport.new(0,0,544,416)

    super(@viewport)

    self.bitmap = Bitmap.new(140, 48)

    self.bitmap.font.name = 'Digital-7'

    self.bitmap.font.size = 32

    self.bitmap.font.bold = true

    self.x, self.y, self.z, self.visible = x, y, 1000, true

        update

    end

    

  def refresh

    self.bitmap.clear

    @total_sec = Graphics.frame_count / Graphics.frame_rate

    hour = @total_sec / 60 / 60

    min = @total_sec / 60 % 60

    sec = @total_sec % 60

    text = sprintf("%02d:%02d:%02d", hour, min, sec)

    self.bitmap.font.color.set(255, 255, 255)

    self.bitmap.draw_text(self.bitmap.rect, text)

  end

 

  def update

    super

    if Graphics.frame_count / Graphics.frame_rate != @total_sec

      refresh

    end

  end

end

  

class Sprite_KyoWatch < Sprite

  def initialize(x=0,y=0)

    @viewport = Viewport.new(0,0,544,416)

    super(@viewport)

    self.bitmap = Bitmap.new(156, 48)

    self.bitmap.font.name = 'Digital-7'

    self.bitmap.font.size = 32

    self.bitmap.font.bold = true

    self.x, self.y, self.z, self.visible = x, y, 1000, true

    @time_now = []

    @clock = $game_kyowatch

    update

  end

  

  def update

    super

    if @clock.time_now != @time_now

      refresh

    end

  end

  

  def refresh

    self.bitmap.clear

    @clock.update_clock

    c = @clock.time_now

    text = sprintf("%02d %02d:%02d", c[2], @clock.hours, c[4])

    ampm = @clock.disable_24H ? ' '+@clock.time_now[5] : ''

    self.bitmap.font.color.set(255, 255, 255)

    self.bitmap.draw_text(self.bitmap.rect, text + ampm)

    @time_now = @clock.time_now

  end

end

 

class Sprite_KyoYear < Sprite#_KyoWatch

  attr_accessor :year

  def initialize(x=0,y=0)

    @viewport = Viewport.new(0,0,544,416)

    super(@viewport)

    self.bitmap = Bitmap.new(156, 48)

    self.bitmap.font.name = 'Digital-7'

    self.bitmap.font.size = 32

    self.bitmap.font.bold = true

    self.x, self.y, self.z, self.visible = x, y, 1000, true

    @clock = $game_kyowatch

    @year  = @clock.kyoclock[0]

    @value = 0

    update

  end

  

  def update

    refresh if @year != @value

  end

  

  def refresh

    self.bitmap.clear

    @clock.update_clock

    self.bitmap.font.color.set(255, 255, 255)

    self.bitmap.draw_text(self.bitmap.rect, @year.to_s)

    @value = @year

  end

end

 

class Sprite_KyoDay < Sprite

  attr_accessor :day

  def initialize(x=0,y=0)

    @viewport = Viewport.new(0,0,544,416)

    super(@viewport)

    self.bitmap = Bitmap.new(92, 48)

    self.bitmap.font.name = 'Digital-7'

    self.bitmap.font.size = 32

    self.bitmap.font.bold = true

    self.x, self.y, self.z, self.visible = x, y, 1000, true

    @clock = $game_kyowatch

    @time_now = []

    @day = @clock.kyoclock[2]

    update

  end

  

  def update

    super

    @clock.update_clock

    if @clock.time_now != @time_now

      refresh

    end

  end

  

  def refresh

    self.bitmap.clear

    @clock.update_clock

    self.bitmap.font.color.set(255, 255, 255)

    self.bitmap.draw_text(self.bitmap.rect, @day.to_s)

    @time_now = @clock.time_now

  end

end

 

class Sprite_KyoWatchSys < Sprite # Make the Clock hands rotate

  attr_accessor :hour, :min, :ampm, :active

  def initialize(x=0,y=0,f1=false,f2=false,f3=false)

    @viewport = Viewport.new(0,0,544,416)

    super(@viewport)

    self.bitmap = Bitmap.new(116, 48)

    self.bitmap.font.name = 'Digital-7'

    self.bitmap.font.size = 32

    self.bitmap.font.bold = true

    self.x, self.y, self.z, self.visible = x, y, 1000, true

    @active = false

    @clock = $game_kyowatch.kyoclock

    @hour, @min, @ampm = @clock[3]%12, @clock[4], @clock[5]

    update(f1,f2,f3) if @active

  end

  

  def update(hour_flag, min_flag, ampm_flag)

    if @active

      @hour_flag, @min_flag, @ampm_flag = hour_flag, min_flag, ampm_flag

      update_hour   if !@hour_flag

      update_minute if @hour_flag and !@min_flag

      update_ampm   if @hour_flag and @min_flag and !@ampm_flag

    end

    refresh

  end

  

  def update_hour

    @hour = 12  if @hour == 0

    @hour -= 12 if @hour >= 13

    if Input.trigger?(Input::UP) or Input.repeat?(Input::UP)

      @hour += 1 if @hour >= 0 and @hour <= 12

      @hour =  1 if @hour == 13

    elsif Input.trigger?(Input::DOWN) or Input.repeat?(Input::DOWN)

      @hour -= 1 if @hour >= 0 and @hour <= 12

      @hour = 12 if @hour == 0

    end

  end

  

  def update_minute

    if Input.trigger?(Input::UP) or Input.repeat?(Input::UP)

      @min  += 1 if @min >= 0 and @min <= 60

      @min  = 0  if @min == 60

    elsif Input.trigger?(Input::DOWN) or Input.repeat?(Input::DOWN)

      @min  -= 1 if @min >= 0 and @min <= 60

      @min  = 59 if @min == -1

    end

  end

  

  def update_ampm

    if Input.trigger?(Input::DOWN) or Input.trigger?(Input::LEFT)

      @ampm = 'AM'

    elsif Input.trigger?(Input::UP) or Input.trigger?(Input::RIGHT)

      @ampm = 'PM'

    end

  end

  

  def refresh

    self.bitmap.clear

    text = sprintf("%02d:%02d", @hour, @min)

    self.bitmap.font.color.set(255, 255, 255)

    self.bitmap.draw_text(self.bitmap.rect, text+' '+@ampm, 1)

  end

end

 

class Sprite_KyoCalendarSys < Sprite_KyoWatchSys # Setup the current date

  include KyoVocab

  attr_accessor :year, :month, :day, :day_name, :update_sprite, :on_screen

  alias :kyon_skcs_init :initialize

  def initialize(x=0,y=0,f1=false,f2=false,f3=false,f4=false)

    kyon_skcs_init(x=0,y=0,f1=false,f2=false,f3=false)

    @clock_req = $game_kyowatch

    @year, @month, @day = @clock[0], @clock[1], @clock[2]

    @day_name = @clock[6]

    @update_sprite = nil

    @on_screen = false

    update(f1,f2,f3,f4) if @active

  end

  

  def update(year_flag, month_flag, day_flag, day_name_flag)

    if @active

      @year_flag, @month_flag   = year_flag, month_flag

      @day_flag, @day_name_flag = day_flag, day_name_flag

      update_year     if !@year_flag

      update_month    if @year_flag and !@month_flag

      update_day      if @year_flag and @month_flag and !@day_flag

      update_day_name if @day_flag and !@day_name_flag and !@on_screen

    end

    refresh(@update_sprite)

  end

  

  def update_year

    if Input.trigger?(Input::UP) or Input.repeat?(Input::UP)

      @year += 1 if @year >= YearRangeMIN  and @year <= YearRangeMAX

      @year  = YearRangeMIN if @year == YearRangeMAX+1

    elsif Input.trigger?(Input::DOWN) or Input.repeat?(Input::DOWN)

      @year -= 1 if @year >= YearRangeMIN  and @year <= YearRangeMAX

      @year  = YearRangeMAX if @year == YearRangeMIN-1

    end

  end

  

  def update_month

    if Input.trigger?(Input::UP) or Input.repeat?(Input::UP)

      @month += 1 if @month >= 1 and @month <= 12

      @month = 1  if @month == 13 or @month == 0

    elsif Input.trigger?(Input::DOWN) or Input.repeat?(Input::DOWN)

      @month -= 1 if @month >= 1 and @month <= 12

      @month = 12 if @month == 0

    end

  end

  

  def update_day

    if Input.trigger?(Input::UP) or Input.repeat?(Input::UP)

      if !@clock_req.leap? @year

        @day += 1 if @day >= 1 and @day <= REGYEAR[@month]

        @day =  1 if @day == 0 or @day > REGYEAR[@month]

      elsif @clock_req.leap? @year

        @day += 1 if @day >= 1 and @day <= LEAPYEAR[@month]

        @day =  1 if @day == 0 or @day > LEAPYEAR[@month]

      end

    elsif Input.trigger?(Input::DOWN) or Input.repeat?(Input::DOWN)

      if !@clock_req.leap? @year

        @day -= 1 if @day >= 1 and @day <= REGYEAR[@month]

        @day = REGYEAR[@month] if @day == 0 or @day > REGYEAR[@month]

      elsif @clock_req.leap? @year

        @day -= 1 if @day >= 1 and @day <= LEAPYEAR[@month]

        @day = LEAPYEAR[@month] if @day == 0 or @day > LEAPYEAR[@month]

      end

    end

  end

  

  def update_day_name

    @day_name = @clock_req.day_name(@year,@month,@day)

    print @month_flag, @day_flag, @day_name_flag, @on_screen

    @on_screen = true

  end

  

  def refresh(target_sprite=nil) # A Sprite as argument

    @target_sprite = target_sprite

    if @target_sprite != nil and @target_sprite.is_a? Sprite

      # Current target is KyoYear

      if !@year_flag and !@month_flag

        @this_year = @target_sprite

        @this_year.year = @year

        @this_year.refresh

      # Current target is KyoMonthName

      elsif @year_flag and !@month_flag and !@day_flag

        @this_month = @target_sprite

        @this_month.mname = @month

        @this_month.refresh

      # Current target is KyoDay

      elsif @year_flag and @month_flag and !@day_flag

        @todaynum = @target_sprite

        @todaynum.day = @day

        @todaynum.refresh

      elsif @month_flag and @day_flag and !@day_name_flag

        @today = @target_sprite

        @today.dname = @day_name

        @today.refresh

      end

    end

  end

end

 

class Sprite_KyoDayName < Sprite

  include KyoVocab

  attr_accessor :dname, :mname

  def initialize(x=0,y=0,full_name=false)

    @viewport = Viewport.new(0,0,544,416)

    super(@viewport)

    self.bitmap = Bitmap.new(168, 48)

    self.bitmap.font.name = 'Digital-7'

    self.bitmap.font.size = 32

    self.bitmap.font.bold = true

    self.x, self.y, self.z, self.visible = x, y, 1000, true

    @time_now = []

    @clock = $game_kyowatch

    @clock.full_mnames = full_name

    @dname = @clock.kyoclock[6]

    @mname = @clock.kyoclock[1]

    update

  end

  

  def update

    super

    @clock.update_clock

    if @clock.time_now != @time_now

      refresh

    end

  end

  

  def refresh

    self.bitmap.clear

    @clock.update_clock

    c = @clock.time_now

    @clock.weekday = KyoDayFullNames    if @clock.full_mnames

    @clock.weekday = KyoDayPartialNames if !@clock.full_mnames

    text = @clock.weekday[@dname]

    self.bitmap.font.color.set(255, 255, 255)

    self.bitmap.draw_text(self.bitmap.rect, text)

    @time_now = @clock.time_now

  end

end

 

class Sprite_KyoMonthName < Sprite_KyoDayName

  def refresh

    self.bitmap.clear

    @clock.update_clock

    c = @clock.time_now

    @clock.month_name = KyoMonthFullNames    if @clock.full_mnames

    @clock.month_name = KyoMonthPartialNames if !@clock.full_mnames

    text = @clock.month_name[@mname]

    self.bitmap.font.color.set(255, 255, 255)

    self.bitmap.draw_text(self.bitmap.rect, text)

    @time_now = @clock.time_now

  end

end

 

class Scene_Menu < Scene_Base

    include KyoVocab

  def initialize(menu_index=0)

    @menu_index = menu_index

    @clock      = $game_kyowatch # Call Watch script

    @minutes    = @clock.minutes * 6 if !@clock.no_clocktime

    @hours      = @clock.hours * 30  if !@clock.no_clocktime

  end

 

  def start

    super

    create_menu_background

    create_command_window

    @gold_window = Window_Gold.new(384, @kyon_options.size*24+32)

    @pokeball = Sprite_KyoPicture.new(PokeballSh)

    @pokeball.x, @pokeball.y = 542, 360

    @clockpic = Sprite_KyoPicture.new(KyoClock)

    @clockpic.x, @clockpic.y = KyoX, KyoY

    @clockmin = Sprite_KyoPicture.new(KyoMin)

    @clockmin.x, @clockmin.y, @clockmin.z = KyoX, KyoY, 1000

    @clockmin.rotate(@clock.minutes*6) if !@clock.no_clocktime

    @clockhour = Sprite_KyoPicture.new(KyoHour)

    @clockhour.x, @clockhour.y, @clockhour.z = KyoX, KyoY, 2000

    @clockhour.rotate(@clock.hours*30) if !@clock.no_clocktime

        @playtime = Sprite_PlayTime.new(392,336)

    @watch    = Sprite_KyoWatch.new(392,368) if !@clock.no_clocktime

    @weekday  = Sprite_KyoDayName.new(328,368) if !@clock.no_clocktime

  end

  

  def terminate

    super

    dispose_menu_background

        [@command_window,@gold_window,@pokeball,@playtime].each {|s| s.dispose}

    [@clockpic, @clockmin, @clockhour, @watch, @weekday].each do |s|

      s.dispose if !@clock.no_clocktime

    end

  end

 

  def update

    super

    update_menu_background

    @command_window.update

    if !@clock.no_clocktime 

      @clockmin.rotate(@clock.minutes*6-@minutes)

      @clockhour.rotate(@clock.hours*30-@hours)

      @minutes = @clock.minutes*6

      @hours   = @clock.hours*30

    end

    @pokeball.update(45)

    @gold_window.update

        @playtime.update

    @watch.update if !@clock.no_clocktime

    @weekday.update if !@clock.no_clocktime

    update_command_selection if @command_window.active

  end

 

  def create_command_window

    s1 = 'Bestiary'

    s2 = 'Party'

    s3 = Vocab::item

    s4 = 'Map'

    s5 = 'Watch'

    s6 = 'Achievements'

    s7 = Vocab::save

    s8 = 'Options'

    s9 = Vocab::game_end

    @kyon_options = [s1,s2,s3,s4,s5,s6,s7,s8,s9]

    @command_window = Window_Command.new(160, @kyon_options)

    @command_window.x = 384

    @command_window.index = @menu_index

    if $game_system.save_disabled         # If save is forbidden

      @command_window.draw_item(6, false) # Disable save

    end

  end

 

  def update_command_selection

    if Input.trigger?(Input::B)

      Sound.play_cancel

      $scene = Scene_Map.new

    elsif Input.trigger?(Input::C)

      if $game_system.save_disabled and @command_window.index == 4

        Sound.play_buzzer

        return

      end

      Sound.play_decision

      case @command_window.index

      when 0 # Bestiary

        #$scene = Scene_KyoBestiary.new

      when 1 # Party Members

        #$scene = Scene_KyoMembers.new

      when 2 # Items / Bag

        #$scene = Scene_KyoItems.new

      when 3 # Map

        #$scene = Scene_KyoMapViewer.new

      when 4 # Watch

        $scene = Scene_KyoWatch.new if !$game_kyowatch.no_reset

      when 5 # Achievements

        #$scene = Scene_KyoMadeIt.new

      when 6 # Save

        $scene = Scene_File.new(true, false, false)

      when 7 # Options

        #$scene = Scene_KyoWinSkin.new

      when 8 # End Game

        $scene = Scene_End.new

      end

    end

  end

end

 

class Scene_KyoWatch < Scene_Base

  include KyoVocab

  def initialize

    @clock = $game_kyowatch

  end

  

  def start

    super

    create_menu_background

    create_command_window

    @help_window = Window_Help.new

    @watch_back = Sprite_KyoPicture.new(KyoWatchBack)

    @watch_back.x, @watch_back.y = 200, 360

    @watch = Sprite_KyoWatchSys.new(KyoX-64, KyoY+108)

    @watch.update(@kyon_fixed_hour, @kyon_fixed_min, @kyon_fixed_ampm)

    @clockpic = Sprite_KyoPicture.new(KyoClock)

    @clockpic.x, @clockpic.y = KyoX, KyoY

    @clockmin = Sprite_KyoPicture.new(KyoMin)

    @clockmin.x, @clockmin.y, @clockmin.z = KyoX, KyoY, 1000

    @clockmin.rotate(@watch.min*6)

    @clockhour = Sprite_KyoPicture.new(KyoHour)

    @clockhour.x, @clockhour.y, @clockhour.z = KyoX, KyoY, 2000

    @clockhour.rotate(@watch.hour*30)

    @this_year  = Sprite_KyoYear.new(440, 60)

    @this_month = Sprite_KyoMonthName.new(276, 60, true)

    @todaynum   = Sprite_KyoDay.new(440,96)

    @today      = Sprite_KyoDayName.new(296, 96, true)

    @calendar = Sprite_KyoCalendarSys.new(0,0)

    sun_moon_settings

    @sun_moon = Sprite_KyoPicture.new(@picture)

    @sun_moon.y = 140

  end

  

  def create_command_window

    @command_window = Window_Command.new(160, ['Clock', 'Calendar'], 1)

    @command_window.x = (544-@command_window.width) / 2

    @command_window.y = 56

    @command_window.index = 0

  end

  

  def sun_moon_settings # Should the Sun or the Moon picture appear?

    @am_pm = @watch.ampm # Load picture depending on current daytime

    @hour  = @watch.hour

    if @am_pm == 'AM' or @am_pm == 'PM' # Check the Daytime Hash

      @picture = KyoSun  if KyoDay[@am_pm].include?(@hour)

      @picture = KyoMoon if !KyoDay[@am_pm].include?(@hour)

    elsif @am_pm == '??'

      @picture = KyoSun

    end

  end

  

  def terminate

    super

    dispose_menu_background

    things = [@clockhour, @clockmin, @watch_back, @help_window, @sun_moon]

    things.push @clockpic, @watch, @command_window, @calendar

    things.push @this_year, @this_month, @todaynum, @today

    things.each {|s| s.dispose}

  end

  

  def update

    super

    update_menu_background

    @command_window.update

    @help_window.update

    if @command_window.active

      update_command

    elsif !@command_window.active

      # Set the clock if index == 0

      if @command_window.index == 0

        @watch.update(@kyon_fixed_hour, @kyon_fixed_min, @kyon_fixed_ampm)

        if !@kyon_fixed_hour and @kyon_set_flags and !@kyon_exit

          update_hour

        elsif @kyon_fixed_hour and !@kyon_fixed_min

          update_min

        elsif @kyon_fixed_hour and @kyon_fixed_min and !@kyon_fixed_ampm

          update_ampm

        elsif @kyon_fixed_min and @kyon_fixed_ampm and !@kyon_exit

          update_exit_current_setup # Show confirmation message

        end

      # Setup the calendar if index == 1

      elsif @command_window.index == 1

        @calendar.update(@kyon_fixed_year, @kyon_fixed_month,

          @kyon_fixed_day, @kyon_fixed_day_name)

        if !@kyon_fixed_year and !@kyon_fixed_month

          update_year

        elsif @kyon_fixed_year and !@kyon_fixed_month

          update_month

        elsif @kyon_fixed_year and @kyon_fixed_month and !@kyon_fixed_day

          update_day

        elsif @kyon_fixed_year and @kyon_fixed_month and @kyon_fixed_day and

          !@kyon_fixed_day_name

          update_day_name

        elsif @kyon_fixed_day and @kyon_fixed_day_name and @calendar.on_screen

          update_exit_current_setup # Show confirmation message

        end

      end

    end

  end

  

  def update_command

    @help_window.set_text('KyoWatch VX version 1.0', 1)

    if Input.trigger?(Input::B)

      if @kyon_set_flags

        Sound.play_buzzer

        return

      else

        Sound.play_cancel

        $scene = Scene_Map.new

      end

    elsif Input.trigger?(Input::C)

      Sound.play_decision

      @index = @command_window.index

      case @index

      when 0, 1

        kyon_reset_flags

        @kyon_exit = false # Need to set the clock

        @command_window.active  = false

        @command_window.visible = false

        @calendar.update_sprite = @this_year if @index == 1

        @watch.active    = true if @index == 0

        @calendar.active = true if @index == 1

      end

    end

  end

  

  def update_hour

    @help_window.set_text('Please set the current hour.', 1)

    @clockhour.update(30) if !@kyon_fixed_hour

    if Input.trigger?(Input::C)

      @kyon_fixed_hour = true if !@kyon_fixed_hour

    end

  end

  

  def update_min

    @help_window.set_text('Please set the current minutes.', 1)

    @clockmin.update(6) if @kyon_fixed_hour and !@kyon_fixed_min

    if Input.trigger?(Input::C)

      @kyon_fixed_min = true if !@kyon_fixed_min

    end

  end

  

  def update_ampm

    @help_window.set_text('Is it AM or PM?', 1)

    if Input.trigger?(Input::C)

      if !@kyon_fixed_ampm and @watch.ampm != '??'

        @kyon_fixed_ampm = true

      else

        return

      end

      sun_moon_settings

      @sun_moon.refresh(@picture,0,140)

          # Clock does not handle 24 hours, check how many hours passed

          # and calculate the time in 24 hour format if needed

      if @watch.hour > 0 and @watch.hour < 12 and @watch.ampm == 'PM'

        hour = @watch.hour + 12

      elsif @watch.hour == 12 and @watch.ampm == 'AM'

        hour = 0

      else

        hour = @watch.hour

      end

      h_min_ampm = [hour, @watch.min, @watch.ampm]

          @clock.kyoclock[3,3] = h_min_ampm

      @clock.frame_count = Graphics.frame_count

      @clock.update_clock

      @clock.no_clocktime = false

    end

  end

  

  def update_year

    @help_window.set_text('And the current year is...', 1)

    if Input.trigger?(Input::C)

      if !@kyon_fixed_year and @calendar.year >= YearRangeMIN

        @kyon_fixed_year = true 

        @calendar.update_sprite = @this_month

      end

    end

  end

  

  def update_month

    @help_window.set_text('What about the current month?', 1)

    if Input.trigger?(Input::C)

      if !@kyon_fixed_month

        @kyon_fixed_month = true

        @calendar.update_sprite = @todaynum

      end

    end

  end

  

  def update_day

    @help_window.set_text('What day is it?', 1)

    if Input.trigger?(Input::C)

      if !@kyon_fixed_day

        @kyon_fixed_day = true

        @calendar.update_sprite = @today

      @today.refresh

      end

    end

  end

  

  def update_day_name

    @help_window.set_text('Now you should see the name of the day', 1)

    if Input.trigger?(Input::C)

      return if @kyon_fixed_day_name

      @kyon_fixed_day_name = true

      year_month_day = [@calendar.year, @calendar.month, @calendar.day]

      @clock.kyoclock[6] = @calendar.day_name if @kyon_set_flags

      @clock.kyoclock[0,3] = year_month_day   if @kyon_set_flags

    end

  end

  

  def update_exit_current_setup

    text = 'Ready! Now press Enter to exit to the selection menu'

    @help_window.set_text(text, 1)

    if Input.trigger?(Input::C)

      @kyon_set_flags  = false if @kyon_set_flags

      @watch.active    = false if @watch.active

      @calendar.active = false if @calendar.active

      @command_window.visible = true

      @command_window.active  = true

    end

  end

  

  def kyon_reset_flags

    if @command_window.index == 0

      @kyon_fixed_hour, @kyon_fixed_ampm, @kyon_fixed_min = false, false, false

    elsif @command_window.index == 1

      @kyon_fixed_year, @kyon_fixed_month = false, false

      @kyon_fixed_day, @kyon_fixed_day_name = false, false

    end

    @kyon_set_flags = true # Need to set hour, minutes and AM / PM or setup date

  end

end

 

class Scene_Title

  alias kyon_title_cgo create_game_objects

  alias kyon_title_cng command_new_game

  

  def create_game_objects

    kyon_title_cgo

    $game_kyowatch = Game_KyoWatch.new # Call system script

  end

 

  def command_new_game

    $game_kyowatch.frame_count = 0 # Reset frame count before

    kyon_title_cng # setting up the clocktime for the first time

  end

end

 

class Scene_File

  def return_scene

    if @from_title

      $scene = Scene_Title.new

    elsif @from_event

      $scene = Scene_Map.new

    else

      $scene = Scene_Menu.new(6) # Save option current position

    end

  end

  

  alias kyon_sf_wsd write_save_data

  def write_save_data(file)

    kyon_sf_wsd(file) # Do not forget to save the System script

    Marshal.dump($game_kyowatch, file)

  end

  

  def read_save_data(file)

    characters           = Marshal.load(file)

    Graphics.frame_count = Marshal.load(file)

    @last_bgm            = Marshal.load(file)

    @last_bgs            = Marshal.load(file)

    $game_system         = Marshal.load(file)

    $game_message        = Marshal.load(file)

    $game_switches       = Marshal.load(file)

    $game_variables      = Marshal.load(file)

    $game_self_switches  = Marshal.load(file)

    $game_actors         = Marshal.load(file)

    $game_party          = Marshal.load(file)

    $game_troop          = Marshal.load(file)

    $game_map            = Marshal.load(file)

    $game_player         = Marshal.load(file)

    # Load Watch System script data

    $game_kyowatch     = Marshal.load(file) if !file.eof?

    $game_kyowatch     = Game_Kyowatch.new if file.eof?

    if $game_system.version_id != $data_system.version_id

      $game_map.setup($game_map.map_id)

      $game_player.center($game_player.x, $game_player.y)

    end

  end

end

Instructions

The script includes a menu screen that already includes an option to enter the Clock and Calendar scene. You may need to add that option manually to any other menu like a Ring Menu script.

You may call the script like this

$scene = Scene_KyoWatch.new

To enable or disable access to the scene, use this line at any time

$game_kyowatch.no_reset = true (or false if needed)

Take a look at the Constants inside the KyoVocab module, there you can edit any graphic configuration related to the script, but there are a lot of things you may leave alone to make sure the script will work properly.

BTW, the Scene_File script was modified to include my script while saving or loading data from the save data file. Don't ever forget that! Of course, I modified the Scene_Title scene, too, to load the Game class I added named Game_KyoWatch.

Bugs

There was a little bug in a previous version that was solved in the current one (1.0.0.1). I just forgot to include an if statement twice in lines 540 and 541, I think, so the clock does not start spinning right away but just after the player set the clock at least once.

The Demo and the Script were updated.

FAQ

None yet.

Compatibility

Not sure if it's SDK compliant, maybe not, gotta check it out.

Credits and Thanks

Well, the clock graphic (except for the clock hands) are not mine but from a guy that made it for KDE (a Linux OS GUI).

Author's Notes

Now you can also get the XP version of this script!

I wished the Maker included the DateTime class... it would make it a bit easier to develop it. Thanks GlitchFinder for letting me know it was a need to make the script compatible with old saved games data.

Terms and Conditions

Not intended for Commercial Use.

I should be credited for the script if included in any project or game.
 
I have a few things to say about this script. First off, it is looking like at least some of the code was taken from Poccil's Pokemon Starter Kit. The reason I say this first becomes evident on line 45, which reads as follows:

Code:
    PokeballSh   = 'pokeballbg'

As far as I know, Poccil is the only scripter around who not only uses those atrocious naming conventions, but also has a significant body of Pokemon-related coding.

The next comment I had was regarding your edit to the load file method. Specifically, the fact that you introduced an unnecessary fatal error to the script, by removing compatibility with older save files. When adding new things to save files, you should always make sure you check for an end of file error before trying to load that new data, so as to make sure that the game doesn't crash when you try to load a save file from before the script was installed. The method could easily be rewritten as follows:

Code:
   def read_save_data(file)

    characters           = Marshal.load(file)

    Graphics.frame_count = Marshal.load(file)

    @last_bgm            = Marshal.load(file)

    @last_bgs            = Marshal.load(file)

    $game_system         = Marshal.load(file)

    $game_message        = Marshal.load(file)

    $game_switches       = Marshal.load(file)

    $game_variables      = Marshal.load(file)

    $game_self_switches  = Marshal.load(file)

    $game_actors         = Marshal.load(file)

    $game_party          = Marshal.load(file)

    $game_troop          = Marshal.load(file)

    $game_map            = Marshal.load(file)

    $game_player         = Marshal.load(file)

    if file.eof?

      $game_kyowatch     = Game_KyoWatch.new

    else

      $game_kyowatch     = Marshal.load(file) # Load System Script data

    end

    if $game_system.version_id != $data_system.version_id

      $game_map.setup($game_map.map_id)

      $game_player.center($game_player.x, $game_player.y)

    end

  end

Aside from these, I can't really give much commentary without actually testing the script. I do have to commend you for creating such a large script, since this was apparently quite the undertaking.

Also, please don't take the commentary the wrong way. Although my wording may have had a bit of an edge, both things I pointed out are valid concerns for your script, for very different reasons.
 
Well, the reason why I chose that naming convention for the pokeball shadow that was place on the lower right corner is that I was planning to develop a simple Pokemon project on my own for a Spanish speaking audience, but once the project itself was looking more and more like a clock / calendar script, I decided it was time to devote all my free time to develop it and see if I was already capable of creating it or not, because for me it was a challenge to develop something more different that my very first scripts. (I was thinking I should also remove all Pokemon influence to make the script look more impartial, more generic...)

I didn't like the first script I ever posted because it was a ridiculously simple PlayTime script that didn't include any features I now included in my KyoWatch script. So the script above is the result of my devotion / obsession of making a major effort to get something I could consider more valuable, even if I'm still an amateur scripter that has just about two years experience with RGSS with some not so extended periods of scripting obscurantism included. I know I'm far away from where renown scripters are, but learning RGSS and also Ruby (and wxRuby and FXRuby) makes me feel the need, the urge of creating better and more complicated scripts... but it takes a lot of time, patience and headaches. :) I guess it's not so easy to change your way of thinking suddenly.

By the way, I haven't seen Poccil's coding but if I find his or hers scripts for developing a PKMN project, well, I'd give up making my own scripts and would start adapting it for any Pokemon game I might develop. That's because I'd become too lazy to do something on my own (that's why I avoid downloading such stuff so I don't lose any inspiration and some valuable learning experience on the way).

I didn't know I could check the end of file while calling Marshal.load. Thanks for the tip, it's pretty helpful.

That makes me remember the time I was afraid of scripting long back ago when RM2K3 was still considered fresh but could be easily beaten by the newcomer XP that showed up in the market a few months later.

And yes, I know you call yourself the glitchfinder, so I guess it's normal for you to point those things out once they started bugging you. And thanks, I'll know avoid those atrocious naming conventions from now on.

Anyway, this kind of script was intended to be used in games where a clock is required like Pokemon, Harvest Moon and any other similar games.
 
Updated the script to include a set time feature that uses a Hash to set the new values for days, hours, minutes or anything else related to my watch script.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top