System nauki walki bronią i atrybutów z G2NK w G1 5590 1

O temacie

Autor bgb

Zaczęty 19.01.2016 roku

Wyświetleń 5590

Odpowiedzi 1

bgb

bgb

Użytkownicy
posty848
Propsy592
Profesjabrak
  • Użytkownicy
Obydwa systemy przeniesiemy wprost ze skryptów G2NK, lekko je dostosowując tak by działały pod Gothic 1.
Dobrze jest mieć skrypty z G2nk gdzieś pod ręką, aczkolwiek nie jest to konieczne, jeśli chce się korzystać tylko z tego samouczka.

1. Część pierwsza - walka bronią

Zacznijmy od porównania jak wyglądają obydwa systemy nauki w g1 i g2nk.

System walki broniami w G1 jest trzystopniowy. Gracz zaczyna od zera z poziomem "brak" i może awansować na poziom "adept" oraz "mistrz" poprzez bezpośrednie wyuczenie się tych poziomów u NPC. Każdy z poziomów posiada odmienne animacje ataku oraz sztywno przydzieloną szansę na uderzenie krytyczne.

W G2NK wygląda to odmiennie. Gracz nie uczy się samych poziomów, lecz podnosi swą biegłość w używaniu danego rodzaju broni wyrażonej w procentowej szansie na obrażenia krytyczne. Po osiągnięciu odpowiednio wysokiej wartości gra automatycznie ustawia bohaterowi kolejny poziom. Tych podobnie jak w G1 jest trzy i również odpowiadają za animacje ataku, noszą jednak lekko odmienne nazwy (np. zielony, wojownik, mistrz). Gracz startuje z 10% szansą na trafienie krytyczne w każdym rodzaju broni, a gra automatycznie awansuje nas na drugi poziom po osiągnięciu 30% biegłości, oraz na trzeci - przy progu 60%. Progi to kolejna znacząca różnica pomiędzy G1, a G2nk. Przechodząc do rzeczy, istnieją 3 progi, od których zależny jest koszt Punktów Nauki (PN) jaki wydamy na 1% w biegłości danej broni. Do 30% biegłości: 1% = 1PN, od 30% do 60%: 1% = 2PN, od 60% do 90%: 1% = 3PN, od 90%: 1% = 4PN. Można by pociągnąć to jeszcze wyżej jednak osiągnięcie 100% biegłości jest zazwyczaj limitem.


Część teoretyczna za nami, a przed nami zadanie by przenieść to co wyżej zostało opisane do G1.

Interesuje nas kilka funkcji, pierwsza z nich nosi nazwę B_TeachFightTalentPercent. Otwieramy plik ze skryptów G2NK: Story\B_Story\B_TeachFighTalentPercent.d i kopiujemy naszą funkcję.

func int B_TeachFightTalentPercent(var C_Npc slf,var C_Npc oth,var int talent,var int percent,var int teacherMAX)

{
var string concatText;
var int kosten;
var int realHitChance;
kosten = B_GetLearnCostTalent(oth,talent,1) * percent;
if((talent != NPC_TALENT_1H) && (talent != NPC_TALENT_2H) && (talent != NPC_TALENT_BOW) && (talent != NPC_TALENT_CROSSBOW))
{
Print("*** Błąd: Zły parametr ***");
return FALSE;
};
if(talent == NPC_TALENT_1H)
{
realHitChance = oth.HitChance[NPC_TALENT_1H];
}
else if(talent == NPC_TALENT_2H)
{
realHitChance = oth.HitChance[NPC_TALENT_2H];
}
else if(talent == NPC_TALENT_BOW)
{
realHitChance = oth.HitChance[NPC_TALENT_BOW];
}
else if(talent == NPC_TALENT_CROSSBOW)
{
realHitChance = oth.HitChance[NPC_TALENT_CROSSBOW];
};
if(realHitChance >= teacherMAX)
{
concatText = ConcatStrings(PRINT_NoLearnOverPersonalMAX,IntToString(teacherMAX));
PrintScreen(concatText,-1,-1,FONT_Screen,2);
B_Say(slf,oth,"$NOLEARNYOUREBETTER");
return FALSE;
};
if((realHitChance + percent) > teacherMAX)
{
concatText = ConcatStrings(PRINT_NoLearnOverPersonalMAX,IntToString(teacherMAX));
PrintScreen(concatText,-1,-1,FONT_Screen,2);
B_Say(slf,oth,"$NOLEARNOVERPERSONALMAX");
return FALSE;
};
if(oth.lp < kosten)
{
PrintScreen(PRINT_NotEnoughLP,-1,-1,FONT_Screen,2);
B_Say(slf,oth,"$NOLEARNNOPOINTS");
return FALSE;
};
oth.lp = oth.lp - kosten;
if(talent == NPC_TALENT_1H)
{
B_RaiseFightTalent(oth,NPC_TALENT_1H,percent);
if(oth.aivar[REAL_TALENT_1H] >= (oth.aivar[REAL_TALENT_2H] + 30))
{
B_RaiseFightTalent(oth,NPC_TALENT_2H,percent);
PrintScreen(PRINT_Learn1H_and_2H,-1,-1,FONT_Screen,2);
}
else
{
PrintScreen(PRINT_Learn1H,-1,-1,FONT_Screen,2);
};
return TRUE;
};
if(talent == NPC_TALENT_2H)
{
B_RaiseFightTalent(oth,NPC_TALENT_2H,percent);
if(oth.aivar[REAL_TALENT_2H] >= (oth.aivar[REAL_TALENT_1H] + 30))
{
B_RaiseFightTalent(oth,NPC_TALENT_1H,percent);
PrintScreen(PRINT_Learn2H_and_1H,-1,-1,FONT_Screen,2);
}
else
{
PrintScreen(PRINT_Learn2H,-1,-1,FONT_Screen,2);
};
return TRUE;
};
if(talent == NPC_TALENT_BOW)
{
B_RaiseFightTalent(oth,NPC_TALENT_BOW,percent);
if(oth.aivar[REAL_TALENT_BOW] >= (oth.aivar[REAL_TALENT_CROSSBOW] + 30))
{
B_RaiseFightTalent(oth,NPC_TALENT_CROSSBOW,percent);
PrintScreen(PRINT_LearnBow_and_Crossbow,-1,-1,FONT_Screen,2);
}
else
{
PrintScreen(PRINT_LearnBow,-1,-1,FONT_Screen,2);
};
return TRUE;
};
if(talent == NPC_TALENT_CROSSBOW)
{
B_RaiseFightTalent(oth,NPC_TALENT_CROSSBOW,percent);
if(oth.aivar[REAL_TALENT_CROSSBOW] >= (oth.aivar[REAL_TALENT_BOW] + 30))
{
B_RaiseFightTalent(oth,NPC_TALENT_BOW,percent);
PrintScreen(PRINT_LearnCrossbow_and_Bow,-1,-1,FONT_Screen,2);
}
else
{
PrintScreen(PRINT_LearnCrossbow,-1,-1,FONT_Screen,2);
};
return TRUE;
};
};

Wklejamy ją do skryptów G1 (ja umieściłem ją w pliku Story\B\B_GiveSkill.d, ale jeśli chcemy można utworzyć osobny plik na tą funkcję).

Pierwszym co edytujemy są linijki:

realHitChance = oth.HitChance[NPC_TALENT_1H];
realHitChance = oth.HitChance[NPC_TALENT_2H];
realHitChance = oth.HitChance[NPC_TALENT_BOW];
realHitChance = oth.HitChance[NPC_TALENT_CROSSBOW];

w G1 Hitchance nie istnieje, zmieniamy je więc na Npc_GetTalentValue (funkcja, która pobiera "wysokość skilla" danej umiejętności):

realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_1H);
realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_2H);
realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_BOW);
realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW);


Następna rzecz, którą zmieniamy są linijki:

concatText = ConcatStrings(PRINT_NoLearnOverPersonalMAX,IntToString(teacherMAX));
PrintScreen(concatText,-1,-1,FONT_Screen,2);

na:

concatText = ConcatStrings("Maksimum dla tego nauczyciela wynosi ",IntToString(teacherMAX));
PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",2);

Stała z tekstem PRINT_NoLearnOverPersonalMAX występuje tylko w G2, dlatego musimy albo dodać ją sami albo użyć w jej miejscu podobnej stałej z G1. Można też wpisać po prostu tekst w cudzysłowiu (ten sposób jest zaprezentowany na przykładzie).
Podobnie ma się sprawa ze stałą definiującą czcionkę. FONT_Screen nie występuje w G1 dlatego, od razu użyłem bezpośredniej nazwy czcionki "FONT_OLD_20_WHITE.TGA".

Z resztą przeniesionych stałych postępujemy podobnie.

Przejdźmy teraz do części funkcji odpowiedzialnej za podnoszenie umiejętności broni. Za przykład weźmy broń jednoręczną, pozostałe rodzaje broni zedytujemy analogicznie.

