• Anmelden

1

Sonntag, 29. Juni 2014, 18:18

Angriff des Gengners auf einen Held als Condinitional Branch abfrage

Ich brauche von euch eine Skriptabfrage, die man in einem condinitional branch einsetzen kann. Ich möchte eine Skript Abfrage die folgendermaßen aussehen soll:

wenn Monster 1 (Es kann ja nur maximal 8 geben im battle) eine Aktion gegen den den Helden mit der ID Nummer 17 durchführt, egal ob normale Attacke, phy oder magie Attacke.
Diese Skriptabfrage hätte ich gerne von euch, da ich kaum Ahnung von Skripten habe, dies aber unumgänglich ist für mein Projekt. Es handelt sich natürlich um eine skriptfolge, die mit "if" beginnt.

Wichtig ist, dass diese Skript abfrage in einem condinitional branch verwendet werden kann. Auch sollte sich die Skript abfrage auf den Helden mit der ID 17 beziehn.
Das gleiche gilt für den Enemy mit der Nummer 1.

Ich hoffe das war deutlich.

Mit freundlichen Grüßen, Colchianrebell

Mitsch93

Drachentöter

Motto: Aufgeben ist es, was den Menschen tötet. Nur der Mensch, der sich weigert aufzugeben, hat sich das Recht verdient, auf dem glanzvollen Pfad der Menschheit zu wandeln.

  • Nachricht senden

3

Montag, 30. Juni 2014, 17:25

Was eine derartige Funktion gibt es??
Hättest du auch gleich schreiben können


Welche Funktion ist das? Ich hab lange nicht mehr mit events rumgebastelt..
Du weißt schon, dass es auch im Kampf funktionieren muss.. oder?


Ansonsten bin ich weiterhin auf der Suche nach diesem Skriptschnippsel.

Mitsch93

Drachentöter

Motto: Aufgeben ist es, was den Menschen tötet. Nur der Mensch, der sich weigert aufzugeben, hat sich das Recht verdient, auf dem glanzvollen Pfad der Menschheit zu wandeln.

  • Nachricht senden

4

Montag, 30. Juni 2014, 18:42

Das geht ganz normal mit Eventcode und dem Battle Event. Eine konkrete Funktion
gibts da nicht, aber man kann sich selbst sozusagen eine per Event erstellen.
Stellt sich nur die Frage ob du das bei EINEM bestimmten Kampf oder bei allen brauchst.
Und in wiefern die Funktion benötigt wird im Kampf.

5

Montag, 30. Juni 2014, 18:54

Ich könnte es auch bei allen events machen. Das ist kein problem..
Ich brauche es für alle Kämpfe. Aber theoretisch kann man es auch überall einfügen.

Aber mach dochmal ein Beispiel. Wie soll man das machen, wenn es dazu keine Funktion gibt...
??

ich hab es mit diesem condinitional branch versucht als Skrript

Ruby Quellcode

1
if $game_troop.enemies[1]_action.target_$game_actors[17]


Aber irgendwie funktioniert das überhaupt nicht........ -.-

6

Montag, 30. Juni 2014, 19:11

Das "if" kannst Du weglassen, der ConditionalBranch wertet deinen Code aus, und wenn das Ergebnis nicht false oder nil ist, wird der Inhalt des ConditionalBranch Block ausgeführt.

Abgesehen davon - ist deine Codezeile voller Syntaxfehler :>
unser Scientia Wiki ist gerade nicht da, aber hier findest Du ein 20 Minuten Tutorial, damit Du schonmal ein paar Ideen zur Syntax bekommst: Ruby in 20 Minuten (dein setzen von Punkten, Unterstrichen und Leerzeichen im Quellcode wirkt etwas wilkürlich)

7

Montag, 30. Juni 2014, 19:23

Das dauert Monate bis ich Scripten lerne. Zeit, die ich leider nicht habe. Ich bin untalentiert. Total sogar. Das vorhin war eine Kostprobe.


Du hast doch bestimmt Ahnung von Skripten? Könntest du nicht gleich die Lösung für mein Problem liefern. Für dich ist sowas doch nur' ne Aufgabe von Minuten... :))
Deswegen habe ich ja auch hier gefragt.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Colchianrebell1995« (30. Juni 2014, 20:49)


8

Montag, 30. Juni 2014, 21:45

Der Witz an dem "Ruby in 20 Minuten" Tutorial ist ja, das Du Ruby in zwanzig Minuten lernst. :P
Naja, zumindest oberflächlich, wodurch schonmal die Syntaxfehler wegfallen werden.

