Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : [VX-Ace] Script für variablen Truheninhalt



Elster
01.07.2014, 18:31
Hey, ich schon wieder :(

Mir ist heute aufgefallen das ich in meinen Spiel nicht mit einem normalen Zufallssystem über Commen Events weiter komme.
Grund dafür, so in eine Truhe mehr als 200 Gegenstände zu verstauen ist einfach vollkommen unübersichtlich und ich will später nicht raten ob ich da das richtige stehen habe...

Also dachte ich mir heute... schreib doch ein Script dafür... was genauso funktioniert wie ein Commen Event nur... das wird auch unsagbar nervig und du hast wirklich wenig Ahnung von Ruby...


Mein Verbrechen in Ruby sieht bis nun so aus....



class BlueChest

#True/ False Abfrage damit das Script nur dann läuft wenn ich will
chest = $game_variables[20]
# Bestimmt welcher Gegenstand in der Truhe liegt. Wird beim Anklicken der Truhe bestimmt.
itemCounter = $game_variables[3]

if chest == 1
if itemCounter == 1
#Waffe Ciupaga+
item = &data_weapons[51]
&game_party.gain_item(item, 1)

end

end


So weit so schlecht... nun... es könnte in dieser Art funktionieren, wenn ich noch rausfinde wie ich den Namen des Gegenstands, welchen man aus der Truhe bekommt, in einer Nachricht wiedergebe.

Leider sehe ich es nun kommen, dass das auch vollkommen überladen wird und mehrere hundert Zeilen an kopierten Code bekomme was einfach nur grauenvoll ist und im schlimmsten Fall das Spiel zum ruckeln bringt (je nachdem wie viele Gegenstände es am Ende wirklich werden).

Jemand eine Idee wie man das schöner lösen könnte?

Eine Idee hätte ich noch, weiß aber nicht wie man das in Ruby umsetzen kann.
Es könnte vielleicht ja möglich sein, dass man in die Notes eines Gegenstands einen Kommentar verfasst aller <hier könnte ihr Befehl stehen>
So was hab ich schon bei Skills gesehen und dann setzt das Script das um (wie zum Beispiel bei Pokeballscrips Monster fangen)
Jetzt könnte man ja sagen <store> oder so und der Gegenstand wird in einer Liste hinterlegt und dann wird über einen Zufallswert der Gegenstand aus der Liste an Platz x genommen und in das Inventar gelegt mit z.B. der Meldung "x mal Heiltrank erhalten"

Denke aber das Letzteres wesentlich schwerer umzusetzen ist.
Bin auch für andere Vorschläge offen...
Freue mich jedenfalls auf Hilfe und Ideen

Linkey
01.07.2014, 21:24
Hey Elster,

habe dir gerade folgendes Script erstellt (einfach über main einfügen):


class Custom_Chest

def initialize
@chests ={}
@var_id = 9
init_chests()
end

def init_chests()
$data_weapons.each do |tw|
add_item?(tw,"weapon")
end
$data_armors.each do |ta|
add_item?(ta,"armor")
end
$data_items.each do |ti|
add_item?(ti,"item")
end
end

def add_item?(item,ptype)
return unless(item)
reg_type = /<ch_type:\s*(.+)\s*>/i
reg_amount = /ch_amount:\s*(.+)\s*>/i
reg_chance = /ch_chance:\s*(.+)\s*>/i
res_type = item.note.match(reg_type)
res_amount = item.note.match(reg_amount)
res_chance = item.note.match(reg_chance)
return false unless(res_type)
type = res_type[1]
amount = res_amount ? res_amount[1].to_i : 1
chance = res_chance ? res_chance[1].to_i : 1

if(type.include?(","))
type.split(",").each do |tp|
@chests[tp] = [] unless(@chests.has_key?(tp))
end
else
@chests[type] = [] unless(@chests.has_key?(type))
end

chance.times do
if(type.include?(","))
type.split(",").each do |tp|
@chests[tp] << Chest_Item.new(item.id,item.name,ptype,amount)
end
else
@chests[type] << Chest_Item.new(item.id,item.name,ptype,amount)
end
end
return true
end

def open_chest(chest_type)
if(@chests.has_key?(chest_type))
ci = @chests[chest_type][rand(@chests[chest_type].size)]
ci.add_to_inventory
$game_variables[@var_id] = ci.amount.to_s + "x " + ci.name
else
$game_variables[@var_id] = "ERROR"
end
end
end

class Chest_Item
attr_reader :id
attr_reader :name
attr_reader :type
attr_reader :amount

def initialize(id,name,type,amount)
@id = id
@name = name
@type = type
@amount = amount
end

def add_to_inventory
case @type
when "weapon"
$game_party.gain_item($data_weapons[@id], @amount)
return true
when "armor"
$game_party.gain_item($data_armors[@id], @amount)
return true
when "item"
$game_party.gain_item($data_items[@id], @amount)
return true
else
return false
end
end
end


module DataManager
class <<self; alias org_setup_new_game setup_new_game; end
def self.setup_new_game
self.org_setup_new_game
$chests = Custom_Chest.new()
end

def self.load_game_without_rescue(index)
File.open(make_filename(index), "rb") do |file|
Marshal.load(file)
extract_save_contents(Marshal.load(file))
reload_map_if_updated
@last_savefile_index = index
end
$chests = Custom_Chest.new()
return true
end
end


Das Script funktioniert wie folgt:
Über die Variable "@var_id" kannst du bestimmen, in welcher Variable die Anzahl + der Itemname gespeichert werden soll. Damit kannst du dann im Event die Variable über die Messagebox anzeigen lassen.
Nimmst du beispielsweise die "@var_id = 9", kannst du in der Messagebox folgenden Befehl verwenden:
\V[9]
Dahinter kannst du dann bspw. " erhalten!" einfügen. Wenn der Spieler dann beispielsweise 5 Potions aus der Truhe erhält, gibt die Messagebox folgendes aus: "5x Potion erhalten!".

Die Items pro Truhe stellst du über folgende Notetags her:


<ch_type: string>
<ch_amount: int> (OPTIONAL. Default: 1)
<ch_chance: int> (OPTIONAL. Default: 1)


ch_type bestimmt dabei den Typ der Truhe. (Beispiel: "Blau", "Selten", "Golden") - per "," getrennt können hier mehrere angegeben werden. (Bspw: "rot,blau,gelb")
ch_amount bestimmt wie oft dieses Item dem Spieler hinzugefügt wird. Gibst du bei einer Potion bspw. hier eine "5" an, erhält der Spieler 5 Potions, wenn dieses Item zufällig gewählt wird. Optionaler Befehl.
ch_chance bestimmt die Chance, dieses Item zu erhalten. Alle Items, die hier nichts stehen haben, sind einmal in der Liste eingetragen. Du könntest bei der Potion hier jetzt eine 10 eintragen, dann wird die Potion 10 mal in der Liste dieser Truhe stehen und somit die Chance erhöht.

Beispiel:

Item: Altes Schwert
<ch_type: blau>

Item: Potion
<ch_type: blau,rot>
<ch_amount: 5>
<ch_chance: 4>

Item: Helm
<ch_type: blau>
<ch_amount: 2>
<ch_chance: 2>

Item: Bombe
<ch_type: rot>

Öffnet der Spieler nun eine Truhe mit dem Typ "rot", wird dieser zu 80% 5x Potion und zu 20% 1x Bombe erhalten.
Öffnet der Spieler nun eine Truhe mit dem Typ "blau", wird dieser zu ca. 58% 5x Potion, zu ca. 28% 2x Helm und zu ca. 14% 1x Altes Schwert.


Eine Truhe öffnest du mit dem Befehl (im Event ein Script ausführen [Button unten rechts auf der 3. Seite]):

$chests.open_chest("rot")
(in Klammern steht der ch_type)

Ich hoffe, es funktioniert, wie du es dir vorstellst. Ansonsten einfach nachfragen.

PS: Hat das andere Script, zum Lernen von Skills über Items, eigentlich zu deiner Zufriedenheit funktioniert?

Elster
02.07.2014, 08:56
Wahnsinn, dass ist genau das, was ich gesucht habe :herz:
Vielen lieben Dank :)