if(talent == NPC_TALENT_1H)
{
B_RaiseFightTalent(oth,NPC_TALENT_1H,percent);
if(oth.aivar[REAL_TALENT_1H] >= (oth.aivar[REAL_TALENT_2H] + 30))
{
B_RaiseFightTalent(oth,NPC_TALENT_2H,percent);
PrintScreen(PRINT_Learn1H_and_2H,-1,-1,FONT_Screen,2);
}
else
{
PrintScreen(PRINT_Learn1H,-1,-1,FONT_Screen,2);
};
return TRUE;
};

Widzimy, że do procentowego podnoszenia biegłości w danej broni używana jest kolejna funkcja: B_RaiseFightTalent. Oczywiście funkcja nie istnieje w G1, a przeniesienie jej było by trudne gdyż bazuje na nieobecnych w g1 aivarach. Dlatego posłużymy się obecną w G1 funkcją Npc_SetTalentValue.
Zastępujemy linijkę:

B_RaiseFightTalent(oth,NPC_TALENT_1H,percent);na:
Npc_SetTalentValue(hero, NPC_TALENT_1H, Npc_GetTalentValue(hero, NPC_TALENT_1H)+percent);

Teraz musimy edytować warunek, odpowiedzialny za automatyczny trening dwóch broni naraz. Zastępujemy linijkę:

if(oth.aivar[REAL_TALENT_1H] >= (oth.aivar[REAL_TALENT_2H] + 30))na:
if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= (Npc_GetTalentValue(hero,NPC_TALENT_2H) +30))
Potem analogicznie jak przedtem:

B_RaiseFightTalent(oth,NPC_TALENT_2H,percent);na:
Npc_SetTalentValue(hero, NPC_TALENT_2H, Npc_GetTalentValue(hero, NPC_TALENT_2H)+percent);
Znów dodajemy stałą z tekstem lub dopisujemy tekst sami, zmieniając:

PrintScreen(PRINT_Learn1H_and_2H,-1,-1,FONT_Screen,2);na:
PrintScreen("Trening: posługiwanie się bronią jedno- i dwuręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
oraz

PrintScreen(PRINT_Learn1H,-1,-1,FONT_Screen,2);na:
PrintScreen("Trening: posługiwanie się bronią jednoręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
To jednak jeszcze nie wszystko. Teraz musimy zadbać o to, aby zależnie od wartości procentowej w umiejętności, gra odpowiednio zwiększała jej poziom (zielony, wojownik, adept). Do tego celu dodamy nową funkcję B_SetFightSkill (wzorowana na podobnej funkcji z g2notr B_AddFightSkill).

func void B_SetFightSkill(var C_Npc slf,var int talent,var int percent)
{
if(talent == NPC_TALENT_1H)
{
if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 0)
{
Npc_SetTalentSkill(slf,NPC_TALENT_1H,0);
};
if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 30)
{
Npc_SetTalentSkill(slf,NPC_TALENT_1H,1);
};
if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 60)
{
Npc_SetTalentSkill(slf,NPC_TALENT_1H,2);
};
};
if(talent == NPC_TALENT_2H)
{
if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 0)
{
Npc_SetTalentSkill(slf,NPC_TALENT_2H,0);
};
if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 30)
{
Npc_SetTalentSkill(slf,NPC_TALENT_2H,1);
};
if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 60)
{
Npc_SetTalentSkill(slf,NPC_TALENT_2H,2);
};
};
if(talent == NPC_TALENT_BOW)
{
if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 0)
{
Npc_SetTalentSkill(slf,NPC_TALENT_BOW,0);
};
if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 30)
{
Npc_SetTalentSkill(slf,NPC_TALENT_BOW,1);
};
if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 60)
{
Npc_SetTalentSkill(slf,NPC_TALENT_BOW,2);
};
};
if(talent == NPC_TALENT_CROSSBOW)
{
if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 0)
{
Npc_SetTalentSkill(slf,NPC_TALENT_CROSSBOW,0);
};
if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 30)
{
Npc_SetTalentSkill(slf,NPC_TALENT_CROSSBOW,1);
};
if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 60)
{
Npc_SetTalentSkill(slf,NPC_TALENT_CROSSBOW,2);
};
};
};

Jak widać, funkcja sprawdza obecną wartość umiejętności i w zależności pod jaki próg się kwalifikuje, ustawia skill od 0, 1, 2 (czyli dla broni jednoręcznej będzie to odpowiednio: zielony, wojownik, mistrz).

Wracamy więc do naszej pierwszej funkcji (B_TeachFightTalentPercent)  i do warunku odpowiedzialnego za broń jednoręczną dodajemy na końcu:

B_SetFightSkill(hero,talent,percent);
Teraz po osiągnięciu 30% automatycznie powinniśmy uzyskać wojownika wraz ze zmienionymi animacjami ataku.

Pamiętajmy jednak, że w systemie nauki z nocy kruka istnieje możliwość nauki dwóch broni równocześnie, dlatego musimy wywołać funkcję jeszcze w jednym miejscu, tym razem definiując jaki talent ma podnieść (automatycznie wykrywany jest jedynie talent glowny, którego się uczymy):

B_SetFightSkill(hero,NPC_TALENT_2H,percent);
Całość odpowiedzialna za naukę broni jednoręcznej powinna wyglądać mniej więcej tak:

if(talent == NPC_TALENT_1H)
{
Npc_SetTalentValue(hero, NPC_TALENT_1H, Npc_GetTalentValue(hero, NPC_TALENT_1H)+percent);
if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= (Npc_GetTalentValue(hero,NPC_TALENT_2H) +30))
{
Npc_SetTalentValue(hero, NPC_TALENT_2H, Npc_GetTalentValue(hero, NPC_TALENT_2H)+percent);
B_SetFightSkill(hero,NPC_TALENT_2H,percent);
PrintScreen ("Trening: posługiwanie się bronią jedno- i dwuręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
}
else
{
PrintScreen ("Trening: posługiwanie się bronią jednoręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
};

B_SetFightSkill(hero,talent,percent);

return TRUE;
};

Analogicznie postępujemy z pozostałymi rodzajami broni. W efekcie cała funkcja powinna wyglądać tak:   

func int B_TeachFightTalentPercent(var C_Npc slf,var C_Npc oth,var int talent,var int percent,var int teacherMAX)
{
var string concatText;
var int kosten;
var int realHitChance;
kosten = B_GetLearnCostTalent(oth,talent,1) * percent;
if((talent != NPC_TALENT_1H) && (talent != NPC_TALENT_2H) && (talent != NPC_TALENT_BOW) && (talent != NPC_TALENT_CROSSBOW))
{
Print("*** Błąd: Zły parametr ***");
return FALSE;
};
if(talent == NPC_TALENT_1H)
{
realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_1H);
}
else if(talent == NPC_TALENT_2H)
{
realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_2H);
}
else if(talent == NPC_TALENT_BOW)
{
realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_BOW);
}
else if(talent == NPC_TALENT_CROSSBOW)
{
realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW);
};
if(realHitChance >= teacherMAX)
{
concatText = ConcatStrings("Maksimum dla tego nauczyciela wynosi ",IntToString(teacherMAX));
PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",2);
B_Say(slf,oth,"$NOLEARNYOUREBETTER");
return FALSE;
};
if((realHitChance + percent) > teacherMAX)
{
concatText = ConcatStrings("Maksimum dla tego nauczyciela wynosi ",IntToString(teacherMAX));
PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",2);
B_Say(slf,oth,"$NOLEARNOVERPERSONALMAX");
return FALSE;
};
if(oth.lp < kosten)
{
PrintScreen("Za mało punktów umiejętności!",-1,-1,"FONT_OLD_20_WHITE.TGA",2);
B_Say(slf,oth,"$NOLEARNNOPOINTS");
return FALSE;
};
oth.lp = oth.lp - kosten;
if(talent == NPC_TALENT_1H)
{
Npc_SetTalentValue(hero, NPC_TALENT_1H, Npc_GetTalentValue(hero, NPC_TALENT_1H)+percent);
if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= (Npc_GetTalentValue(hero,NPC_TALENT_2H) +30))
{
Npc_SetTalentValue(hero, NPC_TALENT_2H, Npc_GetTalentValue(hero, NPC_TALENT_2H)+percent);
PrintScreen("Trening: posługiwanie się bronią jedno- i dwuręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
B_SetFightSkill(hero,NPC_TALENT_2H,percent);
}
else
{
PrintScreen("Trening: posługiwanie się bronią jednoręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
};
B_SetFightSkill(hero,talent,percent);
return TRUE;
};
if(talent == NPC_TALENT_2H)
{
Npc_SetTalentValue(hero, NPC_TALENT_2H, Npc_GetTalentValue(hero, NPC_TALENT_2H)+percent);
if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= (Npc_GetTalentValue(hero,NPC_TALENT_1H) +30))
{
Npc_SetTalentValue(hero, NPC_TALENT_1H, Npc_GetTalentValue(hero, NPC_TALENT_1H)+percent);
B_SetFightSkill(hero,NPC_TALENT_1H,percent);
PrintScreen ("Trening: posługiwanie się bronią dwu- i jednoręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
}
else
{
PrintScreen ("Trening: posługiwanie się bronią dwuręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
};
B_SetFightSkill(hero,talent,percent);
return TRUE;
};
if(talent == NPC_TALENT_BOW)
{
Npc_SetTalentValue(hero, NPC_TALENT_BOW, Npc_GetTalentValue(hero, NPC_TALENT_BOW)+percent);
if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= (Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) +30))
{
Npc_SetTalentValue(hero, NPC_TALENT_CROSSBOW, Npc_GetTalentValue(hero, NPC_TALENT_CROSSBOW)+percent);
PrintScreen ("Trening: posługiwanie się łukiem i kuszą", -1,10,"FONT_OLD_20_WHITE.TGA",2);
B_SetFightSkill(hero,NPC_TALENT_CROSSBOW,percent);
}
else
{
PrintScreen ("Trening: posługiwanie się łukiem", -1,10,"FONT_OLD_20_WHITE.TGA",2);
};
B_SetFightSkill(hero,talent,percent);
return TRUE;
};
if(talent == NPC_TALENT_CROSSBOW)
{
Npc_SetTalentValue(hero, NPC_TALENT_CROSSBOW, Npc_GetTalentValue(hero, NPC_TALENT_CROSSBOW)+percent);
if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= (Npc_GetTalentValue(hero,NPC_TALENT_BOW) +30))
{
Npc_SetTalentValue(hero, NPC_TALENT_BOW, Npc_GetTalentValue(hero, NPC_TALENT_BOW)+percent);
B_SetFightSkill(hero,NPC_TALENT_BOW,percent);
PrintScreen ("Trening: posługiwanie się kuszą i łukiem", -1,10,"FONT_OLD_20_WHITE.TGA",2);
}
else
{
PrintScreen ("Trening: posługiwanie się kuszą", -1,10,"FONT_OLD_20_WHITE.TGA",2);
};
B_SetFightSkill(hero,talent,percent);
return TRUE;
};
};

