1.0 Einführung 

2.0 Die Anfänge

3.0 Der Hauptscript

4.0 Move-Script

5.0 Kamera

6.0DorfbewohnerKI

7.0 Erste Waffen

8.0 Panels

9.0 Der erste Quest

10.0 Partikel

11.0 Menü

12.0 Abschließung

13.0 Downloads

14.0 Codesammlung

15.0 Frei Belegbare

Steuerung

9.0 Der erste Quest

Wir wollen Jetzt einen einfachen Quest erstellen, in dem der Spieler mit einen Wächter redet der ihm den Auftrag gibt ein Monster zu suchen und zu erschlagen! Wenn man es geschafft hat soll man eine Belohnung bekommen! Hier eine Zeichung wie ich es mir vorstelle: 

Als Erstes soll der Spieler einen Auftrag von den NPC bekommen! Den kann er nur ansprechen wenn das Schwert eingesteckt ist! Wenn er dann den Auftrag hat wird das Schwarz eingezeichnete unsichtbare Map-enity gelöscht damit der Spieler aus der Burg kommt! Danach soll der Spieler den Pfad folgen und das Skeltett angreifen! Das Skelett soll eine Waffe hinterlassen! Danach greift er den Goblin an der einen Heiltrank hinterlässt! Wenn der Spieler dann den Endgegner besiegt hinterlässt der einen Ring, der als Beweismittel dient das er den Gegner erschlagen hat! Wenn man dann zurück zum NPC geht bekommt man von dem 100 Geldstücke! 

9.1 Reden mit den Dorfbewohner

Gehen wir nochmal zu unseren Dorfbewohner KI und zu der Waffen Aktion! Wir wollen es als erstes so machen das der Spieler den NPC nur dann Anreden kann wenn er keine Waffe in der Hand hat! Nun haben wir breits in die Waffen Aktion geschrieben das wenn der Spieler die Waffe hat der skill waffe_haben 1 ist! Nun schreiben wir einfach leicht einen Npc IF Satz um!:

//Wenn der Actor angeklickt worden ist
if(event_type==event_click)&&(player.waffe_haben==0)
{

reden=1; // Die Variable Reden wird auf 1 gesetzt da man ja jetzt redet!!
my.event=null; /*hat der Spieler für eine Kurze zeit kein Event mehr um zu verhindern das der Spieler den actor nochmal anklicken kann

Nun kann man den NPC nur anklicken wenn Waffe_haben Null ist! 

Ok nun haben wir es schon geschafft das man den NPC nicht immer anreden kann jetzt ändern wir noch die Texte die der Npc sagt: 

  text Leben_Txt{layer=8;pos_x=0; pos_y=150;flags=d3d;font=standard_font;string="was wollen Sie?";}
//DIe Anfangsfrage bleibt gleich


text haben_geld{layer=8;pos_x=0; pos_y=175;flags=d3d;font=standard_font;string="1:Haben sie einen Ahnung was ich vieleicht machen könnte?";}

// Hier kommt die Frage nach dem Auftrag!!

text Nichts{layer=8;pos_x=0; pos_y=200;flags=d3d;font=standard_font;string="2:Ich geh wieder!";}
//Die Antwort bleibt auch gleich!


text Kein_geld{layer=8;pos_x=0; pos_y=200;flags=d3d;font=standard_font;string="Ja! Hier in der Gegend ist ein schreckliches Monster!\n Wenn sie es besiegen werden sie eine angemessene Belohnung bekommen!";}

//Die Antwort auf die Frage nach den Auftrag! "\n" bedeutet das eine neue Zeile beginnt

text Verschwinden{layer=8;pos_x=0; pos_y=175;flags=d3d;font=standard_font;string="Ok Verschwinden Sie!";}

 

Gut nun redet der Npc auch schon was sinnvolles! Nun brauchen wir noch einen Text der erscheint wenn Sie das Monster besiegt haben und zurück kommen! 

text Schwetzchen{layer=8;pos_x=0; pos_y=225;flags=d3d;font=arial;string="Sie haben das monster besiegt!";}

//Kommt wenn sie das Monster besiegt haben! (Sagt nicht der NPC!!
text Schwetzchen3{layer=8;pos_x=0; pos_y=625;flags=d3d;font=arial;string="Sie haben das Monster besiegt! Fantastisch hier haben sie 100 Goldmünzen! Das ist eine angemssene Belohnung!";}

// Belohnungssatz dafür das man das Monster besiegt hat!

Ok nun müssen wir noch das unsichtbare Entity scripten!

//in die vars.wdl
var nicht_durchlassen=0; //diese Variable sagt ob der Spieler durchgelassen wird oder nicht!

//in die andere.wdl


text Auftrag_abholen{layer=8;pos_x=40; pos_y=200;flags=d3d;font=standard_font;string="Ich muss mir noch einen Auftrag abholen!";}

//Dieser Text sagt das der Spieler nicht durchdarf!
function durchlassen_event()
{
if(event_type==event_impact)||(event_type==event_entity)
{//Wenn der Spieler die entity trifft 
auftrag_abholen.visible=on; //zeige das Text
waitt(32); //warte 2 Sekunden
auftrag_abholen.visible=off; //mache den Text wieder weg!
}
}


action durchlassen
{
my.invisible=on; //unsichtbar
while(nicht_durchlasse==0) 
{//solange nicht durchlassen null ist
my.event=durchlassen_event;  // ist das event durchlassen_event
my.enable_entity=on; //mache das entity sensitiv für Entity kollisionen!
my.enable_impact=on;
wait(1);
}
remove(my); //wenn der Spieler den Auftrag erhalten hat, entferne mich!
}

Ok, nun werden sie sich denken wie mache ich das mit der Variable nicht_durchlassen ??Ist eigentlich ganz einfach! Dazu überarbeiten wir einfach nochmal die NPC Aktion! Hier die überarbeite Aktion:

//in der actors.wdl in der Npc Aktion! 

leben_txt.visible=on;
haben_geld.visible=on;
nichts.visible=on;
dialog.visible=on;
while(key_1==0)&&(key_2==0)&&(key_esc==null)&&(key_3==null) { wait(1); }
if(key_1==1) {nichts.visible=off; kein_geld.visible=on; nicht_durchlasse=1; }

Die letze Zeile ist wichtig! Wenn jetzt  Key 1 gedrückt ist (Damit gelangt man zu den Satz was der Auftrag ist), soll nicht_durchlassen 1 sein und der Spieler wird durchgelassen!

 

GEGNER

Nun soll es in der Spielwelt ja auch einige Gegner geben! Da KI grundsätzlich sehr schwer zu scripten ist habe ich nur einen etwas dümmeren KI genommen! Der Gegner kann sich wehren und rennt auf den Spieler zu! Wenn er Tod ist spielt er die Todesanimtaion ab! Hier der Code

entity* enemy;

define gegner_schaden,skill5;

define gebe_erfahrung,skill4;

define sword_tip,skill6;

define sword_base,skill7;

var enemy_distance[3];

action gegner 
{
enemy = me; 
enemy.leben = 100; //Der Gegner hat 100 Leben
my.gegner_schaden = 2;  //Mein schaden ist 2!
my.gebe_erfahrung=175; //Meine Erfahrung die ich den Spieler gebe ist 100
while (my.leben > 0) // So lange man lebt
{
if (vec_dist (my.x, player.x) < 600 && player.leben > 0) /* Wenn der Spieler näher als 600 Quants an den Gegner herangekommen ist */
{
vec_set(temp, player.x);  //Setze Temp auf Player.X
vec_sub(temp, my.x); //Subtrahiere temp von my.x
vec_to_angle(my.pan, temp); //Drehe mich schließlich zum Spieler
trace_mode=ignore_me+ignore_passable; //Trace mit diesen Tracemode
my.tilt = 0; // der Gegner ist "grade"
enemy_distance.y = 0; //Keine distanz in die Y richtung!
enemy_distance.z = 0; //Keine Distanz in die Z richtung
enemy_distance.x = 5 * time; //Gehe mit 5* Time 
ent_move(enemy_distance, nullvector); //Bewege den Gegner (MOVE-KAPITEL)
ent_cycle("walk", my.skill19); // Animiere den Gegner mit der Geschwindigkeit von my.skill19
my.skill19 += 5 * time; // Der Animationsspeed
if (my.skill19 > 100) {my.skill19 = 0;} // Mache die Antimation immer
if (vec_dist (my.x, player.x) < 50) // Wenn der Spieler näher als 50 Quants an den Gegner ist
{
my.skill20 = 0; // Setze skill 20 auf 0
while (my.skill20 < 100)
{ //solange skill20 kleiner als 100 ist 
ent_vertex(my.sword_tip, 291); //Das obere ende des schwertes wird per ent_vertex festgelegt! (im med rausfinden)
ent_vertex(my.sword_base, 306); // Das untere Ende des Schwertes wird per ent_vertex festgelegt (im med herausfinden)
trace_mode = ignore_me + ignore_passable; //trace
trace (my.sword_base, my.sword_tip); // zwischen den Schwert Anfang und Ende
if (result != 0) // Wenn es etwas trifft
{
effect (particle_blood, 25, target, normal); //Mache ein Effekt
if (you != null) 
{
you.leben -= my.gegner_schaden * time;//ziehe von dem YOU Enemy schaden ab!
}
}
ent_playsound (my, sword_snd, 50); // und Spiele einen sound!
}
ent_cycle("attack", my.skill20); //Und zeige die Animation
my.skill20 += 5 * time; // Die Animationsgeschwindigkeit 
wait (1);
}
waitt (6); //warte 6 Ticks
}
}
else // Wenn der Spieler wieder weiter weg ist
{
ent_cycle("stand", my.skill21); // Spiele die stand animation ab!
my.skill21 += 2 * time; // "Der Animationsspeed
if (my.skill21 > 100) {my.skill21 = 0;} // Wiederhohle andauernd die Animation!
}
wait (1);
}
my.leben=0; //Wenn man Tod hat setzte die Lebensanzahl des Gegners wieder auf 0!
player.1erfahrung+=my.gebe_erfahrung; //gebe den Spieler Erfahrung
while (my.skill22 < 80) 
{ //solange die Todes Animation abgespielt wird 
ent_cycle("death", my.skill22);
my.skill22 += 1 * time; // "Tod" Animationsgeschwindigkeit
wait (1);
}
remove(my); //*Wenn der Gegner die Animation abgespielt habe soll er nicht da liegen bleiben (Framerate ) sondern er wird aus dem Spiel entfernt! */
}

 