Nur ich habe noch eine Frage, kann man irgendwie variabel sagen wie viele dieser Items in der Truhe sind? (nicht so wichtig aber wäre für Heiltränke ganz lustig)

@Skilllernen
Sorry, ich habe total verplant dir bescheid zu sagen, dass Script ist klasse, vielen lieben Dank.

Linkey
02.07.2014, 19:55
Wahnsinn, dass ist genau das, was ich gesucht habe :herz:
Vielen lieben Dank :)

Nur ich habe noch eine Frage, kann man irgendwie variabel sagen wie viele dieser Items in der Truhe sind? (nicht so wichtig aber wäre für Heiltränke ganz lustig)

@Skilllernen
Sorry, ich habe total verplant dir bescheid zu sagen, dass Script ist klasse, vielen lieben Dank.
Meinst du mit dieser Frage, ob es möglich wäre es einzustellen, dass nicht immer X-Items drin sind, sondern in einer bestimmten Range? => Dass es bspw. sein kann, dass der Held mal 5 Potions direkt erhält - mal nur 3? Oder wie ist diese Frage zu verstehen? x3

Edit:
Habe es einfach mal im glauben, dass meine Annahme richtig ist, angepasst:

class Custom_Chest

def initialize
@chests ={}
@var_id = 9
init_chests()
end