Ostatnią funkcję, którą przeniesiemy z Nocy Kruka będzie funkcja odpowiedzialna za obliczanie kosztu punktów nauki. Funkcja ta nosi nazwę: B_GetLearnCostTalent

W Nocy Kruka jest ona bardzo rozbudowana, gdyż  oblicza koszt wszystkich umiejętności. Nas interesuje jedynie fragment odpowiedzialny za bronie. Oryginalna funkcja korzysta z hitchance i aivarów, więc tak jak poprzednio używamy zamiast tego funkcji z g1, Npc_GetTalentValue

Nie  ma sensu tłumaczyć drugi raz tego samego, zaprezentuje więc od razu całość:      

func int B_GetLearnCostTalent(var C_Npc oth,var int talent,var int skill)
{
var int kosten;
kosten = 0;
if(talent == NPC_TALENT_1H)
{
if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 90)
{
kosten = 4;
}
else if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 60)
{
kosten = 3;
}
else if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 30)
{
kosten = 2;
}
else
{
kosten = 1;
};
kosten = kosten * skill;
};
if(talent == NPC_TALENT_2H)
{
if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 90)
{
kosten = 4;
}
else if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 60)
{
kosten = 3;
}
else if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 30)
{
kosten = 2;
}
else
{
kosten = 1;
};

kosten = kosten * skill;
};
if(talent == NPC_TALENT_BOW)
{
if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 90)
{
kosten = 4;
}
else if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 60)
{
kosten = 3;
}
else if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 30)
{
kosten = 2;
}
else
{
kosten = 1;
};

kosten = kosten * skill;
};
if(talent == NPC_TALENT_CROSSBOW)
{
if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 90)
{
kosten = 4;
}
else if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 60)
{
kosten = 3;
}
else if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 30)
{
kosten = 2;
}
else
{
kosten = 1;
};

kosten = kosten * skill;
};
return kosten;
};
         

Wszystko powinno być jasne. Największa część pracy za nami. Teraz pozostało tylko parę szczegołów.

Musimy zmienić nazwy stopni władania bronią. Gothic 1 miał domyślnie ustawione dla wszystkich czterech rodzaji broni takie same poziomy brak, adept, mistrz. W g2 wygląda to inaczej. Otwieramy więc plik story\text.d i odnajdujemy linijkę: const string TXT_TALENTS_SKILLS[12]
Poniżej powinniśmy zobaczyć:
"",
"brak|adept|mistrz",
"brak|adept|mistrz",
"brak|adept|mistrz",
"brak|adept|mistrz",

Pierwszą pozycję zostawiamy pustą, a kolejne zmieniamy na:
"",
"Zielony|Wojownik|Mistrz",
"Zielony|Wojownik|Mistrz",
"Zielony|Łucznik|Mistrz",
"Zielony|Kusznik|Mistrz",

Pozostaje nam jeszcze ustawić poziom startowy umiejętności na 10% wzorem G2NK. W tym celu otwieramy plik Story\NPC\PC_Hero.d

Do instancji naszego bohatera (pierwsza z góry) dodajemy następujące linijki:
Npc_SetTalentValue(self, NPC_TALENT_1H,10);
Npc_SetTalentValue(self, NPC_TALENT_2H,10);
Npc_SetTalentValue(self, NPC_TALENT_BOW,10);
Npc_SetTalentValue(self, NPC_TALENT_CROSSBOW,10);
   
To właściwie tyle. Podam jeszcze przykład jak powinien wyglądać skrypt dialogu u trenera, wykorzystujący system nauki jaki zaimplementowaliśmy. Polecam wykorzystać do tego character helpera, by szybko przekonać się czy wszystko gra.
Otwieramy plik AI\Test_Scripts\CharacterHelper.d i wklejamy poniższy kod.

instance CH_Training_NotRCombat(C_Info)
{
npc = ch;
condition = CH_Training_NotRCombat_Condition;
information = CH_Training_NotRCombat_Info;
important = 0;
permanent = 1;
description = "TALENT: Walka Notr";
};


func int CH_Training_NotRCombat_Condition()
{
return TRUE;
};

func void CH_Training_NotRCombat_Info()
{
Info_ClearChoices(CH_Training_NotRCombat);
Info_AddChoice(CH_Training_NotRCombat,"Wróć",CH_Training_NotRCombat_BACK);

Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);

};


func void CH_Training_NotRCombat_1H_1()
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_1H,1,100);
Info_ClearChoices(CH_Training_NotRCombat);
Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_1H_5()
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_1H,5,100);
Info_ClearChoices(CH_Training_NotRCombat);
Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_2H_1()
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_2H,1,100);
Info_ClearChoices(CH_Training_NotRCombat);
Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_2H_5()
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_2H,5,100);
Info_ClearChoices(CH_Training_NotRCombat);
Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_Bow_1()
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_BOW,1,100);
Info_ClearChoices(CH_Training_NotRCombat);
Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_Bow_5()
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_BOW,5,100);
Info_ClearChoices(CH_Training_NotRCombat);
Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_Crossbow_1()
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_CROSSBOW,1,100);
Info_ClearChoices(CH_Training_NotRCombat);
Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_Crossbow_5()
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_CROSSBOW,5,100);
Info_ClearChoices(CH_Training_NotRCombat);
Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};


func void CH_Training_NotRCombat_BACK()
{
Info_ClearChoices(CH_Training_NotRCombat);
};

Następnie kompilujemy skrypty, odpalamy nową grę, włączamy konsole i przyzywamy character helpera komendą: "insert CH".
Ustawiamy sobie jeszcze Punkty Nauki (wpisujemy edit abilities w konsoli, a potem lp = 60), po czym rozmawiamy z przyzwaną postacią. Wybieramy dialog "TALENT: Walka Notr" i sprawdzamy jak działa system walki, który zaimplementowaliśmy.


2. Część druga - atrybuty

Część pierwsza za nami, teraz pora na część drugą, czyli przeniesienie systemu nauki atrybutów. Interesuje nas funkcja B_TeachAttributePoints, w nocy kruka wygląda ona tak:

func int B_TeachAttributePoints(var C_Npc slf,var C_Npc oth,var int attrib,var int points,var int teacherMAX)
{
var string concatText;
var int kosten;
var int realAttribute;
kosten = B_GetLearnCostAttribute(oth,attrib) * points;
if((attrib != ATR_STRENGTH) && (attrib != ATR_DEXTERITY) && (attrib != ATR_MANA_MAX))
{
Print("*** Błąd: Zły parametr ***");
return FALSE;
};
if(attrib == ATR_STRENGTH)
{
realAttribute = oth.attribute[ATR_STRENGTH];
}
else if(attrib == ATR_DEXTERITY)
{
realAttribute = oth.attribute[ATR_DEXTERITY];
}
else if(attrib == ATR_MANA_MAX)
{
realAttribute = oth.attribute[ATR_MANA_MAX];
};
if(realAttribute >= teacherMAX)
{
concatText = ConcatStrings(PRINT_NoLearnOverPersonalMAX,IntToString(teacherMAX));
PrintScreen(concatText,-1,-1,FONT_Screen,2);
B_Say(slf,oth,"$NOLEARNYOUREBETTER");
return FALSE;
};
if((realAttribute + points) > teacherMAX)
{
concatText = ConcatStrings(PRINT_NoLearnOverPersonalMAX,IntToString(teacherMAX));
PrintScreen(concatText,-1,-1,FONT_Screen,2);
B_Say(slf,oth,"$NOLEARNOVERPERSONALMAX");
return FALSE;
};
if(oth.lp < kosten)
{
PrintScreen(PRINT_NotEnoughLP,-1,-1,FONT_Screen,2);
B_Say(slf,oth,"$NOLEARNNOPOINTS");
return FALSE;
};
oth.lp = oth.lp - kosten;
B_RaiseAttribute(oth,attrib,points);
return TRUE;
};

Kopiujemy ją i umieszczamy np. w story\b\b_buyattributepoints.d
Nie musimy tutaj za dużo zmieniać, interesują nas stałe, odpowiadające za wyswietlany tekst oraz wywołanie funkcji B_RaiseAttribute.
Ta co prawda wystepuje już w G1, jednak rózni się nieco od tej z g2, dlatego najlepiej będzie jesli zamiast ją zastępowac, bądź edytować dodamy drugą o lekko zmienionej nazwie, powiedzmy B_RaiseAttribute_Gothic2

Zmieńmy więc jej nazwę w funkcji b_buyattributepoints:

func int B_TeachAttributePoints(var C_Npc slf,var C_Npc oth,var int attrib,var int points,var int teacherMAX)
{
var string concatText;
var int kosten;
var int realAttribute;
kosten = B_GetLearnCostAttribute(oth,attrib) * points;
if((attrib != ATR_STRENGTH) && (attrib != ATR_DEXTERITY) && (attrib != ATR_MANA_MAX))
{
Print("*** Błąd: Zły parametr ***");
return FALSE;
};
if(attrib == ATR_STRENGTH)
{
realAttribute = oth.attribute[ATR_STRENGTH];
}
else if(attrib == ATR_DEXTERITY)
{
realAttribute = oth.attribute[ATR_DEXTERITY];
}
else if(attrib == ATR_MANA_MAX)
{
realAttribute = oth.attribute[ATR_MANA_MAX];
};
if(realAttribute >= teacherMAX)
{
concatText = ConcatStrings("Maksimum dla tego nauczyciela wynosi ",IntToString(teacherMAX));
PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",2);
B_Say(slf,oth,"$NOLEARNYOUREBETTER");
return FALSE;
};
if((realAttribute + points) > teacherMAX)
{
concatText = ConcatStrings("Maksimum dla tego nauczyciela wynosi ",IntToString(teacherMAX));
PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",2);
B_Say(slf,oth,"$NOLEARNOVERPERSONALMAX");
return FALSE;
};
if(oth.lp < kosten)
{
PrintScreen("Za mało Punktów Nauki!",-1,-1,"FONT_OLD_20_WHITE.TGA",2);
B_Say(slf,oth,"$NOLEARNNOPOINTS");
return FALSE;
};
oth.lp = oth.lp - kosten;
B_RaiseAttribute_Gothic2(oth,attrib,points);
return TRUE;
};

I przejdzmy do funkcji B_RaiseAttribute.

func void B_RaiseAttribute(var C_Npc oth,var int attrib,var int points)
{
var string concatText;
if(attrib == ATR_STRENGTH)
{
oth.attribute[ATR_STRENGTH] = oth.attribute[ATR_STRENGTH] + points;
concatText = ConcatStrings(PRINT_LearnSTR,IntToString(points));
PrintScreen(concatText,-1,-1,FONT_Screen,2);
};
if(attrib == ATR_DEXTERITY)
{
oth.attribute[ATR_DEXTERITY] = oth.attribute[ATR_DEXTERITY] + points;
if((oth.attribute[ATR_DEXTERITY] >= 90) && (Npc_GetTalentSkill(oth,NPC_TALENT_ACROBAT) == 0))
{
Npc_SetTalentSkill(oth,NPC_TALENT_ACROBAT,1);
PrintScreen(PRINT_Addon_AcrobatBonus,-1,55,FONT_Screen,2);
};
concatText = ConcatStrings(PRINT_LearnDEX,IntToString(points));
PrintScreen(concatText,-1,-1,FONT_Screen,2);
};
if(attrib == ATR_MANA_MAX)
{
oth.attribute[ATR_MANA_MAX] = oth.attribute[ATR_MANA_MAX] + points;
concatText = ConcatStrings(PRINT_LearnMANA_MAX,IntToString(points));
PrintScreen(concatText,-1,-1,FONT_Screen,2);
};
if(attrib == ATR_HITPOINTS_MAX)
{
oth.attribute[ATR_HITPOINTS_MAX] = oth.attribute[ATR_HITPOINTS_MAX] + points;
concatText = ConcatStrings(PRINT_Learnhitpoints_MAX,IntToString(points));
PrintScreen(concatText,-1,-1,FONT_Screen,2);
};
B_RaiseRealAttributeLearnCounter(oth,attrib,points);
};

Tu również zmieniamy jej nazwę na B_RaiseAttribute_Gothic2. Widzimy też, że wywoluje ona kolejna funkcje B_raiserealattributelearncounter.

Służy ona do liczenia prawdziwych wartości atrybutów (bez bonusów), jedak z racji tego, że opiera się ona na aivarach z g2, my z niej zrezygnujemy i będziemy opierać się po prostu na obecnych statystykach gracza.
Niestety rozwiązanie ten ma tę wadę, że w przypadku, gdy gracz założony będzie mieć przedmiot podnoszący atrybut, gra nie będzie w stanie rozróżnić, jaką wartość ma tenże atrybut "na czysto" (bez dodatkowego bonusu), co będzie skutkować w obliczaniu progów wliczając w nie dodatkowy bonus. Jeśli bardzo chcemy problem ten można oczywiście ominąć, np. wprowadzając własne zmienne i licząc na nich osobno aytrubuty przy nauce, ale to już zostawiam chętnym do własnej realizacji.
My nie będziemy sobie tutaj tego komplikować i z poprawiania tej funkcji po prostu zrezygnujemy.

Usuwamy więc (bądź zakomentowujemy) wywolanie funkcji B_RaiseRealAttributeLearnCounter. Tradycyjnie znowu też poprawiamy zmienne odpowiedzialne za tekst.
Usuwamy też warunek odpowiedzialny za automatyczną naukę akrobatyki po osiągnięciu 90 zręczności (chyba, że chcemy by tak to zostało) i otrzymujemy:

func void B_RaiseAttribute_Gothic2(var C_Npc oth,var int attrib,var int points)
{
var string concatText;
if(attrib == ATR_STRENGTH)
{
oth.attribute[ATR_STRENGTH] = oth.attribute[ATR_STRENGTH] + points;
concatText = ConcatStrings(NAME_RaiseStrength,IntToString(points));
PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",4);
};
if(attrib == ATR_DEXTERITY)
{
oth.attribute[ATR_DEXTERITY] = oth.attribute[ATR_DEXTERITY] + points;
concatText = ConcatStrings(NAME_RaiseDexterity,IntToString(points));
PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",4);
};
if(attrib == ATR_MANA_MAX)
{
oth.attribute[ATR_MANA_MAX] = oth.attribute[ATR_MANA_MAX] + points;
concatText = ConcatStrings(NAME_RaiseManaMax,IntToString(points));
PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",4);
};
if(attrib == ATR_HITPOINTS_MAX)
{
oth.attribute[ATR_HITPOINTS_MAX] = oth.attribute[ATR_HITPOINTS_MAX] + points;
concatText = ConcatStrings(NAME_RaiseHealthMax,IntToString(points));
PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",4);
};
//B_RaiseRealAttributeLearnCounter(oth,attrib,points);
};


Następnie dodajemy funkcję liczącą koszt Pn atrybutów: B_GetLearnCostAttribute

