Page: << 1 2 3 >>
So now let's use this template to create a real Gothic character.
We'll call him Gunther - he'll not be a member of any guild and
will be an 'ambient NPC'. He's a bit of a bruiser, Level 17, Strength
100 and 200 HP. No mana, though. And he's deaf, why not. His other
senses have a 20m range. He'll also have level 2 skills with one-handed
weapons. We'll put an appropriate weapon in his inventory. So here
goes. You need to produce (or paste) this text in a text editor...
instance None_999_Gunther (Npc_Default) // Gunther will be a member
of the class Npc_Default. We could also use C_Npc itself.
{
//-------- primary data --------
name = "Gunther";
guild = GIL_NONE;
npctype = NPCTYPE_AMBIENT;
level = 17;
voice = 8;
id = 999;
// ----- attributes --------
attribute[ATR_STRENGTH] = 100;
attribute[ATR_DEXTERITY] = 100;
attribute[ATR_MANA_MAX] = 0;
attribute[ATR_MANA] = 0;
attribute[ATR_HITPOINTS_MAX]= 200;
attribute[ATR_HITPOINTS] = 200;
//-------- visuals --------
Mdl_SetVisual (self, "humans.mds"); // Basic animation file - this
file is used for all humans. Mdl_ApplyOverlayMds (self, "humans_militia.mds");
// Overlay animation file, giving a military movement type.
Mdl_SetVisualBody |
(self, "hum_body_naked0", // body mesh |
|
0, // body texture variant |
|
1, // skin color |
|
"hum_head_fighter", // head mesh |
|
51, // head texture variant |
|
2, // teeth texture variant |
|
GRD_ARMOR_M); // armor instance |
B_Scale (self); // body width according to strength of character
Mdl_SetModelFatness (self, 0); // limb fatness
//-------- talents --------
Npc_SetTalentSkill (self, NPC_TALENT_1H,2); // One handed weapons,
level 2
//-------- inventory --------
EquipItem (self, ItMw_1H_Mace_War_03); // Start him off with a
mace.
CreateInvItems (self, ITFO_Potion_Health_01, 10); // 10 Healing
potions, just in case...
//--------senses-------------
senses = SENSE_SEE | SENSE_SMELL;
senses_range = 2000; // cm!
//------------- ai -------------
fight_tactic = FAI_HUMAN_STRONG; // Governs combat behaviour
// We also have to identify the character's daily routine.
daily_routine = Rtn_start_999;
};
// We just need this function defined for now, so things work.
func void Rtn_Start_999 ()
{
};
Save this text file in /_work/data/scripts/content/story/Npc, called
something like Gunther.d. The .d extension means it will be picked
up when Gothic comes to parse its scripts.
Now we need Gothic to recognise the existence of this new instance
of the NPC class. We either do this by starting the Spacer and choosing
World/Reparse Scriptfiles... or by choosing 'Reparse all scripts'
when we start Gothic from GothicStarter. (You only have to do this
once.) I find using the Spacer more reliable, albeit slower.
Once this is done, Gunther can be introduced into the game world
from the console, with the command Insert None_999_Gunther. Doesn't
do much yet, does he. That will now change... If you can't insert
Gunther from the console, something's gone wrong, and you should
sort it out before proceeding.
3. Gunther's daily routine
To give the NPC something to do while he waits for you, he 'll
need either a Daily Routine or a start state. Gunther's daily routine
will involve standing in a particular place, and occasionally taking
a leak.
This simple NPC is only going to react to the approach of the player.
He won't have especially sophisticated reactions to other things,
like attacks etc.
Here's the code:
func void ZS_GuntherWait ()
{
PrintDebugNpc (PD_TA_FRAME, "ZS_GuntherWait"); // Debug output,
which is picked up by the ZSpy application.
Npc_PercEnable(self, PERC_ASSESSPLAYER, B_AssessSC); // Amongst
other things, checks whether this NPC needs to speak to the player
on approach.
Npc_PercEnable(self, PERC_ASSESSTALK, B_AssessTalk); // Means you
can talk to the NPC, for example to end the quest.
AI_StandUp (self);
AI_SetWalkmode (self, NPC_WALK);
AI_GotoWP (self, self.wp); // Go to the start point of your Daily
Routine
AI_AlignToWP (self); // Face in the same direction as the waypoint
arrow
};
func void ZS_GuntherWait_Loop ()
{
PrintDebugNpc (PD_TA_LOOP, "ZS_GuntherWait_Loop"); // More debug
output
AI_GotoWP (self, self.wp); // Go to the Daily Routine start point.
AI_Wait (self, 100); // Wait 100 seconds here
AI_GotoWP (self, Npc_GetNearestWP (Self)); // Look for another nearby
waypoint
AI_PlayAni(self, "T_PEE");
AI_Wait (self, 100); // Wait another 100 seconds before the loop
ends
};
func void ZS_GuntherWait_End ()
{
PrintDebugNpc (PD_TA_FRAME,"ZS_GuntherWait_End");
};
So, nearly ready. We just have to include this Daily Routine in
the list of such routines. To do this, we open /_work/data/skripts/content/story/ZS/TA.d
and insert these lines:
func void TA_GuntherWait (var int start_h,var int start_m,var int
stop_h,var int stop_m,var string waypoint)
{
TA_Min (self, start_h,start_m, stop_h, stop_m, ZS_GuntherWait, waypoint);
};
Then save TA.d. Now these lines:
func void Rtn_Start_999 ()
{
TA_GuntherWait (0,00,13,00, "OC1");
TA_GuntherWait (13,00,0,00, "OC1");
};
ensure that Gunther will stand in front of the Old Camp all day
long.
NB: Daily Routines (which often start TA_, from the German 'Tagesablauf')
need at least two periods, as above. Otherwise, the engine gets
confused. They get saved with some filename, in /_work/data/skripts/content/story/ZS,
with a .d extension.
One final step, and Gunther is in the game. Open /_work/data/skripts/content/story/Startup.d
and insert this:
Wld_InsertNpc(None_999_Gunther,"OC1");
in the block which refers to the Old Camp. And there we have it.
Reparse the scripts, as you did before, and Gunther is in the game.
Page: << 1 2 3 >> |