Was genau hast Du denn vor? Das ist ja schon ein ziemlich spezieller Wunsch, wenn es auf den ersten Gegner und den Helden mit der ID 17 abzielt.

9

Montag, 30. Juni 2014, 21:56

Ich weiß nicht wie ich es deutlicher machen soll..

Eigentlich GENAU so wie ich es beschrieben haben.

Ich möchte eine if skript abfrage als condinational branch einbauen.
Die soll abfragen wenn enemy vom troop 1 ( es kann ja nur 8 geben) den Helden mit der ID 17 angreift. Wichtig ist auch, der trigger muss auch zuschlagen, wenn magische oder physische zauber benutzt werden gegen den Helden.

Ich kann nur soviel sagen, dass es viel mit dem counterskript zutun hat, der ja nicht funktioniert und auch nicht funktionieren will :((((
Ich hoffe du verstehst mich.

Also eine if skriptcode zeile die als trigger dient in einem condinational branch.

Ruby Quellcode

1
 $game_troop.enemies[1]_action.target_$game_actors[17]



Genau so, nur sollte es funktionieren und nicht so ein Schrott wie meins, das nicht funktioniert..
ps. Ich bin sehr untalentiert was das skripten angeht und damit quasi auf euch angewiesen. :((

10

Montag, 30. Juni 2014, 22:12

Wann soll das denn in der zeitlichen Abfolge triggern?
Sobald der Held als Ziel gewählt wird, sobald der Angriff ausgeführt wird, wenn Schaden verursacht wird oder nach dem Angriff?

11

Montag, 30. Juni 2014, 22:31

nachdem angriff. bzw. nach dem skill.


"Wann soll das denn in der zeitlichen Abfolge triggern?"
wie meinst du das?
Du brauchst nur den code liefern. Das triggern werde ich im battle lösen. Da wird auch die zeitliche abfolge bestimmt.
ps. Sorry ich war auf Klo^^

Ruby Quellcode

1
$game_troop.enemies[1].current_action.target_index == $game_actors[17]

Ich versuche es mit diesem code. Aber ich kriege nur ein undefined method error für current action..


:((

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Colchianrebell1995« (4. Juli 2014, 23:28)


Irrlicht

Leuchtendes Irgendwas

Motto: Keep shining!

  • Nachricht senden

12

Montag, 7. Juli 2014, 12:23

Huhu,

Für den Fall dass der Thread noch aktiv ist:

So schlecht sieht der Scriptbefehl doch schon gar nicht mehr aus. :) Zumindest meckert das Spiel nicht mehr über Syntaxfehler.
Ansonsten zu deinem Fehler:
Auflistungen wie $game_troop.enemies beginnen in Ruby in aller Regel bei 0, d.h. mit
$game_troop.enemies[1]
greifst du auf den zweiten Gegnerslot zu.
Nicht verwendete Gegnerslots werden im Spiel mit einem Platzhalter nil gefüllt. Diese Marke verfügt aber nicht über alle Aufrufe, die auf einen richtigen Gegner möglich wären. Versuchst du einen Aufruf, den das Ziel (in diesem Fall nil)nicht definiert hat bekommst du die charakteristische Fehlermeldung:

Position des Fehlers: NoMethodError occurred: Undefined method Aufrufname for nil:NilClass

Das nil:NilClass zeigt dir an, dass du versehendlich auf nil zugegriffen hast, also in diesem Fall auf einen nicht belegten Gegnerslot (der natürlich folglich auch keine Kampfaktion besitzt).
Steht dort etwas anderes solltest du zuerst überprüfen ob dein Aufruf vielleicht Tippfehler enthält.


Ansonsten zum Scriptkommando:
Der Ansatz ist in diesem Fall mMn. eher weniger geeignet, da er nicht wirklich zuverlässig ist.
Der Gegner kann z.B. während der Runde betäubt werden/sterben und deshalb gar nicht angreifen oder das ursprüngliche Ziel ist zum Zeitpunkt des Angriffs tot und der Gegner muss ein neues wählen. Die Aktion des Gegners würde dabei im ersten Fall erst in seinem Zug, im zweiten Fall gar nicht korrigiert.

Ansonsten liefert target_index die Position des Ziels in seiner Gruppe (wieder beginnend bei 0). Anstatt mit dem 17. Actor müsstest du diese Zahl also mit der Position dieses Actors in der Party vergleichen: Kennst du seine Position nicht kannst du das aber relativ einfach mit einem zusätzlichen Aufruf ermitteln:
$game_troop.enemies[0].current_action.target_index == $game_actors[17].index

Dazu müsste der Scriptbefehl auch noch erweitert werden, denn je nach dem was für eine Aktion der Gegner verwendet kann target_index eine andere Bedeutung haben: Greift der Gegner normal an wäre der Aufruf korrekt, will er Verteidigen/Flüchten/Warten hätte target_index wiederum keine Bedeutung, verwendet er einen Skill muss unterschieden werden welchen "Scope" der Skill hat. Bei einem Heilzauber würde target_index z.B. den Gegner markieren, auf den der Skill gewirkt werden soll.


Anderer Ansatz:
Wenn du Angreifer und Ziele nach einem Angriff auslesen willst könte eine Möglichkeit theoretisch so aussehen:
Der Befehl ist allerdings nicht nur ziemlich hässlich, er wird in einigen Kampfsystemen vermutlich auch nicht funktionieren, da die Art und Weise Angreifer und Ziele zu speichern abweichen kann.

$scene.instance_variable_get(:@active_battler) == $game_troop.enemies[0] and $scene.instance_variable_get(:@target_battlers).include?($game_actors[17])

Der Befehl funktioniert zudem nur wenn du ihn verwendest nachdem Gegner 1 angegriffen hat, jedoch vor der Aktion des nächsten Battlers.
Etwas einfacher wäre es die Abfrage direkt in den Kampfablauf zu integrieren, um z.B. einen Switch auszulösen:
Spoiler

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Scene_Battle
 
  # Konstante, die die Angreifer->Ziel->Switch - Kombinationen enthält:
  # z.B.: Gegner mit Index 0 (erster Gegner) greift Actor 17 an (=> Switch 12).
  ATTACKER_SWITCH_INFOS = [
  # [[     Attacker     ], [     Target     ], Switch-ID],
 
    [[:enemy, :index,  0], [:actor, :id,  17],     12    ],
 
 
  #-------------------------------------------------------
  ]
 
 
  alias_method(:update_phase4_step6_ILC_check_targets, :update_phase4_step6)
  def update_phase4_step6
    update_phase4_step6_ILC_check_targets
    # Nach Ende der Aktion werden die oben angegebenen Kombinationen
    # nach Treffern durchsucht:
    ATTACKER_SWITCH_INFOS.each do |attacker_set, target_set, switch_id|
      next  unless @active_battler.match_battler?(*attacker_set)
      next  unless @target_battlers.any? { |b| b.match_battler?(*target_set) }
      # Switch aktivieren wenn Treffer gefunden wurde:
      $game_switches[switch_id] = true
      $game_map.need_refresh = true
    end
  end
end
 
 
class Game_Battler
 
  # Diese Methode prüft, ob die oben angegebenen Informationen auf diesen
  # Battler zutreffen:
  def match_battler?(team, set_type = nil, pos = nil)
    kind = (team == :enemy ? Game_Enemy : team == :actor ? Game_Actor : nil)
    return false  if kind != nil and not self.is_a?(kind)
    index = (set_type == :id ? self.id : set_type == :index ? self.index : nil)
    return pos.is_a?(Enumerable) ? pos.include?(index) : pos == index
  end
end
zum Lesen den Text mit der Maus markieren

In dem bereits aufgeführten Beispiel wird Switch 12 aktiviert wenn der erste Gegner in der Gruppe Actor #17 angreift, lässt sich bei Bedarf erweitern.


Gruß
~Irrlicht.

Spoiler: Alter Text - Meep, Thema nicht richtig gelesen...
Grundsätzlich sind Abfragen immer auf einen Moment bezogen. Wenn du z.B. in einem Event mit Conditional Branch abfragst ob der Spieler mindestens 100 Gold besitzt zählt dafür der Moment in dem das Event den Conditional Branch erreicht, auch wenn sich die Goldmenge im weiteren Verlauf nochmal ändert.
Je nach dem was genau du mit der Abfrage bezwecken willst sind hier evtl. andere Abfragen nötig:

Welcher Gegner welche Aktion ausführen will wird vor Beginn einer Kampfrunde festgelegt. Welches Ziel er damit angreifen will kann also direkt nach Beginn der Runde abgefragt werden (das wäre der Ansatz der bereits oben gepostet wurde, mehr dazu unten).
Damit ist jedoch nicht garantiert dass der Gegner auch wirklich dieses Ziel angreift: es kann schließlich auch passieren, dass z.B...
...der Gegner betäubt wird/stirbt und nicht angreifen kann,
...der Gegner mit Raserei belegt ist/wird und willkürlich ein neues Ziel wählt,
...das ursprünglich geplante Ziel vor dem Angriff stirbt und der Gegner ein neues wählen muss.

Welches Ziel der Gegner also tatsächlich angreift wird erst unmittelbar vor seinem Angriff bestimmt. Brauchst du diese Information bliebe die Frage ob es ausreicht diese nach dem Angriff des Gegners abzufragen oder ob du noch vor der Aktion des Gegners einschreiten musst.


Ansonsten zum Scriptkommando:

So schlecht sieht es doch noch gar nicht aus, die Syntaxfehler sind auch schonmal draußen. :)

Zur Erklärung des Fehlers:
Die Nummerierung der Gegner in $game_troop.enemies beginnt bei 0, d.h. mit $game_troop.enemies[1] greifst du auf den zweiten Gegner zu.

Nicht belegte Gegnerslots in der Liste werden dabei mit einem Platzhalter nil gefüllt. nil bedeutet 'not in list' und wird häufig verwendet um zu symbolisieren dass an dieser Stelle kein Element vorhanden ist.
Viele Aufrufe sind für nil nicht definiert. Wird im Spiel trotzdem ein solcher Aufruf versucht erhältst du die charakteristische Fehlermeldung:
Position des Fehlers: NoMethodError occurred: Undefined method Name for nil:NilClass.
Anstatt nil:NilClass kann dort natürlich auch etwas anderes stehen: insbesondere dann wenn dein Aufruf Tippfehler enthält!

Ansonsten:
Das Ergebnis von IrgendeineAktion.target_index ist eine Zahl, die die Position des Ziels in seiner Gruppe repräsentiert (wieder beginnend bei 0). Um diese Zahl mit der Position deines Actors in der Gruppe zu vergleichen kannst du den Aufruf index deines Actors verwenden:
$game_actors[17].index

Der Aufruf sähe damit bisher also so aus:
$game_troop.enemies[0].current_action.target_index == $game_actors[17].index

Leider reicht dieser Befehl noch nicht ganz aus, je nach dem was für eine Aktion der Gegner ausführen will:
...angreift (in dem Fall wäre der Scriptbefehl korrekt)
...verteidigt/flüchtet/wartet (in dem Fall bleibt der Zielindex der letzten Aktion erhalten!)
...einen Skill verwendet (hier muss unterschieden werden welchen "Scope" der Skill hat)

Der Scriptbefehl würde mit diesen Abfragen vermutlich etwas zu lang für eine Befehlszeile, von daher ein kleiner Scriptfetzen:
Spoiler

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Game_Battler
 
  def attack_this_member?(member)
    return false  if member == nil
    action = self.current_action
    # Eigenschaften ermitteln:
    same_team =   (member.is_a?(Game_Actor) == self.is_a?(Game_Actor))
    index_match = (member.index == action.target_index)
    index_valid = (member.index != nil)
    # Basisaktion?
    if action.kind == 0
      return (action.basic == 0 and not same_team and index_match)
    end
    # Skill/Item?
    if action.kind.between?(1, 2)
      item = $data_skills[action.skill_id]  if action.kind == 1
      item = $data_items[action.item_id]    if action.kind == 2
      return false  if item == nil
      # Scope auswerten:
      case item.scope
      when 0     then return false                            # None
      when 1     then return (not same_team and index_match)  # One Enemy
      when 2     then return (not same_team and index_valid)  # All Enemies
      when 3, 5  then return (same_team and index_match)      # One Friend
      when 4, 6  then return (same_team and index_valid)      # All Friends
      when 7     then return (index_valid and member == self) # Self
      end
    end
    # Nichts von allem?
    return false
  end
end
zum Lesen den Text mit der Maus markieren

Wenn du diesen Code als neues Script über Main einfügst kannst du anschließend mit
$game_troop.enemies[0].attack_this_member?($game_actors[17])
überprüfen ob Gegner1 Actor 17 angreifen will (rot markiertes kann bei Bedarf angepasst werden).

Diese Überprüfung entspricht allerdings der einfachen Methode, die oben beschrieben wurde - es gibt also keine Garantie dass der Angriff so stattfindet.

Hoffe die Erläuterungen konnten trotzdem etwas helfen. :)
zum Lesen den Text mit der Maus markieren

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »Irrlicht« (7. Juli 2014, 12:23)


13

Montag, 7. Juli 2014, 17:00

Ja der topic ist immernoch aktuell. Ich verwende das Abcs von atoa, ein siedview battlesystem.

Ich habe beide varianten ausprobiert. Einmal mit dem skript und dem kleinen code als condinational branch. Beide zeigen keine Wirkung. Der switch wird nicht aktiviert und beim condinational branch tut sich auch nichts.

Ich habe es bei einem standart kampfsystem getestet. Da funktioniert das Skript aber.