func int B_GetLearnCostAttribute(var C_Npc oth,var int attribut)
{
var int kosten;
kosten = 0;
if(attribut == ATR_STRENGTH)
{
if(oth.aivar[REAL_STRENGTH] >= 120)
{
kosten = 5;
}
else if(oth.aivar[REAL_STRENGTH] >= 90)
{
kosten = 4;
}
else if(oth.aivar[REAL_STRENGTH] >= 60)
{
kosten = 3;
}
else if(oth.aivar[REAL_STRENGTH] >= 30)
{
kosten = 2;
}
else
{
kosten = 1;
};
};
if(attribut == ATR_DEXTERITY)
{
if(oth.aivar[REAL_DEXTERITY] >= 120)
{
kosten = 5;
}
else if(oth.aivar[REAL_DEXTERITY] >= 90)
{
kosten = 4;
}
else if(oth.aivar[REAL_DEXTERITY] >= 60)
{
kosten = 3;
}
else if(oth.aivar[REAL_DEXTERITY] >= 30)
{
kosten = 2;
}
else
{
kosten = 1;
};
};
if(attribut == ATR_MANA_MAX)
{
if(oth.aivar[REAL_MANA_MAX] >= 120)
{
kosten = 5;
}
else if(oth.aivar[REAL_MANA_MAX] >= 90)
{
kosten = 4;
}
else if(oth.aivar[REAL_MANA_MAX] >= 60)
{
kosten = 3;
}
else if(oth.aivar[REAL_MANA_MAX] >= 30)
{
kosten = 2;
}
else
{
kosten = 1;
};
};
return kosten;
};

W funkcji tej musimy pozmieniac wszystkie linijki zawierające odniesienia do aivarów określających prawdziwą wartość atrybutu, czyli np.

if(oth.aivar[REAL_STRENGTH] >= 120)
zmieniamy na :

if(oth.attribute[ATR_STRENGTH] >= 120)

Po poprawieniu wszystkich linijek powinniśmy mieć taki fragment kodu:

func int B_GetLearnCostAttribute(var C_Npc oth,var int attribut)
{
var int kosten;
kosten = 0;
if(attribut == ATR_STRENGTH)
{
if(oth.attribute[ATR_STRENGTH] >= 120)
{
kosten = 5;
}
else if(oth.attribute[ATR_STRENGTH] >= 90)
{
kosten = 4;
}
else if(oth.attribute[ATR_STRENGTH] >= 60)
{
kosten = 3;
}
else if(oth.attribute[ATR_STRENGTH] >= 30)
{
kosten = 2;
}
else
{
kosten = 1;
};
};
if(attribut == ATR_DEXTERITY)
{
if(oth.attribute[ATR_DEXTERITY] >= 120)
{
kosten = 5;
}
else if(oth.attribute[ATR_DEXTERITY] >= 90)
{
kosten = 4;
}
else if(oth.attribute[ATR_DEXTERITY] >= 60)
{
kosten = 3;
}
else if(oth.attribute[ATR_DEXTERITY] >= 30)
{
kosten = 2;
}
else
{
kosten = 1;
};
};
if(attribut == ATR_MANA_MAX)
{
if(oth.attribute[ATR_MANA_MAX] >= 120)
{
kosten = 5;
}
else if(oth.attribute[ATR_MANA_MAX] >= 90)
{
kosten = 4;
}
else if(oth.attribute[ATR_MANA_MAX] >= 60)
{
kosten = 3;
}
else if(oth.attribute[ATR_MANA_MAX] >= 30)
{
kosten = 2;
}
else
{
kosten = 1;
};
};
return kosten;
};


I to w zasadzie wszystko. Podobnie jak poprzednio podam jeszcze przyklad wykorzystanie systemu nauki w dialogu trenera. Znów posłużymy się do tego celu character helperem.

instance CH_Training_NotRAttributes(C_Info)
{
npc = ch;
condition = CH_Training_NotRAttributes_Condition;
information = CH_Training_NotRAttributes_Info;
important = 0;
permanent = 1;
description = "ATRYBUTY: NotR";
};


func int CH_Training_NotRAttributes_Condition()
{
return TRUE;
};

func void CH_Training_NotRAttributes_Info()
{
Info_ClearChoices(CH_Training_NotRAttributes);
Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);

Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);

};

func void CH_Training_NotRAttributes_STR_1()
{
B_TeachAttributePoints(self,other,ATR_STRENGTH,1,100);
Info_ClearChoices(CH_Training_NotRAttributes);
Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);

Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_STR_5()
{
B_TeachAttributePoints(self,other,ATR_STRENGTH,5,100);
Info_ClearChoices(CH_Training_NotRAttributes);
Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);

Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_DEX_1()
{
B_TeachAttributePoints(self,other,ATR_DEXTERITY,1,100);
Info_ClearChoices(CH_Training_NotRAttributes);
Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);

Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_DEX_5()
{
B_TeachAttributePoints(self,other,ATR_DEXTERITY,5,100);
Info_ClearChoices(CH_Training_NotRAttributes);
Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);

Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_MAN_1()
{
B_TeachAttributePoints(self,other,ATR_MANA_MAX,1,100);
Info_ClearChoices(CH_Training_NotRAttributes);
Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);

Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_MAN_5()
{
B_TeachAttributePoints(self,other,ATR_MANA_MAX,5,100);
Info_ClearChoices(CH_Training_NotRAttributes);
Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);

Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_BACK()
{
Info_ClearChoices(CH_Training_NotRAttributes);
};

Kirgo2

Kirgo2

Użytkownicy
posty10
Propsy3
ProfesjaGracz
  • Użytkownicy
Prosiłbym o pomoc bo już od kilku dni próbuję dodać ten system nauki do gry i nie mogę znaleźć przyczyny dla której to się nie udaje.

Po wklejeniu wskazanych w tutorialu rzeczy, wchodzę w spacera, biorę Tools->Reparse Scriptfiles i... wyskakuje miliard błędów. Pierwszy z nich to:
U:PAR Undefined function: B_GETLEARNCOSTATTRIBUTE (line 56)

Dużo jest właśnie błędów "Undefined function" z B_(nazwa kolejnych wklejonych funkcji). Próbowałem nawet wkleić każdą z tych funkcji do oddzielnego pliku .d w folderze Gothic\_work\DATA\scripts\Content\Story ale to nic nie dało.

Bardzo prosiłbym o pomoc - jestem bardziej graczem, który chce trochę zmodyfikować Gothica pod swoim kontem niż modderem i dopiero zaczynam swoją przygodę z edycją skryptów, więc pewnie coś przeoczyłem albo nie uwzględniłem jakiejś oczywistości, która nie jest aż tak oczywista dla świeżaków w tej dziedzinie.

Tak wygląda mój plik Gothic\_work\DATA\scripts\Content\Story\B\B_GiveSkill.d
Przekleiłem do niego funkcje:
- B_TeachFightTalentPercent
- B_SetFightSkill
- B_GetLearnCostTalent

