#=============================================================================== # ■ Shop Stock #------------------------------------------------------------------------------- # Auteur : Mat (& Åvygeil pour quelques trucs...) # Version : 1.5.1 # Date : 15/12/2006 #------------------------------------------------------------------------------- # Ce systême permet de créer des magasins réalistes avec une caisse et un stock. # Un magasin ne peut donc pas acheter des objets au héros si il ne dispose pas # d'assez d'argent dans sa caisse ; les objets vendus à un magasin y sont # conservés et les objets à acheter sont en quantité limitée. # # Peut-être dans une future version : # - Certains objets en quantité infini. # - Réapprovisionnement régulier des magasins. # # Nécessite le SDK #------------------------------------------------------------------------------- # Utilisation : # # 1) Création de la base de données des magasins : # # - Créer dans le dossier du jeu un nouveau répertoire "Shops Data". # # - Dans ce répertoire, créer des fichiers txt, # dont les noms seront ceux des magasins, sous la forme : # Argent : une_somme_dargent # Objets : # qté1-nom_de_lobjet1 # qté2-nom_de_lobjet2 # ... # Armes : # qté1-nom_de_larme1 # qté2-nom_de_larme2 # ... # Armures : # qté1-nom_de_larmure1 # qté2-nom_de_larmure2 # ... # ATTENTION !! la syntaxe doit être exacte au niveau des majuscules # et des espaces qui peuvent se trouver à la fin des noms # dans les fichiers ou dans la base de données. # Le script ne reconnaît pas non plus les accents # et autres caractères spéciaux # # - Lancer le jeu pour générer dans le dossier "Data" # un nouveau fichier Shops.rxdata. # Quand le jeu sera fini et prêt à être crypter, # supprimer avant le dossier "Shops Data" et mettre la constante Scene_Title::CREATE_SHOPS_RXDATA = true # à false. # # 2) Appel de magasin : # # Il suffit de créer un evènement avec le nom d'un magasin, # et d'appeler dans ses commandes un magasin en lui passant # des objets à vendre qui ne seront pas pris en compte. #=============================================================================== #------------------------------------------------------------------------------- # Identification SDK #------------------------------------------------------------------------------- SDK.log('Shop Stock', 'Mat', '1.5.1', '15/12/2006') #------------------------------------------------------------------------------- # Début Vérification d'Activation par le SDK #------------------------------------------------------------------------------- if SDK.state('Shop Stock') == true #=============================================================================== # ▼ Game_Shop #------------------------------------------------------------------------------- # Cette classe modélise des magasins avec une caisse et un stock d'objets. #=============================================================================== class Game_Shop attr_reader :gold # montant de la caisse attr_reader :items # stock d'objets attr_reader :weapons # stock d'armes attr_reader :armors # stock d'armures #============================================================================= # ● initialize # gold : Montant initial de la caisse # items : Stock initial d'objets # weapons : Stock initial d'armes # armors : Stock initial d'armures #----------------------------------------------------------------------------- # Méthode de création du magasin. #============================================================================= def initialize(gold, items, weapons, armors) @gold = gold @items = items @weapons = weapons @armors = armors end #============================================================================= # ● gain_gold # n : L'argent à ajouter #----------------------------------------------------------------------------- # Méthode d'ajout d'argent au magasin #============================================================================= def gain_gold(n) @gold = [[@gold + n, 0].max, 9999999].min end #============================================================================= # ● lose_gold # n : L'argent à retirer #----------------------------------------------------------------------------- # Méthode pour retirer de l'argent au magasin #============================================================================= def lose_gold(n) gain_gold(-n) end #============================================================================= # ● item_number # item_id : L'id dans la base de données de l'item à chercher #----------------------------------------------------------------------------- # Méthode qui retourne la quantité d'un item possédé par le magasin #============================================================================= def item_number(item_id) return @items.include?(item_id) ? @items[item_id] : 0 end #============================================================================= # ● weapon_number # weapon_id : L'id dans la base de données de l'arme à chercher #----------------------------------------------------------------------------- # Méthode qui retourne la quantité d'une arme possédée par le magasin #============================================================================= def weapon_number(weapon_id) return @weapons.include?(weapon_id) ? @weapons[weapon_id] : 0 end #============================================================================= # ● armor_number # armor_id : L'id dans la base de données de l'armure à chercher #----------------------------------------------------------------------------- # Méthode qui retourne la quantite d'une armure possédée par le magasin #============================================================================= def armor_number(armor_id) return @armors.include?(armor_id) ? @armors[armor_id] : 0 end #============================================================================= # ● gain_item # item_id : L'id dans la base de données de l'item à ajouter # n : La quantite de l'item à ajouter #----------------------------------------------------------------------------- # Méthode qui permet d'ajouter des items au magasin #============================================================================= def gain_item(item_id, n) if item_id > 0 @items[item_id] = [[item_number(item_id) + n, 0].max, 99].min end end #============================================================================= # ● gain_weapon # weapon_id : L'id dans la base de données de l'arme à ajouter # n : La quantite de l'arme à ajouter #----------------------------------------------------------------------------- # Méthode qui permet d'ajouter des armes au magasin #============================================================================= def gain_weapon(weapon_id, n) if weapon_id > 0 @weapons[weapon_id] = [[weapon_number(weapon_id) + n, 0].max, 99].min end end #============================================================================= # ● gain_armor # item_id : L'id dans la base de données de l'armrue à ajouter # n : La quantite de l'armure à ajouter #----------------------------------------------------------------------------- # Méthode qui permet d'ajouter des armures au magasin #============================================================================= def gain_armor(armor_id, n) if armor_id > 0 @armors[armor_id] = [[armor_number(armor_id) + n, 0].max, 99].min end end #============================================================================= # ● lose_item # item_id : L'id dans la base de données de l'item à retirer # n : La quantite de l'item à retirer #----------------------------------------------------------------------------- # Méthode qui permet de retirer des items au magasin #============================================================================= def lose_item(item_id, n) gain_item(item_id, -n) end #============================================================================= # ● lose_weapon # weapon_id : L'id dans la base de données de l'arme à retirer # n : La quantite de l'arme à retirer #----------------------------------------------------------------------------- # Méthode qui permet de retirer des armes au magasin #============================================================================= def lose_weapon(weapon_id, n) gain_weapon(weapon_id, -n) end #============================================================================= # ● lose_armor # armor_id : L'id dans la base de données de l'armrue à retirer # n : La quantite de l'armure à retirer #----------------------------------------------------------------------------- # Méthode qui permet de retirer des armures au magasin #============================================================================= def lose_armor(armor_id, n) gain_armor(armor_id, -n) end end #=============================================================================== # ▼ Game_Temp #------------------------------------------------------------------------------- # On ajoute à la classe Game_Temp un nouvel attribut @game_shop # correspondant au magasin appelé, ce qui remplace l'attribut @shop_goods #=============================================================================== class Game_Temp attr_accessor :game_shop alias shop_initialize initialize def initialize shop_initialize @game_shop = nil end end #=============================================================================== # ▼ Interpreter & Game_Event #------------------------------------------------------------------------------- # On modifie dans la classe Interpreter la commande d'appel d'un magasin, pour # qu'il utilise $game_temp.game_shop et non $game_temp.shop_goods. # Pour celà, on a besoin d'ajouter à la classe Game_Event un accès à son event. #=============================================================================== class Interpreter #============================================================================= # ● command_302 #----------------------------------------------------------------------------- # Commande d'appel d'un magasin. #============================================================================= def command_302 $game_temp.battle_abort = true $game_temp.shop_calling = true $game_temp.game_shop = $game_shops[$game_map.events[@event_id].event.name] end end class Game_Event attr_reader :event # accès à l'évènement end #=============================================================================== # ▼ Window_ShopBuy #------------------------------------------------------------------------------- # On redéfinit des méthodes de cette classe pour afficher # non plus $game_temp.shop_goods mais les obejts de $game_temp.game_shop. #=============================================================================== class Window_ShopBuy < Window_Selectable #============================================================================= # ● initialize # bidon : un attribut qui n'est plus utilisé #----------------------------------------------------------------------------- # Méthode d'initialisation de la fenêtre. #============================================================================= def initialize(bidon) super(0, 128, 368, 352) refresh self.index = 0 end #============================================================================= # ● refresh #----------------------------------------------------------------------------- # Méthode qui permet d'afficher les objets de $game_temp.game_shop #============================================================================= def refresh if self.contents != nil self.contents.dispose self.contents = nil end @data = [] for key in $game_temp.game_shop.items.keys item = $data_items[key] if item != nil && $game_temp.game_shop.items[key] > 0 @data.push(item) end end for key in $game_temp.game_shop.weapons.keys item = $data_weapons[key] if item != nil && $game_temp.game_shop.weapons[key] > 0 @data.push(item) end end for key in $game_temp.game_shop.armors.keys item = $data_armors[key] if item != nil && $game_temp.game_shop.armors[key] > 0 @data.push(item) end end @item_max = @data.size if @item_max > 0 self.contents = Bitmap.new(width - 32, row_max * 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize for i in 0...@item_max draw_item(i) end end end end #=============================================================================== # ▼ Scene_Shop #------------------------------------------------------------------------------- # On redéfinit des méthodes de cette classe pour pouvoir # gérer la caisse et le stock de $game_temp.game_shop. #=============================================================================== class Scene_Shop #============================================================================= # ● update_buy #----------------------------------------------------------------------------- # Gestion de l'achat d'objets. #============================================================================= def update_buy @status_window.item = @buy_window.item if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) @command_window.active = true @dummy_window.visible = true @buy_window.active = false @buy_window.visible = false @status_window.visible = false @status_window.item = nil @help_window.set_text("") return end if Input.trigger?(Input::C) @item = @buy_window.item if @item == nil or @item.price > $game_party.gold $game_system.se_play($data_system.buzzer_se) return end case @item when RPG::Item party_number = $game_party.item_number(@item.id) when RPG::Weapon party_number = $game_party.weapon_number(@item.id) when RPG::Armor party_number = $game_party.armor_number(@item.id) end if party_number == 99 $game_system.se_play($data_system.buzzer_se) return end $game_system.se_play($data_system.decision_se) case @item when RPG::Item shop_number = $game_temp.game_shop.item_number(@item.id) when RPG::Weapon shop_number = $game_temp.game_shop.weapon_number(@item.id) when RPG::Armor shop_number = $game_temp.game_shop.armor_number(@item.id) end max = @item.price == 0 ? 99 : $game_party.gold / @item.price max = [max, 99 - party_number, shop_number].min @buy_window.active = false @buy_window.visible = false @number_window.set(@item, max, @item.price) @number_window.active = true @number_window.visible = true end end #============================================================================= # ● update_sell #----------------------------------------------------------------------------- # Gestion de la vente d'objets. #============================================================================= def update_sell if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) @command_window.active = true @dummy_window.visible = true @sell_window.active = false @sell_window.visible = false @status_window.item = nil @help_window.set_text("") return end if Input.trigger?(Input::C) @item = @sell_window.item @status_window.item = @item if @item == nil or @item.price == 0 or (@item.price/2) > $game_temp.game_shop.gold $game_system.se_play($data_system.buzzer_se) return end $game_system.se_play($data_system.decision_se) case @item when RPG::Item number = $game_party.item_number(@item.id) when RPG::Weapon number = $game_party.weapon_number(@item.id) when RPG::Armor number = $game_party.armor_number(@item.id) end max = number @sell_window.active = false @sell_window.visible = false @number_window.set(@item, max, @item.price / 2) @number_window.active = true @number_window.visible = true @status_window.visible = true end end #============================================================================= # ● update_number #----------------------------------------------------------------------------- # Gestion du nombre d'objets à acheter ou vendre. #============================================================================= def update_number if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) @number_window.active = false @number_window.visible = false case @command_window.index when 0 @buy_window.active = true @buy_window.visible = true when 1 @sell_window.active = true @sell_window.visible = true @status_window.visible = false end return end if Input.trigger?(Input::C) $game_system.se_play($data_system.shop_se) @number_window.active = false @number_window.visible = false case @command_window.index when 0 $game_party.lose_gold(@number_window.number * @item.price) $game_temp.game_shop.gain_gold(@number_window.number * @item.price) case @item when RPG::Item $game_party.gain_item(@item.id, @number_window.number) $game_temp.game_shop.lose_item(@item.id, @number_window.number) when RPG::Weapon $game_party.gain_weapon(@item.id, @number_window.number) $game_temp.game_shop.lose_weapon(@item.id, @number_window.number) when RPG::Armor $game_party.gain_armor(@item.id, @number_window.number) $game_temp.game_shop.lose_armor(@item.id, @number_window.number) end @gold_window.refresh @buy_window.refresh @status_window.refresh @buy_window.active = true @buy_window.visible = true when 1 $game_party.gain_gold(@number_window.number * (@item.price / 2)) $game_temp.game_shop.lose_gold(@number_window.number * (@item.price / 2)) case @item when RPG::Item $game_party.lose_item(@item.id, @number_window.number) $game_temp.game_shop.gain_item(@item.id, @number_window.number) when RPG::Weapon $game_party.lose_weapon(@item.id, @number_window.number) $game_temp.game_shop.gain_weapon(@item.id, @number_window.number) when RPG::Armor $game_party.lose_armor(@item.id, @number_window.number) $game_temp.game_shop.gain_armor(@item.id, @number_window.number) end @gold_window.refresh @sell_window.refresh @status_window.refresh @sell_window.active = true @sell_window.visible = true @status_window.visible = false end return end end end #=============================================================================== # ▼ Scene_Title #------------------------------------------------------------------------------- # On génère dans Scene_Title la base de données des magasins. #=============================================================================== class Scene_Title #============================================================================= # ● itemId # name : nom d'un objet #----------------------------------------------------------------------------- # Renvoie l'id de l'objet de nom name. #============================================================================= def itemId(name) $data_items.each do |item| return item.id if item != nil and item.name == name end end #============================================================================= # ● weaponId # name : nom d'une arme #----------------------------------------------------------------------------- # Renvoie l'id de l'arme de nom name. #============================================================================= def weaponId(name) $data_weapons.each do |weapon| return weapon.id if weapon != nil and weapon.name == name end end #============================================================================= # ● armorId # name : nom d'une armure #----------------------------------------------------------------------------- # Renvoie l'id de l'armure de nom name. #============================================================================= def armorId(name) $data_armors.each do |armor| return armor.id if armor != nil and armor.name == name end end #============================================================================= # ● create_shops_rxdata #----------------------------------------------------------------------------- # Méthode qui crée le fichier Shops.rxdata à partir # des fichiers txt dans le dossier "Shops Data". #============================================================================= def create_shops_rxdata shops_data = {} Dir.foreach("Shops Data") do |nom_fichier| if nom_fichier.include?(".txt") items = {} weapons = {} armors = {} fichier_txt = File.open("Shops Data/"+nom_fichier, 'r') gold = fichier_txt.readline.delete("Argent : ").to_i fichier_txt.readline loop do line = fichier_txt.readline break if line == "Armes :\n" tab = line.split('-') items[itemId(tab[1].delete("\n"))] = tab[0].to_i end loop do line = fichier_txt.readline break if line == "Armures :\n" tab = line.split('-') weapons[weaponId(tab[1].delete("\n"))] = tab[0].to_i end while(not fichier_txt.eof?) line = fichier_txt.readline tab = line.split('-') armors[armorId(tab[1].delete("\n"))] = tab[0].to_i end fichier_txt.close shops_data[nom_fichier.chomp(".txt")] = Game_Shop.new(gold,items,weapons,armors) end fichier_rxdata = File.open("Data/Shops.rxdata", 'wb') Marshal.dump(shops_data, fichier_rxdata) fichier_rxdata.close end end #============================================================================= # ● main_data_base #----------------------------------------------------------------------------- # Création de la base de données des magasins si CREATE_SHOPS_RXDATA # est à true et chargement de la base de données d'origine et # de celle des magasins dans $data_shops. #============================================================================= alias stock_main_database main_database def main_database stock_main_database create_shops_rxdata if CREATE_SHOPS_RXDATA $data_shops = load_data("Data/Shops.rxdata") end #============================================================================= # ● command_new_game #----------------------------------------------------------------------------- # Méthode qui commence une nouvelle partie. # Initialise $game_shops à $data_shops. #============================================================================= alias stock_command_new_game command_new_game def command_new_game $game_shops = $data_shops stock_command_new_game end end #=============================================================================== # ▼ Scene_Save #------------------------------------------------------------------------------- # Il faut sauvegarder l'état actuel des caisses et stocks des magasins. #=============================================================================== class Scene_Save #============================================================================= # ● write_save_data # file : nom du fichier de sauvegarde #----------------------------------------------------------------------------- # On sauvegarde l'état des caisses et stocks des magasins. #============================================================================= alias stock_write_save_data write_save_data def write_save_data(file) stock_write_save_data(file) Marshal.dump($game_shops, file) end end #=============================================================================== # ▼ Scene_Load #------------------------------------------------------------------------------- # Il faut charger l'état actuel des caisses et stocks des magasins. #=============================================================================== class Scene_Load #============================================================================= # ● read_data # file : nom du fichier où se trouvent les données à charger #----------------------------------------------------------------------------- # On charge l'état dans lequel se trouvaient # les magasins au moment de la sauvegarde. #============================================================================= alias stock_read_data read_data def read_data(file) stock_read_data(file) $game_shops = Marshal.load(file) end end end #------------------------------------------------------------------------------- # Fin Vérification d'Activation par le SDK #-------------------------------------------------------------------------------