Ostatnie wiadomości

Temat do przeniesienia skoro mod już wyszedł @Simon Said
@Simon Said Ten temat to chyba można zamknąć bo hula tu jedynie wiatr a autor nawet nie raczy odpowiedzieć na pytanie.
Cześć.

Mam pewien problem. Chciałbym podmienić dźwięki machania bronią jeśli materiał tej broni jest inny niż metal.

Dlaczego: Bo jest 6 instancji WHOOSH w pliku sfxinst.d a gra pobiera tylko nazwę WHOOSH i ładuje wszystkie wariacje typu WHOOSH_A1 itd do pamięci przy wczytywaniu save i losuje je podczas wymachiwania czymkolwiek nawet pięściami.

Cel:
Odgrywać instancje WHOOSH_A1 do A5 tylko dla broni metalowych (SND_MAT_METAL) reszta niech korzysta z WHOOSH_A1 i WHOOSH_A2 (sam WHOOSH też mógłby być ale spodziewam się że jeśli nie będzie podmienione w pamięci na sztywno to jakaś funkcja znowu strigeruje losowanie).

Próbowałem się dostać od strony:
- animacji próbując wyszukać kiedy podczas walki używany jest dźwięk - i nie zarejestrowałem wywołana WHOOSH
- systemu odtwarzania dźwięku w miles starając się odnaleźć dla playsound3D te instancje i zamienić.. i nic nie znajduje
- próbowałem przeszukać funkcję ataku ale tam gra tworzy jeden dźwięk z CS_IAM, cachuje i odtwarza same uderzenia więc nie jest to powiązane
- myślałem że dostanę się tam od strony eventów playsfx ale też nie odnajduje w tablicach wywołania tego dźwięku.

Czy ktoś ma z tym doświadczenie i może pomóc? Od razu mówię że podmiana w plikach mds odpada, po to chciałem zrobić plugin żeby był uniwersalny i robił to w locie.

Proszę o pomoc osoby z doświadczeniem jak dobrać się do tego dźwięku i nim manipulować. Pozdrawiam.

EDIT:Zapomniałem dodać platforma to Gothic 1 Classic.
Może i lepiej ale ja zrobiłem tak i działa.

Wcześniej próbowałem to robić na wzór Gothica 2 Noc Kruka ale to wymagało widocznie trochę większej wiedzy o skryptach, więc zrobiłem tak jak umiałem. Zawsze jednak możesz podrzucić swoje rozwiązanie.
a to nie lepiej zrobic to tak jak jest zrobione w G2 zamiast jakies chujemuje odpierdalac z nastawieniem gildii?
Podrzucam gotowiec skryptu, bo widziałem, że niektórzy pytali jak zrobić efekt taki jak w Gothic 2 Noc Kruka, że NPC atakują gracza gdy ma na sobie pancerz bandyty. Jako, że nigdzie nie znalazłem by było to wytłumaczone w sposób przystępny dla moddera-nowicjusza wrzucam to na forum do korzystania dla wszystkich.

Ja akurat potrzebowałem tego efektu w stosunku do szaty nekromanty więc wstawiam tutaj skrypt, który sprawia, że postacie niezależne atakują gracza gdy ma na sobie strój nekromanty. Skrypt opiera się na dodaniu dwóch nowych "tabelek" z nastawieniem gildii do pliku "Guilds.d", w których wszystkie gildie nienawidzą nekromantów - "tabelki" te są uruchamiane po założeniu stroju nekromanty a po zdjęciu stroju nekromanty przeskakuje z powrotem do "podstawowych tabelek".

PS: Zapewne dałoby się to zrobić subtelniej modyfikując funkcje typu ZS_Attack, ZS_AssessEnemy czy ZS_AssessMurder ale to dla mnie wyższa szkoła jazdy. Jeżeli jednak ktoś czuje się na siłach i ma ochotę to może tu podrzucić swoje rozwiązanie.

Jak wkleić tego gotowca
W pliku "armor.d" znajdującym się w folderze "_work\DATA\scripts\Content\Items" musimy dodać

on_equip = Equip_DMB_ARMOR_M;
on_unequip = UnEquip_DMB_ARMOR_M;

