PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATB -> CTB



IndependentArt
01.04.2019, 23:25
Hallo? Hallooooo?! Ist hier noch jemand? Ich hoffe.

Ich bin gerade dabei, mein ATB in ein CTB (siehe FF10, Velsarbor) zu verwandeln.
Ein Skript zu erstellen, was die Grundfunktion, also das errechnen der Reihenfolge durchführt war leichter als gedacht.

Ich nehme einfach den Tempowert, setze ihn gleich eine andere Variable, subtrahiere von dieser solange 1, bis sie 0 ist. Geschieht das, wird der 1. Slot gefüllt. Dann wird die 2. Variable wieder gleich den Tempowert gesetzt und die ID des gerade zu befüllenden Slots wird +1 gesetzt, solang bis alle Slots voll sind.
Der Code für 2 Kampfteilnehmer sieht so aus:



@> Control Variables: [1807:R-CTB Order] = Variable [1016] (Charakter Tempo Wert)
@> Control Variables: [1810:G1-CTB Order] = Variable [1130] (Gegner Tempo Wert)
@> Control Variables: [1814:current CTB slot] = 1821
@> Comment:
: :
@> Label: 1
@> Conditional Branch: Switch [1005:Ramirez tot] is OFF
@> Conditional Branch: Switch [1001:Ramirez nicht im K] is OFF
@> Control Variables: [1807:R-CTB Order] - = 1
@> Conditional Branch: Variable [1807:R-CTB Order] = 0
@> Control Variables: [1807:R-CTB Order] = Variable [1016]
@> Control Variables: Variable [1814] = 1
@> Control Variables: [1814:current CTB slot] += 1
@>
: Branch End
@>
: Branch End
@>
: Branch End
@> Conditional Branch: Switch [1009:Gegner 1] is ON
@> Control Variables: [1810:G1-CTB Order] - = 1
@> Conditional Branch: Variable [1810:G1-CTB Order] = 0
@> Control Variables: [1810:G1-CTB Order] = Variable [1130]
@> Control Variables: Variable [1814] = 4
@> Control Variables: [1814:current CTB slot] += 1
@>
: Branch End
@>
: Branch End
@> Conditional Branch: Variable [1814:current CTB slot] < 1837
@> Jump to Label: 1
@>
: Branch End
@> Erase Event




Das Problem dabei ist jetzt nur, dass der Teilnehmer mit dem niedrigsten Tempowert am häufigsten dran ist. Es sollte natürlich genau anders herum sein, aber ich bin noch nicht richtig drauf gekommen, wie ich das am besten mache.
Eine Möglichkeit, die mir eingefallen ist, ist den Tempowert als "Summand" zu benutzen und bis zu einem Zielwert aufzuaddieren. Als Zielwert hatte ich 255 genommen, weil das vorraussichtlich den maximalen Tempowert darstellt, aber das ist jetzt unwichtig.
Ich befürchte nur, dass diese Methode nicht so genau ist, wie die Subtraktion -1. Angenommen, der Tempowert ist 50, dann würde es zu einem "Überschuss" von 45 kommen (6*50-255 = 45).
Ich kann das ehrlich gesagt grad nicht so recht überblicken, wie sich das auswirkt, vielleicht kann mir da jemand helfen.

Hasenmann
02.04.2019, 02:29
Hi,
warum addierst du nicht +1 bis zu einem bestimmten Wert anstatt 1 zu subtrahiern bis du 0 erreichst? So hättest du warscheinlich den umgekehrten Effekt. Oder du nimmst 255-[Geschwindigkeitswert] und subtrahierst dann bis 0.
Aus dem Skript werd ich so nicht ganz schlau: Was ist Variable 1130 oder 1016 und was bedeutet die Variable 1837 mit der du den current CTB slot vergleichst?

IndependentArt
02.04.2019, 02:56
warum addierst du nicht +1 bis zu einem bestimmten Wert anstatt 1 zu subtrahiern bis du 0 erreichst?

und was wäre dieser bestimmte Wert?


Oder du nimmst 255-[Geschwindigkeitswert] und subtrahierst dann bis 0.

das wäre vmtl. genau das was ich bereits ausprobiert hab, nur umgekehrt.

1130 und 1016 sind die Tempo-Stats von Charakter und Gegner.
Ich vergleiche am Ende nur, ob "Current CTB Slot" größer als 1837 ist, weil auf der Variablen ID 1836 der letzte zu befüllende Slot liegt.

Hasenmann
02.04.2019, 12:34
und was wäre dieser bestimmte Wert?

Den bestimmst du selbst. Vielleicht 255? Weil das Max Wert ist?


das wäre vmtl. genau das was ich bereits ausprobiert hab, nur umgekehrt.

Und hat es dann so funtioniert? Müsste ja logischerweise,
Da Bsp. Char hat Wert 50 und Gegner 60 -> 255-50= 205 und 255-60 ist 195. Wenn du dann runterzählst sollte Der Gegner Schneller sein, weil er den höheren Wert hat.


1130 und 1016 sind die Tempo-Stats von Charakter und Gegner.
Ich vergleiche am Ende nur, ob "Current CTB Slot" größer als 1837 ist, weil auf der Variablen ID 1836 der letzte zu befüllende Slot liegt.
OK macht Sinn.

Ken der Kot
02.04.2019, 12:36
Der Überschuss ist kinderleicht in den Griff zu bekommen, in dem man Abfragt, ob der Zähler > 255 ist und im Ja-Fall dieselbe Variable auf 255 setzt.

Leider wird IndependentArt diese Antwort nicht lesen, da er mir vor Wochen mitgeteilt hat, mich ohne Angabe von Gründen und ohne eine mir bekannte Vorgeschichte auf seine Ignore-Liste zu setzen.

IndependentArt
02.04.2019, 15:15
warum addierst du nicht +1 bis zu einem bestimmten Wert anstatt 1 zu subtrahiern bis du 0 erreichst?


Den bestimmst du selbst. Vielleicht 255? Weil das Max Wert ist?

Nochmal folgende Erklärung wie es momentan funktioniert:
Charakter 1 Tempowert = 20
Gegner Tempowert = 10

Ich setze 2 andere Variablen gleich diese Tempovariablen (damit mir die Originalwerte erhalten bleiben).

Von diesen ziehe ich -1 ab, bis eine davon 0 ist. Der Gegner-Wert wäre als erstes 0, weil er kleiner ist. Wenn das passiert, wird der erste Slot mit der Zahl die für den Gegner steht bestückt (Gegner 1 = 4) und der Wert von dem abstrahiert wird, wird resettet (also wieder 10). Fällt der Charakterwert auf 0, passiert das gleiche (für Charakter 1 wird der Slot = 1 gesetzt). Da der Gegnerwert genau halb so groß ist, werden die Werte jetzt gleichzeitig auf 0 fallen. Der Charakter erhält allerdings Vorzug, weil die Abfrage im Skript über dem Gegner steht.
Hierdurch ergibt sich für die ersten 10 Slots ca. Folgendes Pattern: 4 1 4 4 1 4 4 1 44
Gibt auch schon eine Visualisierung dazu:
http://independentart.bplaced.net/wordpress/wp-content/uploads/2019/04/Screenshot-66-1024x73.png

Was würde es mir nun nützen, eine Variable +1 zu rechnen, bis sie 255 ist? ^^ Vlt meintest du aber auch +Tempowert, wie ich es bereits gemacht habe und ich hab das falsch verstanden.

Auf jeden Fall kommt es ja auf das gleiche raus, ob ich +Tempowert rechne, bis die Variable 255 überschreitet oder -Tempowert von 255 an runter zähle.


@Ken
Ich glaube, es wurde noch nicht so recht verstanden, warum ich mir Sorgen um den Überschuss mache und ich bin auch nicht sicher, wie ich das artikulieren kann.
Mir ist klar, dass ich fragen kann ob der Zähler > 255 ist. Mir gehts aber gar nicht darum, irgendeinen Wert auf 255 runter zu bügeln. Wäre der Tempowert 50, würden die 255 ja mit 300 überschritten werden und ich könnte die Aktion einleiten.
Die Differenz von 45 würde allerdings völlig unberücksichtigt bleiben, was mich zu der Befürchtung führt, dass hier nicht genau gerechnet wird, im Gegensatz zu der Variante wo 1 subtrahiert wird und man genau auf 0 kommt.

Es müsste vielleicht irgendeine Möglichkeit geben, wie man die Statuswerte in ihr Gegenteil vekehrt. So dass die hohen Werte niedrig werden und die niedrigen Werte hoch. Aber mir ist noch nichts brauchbares dazu eingefallen.
Ich hoffe, man versteht das irgendwie.

btw: Ich hab dich mal entblockt. :p

