Code: |
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= # Advanced Time and Environment System (ATES) par Blizzard et ThallionDarkshine # Version: 1.0 # Type: Contrôleur autonome de l'écoulement du temps et de l'environnement # Date v0.3: 11.3.2008 # Date v0.31: 8.4.2009 # Date v0.32: 13.4.2009 # Date v0.33: 4.5.2009 # Date v0.34: 5.5.2009 # Date v1.0: 12.2.2013 # Traduction française par Moy #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= # # Ce travail est protégé par la licence qui suit: # #---------------------------------------------------------------------------- # # # # Creative Commons - Attribution-NonCommercial-ShareAlike 3.0 Unported # # ( http://creativecommons.org/licenses/by-nc-sa/3.0/ ) # # # # Vous êtes autorisé à : # # # # Partager — copier, distribuer et communiquer le matériel par tous moyens et sous tous formats # # Adapter — remixer, transformer et créer à partir du matériel # # # # Sleon les conditions suivantes: # # # # Attribution. Vous devez attribuer l'oeuvre de la manière indiquée par # # l'auteur original (mais pas d'une manière qui suggérere qu'il # # approuve votre utilisation de l'oeuvre). # # # # Non commercial. Vous ne devez pas utiliser ce travail à des fins commerciales. # # # # Partage à l'identique. Si vous modifiez, transformez ou adaptez cette création, vous pouvez # # distribuer l'œuvre résultante sous la même licence ou l'une similaire à # # celle-ci. # # # # - A chaque réutilisation ou distribution, vous devez faire apparaître clairement aux autres # # les termes de la licence de ce travail. La meilleure façon de le faire est avec un lien # # vers cette page web. # # # # - Chacune de ces conditions peut être levée si vous obtenez l'autorisation du # # titulaire du droit d'auteur. # # # # - Rien dans ce contrat ne diminue ou ne restreint le droit moral de l'auteur. # # # #---------------------------------------------------------------------------- # #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= # # Compatibilité: # # 99% compatible avec SDK v1.x. 90% compatible avec SDK 2.x. Va corrompre vos # anciennes sauvegardes. Peut causes des problèmes d'incompatibilité avec DNS-es. # # # Caractéristiques: # # - Contrôle complet et facile de la manipulation du temps et la météo # - Teintes Jour/Nuit personalisables # - HUD facultatif # - Plus facile à contrôler et plus puissant que DDNS # # # NOTES IMPORTANTES: # # - Ce système a une préconfiguration de travail, soyez conscient qu'une # configuration personnalisée aura besoin que vous comprenez chaques options, # donc s'il vous plaît lisez les instructions de configuration. # - Pourquoi ce système utilise des interrupteurs pour déterminer si c'est le jour ou la nuit ? # Simple: Vous pouvez utiliser des conditions dans les attaques ennemies afin de déterminer si une # attaque doit être utilisé uniquement la nuit ou le jour. # # # Instructions: # # - Explication: # # Ce système de temps créra pour votre jeu des périodes de jour et de nuit. # L'écran sera teinté en conséquence. Vous pouvez configurer la durée du # jour. Les autres caractéristiques sont expliqué ci-dessous. # S'il vous plaît soyer sûr de configurer ce système de manière appropriée. # # # - Manipulations basiques d'ATES: # # Ce système travaillera essentiellement si vous le voulez, # mais avec un peu d'utilisation d'appel de script vous êtes en mesure de contrôler ce système entièrement. # Vous pouvez appeler les commandes suivantes: # # ATES.on # Active ATES. # # ATES.off # Désactive ATES. # # ATES.tint_on # Active le teintement de l'écran d'ATES. # # ATES.tint_off # Désactive le teintement de l'écran d'ATES. # # ATES.clock_on # Active l'affichage de l'heure d'ATES # # ATES.clock_off # désactive l'affichage de l'heure d'ATES # # ATES.active? # Retourne "true" si ATES tourne, autrement c'est "false". # # ATES.tinting? # Retourne "true" si le teintement de l'écran d'ATES tourne, autrement c'est "false". # # ATES.day? # Retourne "true" si c'est le jour, autrement c'est "false". Alternativement # vous pouvez vérifié l'interrupteur assigné à la place. # # ATES.night? # Retourne "true" si c'est la nuit, autrement c'est "false". Alternativement # vous pouvez vérifié l'interrupteur assigné à la place. # # ATES.advance(M, H) # Va avancer le temps de M minutes et H heures. Toutes valeurs # négatives annulent l'éxécution de la commande. # # ATES.make_it_day # C'est une caractéristique de DDNS qui permet de sauter rapidement vers la journée. # # ATES.make_it_night # C'est une caractéristique de DDNS qui permet de sauter rapidement vers la nuit. # # ATES.weather_on # Permet d'activer la météo. # # ATES.weather_off # Permet de désactiver la météo. # # ATES.lock_weather # Permet de blocker le temps actuel sans désactiver la météo. # # ATES.unlock_weather # Permet de déblocker la météo. # # ATES.weather_active? # Retourne "true" si la météo est activer, sinon "false". # # ATES.set_time(TIME_INDEX or TIME_NAME) # Définis l'heure actuel par rapport à l'heure de l'index de TIME_INDEX ou avec # le nom de TIME_NAME. Mieux vaut utiliser TIME_NAME car quelques bug peuvent survenir # à l'utilisation de TIME_INDEX. # # ATES.go_inside # Une caractéristique de DDNS permettant de changer le mode de lumière pour l'intérieur. # # ATES.go_inside_dark # Une caractéristique de DDNS permettant de changer le mode de lumière pour un intérieur sombre. # # ATES.go_outside # Une caractéristique de DDNS permettant de changer le mode de lumière pour l'extérieur. # # ATES.set_weather(INDEX) # Configure la météo par rapport à INDEX. # # ATES.terrain=(TERRAIN_NAME) # Configure le terrain par rapport à TERRAIN_NAME. # # ATES.time_name # Retourne le nom du moment de la journée. # # - Conseils d'amélioration: # # Si vous souhaitez mettre en œuvre le DDNS plus loin dans votre jeu et, par exemple # permettre des comportements différents de monstres durant la journée et la nuit, # il vous suffit de vérifier l'état de l'interrupteur approprié. Par exemple # si NSwitch est activée infliger "Sleep" sur un ennemi. # # # Info additionelle: # # Les teites jour/nuit ont été testés de manière appropriée et les teints optimales # sont utilisé. # Gardez à l'esprit que ATES est initialement désactivée, vous devez l'activer en # utilisant les ATES.on et ATES.tint_on ensembles. (Note trad. : faux !) # # Si vous trouvez des bugs, reportez les ici : # http://forum.chaos-project.com #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= module ATES #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # START Configuration #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # ID de l'interrupteur du jour. DSWITCH = 51 # ID de l'interrupteur de la nuit. NSWITCH = 52 # ID de la varible de la température. TVARIABLE = 51 # Durée d'une journée en secondes dans le jeu, ne peut pas être inférieur à 36. # Ici une minute dans le jeu est égale à 2 seconde IRL. LENGTH = 2880 # Le montant à multiplier pour entendre le son de la météo de l'intérieur. INSIDE_SOUND = 0.7 # le montant à multiplier pour les tons rouge, vert, bleu et gris quand à # on est à l'intérieur. INSIDE_TONE = 0.0 # La teintes des intérieurs sombres. DARK_INSIDE_TONE = Tone.new(-85, -85, -85, 85) # Config de la météo, créez des nouvelles météo ici # note - si vous ne voulez pas un certain effet comme la météo, le brouillard ou le son, # il suffit de laisser le tableau pour cet effet vide. # ['NOM', RIGUEUR_CLIMAT, [TYPE_CLIMAT, FAIBLE_RESISTANCE..HAUTE_RESISTANCE], # [NOM_SON, VOLUME_MIN_SON..VOLUME_MAX_SON, HAUTEUR_SON], [NOM_BROUILLARD, OPACITE_BROUILLARD, NUANCE_BROUILLARD, # ZOOM_BROUILLARD, BROUILLARD_SX, BROUILLARD_SY, [TON_ROUGE, TON_VERT, TON_BLEU, TON_GRIS]], # [NOM_SON_EFFET, VOLUME_MIN_SON..VOLUME_MAX_SON, HAUTEUR_SON, PROBABILITE_EFFET, # DUREE_FLASH, [COULEUR_FLASH_ROUGE, COULEUR_FLASH_VERT, COULEUR_FLASH_BLEU]]] WEATHER = [['Crachin', 0, 1..4, [1], ['005-Rain01', 65..80, 100], [], []], ['Pluie', 0, 5..8, [1], ['006-Rain02', 75..90, 100], [], ['061-Thunderclap01', 60..85, 100, 0.07, 4, [255, 255, 255]]], ['Orage', 1, 9..10, [1], ['007-Rain03', 80..100, 100], [], ['061-Thunderclap01', 70..95, 110, 0.08, 6, [255, 255, 255]]], ['Couvert', 0, 1..1, [], [], ['002-Clouds01', 60, 0, 200, 4, 3, [0, 0, 0, 0]], []], ['Pluie', 0, 1..4, [2], ['006-Rain02', 70..85, 100], [], ['061-Thunderclap01', 65..90, 110, 0.08, 6, [255, 255, 255]]], ['Orage', 1, 5..8, [2], ['007-Rain03', 75..90, 100], [], ['061-Thunderclap01', 70..95, 110, 0.09, 7, [255, 255, 255]]], ['Orage', 2, 9..10, [2], ['007-Rain03', 90..100, 100], [], ['061-Thunderclap01', 85..100, 110, 0.11, 7, [255, 255, 255]]], ['Rafale', 1, 1..4, [3], ['002-Wind02', 70..85, 100], [], []], ['Neige', 1, 5..8, [3], ['003-Wind03', 80..95, 100], [], []], ['Blizzard', 2, 9..10, [3], ['004-Wind04', 85..100, 100], [], []]] # Durée normale de la météo en seconde. WEATHER_DURATION = 1140 # Variation de la météo en seconde. WEATHER_VARIANCE = 480 # Nom du temps par défault (ce qui est motré sur l'HUD quand # il n'y à pas de météo spéciale). DEFAULT_WEATHER_NAME = 'Soleil' # Config des saisons, créez de nouvelles saison en utilisant ce modéle : # ['NOM', JOUR_COMMENCANT, MOIS_COMMENCANT, TEMPERATURE_MIN..TEMP_MAX, PROBABILITE_TEMPS, # PROBABILITE_MAUVAIS_TEMPS, PROBABILITE_TRES_MAUVAIS_TEMPS, [POSSIBILITE_TEMPS]] SEASONS = [ ['Printemps', 22, 3, 0..25, 0.003, 0.3, 0.05, [0, 1, 2, 3, 4, 5]] , ['Eté', 21, 6, 20..35, 0.003, 0.1, 0.2, [0, 1, 3, 4, 5, 6]] , ['Automne', 20, 9, 0..25, 0.003, 0.2, 0.1, [0, 2, 3, 4, 5, 7]] , ['Hiver', 21, 12, -20..5, 0.003, 0.5, 0.1, [0, 2, 3, 4, 7, 8, 9]] ] # Cconfi terrain, créez de nouveaux terrain en utilisant ce modéle : # ['NOM', TEMP_MIN..TEMP_MAX, TEMPS_EXCLU] TERRAINS = [ ['Forêt', -7..0, [3]], ['Désert', 11..16, [8, 9]], ['Montagne', -9..-4, []], ['Plaine', -2..0, []], ['Plage', -5..-2, [8, 9]] ] # Date du jour le plus long, la plus longue nuit est une demi année plus tôt/tard. LONGEST = [21, 6] # Début de la journée. DAY_START = "Matin" # Début de la nuit. NIGHT_START = "Crépuscule" # Les différentes modification de teintes et différence de température à certain moment da la journée pendant les plus longs et plus courts jours. # Pour créer un nouveau moment dans la journé, ajouter ceci à TIMES : NOM => [ROUGE, VERTE, BLEU, GRIS, MODIFICATEUR_TEMP] TIMES = { "Aube" => [-17, -17, 17, 0, -4], "Matin" => [48, 30, 30, 0, -2], "Midi" => [24, 10, 10, 0, 5], "Soir" => [57, -17, -17, 0, 1], "Crépuscule" => [-17, -17, 17, 0, -3], "Nuit" => [-150, -120, -120, 200, -8] } # Quand vous les avez personnalisé, mettre les tons dans LONG_TIMES et SHORT_TIMES avec [nom_du_moment, heure, minute] LONG_TIMES = [["Aube", 4, 30], ["Matin", 5, 30], ["Midi", 13, 00], ["Soir", 21, 00], ["Crépuscule", 22, 00], ["Nuit", 1, 30]] SHORT_TIMES = [["Aube", 6, 30], ["Matin", 7, 30], ["Midi", 13, 00], ["Soir", 16, 30], ["Crépuscule", 17, 00], ["Nuit", 23, 30]] # rendre l'écran plus lumineux pendant les jours d'été. OVERLIGHTING = true # rendre l'écran plus sombre pendant la nuit, non recommandé. OVERDARKENING = false # la premiére année du calendrier, le joueur ne peut allé défiler avant. FYEAR = 1990 # la dernière année du calendrier, le joueur ne peut allé défiler après. LYEAR = 2099 # le suffixe des température TEMP_SUFFIX = "°C" # les différentes vacances et leurs dates # le format pour ajouter de nouvelles vacances est: # [NOM, TYPE_CONFIG, MOIS, (JOUR ou JOUR_SEMAINE, NOMBRE)] # si vous souhaitez utiliser JOUR ou JOUR_SEMAINE, NOMBRE dépend de SETUP_TYPE: # (0 - JOUR; 1 - JOUR_SEMAINE, NOMBRE) # note - Les vacances du moment remplace le nom du jour sur l'HUD HOLIDAYS = [ ["Noël", 0, 11, 24], ["Nouvel An", 0, 0, 0], ["Thanksgiving", 1, 10, 4, 4], ["Jour de la Marmotte", 0, 1, 1], ["St Valentin", 0, 1, 13], ["Jour de la Terre", 0, 3, 21], ["Jour de l'arbre", 1, 3, 5, -1], ["Fête des Mére", 1, 5, 7, 3], ["Fête des Pére", 1, 6, 7, 3], ["Halloween", 0, 9, 30], ] # Format de l'HUD # par default : ['%H:%M%s', '%A', '%d/%m/%Y', '%S'] # cela veut dire : 1ere rangée - "HEURES:MINUTES SUFFIXE" # 2nd rangée - "JOUR_SEMAINE" # 3eme rangée - "JOUR/MOIS/ANNEE" # 4eme rangée - "SAISON" # utilisez [] pour ne pas avoir d'HUD # differentes combinaisons à mettre pour l'HUD : # %H - Heure # %M - Minute # %s - Suffixe (AM or PM) (only if not using 24 hour time) # %A - Jour de la semaine # %d - Jour du mois # %D - Jour de l'année # %m - Mois # %n - Nom du mois # %l - Durée du mois # %Y - Année # %L - Durée année # %S - Saison # %w - Temps # %t - Terrain # %T - Température # %p - Moment de la journée CFORMAT = ['%H:%M', '%d/%m/%Y', '%A', '%w'] # largeur de l'HUD CWIDTH = 180 # noms de vos jours, définit automatiquement la longueur d'une semaine WEEKDAYS = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'] WEEKDAY_ABBREVIATIONS = ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'] # Noms de vos mois, définit automatiquement la longueur d'une année MONTHS = ['Janvier', 'Fevrier', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Aout', 'Septembre', 'Octobre', 'Novembre', 'Decembre'] # Abbréviation du noms des mois MONTH_ABBREVIATIONS = ['Jan', 'Fev', 'Mars', 'Avr', 'Mai', 'Juin', 'Jui', 'Aout', 'Sept', 'Oct', 'Nov', 'Dec'] # jours par mois MONTHDAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] # le premier jour dans le jeu [JOUR, MOIS, ANNÉE, SEMAINE] # définir cette option à [] si vous voulez que le jeu commence "maintenant" START = [29, 6, 2014, 1] # définir cette option à true pour activer le temps militaire (sur 24 heures) HOUR24 = true #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # END Configuration #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: mon = (LONGEST[1] + MONTHS.length / 2) % 12 mon = 12 if mon == 0 day = LONGEST[0] + (MONTHS.length % 2) == 1 ? MONTHDAYS[mon - 1] / 2 : 0 while day > MONTHDAYS[mon - 1] day -= MONTHDAYS[mon - 1] mon = (mon + 1) % 12 mon = 12 if mon == 0 end SHORTEST = [day, mon] $ates = 1.0 #============================================================================ # ATES::Time #============================================================================ class Time attr_accessor :min attr_accessor :hour attr_accessor :day attr_accessor :mon attr_accessor :year attr_accessor :wday def initialize(m, h, d, mon, y, w) @min, @hour, @day, @mon, @year, @wday = m, h, d, mon, y, w end end def self.on $game_system.ates.active = true return true end def self.off $game_system.ates.active = false return true end def self.tint_on(frames = 0) $game_screen.start_tone_change($game_system.ates.get_environment[0], frames) $game_system.ates.tinting = true return true end def self.tint_off(reset = true) $game_screen.start_tone_change(Tone.new(0, 0, 0, 0), 0) if reset $game_system.ates.tinting = false return true end def self.weather_off $game_system.ates.weather.weather_enabled = false $game_system.ates.weather.pause_weather(0) if $game_system.ates.weather.current_weather and $game_system.ates.weather.current_weather != -1 end def self.weather_on $game_system.ates.weather.weather_enabled = true $game_system.ates.weather.resume_weather(0) if $game_system.ates.weather.current_weather and $game_system.ates.weather.current_weather != -1 end def self.weather_active? return $game_system.ates.weather.weather_enabled end def self.lock_weather $game_system.ates.weather.locked = true end def self.unlock_weather $game_system.ates.weather.locked = false end def self.clock_on $game_system.show_clock = true return true end def self.clock_off $game_system.show_clock = false return true end def self.active? return $game_system.ates.active end def self.tinting? return $game_system.ates.tinting end def self.day? i = $game_system.ates.time_index while true if $game_system.ates.current_times[i][0] == DAY_START return true elsif $game_system.ates.current_times[i][0] == NIGHT_START return false end i = (i + $game_system.ates.current_times.length - 1) % $game_system.ates.current_times.length end end def self.night? return !(self.day?) end def self.make_it_day time = $game_system.ates.current_times.select { |time| time[0] == DAY_START } h, m = time[0][1], time[0][2] $game_system.ates.time.hour = h $game_system.ates.time.min = m return true end def self.make_it_night time = $game_system.ates.current_times.select { |time| time[0] == NIGHT_START } h, m = time[0][1], time[0][2] $game_system.ates.time.hour = h $game_system.ates.time.min = m return true end def self.set_time(time = 0) return unless $game_system if time.is_a?(Fixnum) time = $game_system.ates.current_times[time.to_i] else time = $game_system.ates.current_times.select { |current_time| current_time[0] == time }[0] end h, m = time[1], time[2] $game_system.ates.time.hour = h $game_system.ates.time.min = m return true end def self.day_start return DAY_START end def self.night_start return NIGHT_START end def self.go_inside_dark weather = $game_system.ates.weather.current_weather $game_system.ates.map_type = 2 self.tint_on $game_system.ates.weather.pause_weather(0) return true if weather == -1 low, high = weather[2].first, weather[2].last intensity = $game_system.ates.weather.current_intensity if weather[4].length > 0 volume = ATES::INSIDE_SOUND * weather[4][1].first + (weather[4][1].last - weather[4][1].first) * (high - intensity).to_f / (high - low) bgm = RPG::AudioFile.new(weather[4][0], volume, weather[4][2]) $game_system.bgs_play(bgm) end return true end def self.go_inside weather = $game_system.ates.weather.current_weather $game_system.ates.map_type = 1 self.tint_on $game_system.ates.weather.pause_weather(0) return true if weather == -1 low, high = weather[2].first, weather[2].last intensity = $game_system.ates.weather.current_intensity if weather[4].length > 0 volume = ATES::INSIDE_SOUND * weather[4][1].first + (weather[4][1].last - weather[4][1].first) * (high - intensity).to_f / (high - low) bgm = RPG::AudioFile.new(weather[4][0], volume, weather[4][2]) $game_system.bgs_play(bgm) end return true end def self.go_outside $game_system.ates.weather.resume_weather(0) $game_system.ates.map_type = 0 self.tint_on return true end def self.set_weather(id) $game_system.ates.weather.set_weather(WEATHER[id]) end def self.terrain=(terrain) terrain = TERRAINS[terrain.to_i][0] if terrain.is_a?(Fixnum) $game_system.ates.terrain = terrain end def self.advance(m, h, d, mon, y) return false if [m, h, d, mon, y].any? {|i| i < 0} changed = false h += ($game_system.ates.time.min + m) / 60 $game_system.ates.time.min = ($game_system.ates.time.min + m) % 60 d += ($game_system.ates.time.hour + h) / 24 changed = true if d > 0 $game_system.ates.time.hour = ($game_system.ates.time.hour + h) % 24 while d > 0 if $game_system.ates.time.day < MONTHDAYS[mon] $game_system.ates.time.day += 1 else $game_system.ates.time.day = 0 mon = (mon + 1) % MONTHS.size end $game_system.ates.time.wday += 1 $game_system.ates.time.wday %= WEEKDAYS.size d -= 1 end y += ($game_system.ates.time.mon + mon) / MONTHS.size $game_system.ates.time.mon = ($game_system.ates.time.mon + mon) % MONTHS.size $game_system.ates.time.year += y return changed end def self.time_name return $game_system.ates.current_times[$game_system.ates.time_index][0] end end if ATES::MONTHS.size > ATES::MONTHDAYS.size raise 'ATEScfgError: Not all months have a length in days specified!' #elsif ATES::DAY_START > ATES::NIGHT_START # raise 'ATEScfgError: A night can\'t start earlier than a day.' elsif ATES::LENGTH < 36 raise 'ATEScfgError: A day\'s length must be equal to or greater than 36 seconds!' end #============================================================================== # Weather #============================================================================== class Weather attr_accessor :current_weather, :current_intensity, :weather_enabled, :locked def initialize @current_weather = -1 @current_intensity = 0 @normal_weather = [] @bad_weather = [] @very_bad_weather = [] @weather_enabled = true @locked = false end def decimal_places(num) if num.is_a?(Float) return num.to_s.split('.')[1].length else return 0 end end def get_weather(severity = 0) weather = [] season = $game_system.ates.get_full_season ATES::WEATHER.each_with_index { |el, ind| weather.push(el) if el[1] == severity and season[7].include?(ind) } return weather end def update season = $game_system.ates.get_full_season if !@season or @season != season @normal_weather = get_weather @bad_weather = get_weather(1) @very_bad_weather = get_weather(2) @season = season end unless @locked places = [decimal_places(season[4]), decimal_places(season[5]), decimal_places(season[6])] if rand(10 ** places[0]) <= season[4] * (10 ** places[0]) and season[7].length > 0 if rand(10 ** places[1]) <= season[4] * (10 ** places[1]) and @bad_weather.length > 0 weather = rand(@bad_weather.length) weather = @bad_weather[weather] set_weather(weather) elsif rand(10 ** places[2]) <= season[4] * (10 ** places[2]) and @very_bad_weather.length > 0 weather = rand(@very_bad_weather.length) weather = @very_bad_weather[weather] set_weather(weather) elsif @normal_weather.length > 0 weather = rand(@normal_weather.length) weather = @normal_weather[weather] set_weather(weather) end end end if @current_weather != -1 update_effect if @weather_enabled and @current_weather[6].length > 0 @weather_count += 1 if @weather_count >= @weather_duration stop_weather unless @locked end end end def update_effect weather = @current_weather places = decimal_places(weather[6][3]) if rand(10 ** places) <= weather[6][3] * 10 ** places high, low = weather[2].first, weather[2].last vol = weather[6][1].first + (weather[6][1].last - weather[6][1].first) * (high - @current_intensity).to_f / (high - low) vol *= ATES::INSIDE_SOUND if $game_system.ates.map_type > 0 sound = RPG::AudioFile.new(weather[6][0], vol, weather[6][2]) $game_system.se_play(sound) col = Color.new(0, 0, 0) $game_screen.start_flash(Color.new(*weather[6][5]), weather[6][4]) end end def stop_weather(speed = -1) return if @current_weather == -1 speed = speed == -1 ? rand(10) + 60 : speed if @current_weather[3].length > 0 $game_screen.weather(0, 1, speed) end if @current_weather[4].length > 0 $game_system.bgs_fade(speed.to_f / 40) end if @current_weather[5].length > 0 $game_map.fog_name = '' end @current_weather = -1 end def pause_weather(speed = -1) return if @current_weather == -1 $game_system.ates.show_weather = false speed = speed == -1 ? rand(10) + 60 : speed if @current_weather[3].length > 0 $game_screen.weather(0, 1, speed) end if @current_weather[4].length > 0 $game_system.bgs_fade(speed.to_f / 40) end if @current_weather[5].length > 0 $game_map.fog_name = '' end end def resume_weather(speed = -1) return if @current_weather == -1 $game_system.ates.show_weather = true weather = @current_weather intensity = @current_intensity low, high = weather[2].first, weather[2].last speed = speed == -1 ? rand(10) + 60 : speed if weather[3].length > 0 $game_screen.weather(weather[3][0], intensity, speed) end if weather[4].length > 0 volume = weather[4][1].first + (weather[4][1].last - weather[4][1].first) * (high - intensity).to_f / (high - low) bgm = RPG::AudioFile.new(weather[4][0], volume, weather[4][2]) $game_system.bgs_play(bgm) end if weather[5].length > 0 $game_map.fog_name = weather[5][0] $game_map.fog_opacity = weather[5][1] $game_map.fog_hue = weather[5][2] $game_map.fog_zoom = weather[5][3] $game_map.fog_sx = weather[5][4] $game_map.fog_sy = weather[5][5] $game_map.start_fog_tone_change(Tone.new(*weather[5][6]), 0) end end def set_weather(weather, speed = -1) stop_weather if @current_weather != -1 @weather_count = 0 @weather_duration = ATES::WEATHER_DURATION + rand(ATES::WEATHER_VARIANCE) low, high = weather[2].first, weather[2].last intensity = rand(high + 1 - low) + low @current_weather = weather @current_intensity = intensity return unless @weather_enabled if weather.is_a?(Fixnum) weather = WEATHER[weather] end speed = speed == -1 ? rand(10) + 60 : speed if weather[4].length > 0 volume = weather[4][1].first + (weather[4][1].last - weather[4][1].first) * (high - intensity).to_f / (high - low) volume *= ATES::INSIDE_SOUND if $game_system.ates.map_type > 0 bgm = RPG::AudioFile.new(weather[4][0], volume, weather[4][2]) $game_system.bgs_play(bgm) end return if $game_system.ates.map_type > 0 if weather[3].length > 0 if $modified_aws and weather[3].length > 1 $game_screen.weather(weather[3][0], intensity, speed, weather[3][1]) else $game_screen.weather(weather[3][0], intensity, speed) end end if weather[5].length > 0 $game_map.fog_name = weather[5][0] $game_map.fog_opacity = weather[5][1] $game_map.fog_hue = weather[5][2] $game_map.fog_zoom = weather[5][3] $game_map.fog_sx = weather[5][4] $game_map.fog_sy = weather[5][5] $game_map.start_fog_tone_change(Tone.new(*weather[5][6]), 0) end end end #============================================================================== # Game_System #============================================================================== class Game_System attr_accessor :ates attr_accessor :show_clock alias init_ates_later initialize def initialize init_ates_later @ates = Game_ATES.new @show_clock = (ATES::CFORMAT != []) end end #============================================================================== # Game_ATES #============================================================================== class Game_ATES attr_accessor :active attr_accessor :tinting attr_accessor :time attr_accessor :weather attr_accessor :frame_count attr_accessor :current_times attr_accessor :tone attr_accessor :map_type attr_accessor :show_weather attr_accessor :terrain attr_accessor :temp attr_reader :holiday attr_reader :time_index def initialize if ATES::START.size == 4 @time = ATES::Time.new(0, 0, ATES::START[0], ATES::START[1], ATES::START[2], ATES::START[3]) else @time = Time.now @time = ATES::Time.new(@time.min, @time.hour, @time.mday, @time.mon, @time.year, @time.wday) end @weather = Weather.new @long_times = ATES::LONG_TIMES.sort { |t1, t2| t1[1] * 100 + t1[2] <= t2[1] * 100 + t2[2] } @short_times = ATES::SHORT_TIMES.sort { |t1, t2| t1[1] * 100 + t1[2] <= t2[1] * 100 + t2[2] } @year_length = ATES::MONTHDAYS.inject { |sum, x| sum + x } @terrain = '' @current_times = setup_times @temp_modifier = (rand(201) - 100) / 100.0 @tone, @temp = get_environment @holiday = get_holiday(@time.mon, @time.day, @time.wday) @s_time = get_time(@time.min, @time.hour) $game_screen.start_tone_change(@tone, 0) if $game_screen @active = true @tinting = true @show_weather = true @map_type = 0 @frame_count = 0 end def get_holiday(month, day, wday) ATES::HOLIDAYS.select { |i| case i[1] when 0: i[2..3] == [month, day] when 1: if i[4] > 0 i[2] == month and i[3] == wday and i[4] == (day.to_f / 7 + 1).floor elsif i[4] < 0 i[2] == month and i[3] == wday and -i[4] == ((ATES::MONTHDAYS[month] - 1 - day).to_f / 7 + 1).floor end end }[0] end def get_environment red = 0 green = 0 blue = 0 grey = 0 @temp_modifier += (rand(3) - 1) / 100.0 if rand(10) == 0 changed = false for i in 0...@current_times.length time1 = get_time(@current_times[i][2], @current_times[i][1]) time2 = get_time(@current_times[(i + 1) % @current_times.length][2], @current_times[(i + 1) % @current_times.length][1]) current = get_time(@time.min, @time.hour) if time2 < time1 time2 += 24 * 60 end if current < time1 current += 24 * 60 end if time1 <= current and time2 >= current changed = true tone1 = @current_times[i] tone2 = @current_times[(i + 1) % @current_times.length] tone1 = ATES::TIMES[tone1[0]] tone2 = ATES::TIMES[tone2[0]] max = time2 - time1 ratios = [(current - time1).to_f / max, (time2 - current).to_f / max] red = tone1[0] * ratios[1] + tone2[0] * ratios[0] green = tone1[1] * ratios[1] + tone2[1] * ratios[0] blue = tone1[2] * ratios[1] + tone2[2] * ratios[0] grey = tone1[3] * ratios[1] + tone2[3] * ratios[0] temp_range = get_full_season[3] temp_range = [temp_range.first, temp_range.last].sort unless @base_temp temp = temp_range[0] + rand(temp_range[1] - temp_range[0] + 1) if @terrain != '' modifier = ATES::TERRAINS.select { |terrain| terrain[0] == @terrain }[0][1] modifier = [modifier.first, modifier.last].sort modifier = modifier[0] + rand(modifier[1] - modifier[0] + 1) temp += modifier end @base_temp = temp else temp = @base_temp end temp_mod = round(tone1[4] * ratios[1] + tone2[4] * ratios[0], 2) temp += temp_mod + @temp_modifier @time_index = ratios[0] < 0.5 ? i : (i + 1) % @current_times.length break end end print "not right" unless changed if @map_type == 1 return Tone.new(red * ATES::INSIDE_TONE, green * ATES::INSIDE_TONE, blue * ATES::INSIDE_TONE, grey * ATES::INSIDE_TONE), temp elsif @map_type == 2 return ATES::DARK_INSIDE_TONE, temp else return Tone.new(red, green, blue, grey), temp end end def setup_times current_date = [@time.day, @time.mon] if current_date == ATES::LONGEST or @long_times == @short_times return @long_times elsif current_date == ATES::SHORTEST return @short_times end short_times = @long_times.clone addons = @short_times.clone current_date = get_date(*current_date) long, short = get_date(*ATES::LONGEST), get_date(*ATES::SHORTEST) dists = [] if (current_date >= short and current_date <= long) dists = [current_date - short, long - current_date] elsif (current_date >= short and short >= long) dists = [current_date - short, long + @year_length - current_date] elsif (current_date <= long and long <= short) dists = [current_date + @year_length - short, long - current_date] elsif (current_date >= long and current_date <= short) dists = [current_date - long, short - current_date] elsif (current_date <= short and short <= long) dists = [current_date + @year_length - long, short - current_date] elsif (current_date >= long and long >= short) dists = [current_date - long, short + @year_length - current_date] end sum = dists.inject { |sum, x| sum + x } short_times.each { |tone| addons.each { |addon| if tone[0] == addon[0] ts = [tone[1] * 100 + tone[2] * 50 / 30.0, addon[1] * 100 + addon[2] * 50 / 30.0] ts = ts[0] * dists[0] / sum.to_f + ts[1] * dists[1] / sum.to_f h = (ts / 100).floor m = ((ts - h * 100) * 30 / 50).floor tone[1], tone[2] = h, m end } } return short_times.sort { |x, y| get_time(x[2], x[1]) <= get_time(y[2], y[1]) } end def round(num, places = 0) return ((num * 10 ** places).round.to_f) / (10 ** places) end def get_time(minutes, hours) return minutes + hours * 60 end def get_season season_list = ATES::SEASONS.sort { |x, y| get_date(x[1], x[2]) <= get_date(y[1], y[2]) } day = @time.day month = @time.mon current = get_date(day, month) for i in 0...season_list.length seasons = [season_list[i], season_list[(i + 1) % season_list.length]] times = [get_date(seasons[0][1], seasons[0][2]), get_date(seasons[1][1], seasons[1][2])] if times[0] <= current and current < times[1] return seasons[0][0] end end return season_list[0][0] end def get_full_season season_list = ATES::SEASONS.sort { |x, y| get_date(x[1], x[2]) <= get_date(y[1], y[2]) } day = @time.day month = @time.mon current = get_date(day, month) for i in 0...season_list.length seasons = [season_list[i], season_list[(i + 1) % season_list.length]] times = [get_date(seasons[0][1], seasons[0][2]), get_date(seasons[1][1], seasons[1][2])] if times[0] <= current and current < times[1] return seasons[0] end end return season_list[0] end def get_date(day, month) month = ATES::MONTHS.length if month == 0 return (ATES::MONTHDAYS[0...month - 1].inject { |sum, x| sum + x } or 0) + day end def update if @active @frame_count += 1 changed = false if @frame_count % (ATES::LENGTH / 36) == 0 tmp = @time.day changed = (ATES.advance(1, 0, 0, 0, 0)) if @time.day != tmp @holiday = get_holiday(@time.mon, @time.day, @time.wday) end @weather.update end if changed @current_times = setup_times end end if ATES.day? $game_map.need_refresh = true if $game_switches[ATES::NSWITCH] $game_switches[ATES::DSWITCH] = true $game_switches[ATES::NSWITCH] = false else $game_map.need_refresh = true if $game_switches[ATES::DSWITCH] $game_switches[ATES::DSWITCH] = false $game_switches[ATES::NSWITCH] = true end @tone, @temp = get_environment tmp = get_time(@time.min, @time.hour) $game_screen.start_tone_change(@tone, ((@s_time - tmp).abs < [1440 / ATES::LENGTH, 1].max ? 0 : 20)) if @tinting end end #============================================================================== # Bitmap #============================================================================== class Bitmap if $tons_version == nil || $tons_version < 1.6 alias draw_text_shaded_later draw_text end def draw_text_full(x2, y2, w2 = 0, h2 = 0, text2 = '', a2 = 0) if x2.is_a?(Rect) x, y, w, h, text, a = x2.x, x2.y, x2.width, x2.height, y2, w2 else x, y, w, h, text, a = x2, y2, w2, h2, text2, a2 end save_color = self.font.color.clone self.font.color = Color.new(0, 0, 0) [x-1, x+1].each {|xx| [y-1, y+1].each {|yy| draw_text_shaded_later(xx, yy, w, h, text, a)}} self.font.color = save_color draw_text_shaded_later(x, y, w, h, text, a) end end #============================================================================== # Clock_Sprite #============================================================================== class Clock_Sprite < Sprite def initialize super self.x, self.y, self.z = 640 - 8 - ATES::CWIDTH, 8, 5000 self.bitmap = Bitmap.new(ATES::CWIDTH, ATES::CFORMAT.length * 32) if $fontface != nil self.bitmap.font.name = $fontface elsif $defaultfonttype != nil self.bitmap.font.name = $defaultfonttype end self.bitmap.font.size = 26 @odd = 0 draw if $game_system.ates.active end def draw self.bitmap.clear hours = $game_system.ates.time.hour minutes = sprintf('%02d', $game_system.ates.time.min) weekday = ATES::WEEKDAYS[$game_system.ates.time.wday - 1] wday_abbr = ATES::WEEKDAY_ABBREVIATIONS[$game_system.ates.time.wday - 1] day = $game_system.ates.time.day + 1 month = $game_system.ates.time.mon + 1 yday = ATES::MONTHDAYS[0..month - 1].inject { |s, r| s + r } + day month_name = ATES::MONTHS[month - 1] month_abbr = ATES::MONTH_ABBREVIATIONS[month - 1] month_days = ATES::MONTHDAYS[month - 1] year = $game_system.ates.time.year year_days = ATES::MONTHDAYS.inject { |s, r| s + r } season = $game_system.ates.get_season terrain = $game_system.ates.terrain temp = $game_system.ates.temp.to_s + ATES::TEMP_SUFFIX weather = $game_system.ates.weather.current_weather == -1 ? ATES::DEFAULT_WEATHER_NAME : $game_system.ates.weather.current_weather[0] tod = $game_system.ates.current_times[$game_system.ates.time_index][0] hday = $game_system.ates.holiday if hday != nil weekday = hday[0] end clock_text = ATES::CFORMAT.map { |ln| ln.clone } unless ATES::HOUR24 suffix = "PM" if hours < 12 suffix = "AM" hours = 12 if hours == 0 elsif hours > 12 suffix = "PM" hours -= 12 end else suffix = "" hours = 24 if hours == 0 hours = sprintf('%02d', hours) end colon = @odd % 2 == 0 ? " " : ":" clock_text.each { |ln| ln.gsub!(/%M/, minutes) ln.gsub!(/%H/, hours.to_s) ln.gsub!(/%A/, weekday) ln.gsub!(/%s/, " " + suffix) ln.gsub!(/:/, colon) ln.gsub!(/%m/, month.to_s) ln.gsub!(/%n/, month_name) ln.gsub!(/%l/, month_days.to_s) ln.gsub!(/%Y/, year.to_s) ln.gsub!(/%L/, year_days.to_s) ln.gsub!(/%d/, day.to_s) ln.gsub!(/%D/, yday.to_s) ln.gsub!(/%S/, season) ln.gsub!(/%w/, weather) ln.gsub!(/%t/, terrain) ln.gsub!(/%T/, temp) ln.gsub!(/%p/, tod) } if @odd % 2 == 0 string = "#{hours} #{minutes}" else string = "#{hours}:#{minutes}" end string += " #{suffix}" unless ATES::HOUR24 for i in 0...clock_text.length self.bitmap.draw_text_full(0, i * 32, self.bitmap.width, 32, clock_text[i], 1) end @odd = (@odd + 1) % 2 end end #============================================================================== # Scene_Map #============================================================================== class Scene_Map alias main_ates_later main def main @clock = Clock_Sprite.new if $game_system.show_clock main_ates_later @clock.dispose if @clock != nil end alias update_ates_later update def update $game_system.ates.update update_ates_later if $game_system.show_clock @clock = Clock_Sprite.new if @clock == nil @clock.draw if $game_system.ates.frame_count % 20 == 0 elsif @clock != nil @clock.dispose @clock = nil end end end #============================================================================== # Scene_Battle #============================================================================== class Scene_Battle alias update_ates_later update def update $game_system.ates.update update_ates_later end end #============================================================================== # Game_Map #============================================================================== class Game_Map alias setup_ates_later setup def setup(map_id) $game_system.ates.update setup_ates_later(map_id) if $game_system.ates.show_weather and $game_system.ates.weather.current_weather and $game_system.ates.weather.current_weather != -1 weather = $game_system.ates.weather.current_weather if weather[5].length > 0 $game_map.fog_name = weather[5][0] $game_map.fog_opacity = weather[5][1] $game_map.fog_hue = weather[5][2] $game_map.fog_zoom = weather[5][3] $game_map.fog_sx = weather[5][4] $game_map.fog_sy = weather[5][5] $game_map.start_fog_tone_change(Tone.new(*weather[5][6]), 0) end end @events.each { |ev| ev = ev[1] if ev.list and ev.list.length > 0 and ev.list[0].code == 108 and ev.list[0].parameters[0] =~ /Terrain='(.+)'/ $game_system.ates.terrain = $1 end } end end #============================================================================== # Scene_Calendar #============================================================================== class Scene_Calendar def main # Make calendar window @calendar_window = Window_Calendar.new @calendar_window.active = true @calendar_window.z = 1000 #@day_window = Window_Day.new #@day_window.z = 1010 #@day_window.visible = false #@dir = rand(4) # Make spriteset @spriteset = Spriteset_Map.new # Execute transition Graphics.transition # Main loop loop do # Update game screen Graphics.update # Update input information Input.update # Frame update update # Abort loop if screen is changed if $scene != self break end end # Prepare for transition Graphics.freeze # Dispose of window @calendar_window.dispose #@day_window.dispose # Dispose of spriteset @spriteset.dispose end def update @calendar_window.update #@day_window.update #if @calendar_window.active #if Input.trigger?(Input::C) # @day_window.visible = true # @day_window.active = true # @calendar_window.active = false # @day_window.x, @day_window.y = 80, 80 # @day_window.appear(@dir) # @dir = rand(4) #end if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) $scene = Scene_Map.new end #elsif @day_window.active #if Input.trigger?(Input::B) # @day_window.disappear(@dir) # @day_window.active = false # @calendar_window.active = true #end #end end end #============================================================================== # Window_Calendar #============================================================================== class Window_Calendar < Window_Base def initialize super(48, 48, 544, 384) self.contents = Bitmap.new(width - 32, height - 32) @month, @day, @wday, @year = $game_system.ates.time.mon, $game_system.ates.time.day, $game_system.ates.time.wday, $game_system.ates.time.year update refresh end def update prev_mon = @month if Input.repeat?(Input::LEFT) $game_system.se_play($data_system.cursor_se) continue = true @day -= 1 if @day == 0 @month -= 1 if @month == 0 unless @year == ATES::FYEAR @year -= 1 @month = ATES::MONTHS.length else @day = 1 @month = 1 continue = false end end @day = ATES::MONTHDAYS[@month - 1] end if continue @wday = (@wday + ATES::WEEKDAYS.length - 1) % ATES::WEEKDAYS.length @wday = ATES::WEEKDAYS.length if @wday == 0 end end if Input.repeat?(Input::RIGHT) $game_system.se_play($data_system.cursor_se) continue = true @day += 1 if @day == ATES::MONTHDAYS[@month - 1] + 1 @month += 1 if @month == ATES::MONTHS.length + 1 unless @year == ATES::LYEAR @year += 1 @month = 1 else @month = ATES::MONTHS.length @day = ATES::MONTHDAYS[@month - 1] continue = false end end @day = 1 end if continue @wday = (@wday + 1) % ATES::WEEKDAYS.length @wday = ATES::WEEKDAYS.length if @wday == 0 end end if Input.repeat?(Input::UP) $game_system.se_play($data_system.cursor_se) continue = true tmpday = @day @day -= ATES::WEEKDAYS.length if @day <= 0 @month -= 1 if @month == 0 unless @year == ATES::FYEAR @year -= 1 @month = ATES::MONTHS.length else @day = tmpday @month = 1 continue = false end end if continue tmp = (@wday + ATES::WEEKDAYS.length - @day) % ATES::WEEKDAYS.length tmp = ATES::WEEKDAYS.length if tmp == 0 if @wday > tmp tmp = tmp + ATES::WEEKDAYS.length - @wday else tmp = tmp - @wday end @day = ATES::MONTHDAYS[@month - 1] @day -= tmp end end end if Input.repeat?(Input::DOWN) $game_system.se_play($data_system.cursor_se) continue = true tmpday = @day @day += ATES::WEEKDAYS.length if @day >= ATES::MONTHDAYS[@month - 1] + 1 @month += 1 if @month == ATES::MONTHS.length + 1 unless @year == ATES::LYEAR @year += 1 @month = 1 else @day = tmpday @month = ATES::MONTHS.length continue = false end end if continue tmp = (@wday + ATES::MONTHDAYS[@month - 2] - @day) % ATES::WEEKDAYS.length tmp = ATES::WEEKDAYS.length if tmp == 0 if @wday <= tmp tmp -= ATES::WEEKDAYS.length end @day = @wday - tmp end end end super() refresh if prev_mon != @month row_count = (ATES::MONTHDAYS.max - 2) / ATES::WEEKDAYS.length + 2 row_height = height - 116 top_margin = ((row_height % row_count) / 2.0).ceil row_height -= row_height % row_count row_height /= row_count colwidth = width - 32 margin = ((colwidth % ATES::WEEKDAY_ABBREVIATIONS.length) / 2.0).ceil colwidth -= colwidth % ATES::WEEKDAY_ABBREVIATIONS.length colwidth /= ATES::WEEKDAY_ABBREVIATIONS.length start_wday = (@wday + ATES::WEEKDAYS.length - (@day - 1) % ATES::WEEKDAYS.length) % ATES::WEEKDAYS.length start_wday = ATES::WEEKDAYS.length if start_wday == 0 row = (@day + start_wday - 2) / ATES::WEEKDAYS.length self.cursor_rect.set(margin + (@wday - 1) * colwidth, 84 + top_margin + row * row_height, colwidth, 32) end def refresh self.contents.clear self.contents.font.size = 32 self.contents.font.color = system_color self.contents.draw_text_full(Rect.new(0, 0, width - 32, 32), ATES::MONTHS[@month - 1] + " " + @year.to_s, 1) self.contents.font.size = 24 colwidth = width - 32 margin = ((colwidth % ATES::WEEKDAY_ABBREVIATIONS.length) / 2.0).ceil colwidth -= colwidth % ATES::WEEKDAY_ABBREVIATIONS.length colwidth /= ATES::WEEKDAY_ABBREVIATIONS.length for i in 0...ATES::WEEKDAY_ABBREVIATIONS.length self.contents.draw_text_full(Rect.new(margin + i * colwidth, 40, colwidth, 32), ATES::WEEKDAY_ABBREVIATIONS[i], 1) end self.contents.fill_rect(Rect.new(0, 76, width - 32, 2), system_color) row_count = (ATES::MONTHDAYS.max - 2) / ATES::WEEKDAYS.length + 2 row_height = height - 116 top_margin = ((row_height % row_count) / 2.0).ceil row_height -= row_height % row_count row_height /= row_count cur_wday = (@wday + ATES::WEEKDAYS.length - (@day - 1) % ATES::WEEKDAYS.length) % ATES::WEEKDAYS.length cur_wday = ATES::WEEKDAYS.length if cur_wday == 0 start_wday = cur_wday cur_day = 1 cur_row = (cur_day - 1) / 7 while cur_day <= ATES::MONTHDAYS[@month - 1] if (cur_day == $game_system.ates.time.day and @month == $game_system.ates.time.mon and @year == $game_system.ates.time.year) self.contents.font.color = Color.new(240, 40, 40) elsif $game_system.ates.get_holiday(@month - 1, cur_day - 1, cur_wday) != nil self.contents.font.color = Color.new(150, 150, 0) else self.contents.font.color = normal_color end self.contents.draw_text_full(Rect.new(margin + (cur_wday - 1) * colwidth, 84 + top_margin + cur_row * row_height, colwidth, 32), cur_day.to_s, 1) cur_day += 1 cur_wday = cur_wday + 1 if cur_wday > ATES::WEEKDAYS.length cur_wday -= ATES::WEEKDAYS.length cur_row += 1 end end end end #============================================================================== # Window_Day #============================================================================== class Window_Day < Window_Base def initialize #(dir == 2 ? 320 : 48), (dir == 3 ? 240 : 48), (dir % 2 == 0 ? 272 : 544), (dir % 2 == 1 ? 192 : 384) super(80, 80, 480, 320) self.contents = Bitmap.new(width - 32, height - 32) end def appear(dir, duration = 40) @d_pos = [self.x, self.y] case dir when 0: self.x = -480 when 1: self.y = -320 when 2: self.x = 640 when 3: self.y = 480 end @s_pos = [self.x, self.y] @dir = dir @duration = duration @frames = 0 @moving = true end def disappear(dir, duration = 40) @s_pos = [self.x, self.y] case dir when 0: self.x += 560 when 1: self.y -= 400 when 2: self.x += 560 when 3: self.y += 400 end @d_pos = [self.x, self.y] self.x, self.y = *@s_pos @dir = dir @duration = duration @frames = 0 @moving = true end def update if @moving self.x = (@d_pos[0] * @frames + @s_pos[0] * (@duration - @frames)) / @duration self.y = (@d_pos[1] * @frames + @s_pos[1] * (@duration - @frames)) / @duration @moving = ([self.x, self.y] != @d_pos) @frames += 1 end super() end end class Window_Text < Window_Base def initialize super(48, 48, 544, 384) self.contents = Bitmap.new(width - 32, height - 32) @dual_keys = ['`','1','2','3','4','5','6','7','8','9','0','A','B','C','D','E', 'F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U', 'V','W','X','Y','Z','-','=','[',']','\\',';','\'',',','.','/'] @single_keys = ['NumberPad 0','NumberPad 1','NumberPad 2','NumberPad 3', 'NumberPad 4','NumberPad 5','NumberPad 6','NumberPad 7', 'NumberPad 8','NumberPad 9','Space','Enter','Tab'] @chars1 = ['`','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w', 'x','y','z','-','=','[',']','/',';','\'',',','.','\\'] @chars2 = ['~','!','@','#','$','%','^','&','*','(',')','A','B','C','D','E','F', 'G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W', 'X','Y','Z','_','+','{','}','?',':','"','<','>','|'] @chars = ['0','1','2','3','4','5','6','7','8','9',' ','\n','\t'] @text = "" @cursor = true end def update @dual_keys.each_with_index { |i, ind| if Input.repeat?(Input::Key[i]) @text += (Input.press?(Input::Key['Shift']) ? @chars2[ind] : @chars1[ind]) end } @single_keys.each_with_index { |i, ind| if Input.repeat?(Input::Key[i]) @text += @chars[ind] end } if Input.repeat?(Input::Key['Backspace']) @text = @text.split('') tmp = @text.pop() if (tmp == 'n' or tmp == 't') and @text[@text.length - 1] == '\\' @text.pop() end @text = @text.join('') end @cursor = !@cursor if Graphics.frame_count % 20 == 0 refresh end def refresh self.contents.clear tmp = @text.gsub(/((?:\\n)+)\z/, '') y_mod = $1 ? $1.length / 2 : 0 x_pos = y_mod > 0 lns = tmp.gsub(/\\t/,' ').split(/\\n/) y = 0 x = 0 lns.each_with_index { |ln, ind| rect = self.contents.text_size(ln) rect.height = self.contents.text_size('a').height rect.width += 1 unless ln.index(/[vVAwf\/\\]\z/).nil? rect.y = y self.contents.draw_text(rect, ln) y += rect.height x = rect.width } #p lns if lns.length > 1 height = self.contents.text_size('a').height y -= height unless lns.last.nil? y += y_mod * height x = (x_pos ? 0 : x + 1) self.contents.fill_rect(Rect.new(x, y, 2, height), Color.new(0, 0, 0)) if @cursor #@cursor = !@cursor end end unless $BlizzABS or ($tons_version and TONS_OF_ADDONS::CUSTOM_CONTROLS) #============================================================================== # module Input #============================================================================== module Input #---------------------------------------------------------------------------- # Simple ASCII table #---------------------------------------------------------------------------- Key = {'A' => 65, 'B' => 66, 'C' => 67, 'D' => 68, 'E' => 69, 'F' => 70, 'G' => 71, 'H' => 72, 'I' => 73, 'J' => 74, 'K' => 75, 'L' => 76, 'M' => 77, 'N' => 78, 'O' => 79, 'P' => 80, 'Q' => 81, 'R' => 82, 'S' => 83, 'T' => 84, 'U' => 85, 'V' => 86, 'W' => 87, 'X' => 88, 'Y' => 89, 'Z' => 90, '0' => 48, '1' => 49, '2' => 50, '3' => 51, '4' => 52, '5' => 53, '6' => 54, '7' => 55, '8' => 56, '9' => 57, 'NumberPad 0' => 45, 'NumberPad 1' => 35, 'NumberPad 2' => 40, 'NumberPad 3' => 34, 'NumberPad 4' => 37, 'NumberPad 5' => 12, 'NumberPad 6' => 39, 'NumberPad 7' => 36, 'NumberPad 8' => 38, 'NumberPad 9' => 33, 'F1' => 112, 'F2' => 113, 'F3' => 114, 'F4' => 115, 'F5' => 116, 'F6' => 117, 'F7' => 118, 'F8' => 119, 'F9' => 120, 'F10' => 121, 'F11' => 122, 'F12' => 123, ';' => 186, '=' => 187, ',' => 188, '-' => 189, '.' => 190, '/' => 220, '\\' => 191, '\'' => 222, '[' => 219, ']' => 221, '`' => 192, 'Backspace' => 8, 'Tab' => 9, 'Enter' => 13, 'Shift' => 16, 'Left Shift' => 160, 'Right Shift' => 161, 'Left Ctrl' => 162, 'Right Ctrl' => 163, 'Left Alt' => 164, 'Right Alt' => 165, 'Ctrl' => 17, 'Alt' => 18, 'Esc' => 27, 'Space' => 32, 'Page Up' => 33, 'Page Down' => 34, 'End' => 35, 'Home' => 36, 'Insert' => 45, 'Delete' => 46, 'Arrow Left' => 37, 'Arrow Up' => 38, 'Arrow Right' => 39, 'Arrow Down' => 40, 'Mouse Left' => 1, 'Mouse Right' => 2, 'Mouse Middle' => 4, 'Mouse 4' => 5, 'Mouse 5' => 6} #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # START Configuration #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: UP = [Key['Arrow Up']] LEFT = [Key['Arrow Left']] DOWN = [Key['Arrow Down']] RIGHT = [Key['Arrow Right']] A = [Key['Shift']] B = [Key['Esc'], Key['NumberPad 0'], Key['X']] C = [Key['Space'], Key['Enter'], Key['C']] X = [Key['A']] Y = [Key['S']] Z = [Key['D']] L = [Key['Q'], Key['Page Down']] R = [Key['W'], Key['Page Up']] F5 = [Key['F5']] F6 = [Key['F6']] F7 = [Key['F7']] F8 = [Key['F8']] F9 = [Key['F9']] SHIFT = [Key['Shift']] CTRL = [Key['Ctrl']] ALT = [Key['Alt']] #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # END Configuration #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # All keys KEY_COUNT = 256 ALL_KEYS = (0...KEY_COUNT).to_a # Win32 API calls GetKeyboardState = Win32API.new('user32', 'GetKeyboardState', 'P', 'I') GetKeyboardLayout = Win32API.new('user32', 'GetKeyboardLayout', 'L', 'L') MapVirtualKeyEx = Win32API.new('user32', 'MapVirtualKeyEx', 'IIL', 'I') ToUnicodeEx = Win32API.new('user32', 'ToUnicodeEx', 'LLPPILL', 'L') # some other constants DOWN_STATE_MASK = 0x80 DEAD_KEY_MASK = 0x80000000 # data @state = "\0" * KEY_COUNT @triggered = Array.new(KEY_COUNT, false) @pressed = Array.new(KEY_COUNT, false) @released = Array.new(KEY_COUNT, false) @repeatedKey = -1 @repeatedCount = 0 #---------------------------------------------------------------------------- # update # Updates input. #---------------------------------------------------------------------------- def self.update # get current language layout @language_layout = GetKeyboardLayout.call(0) # get new keyboard state GetKeyboardState.call(@state) # this special code is used because Ruby 1.9.x does not return a char # when using String#[] but another String key = 0 @state.each_byte {|byte| # if pressed state if (byte & DOWN_STATE_MASK) == DOWN_STATE_MASK # not released anymore @released[key] = false # if not pressed yet if !@pressed[key] # pressed and triggered @pressed[key] = true @triggered[key] = true @repeatedKey = key @repeatedCount = 0 else # not triggered anymore @triggered[key] = false end # update of repeat counter if key == @repeatedKey @repeatedCount < 17 ? @repeatedCount += 1 : @repeatedCount = 15 end # not released yet elsif !@released[key] # if still pressed if @pressed[key] # not triggered, pressed or repeated, but released @triggered[key] = false @pressed[key] = false @released[key] = true if key == @repeatedKey @repeatedKey = -1 @repeatedCount = 0 end end else # not released anymore @released[key] = false end key += 1} end #---------------------------------------------------------------------------- # dir4 # 4 direction check. #---------------------------------------------------------------------------- def self.dir4 return 2 if self.press?(DOWN) return 4 if self.press?(LEFT) return 6 if self.press?(RIGHT) return 8 if self.press?(UP) return 0 end #---------------------------------------------------------------------------- # dir8 # 8 direction check. #---------------------------------------------------------------------------- def self.dir8 down = self.press?(DOWN) left = self.press?(LEFT) return 1 if down && left right = self.press?(RIGHT) return 3 if down && right up = self.press?(UP) return 7 if up && left return 9 if up && right return 2 if down return 4 if left return 6 if right return 8 if up return 0 end #---------------------------------------------------------------------------- # trigger? # Test if key was triggered once. #---------------------------------------------------------------------------- def self.trigger?(keys) keys = [keys] unless keys.is_a?(Array) return keys.any? {|key| @triggered[key]} end #---------------------------------------------------------------------------- # press? # Test if key is being pressed. #---------------------------------------------------------------------------- def self.press?(keys) keys = [keys] unless keys.is_a?(Array) return keys.any? {|key| @pressed[key]} end #---------------------------------------------------------------------------- # repeat? # Test if key is being pressed for repeating. #---------------------------------------------------------------------------- def self.repeat?(keys) keys = [keys] unless keys.is_a?(Array) return (@repeatedKey >= 0 && keys.include?(@repeatedKey) && (@repeatedCount == 1 || @repeatedCount == 16)) end #---------------------------------------------------------------------------- # release? # Test if key was released. #---------------------------------------------------------------------------- def self.release?(keys) keys = [keys] unless keys.is_a?(Array) return keys.any? {|key| @released[key]} end #---------------------------------------------------------------------------- # get_character # vk - virtual key # Gets the character from keyboard input using the input locale identifier # (formerly called keyboard layout handles). #---------------------------------------------------------------------------- def self.get_character(vk) # get corresponding character from virtual key c = MapVirtualKeyEx.call(vk, 2, @language_layout) # stop if character is non-printable and not a dead key return '' if c < 32 && (c & DEAD_KEY_MASK != DEAD_KEY_MASK) # get scan code vsc = MapVirtualKeyEx.call(vk, 0, @language_layout) # result string is never longer than 4 bytes (Unicode) result = "\0" * 4 # get input string from Win32 API length = ToUnicodeEx.call(vk, vsc, @state, result, 4, 0, @language_layout) return (length == 0 ? '' : result) end #---------------------------------------------------------------------------- # get_input_string # Gets the string that was entered using the keyboard over the input locale # identifier (formerly called keyboard layout handles). #---------------------------------------------------------------------------- def self.get_input_string result = '' # check every key ALL_KEYS.each {|key| # if repeated if self.repeat?(key) # get character from keyboard state c = self.get_character(key) # add character if there is a character result += c if c != '' end} # empty if result is empty return '' if result == '' # convert string from Unicode to UTF-8 return self.unicode_to_utf8(result) end #---------------------------------------------------------------------------- # unicode_to_utf8 # string - string in Unicode format # Converts a string from Unicode format to UTF-8 format as RGSS does not # support Unicode. #---------------------------------------------------------------------------- def self.unicode_to_utf8(string) result = '' # L* format means a bunch of 4-byte wide-chars string.unpack('L*').each {|c| # characters under 0x80 are 1 byte characters if c < 0x0080 result += c.chr # other characters under 0x800 are 2 byte characters elsif c < 0x0800 result += (0xC0 | (c >> 6)).chr result += (0x80 | (c & 0x3F)).chr # other characters under 0x10000 are 3 byte characters elsif c < 0x10000 result += (0xE0 | (c >> 12)).chr result += (0x80 | ((c >> 6) & 0x3F)).chr result += (0x80 | (c & 0x3F)).chr # other characters under 0x200000 are 4 byte characters elsif c < 0x200000 result += (0xF0 | (c >> 18)).chr result += (0x80 | ((c >> 12) & 0x3F)).chr result += (0x80 | ((c >> 6) & 0x3F)).chr result += (0x80 | (c & 0x3F)).chr # other characters under 0x4000000 are 5 byte characters elsif c < 0x4000000 result += (0xF8 | (c >> 24)).chr result += (0x80 | ((c >> 18) & 0x3F)).chr result += (0x80 | ((c >> 12) & 0x3F)).chr result += (0x80 | ((c >> 6) & 0x3F)).chr result += (0x80 | (c & 0x3F)).chr # other characters under 0x80000000 are 6 byte characters elsif c < 0x80000000 result += (0xFC | (c >> 30)).chr result += (0x80 | ((c >> 24) & 0x3F)).chr result += (0x80 | ((c >> 18) & 0x3F)).chr result += (0x80 | ((c >> 12) & 0x3F)).chr result += (0x80 | ((c >> 6) & 0x3F)).chr result += (0x80 | (c & 0x3F)).chr end} return result end end end |