Spoiler
func int B_GiveSkill(var C_NPC typ, var int TAL, var int NEW_Wert, var int LP_Cost) //return 1
{
   // ---------- Umwandeln von var in const
   var int TAL_Wert;
   if       (TAL == NPC_TALENT_1H)         {   TAL_Wert = Npc_GetTalentSkill(typ, NPC_TALENT_1H      );   }
   else if (TAL == NPC_TALENT_2H)         {   TAL_Wert = Npc_GetTalentSkill(typ, NPC_TALENT_2H      );   }
   else if (TAL == NPC_TALENT_BOW)         {   TAL_Wert = Npc_GetTalentSkill(typ, NPC_TALENT_BOW      );   }
   else if (TAL == NPC_TALENT_CROSSBOW)   {   TAL_Wert = Npc_GetTalentSkill(typ, NPC_TALENT_CROSSBOW   );   }
   else if (TAL == NPC_TALENT_PICKLOCK)   {   TAL_Wert = Npc_GetTalentSkill(typ, NPC_TALENT_PICKLOCK   );   }
   else if (TAL == NPC_TALENT_PICKPOCKET)   {   TAL_Wert = Npc_GetTalentSkill(typ, NPC_TALENT_PICKPOCKET);   }
   else if (TAL == NPC_TALENT_MAGE)      {   TAL_Wert = Npc_GetTalentSkill(typ, NPC_TALENT_MAGE      );   }
   else if (TAL == NPC_TALENT_SNEAK)      {   TAL_Wert = Npc_GetTalentSkill(typ, NPC_TALENT_SNEAK      );   }
   else if (TAL == NPC_TALENT_REGENERATE)   {   TAL_Wert = Npc_GetTalentSkill(typ, NPC_TALENT_REGENERATE);   }
   else if (TAL == NPC_TALENT_FIREMASTER)   {   TAL_Wert = Npc_GetTalentSkill(typ, NPC_TALENT_FIREMASTER);   }
   else if (TAL == NPC_TALENT_ACROBAT)      {   TAL_Wert = Npc_GetTalentSkill(typ, NPC_TALENT_ACROBAT   );   };

   // ----------- Bedingungen/LP checken, dann ggf. vergeben
   if ((TAL_Wert+1) == NEW_Wert)
   {   
      if (typ.lp >= LP_cost)
      {
         typ.lp = typ.lp - LP_cost;
         
         if (tal == NPC_TALENT_1H)         
         {   
            Npc_SetTalentSkill(typ, NPC_TALENT_1H, NEW_Wert);
            Npc_SetTalentValue(typ, NPC_TALENT_1H, Npc_GetTalentValue(typ, NPC_TALENT_1H)+5);
            PrintScreen   ("Nowa umiejętność: Walka jednoręcznym orężem", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
            return 1;
         }
         else if (tal == NPC_TALENT_2H)
         {
            Npc_SetTalentSkill(typ, NPC_TALENT_2H, NEW_Wert);
            Npc_SetTalentValue(typ, NPC_TALENT_2H, Npc_GetTalentValue(typ, NPC_TALENT_2H)+5);
            PrintScreen   ("Nowa umiejętność: Walka dwuręcznym orężem", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
            return 1;
         }
         else if (tal == NPC_TALENT_BOW)
         {
            Npc_SetTalentSkill(typ, NPC_TALENT_BOW, NEW_Wert);
            Npc_SetTalentValue(typ, NPC_TALENT_BOW, Npc_GetTalentValue(typ, NPC_TALENT_BOW)+15);
            PrintScreen   ("Nowa umiejętność: Strzelanie z łuku", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
            return 1;
         }
         else if (tal == NPC_TALENT_CROSSBOW)
         {
            Npc_SetTalentSkill(typ, NPC_TALENT_CROSSBOW, NEW_Wert);
            Npc_SetTalentValue(typ, NPC_TALENT_CROSSBOW, Npc_GetTalentValue(typ, NPC_TALENT_CROSSBOW)+20);
            PrintScreen   ("Nowa umiejętność: Strzelanie z kuszy", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
            return 1;
         }
         else if (tal == NPC_TALENT_PICKLOCK)
         {
            Npc_SetTalentSkill(typ, NPC_TALENT_PICKLOCK, NEW_Wert);
            Npc_SetTalentValue(typ, NPC_TALENT_PICKLOCK, Npc_GetTalentValue(typ, NPC_TALENT_PICKLOCK)-40);
            PrintScreen   ("Nowa umiejętność: Otwieranie zamków", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
            return 1;
         }
         else if (tal == NPC_TALENT_PICKPOCKET)
         {
            Npc_SetTalentSkill(typ, NPC_TALENT_PICKPOCKET, NEW_Wert);
            Npc_SetTalentValue(typ, NPC_TALENT_PICKPOCKET, Npc_GetTalentValue(typ, NPC_TALENT_PICKPOCKET)-40);
            PrintScreen   ("Nowa umiejętność: Kradzież kieszonkowa", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
            return 1;
         }
         else if (tal == NPC_TALENT_MAGE)
         {
            Npc_SetTalentSkill(typ, NPC_TALENT_MAGE, NEW_Wert);
            PrintScreen   ("Nowa umiejętność: Kolejny krąg magii", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
            return 1;
         }
         else if (tal == NPC_TALENT_SNEAK)
         {
            Npc_SetTalentSkill(typ, NPC_TALENT_SNEAK, NEW_Wert);
            PrintScreen   ("Nowa umiejętność: Skradanie się", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
            return 1;
         }
         else if (tal == NPC_TALENT_REGENERATE)
         {
            Npc_SetTalentSkill(typ, NPC_TALENT_REGENERATE, NEW_Wert);
            PrintScreen   ("Zwiększone tempo regeneracji", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
            return 1;
         }
         else if (tal == NPC_TALENT_FIREMASTER)
         {
            Npc_SetTalentSkill(typ, NPC_TALENT_FIREMASTER, NEW_Wert);
            PrintScreen   ("Nowa umiejętność: Mistrz Ognia", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
            return 1;
         }
         else if (tal == NPC_TALENT_ACROBAT)
         {
            Npc_SetTalentSkill(typ, NPC_TALENT_ACROBAT, NEW_Wert);
            PrintScreen   ("Nowa umiejętność: Akrobatyka", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
            return 1;
         }
         else
         {
            return 0;
         };
      }
      else
      {
         PrintScreen   ("Za mało punktów umiejętności!", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
         B_Say (self, other, "$NOLEARNNOPOINTS");
         return 0;
      };
   }
   else // NICHT eine Stufe davor
   {   
      if (TAL_Wert >= NEW_Wert)
      {
         B_Say (self, other, "$NOLEARNYOUREBETTER"); //Jesteś już lepszy!
         return 0;
      }
      else if ((TAL_Wert+1) < NEW_Wert) //d.h. i.d.R. TAL_Wert=2 und NEW_Wert=0, außer bei TALENT_MAGE
      {
         B_Say (self, other, "$NOLEARNYOUALREADYKNOW"); //Musisz się jeszcze wiele nauczyć zanim zostaniesz Mistrzem!
         return 0;
      };
   };   
};   

func int B_TeachFightTalentPercent(var C_Npc slf,var C_Npc oth,var int talent,var int percent,var int teacherMAX)
{
   var string concatText;
   var int kosten;
   var int realHitChance;
   kosten = B_GetLearnCostTalent(oth,talent,1) * percent;
   if((talent != NPC_TALENT_1H) && (talent != NPC_TALENT_2H) && (talent != NPC_TALENT_BOW) && (talent != NPC_TALENT_CROSSBOW))
   {
      Print("*** Błąd: Zły parametr ***");
      return FALSE;
   };
   if(talent == NPC_TALENT_1H)
   {
      realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_1H);
   }
   else if(talent == NPC_TALENT_2H)
   {
      realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_2H);
   }
   else if(talent == NPC_TALENT_BOW)
   {
      realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_BOW);
   }
   else if(talent == NPC_TALENT_CROSSBOW)
   {
      realHitChance = Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW);
   };
   if(realHitChance >= teacherMAX)
   {
      concatText = ConcatStrings("Maksimum dla tego nauczyciela wynosi ",IntToString(teacherMAX));
      PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",2);
      B_Say(slf,oth,"$NOLEARNYOUREBETTER");
      return FALSE;
   };
   if((realHitChance + percent) > teacherMAX)
   {
      concatText = ConcatStrings("Maksimum dla tego nauczyciela wynosi ",IntToString(teacherMAX));
      PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",2);
      B_Say(slf,oth,"$NOLEARNOVERPERSONALMAX");
      return FALSE;
   };
   if(oth.lp < kosten)
   {
      PrintScreen("Za mało punktów umiejętności!",-1,-1,"FONT_OLD_20_WHITE.TGA",2);
      B_Say(slf,oth,"$NOLEARNNOPOINTS");
      return FALSE;
   };
   oth.lp = oth.lp - kosten;
   if(talent == NPC_TALENT_1H)
   {
      Npc_SetTalentValue(hero, NPC_TALENT_1H, Npc_GetTalentValue(hero, NPC_TALENT_1H)+percent);
      if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= (Npc_GetTalentValue(hero,NPC_TALENT_2H) +30))
      {
         Npc_SetTalentValue(hero, NPC_TALENT_2H, Npc_GetTalentValue(hero, NPC_TALENT_2H)+percent);
         PrintScreen("Trening: posługiwanie się bronią jedno- i dwuręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
         B_SetFightSkill(hero,NPC_TALENT_2H,percent);
      }
      else
      {
         PrintScreen("Trening: posługiwanie się bronią jednoręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
      };
      B_SetFightSkill(hero,talent,percent);
      return TRUE;
   };
   if(talent == NPC_TALENT_2H)
   {
      Npc_SetTalentValue(hero, NPC_TALENT_2H, Npc_GetTalentValue(hero, NPC_TALENT_2H)+percent);   
      if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= (Npc_GetTalentValue(hero,NPC_TALENT_1H) +30))   
      {
         Npc_SetTalentValue(hero, NPC_TALENT_1H, Npc_GetTalentValue(hero, NPC_TALENT_1H)+percent);
         B_SetFightSkill(hero,NPC_TALENT_1H,percent);
         PrintScreen   ("Trening: posługiwanie się bronią dwu- i jednoręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
      }
      else
      {
         PrintScreen   ("Trening: posługiwanie się bronią dwuręczną", -1,10,"FONT_OLD_20_WHITE.TGA",2);
      };
      B_SetFightSkill(hero,talent,percent);
      return TRUE;
   };
   if(talent == NPC_TALENT_BOW)
   {
      Npc_SetTalentValue(hero, NPC_TALENT_BOW, Npc_GetTalentValue(hero, NPC_TALENT_BOW)+percent);
      if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= (Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) +30))   
      {
         Npc_SetTalentValue(hero, NPC_TALENT_CROSSBOW, Npc_GetTalentValue(hero, NPC_TALENT_CROSSBOW)+percent);
         PrintScreen   ("Trening: posługiwanie się łukiem i kuszą", -1,10,"FONT_OLD_20_WHITE.TGA",2);
         B_SetFightSkill(hero,NPC_TALENT_CROSSBOW,percent);
      }
      else
      {
         PrintScreen   ("Trening: posługiwanie się łukiem", -1,10,"FONT_OLD_20_WHITE.TGA",2);
      };
      B_SetFightSkill(hero,talent,percent);
      return TRUE;
   };
   if(talent == NPC_TALENT_CROSSBOW)
   {
      Npc_SetTalentValue(hero, NPC_TALENT_CROSSBOW, Npc_GetTalentValue(hero, NPC_TALENT_CROSSBOW)+percent);
      if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= (Npc_GetTalentValue(hero,NPC_TALENT_BOW) +30))   
      {
         Npc_SetTalentValue(hero, NPC_TALENT_BOW, Npc_GetTalentValue(hero, NPC_TALENT_BOW)+percent);
         B_SetFightSkill(hero,NPC_TALENT_BOW,percent);
         PrintScreen   ("Trening: posługiwanie się kuszą i łukiem", -1,10,"FONT_OLD_20_WHITE.TGA",2);         
      }
      else
      {
         PrintScreen   ("Trening: posługiwanie się kuszą", -1,10,"FONT_OLD_20_WHITE.TGA",2);
      };
      B_SetFightSkill(hero,talent,percent);
      return TRUE;
   };
};

func void B_SetFightSkill(var C_Npc slf,var int talent,var int percent)
{
   if(talent == NPC_TALENT_1H)
   {
      if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 0)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_1H,0);
      };
      if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 30)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_1H,1);
      };
      if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 60)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_1H,2);
      };
   };
   if(talent == NPC_TALENT_2H)
   {
      if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 0)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_2H,0);
      };
      if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 30)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_2H,1);
      };
      if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 60)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_2H,2);
      };
   };
   if(talent == NPC_TALENT_BOW)
   {
      if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 0)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_BOW,0);
      };
      if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 30)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_BOW,1);
      };
      if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 60)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_BOW,2);
      };
   };
   if(talent == NPC_TALENT_CROSSBOW)
   {
      if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 0)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_CROSSBOW,0);
      };
      if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 30)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_CROSSBOW,1);
      };
      if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 60)
      {
         Npc_SetTalentSkill(slf,NPC_TALENT_CROSSBOW,2);
      };
   };
};

