IF-Forum

» IF-Forum - Autorencafé - Schreiben! - Eine Frage der Theorie
AntwortenNeues ThemaNeue Umfrage

Eine Frage der Theorie

Geschrieben um 00:08 am 02.05.2007 | Zitat | Editieren | Löschen
Basti
Mitglied
Pupil Gumby
Beiträge: 14

Hallo ich bin's wieder und diesmal sogar mit einem richtigen Problem. Bisher laufen die Arbeiten leider nicht so schnell wie ich es gerne hätte aber immerhin wurde (obs nun gut ist oder schlecht) die 256 K Marke gesprengt. Allerdings ist mir dabei etwas aufgefallen, was ziemlich katastrophale Auswirkung auf das Projekt haben könnte und wohl auch haben wird.

Ich hatte mir nach den Anregungen hier ein wenig im I-Net umgesehen und mir diese Conversation Extension von Mark Tilord heruntergeladen:

http://www.inform-fiction.org/I7Downloads/Extensions/Mark%20Tilford/Simple%20Chat

Schätze die Leute mit deutlich mehr Ahnung als ich erkennen sofort, dass diese Ext. nicht im Glulx Format kompilierbar ist.

Da ich allerdings später wohl einen ziemlich hohen Speicherbedarf haben werde (momentan habe ich gerade mal eine handvoll Räume und einige Menüs) bin ich quasi technisch aufgeschmissen.

Gibt es irgendeine einfache Möglichkeit den Code doch noch zu retten, oder muss ich nun endgültig Inform 6 Programmierung lernen? ;)

Edit: Genauer wäre die Frage wohl, was kann an dem oben aufgeführten Quellcode zum Kompilierungsfehler führen? Ich habe leider wenig Ahnung von Glulx. Was sind den die merklichsten Unterschiede zwischen Z-Code und Glulx Kompilierung?

Geschrieben um 19:29 am 03.05.2007 | Zitat | Editieren | Löschen
Basti
Mitglied
Pupil Gumby
Beiträge: 14

Ok, habe hier eine Lösung gefunden.

Das Problem schien zu sein, dass Glulx keine vollständige Wortreihe lesen kann sondern diese einzeln eingelesen werden müssen über den Befehl KeyboardPrimitive().

Man muss lediglich die Zeile read buffer parse; mit KeyboardPrimitive(buffer, parse); ersetzen und von da an sollte sich der Code in Glulx kompilieren lassen.

Außerdem kann man statdessen auch

*#ifdef TARGET_ZCODE;

read buffer parse;

ifnot; ! TARGET_GLULX;

KeyboardPrimitive(buffer, parse);

endif;*

eingeben, so dass Inform gegebenenfalls von Z-Code zu Glulx überspringt. Aber ob das was bringt weiß ich leider nicht.

Ich hoffe das hilft anderen Inform 7 Neueinsteigern.

Es gibt allerdings einen neuen Bug der wohl von der aktuellen 4S08 Version herrührt. Wenn ich versuche über run a conversation from Y von einem chat node X aus nach Y zu springen wird plötzlich eine neue Konversation gestartet, die parallel zu der vorherigen läuft (dies ist soweit ich mich zurückerinnern kann bei der älteren Version nicht der Fall gewesen. Ich müsste allerdings mal nachschauen). Soll: heißen nach einigen Malen hin und her gibt es einen overflow crash, da zu viele rulebooks simultan laufen. Sehr ärgerlich.

Geschrieben um 15:56 am 20.05.2007 | Zitat | Editieren | Löschen
Basti
Mitglied
Pupil Gumby
Beiträge: 14

Hallo noch mal,

Ganz dämliche Frage: Ich habe momentan Probleme Trefferpunkte für einzelne Körperteile in das System zu integrieren, weil es scheinbar keine doppelten Referenzen akzeptiert, also zB. Gesundheit of Torso of Person X. Für Gesundheit habe ich eine (spezifische) Kind of Value verwendet um es flexibler zu gestalten und um nicht für jeden einzelnen Charakter eine variable Nummer zu erstellen. Torso ist eine Kind of Körperteil welches wiederum ein thing und Szenerie ist (um später auch Ganzkörperschäden zu ermöglichen. Zumindest theoretisch).

Zwar funktioniert: say Gesundheit of your Torso,

aber wenn ich was anderes ähnlich wie das obere Beispiel versuche schafft es Inform nicht die Referenz richtig zu deuten und nimmt of X of Y als eine einzige zusammenhängende Beschreibung.

Weiß vielleicht jemand Rat?

Geschrieben um 13:39 am 22.05.2007 | Zitat | Editieren | Löschen
Clive
Mitglied
Bachelor Gumby
Beiträge: 60

Bin mir nicht sicher, was du jetzt wie implementiert hast, darum einfach mal ein funktionierendes Stück Quellcode (mit aktueller Version 4U65).


"Meeting Chuck Norris" by me

A body part is a kind of thing.

Health is a kind of value. The health is good and bad.

A torso is a kind of body part. Every torso has health.

The description of a torso is usually

"[if the health of the noun is bad]Blood drips from many wounds in[otherwise]Your eyes fall on the flawless skin of[end if]

[the noun]."

A torso is part of every person.

Home is a room. The description is "You are at home."

The Health of your torso is bad.

Chuck Norris is a man in Home. The description of Chuck Norris is "You think that you know him from... somewhere."

The Health of the torso which is part of Chuck Norris is good.

Ich glaube für dich ist vor allem die letzte Zeile interessant. Doppelt "of" geht nicht, aber "which is bla of bla" wird problemlos angenommen.

edit: Ich halte es für keine gute Idee, ein nicht-englischsprachiges Spiel mit Inform 7 zu schreiben. Aber das interessiert wohl eh keinen. Just my 2 cent.

Geschrieben um 15:18 am 22.05.2007 | Zitat | Editieren | Löschen
Crowley
Mitglied
Student Gumby
Beiträge: 24