oraz

FUNC VOID Equip_DMB_ARMOR_M()
{
self.guild =  GIL_DMB;
Npc_SetTrueGuild(self,GIL_DMB);
B_InitGuildAttitudes();
};

FUNC VOID UnEquip_DMB_ARMOR_M()
{
self.guild =  GIL_DMB;
Npc_SetTrueGuild(self,GIL_DMB);
B_InitGuildAttitudes();
};

Skrypt zbroi w "armors.d" powinien wyglądać tak:
Spoiler
// Dämonenbeschwörer

INSTANCE DMB_ARMOR_M(C_Item)
{
name = "Szata Mrocznych Sztuk";

mainflag = ITEM_KAT_ARMOR;
flags = 0;

protection [PROT_EDGE] = 90;
protection [PROT_BLUNT] = 90;
protection [PROT_POINT] = 20;
protection [PROT_FIRE] = 60;
protection [PROT_MAGIC] = 30;

wear = WEAR_TORSO;

  value = protection [PROT_EDGE] * ARMOR_VALUE_MULTIPLIER;

ownerGuild = GIL_DMB;

visual = "dmbm.3ds";
visual_change = "Hum_DMBM_ARMOR.asc";
visual_skin = 0;
material = MAT_LEATHER;
on_equip = Equip_DMB_ARMOR_M;
on_unequip = UnEquip_DMB_ARMOR_M;

description = name;
TEXT[0] = "Lepiej nie nosić tego publicznie.";
TEXT[1] = NAME_Prot_Edge; COUNT[1] = protection [PROT_EDGE];
TEXT[2] = NAME_Prot_Point; COUNT[2] = protection [PROT_POINT];
TEXT[3] = NAME_Prot_Fire; COUNT[3] = protection [PROT_FIRE];
TEXT[4] = NAME_Prot_Magic; COUNT[4] = protection [PROT_MAGIC];
TEXT[5] = NAME_Value; COUNT[5] = value;
};


FUNC VOID Equip_DMB_ARMOR_M() ///deleted
{
self.guild =  GIL_DMB;
Npc_SetTrueGuild(self,GIL_DMB);
B_PeopleHatesYouNecromancer = TRUE;
B_InitGuildAttitudes();
};

FUNC VOID UnEquip_DMB_ARMOR_M()
{
self.guild =  GIL_DMB;
Npc_SetTrueGuild(self,GIL_DMB);
B_PeopleHatesYouNecromancer = FALSE;
B_InitGuildAttitudes();
};


W pliku "Story_Globals.d" znajdującym się w folderze "_work\DATA\scripts\Content\Story" dodajemy
var int B_PeopleHatesYouNecromancer;
W pliku "GUILDS.d" znajdującym się w folderze "_work\DATA\scripts\Content\Story" dodajemy dwie nowe "tabelki" o nazwach: "CONST INT GIL_ATTITUDES_NecromancerArmor" oraz GIL_ATTITUDES_FMTAKEN_NecromancerArmor. To są odpowiedniki "tabelek" nastawienia gildyjnego z początku gry oraz nastawienia gildyjnego od IV rozdziału z dodatkową parą tych "tabelek" różniących się tylko tym, że wszystkie inne gildie nienawidzą gildii Nekromanty.

Po prostu wklejamy je do tego dokumentu na samym dole:

CONST INT GIL_ATTITUDES_NecromancerArmor [TAB_ANZAHL] = // AL und  NL verärgert (Magier zueinander freundlich) ST neutral zu AL und NL (Magier verärgert zu ST)
{
// None EBr Grd Stt KdF Vlk KdW Sld Org Bau SfB Gur Nov Tpl Däm Bab
/*Non*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Non*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Non*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Non*/ ATT_HOSTILE, ATT_NEUTRAL,

/*Ebr*/ ATT_NEUTRAL, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Ebr*/ ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, /*Ebr*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Ebr*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Grd*/ ATT_NEUTRAL, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Grd*/ ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, /*Grd*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Grd*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Stt*/ ATT_NEUTRAL, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Stt*/ ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, /*Stt*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Stt*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Kdf*/ ATT_NEUTRAL, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Kdf*/ ATT_FRIENDLY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, /*Kdf*/ ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, /*Kdf*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Vlk*/ ATT_NEUTRAL, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Vlk*/ ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, /*Vlk*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Vlk*/ ATT_HOSTILE, ATT_NEUTRAL,

/*Kdw*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_FRIENDLY, ATT_NEUTRAL, /*Kdw*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Kdw*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Kdw*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Sld*/ ATT_NEUTRAL, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, /*Sld*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_NEUTRAL, ATT_FRIENDLY, ATT_FRIENDLY, /*Sld*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Sld*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Org*/ ATT_NEUTRAL, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, /*Org*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Org*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Org*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Bau*/ ATT_NEUTRAL, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, /*Bau*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Bau*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Bau*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Sfb*/ ATT_NEUTRAL, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, ATT_ANGRY, /*Sfb*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Sfb*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Sfb*/ ATT_HOSTILE, ATT_NEUTRAL,

/*Gur*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_ANGRY, ATT_NEUTRAL, /*Gur*/ ATT_ANGRY, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Gur*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Gur*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Nov*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_ANGRY, ATT_NEUTRAL, /*Nov*/ ATT_ANGRY, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Nov*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Nov*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Tpl*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_ANGRY, ATT_NEUTRAL, /*Tpl*/ ATT_ANGRY, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Tpl*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Tpl*/ ATT_HOSTILE, ATT_NEUTRAL,

/*Dmb*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Dmb*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_FRIENDLY, /*Dmb*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Dmb*/ ATT_FRIENDLY, ATT_HOSTILE,
/*Bab*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Mst*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Mst*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Mst*/ ATT_HOSTILE, ATT_FRIENDLY

};

CONST INT GIL_ATTITUDES_FMTAKEN_NecromancerArmor [TAB_ANZAHL] = // AL und NL feindlich
{
// None EBr Grd Stt KdF Vlk KdW Sld Org Bau SfB Gur Nov Tpl Däm Bab
/*Non*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Non*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Non*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Non*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Ebr*/ ATT_HOSTILE, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_HOSTILE, ATT_FRIENDLY, /*Ebr*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Ebr*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Ebr*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Grd*/ ATT_HOSTILE, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_HOSTILE, ATT_FRIENDLY, /*Grd*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Grd*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Grd*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Stt*/ ATT_HOSTILE, ATT_FRIENDLY, ATT_NEUTRAL, ATT_FRIENDLY, ATT_HOSTILE, ATT_NEUTRAL, /*Stt*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Stt*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Stt*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Kdf*/ ATT_FRIENDLY, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_FRIENDLY, ATT_NEUTRAL, /*Kdf*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Kdf*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Kdf*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Vlk*/ ATT_HOSTILE, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Vlk*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Vlk*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Vlk*/ ATT_HOSTILE, ATT_NEUTRAL,

/*Kdw*/ ATT_FRIENDLY, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_FRIENDLY, ATT_HOSTILE, /*Kdw*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Kdw*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Kdw*/ ATT_HOSTILE, ATT_FRIENDLY,
/*Sld*/ ATT_FRIENDLY, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_FRIENDLY, ATT_HOSTILE, /*Sld*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_NEUTRAL, ATT_FRIENDLY, ATT_FRIENDLY, /*Sld*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Sld*/ ATT_HOSTILE, ATT_FRIENDLY,
/*Org*/ ATT_FRIENDLY, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_FRIENDLY, ATT_HOSTILE, /*Org*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Org*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Org*/ ATT_HOSTILE, ATT_FRIENDLY,
/*Bau*/ ATT_FRIENDLY, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_FRIENDLY, ATT_HOSTILE, /*Bau*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Bau*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Bau*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Sfb*/ ATT_FRIENDLY, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_FRIENDLY, ATT_HOSTILE, /*Sfb*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Sfb*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Sfb*/ ATT_HOSTILE, ATT_NEUTRAL,

/*Gur*/ ATT_FRIENDLY, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_FRIENDLY, ATT_NEUTRAL, /*Gur*/ ATT_ANGRY, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Gur*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Gur*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Nov*/ ATT_FRIENDLY, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_FRIENDLY, ATT_NEUTRAL, /*Nov*/ ATT_ANGRY, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Nov*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Nov*/ ATT_HOSTILE, ATT_NEUTRAL,
/*Tpl*/ ATT_FRIENDLY, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_FRIENDLY, ATT_NEUTRAL, /*Tpl*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Tpl*/ ATT_FRIENDLY, ATT_FRIENDLY, ATT_FRIENDLY, /*Tpl*/ ATT_HOSTILE, ATT_NEUTRAL,

/*Dmb*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Dmb*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, ATT_FRIENDLY, /*Dmb*/ ATT_HOSTILE, ATT_HOSTILE, ATT_HOSTILE, /*Dmb*/ ATT_FRIENDLY, ATT_HOSTILE,
/*Bab*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Mst*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Mst*/ ATT_NEUTRAL, ATT_NEUTRAL, ATT_NEUTRAL, /*Mst*/ ATT_HOSTILE, ATT_FRIENDLY

};