func int B_GetLearnCostTalent(var C_Npc oth,var int talent,var int skill)
{
   var int kosten;
   kosten = 0;
   if(talent == NPC_TALENT_1H)
   {
      if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 90)
      {
         kosten = 4;
      }
      else if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 60)
      {
         kosten = 3;
      }
      else if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 30)
      {
         kosten = 2;
      }
      else
      {
         kosten = 1;
      };
      kosten = kosten * skill;
   };
   if(talent == NPC_TALENT_2H)
   {
      if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 90)
      {
         kosten = 4;
      }
      else if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 60)
      {
         kosten = 3;
      }
      else if(Npc_GetTalentValue(hero,NPC_TALENT_2H) >= 30)
      {
         kosten = 2;
      }
      else
      {
         kosten = 1;
      };
      
      kosten = kosten * skill;
   };
   if(talent == NPC_TALENT_BOW)
   {
      if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 90)
      {
         kosten = 4;
      }
      else if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 60)
      {
         kosten = 3;
      }
      else if(Npc_GetTalentValue(hero,NPC_TALENT_BOW) >= 30)
      {
         kosten = 2;
      }
      else
      {
         kosten = 1;
      };
      
      kosten = kosten * skill;
   };
   if(talent == NPC_TALENT_CROSSBOW)
   {
      if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 90)
      {
         kosten = 4;
      }
      else if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 60)
      {
         kosten = 3;
      }
      else if(Npc_GetTalentValue(hero,NPC_TALENT_CROSSBOW) >= 30)
      {
         kosten = 2;
      }
      else
      {
         kosten = 1;
      };
      
      kosten = kosten * skill;
   };   
   return kosten;
};


Tak wygląda mój plik Gothic\_work\DATA\scripts\Content\Story\B_BuyAttributePoints.d
Przekleiłem do niego funkcje:
- B_TeachAttributePoints
- B_RaiseAttribute_Gothic2
- B_GetLearnCostAttribute

Spoiler
func void B_BuyAttributePoints (var C_NPC typ, var int ATR, var int AtrPlus)
{
   // --------- Umwandeln von var in const
   var int Typ_Atr;
   if       (ATR == ATR_STRENGTH)   {   Typ_Atr = typ.attribute[ATR_STRENGTH];   }
   else if (ATR == ATR_DEXTERITY)   {   Typ_Atr = typ.attribute[ATR_DEXTERITY];   }
   else if (ATR == ATR_MANA_MAX)   {   Typ_Atr = typ.attribute[ATR_MANA_MAX];   };
   
   // --------- Steigern oder verbieten   
   var string AtrPlusSTRING; AtrPlusSTRING   = IntToString(AtrPlus);
   var string PrintSTRING;
   
   if (!(typ.lp < AtrPlus))
   {
      if (Typ_Atr + AtrPlus <= 100)
      {   
         typ.lp = typ.lp - AtrPlus;
                  
         if (ATR == ATR_STRENGTH)
         {
            typ.attribute[ATR_STRENGTH] = typ.attribute[ATR_STRENGTH] + AtrPlus;
            PrintString = ConcatStrings(NAME_BuyAttributeSTR, AtrPlusSTRING);
            PrintScreen   (PrintSTRING, -1,-1,"FONT_OLD_20_WHITE.TGA",1);
         }
         else if (ATR == ATR_DEXTERITY)
         {
            typ.attribute[ATR_DEXTERITY] = typ.attribute[ATR_DEXTERITY] + AtrPlus;
            PrintString = ConcatStrings(NAME_BuyAttributeDEX, AtrPlusSTRING);
            PrintScreen   (PrintSTRING, -1,-1,"FONT_OLD_20_WHITE.TGA",1);
         }
         else if (ATR == ATR_MANA_MAX)
         {
            typ.attribute[ATR_MANA_MAX] = typ.attribute[ATR_MANA_MAX] + AtrPlus;
            PrintString = ConcatStrings(NAME_BuyAttributeMAN, AtrPlusSTRING);
            PrintScreen   (PrintString, -1,-1,"FONT_OLD_20_WHITE.TGA",1);
         };
      }
      else
      {
         PrintScreen   ("100 punktów to wartość maksymalna!", -1,-1,"FONT_OLD_20_WHITE.TGA",1);
         B_Say (self, other, "$NOLEARNOVERMAX");
      };
   }
   else
   {
      PrintScreen   ("Za mało punktów umiejętności!", -1,-1,"FONT_OLD_20_WHITE.TGA",1);
      B_Say (self, other, "$NOLEARNNOPOINTS");
   };
};

func int B_TeachAttributePoints(var C_Npc slf,var C_Npc oth,var int attrib,var int points,var int teacherMAX)
{
   var string concatText;
   var int kosten;
   var int realAttribute;
   kosten = B_GetLearnCostAttribute(oth,attrib) * points;
   if((attrib != ATR_STRENGTH) && (attrib != ATR_DEXTERITY) && (attrib != ATR_MANA_MAX))
   {
      Print("*** Błąd: Zły parametr ***");
      return FALSE;
   };
   if(attrib == ATR_STRENGTH)
   {
      realAttribute = oth.attribute[ATR_STRENGTH];
   }
   else if(attrib == ATR_DEXTERITY)
   {
      realAttribute = oth.attribute[ATR_DEXTERITY];
   }
   else if(attrib == ATR_MANA_MAX)
   {
      realAttribute = oth.attribute[ATR_MANA_MAX];
   };
   if(realAttribute >= teacherMAX)
   {
      concatText = ConcatStrings("Maksimum dla tego nauczyciela wynosi ",IntToString(teacherMAX));
      PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",2);
      B_Say(slf,oth,"$NOLEARNYOUREBETTER");
      return FALSE;
   };
   if((realAttribute + points) > teacherMAX)
   {
      concatText = ConcatStrings("Maksimum dla tego nauczyciela wynosi ",IntToString(teacherMAX));
      PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",2);
      B_Say(slf,oth,"$NOLEARNOVERPERSONALMAX");
      return FALSE;
   };
   if(oth.lp < kosten)
   {
      PrintScreen("Za mało Punktów Nauki!",-1,-1,"FONT_OLD_20_WHITE.TGA",2);
      B_Say(slf,oth,"$NOLEARNNOPOINTS");
      return FALSE;
   };
   oth.lp = oth.lp - kosten;
   B_RaiseAttribute_Gothic2(oth,attrib,points);
   return TRUE;
};

func void B_RaiseAttribute_Gothic2(var C_Npc oth,var int attrib,var int points)
{
   var string concatText;
   if(attrib == ATR_STRENGTH)
   {
      oth.attribute[ATR_STRENGTH] = oth.attribute[ATR_STRENGTH] + points;
      concatText = ConcatStrings(NAME_RaiseStrength,IntToString(points));
      PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",4);
   };
   if(attrib == ATR_DEXTERITY)
   {
      oth.attribute[ATR_DEXTERITY] = oth.attribute[ATR_DEXTERITY] + points;
      concatText = ConcatStrings(NAME_RaiseDexterity,IntToString(points));
      PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",4);
   };
   if(attrib == ATR_MANA_MAX)
   {
      oth.attribute[ATR_MANA_MAX] = oth.attribute[ATR_MANA_MAX] + points;
      concatText = ConcatStrings(NAME_RaiseManaMax,IntToString(points));
      PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",4);
   };
   if(attrib == ATR_HITPOINTS_MAX)
   {
      oth.attribute[ATR_HITPOINTS_MAX] = oth.attribute[ATR_HITPOINTS_MAX] + points;
      concatText = ConcatStrings(NAME_RaiseHealthMax,IntToString(points));
      PrintScreen(concatText,-1,-1,"FONT_OLD_20_WHITE.TGA",4);
   };
   //B_RaiseRealAttributeLearnCounter(oth,attrib,points);
};

