Page: << 1 2 3
4. The Quest
Quests are implemented in Gothic through the dialogue system. We'll
go through the basic structure of a dialogue, and then fill it out
with the info which describes the quest to find the sword and hand
it over.
The code:
instance Instance_Name (C_INFO)
{
npc = NPC_Name; // This is the NPC whose dialogue this is.
condition = Instance_Name_Condition; // This points to a function
which assesses whether this dialogue is to be triggered
information = Instance_Name_Info; // This points to a function
which implements the actual dialogue.
important = 1; // Identifies dialogues which the NPC will start
up, without the player talking to the NPC first.
permanent = 0; // Permanent dialogues are always offered
FUNC int Instance_Name_Condition()
{
return 1;
};
The function evaluates to True or False (or 1 or 0). When true,
the NPC will offer the dialogue. Here it is always true.
func void Instance_Name_Info()
{
// This function will hold the actual dialogue - explained in more
detail below..
};
In addition, NPC dialogues always have an Exit function, which
puts the 'End' in the dialogue options.
// ************************ Exit function **************************
instance Instance_Name_Exit (C_INFO)
{
npc = NPC_Name;
condition = Instance_Name_Exit_Condition;
information = Instance_Name_Exit_Info;
important = 0; // Only presented if the player speaks to the NPC
permanent = 1; // Does not go away if chosen in earlier dialogues.
description = "END"
;
};
FUNC int Instance_Name_Exit_Condition()
{
return 1; // Always needed...
};
FUNC VOID Instance_Name_Exit_Info()
{
AI_StopProcessInfos (self);
};
So that's it. By including the right values and appropriate functions
in these dialogues, quests are created.
Let's go.
Step 1. In _work/data/skripts/content/story/Storyglobals.d
add these lines:
const string GunthersSword = "Bring Gunther's sword back";
var int int_GotSword;
These describe the quest in your journal and keep track of whether
you've completed the quest.
Save.
Some code:
instance None_999_Gunther_AskForSword (C_INFO)
{
npc = None_999_Gunther;
condition = None_999_Gunther_AskForSword_Condition;
information = None_999_Gunther_AskForSword_Info;
important = TRUE; // Gunther will talk to the player on approach
permanent = FALSE; // The quest is offered only once.
description = ""; // Empty here, as nothing is to appear in the
initial dialogue box at the top of the screen.
};
FUNC int None_999_Gunther_AskForSword_Condition()
{
if (hero.level >= 0) // A fake check - only players above level
0 will be offered the quest.
{
return TRUE;
};
return FALSE; // This is Daedelus' IF-THEN-ELSE structure
};
func void None_999_Gunther_AskForSword_Info()
{
AI_Output ( self, other, "None_999_Gunther_AskForSword_Info_8_01");
// Hey you, busy?
// The first number represents the NPC's voice, the second is a
counter, identifying each line.
Info_ClearChoices (None_999_Gunther_AskForSword);
Info_AddChoice (None_999_Gunther_AskForSword, "Nope.",
None_999_Gunther_AskForSword_Yes);
Info_AddChoice (None_999_Gunther_AskForSword, "Afraid so.",
None_999_Gunther_AskForSword_No);
};
// If the player says he's busy...
void None_999_Gunther_AskForSword_No ()
{
AI_Output(other,self, "None_999_Gunther_AskForSword_Info_8_02");
// I'm busy
AI_Output(self,other, "None_999_Gunther_AskForSword_Info_8_03");
// Ok, whatever...
AI_StopProcessInfos (self);
};
// If the player says yes...
func void None_999_Gunther_AskForSword_No ()
{
AI_Output(other,self,"None_999_Gunther_AskForSword_Info_8_04");
// Nope... AI_Output(self,other,"None_999_Gunther_AskForSword_Info_8_05");
// Go get ma sword.
Log_CreateTopic (GunthersSword,LOG_MISSION);
Log_SetTopicStatus (GunthersSword,LOG_RUNNING);
B_LogEntry(GunthersSword, "Gunther's has rather tersely asked me
to get his sword back.");
AI_StopProcessInfos (self);
};
And that's basically it. Gunther asks the player if he's busy,
and responds differently according to what he says...
You need to save this dialogue as a file called DIA_something.d,
in /_work/data/skripts/content/story/Missions. You also need to
create the 'Output Units' files, before your text will actually
appear. Delete or move the files OU.bin and OU.csl from whichever
Gothic folder they're currently in.
Start the Spacer. Press the button on the horizontal toolbar to
bring up the Output Units window. Press Refresh. Press Save.
That's it.
NB: Bear in mind that if you are creating a Mod, you might want
to set the parameter enableSubtitles, to ensure people can see the
text, given that there's no sound.
5. The Object of the Quest
We're going to create a sword, to be the object of the quest. As
with the NPC described above, we'll outline the relevant class,
and then fill in a particular instance.
The class:
CLASS C_Item
{
VAR INT id; // As with the C_Npc class above.
VAR STRING name, nameID; As with C_Npc
VAR INT hp,hp_max; As with C_Npc
VAR INT mainflag, flags;
VAR INT weight, value; // Integer values
// For Weapons:
VAR INT damageType; Type of damage
VAR INT damageTotal;
VAR INT damage [DAM_INDEX_MAX];
// For Armour
VAR INT wear;
//Only WEAR_TORSO is used, as there are no other kinds of armour
in the game.
VAR INT protection [PROT_INDEX_MAX];
// This is an array which stores the protection afforded by the
armour against each damage type.
// For foods
VAR INT nutrition; // HP increase on consumption
Obsolete
// When using items...
VAR INT cond_atr [3];
VAR INT cond_value [3];
// An array of two x three integers, used to hold the level of
the attribute necessary to use the item.
// The attributes which are changed when the object is used or
worn.
VAR INT change_atr [3];
VAR INT change_value [3];
//Obsolete
// Parser functions
VAR FUNC magic;
VAR FUNC on_equip;
VAR FUNC on_unequip;
VAR FUNC on_state [4];
// Owner
VAR FUNC owner; // Owner: Instance-Name
VAR INT ownerGuild; // Owner: Guild
VAR INT disguiseGuild; // Obsolete
//3DS Data
VAR STRING visual; //The location of the visual (mesh) for the object.
// Changing appearances with objects
VAR STRING visual_change ; // ASC - File
Identifies the new visual associated with putting on armour.
VAR INT visual_skin;
The texture for the armour mesh.
VAR STRING scemeName;
Internal name for the use of items
6. The 'Quest Complete' Dialogue
This is the dialogue that is triggered if the quest conditions
have been met.
// ************************
EXIT **************************
instance None_999_Gunther_AskForSword_Exit (C_INFO)
{
npc = None_999_Gunther;
condition = None_999_Gunther_AskForSword_Exit_Condition;
information = None_999_Gunther_AskForSword_Exit_Info;
important = 0;
permanent = 1;
description = "END";
};
FUNC int None_999_Gunther_AskForSword_Exit_Condition()
{
return 1; // Always has the option to choose End
};
FUNC VOID None_999_Gunther_AskForSword_Exit_Info()
{
AI_StopProcessInfos ( self );
};
instance None_999_Gunther_BringSword
(C_INFO)
{
npc = None_999_Gunther;
condition = None_999_Gunther_bringSword_Condition;
information = None_999_Gunther_bringSword_Info;
important = FALSE;
permanent = TRUE;
description = "Do you
have the sword?";
};
FUNC int None_999_Gunther_bringSword_Condition()
{
// 1.Nur wenn der Held den Auftrag hat kann er ihn auch beenden
// 2.Nur wenn der Auftrag nicht als erfüllt gilt wird der Dialog
angeboten
// 3.Schwert instanz abfragen, nur dann macht Auftraglösen Sinn
// 1. If the player accepted the quest...
// 2. and hasn't yet completed it...
// 3. and has the sword...
// ... offer the dialogue
if (Npc_KnowsInfo ( hero,
None_999_Gunther_AskForSword)
// (1) &! int_GotSword
// (2) && Npc_HasItems (other, ItMw_1H_GuntherWantedSword) >= 1)
// (3)
{
return TRUE;
};
return FALSE;
};
func void None_999_Gunther_bringSword_Info()
{
Info_ClearChoices (None_999_Gunther_bringSword);
Info_AddChoice
|
(None_999_Gunther_bringSword, |
|
"I've
got it and I'm keeping it!", |
|
None_999_Gunther_bringSword_Yes); |
|
|
Info_AddChoice
|
(None_999_Gunther_bringSword, |
|
"Here
you go, mate.", |
|
None_999_Gunther_bringSword_No); |
}; |
|
// If the player doesn't
hand it over...
func void None_999_Gunther_bringSword_Yes ()
{
AI_Output( other, self, "None_999_Gunther_bringSword_Info_8_06");
// I don't think so, sonny.
AI_Output( self, other, "None_999_Gunther_bringSword_Info_8_07");
// Then take this!
AI_StopProcessInfos (self);
AI_StartState( self, ZS_Attack, 0, ""); // Gunther attacks
};
// The player hands it
over func void None_999_Gunther_bringSword_No ()
{
AI_Output ( other, self, "None_999_Gunther_bringSword_Info_8_08");
// Here you go.
AI_Output ( self, other, "None_999_Gunther_bringSword_Info_8_09");
// Triffic.
B_LogEntry (GunthersSword,
"Gave him his sword");
other.exp = other.exp
+ 100; // +100 experience points
other.lp = other.lp + 10; // ... and some learn points
//Npc_GiveItem ( other,
MilhouseSchwert, self); // Gunther gets the sword
AI_StopProcessInfos (self);
};
Page: << 1 2 3 |