Kluczowe jest by nastawienie "Däm" (tak w tej tabeli oznaczono gildię nekromanty)  przestawić na "ATT_HOSTILE". Jak chcemy by inne postacie z tą gildią nas nie atakowały to na "przecięciu" dwóch "Däm" wstawiamy "ATT_FRIENDLY"

Na koniec w pliku B_Functions.d w folderze _work\DATA\Scripts\Content\AI\AI_Intern znajdujesz funkcję B_InitGuildAttitudes, która wygląda tak:


Spoiler
//////////////////////////////////////////////////////////////////////////
// B_InitGuildAttitudes
// ====================
// Setzt bzw. resettet die Attitüde unter den Menschengilden
// und berücksichtigt dabei den Storyverlauf
//////////////////////////////////////////////////////////////////////////
func void B_InitGuildAttitudes ()
{
PrintDebugNpc (PD_ZS_FRAME, "B_InitGuildAttitudes");

if (Kapitel <= 3)
{
Wld_ExchangeGuildAttitudes ("GIL_ATTITUDES");
}
else
{
Wld_ExchangeGuildAttitudes ("GIL_ATTITUDES_FMTAKEN");
};
};

I podmieniamy jej zawartość. Ostatecznie powinna wyglądać tak

//////////////////////////////////////////////////////////////////////////
// B_InitGuildAttitudes
// ====================
// Setzt bzw. resettet die Attitüde unter den Menschengilden
// und berücksichtigt dabei den Storyverlauf
//////////////////////////////////////////////////////////////////////////
func void B_InitGuildAttitudes ()
{
PrintDebugNpc (PD_ZS_FRAME, "B_InitGuildAttitudes");

if (Kapitel <= 3)
{
if B_PeopleHatesYouNecromancer == FALSE { Wld_ExchangeGuildAttitudes("GIL_ATTITUDES"); };
if B_PeopleHatesYouNecromancer == TRUE  { Wld_ExchangeGuildAttitudes("GIL_ATTITUDES_NecromancerArmor"); };
}
else
{
if B_PeopleHatesYouNecromancer == FALSE { Wld_ExchangeGuildAttitudes("GIL_ATTITUDES_FMTAKEN"); };
if B_PeopleHatesYouNecromancer == TRUE { Wld_ExchangeGuildAttitudes("GIL_ATTITUDES_FMTAKEN_NecromancerArmor"); }; ///// You wear Necromancer's Armor
};
};

Uwagi:
1. Postacie "Npctype = NPCTYPE_FRIEND;" nie powinny nas atakować.

Jak przerobić tego gotowca, żeby dotyczył np. zbroi bandytów

Na podstawie tego skryptu można uzyskać efekt zbliżony do efektu nałożonej zbroi bandyty z Gothic 2 Noc Kruka. Trzeba wówczas go trochę przerobić. Przykładowo można użyć gildii magnata ("Ebr"). Należy wtedy też zmienić gildię NPC-om z tą gildią na inną, by postacie nie rzucały się na magnatów tylko na gracza noszącego konkretną zbroję.

W moim skrypcie po założeniu zbroi zmienia nam się gildia na GIL_DMB. Żeby nam się zmieniała na tą co mieliśmy przed założeniem zbroi musielibyśmy pokombinować z warunkami przy "FUNC VOID UnEquip_DMB_ARMOR_M" ale to już nie wymaga wiedzy tylko odrobinę "benedyktyńskiej pracy".
Gdybym miał radzić to do każdej opcji dialogowej gdzie jesteśmy przyjmowani do gildii  (typu Gomez przyjmuje nas do Cieni, Lee do najemników itd.) można byłoby dodać coś takiego:
Spoiler
ReturnToSTT = TRUE;
ReturnToGRD = FALSE;
ReturnToKDF = FALSE;
ReturnToORG = FALSE;
ReturnToSLD = FALSE;
ReturnToKDW = FALSE;
ReturnToNOV = FALSE;
ReturnToTPL = FALSE;
ReturnToNone = FALSE;
(analogicznie do przyjęcia do innych gildii)

A w "FUNC VOID UnEquip_DMB_ARMOR_M"

Pobawić się z warunkami
if (ReturnToSTT) == TRUE
{
self.guild =  GIL_STT;
Npc_SetTrueGuild(self,GIL_STT);
B_PeopleHatesYouNecromancer = FALSE;
B_InitGuildAttitudes();
}
i oczywiście "ReturnToSTT" i resztę "returnów" trzeba by było dodać do pliku "Story_Globals.d".

Całość powinna ładnie śmigać :)


Kopiowanie i udostępnianie dozwolone. Nie potrzeba uwzględniać w creditsach.
Opis uzupełniony o nowy mirrory, a także o przekierowanie na Sefaris.
Opis uzupełniony o nowy mirrory, a także o przekierowanie na Sefaris.
Piękna sprawa, czekam! <3
Naprawdę ogromne dzięki za pomoc. Bardzo mi zależało, żeby załatwić kwestię bonusów do siły, zręczności i w mniejszym stopniu do many. Z tymi trzema statystykami wszystko ładnie śmiga.

Trochę gorzej jest z umiejętnościami bojowymi.

Wkleiłem ten kod:

if(talent == NPC_TALENT_1H)
   {
      B_RaiseFightTalent(oth,NPC_TALENT_1H,percent);
        Learned_1H = Learned_1H + percent;

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

do funkcji B_TeachFightTalentPercent.

Tylko, że w Gothic 1 funkcji B_RaiseFightTalent nie ma i w swoim skrypcie @bgb też go nie dodawał więc go nie ma.

@bgb w swoim skrypcie (na którym ja bazuję) zastąpił:

B_RaiseFightTalent(oth,NPC_TALENT_1H,percent);
czymś takim:

Npc_SetTalentValue(hero, NPC_TALENT_1H, Npc_GetTalentValue(hero, NPC_TALENT_1H)+percent);


Może więc po prostu wkleję wszystkie rzeczy, które dotyczą nauki umiejętności bojowych z tego skryptu to będzie łatwiej wychwycić co poszło nie tak:

//////////////////////////////////////////////////////////////////////////
// NOTR learning weapon and atrribute system
// ===============
//
//////////////////////////////////////////////////////////////////////////

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;
};

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_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 = Learned_1H; /// nie wiem czy dobrze
   }
   else if(talent == NPC_TALENT_2H)
   {
      realHitChance = Learned_2H; /// nie wiem czy dobrze
   }
   else if(talent == NPC_TALENT_BOW)
   {
      realHitChance = Learned_Bow; /// nie wiem czy dobrze
   }
   else if(talent == NPC_TALENT_CROSSBOW)
   {
      realHitChance = Learned_CrossBow; /// nie wiem czy dobrze
   };
   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 Nauki!",-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;
   };
};

W pliku PC_Hero.d na próbę zrobiłem też żeby było
Npc_SetTalentValue(self, NPC_TALENT_1H,10);
Learned_1H = 90;
Npc_SetTalentValue(self, NPC_TALENT_2H,10);
Learned_2H = 90;

bo chciałem zobaczyć czy zostanie to uwzględnione u nauczycieli broni jednoręcznej. Cord dalej jednak przeliczał tak jakby nie widział "Learned_1H = 90".

Podrzucam też dla pewności przykładowy dialog z nauką broni jednoręcznej u Corda:

Spoiler
// **************************************************
// TRAIN 1H - NOTR
// **************************************************

instance Cord_Training_NotRCombat(C_Info)
{
npc = SLD_709_Cord;
condition = Cord_Training_NotRCombat_Condition;
information = Cord_Training_NotRCombat_Info;
important = 0;
permanent = 1;
description = "Naucz mnie walczyć bronią jednoręczną";
};


func int Cord_Training_NotRCombat_Condition()
{
if (Npc_KnowsInfo(hero,SLD_709_Cord_TRAINOFFER))
{
return 1;
};
};

func void Cord_Training_NotRCombat_Info()
{
Info_ClearChoices(Cord_Training_NotRCombat);
Info_AddChoice(Cord_Training_NotRCombat,"Wróć",Cord_Training_NotRCombat_BACK);

Info_AddChoice(Cord_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5 (20 bryłek za każdy 1 PN)",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),Cord_Training_NotRCombat_1H_5);

};

func void Cord_Training_NotRCombat_1H_5()
{
      if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 100) && (Npc_HasItems(other,itminugget) >= 400)
{
PrintScreen ("Ale Ty już osiągnąłeś 100% tej umiejętności!", -1,-1,"font_old_20_white.tga",3);
Info_ClearChoices(Cord_Training_NotRCombat);
Info_AddChoice(Cord_Training_NotRCombat,Dialog_Back,Cord_Training_NotRCombat_Back);
}
 
  else if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 90) && (Npc_HasItems(other,itminugget) >= 400)
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_1H,5,100);
B_GiveInvItems(other,self,itminugget,400);
Info_ClearChoices(Cord_Training_NotRCombat);
Info_AddChoice(Cord_Training_NotRCombat,Dialog_Back,Cord_Training_NotRCombat_Back);

Info_AddChoice(Cord_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5 (20 bryłek za każdy 1 PN)",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),Cord_Training_NotRCombat_1H_5);

}
      else if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 60) && (Npc_HasItems(other,itminugget) >= 300)
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_1H,5,100);
B_GiveInvItems(other,self,itminugget,300);
Info_ClearChoices(Cord_Training_NotRCombat);
Info_AddChoice(Cord_Training_NotRCombat,Dialog_Back,Cord_Training_NotRCombat_Back);

Info_AddChoice(Cord_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5 (20 bryłek za każdy 1 PN)",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),Cord_Training_NotRCombat_1H_5);

}
      else if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 30) && (Npc_HasItems(other,itminugget) >= 200)
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_1H,5,100);
B_GiveInvItems(other,self,itminugget,200);
Info_ClearChoices(Cord_Training_NotRCombat);
Info_AddChoice(Cord_Training_NotRCombat,Dialog_Back,Cord_Training_NotRCombat_Back);

Info_AddChoice(Cord_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5 (20 bryłek za każdy 1 PN)",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),Cord_Training_NotRCombat_1H_5);

}
      else if(Npc_GetTalentValue(hero,NPC_TALENT_1H) >= 0) && (Npc_HasItems(other,itminugget) >= 100)
{
B_TeachFightTalentPercent(self,other,NPC_TALENT_1H,5,100);
B_GiveInvItems(other,self,itminugget,100);
Info_ClearChoices(Cord_Training_NotRCombat);
Info_AddChoice(Cord_Training_NotRCombat,Dialog_Back,Cord_Training_NotRCombat_Back);

Info_AddChoice(Cord_Training_NotRCombat,B_BuildLearnString("Broń jednoręczna +5 (20 bryłek za każdy 1 PN)",B_GetLearnCostTalent(other,NPC_TALENT_1H,5),0),Cord_Training_NotRCombat_1H_5);

}
       else
{
AI_Output (self,other,"DIA_Cord_TRAIN_2h_NoOre_01_00"); //Wróć, gdy będziesz miał wystarczająco dużo rudy.
};
};

func void Cord_Training_NotRCombat_BACK()
{
Info_ClearChoices(Cord_Training_NotRCombat);
};

Do góry