func int B_GetLearnCostAttribute(var C_Npc oth,var int attribut)
{
   var int kosten;
   kosten = 0;
   if(attribut == ATR_STRENGTH)
   {
      if(oth.attribute[ATR_STRENGTH] >= 120)
      {
         kosten = 5;
      }
      else if(oth.attribute[ATR_STRENGTH] >= 90)
      {
         kosten = 4;
      }
      else if(oth.attribute[ATR_STRENGTH] >= 60)
      {
         kosten = 3;
      }
      else if(oth.attribute[ATR_STRENGTH] >= 30)
      {
         kosten = 2;
      }
      else
      {
         kosten = 1;
      };
   };
   if(attribut == ATR_DEXTERITY)
   {
      if(oth.attribute[ATR_DEXTERITY] >= 120)
      {
         kosten = 5;
      }
      else if(oth.attribute[ATR_DEXTERITY] >= 90)
      {
         kosten = 4;
      }
      else if(oth.attribute[ATR_DEXTERITY] >= 60)
      {
         kosten = 3;
      }
      else if(oth.attribute[ATR_DEXTERITY] >= 30)
      {
         kosten = 2;
      }
      else
      {
         kosten = 1;
      };
   };
   if(attribut == ATR_MANA_MAX)
   {
      if(oth.attribute[ATR_MANA_MAX] >= 120)
      {
         kosten = 5;
      }
      else if(oth.attribute[ATR_MANA_MAX] >= 90)
      {
         kosten = 4;
      }
      else if(oth.attribute[ATR_MANA_MAX] >= 60)
      {
         kosten = 3;
      }
      else if(oth.attribute[ATR_MANA_MAX] >= 30)
      {
         kosten = 2;
      }
      else
      {
         kosten = 1;
      };
   };
   return kosten;
};

Tak zaś wygląda mój Gothic\_work\DATA\scripts\Content\AI\Test_Skripts\CharacterHelper.d
Dosłownie nic nie zmieniałem w tym pliku poza wklejeniem tych dwóch rzeczy na samym dole po ostatnim };

Spoiler

instance CH_Training_NotRCombat(C_Info)
{
   npc = ch;
   condition = CH_Training_NotRCombat_Condition;
   information = CH_Training_NotRCombat_Info;
   important = 0;
   permanent = 1;
   description = "TALENT: Walka Notr";
};


func int CH_Training_NotRCombat_Condition()
{
   return TRUE;
};

func void CH_Training_NotRCombat_Info()
{
   Info_ClearChoices(CH_Training_NotRCombat);
   Info_AddChoice(CH_Training_NotRCombat,"Wróć",CH_Training_NotRCombat_BACK);
   
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);

};


func void CH_Training_NotRCombat_1H_1()
{
   B_TeachFightTalentPercent(self,other,NPC_TALENT_1H,1,100);
   Info_ClearChoices(CH_Training_NotRCombat);
   Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);
   
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_1H_5()
{
   B_TeachFightTalentPercent(self,other,NPC_TALENT_1H,5,100);
   Info_ClearChoices(CH_Training_NotRCombat);
   Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_2H_1()
{
   B_TeachFightTalentPercent(self,other,NPC_TALENT_2H,1,100);
   Info_ClearChoices(CH_Training_NotRCombat);
   Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);
   
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_2H_5()
{
   B_TeachFightTalentPercent(self,other,NPC_TALENT_2H,5,100);
   Info_ClearChoices(CH_Training_NotRCombat);
   Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_Bow_1()
{
   B_TeachFightTalentPercent(self,other,NPC_TALENT_BOW,1,100);
   Info_ClearChoices(CH_Training_NotRCombat);
   Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);
   
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_Bow_5()
{
   B_TeachFightTalentPercent(self,other,NPC_TALENT_BOW,5,100);
   Info_ClearChoices(CH_Training_NotRCombat);
   Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_Crossbow_1()
{
   B_TeachFightTalentPercent(self,other,NPC_TALENT_CROSSBOW,1,100);
   Info_ClearChoices(CH_Training_NotRCombat);
   Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);
   
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};

func void CH_Training_NotRCombat_Crossbow_5()
{
   B_TeachFightTalentPercent(self,other,NPC_TALENT_CROSSBOW,5,100);
   Info_ClearChoices(CH_Training_NotRCombat);
   Info_AddChoice(CH_Training_NotRCombat,Dialog_Back,CH_Training_NotRCombat_Back);

   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_1H,1),0),CH_Training_NotRCombat_1H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),CH_Training_NotRCombat_1H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +1",B_GetLearnCostTalent(other,NPC_TALENT_2H,1),0),CH_Training_NotRCombat_2H_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Broń dwuręczna +5",B_GetLearnCostTalent(other,NPC_TALENT_2H,5),0),CH_Training_NotRCombat_2H_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +1",B_GetLearnCostTalent(other,NPC_TALENT_BOW,1),0),CH_Training_NotRCombat_Bow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Łuki +5",B_GetLearnCostTalent(other,NPC_TALENT_BOW,5),0),CH_Training_NotRCombat_Bow_5);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +1",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,1),0),CH_Training_NotRCombat_Crossbow_1);
   Info_AddChoice(CH_Training_NotRCombat,B_BuildLearnString("Kusze +5",B_GetLearnCostTalent(other,NPC_TALENT_CROSSBOW,5),0),CH_Training_NotRCombat_Crossbow_5);
};


func void CH_Training_NotRCombat_BACK()
{
   Info_ClearChoices(CH_Training_NotRCombat);
};

instance CH_Training_NotRAttributes(C_Info)
{
   npc = ch;
   condition = CH_Training_NotRAttributes_Condition;
   information = CH_Training_NotRAttributes_Info;
   important = 0;
   permanent = 1;
   description = "ATRYBUTY: NotR";
};


func int CH_Training_NotRAttributes_Condition()
{
   return TRUE;
};

func void CH_Training_NotRAttributes_Info()
{
   Info_ClearChoices(CH_Training_NotRAttributes);
   Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);
   
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
   
};

func void CH_Training_NotRAttributes_STR_1()
{
   B_TeachAttributePoints(self,other,ATR_STRENGTH,1,100);
   Info_ClearChoices(CH_Training_NotRAttributes);
   Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);
   
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_STR_5()
{
   B_TeachAttributePoints(self,other,ATR_STRENGTH,5,100);
   Info_ClearChoices(CH_Training_NotRAttributes);
   Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);
   
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_DEX_1()
{
   B_TeachAttributePoints(self,other,ATR_DEXTERITY,1,100);
   Info_ClearChoices(CH_Training_NotRAttributes);
   Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);
   
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_DEX_5()
{
   B_TeachAttributePoints(self,other,ATR_DEXTERITY,5,100);
   Info_ClearChoices(CH_Training_NotRAttributes);
   Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);
   
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_MAN_1()
{
   B_TeachAttributePoints(self,other,ATR_MANA_MAX,1,100);
   Info_ClearChoices(CH_Training_NotRAttributes);
   Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);
   
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_MAN_5()
{
   B_TeachAttributePoints(self,other,ATR_MANA_MAX,5,100);
   Info_ClearChoices(CH_Training_NotRAttributes);
   Info_AddChoice(CH_Training_NotRAttributes,"Wróć",CH_Training_NotRAttributes_BACK);
   
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +1",B_GetLearnCostAttribute(other,ATR_STRENGTH),0),CH_Training_NotRAttributes_STR_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Siła +5",B_GetLearnCostAttribute(other,ATR_STRENGTH) * 5,0),CH_Training_NotRAttributes_STR_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +1",B_GetLearnCostAttribute(other,ATR_DEXTERITY),0),CH_Training_NotRAttributes_DEX_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Zręczność +5",B_GetLearnCostAttribute(other,ATR_DEXTERITY) * 5,0),CH_Training_NotRAttributes_DEX_5);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +1",B_GetLearnCostAttribute(other,ATR_MANA_MAX),0),CH_Training_NotRAttributes_MAN_1);
   Info_AddChoice(CH_Training_NotRAttributes,B_BuildLearnString("Mana +5",B_GetLearnCostAttribute(other,ATR_MANA_MAX) * 5,0),CH_Training_NotRAttributes_MAN_5);
};

func void CH_Training_NotRAttributes_BACK()
{
   Info_ClearChoices(CH_Training_NotRAttributes);
};

Uzupełniłem też te pojedyncze rzeczy w pliku "story\text.d" oraz "PC_Hero".
 


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry