Przejdź do głównej zawartości

Mój pierwszy NPC

W tym poradniku nauczysz się tworzyć prostą postać niezależną (NPC) w języku Daedalus. Stworzymy farmera, który stoi na rynku i ma swój dzienny plan zajęć.

Wymagania wstępne

Przed rozpoczęciem upewnij się, że:

  • Masz zainstalowane skrypty Gothic (folder Scripts/Content/)
  • Rozumiesz strukturę skryptów
  • Wiesz, czym jest instancja i prototyp w Daedalusie

Klasa C_NPC - co definiuje postać?

Każdy NPC w Gothic jest instancją klasy C_NPC. Najważniejsze pola tej klasy to:

PoleTypOpis
namestring[5]Imię NPC (wyświetlane w grze)
guildintGildia (np. GIL_MIL - milicja, GIL_OUT - bezgildyjny)
idintUnikalny identyfikator NPC
voiceintNumer głosu (powiązany z plikami audio)
levelintPoziom postaci
attribute[]int[]Atrybuty: HP, mana, siła, zręczność
protection[]int[]Ochrona przed typami obrażeń
fight_tacticintTaktyka walki (np. FAI_HUMAN_COWARD)
daily_routinefuncFunkcja z dziennym planem NPC
npctypeintTyp NPC (główny, przyjaciel, wróg)
flagsintFlagi (np. NPC_FLAG_IMMORTAL)

Prototyp Npc_Default

Zanim stworzymy własną postać, musimy rozumieć prototyp Npc_Default. Jest to szablon, z którego dziedziczą prawie wszystkie postacie w grze:

prototype Npc_Default (C_NPC)
{
// Podstawowe atrybuty
attribute[ATR_STRENGTH] = 10;
attribute[ATR_DEXTERITY] = 10;
attribute[ATR_MANA_MAX] = 10;
attribute[ATR_MANA] = 10;
attribute[ATR_HITPOINTS_MAX] = 40;
attribute[ATR_HITPOINTS] = 40;

// Szanse trafienia (0% - nie umie walczyć daną bronią)
HitChance[NPC_TALENT_1H] = 0;
HitChance[NPC_TALENT_2H] = 0;
HitChance[NPC_TALENT_BOW] = 0;
HitChance[NPC_TALENT_CROSSBOW] = 0;

// Ochrona (0 - brak ochrony)
protection[PROT_EDGE] = 0;
protection[PROT_BLUNT] = 0;
protection[PROT_POINT] = 0;
protection[PROT_FIRE] = 0;
protection[PROT_MAGIC] = 0;

// Domyślne ustawienia
damagetype = DAM_BLUNT;
senses = SENSE_HEAR | SENSE_SEE;
senses_range = PERC_DIST_ACTIVE_MAX;
};
PoleDomyślnieOpis
attribute[ATR_STRENGTH]10Bazowa siła
attribute[ATR_DEXTERITY]10Bazowa zręczność
attribute[ATR_MANA_MAX]10Maksymalna mana
attribute[ATR_MANA]10Startowa mana
attribute[ATR_HITPOINTS_MAX]40Maksymalne zdrowie
attribute[ATR_HITPOINTS]40Startowe zdrowie
HitChance[NPC_TALENT_*]0Szansa trafienia per typ broni - 0% = nie umie walczyć tą bronią
protection[PROT_*]0Ochrona przed typami obrażeń - 0 = brak ochrony
damagetypeDAM_BLUNTDomyślny typ zadawanych obrażeń
sensesSENSE_HEAR | SENSE_SEENPC słyszy i widzi
senses_rangePERC_DIST_ACTIVE_MAXMaksymalny zasięg percepcji
informacja

Prototyp ustawia domyślne wartości. Każda instancja NPC może nadpisać dowolne z nich.

Tworzenie instancji NPC

Stwórzmy farmera o imieniu Konrad. Utwórz plik BAU_900_Konrad.d w folderze Story/NPC/:

instance BAU_900_Konrad (Npc_Default)
{
// --- Podstawowe informacje ---
name = "Konrad";
guild = GIL_OUT;
id = 900;
voice = 90;
flags = 0;
npctype = NPCTYPE_MAIN;

// --- Atrybuty ---
attribute[ATR_STRENGTH] = 30;
attribute[ATR_DEXTERITY] = 15;
attribute[ATR_HITPOINTS_MAX] = 80;
attribute[ATR_HITPOINTS] = 80;
level = 5;

// --- Walka ---
fight_tactic = FAI_HUMAN_COWARD;

// --- Ekwipunek ---
EquipItem (self, ItMw_1h_Bau_Axe);
CreateInvItems (self, ItMi_Gold, 25);
CreateInvItems (self, ItFo_Apple, 3);

// --- Wygląd ---
B_SetNpcVisual (self, MALE, "Hum_Head_Bald", Face_N_NormalBart_Senyan, BodyTex_N, ITAR_Bau_L);
Mdl_SetModelFatness (self, 1);
Mdl_ApplyOverlayMds (self, "Humans_Relaxed.mds");

// --- Umiejętności ---
B_GiveNpcTalents (self);
B_SetFightSkills (self, 15);

// --- Plan dnia ---
daily_routine = Rtn_Start_900;
};
Pole / WywołanieOpis
name = "Konrad"Imię NPC wyświetlane w grze
guild = GIL_OUTBezgildyjny (rolnik)
id = 900Unikalny numer identyfikacyjny
voice = 90Numer głosu (powiązany z plikami audio)
flags = 00 = normalny, NPC_FLAG_IMMORTAL = nieśmiertelny
npctype = NPCTYPE_MAINWażna postać (związana z questami)
attribute[ATR_STRENGTH] = 30Siła (nadpisuje 10 z prototypu)
attribute[ATR_DEXTERITY] = 15Zręczność (nadpisuje 10 z prototypu)
attribute[ATR_HITPOINTS_MAX] = 80Maksymalne zdrowie (nadpisuje 40 z prototypu)
attribute[ATR_HITPOINTS] = 80Startowe zdrowie
level = 5Poziom postaci
fight_tactic = FAI_HUMAN_COWARDUcieka przed walką
EquipItem(self, ItMw_1h_Bau_Axe)Zakłada topór farmera
CreateInvItems(self, ItMi_Gold, 25)25 sztuk złota w ekwipunku
CreateInvItems(self, ItFo_Apple, 3)3 jabłka w ekwipunku
B_SetNpcVisual(self, ...)Ustawia mesh ciała, głowę, twarz, teksturę i zbroję
Mdl_SetModelFatness(self, 1)Tusza postaci (0 = chudy, 1 = normalny, 2 = gruby)
Mdl_ApplyOverlayMds(self, "Humans_Relaxed.mds")Zrelaksowana nakładka animacji
B_GiveNpcTalents(self)Przypisuje domyślne talenty
B_SetFightSkills(self, 15)15% szans trafienia dla wszystkich typów broni
daily_routine = Rtn_Start_900Funkcja planu dnia (zobacz niżej)
wskazówka

Konwencja nazewnictwa: BAU (Bauer = farmer), 900 (unikalne ID), Konrad (imię). W oryginalnych skryptach Gothic każda gildia ma swój prefix.

Plan dnia (Daily Routine)

Każdy NPC potrzebuje planu dnia - funkcji określającej, co robi o danej godzinie:

func void Rtn_Start_900 ()
{
// Od 7:00 do 12:00 - stoi przy studni
TA_Stand_ArmsCrossed (07, 00, 12, 00, "NW_CITY_WELL_01");

// Od 12:00 do 13:00 - je posiłek
TA_Sit_Bench (12, 00, 13, 00, "NW_CITY_BENCH_01");

// Od 13:00 do 20:00 - pracuje na farmie
TA_Smalltalk (13, 00, 20, 00, "NW_FARM1_PATH_01");

// Od 20:00 do 7:00 - śpi
TA_Sleep (20, 00, 07, 00, "NW_FARM1_BED_01");
};
ostrzeżenie

Waypointy (np. "NW_CITY_WELL_01") muszą istnieć w świecie gry (pliku .zen). Jeśli użyjesz nieistniejącego waypointa, NPC pojawi się w punkcie (0, 0, 0).

Dostępne funkcje planu dnia:

FunkcjaOpis
TA_Stand_ArmsCrossedStoi ze skrzyżowanymi rękoma
TA_Stand_GuardingStoi na straży
TA_Sit_BenchSiedzi na ławce
TA_SleepŚpi
TA_SmalltalkRozmawia z pobliskimi NPC
TA_SmithKowalstwo
TA_EatJe
TA_PracticeĆwiczy

Rejestracja w Gothic.src

Aby gra załadowała nowego NPC, musisz dodać plik do Gothic.src:

Story\NPC\BAU_900_Konrad.d
ważne

Kolejność plików w Gothic.src ma znaczenie! NPC musi być zadeklarowany po prototypie Npc_Default, ale przed dialogami.

Osadzenie NPC w świecie

Aby NPC pojawił się w świecie gry, musisz go wstawić (spawn) w funkcji startowej odpowiedniego świata. W pliku Startup.d (lub odpowiednim pliku świata) dodaj:

func void Startup_NewWorld ()
{
// ... inne NPC ...
Wld_InsertNpc (BAU_900_Konrad, "NW_CITY_WELL_01");
};

Wld_InsertNpc wstawia postać do świata w podanym waypoinecie. Od tego momentu NPC zacznie wykonywać swój plan dnia.

Podsumowanie

Utworzenie NPC wymaga:

  1. Instancji dziedziczącej po Npc_Default
  2. Ustawienia atrybutów (siła, HP, poziom)
  3. Konfiguracji wyglądu (model, tekstura, zbroja)
  4. Zdefiniowania planu dnia
  5. Rejestracji w Gothic.src
  6. Wstawienia do świata w Startup.d