Ken der Kot
02.04.2019, 20:25
Ich glaube, es wurde noch nicht so recht verstanden, warum ich mir Sorgen um den Überschuss mache und ich bin auch nicht sicher, wie ich das artikulieren kann.
Mir ist klar, dass ich fragen kann ob der Zähler > 255 ist. Mir gehts aber gar nicht darum, irgendeinen Wert auf 255 runter zu bügeln. Wäre der Tempowert 50, würden die 255 ja mit 300 überschritten werden und ich könnte die Aktion einleiten.

Also kein Plan, ob ich das jetzt richtig verstehe, aber wenn die 6 einfach bedeutet, dass das Tempo sechs Mal aufaddiert wird, bis sie einen Wert größer oder gleich 255 erreicht, hast du bei Tempo = 50 mit der Rechnung 50+50+50+50+50+50=300 zwar als Ergebnis 300, du kannst den Wert aber in eine neue Variable speichern und davon 255 abziehen und erhälst damit den Überschuss. Die eigentliche Zielvariable, die somit ja immer noch > 255 ist, setzt du trotzdem wieder auf 255. Im ersten Additionsschritt addierst du diesen Überschuss (45) zusätzlich auf den ersten Step der Tempovariable, sodass sich ergibt: (50+45)+50+50+50+50+50=345. (Einfach zwei Variablen addieren sollte deinem Code nichts tun, denn wenn du mal genau auf 255 landest enthält die Überschussvariable dementsprechend den Wert 0). Der nächste Wert, der in die Überschussvariable eingespeichert wird, wäre 345-255 und würde im nächsten 6er-Schritt wieder auf den ersten Wert aufaddiert werden usw.


Es müsste vielleicht irgendeine Möglichkeit geben, wie man die Statuswerte in ihr Gegenteil vekehrt. So dass die hohen Werte niedrig werden und die niedrigen Werte hoch. Aber mir ist noch nichts brauchbares dazu eingefallen.

Du speicherst die Tempowerte doch in Variablen. Die multiplizierst du jeweils mit -1 und dann müsste das passen.

Caledoriv
02.04.2019, 20:43
Was würde es mir nun nützen, eine Variable +1 zu rechnen, bis sie 255 ist? ^^ Vlt meintest du aber auch +Tempowert, wie ich es bereits gemacht habe und ich hab das falsch verstanden.

Ich nehme an, dass das eine Antwort auf dein Problem war:


Das Problem dabei ist jetzt nur, dass der Teilnehmer mit dem niedrigsten Tempowert am häufigsten dran ist. Es sollte natürlich genau anders herum sein, aber ich bin noch nicht richtig drauf gekommen, wie ich das am besten mache.



Nochmal folgende Erklärung wie es momentan funktioniert:
Charakter 1 Tempowert = 20
Gegner Tempowert = 10

Ich setze 2 andere Variablen gleich diese Tempovariablen (damit mir die Originalwerte erhalten bleiben).

Von diesen ziehe ich -1 ab, bis eine davon 0 ist. Der Gegner-Wert wäre als erstes 0, weil er kleiner ist. Wenn das passiert, wird der erste Slot mit der Zahl die für den Gegner steht bestückt (Gegner 1 = 4) und der Wert von dem abstrahiert wird, wird resettet (also wieder 10). Fällt der Charakterwert auf 0, passiert das gleiche (für Charakter 1 wird der Slot = 1 gesetzt). Da der Gegnerwert genau halb so groß ist, werden die Werte jetzt gleichzeitig auf 0 fallen. Der Charakter erhält allerdings Vorzug, weil die Abfrage im Skript über dem Gegner steht.
Hierdurch ergibt sich für die ersten 10 Slots ca. Folgendes Pattern: 4 1 4 4 1 4 4 1 44
Gibt auch schon eine Visualisierung dazu:
http://independentart.bplaced.net/wordpress/wp-content/uploads/2019/04/Screenshot-66-1024x73.png

Aus der Erklärung wird mir jetzt so langsam das Problem klar. Der Gegner hat weniger Tempowert als der Held, kommt aber öfter dran. Und jetzt möchtest du, dass das genau andersrum ist.
Die Lösung von Hasenmann zielt genau darauf ab. Nehmen wir dein Beispiel:

Held: Tempo 20
Gegner: Tempo 10
neuer Maximalwert: 30

Jetzt addierst du die ganze Zeit 1 auf die Tempowerte, bis einer den Maximalwert erreicht.
- Das ist jetzt nach 10 Schritten der Held => Held erhält Slot in der Reihenfolge und setzt seinen Wert wieder auf 20.
- Nach 10 weiteren Schritten stehen beide auf 30 => Beide erhalten einen Slot, Held wird wieder auf 20 gesetzt, Gegner wieder auf 10
- Das Ganze beginnt von vorne

Damit bedeutet ein höherer Wert, dass man öfter dran kommt.

-------
Es gibt dabei aber ein paar Sachen, die du beachten musst:
- Kein Charakter kann einen höheren Tempowert als das festgelegte Maximum haben. Außerdem sollte niemand sehr nahe daran kommen können, sonst kann es sein, dass einer sehr, sehr oft hintereinader dran ist.
Beispiel: Maximalwert ist 300, dein Held hat Tempo 299. Jetzt kommt er in jedem +1 Schritt dran, d.h. selbst wenn der Gegner Tempo 290 hat, ist der Held 10 Mal so oft dran.
- Das Beispiel macht schon den Effekt deutlich: Der Zusammenhang zwischen unterschiedlichen Tempowerten ist nicht mehr konstant, d.h. wenn der Held den doppelten Tempowert eines Gegners hat, kommt er nicht zwangsläufig doppelt so häufig dran.
Mit dieser Methode kommt es auf den Unterschied zur Maximalgrenze an: Wenn die Differenz (Maximalwert - Heldentempo) halb so groß ist wie die Differenz (Maximalwert - Gegnertempo), dann ist der Held doppelt so oft dran.


------
Und noch eine kleine Anmerkung:
Ich behaupte, du musst dein Skript mit -1 nicht umbauen, wenn du stattdessen als Grundwerte "Maximalwert - Tempo" als Input lieferst. Probier einfach mal, deine temporäre Variable (die du ja momentan nur setzt, um den "richtigen" Tempowert nicht zu überschreiben), auf "Maximalwert - Tempo" zu setzen. Das Sollte den gewünschten Effekt erzielen :).

Bei der Wahl des Maximalwertes musst du dir dann Gedanken machen, wie groß diese Spanne werden soll und wie schnell der Held seinen Tempowert steigern kann bzw. welche Items / Ausrüstung das in welchem Ausmaß tun können.

Hasenmann
02.04.2019, 21:30
@Caledoriv
Jop so hab ich das gemeint.

IndependentArt
03.04.2019, 09:04
@Ken

Das mit dem "Aufgeben" ist gar kein schlechter Gedanke. Ich könnte auch einfach -255 rechnen, sobald 255 überschritten wird. Damit würde ich quasi beim "Überschuss" wieder anfangen aufzuaddieren für den nächsten Slot.

Das scheint mir im Moment am praktikabelsten zu sein. Habs auch grad schon getestet. :A


Caledoriv

Ich glaube, die Variante ist für stark variierende Tempowerte nicht praktikabel. Für die Tempowerte 10 u. 20 und Max. 30 funktioniert es natürlich genau so wie vorher. Ich denke aber, mein Maximalwert wird schon irgendwo um 255 liegen. So kehren sich die Tempowerte im Verhältnis zum Max. Um, damit hätte ich quasi Werte von 245 und 235, was ein 1 4 1 4 1 4 Pattern ergeben würde, weil der Unterschied zwischen den Werten quasi aufgehoben wird. ^^

maniglo93
03.04.2019, 14:19
Ich habe in meinem Spiel auch ein CBS, wie du es suchst. Dabei bin ich über 3 verschiedene Designs / Techniken gegangen:

Das erste ist, wie beschrieben, ein fixer Maximalwert. Dies fand ich zuerst sehr gut, aber später sind mir paar Probleme klar geworden: Relationen gab es nicht. Dies ist ein Design Problem, so ist ein sehr schneller Charakter gefühlt nicht wirklich schneller. Es fühlte sich eher an, als wären alle gleich schnell und erst in Runde 5 oder 6 agierte der schnelle Charakter bemerkbar öfters. Also müsste ein Kampf über 15 Runden mind. gehen um einen schnellen Charakter auch schnell wirken zu lassen, was ich vermeiden wollte.

Die zweite ist, ein variabler Maximalwert. Der Maximalwert ist die Summe aller Tempo-Werte. Dies funktionierte und fühlte sich schon viel besser an, doch gab dies mir kaum Kontrolle über das Balanzing, so dass schnell einige Probleme geschahen.

Die nun dritte Möglichkeit ist ein Slot / Turn - Max. Dies ist etwas schwieriger technisch. Es wird ganz normal vom Tempo -1 gerechnet, bis einer bei 0 ist, der übernimmt Slot 1 und bekommt dann wieder sein Tempo wert (addiert). Dies wird dann Bsp. 10 mal wiederholt. Nun ist es aber nicht so, dass Slot 1 anfängt, sondern der letzte Slot. Dabei hat jede Aktion seinen fixen Tempo-Wert (Verteidigen hat z.B. Tempo 300, während Angriff Tempo 100 hat) und der Abzug (also -1) ist abhängig vom Agi Wert. Ein schneller Charakter (also mit hohen Agi) ist somit schneller wieder dran.

Ich hoffe das konnte dir etwas helfen / inspirieren :)

Cornix
04.04.2019, 01:14
Ich habe einmal ein Kampfsystem mit einem ähnlichen System entwickelt. Ich hatte damals viele detaillierte Tests durchgeführt, bis ich ein System gefunden habe, mit dem ich zufrieden war.
Mein System hat folgende Eigenschaften:
* Es ist relativ simpel zu implementieren. (das ist sehr gut)
* Ein Character mit doppelter Geschwindigkeit erhält ca. doppelt so viele Züge. (das ist eher gut)
* Die Anzahl der Züge für einen Character entspricht ca. der Prozentzahl von dessen Geschwindigkeitswerts in Bezug zu der Summe aller Geschwindigkeitswerte. (das ist eher gut)
* Es verhält sich zyklisch für genügend viele Züge. Das heist es bilden sich Muster für der Abfolge der Charactere. (kann gut oder schlecht sein, je nach Geschmack)
* Sehr langsame Charaktere kommen erst sehr sehr spät zum Zug (das ist eher schlecht)

Hier ist eine Beispielausgabe:


Charakter-Nummer
Geschwindigkeit des Charakters
Prozent der Summe


0
40
40


1
30
30


2
20
20


3
10
10



Summe der Geschwindigkeitswerte: 100

Anzahl der Runden: 10



Charakter-Nummer
Züge pro Charakter
Prozent der Summe


0
4
40%


1
3
30%


2
2
20%


3
1
10%



Zugreihenfolge: 0, 1, 0, 1, 2, 0, 0, 1, 2, 3

Visualisiert:

0: | | ||
1: | | |
2: | |
3: ||

Hier ist ein zweites Beispiel mit Zahlen die näher bei einander liegen:


Charakter-Nummer
Geschwindigkeit des Charakters
Prozent der Summe


0
40
~30%


1
35
~27%


2
30
~23%


3
25
~19%



Summe der Geschwindigkeitswerte: 130

Anzahl der Runden: 20



Charakter-Nummer
Züge pro Charakter
Prozent der Summe


0
6
30%


1
5
25%


2
5
25%


3
4
20%



Zugreihenfolge: 0, 1, 0, 2, 3, 1, 0, 2, 1, 0, 2, 3, 1, 0, 3, 2, 0, 1, 3, 0

Visualisiert:

0: | | | | | |
1: | | | | |
2: | | | | |
3: | | | |

Zuletzt ein extremes Beispiel mit einhundert Zügen und sehr geringen Geschwindigkeitsunterschieden:


Charakter-Nummer
Geschwindigkeit des Charakters
Prozent der Summe


0
40
~26%


1
39
~25%


2
38
~25%


3
37
~24%



Summe der Geschwindigkeitswerte: 154

Anzahl der Runden: 100



Charakter-Nummer
Züge pro Charakter
Prozent der Summe


0
26
26%


1
25
25%


2
25
25%


3
24
24%



Zugreihenfolge: 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 0, 1, 3, 2, 0, 1, 3, 2, 0, 1, 3, 2, 0, 1, 3, 2, 0, 1, 3, 2, 0, 1, 3, 2, 0, 1, 3, 0, 2, 1, 0, 2, 3, 1, 0, 2, 3, 1, 0, 2, 3, 1, 0, 2, 3, 1, 0, 2, 3, 1, 0, 2, 3

Visualisiert:

0: | | | | | | | | | | | | | | | | | | | | | | | | | |
1: | | | | | | | | | | | | | | | | | | | | | | | | |
2: | | | | | | | | | | | | | | | | | | | | | | | | |
3: | | | | | | | | | | | | | | | | | | | | | | | |



Hier ist der Ablauf des Algorithmus:

Jeder Charakter hat einen Geschwindigkeitswert (ich nenne diesen Agi). Hohe Werte sind besser als niedrige.
Im Kampf gibt es für jeden Charakter einen Ready-Wert. Also wie bereit der Charakter ist am Zug zu sein.
Zu Beginn des Kampfes wird das Ready-Limit auf das (Maximum aller Agi-Werte) + 1 gesetzt. <- Die +1 in dieser Berechnung ist wichtig! Sie verbessert das Ergebnis erheblich!
Der folgende Pseudo-Code bestimmt, welcher Charakter im Moment am Zug ist:




1) Suche den Charakter mit dem höchsten Ready-Wert
2) Hat ein Charakter einen Ready-Wert >= Ready-Limit ?
2) Falls ja => Dieser Charakter ist am Zug.
3) Falls nein => Setze für jeden Charakter den Ready-Wert = Ready-Wert + Agi
4) Gehe zurück zu 1)

Es ist hierbei wichtig, dass entweder der Ready-Wert von allen Charakteren oder von keinem erhöht wird.
Sobald ein Charakter seinen Zug durchgeführt hat gilt: Ready-Wert = Ready-Wert - Ready-Limit.
Der Ready-Wert für den aktiven Charakter wird also um das Ready-Limit reduziert.


Ich hoffe das war ausführlich genug, um das Prinzip zu verstehen.

IndependentArt
06.04.2019, 12:42
Danke für die weiteren Antworten.

@Cornix

Soweit ich das verstehe, ist das ziemlich genau das System wie ich es jetzt implementiert habe.
Interessant finde ich, dass du den Ready-Wert aus allen Agi-Werten errechnest. Das ist vermutlich ökonomischer und letztlich wohl auch gerechter. Deshalb werd ich es wohl übernehmen. :)

Apropos gerecht, ich frage mich gerade noch, was die Reihenfolge der Abfragen für einen Einfluss auf die Züge hat.
Momentan sieht meine Abfragen-Struktur für 6 Teilnehmer so aus:
Charakter 1
Gegner 1
Charakter 2
Gegner 2
Charakter 3
Gegner 3

Damit haben die oberen evtl in einigen Situationen eine starke Priorität, weil sie immer als erstes abgefragt werden. Zumindest sieht es mir danach aus, ich kann die Konsquenzen nicht völlig abschätzen.
Zum Gegensteuern schwebt mir vor, jeder Abfrage ein Label vorzuschieben. Eine Variable zählt dann immer von 1-6 und lässt das Skript damit zum jeweiligen Label springen, was das ganz wohl etwas ausgeglichener machen dürfte.

Caledoriv
06.04.2019, 13:19
Ich würde das konsistent halten und nicht Helden und Gegner abwechseln. D.h. entweder alle Helden zuerst oder alle Gegner zuerst. Im Extremfall wirkt es dann für den Spieler zufällig, wer in welcher Reihenfolge dran kommt.

Aber die Reihenfolge der Abfrage sollte sowieso nur dann etwas ändern, wenn zwei Kämpfer den gleichen Tempowert angesammelt haben. Soll heißen, die Abfrage ist im Idealfall noch etwas komplexer:

Beispiel 1:
Grenzwert ist 300
Tempo Held: 20
Tempo Gegner: 15
Momentaner Wert Held: 290
Momentaner Wert Gegner: 295

Nach dem nächsten Schritt hätten beide einen Wert von 310. Nur in diesem Fall sollte die Reihenfolge der Abfrage einen Unterschied machen.

Beispiel 2:
Grenzwert ist 300
Tempo Held: 20
Tempo Gegner: 15
Momentaner Wert Held: 290
Momentaner Wert Gegner: 290

Nach dem nächsten Schritt überschreiten beide den Grenzwert: Der Held hat 310 und der Gegner hat 305. In dem Fall wäre es in meinen Augen ideal, wenn der Held den ersten Slot bekommt und der Gegner den zweiten, obwohl beide in derselben Iteration den Grenzwert überschritten haben.

IndependentArt
07.04.2019, 19:30
@Caledoriv

Ich hab mal mit verschiedenen Abfragemethoden herumprobiert und alle haben mir zumindest für meine Werte die exakt gleichen Ergebnisse gebracht. Es scheint also, als macht das nur einen marginalen Unterschied.

---

Ich habe indessen die Basisvariante implementiert, welchen sehr zuverlässig die Reihenfolge ermittelt.
Jetzt hantiere ich gerade mit Dingen herum, die doch etwas komplizierter sind als erwartet: Flexible "Zugzeit" und Preview. Damit meine ich einfach, dass natürlich unterschiedliche Aktionen unterschiedlich lang dauern sollen. Ich will jetzt nicht auf die spefizischen Probleme eingehen, auf die ich dabei gerade stoße, weil ich im Moment schon noch davon ausgehe, die selbst lösen zu können.