Nun die Erklärungen:

entity* enemy;

define gegner_schaden,skill5;

define gebe_erfahrung,skill4;

define sword_tip,skill6;

define sword_base,skill7;

var enemy_distance[3];

Hier werden ein paar Variablen Skills und Entitys definiert ! Gegner_Schaden steht für den Schaden den der Gegner macht! Gebe_Erfahrung für die Erfahrung die der Gegner den Spieler gibt! Sword_tip die ober Grenze vom Schwert, sword_base die untere! Enemy_distance ist das gleiche wie dist bei den Move-Code!

action gegner 
{
enemy = me; 
enemy.leben = 100; //Der Gegner hat 100 Leben
my.gegner_schaden = 2;  //Mein schaden ist 2!
my.gebe_erfahrung=175; //Meine Erfahrung die ich den Spieler gebe ist 100

Enemy soll der Gegner sein! Er soll 100 Leben haben (der Spieler hat 500)! Er fügt den Spieler 2 Schaden pro Tick zu und er gibt 175 Erfahrung wenn er Tod ist!

while (my.leben > 0) // So lange man lebt
{
if (vec_dist (my.x, player.x) < 600 && player.leben > 0) /* Wenn der Spieler näher als 600 Quants an den Gegner herangekommen ist */
{
vec_set(temp, player.x);  //Setze Temp auf Player.X
vec_sub(temp, my.x); //Subtrahiere temp von my.x
vec_to_angle(my.pan, temp); //Drehe mich schließlich zum Spieler

                              zurück     weiter