def init_chests()
$data_weapons.each do |tw|
add_item?(tw,"weapon")
end
$data_armors.each do |ta|
add_item?(ta,"armor")
end
$data_items.each do |ti|
add_item?(ti,"item")
end
end

def add_item?(item,ptype)
return unless(item)
reg_type = /<ch_type:\s*(.+)\s*>/i
reg_amount = /ch_amount:\s*(.+)\s*>/i
reg_chance = /ch_chance:\s*(.+)\s*>/i
res_type = item.note.match(reg_type)
res_amount = item.note.match(reg_amount)
res_chance = item.note.match(reg_chance)
return false unless(res_type)
type = res_type[1]
amount = res_amount ? res_amount[1] : 1
chance = res_chance ? res_chance[1].to_i : 1

if(type.include?(","))
type.split(",").each do |tp|
@chests[tp] = [] unless(@chests.has_key?(tp))
end
else
@chests[type] = [] unless(@chests.has_key?(type))
end

chance.times do
if(type.include?(","))
type.split(",").each do |tp|
@chests[tp] << Chest_Item.new(item.id,item.name,ptype,amount)
end
else
@chests[type] << Chest_Item.new(item.id,item.name,ptype,amount)
end
end
return true
end

def open_chest(chest_type)
if(@chests.has_key?(chest_type))
ci = @chests[chest_type][rand(@chests[chest_type].size)]
ci.add_to_inventory(@var_id)
else
$game_variables[@var_id] = "ERROR"
end
end
end

class Chest_Item
attr_reader :id
attr_reader :name
attr_reader :type
attr_reader :amount

def initialize(id,name,type,amount)
@id = id
@name = name
@type = type
@amount = amount
end

def add_to_inventory(mess_var_id=1)
tamount = 1
if(@amount.include?("-"))
trand = @amount.split("-")
tamount = trand[0].to_i + rand(trand[1].to_i - trand[0].to_i + 1)
else
tamount = @amount.to_i
end

$game_variables[mess_var_id] = tamount.to_s + "x " + @name
case @type
when "weapon"
$game_party.gain_item($data_weapons[@id], tamount)
return true
when "armor"
$game_party.gain_item($data_armors[@id], tamount)
return true
when "item"
$game_party.gain_item($data_items[@id], tamount)
return true
else
return false
end
end
end


module DataManager
class <<self; alias org_setup_new_game setup_new_game; end
def self.setup_new_game
self.org_setup_new_game
$chests = Custom_Chest.new()
end

def self.load_game_without_rescue(index)
File.open(make_filename(index), "rb") do |file|
Marshal.load(file)
extract_save_contents(Marshal.load(file))
reload_map_if_updated
@last_savefile_index = index
end
$chests = Custom_Chest.new()
return true
end
end

Einfach das alte hiermit ersetzen. Beim Befehl für die Anzahl kannst du nun eine Range eingeben (Minimum-Maximum ohne Leerzeichen, getrennt durch Bindestrich):
<ch_amount: 3-6>

Elster
03.07.2014, 08:32
Ja, dass so meinte ich das, danke :3

Edit:
Hm, die Nachricht geht jetzt nicht mehr... da steht nun "0 erhalten!" vorher ging es noch ^^"

Edit2:
Mein Fehler, ich hab vergessen die eine Variable umzustellen...

Linkey
03.07.2014, 10:28
Super :)

Sollten dennoch Probleme in Zukunft mit dem Script auftauchen, gib einfach Bescheid.