Ich bin dabei jedoch auf eine Design-Frage gestoßen: Angenommen ich wähle für meinen gegenwärtigen Zug eine Aktion, welche die doppelte Zeit benötigt. Sollte der gleiche Zug auch für alle folgenden berechneten Züge angenommen werden oder wird für die ein Zug mit normaler Geschwindigkeit angenommen?
Angenommen die Basisdauer ist 100 und eine spezielle Aktion dauert 200.
Dann würde für die Folgezüge eins dieser Muster herauskommen:

200 100 100 100 100 100 100 (für den 2. Zug zurück zur Basisberechnung)
200 200 200 200 200 200 200 (spezielle Berechnung beibehalten)

Aus meiner Sicht ist es ziemlich naheliegend, die erste Variante zu wählen, so baue ich es auch gerade. Aber vielleicht habt ihr ja noch andere Gedanken dazu.

Caledoriv
07.04.2019, 20:02
Ja, die Reihenfolge der Abfrage macht nur einen Unterschied, wenn mehrere Kämpfer gleichzeitig die Grenze überschreiten.

@ Zugdauer:
Mehr Infos bitte^^. Im Moment habe ich den Eindruck, dass sich beim Wählen dieser "langen" Aktion die Zugreihenfolge ändern kann und dementsprechend an dieser Stelle neu berechnet werden müsste? Ist das so oder habe ich das falsch verstanden?

Generell hatte ich eine Zugdauer bisher nicht auf dem Schirm; ich bin bisher davon ausgegangen, dass Aktionen keine Dauer haben und dementsprechend nur der Tempowert die Reihenfolge bestimmt. Falls dem nicht so ist, würde ich die Aktionsdauer für den Standardangriff als Referenzwert nehmen.

-----
Ich bin gerade so überrascht, weil eine sich ändernde Reihenfolge für mich als Spieler ersteinmal komisch wirkt und mir im schlechtesten Fall meine Strategie versaut, weil mein Held auf einmal nicht mehr wie angezeigt an die Reihe kommt. Wenn man die Reihenfolge nicht so hunderprozentig genau sieht (wie z.B. in Mondschein), sind solche Änderungen kein Problem.
Aber wenn ich als Spieler alles schon mehrere Züge vorausplanen kann und für mich die neue Zugreihenfolge nicht ersichtlich ist, macht das u.U. keinen guten Eindruck.

Daher würde ich in dem Fall unbedingt eine Anzeige einbauen, wie sich die Zugreihenfolge mit dieser Aktion verändert! Dann kann ich als Spieler immer noch genau so vorausplanen und erlebe keine "bösen" Überraschungen. Außerdem ist das ein cooler Effekt für Dinge, welche das Tempo erhöhen / erniedrigen.

IndependentArt
10.04.2019, 17:31
Hi,
sorry für die späte Antwort, war etwas beschäftigt.
Ich hab nun festgestellt, dass ich die Abfragereihenfolge doch durchzählen muss. Ich hatte einen Fall mit 2 Kampfteilnehmern und es kam immer nur der Charaktere an die Reihe. Das Durchzählen der Abfragen konnte das fixen.


@ Zugdauer:
Mehr Infos bitte^^. Im Moment habe ich den Eindruck, dass sich beim Wählen dieser "langen" Aktion die Zugreihenfolge ändern kann und dementsprechend an dieser Stelle neu berechnet werden müsste? Ist das so oder habe ich das falsch verstanden?
Exakt.
Ich kenne ehrlich gesagt nur 2 Spiele mit diesem System und beide haben unterschiedliche Zugdauer für bestimmte Aktionen.


Daher würde ich in dem Fall unbedingt eine Anzeige einbauen, wie sich die Zugreihenfolge mit dieser Aktion verändert! Dann kann ich als Spieler immer noch genau so vorausplanen und erlebe keine "bösen" Überraschungen. Außerdem ist das ein cooler Effekt für Dinge, welche das Tempo erhöhen / erniedrigen.
Ich denke, das ist ja auch genau das, was ich mit dem Preview bezwecken will, sofern wir da nicht aneinander vorbei reden.
Ich hab mal ein Beispiel:

https://imgdb.net/images/5270.png


Ich experimentiere gerade mit Prozentwerten herum:
Die Aktion Angriff läuft bei diesem Beispiel auf 100% des Tempowerts.
Zauber hingegen läuft auf 500%.
Die Tempowerte beider Teilnehmer sind 11. Damit ergibt sich ein Ready-Wert von 22+1.
Ich hätte bei 500% glaube ich mit einem etwas größeren Unterschied gerechnet, sprich, dass Ramirez noch mehr Züge bekommt. Aber ich denke, das liegt am Wechsel der Abfragenreihenfolge und an der Formel des Ready-Werts.
Gleich mal ausprobieren ... YO, frage ich eine feste Größe wie 255 als ab, sieht die Verteilung für "Zauber" schon anders aus:

https://imgdb.net/images/5271.png

edit: stimmt nicht, war mein Fehler. auch mit einem festen ready Wert von 255 kommt genau das gleiche raus.

Die 500% sind natürlich ein unrealistisches Beispiel. Ich denke nicht, dass die Zuglänge großartig über Unterschiede zwischen 50-200% hinaus geht, aber es verdeutlicht, worauf man achten muss, je nachdem, in welche Richtung man das Syteam tweaken will. Das muss ich mir jetzt eben genau überlegen.

Caledoriv
10.04.2019, 18:23
Moment; das mit den Prozentwerten erscheint mir nicht schlüssig... sofern ich das richtig verstehe.

Beispiel:
Mein Startheld lernt auf Level 5 gerade seinen ersten Zauber. Der Zauber dauert 200% des Tempos. Der Tempowert auf dem niedrigen Level ist 15. Ergo: Die Aktion dauert 30 Einheiten.

Jetzt spiele ich weiter. Mein Held wird Level 35 und hat jetzt Tempowert 50. Derselbe Zauber dauert jetzt nach dieser Logik 100 Einheiten (anstatt wie auf dem niedrigen Level nur 30).


=> Habe ich das so richtig verstanden? Das erscheint mir nicht sinnvoll zu sein, wenn dem wirklich so ist. Als Alternative werfe ich mal das hier ein:

(Dauer des Standardangriffs) * (Modifikator der Aktion)
------------------------------------------------------------------------------ = Dauer der Aktion
...................... Tempowert des Charakters


@ Reihenfolgeanzeige:
In den Bildern wird also die Reihenfolge bei Ausführen dieser Aktion angezeigt? D.h. wenn ich Pfeil hoch / runter drücke, wird sofort die Reihenfolge geupdated? Wenn das so ist, finde ich das top :A.

IndependentArt
10.04.2019, 18:36
=> Habe ich das so richtig verstanden? Das erscheint mir nicht sinnvoll zu sein, wenn dem wirklich so ist.

Nein. Die Prozent beziehen sich auf das, was hinzugefügt wird.
Beispiel für einen Durchlauf des Skripts bei Tempowert 10:
100%: aktueller Zeitwert + 10
500%: aktueller Zeitwert + 50

Der "aktuelle Zeitwert" ist quasi der Wert, der den Ready-Wert überschreiten muss, damit ein Slot in der Aktionsreihenfolge belegt wird.


In den Bildern wird also die Reihenfolge bei Ausführen dieser Aktion angezeigt? D.h. wenn ich Pfeil hoch / runter drücke, wird sofort die Reihenfolge geupdated? Wenn das so ist, finde ich das top .

So wahr mir Gott helfe:

https://imgdb.net/images/5272.gif

Das ist ein Test mit 1000% für Zauber. Ich verstehe es noch nicht ganz.

Caledoriv
10.04.2019, 18:59
Danke für die Bilder^^.
Sieht auf jeden Fall richtig gut aus! :D
Die 3D-Perspektive macht richtig was her :A.

Bzgl. Dauer einer Aktion:
Anscheinend haben wir wirklich aneinander vorbeigeredet. Bisher bin ich davon ausgegangen, dass die Aktion sofort ausgeführt wird, aber die Aktionsdauer dann negativ für den folgenden Zug berechnet wird (d.h. mache ich jetzt eine Aktion mit hoher Dauer, dauert es länger, bis ich wieder dran komme).

Jetzt habe ich den Eindruck, dass die Aktion erst ausgeführt wird, wenn diese Dauer vergangen ist. So ähnlich wie in Grandia.
Also so ganz blicke ich noch nicht, wie genau du das umsetzt. Ist aber auch nicht so wichtig^^.

IndependentArt
10.04.2019, 20:21
Danke. ^^ Der Gegner ist nur nicht für den HG gedacht, deswegen kollidiert er ein wenig mit dem Haus.