Clive:

Ich halte es für keine gute Idee, ein nicht-englischsprachiges Spiel mit Inform 7 zu schreiben. Aber das interessiert wohl eh keinen.

Ich bin 100%ig Deiner Ansicht!

Geschrieben um 19:55 am 22.05.2007 | Zitat | Editieren | Löschen
Basti
Mitglied
Pupil Gumby
Beiträge: 14

@Clive

Nah, das which hatte ich schon ausprobiert und es funktioniert leider in meinen Fall nicht so wie es sollte. Ich geb mal die Codefragmente an:



Every Person has a Health. Health of a person is 100 HP.

Body Part is a kind of thing. Body Part is scenery.

[Wie bereits ewähnt eigentlich nur dazu da, um später etwas schreiben zu können wie: Change health of every body part which is part of a person to 10 TP. Falls so etwas überhaupt möglich ist. Ich habe meine Zweifel]

Every Body Part has a Health. Health of a body part is 100 TP.

Head is a kind of Body Part. A Head is part of every person.

A Torso is a kind of Body Part... usw.

[Jetzt der experimentelle Teil]

Adam is a person. Adam is in room.

Every turn:

Say Health of your Head;

change Health of your Head to health of your Head - 10 TP;

say Health of adam's Head.

[Soweit so gut alles wird problemlos angezeigt und verändert. Will ich aber so etwas wie:]

Every turn: if a person (called current) is in room two, change Health of Head which is part of current to 10 TP.

[...geht das in die Hose ob ich nun sage, dass es part of current ist oder nich]```

Was den Rest angeht.. Klar interessiere ich mich für deine Meinung aber noch mehr für das Warum.

Etwa wegen der englischen Platzhaltersätze, die hie und da auftauchen könnten?
Geschrieben um 00:45 am 23.05.2007 | Zitat | Editieren | Löschen
Clive
Mitglied
Bachelor Gumby
Beiträge: 60

Nach ewigem Rumprobieren hab ich endlich eine funktionstüchtige Version gefunden:


Every turn:

   repeat with target running through heads which are part of persons in room begin;

      if the target is part of the player begin;

      decrease health of target by 10 HP;

      say Health of target;

      say "   ";

      otherwise;

      decrease health of target by 20 HP;

      say Health of target;

      end if;

   end repeat.

Das ist nicht praktisch. Aber es klappt, und in der Dokumentation hab ich auch leider keine Hinweise gefunden, wie es anders zu lösen ist (ich hab aber auch mehr probiert als nachgelesen).

Dass aber solch einfache Sachen eines solchen Aufwands bedürfen, zeigt imho wieder einmal, dass Inform 7 entworfen wurde, um eine Geschichte in natürlicher Sprache erzählen und in ein Spiel umwandeln zu können.

Das geht schon nicht mehr, wenn man ein deutsches Spiel mit Inform 7 schreiben möchte. Dazu kommt noch die deutsche Grammatik.

Wer gern eine komplexe Spielwelt, gar ein Kampfsystem haben will, dem rate ich dringend zu Inform 6. Einige Gründe:

  • Fast alle deine bisherigen Probleme in diesem Thread wären mit Inform 6 im Vergleich leicht zu lösen

  • Dabei wäre der Quellcode sehr viel übersichtlicher

  • Du hast fertig übersetzte, oft verbesserte Libraries

  • Ganz zu schweigen von den vielen Tutorials

  • Martin z.B. würde dir für die meisten Fragen gleich die richtige Lösung servieren können ;-)

Ich will dich nicht entmutigen, aber ich kann beim besten Willen keinen guten Grund erkennen, der bei deinem Vorhaben für Inform 7 spricht.

Geschrieben um 14:29 am 23.05.2007 | Zitat | Editieren | Löschen
Clive
Mitglied
Bachelor Gumby
Beiträge: 60

So, ich konnte nicht widerstehen und hab ein kleines Inform 7-Kampfsystem gebastelt, in dem Personen freundlich oder feindlich gesinnt sind. Feindliche Personen im selben Raum greifen den Spieler jede Runde an, freundliche werden feindlich, wenn der Spieler sie angreift.

Außerdem wird automatisch der Torso angegriffen, wenn man eine Person angreift, es sei denn, man greift ein bestimmtes Körperteil an. Ich finde es unsinnig, zusätzlich health für die ganze Person zu haben, denn wenn z.B. der Kopf zu Brei geschlagen wurde, ist die Person schließlich auch tot.

Bisher ist nur der Torso als Körperteil implementiert, aber in dieser Form ist das leicht zu erweitern.


"Kampfsystem" by Clive

Health is a kind of value. 100 HP specifies Health.

A body part is a kind of thing.

Every body part has health. Health of a body part is usually 100 HP.

A person is either friendly or hostile. The player is friendly.

A torso is a kind of body part.

A torso is a part of every person.

Adam is a friendly person. Adam is in room.

Every turn when a hostile person is in the location:

   repeat with enemy running through hostile persons in the location begin;

      try the enemy fighting the player;

   end repeat.

Instead of attacking something:

   if the noun is the player begin;

      say "That would be ridiculous.";

   otherwise;

   try fighting the noun;

   if the noun is a friendly person, now the noun is hostile;

   if the noun is a body part begin;

      repeat with victim running through friendly persons in the location begin;

         if the noun is part of the victim, now the victim is hostile;

      end repeat;

   end if;

   end if.

Fighting is an action applying to one touchable thing.

Carry Out fighting:

   if the noun is a body part, decrease health of the noun by 10 HP;

   if the noun is a person begin;

      repeat with target running through torsos begin;

         if the target is part of the noun, decrease health of the target by 10 HP;

      end repeat;

   end if.

Report fighting:

   if the noun is a body part, say "You attack [the noun]. The health of [the noun] is now [health of the noun].";

   if the noun is a person begin;

      repeat with target running through torsos begin;

         if the target is part of the noun, say "You attack [the target]. The health of [the target] is now [health of the target].";

      end repeat;

   end if.

Check someone fighting:

   if the noun is the player begin;

      if the person asked is friendly, stop the action;

   end if.

Carry Out someone fighting:

      if the noun is a body part, decrease health of the noun by 10 HP;

   if the noun is a person begin;

      repeat with target running through torsos begin;

         if the target is part of the noun, decrease health of the target by 10 HP;

      end repeat;

   end if.

Report someone fighting:

   if the noun is the player begin;

      say "[The person asked] attacks you and hits your torso. The health of your torso is now [health of your torso].";

   otherwise;

      if the noun is a person begin;

      repeat with target running through torsos begin;

         if the target is part of the noun, say "[The person asked] attacks [the target]. The health of [the target] is now [health of the target].";

      end repeat;

      end if;

   end if.

Was mich stört ist nur der extensive Gebrauch von Schleifen, aber wie gesagt... hab noch nicht herausgefunden, wie es anders zu lösen ist.

Geschrieben um 00:09 am 24.05.2007 | Zitat | Editieren | Löschen
Basti
Mitglied
Pupil Gumby
Beiträge: 14

Ok, es ist ziemlich spät und ich bin müde aber trotzdem:

Ich könnte mir noch vorstellen, dass man mit relate das ganze ein wenig besser aufteilen könnte in verschiedenen Angriffsarten (Nah- Fernkampf, Einsatz von Hitze oder Elektrizität usw.) aber das würde auch in deinem Beispiel wohl problemlos funktionieren (etwas wenn man vermerkt welche Waffe gerade der Angreifer benutzt).

Nur kurz zu den Personen TP, die sind für einen leichteren Schwierigkeitsgrad gedacht. Ist dieser ausgewählt sollen die aufgeteilte Trefferzonen (zumindest für den Spielercharakter) entfallen und mit einem einzigen Gesundheitsbalken ersetzt werden, welcher mehr TP fasst als Torso und Kopf es einzeln tun würden (deren Verlust im normalen oder schweren Schwierigkeitsgrad natürlich das Leben kostet) und sämtliche Handicaps für den Spieler, wie sie etwa bei einem schwer verletztes Bein entstehen könnten, werden vollkommen entfernt.

Der Spieler überlebt also deutlich länger und ist nicht mehr anfällig gegenüber gezielten Angriffe seiner Gegner.

Aber jetzt erstmal danke. Ich weiß die Mühe wirklich zu würdigen.

Jetzt stehen erst einmal Präsenzklausuren an und ich bin mit dem Üben ein wenig im Verzug. Ich werde versuchen mich am Wochenende ausgiebiger damit zu beschäftigen und schauen was sich ergibt.

Geschrieben um 00:28 am 24.05.2007 | Zitat | Editieren | Löschen
Clive
Mitglied
Bachelor Gumby
Beiträge: 60

Pass auf, dass du nicht mehr Ambitionen entwickelst als deine Motivation ertragen kann. Ich finde unterschiedliche Schwierigkeitsgrade in Textadventures eher überflüssig. Und selbst wenn man es dem Spieler leichter machen will, dann würde ich einfach den Schaden reduzieren, den Monster anrichten. Oder die HP für die Trefferpunkte des Spielers erhöhen. Das hat einen ähnlichen Effekt und kostet kaum zusätzlichen Aufwand. Ist damit auch weniger buganfällig.

Verschiedene Waffen, die verschiedenen Schaden anrichten, wäre ja kein Problem. Aber ich kann nur wiederholen: Diese ganzen eher technischen Sachen sind in Inform 6 sehr viel leichter zu implementieren, wie ich finde. Wenn du also eher ein System bauen als eine Geschichte erzählen willst, überleg dir lieber nochmal, ob du nicht doch umsteigst.

Ansonsten viel Glück mit deinen Klausuren.

Geschrieben um 05:13 am 31.07.2007 | Zitat | Editieren | Löschen
Basti
Mitglied
Pupil Gumby
Beiträge: 14

Yay, es lebt doch noch!

Dann kann ich ja jetzt weitermachen. Erstmal danke @Clive das Glück konnte ich gebrauchen. :D

Leider ist, was das Programmieren betrifft, erschreckend wenig passiert vor allem, da ich momentan umsiedle. Das Problem mit dem Körperteil Referenzen ließ sich ziemlich leicht lösen.

Man braucht lediglich eine zusätzlich Zeile wie etwa:

If Torso (called target) is part of Person X, ... usw.

Daraufhin kann man weiterhin mit 'target' arbeiten. Ob Inform 7 dabei auch durch eine Liste durchläuft weiß ich net aber es ist jedenfalls angenehmer zu benutzen als etwa durch repeat.

Bevor ich aber mit weiteren Errungenschaften prahle nochmals ein, zwei Fragen.

Gibt es eigentlich so etwas wie 'Glulx Farben für Dummies'?

Ein wenig peinlich aber ich habe immer noch nicht verstanden wie dies in Inform 7 (oder 6) funktionieren soll. Das mit den Hexadezimalzahlen ist ja noch im Ansatz nachvollziehbar, aber was nötig ist um Zahl in Farbe umzuwandeln bleibt mir schleierhaft.

Und die zweite: Gäbe es irgendeine Möglichkeit den Speicherbefehl zu modifizieren ohne gleich in der Library rumzupfuschen? Der Gedanke macht mich ein wenig nervös. Wäre also gut, falls es ein Hintertür gibt. Ob in Inform 7 oder 6.

(EDIT: Hat sich glaube ich erledigt. Zumindest falls check saving the game wirklich das tut was ich denke)

Da wäre auch noch das Problem, dass ich bisher noch keine Möglichkeit gefunden habe den Spieler zu verzögern.

Ihn sozusagen für einige Runden 'aussetzten' zu lassen.

Gibt es dafür irgendwelche bekannten Mittel und Wege?

Ich werde mal die grundlegenden Befehlsroutinen runterarbeiten, die ich zustande bekommen habe.

Grundlegend, weil ich einige Sachen absichtlich rauslassen werde, die, mehr oder weniger, spezifisch für das Spiel gedacht sind (etwa das Berechnen der aktuellen Fertigkeiten durch Attribute) und demzufolge ihren allgemeinen Nutzwert verlieren.

Fangen wir am besten mit der Handhabung von Objekten, die vom Spieler kontinuierlich gehalten werden müssen um wirklich gebräuchlich zu sein (wie etwa ein Werkzeug und in diesem Fall natürlich auch Waffen). Ich unterscheide zwischen 3 Objektgrößen, was in meinem Fall vor allem mit dem Inventarmanagement zu tun hat, aber ebenfalls für andere Zwecke verwendet oder ignoriert werden kann. So besteht hier der Unterschied lediglich darin, dass ein großer Gebrauchsgegenstand stets abgelegt wird, wenn man versucht einen anderen zu benutzen oder versucht einen weiteren großen Gegenstand aufzunehmen.

Hier also das 'neutrale' Codesegment:


Health is a kind of value. 10 TP specifies Health.

Body Part is a kind of thing.  Body part is scenery.

Every Body Part has a Health.

Every Body Part has a Health called MaxHealth.

A Head is a kind of body part.

Health of Head is 50 TP. MaxHealth of Head is 50 TP.

Head is part of every person.

A Torso is a kind of body part.

Health of Torso is 100 TP. MaxHealth of Torso is 100 TP.

Torso is part of every person.

Size is a kind of value. The Sizes are small, midsize, and big. A thing has a Size. A thing is usually small.

A Tool is a kind of thing. A Tool can be either used or unused.

Using is an action applying to one visible thing.

Understand "use [something]" as using.

Instead of using a Tool (called current):

If player carries current

 begin;

 If current is unused

   begin;

   repeat with item running through Tool that is carried by the 

   player begin;

    If item is big

      begin;

      If item is not current, try silently dropping item;

      end if;

    If current is not big

     begin;

     now your Fist is used;

     If item is not current, now item is unused;

     otherwise;

     Now your Fist is unused;

     now item is unused;

     end if;

  end repeat;

 now current is used;

 otherwise;

 say conditional paragraph break;

 say "Das hältst du bereits einsatzbereit.";

 end if;

end if.

[Dasselbe nochmal für die NPCs]

Instead of someone (called actor) using a Tool(called current):

If actor carries current

 begin;

 If current is used, stop the action;

 repeat with item running through Tool that is carried by actor begin;

  If item is big

   begin;

   if item is not current, silently try actor dropping item;

   end if;

  Now item is unused;

  end repeat;

 now current is used;

 if current is big

 begin;

 if fist (called temp) is part of actor, now temp is unused;

 otherwise;

 Now temp is used;

end if;

end if.

[Und das erfolgreiche demarkieren von Objekten falls sie entweder abgelegt oder durch einen anderen ersetzt werden sollen]

Before dropping Tool (called current):

If current is carried by player

 begin;

  If current is used

  begin;

  Now current is unused;

   now your Fist is used;

  end if;

end if.

Before someone (called actor) dropping Tool (called current):

 If current is carried by actor

 begin;

  If current is used

  begin;

  Now current is unused;

  If Fist (called temp) is part of actor, now temp is used;

end if;

end if.

[Jetzt noch für den Sonderfall, dass ein Spieler versucht einen großen Gegenstand zu nehmen während ein anderer angelegt ist]

After taking something (called current) that is big: try silently using current.

[Mögliche Buggefahr wäre hier, dass man versucht ein großes thing anstelle eines Tools zu nehmen.]

After someone (called actor) taking something (called current) that is big: silently try actor using current.

[Kommen wir zum saftigen Kern. Dem Kampf. Wie immer die Deklarationen zuerst.]

A Weapon is a kind of Tool.  A Firearm is a kind of weapon. A Meele is a kind of weapon.

[Schusswaffen Alg.]

Every Firearm has a number called Magazin. Every Firearm has a number called Bullets.

Sparebullet is a kind of thing. Every Sparebullet has a number called Bullets. Every Sparebullet has a text called Declaration.

Rifle is a Firearm. Rifle is big.

Magazin of Rifle is 30. Bullets of Rifle is 30.

Instead of examining Rifle: say "Dein Gewehr, dein Stolz. Gut gewartet[if Bullets of Rifle > 0] und [end if][if Bullets of Rifle < 10] immerhin[end if][if Bullets of Rifle < 30] mit [Bullets of Rifle] Kugeln[end if][if Bullets of Rifle is 30] voll geladen[end if][if Bullets of Rifle is 0] aber ohne Kugeln[end if].".

Riflemagazin is a kind of Sparebullet. Bullets of Riflemagazin is usually 30. Declaration of Riflemagazin is usually "Rifle".

Pistol is a Firearm. Pistol is small.

Magazin of Pistol is 10. Bullets of Pistol is 10.

Pistolmagazin is a kind of Sparebullet. Bullets of Pistolmagazin is usually 10. Declaration of Pistolmagazin is usually "Pistol".

Unloaded is a Sparebullet.

[Was der 'Deklaration's Text soll ist ein ziemlich leidiges Thema, auf dass ich beim Nachlade Befehl zurückkommen werde.]

[Nahkampf Alg.]

Fist is a kind of Meele. Fist is part of every person. Fist is used.

Knife is a Meele.

Instead of examining Knife: do nothing.

Axe is a Meele. Axe is midsize.

Instead of examining Axe: say "Scharf und gefährlich".

Drill Hammer is a Meele. Drill Hammer is big.

Instead of examining Drill Hammer: say "Kommt durch so ziemlich alles durch. Ob Stein, Holz oder Fleisch.".

[Parameter]

 

Tmp is a number that varies.

Tmp_Goal is a Body Part that varies.

Tmp_Attack is a number that varies.

Tmp_Damage is a Health that varies.

Tmp_Magazin is a Sparebullet that varies. Tmp_Magazin is unloaded.

A person can be neutral or hostile.

A person can be aware or unaware.

Every person has a number called Meele_S.

Every person has a number called Range_S.

[Waffentabellen]

Table 0 - Waffentabelle

Name          MaxDamage                Bonus

Knife                40 TP                         10 TP       

Axe                  50 TP                        20 TP

Drill Hammer    60 TP                        15 TP

Rifle                  30 TP                        20 TP

Pistol                15 TP                        20 TP

Table 1 - Schusswaffen

Name          Magazin

Rifle             "Rifle"

Pistol          "Pistol"

[Angriffsbefehl]

Instead of attacking someone (called defender):

say line break;

 If defender is player

  begin;

  say "Das wäre der Situation nicht ganz förderlich.";

  stop the action;

  end if;

now defender is hostile;

 If player has a weapon (called current) that is used

   begin;

   If current is Meele, change Tmp_Attack to Meele_S of player;

   If current is Firearm

     begin;

     If Bullets of current is 0, say "Die Waffe lässt ein trockenes 

     Klicken vernehmen." instead;

     Decrease Bullets of current by 1;

     change Tmp_Attack to Range_S of player;

     end if;

 otherwise;

     try punching defender instead;

 end if;

If torso (called target) is part of defender

  begin;

  If a random chance of Tmp_Attack in 100 succeeds

    begin;

    choose row with name of current in Table 0;

    change Tmp_Damage to a random Health from 1 TP to   

    MaxDamage entry;

    increase Tmp_Damage by Bonus entry;

    decrease Health of target by Tmp_Damage;

  otherwise;

  say "Du hast [defender] verfehlt." instead;

  end if;

 say "Du triffst [defender] am Torso für [Tmp_Damage] ([Health of target]/[MaxHealth of target])  ";

end if.

Instead of someone (called attacker) attacking someone (called defender):

say line break;

 If attacker has a weapon (called current) that is used

   begin;

   If current is Meele, change Tmp_Attack to Meele_S of attacker;

   If current is Firearm

     begin;

     change Tmp_Attack to Range_S of attacker;

     If Bullets of current is 0, do nothing instead;

     decrease Bullets of current by 1;

   end if;

 otherwise;

 try attacker punching defender instead;

 end if;

If torso (called target) is part of defender

 begin;

  If a random chance of Tmp_Attack in 100 succeeds

   begin;

   choose row with name of current in Table 0;

   change Tmp_Damage to a random Health from 1 TP to

   MaxDamage entry;

   increase Tmp_Damage by Bonus entry;

   decrease Health of target by Tmp_Damage;

  otherwise;

    If defender is player, say "[attacker] verfehlt dich." instead;

    If defender is not player, say "[attacker] verfehlt [defender]." instead;

  end if;

If defender is player, say "[attacker] trifft dich mit [current] am Torso um [Tmp_Damage].   ([Health of target]/[MaxHealth of target])";

If defender is not player, say "[attacker] trifft [defender] mit [current] am Torso um [Tmp_Damage]. ([Health of target]/[MaxHealth of target])";

end if.

[Nun zum guten alten Faustgebrauch, der im Gegensatz zum rudimentären Angreifen ein zufälliges Körperteil als Ziel wählt. Aus reinen Demonstrationszwecken]

Punching is an action applying to one visible thing.

Carry out punching something (called defender):

If Fist (called temp) is part of player

  begin;

  if temp is unused, say "Dafür bräuchtest du eine freie Hand." instead;

end if;

change Tmp_Attack to Meele_S of player;

change Tmp_Damage to 1 TP;                   [Platzhaler für MaxD]

If a random chance of Tmp_Attack in 100 succeeds

  begin;

  change Tmp to a random number from 1 to 100;

  If Tmp > 85

    begin;

    if Head (called current) is part of defender,   change Tmp_Goal to current;

  end if;

  If Tmp < 86

    begin;

    if Torso (called current) is part of defender, change Tmp_Goal to current;

  end if;

change Tmp_Damage to a random Health from 1 TP to Tmp_Damage;

decrease Health of Tmp_Goal by Tmp_Damage;

say "Du gräbst deine Faust in [if Tmp_Goal is head]das Gesicht[otherwise]die Brust[end if] von [defender] und erzielst dabei [Tmp_Damage] Schaden.  ([Health of Tmp_Goal]/[MaxHealth of Tmp_Goal])";

otherwise;

say "Dein heroischer Schlag verfehlt.";

end if.

Carry out someone (called attacker) punching something (called defender):

change Tmp_Attack to Meele_S of attacker;

change Tmp_Damage to 1 TP;             [Wieder Platzhalter]

If a random chance of Tmp_Attack in 100 succeeds

  begin;

  change Tmp to a random number from 1 to 100;

  If Tmp > 85

    begin; if Head (called current) is part of defender, change Tmp_Goal to current;

  end if;

  If Tmp < 86

    begin;

    if Torso (called current) is part of defender, change Tmp_Goal to current;

  end if;

  change Tmp_Damage to a random Health from 1 TP to Tmp_Damage;

 decrease Health of Tmp_Goal by Tmp_Damage;

 If defender is player, say "[attacker] versetzt dir einen Hieb am [if current is Torso]Torso[otherwise]Kopf[end if] um [Tmp_Damage].  ([Health of current/[MaxHealth of current])";

If defender is not player, say "[attacker] schlägt [defender] am [if current is torso]Torso[otherwise]Kopf[end if] um [Tmp_Damage] .  ([Health of current]/[MaxHealth of current]).";

otherwise;

 If defender is player, say "[attacker]s Faust verfehlt dich." instead;

 If defender is not player, say "[attacker]s Hieb verfehlt [defender]." instead;

end if.

[Wie man an den beiden oberen Befehlen sieht ist es vollkommen gleichgültig ob man mit current oder Tmp_Goal arbeitet solange nur das Körperteil markiert wird. Aber um mögliche Bugs zu vermeiden habe ich Tmp_Goal erst einmal drin behalten.]

[Nachladen]

[Oh mann, das Nachladen war ein echter Albtraum. Zwei Stunden schwankte ich wild zwischen wildem Ausprobieren und Aufstellen von Theorien. Dabei war der eigentliche Hergang sehr einfach. Wie man sieht arbeite ich rein mit Zahlen. Nicht so tolle Sachen wie Magazine, die man tatsächlich in die Waffe reinstecken kann oder so was. Nein, reines subtrahieren und addieren. Aber wenn man versucht mehrere Duplikate von einem Munitionstyp zu erstellen öffnet das die Tür zu einer neuen Welt der algorithmischen Agonie. Zu meinem Glück (und zum großen Pech für Leute, die etwas daraus lernen wollen), habe ich das meiste dieser Geschehnisse nach einem Monat Kur wieder verdrängt.

Etwa als das Programm mir weismachen wollte, dass Pistolenkugeln auch universell einsetzbar sind.

Naja, lange Rede kurzer Sinn hier das Resultat dieses Höllentrips] 

Reloading automatic is an action applying to nothing.

Reloading is an action applying to one visible thing.

Understand "reload [something]" or "load [something]" or "lade nach [something]" or "lade [something] nach" or "lade [something]" as Reloading.

Understand "reload" or or "lade nach" or "nachladen" or "lade" as Reloading automatic.

Carry out reloading automatic:

if player carries a Firearm (called current) that is used, try reloading current instead;

say "Was genau soll nachgeladen werden?".

Carry out someone(called reloader) reloading automatic: if reloader carries a Firearm (called current) that is used, try reloader reloading current instead.

Carry out reloading something (called current):

If current is not Firearm, say "Patronen sollten stets nur in Geräte, welche diese auch abfeuern können." instead;

If Magazin of current is Bullets of current, say "[current] ist bereits vollständig geladen." instead;

Choose row with name of current in Table 1;

repeat with item running through Sparebullet carried by the player   

  begin;

   If Declaration of item is Magazin Entry

     begin;

     If Tmp_Magazin is Unloaded, change Tmp_Magazin to item;

     If Bullets of item < Bullets of Tmp_Magazin, change Tmp_Magazin to item;

  end if;

end repeat;

If Declaration of Tmp_Magazin is Magazin Entry

  begin;

   change tmp to Magazin of current - Bullets of current;

   if tmp is Magazin of current

     begin;

     if Bullets of Tmp_Magazin is Magazin of current

       begin;

       change Bullets of current to Bullets of current + Bullets of Tmp_Magazin;

       say "Du lässt das alte Magazin geräuschvoll zu Boden fallen und rammst ein neues in [current].";

       remove Tmp_Magazin from play;

     end if;

   end if;

 if tmp > Bullets of Tmp_Magazin

   begin;

   change Bullets of current to Bullets of current + Bullets of Tmp_Magazin;

   say "Du lädst alle restlichen Kugeln des Magazins in [current].";

   remove Tmp_Magazin from play;

 end if;

 if tmp < Bullets of Tmp_Magazin

   begin;

   Change Bullets of current to Bullets of current + tmp;

   Change Bullets of Tmp_Magazin to Bullets of Tmp_Magazin - tmp;

   say "Nachgeladen. Es bleiben sogar [Bullets of Tmp_Magazin] Ersatzpatronen übrig.";

 end if;

otherwise;

say "Dafür werden Kugeln benötigt.";

end if;

change Tmp_Magazin to unloaded.

 

Carry out someone (called reloader) reloading something (called current):

if Magazin of current is Bullets of current, stop the action;

Choose row with name of current in Table 1;

repeat with item running through Sparebullet carried by the reloader

  begin;

  if Declaration of item is Magazin Entry

    begin;

    if Tmp_Magazin is Unloaded, change Tmp_Magazin to item;

    if Bullets of item < Bullets of Tmp_Magazin, change Tmp_Magazin to item;

  end if;

end repeat;

If Tmp_Magazin is Unloaded

  begin;

  say "[reloader] sucht verzweifelt nach Munition findet allerdings nichts.";

  now reloader is aware; 

  stop the action;

end if;

If Declaration of Tmp_Magazin is Magazin Entry

  begin;

  change tmp to Magazin of current - Bullets of current;

  If tmp is Magazin of current

    begin;

    If Bullets of Tmp_Magazin is Magazin of current

      begin;

      change Bullets of current to Bullets of current + Bullets of Tmp_Magazin;

      say "[reloader] zaubert ein neues Magazin hervor und steckt es hastig in seine Waffe.";

      remove Tmp_Magazin from play;

    end if;

  end if;

  If tmp > Bullets of Tmp_Magazin

    begin;

    change Bullets of current to Bullets of current + Bullets of Tmp_Magazin;

    say "Mühselig nimmt [reloader] einige Patronen und steckt sie in [current].";

    remove Tmp_Magazin from play;

  end if;

  If tmp < Bullets of Tmp_Magazin

    begin;

    Change Bullets of current to Bullets of current + tmp;

    Change Bullets of Tmp_Magazin to Bullets of Tmp_Magazin - tmp;

    say "[reloader] füllt seine Bleischleuder mit neuer Nahrung. Er scheint sogar [Bullets of Tmp_Magazin] Patrone[if Bullets of Tmp_Magazin > 1]n[end if] übrig zu behalten.";

  end if;

end if;

change Tmp_Magazin to Unloaded.

[Und damit sind die Grundlagen eigentlich komplett. Zeit es auszuprobieren]

Rumble Room is a room.

Meele_S of yourself is 45.

Range_S of yourself is 60.

Enemy is a kind of person.

Adam is a person that varies.

Sniper is a enemy.

Understand "Adam" as Sniper.

The printed name of Sniper is "Adam".

Meele_S of Sniper is 30.

Range_S of Sniper is 90.

Butcher is a enemy.

Understand "Adam" as Butcher.

The printed name of Butcher is "Adam".

Meele_S of Butcher is 85.

Range_S of Butcher is 10.

When play begins:

change adam to a random enemy;

now adam is neutral;

move Knife to Rumble Room;

move Axe to Rumble Room;

move Drill Hammer to Rumble Room;

move Rifle to Rumble Room;

move Pistol to Rumble Room.

Three Gewehrmagazins are in Rumble Room.

10 Pistolmagazins are in Rumble Room.

Every turn:

 If adam is hostile

   begin;

    If adam is butcher

      begin;

      If adam has a weapon that is used, try adam attacking

      player instead;

      let Tmp_Weapon be a random meele not carried by the player;

      try adam taking Tmp_Weapon;

      if Tmp_Weapon is not big, try adam using Tmp_Weapon;

    otherwise;

      If adam has a Firearm (called current) that is used

        begin;

        If Bullets of current is 0, try adam reloading automatic;

        If adam is aware

          begin;

          If current is pistol

            begin;

            If pistolmagazin (called current) is in Rumble Room, try adam taking current;

          end if;

          If current is rifle

            begin;

            If riflemagazin (called current) is in Rumble Room, try adam taking current;

          end if;

          now adam is unaware;

        otherwise;

          try adam attacking player;

        end if;

      otherwise;

       let Tmp_Weapon be a random Firearm not carried by the player;

       try adam taking Tmp_Weapon;

       if Tmp_Weapon is not big, try adam using Tmp_Weapon;

      end if;

    end if;

  end if.

To say Ammo:

 If player carries a firearm (called current) that is used,

 say "[Bullets of current]/[Magazin of current]".

Every turn:

 If player carries a firearm (called current) that is used, change right hand status line to "[Ammo]";

say paragraph break;

repeat with item running through weapons carried by the player

  begin;

  say item;

  If item is used, say "    (Used)";

  say line break;

end repeat;

say your Fist;

If your Fist is used, say "    (Used)";

say paragraph break;

repeat with item running through weapons carried by adam

  begin;

  say item;

  If item is used, say "    (Used)";

  say line break;

end repeat;

If Fist (called temp) is part of adam, say temp;

If temp is used, say "    (Used)";

say line break.

Könnte sein, dass noch der ein oder andere kleine Fehler auftaucht, da das obige noch ungetestet, da zu einigen Teilen komplett neu geschrieben, ist. Aber im Großen und Ganzen sollte es funktionieren.

Was ich herausgelassen habe sind zum einen die Möglichkeit zum gezielten Schießen (/Schlagen), da dies zum Teil über die Simple Chat Extention abläuft und ich versuchen will solche erstmal heraus zu lassen. Sollte aber das Interesse bestehen kann ich später noch hinzueditieren. Grob gesagt verläuft es so: Der Spieler kann ein bestimmtes Körperteil anvisieren, muss dafür allerdings je nach Wahl einen bestimmten Malus hinnehmen. Jedoch schießt er nicht sofort sondern kann, solange er nicht das Ziel aus den Augen verliert oder seine Waffe ablegt, seinen Gegner weiterhin im Visier behalten und somit die Trefferwahrscheinlichkeit über mehrere Runden hinweg steigern. Die Schnelligkeit dieser Steigerung ist von der Konzentration (quasi das Äquivalent zu Intelligenz in anderen Rollenspielen) abhängig. Der Angriff erfolgt dann durch den normalen Attacking Befehl.

Dann wäre da noch ein Befehl, der die Gesundheit des Spielers in möglichst wagen Worten wiedergibt. Eigentlich nur lästiges copy & paste, man arbeitet sich durch sämtliche Körperteile und fertig.

Also hier nur Platzverschwendung.

Und zu guter Letzt gibt es noch die Möglichkeit zu treten, aber das ist im Moment nichts anderes als eine anders klingende Möglichkeit Leute und Dinge zu schlagen. Wenn erstmal so etwas wie ein Raumverhältnisse existiert soll es den Spieler ermögliche Gegner von ihm wegzustoßen oder ihnen Hindernisse in den Weg zu befördern unter anderem.

Was als nächstes drankommt sind Dimensionen und Raumkoordinaten damit ich endlich ein vernünftiges Arbeitsumfeld bekomme und zeitabhängige Handlungen. Zweites ist bei NPCs kein Problem, weil die keine Befehle eintippen können.

Beim Spieler wird es allerdings schwieriger...

Gah! Augen brennen.

Nacht (oder Morgen)

EDIT: Ok, bin noch mal drübergegangen und habe die gröbsten Fehler bereinigt. Sollte jetzt alles soweit fehlerfrei laufen bis auf die Tabellen.

Geschrieben um 17:32 am 14.08.2007 | Zitat | Editieren | Löschen
Clive
Mitglied
Bachelor Gumby
Beiträge: 60

Basti:

Gibt es eigentlich so etwas wie 'Glulx Farben für Dummies'?

Ein wenig peinlich aber ich habe immer noch nicht verstanden wie dies in Inform 7 (oder 6) funktionieren soll. Das mit den Hexadezimalzahlen ist ja noch im Ansatz nachvollziehbar, aber was nötig ist um Zahl in Farbe umzuwandeln bleibt mir schleierhaft.

In Glulx werden solche sachen durch glk-Funktionen erledigt. Eigentlich musst du nur die entsprechende glk_function raussuchen und den entsprechenden Farbencode als aktuellen Parameter übergeben. Es gibt aber schon Bibliotheken wie die unglklib.h, da kannst du auch mit den englischen Namen für gewisse Standardfarben arbeiten (wenn ich das richtig erinnere). Das gilt jetzt aber alles für Inform 6, ich hab noch nicht versucht, mit Inform 7 Glulx-mäßig was zu machen. Werde ich wohl auch erstmal nicht, dafür ist mir das einfach zu unpraktisch.

Basti:

Da wäre auch noch das Problem, dass ich bisher noch keine Möglichkeit gefunden habe den Spieler zu verzögern.

Ihn sozusagen für einige Runden 'aussetzten' zu lassen.

Gibt es dafür irgendwelche bekannten Mittel und Wege?

Ich würde dafür einfach eine Routine schreiben, wo drinsteht, welche anderen Routinen alle ausgeführt werden sollen, während der Spieler nicht eingreifen kann. Bei Bedarf rufst du sie dann auf und der Spieler kann erst hinterher wieder was machen.

Falls du willst, dass der Spieler aussetzt, weil er ohnmächtig ist oder so, kannst du das dann auch an das Gebiet anpassen, in dem er ohnmächtig geworden ist.

Geschrieben um 02:02 am 24.08.2007 | Zitat | Editieren | Löschen
Basti
Mitglied
Pupil Gumby
Beiträge: 14

Hi Clive,

das mit den glulx Funktionen funktioniert glaub ich nicht wie in Inform 6. Zumindest vermute ich es, weil es auch in der Anleitung nie Erwähnung findet. Mir bleibt wohl doch nur übrig mich ein bisschen mehr mit der Include Funktion auseinander zusetzten (Stöhn). Allerdings ist mit der neuen Inform 7 Version (und dem dazugehörigen Upgrade für Glulx Text Effects) die Möglichkeit gekommen einen individuellen Schreibstil auch eine bestimmte glulx Farbe zu verpassen. Leider kann man bisher nur maximal zwei davon erstellen also bleibt mir nur die Auswahl zwischen fett gedruckten Buchstaben oder roten. Muss ich wohl ein wenig improvisieren.

Beim zweiten Punkt bin ich nicht ganz sicher was du meinst fürchte ich.

Was meinst du zum Beispiel mit 'wenn der Spieler nicht eingreifen kann'? Etwa beim Ende einer Runde (nachdem er einen Befehl eingegeben hat)? Momentan verstehe ich den Ansatz so, dass der Spieler solange nicht handeln kann sofern eine bestimmte Routine durch seine Handlung aktiviert wird. Ich hatte schon vorher so etwas ausprobiert indem ich die Spielfigur quasi 'zwingen' wollte zu warten bis ein Testzähler abgelaufen ist. Aber das Programm lies mich trotzdem jede Runde neue Befehle eingeben und war demzufolge ziemlich sinnfrei.

Geschrieben um 15:16 am 24.08.2007 | Zitat | Editieren | Löschen
Clive
Mitglied
Bachelor Gumby
Beiträge: 60

Damit meine ich einfach nur, dass in der Routine drin steht, was alles in der Zwischenzeit passiert. Da ein Textadventure nicht in Echtzeit abläuft, kannst du ja frei entscheiden, was alles in einem Zug passieren soll.

Nachdem die Routine abgearbeitet ist - im nächsten Zug also - ist der Spieler wieder dran. Ich sehe nicht, wo das Problem ist? Falls der Spieler denken soll, dass mehrere Züge verstrichen sind, und falls die Anzahl der Züge angezeigt wird, setzt du sie einfach manuell hoch. Tatsächlich aber passiert das alles in demselben Zug, in dem der Spieler zuletzt eine Aktion machen durfte, daher kann er zwischendurch natürlich auch nicht eingreifen.

Um dem Spieler zusätzlich das Gefühl von verstreichender Zeit zu geben, kannst du es auch so einrichten, dass er einfach zwischendurch eine Taste drücken muss, bis es weiter geht.

Geschrieben um 17:10 am 13.01.2008 | Zitat | Editieren | Löschen
Basti
Mitglied
Pupil Gumby
Beiträge: 14

Hi zusammen!

Erst einmal frohes Neues und ich hoffe ihr habt alle die Weihnachtszeit gut überstanden.

Ich hab mich in den letzten Monaten mit meinem eigenen kleinen Frankensteins Monster beschäftigt: dem Erstellen 2-dimensionaler Karten für Räume in Inform 7, auf denen sich Figuren bewegen können (was ähnlich aussieht wie bei den berühmt berüchtigten Nethack Spielen). Ich glaube, ich bin jetzt endlich in der Lage zumindest einen ersten Prototypen anbieten zu können (momentan leider nur in Glulx Format). Der Quellcode ist aber viel zu lang, als dass ich ihn so einfach hier hereinkopieren könnte wie ichs vorher gemacht habe. Falls ihr interessiert seid und einen Blick drauf werfen wollt, schick mir einfach eine Mail unter 'Basti_rahn@hotmail.com' und ich liefere den Code als extension. Freihaus natürlich (zusammen mit Dokumentation und einigen veranschaulichenden Beispielen, sowie eine zweite extension, die als eine, zumindest rudimentäre, Wegfindungsroutine fungiert).

Gruß

Basti

Geschrieben um 23:29 am 31.01.2008 | Zitat | Editieren | Löschen
Basti
Mitglied
Pupil Gumby
Beiträge: 14

Ok, Version 1 meiner 'Room & Dimension' extension ist draußen und kann hier heruntergeladen werden. Sie befindet sich allerdings in meinen Augen noch immer in einer Beta Phase. Dementsprechend fände ich es nicht schlecht, wenn sich noch einige weitere Leute finden würden, um den Code auszutesten.

Werbung ende und Gruß

Basti

AntwortenNeues ThemaNeue Umfrage
Powered by Spam Board SVN © 2007 - 2021
Impressum / Datenschutz