Vielleicht kann ich hier auch ne kleine Techdemo von dem System reinstellen. Ich hab auf jeden Fall jetzt mehr Zeit, daran zu arbeiten.

Cornix
10.04.2019, 20:25
Falls du immernoch mit deinem Algorithmus etwas ähnliches implementierst, wie das was ich beschrieben hatte, dann müsstest du eine "Aktions-Dauer" beim abziehen des Ready-Werts implementieren. Also diese Zeile von meinem Algorithmus würde sie ändern:

Alt:

Sobald ein Charakter seinen Zug durchgeführt hat gilt: Ready-Wert = Ready-Wert - Ready-Limit
Neu:

Sobald ein Charakter seinen Zug durchgeführt hat gilt: Ready-Wert = Ready-Wert - (Ready-Limit * Aktions-Dauer)
Eine Aktion könnte also eine Dauer von 2,0 haben und würde dann doppelt so lange dauern wie eine Aktion mit einer Dauer von 1,0.

Falls du keine Kommazahlen zur Verfügung hast kannst du eine simple Prozentrechnung durch eine Teilung durch 100 nach der Multiplikation erreichen. Also:

Ready-Wert = Ready-Wert - (Ready-Limit * Aktions-Dauer) / 100
Hierbei wäre die Aktions-Dauer ein Prozentwert, also 100 für 100%, 175 für 175%, etc.

Vielleicht hilft dir das ja in irgendeiner Weise weiter.

IndependentArt
10.04.2019, 21:49
@Cornix

Von der Seite könnte man das natürlich auch angehen. Muss ich mal ausprobieren. :) u.U. droppt der Wert dann halt zeitweise ins Minus.
Bis jetzt hab ich quasi versucht, die Prozentrechnung auf den Wert, der immer hinzugefügt wird (quasi den Tempowert) anzuwenden. Bin mir nicht sicher, was das für nen Unterschied macht.
edit: das scheint mir zum genau gleichen Ergebnis zu führen. ich schreib morgen nochmal, womit ich momentan etwas hadere.

IndependentArt
12.04.2019, 20:27
Ich habe das Gefühl, es wird langsam. Trotzdem gehen dem Skript noch nicht die Ideen für neue Bugs aus.
Ich versuche mal mein gegenwärtiges Problem mit Hilfe dieses Videos zu erörtern:


https://www.youtube.com/watch?v=pPDWCBMKKoI

Ich verlange nicht, dass da jemand durchsieht. Vielleicht hilft es mir ja auch schon, das einfach aufzuschreiben.
Die Aktion Zauber hat in diesem Beispiel eine Geschwindigkeit von 20% (vom Tempowert, bei Tempowert 10 also 2). Man könnte auch sagen, sie ist 80% langsamer als der normale Angriff. Dementsprechend viele Züge bekommt der Gegner, wenn ich sie auswähle. (ich benutze dann nur Abwehr, weil das als Aktion keine wirkliche Dauer hat)
Verfolgt man das Video weiter, sieht man, dass der Hase 2 Mal dran ist. Nach dem 2. Zug, verändert sich jedoch die Reihenfolge (etwa bei Sekunde 9, Tipp: mit , und . kann man Frames springen ;)). Das hat damit zu tun, dass die "Aktionsdauer" zurückgesetzt wird. Das heißt, ab da werden die nächsten Züge nicht mehr mit 20%, spondern wieder mit 100% berechnet und der Charakter ist schneller dran als ursprünglich gedacht. Das hat damit zu tun, was ich weiter oben beschrieben habe, dass die veränderte Aktionsdauer nur für den nächsten Zug angenommen wird und die Züge danach wieder mit 100% berechnet werden.

Nun könnte man auf die Idee kommen zu sagen: "Na dann lass die Zugdauer halt bis zum nächsten Zug des Charakters gleich".
Das war auch mein erster Impuls, aber ich habe den Eindruck, wenn ich mit 20% NEU berechne, funktioniert das auch nicht wirklich. Vielleicht hab ich da aber auch nur irgendnen Fehler drin, den ich grad noch nicht checke.

Caledoriv
12.04.2019, 21:19
Was wäre denn das gewünschte Verhalten? Irgendwie stehe ich hier öfter auf dem Schlauch... :rolleyes:
Soll der Hase bei dem niedrigen Tempowert des Helden 4x hintereinander dran kommen? In dem Fall sollte der Tempo-Modifikator erst mit dem nächsten Zug des Charakters geändert werden.

Als kleine Anmerkung: Die Berechnung zeigt hier teilweise falsche Prognosen an; es wird angezeigt: Hase Hase Hase Hase Hase Ramirez Hase Hase Hase Hase Hase Ramirez ....
Der unterstrichene Teil ist da ja noch korrekt, aber danach stimmt es nicht mehr.

----
Was hälst du davon, jedem Zauber einfach einen (ggf. vom Tempowert abhängigen) Malus zu geben, der einmalig abgezogen wird? Dann sollte die Berechnung immer korrekt angezeigt werden.

IndependentArt
12.04.2019, 22:40
Soll der Hase bei dem niedrigen Tempowert des Helden 4x hintereinander dran kommen? In dem Fall sollte der Tempo-Modifikator erst mit dem nächsten Zug des Charakters geändert werden.

Ja, so soll das eigentlich laufen. Den Tempo-Modifikator erst mit dem nächsten Zug zu ändern hab ich wie gesagt versucht, aber vlt hab ich da auch nen Fehler reingebaut.


Hase Hase Hase Hase Hase Ramirez Hase Hase Hase Hase Hase Ramirez ....
Der unterstrichene Teil ist da ja noch korrekt, aber danach stimmt es nicht mehr.


Wo genau siehst du da den Fehler ...?


Was hälst du davon, jedem Zauber einfach einen (ggf. vom Tempowert abhängigen) Malus zu geben, der einmalig abgezogen wird? Dann sollte die Berechnung immer korrekt angezeigt werden.

Das dürfte ungefähr auf das gleiche hinauslaufen, was Cornix mit "Ready-Wert = Ready-Wert - (Ready-Limit * Aktions-Dauer) / 100" vorgeschlagen hat, oder?

Caledoriv
12.04.2019, 23:11
Wo genau siehst du da den Fehler ...?
Angezeigt wird: 4x Gegner, Held, 4x Gegner
Aber die tatsächliche Reihenfolge ist doch eher: 4x Gegner, Held, 1x Gegner, Held
Weil der Held ja erstmal wieder sein "normales Tempo" zurückbekommt, wenn er das erste Mal wieder dran ist, oder?


Das dürfte ungefähr auf das gleiche hinauslaufen, was Cornix mit "Ready-Wert = Ready-Wert - (Ready-Limit * Aktions-Dauer) / 100" vorgeschlagen hat, oder?
Das geht alles irgendwo in die gleiche Richtung :). Ich dachte eher an:
Ready-Wert = Ready-Wert - Ready-Limit - (Aktionsdauer / Tempowert)

IndependentArt
14.04.2019, 13:11
Puh, dieses Skript fuckt mich mehr ab, als ich gedacht hätte. Deswegen will ich mein Hauptproblem nochmal mit Hilfe eines Videos illustrieren.

Bedingungen:
Charakter Tempo: 20
Gegner Tempo: 20
ReadyWert: 41

Ich habe im Video das jeweilige Durchzählen beim Charakter mit einer Message Box visualisiert (nicht für das Preview allerdings).
Außerdem läuft die Formel jetzt wieder mit einem "Malus", wie es Caledoriv nannte. Die Aktion Zauber hat eine Aktionsdauer von 500. Es wird also der ReadyWert*5 abgezogen. Bei 00:27 sieht man dann, dass das erfolgreich erledigt wurde und der aktuelle Wert des Charakters bei -194 liegt.
In der Folge bekommt der Gegner ganze 6 Slots, bevor der Charakter wieder einen bekommt.

Jetzt kommt allerdings das Problem: Der Charakter-Wert hat schon in dieser ersten Runde wieder aus dem Minus "herausgefunden" und einen normalen Wert erreicht. Deshalb wird er in der Berechnung, die ab ca. 00:50 stattfindet, wieder weiter vorn eingegliedert.
Vielleicht hab ich ja mal wieder ein Brett vorm Kopf und die Lösung dafür ist relativ offensichtlich.


https://www.youtube.com/watch?v=cxMLzyDX3Pk&feature=youtu.be

Caledoriv
14.04.2019, 16:09
Kann es sein, dass du irgendwo den Wert auf 0 setzt? Weil im Video nach dem Hasenangriff bei 0:47 wieder 0 eingeblendet wird.

Alternativ kann es auch sein, dass es einen Bug gibt, wenn der Wert genau 0 erreicht, sobald das Ready-Limit abgezogen wird. Wenn ich mich nicht irre, passiert das an genau der Stelle nämlich auch. Das kann Zufall sein oder auch nicht^^.

IndependentArt
14.04.2019, 16:41
Dass der Wert dort auf 0 droppt ist Zufall. Der letzte Wert davor, der für den Charakter errechnet wurde, war 21. als nächstes wird also 21+20-41 gerechnet und es kommt genau auf 0.
Das Problem ist halt, dass die Aktionsdauer angewendet wird, aber für den nächsten Rechendurchgang schon wieder aufgehoben ist.
Ich hab zwar ein paar Ideen, wie man das lösen könnte, aber die erscheinen mir im Moment furchtbar kompliziert.
zB könnte man versuchen, dass von der Aktionsdauer bei jedem Rechendurchgang maximal 100%=1 Zug=ReadyWert abgezogen wird. Das heißt, bei der ersten Berechnung nachdem man den 500% Zug ausgeführt hat, werden auch die 500% abgezogen. Gleichzeitig wird allerdings die Aktionsdauer selbst um 100% erleichtert. Danach werden also dann 400% abgezogen, dann 300% usw., bis der Charakter wieder dran ist und eine neue Aktionsdauer festlegen kann.

Caledoriv
14.04.2019, 20:11
Das Problem ist halt, dass die Aktionsdauer angewendet wird, aber für den nächsten Rechendurchgang schon wieder aufgehoben ist.
Ganz doofe Frage von meiner Seite: Warum wird da überhaupt etwas aufgehoben?

Das sollte eigentlich auch so funktionieren. Genau das ist ja das Elegante an der Idee, einfach die Dauer als zusätzlichen Malus draufzurechnen :).
Beim Erreichen des Ready-Limits wird neben dem Ready-Limit zusätzlich noch die Dauer der Aktion abgezogen. Mehr muss dann eigentlich nicht gemacht werden, weil die Berechnung der Züge wie gehabt weitergehen kann... Die Verzögerung entsteht dann durch diesen Malus, d.h. es dauert länger, bis der Ready-Wert erreicht ist, weil zuerst dieser Malus "abgearbeitet"

Oder übersehe ich da etwas?

IndependentArt
15.04.2019, 22:18
Ich bin zwar glaub ich einen Schritt weiter, aber es spackt immer noch rum. Wenigstens mit einem bestimmten Wert für die Aktionsdauer hat es funktioniert.
Noch ein Video mit einer Aktionsdauer von 200 (Rechnung siehe unten) für Zauber:

https://www.youtube.com/watch?v=rEhmSvKgFdg&feature=youtu.be

Man sieht, dass ein Zug des Gegners zwischendrin geschluckt wird.

Evtl übersiehst du bei dem Malus tatsächlich etwas. Ich versuche mal zu erklären warum:
Ich habe das momentan so geregelt, dass ich die Aktionsdauer auf 2 Variablen festlege (1848, 1849). 2 Variablen, weil ich eine davon für das Preview brauche.
Preview Codeblock:


@> Conditional Branch: Switch [1733:CTB PREVIEW] is ON
@> Conditional Branch: Variable [1849:R CTB Aktionsdauer%] > 0
@> Control Variables: [1806:CTB Ready Abzug] = Variable [1805]
@> Control Variables: [1806:CTB Ready Abzug] *= Variable [1849]
@> Control Variables: [1806:CTB Ready Abzug] /= 100
@> Control Variables: [1855:R-CTB Order Preview] -= Variable [1806]
@> Control Variables: [1849:R CTB Aktionsdauer%] = 0
@>
: Branch End
@> Comment:
@> Control Variables: [1855:R-CTB Order Preview] += Variable [1815]
@> Conditional Branch: Variable [1855:R-CTB Order Preview] >= Variable [1805:CTB Ready]
@> Control Variables: [1855:R-CTB Order Preview] -= Variable [1805]


Der erste Teil ist quasi die Malus-Rechnung. Wenn eine Aktionsdauer festgelegt wurde, diese also größer als 0 ist, wird die Rechnung durchgeführt. Für eine StandardAktion nehme ich aus gewissen Gründen eine Aktionsdauer von 0 an. Die Rechnung wird also nur ausgeführt, wenn die Dauer drüber liegt.
Der Malus wird errechnet und vom Preview-Wert abgezogen. Außerdem wird die Aktionsdauer 0 gesetzt, weil das ganze nur 1 Mal durchgeführt werden soll. Ich glaube, das funktioniert auch soweit ganz gut. Wenn ich zB einen Aktionswert von 100 festlege, bekommt der Gegner genau einen Zug mehr.
Ich bin nicht sicher, in wie weit das mit eurem Ansatz überein stimmt. Ich fand es wichtig, dass der Malus vor der sonstigen Rechnung abgezogen wird. Passiert das erst danach, könnte ja zwischendrin schon ein Zug berechnet und ein Slot gefüllt worden sein.

Code der eigentlichen Berechnung des Malus nach dem Zug:


@> Conditional Branch: Variable [1848:R CTB AD% SAVE] > 0
@> Control Variables: [1806:CTB Ready Abzug] = Variable [1805]
@> Control Variables: [1806:CTB Ready Abzug] *= Variable [1848]
@> Control Variables: [1806:CTB Ready Abzug] /= 100
@> Control Variables: [1807:R-CTB Order] -= Variable [1806]
@> Control Variables: [1848:R CTB AD% SAVE] -= 100


Der Block befindet sich direkt am Anfang des Gesamtcodes. Dadurch war es einfacher, ihn nur 1 mal durchlaufen zu lassen. Eigentlich ist fast alles gleich wie bei dem für das Preview. Der Hauptunterschied ist, dass V1848 nicht 0 gesetzt wird, sondern 100 abgezogen wird, weil die Variable ja mehrere Züge, jeweils unter Abzug eines Zuges (-100%) in Benutzung ist.

Die Formel "Ready-Wert = Ready-Wert - Ready-Limit - (Aktionsdauer / Tempowert)" verstehe ich aber offen gesagt auch nicht so recht. :| Kann es sein, dass da ein falsches Zeichen drin ist?

btw: Irgendwelche Tipps, wie man bei sowas besser den Überblick behält? Ich hab das Gefühl, das ist einfach zu viel für mein gehirn. xD

Gesamtcode:


@> Conditional Branch: Switch [1733:CTB PREVIEW] is ON
@> Control Variables: [1855:R-CTB Order Preview] = Variable [1807]
@> Control Variables: [1856:M/B-CTBOrder Preview] = Variable [1808]
@> Control Variables: [1857:C/V-CTBOrder Preview] = Variable [1809]
@> Control Variables: [1858:G1-CTB Order Preview] = Variable [1810]
@> Control Variables: [1859:G2-CTB Order Preview] = Variable [1811]
@> Control Variables: [1860:G3-CTB Order Preview] = Variable [1812]
@> Comment:
@>
: Else
@> Conditional Branch: Variable [1848:R CTB AD% SAVE] > 0
@> Control Variables: [1806:CTB Ready Abzug] = Variable [1805]
@> Control Variables: [1806:CTB Ready Abzug] *= Variable [1848]
@> Control Variables: [1806:CTB Ready Abzug] /= 100
@> Control Variables: [1807:R-CTB Order] -= Variable [1806]
@> Control Variables: [1848:R CTB AD% SAVE] -= 100
@>
: Branch End
@>
: Branch End
@> Control Variables: [1804:Teilnehmer Abfrage] = Variable [1803]
@> Control Variables: [1814:current CTB slot] = 1821
@> Control Variables: [1841:CTB Kapsel ID] = 2000
@> Control Variables: [1842:CTB Kapsel X] = 116
@> Control Variables: [1843:CTB Kapsel Y] = 227
@> Jump to Label: 10
@> Label: 1
@> Conditional Branch: Switch [1005:Ramirez tot] is OFF
@> Conditional Branch: Switch [1001:Ramirez nicht im K] is OFF
@> Conditional Branch: Switch [1733:CTB PREVIEW] is ON
@> Conditional Branch: Variable [1849:R CTB Aktionsdauer%] > 0
@> Control Variables: [1806:CTB Ready Abzug] = Variable [1805]
@> Control Variables: [1806:CTB Ready Abzug] *= Variable [1849]
@> Control Variables: [1806:CTB Ready Abzug] /= 100
@> Control Variables: [1855:R-CTB Order Preview] -= Variable [1806]
@> Control Variables: [1849:R CTB Aktionsdauer%] = 0
@>
: Branch End
@> Comment:
@> Control Variables: [1855:R-CTB Order Preview] += Variable [1815]
@> Conditional Branch: Variable [1855:R-CTB Order Preview] >= Variable [1805:CTB Ready]
@> Control Variables: [1855:R-CTB Order Preview] -= Variable [1805]
@>
: Else
@> Jump to Label: 10
@>
: Branch End
@>
: Else
@> Comment:
: :
@> Control Variables: [1807:R-CTB Order] += Variable [1815]
@> Conditional Branch: Variable [1807:R-CTB Order] >= Variable [1805:CTB Ready]
@> Control Variables: [1807:R-CTB Order] -= Variable [1805]
@> Control Variables: Variable [1814] = 1
@>
: Else
@> Jump to Label: 10
@>
: Branch End
@>
: Branch End
ANZEIGE R

@>
: Branch End
@> Control Variables: [1814:current CTB slot] += 1
@> Control Variables: [1841:CTB Kapsel ID] += 1
@> Control Variables: [1842:CTB Kapsel X] += 14
@>
: Branch End
@>
: Branch End
@> Jump to Label: 10
@> Comment:
: :
@> Label: 2
@> Conditional Branch: Switch [1009:Gegner 1] is ON
@> Conditional Branch: Switch [1733:CTB PREVIEW] is ON
@> Control Variables: [1858:G1-CTB Order Preview] += Variable [1818]
@> Conditional Branch: Variable [1858:G1-CTB Order Preview] >= Variable [1805:CTB Ready]
@> Control Variables: [1858:G1-CTB Order Preview] -= Variable [1805]
@>
: Else
@> Jump to Label: 10
@>
: Branch End
@>
: Else
@> Control Variables: [1810:G1-CTB Order] += Variable [1818]
@> Conditional Branch: Variable [1810:G1-CTB Order] >= Variable [1805:CTB Ready]
@> Control Variables: [1810:G1-CTB Order] -= Variable [1805]
@> Control Variables: Variable [1814] = 4
@>
: Else
@> Jump to Label: 10
@>
: Branch End
@>
: Branch End
ANZEIGE G1

@>
: Branch End
@> Control Variables: [1814:current CTB slot] += 1
@> Control Variables: [1841:CTB Kapsel ID] += 1
@> Control Variables: [1842:CTB Kapsel X] += 14
@>
: Branch End
@> Jump to Label: 10
@> Comment:
: :
: Branch End
@> Comment:
: :
@> Label: 10
@> Conditional Branch: Variable [1814:current CTB slot] < 1838
@> Control Variables: [1804:Teilnehmer Abfrage] += 1
@> Conditional Branch: Switch [1733:CTB PREVIEW] is OFF
@> Control Variables: [1803:Teiln.Abfrage SAVE] = Variable [1804]
@>
: Branch End
@> Conditional Branch: Variable [1804:Teilnehmer Abfrage] == 1
@> Jump to Label: 1
@>
: Else
@> Conditional Branch: Variable [1804:Teilnehmer Abfrage] == 2
@> Jump to Label: 2
@>
: Else
@> Conditional Branch: Variable [1804:Teilnehmer Abfrage] == 3
@> Jump to Label: 3
@>
: Else
@> Conditional Branch: Variable [1804:Teilnehmer Abfrage] == 4
@> Jump to Label: 4
@>
: Else
@> Conditional Branch: Variable [1804:Teilnehmer Abfrage] == 5
@> Jump to Label: 5
@>
: Else
@> Conditional Branch: Variable [1804:Teilnehmer Abfrage] == 6
@> Control Variables: [1804:Teilnehmer Abfrage] = 0
@> Jump to Label: 6
@>
: Branch End
@>
: Branch End
@>
: Branch End
@>
: Branch End
@>
: Branch End
@>
: Branch End
@>
: Branch End

@> Control Switches: [1733:CTB PREVIEW] = OFF

Caledoriv
15.04.2019, 23:34
Die Formel "Ready-Wert = Ready-Wert - Ready-Limit - (Aktionsdauer / Tempowert)" verstehe ich aber offen gesagt auch nicht so recht. :| Kann es sein, dass da ein falsches Zeichen drin ist?

btw: Irgendwelche Tipps, wie man bei sowas besser den Überblick behält? Ich hab das Gefühl, das ist einfach zu viel für mein gehirn. xD

Für den Code ist es mir jetzt zu spät...:hehe:

Zur Formel:
Die Idee dazu ist folgende: Wende die Formel an, soabld der Ready-Wert überschritten ist. Hier mal zwei Beispiele (das erste ohne Tempowert, um es einfach zu halten):


Ready-Wert = Ready-Wert - Ready-Limit - Aktionsdauer
Ready-Limit = 300
Ready-Wert nach dem neuen Update: 320
Tempo des Helden: 40

Schritt 1: Ziehe Ready-Limit ab, damit ganz normal die Reihenfolge berechnet werden kann.
Neuer Ready-Wert: 320 - 300 = 20

Schritt 2: Aktion wählen. Die Aktion hat eine Dauer von 100. Ziehe diesen Wert ebenfalls vom Ready-Wert ab:
Neuer Ready-Wert: 20 - 100 = -80

Berechne jetzt ganz normal die Reihenfolge, indem in jeder Iteration der Tempowert auf den Ready-Wert draufgerechnet wird. Der Held braucht ca. 3 Runden, bis er diesen zusätzlichen Malus aufgeholt hat, sodass der Gegner früher wieder dran kommt.



Ready-Wert = Ready-Wert - Ready-Limit - (Aktionsdauer / Tempowert)
Das hier macht genau das Gleiche wie oben, allerdings ist die Aktionsdauer (und damit der Malus) jetzt nicht immer konstant, sondern hängt vom Tempowert des Helden ab. D.h. wenn der Held ein höheres Tempo hat, hat er auch einen niedrigeren Malus. (Allerdings muss hier die Aktionsdauer wesentlich höher sein als oben!)

Ready-Limit = 300
Ready-Wert nach dem neuen Update: 320
Tempo des Helden: 40

Schritt 1: Ziehe Ready-Limit ab, damit ganz normal die Reihenfolge berechnet werden kann.
Neuer Ready-Wert: 320 - 300 = 20

Schritt 2: Aktion wählen. Die Aktion hat eine Dauer von 4000, d.h. der Bruch (Aktionsdauer / Tempowert) hat einen Wert von 4000/40 = 100. Ziehe diesen Wert vom Ready-Wert ab.
Neuer Ready-Wert: 20 - 100 = -80

-----
Der Held levelt auf und hat jetzt Tempo 50 (statt 40). In Schritt 2 ändert sich damit die Rechnung:
Schritt 2: Aktion wählen. Die Aktion hat eine Dauer von 4000, d.h. der Bruch (Aktionsdauer / Tempowert) hat einen Wert von 4000/50 = 80. Ziehe diesen Wert vom Ready-Wert ab.
Neuer Ready-Wert: 20 - 80 = -60

Die Idee dahinter ist quasi, dass der Malus sich mit der Zeit verringert, d.h. der Held kann die Aktion über die Zeit schneller ausführen. Da müsste aber wohl noch etwas bei der Berechnung nachjustiert werden, weil der Effekt marginal ist...


Tipps:
Du kannst dir das ggf. mit einem Diagramm bzw. Automaten veranschaulichen:
https://de.wikipedia.org/wiki/Zustandsdiagramm_(UML)
https://de.wikipedia.org/wiki/Deterministischer_endlicher_Automat
Der ganze mathematische Hintergrund kann ignoriert werden... Scroll einfach zu den Bildern und lies die Überschiften dazu :D. Diese Dinger sind zwar nicht genau das, was du möchtest, gehen aber in die richtige Richtung.

Genau geht es mit einem Aktivitäsdiagramm, weil du damit den Code quasi "grafisch" vor dir hast:
https://de.wikipedia.org/wiki/Aktivit%C3%A4tsdiagramm
Ich fand es aber am Anfang relativ schwer, mir sowas aufzumalen. Ggf. reichen ein paar einfache Kreise mit ein paar Pfeilen wie oben ja auch schon aus, um den Überblick nicht zu verlieren.

IndependentArt
16.04.2019, 11:52
Ready-Wert = Ready-Wert - Ready-Limit - Aktionsdauer
Ready-Limit = 300
Ready-Wert nach dem neuen Update: 320
Tempo des Helden: 40

Schritt 1: Ziehe Ready-Limit ab, damit ganz normal die Reihenfolge berechnet werden kann.
Neuer Ready-Wert: 320 - 300 = 20

Schritt 2: Aktion wählen. Die Aktion hat eine Dauer von 100. Ziehe diesen Wert ebenfalls vom Ready-Wert ab:
Neuer Ready-Wert: 20 - 100 = -80

Berechne jetzt ganz normal die Reihenfolge, indem in jeder Iteration der Tempowert auf den Ready-Wert draufgerechnet wird. Der Held braucht ca. 3 Runden, bis er diesen zusätzlichen Malus aufgeholt hat, sodass der Gegner früher wieder dran kommt.

Ich denke, das ist im großen und ganzen das, was ich versucht habe einzubauen. Wir müssen nur ein bisschen aufpassen, dass wir mit den Namen für die Werte nicht durcheinander kommen.
Deine Bezeichnungen dürften bei mir so heißen:
Ready-Limit = CTB Ready
Ready-Wert = R-CTB Order (Preview)
Ich bin nicht sicher, ob du das bedacht hast: Wenn erst im Schritt 2 die Aktionsdauer abgezogen wird, wurde ja vorher mit Erreichen des Ready-Limits schon ein Zug berechnet. Vielleicht hängt das aber auch von der Reihenfolge des ganzen Ablaufs ab.
Außerdem: Bei mir wird die Aktionsdauer prozentual auf das Ready-Limit bezogen. Bei Ready-Limit 300 und Aktionsdauer von 100 (%) wäre das also -300. Eine feste Aktionsdauer von 100 wäre ja bei sich veränderndem Ready-Limit etwas schwierig, aber das hast du vmtl. Auch nicht so vorgesehen.
Außerdem muss man da auch wieder unterscheiden zwischen Preview und eigentlicher Berechnung (wie ich es oben getan habe):
Preview:
Hier kann natürlich bequem einfach die komplette Aktionsdauer abgezogen werden. Ich setze wie oben beschrieben anach die Aktionsdauer 0, damit das nur 1 Mal geschieht. Damit also die nächsten Züge wieder mit normaler Dauer berechnet werden.

Eigentliche Berechnung:
Angenommen nach dem Zug des Charakters hat der Gegner 3 Züge, weil die Aktion so lang dauert. Für den ersten Zug ist die Rechnung im Prinzip genau so wie beim Preview: die volle Aktionsdauer wird abgezogen. Nach dem ersten Zug des Gegners wird alles wieder neu berechnet. Die Aktionsdauer muss also sozusagen um 1 Zug verringert werden, so wie oben beschrieben.

Ich hoffe, wir verstehen uns irgendwie. ^^
Danke auch für die Links, mal sehen, ob ich damit was anfanen kann.

Ken der Kot
17.04.2019, 13:31
Puh, langsam wird das schwierig zu durchschauen. :eek: Ich meld mich, sobald ich der Meinung bin, dass ich da noch halbwegs gut genug durchblicke, um dazu was sagen zu können. Aber wär's nicht Stand Jetzt deutlich einfacher, wenn du jemanden bittest, dir ein C-Programm zu schreiben, das sich so verhält wie du es gerne hättest? Ich meine, es ist sehr löblich, dass du das komplette KS über Events realisieren willst, aber bei einem so großen Projekt ist das vom Arbeitsaufwand doch unverhältnismäßig? Frag mal Brei -- der Kerl, der zur Zeit die Spielanalysen streamt. Der scheint von Dyn-Programmen sehr viel Ahnung zu haben. Vielleicht sind das mit C nur ein paar Zeilen Code, während das bei Events echt ausufernd wird. Nur mal so als kleinen Gedankenanstoß, falls du partout nicht weiterkommen solltest.

IndependentArt
17.04.2019, 18:03
Ich denke, ich hab jetzt ne relativ genaue Vorstellung, wo das Problem liegt. Ich versuche das mal in aller kürze darzulegen:
Das Preview fängt ja immer beim gleichen Wert an und rechnet dann alle Slots bis zum Schluss aus.

Angenommen, es werden nach dem Zug des Charakters 3 Züge für den Gegner berechnet, siehe hier:

https://www.youtube.com/watch?v=rEhmSvKgFdg&feature=youtu.be
Die fixe Berechnung (also nicht das Preview) findet nach den Zügen statt. Direkt nachdem der Charakter seinen Zug beendet hat, ist die Berechnung noch synchron mit dem Preview.
Der 2. Durchgang der fixen Berechnung findet nach dem Gegnerzug statt und es wird ein Zug des Charakters weiter vorn berechnet oder anders gesagt: ein Zug des Gegners fällt weg. Warum?

Ganz einfach: Beim 2. Durchgang sind die Ausgangswerte anders. Nachdem die Berechnung 1 Mal durchgeführt wurde (und alle Slots bis nach hinten gefüllt wurden), bleibt der aktuelle Wert ja irgendwo stehen. Und dieses irgendwo unterscheidet sich vom Startpunkt der Preview-Berechnung, so dass bei der nächsten fixen Berechnung etwas anderes rauskommen muss. edit: Außerdem könnte es auch problematisch sein, dass zwischendrin die Abfragepriorität der Teilnehmer irgendwie wechselt (ich fürchte, das hat sogar noch nen größeren Einfluss als die veränderte Startposition).

Eigentlich relativ logisch, ich bin nur noch nicht sicher, wie ich das löse.

@Ken
Das einzige, was hier zu beschränkt ist, ist die Rechenleistung meines Gehirns. ^^
Eigentlich ist der Code ja nicht besonders lang, nur etwas komplex/kompliziert.
Davon abgesehen benutze ich kein DynRPG mehr, sondern easyrpg (mit interierten DynPlugins). Sicher könnte man da auch irgendwas eigenes schreiben, aber ich sehe da nicht wirklich einen Grund dazu bzw. muss ich es ggf. Ja auch selbst noch modifizieren können.
Aber trotzdem danke, dass du noch versuchst mitzudenken. ;)

Cornix
22.04.2019, 23:44
Ein paar Fragen zum Verständnis:

Wie genau sieht deine Formel im Moment aus? Bitte einmal die genaue Rechnung mit allen beteiligten Variablen, deren Bedeutung und Beispielwerten beschreiben.
Hast du einmal alles von Hand nachgerechnet? Bekommst du ein anderes Ergebnis wenn du von Hand rechnest?
Verstehe ich es richtig, dass du die Werte zweimal ausrechnest; einmal für die Zugberechnung und einmal nur für das UI? Wenn ja: warum?
Hast du schon versucht dir einmal alle Werte nacheinander als Textausgabe anzeigen zu lassen? Schreib doch einmal was du dabei ausgegeben bekommst in Reihenfolge.

maniglo93
24.04.2019, 23:48
Ok, ich bin nun, glaube ich, durch dein Code durchgestiegen und... Naja er ist halt individuell :D meine codes sind vermutlich genauso kompliziert, deswegen nimm mein Rat mit etwas Salz :)

Du solltest den Code mehr nach Funktion trennen um einen besseren Überblick zu bekommen. Aktuell ist, so wie es für mich aussieht, jede Funktion in einander vermischt, wodurch es schwer ist Fehler / Bugs unabhängig zu betrachten.

Letztendlich brauchst du 3 Funktionen (mal Graphische Implementation ausgeschlossen) :
-Sortierung
-Berechnung Reihenfolge
-Berechnung Individueller Aktionsdauer

Eine Preview Rechnung brauchst du nicht zwangsläufig (kommt drauf an wie genau du diese später haben möchtest, führe ich unten weiter aus). Denn letztendlich ist die Preview-Rechnung = Aktuelle Rechnung. Dies zu splitten, wie du es gemacht hast, führt zu zwei Funktionen und somit zwei potentielle Fehlerquellen. Als erstes würde ich dir empfehlen, schon bei der Auswahl der Aktion die normal Rechnung auszuführen und diese anzeigen zu lassen. Vielleicht behebt sich da schon dein Fehler. Dann würde ich ein Check machen, wann die Reihenfolge neu berechnet werden soll. Also wenn die Reihen folge ist R - G - G - G - R, dann ist ja schon klar, dass der G 3x an der Reihe ist, weshalb dann neu die Reihenfolge berechnen?

Wenn dein Ziel ist, dass die Gegner auch schnellere bzw langsamere Aktionen durchführen kann, dann wirst es kompliziert für dich und du solltest jetzt schon dein System darum planen, denn aus dem Standpunkt des Designs bringt mir die Info, dass der Gegner 3x dran ist nur dann was, wenn er wirklich 3x dran ist und nicht nur 2x weil er bei der 2ten Aktion ein sehr langen Zauber macht. Dann muss das Preview schon die Auswirkung von Tempo Veränderung der zukünftigen Zauber einbrechnen und das wird mit den Events knifflig. Besonders wenn es Buffs gibt, die das Tempo erhöhen. Und lass uns gar nicht über Chancen reden (50% Chance den Gegner zu verlangsamen). Ein Preview ist nur dann sinnvoll, wenn es so genau wie möglich ist.

Deswegen mein Rat: Glieder deinen Code mehr um vielleicht überflüssige Funktionen herausziehen und Probleme genauer zu identifiziert.

Ich hoffe ich konnte dir helfen

Cheers
Maniglo

IndependentArt
26.04.2019, 20:21
Danke für die Antworten. Ich muss mir das nochmal in Ruhe durch den Kopf gehen lassen und melde mich dann die Tage wieder.

@Cornix: Nur zur Sicherheit: Ist meine letzte Mail angekommen? ^^ Ist jetzt erstmal kurz aufgeschoben, aber es erscheint mir am sinnvollsten, wenn man das mal per Bildschirmübertragung durchgeht, im Gegensatz dazu, dass man es immer versucht zu verschriftlichen.