Aurora Toolset to dość prosty program umożliwiający stworzenie swoich własnych modułów, kampanii czy przygód opartych na systemie zaprezentowanym w Neverwinter Nights. Jednakże czym byłby las czy miasto z rozlokowanymi obiektami bez skryptów? To one są "duszą" każdego modułu i dosłownie wprowadzają życie w poszczególne postacie. Dzięki nim nasze pomysły mogą zostać urzeczywistnione i mamy okazję stworzyć unikalną przygodę własnego autorstwa. Zapewne na pierwszy rzut nowicjuszowskiego oka skryptowanie może okazać się trudne, ale nic bardziej mylnego. Wystarczy znajomość angielskiego, trochę wolnego czasu i dużo samozaparcia, a z czasem dojdzie się do takiej perfekcji, że niektóre komendy będą powstawały w kilka sekund. Nie wszystkie poniżej zamieszczone skrypty są mego autorstwa. Niektóre zostały odnalezione w odmętach internetowej toni i czasami nieco przeze mnie zmienione.
Wielokrotny autozapis · Jednokrotny autozapis · Poruszanie się · Siedzenie · Spanie · Rozmawiająca grupa · Rzucanie zaklęcia · Wyzwalacz teksu · Animacje · Dźwignia otwierająca/zamykająca drzwi · Zwłoki · Atak obiektu · Atakujący obiekt · Pojemnik broniony po ograbieniu przez stworzenie · Pojemnik znika po ograbieniu · Kradzież powodująca wrogość stworzenia · Leczący obiekt · Kadź przywołująca · Atak rozmówcy · Najemnik · Portal · Inteligentny przedmiot: Butelka z Dżinem · Inteligentny przedmiot: Pierścień Translokacji · Hazard: gra w 3 kubki · Hazard: black jack
Wielokrotny autozapis
Opis: Po wejściu na wyzwalacz gra automatycznie stworzy zapis rozgrywki. Funkcja działa wielokrotnie.
Skrypt:
void main()
{
DoSinglePlayerAutoSave ();
}
Gdzie: OnEnter wyzwalacza
Jednokrotny autozapis
Opis: Po wejściu na wyzwalacz gra automatycznie stworzy zapis rozgrywki. Funkcja działa tylko raz.
Skrypt:
void main()
{
int nDone = GetLocalInt (OBJECT_SELF, "ON_ENTER_SAVE_ONCE");
if (nDone == FALSE)
{
DoSinglePlayerAutoSave ();
SetLocalInt (OBJECT_SELF, "ON_ENTER_SAVE_ONCE", TRUE);
}
}
Gdzie: OnEnter wyzwalacza
Poruszanie się
Opis: Dana postać będzie poruszała się w chaotyczny sposób po obszarze.
Skrypt:
void main()
{
ActionRandomWalk();
}
Gdzie: OnHeartbeat postaci
Siedzenie
Opis: Postać będzie siedziała na danym obiekcie (krześle).
Skrypt:
void main()
{
ActionSit (GetNearestObjectByTag ("ETYKIETA OBIEKTU (KRZESŁA)"));
}
Gdzie: OnHeartbeat postaci
Spanie
Opis: Postać będzie spała.
Skrypt:
void main()
{
effect eVis = EffectVisualEffect (VFX_IMP_SLEEP);
SetIsDestroyable (FALSE,FALSE);
ApplyEffectToObject (DURATION_TYPE_PERMANENT, EffectSleep (), OBJECT_SELF);
ApplyEffectToObject (DURATION_TYPE_INSTANT, eVis, OBJECT_SELF);
}
Gdzie: OnHeartbeat postaci
Rozmawiająca grupa
Opis: Grupa postaci będzie ukazywała animacje rozmowy przy danym punkcie nawigacyjnym. Poszczególne animacje można usunąć.
Skrypt:
void main()
{
int nAnimation;
int nRandom = Random(11);
switch(nRandom)
{
case 0: nAnimation = ANIMATION_FIREFORGET_DRINK ; break;
case 1: nAnimation = ANIMATION_FIREFORGET_GREETING ; break;
case 2: nAnimation = ANIMATION_FIREFORGET_HEAD_TURN_LEFT ; break;
case 3: nAnimation = ANIMATION_FIREFORGET_HEAD_TURN_RIGHT ; break;
case 4: nAnimation = ANIMATION_FIREFORGET_PAUSE_BORED ; break;
case 5: nAnimation = ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD ; break;
case 6: nAnimation = ANIMATION_LOOPING_PAUSE_DRUNK; break;
case 7: nAnimation = ANIMATION_LOOPING_PAUSE_TIRED; break;
case 8: nAnimation = ANIMATION_LOOPING_TALK_LAUGHING; break;
case 9: nAnimation = ANIMATION_LOOPING_TALK_FORCEFUL; break;
case 10: nAnimation = ANIMATION_LOOPING_TALK_PLEADING; break;
}
ActionPlayAnimation (ANIMATION_LOOPING_TALK_NORMAL);
ActionPlayAnimation (nAnimation);
ActionPlayAnimation (ANIMATION_LOOPING_TALK_NORMAL);
ActionDoCommand (SetFacingPoint (GetPosition (GetNearestObjectByTag ("ETYKIETA PUNKTU NAWIGACYJNEGO"))));
}
Gdzie: OnHeartbeat postaci
Rzucanie zaklęcia
Opis: Dana postać będzie rzucała określone zaklęcie na obiekt.
Skrypt:
void main()
{
object oCaster = GetObjectByTag ("ETYKIETA POSTACI");
object oTarget = GetObjectByTag ("ETYKIETA OBIEKTU");
AssignCommand (oCaster, ActionCastSpellAtObject (ETYKIETA ZAKLĘCIA, oTarget, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, FALSE));
}
Gdzie: OnHeartbeat lub OnSpawn postaci
Lista etykiet zaklęć: SPELL_*
Wyzwalacz teksu
Opis: Wchodząc na wyzwalacz, wyświetli się tekst postaci/obiektu.
Skrypt:
void main()
{
object oPC = GetEnteringObject();
if (GetLocalInt(oPC, "x_entering_text1") == FALSE)
{
AssignCommand (GetObjectByTag ("ETYKIETA POSTACI/OBIEKTU"),
SpeakString("TEKST"));
SetLocalInt(oPC, "x_entering_text1", TRUE);
}
}
Gdzie: OnEnter wyzwalacza
Animacje
Opis: Postać będzie wykonywała daną animację.
Skrypt:
void main()
{
ActionPlayAnimation (ETYKIETA ANIMACJI);
}
Gdzie: OnHeartbeat postaci
Lista etykiet animacji: ANIMATION_*
Dźwignia otwierająca/zamykająca drzwi
Opis: Dźwignia po pociągnięci otworzy bądź zamknie drzwi. We właściwościach drzwi należy ustawić, by były zamknięte.
Skrypt:
void main()
{
string sTag = GetTag (OBJECT_SELF);
object oDoor = GetNearestObjectByTag ("ETYKIETA DRZWI");
if (GetLocked (oDoor) == TRUE)
{
SetLocked( oDoor, FALSE);
ActionOpenDoor(oDoor);
}
else
{
ActionCloseDoor (oDoor);
SetLocked (oDoor, TRUE);
}
}
Gdzie: OnUsed dźwigni
Zwłoki
Opis: Truchło postaci będzie leżało na ziemi.
Skrypt:
void main()
{
SetIsDestroyable (FALSE,FALSE);
ApplyEffectToObject (DURATION_TYPE_PERMANENT, EffectDeath (TRUE,TRUE), OBJECT_SELF);
}
Gdzie: OnHeartbeat postaci
Atak obiektu
Opis: Postać będzie atakowała określony obiekt. We właściwościach obiektu należy zaznaczyć opcję fabuła, by uniknąć zniszczenia przedmiotu.
Skrypt:
void main()
{
ActionAttack (GetNearestObjectByTag ("ETYKIETA OBIEKTU"));
}
Gdzie: OnHeartbeat postaci
Atakujący obiekt
Opis: Po wejściu na wyzwalacz obiekt, np. statua, zaatakuje postać zadając jej odpowiednią ilość kostek obrażeń ustalonego rodzaju przy jednoczesnym wyświetleniu danego efektu wizualnego. Dostępne kostki obrażeń: d2(X), d3(X), d4(X), d6(X), d8(X), d10(X), d12(X), d20(X), d100(X), gdzie X oznacza ilość rzutów kostką, np. d3(4) oznacza rozpiętość obrażeń (1-3)?4.
Skrypt:
void main()
{
object oPC = GetEnteringObject ();
object oObject = GetNearestObjectByTag ("ETYKIETA OBIEKTU");
effect eBeam = EffectBeam (ETYKIETA EFEKTU WIZUALNEGO, oObject, BODY_NODE_HAND,FALSE);
effect eDMG = EffectDamage (OBRAŻENIA, ETYKIETA RODZAJU OBRAŻEŃ);
ApplyEffectToObject (DURATION_TYPE_TEMPORARY, eBeam, oPC, 1.0);
ApplyEffectToObject (DURATION_TYPE_INSTANT, eDMG, oPC, 0.0);
}
Gdzie: OnEnter wyzwalacza
Lista etykiet efektów wizualnych: VFX_BEAM_*, VFX_COM_*, VFX_DUR_*, VFX_EYES_*, VFX_FNF_*, VFX_IMP_*
Lista etykiet rodzajów obrażeń: DAMAGE_TYPE_*
Pojemnik broniony po ograbieniu przez stworzenie
Opis: W trakcie ograbiania pojemnika, np. zwłok, pojawi się stworzenie przy jednoczesnym wyświetleniu efektu wizualnego. Warto skorzystać również ze skryptu powodującego zniknięcie pojemnika po pojawieniu się stworzenia.
Skrypt:
void main()
{
location locLocation = GetLocation (GetObjectByTag ("ETYKIETA POJEMNIKA"));
object oSpawn = CreateObject (OBJECT_TYPE_CREATURE, "ResRef STWORZENIA", locLocation, FALSE);
effect eVis = EffectVisualEffect (ETYKIETA EFEKTU WIZUALNEGO);
ApplyEffectAtLocation (DURATION_TYPE_INSTANT, eVis, locLocation);
}
Gdzie: OnOpened pojemnika
Lista etykiet efektów wizualnych: VFX_BEAM_*, VFX_COM_*, VFX_DUR_*, VFX_EYES_*, VFX_FNF_*, VFX_IMP_*
Pojemnik znika po ograbieniu
Opis: Pojemnik zniknie po ograbieniu.
Skrypt:
void main()
{
object oDestroy = GetObjectByTag ("ETYKIETA POJEMNIKA");
DestroyObject (oDestroy);
}
Gdzie: OnClosed pojemnika
Kradzież powodująca wrogość stworzenia
Opis: Po zabraniu konkretnego przedmiotu z pojemnika dane stworzenie stanie się wrogie i wypowie tekst.
Skrypt:
void main()
{
object oObject = GetObjectByTag ("ETYKIETA STWORZENIA");
object oPC = GetLastDisturbed ();
object oItem = GetObjectByTag ("ETYKIETA PRZEDMIOTU");
if (GetIsObjectValid (oPC) && (GetInventoryDisturbType () == INVENTORY_DISTURB_TYPE_REMOVED) && (GetInventoryDisturbItem () == oItem))
{
SetIsTemporaryEnemy (oPC, oObject, FALSE);
AssignCommand (oObject, SpeakString ("TEKST"));
AssignCommand (oObject, ActionAttack (oPC, FALSE));
}
}
Gdzie: OnDisturbed pojemnika
Leczący obiekt
Opis: Obiekt, np. snop światła, po dotknięciu uleczy postaci określoną liczbę PW przy jednoczesnym wyświetleniu danego efektu wizualnego nad postacią. We właściwościach obiektu należy zaznaczyć opcję można używać.
Skrypt:
void main()
{
object oPC = GetLastUsedBy ();
effect eHeal = EffectHeal (LICZBA PW);
effect eVis = EffectVisualEffect (ETYKIETA EFEKTU WIZUALNEGO);
ApplyEffectToObject (DURATION_TYPE_INSTANT, eVis, oPC);
ApplyEffectToObject (DURATION_TYPE_INSTANT, eHeal, oPC);
}
Gdzie: OnUsed obiektu
Lista etykiet efektów wizualnych: VFX_BEAM_*, VFX_COM_*, VFX_DUR_*, VFX_EYES_*, VFX_FNF_*, VFX_IMP_*
Kadź przywołująca
Opis: Kadź ogniskowana przez cztery statuy przywołująca losowego potwora z puli czterech co 1s przy jednoczesnym wyświetleniu efektu wizualnego nad zbiornikiem. Po zniszczeniu posągów proces zostaje przerwany.
Skrypt:
void main()
{
object oObject = OBJECT_SELF;
object oBeaconA = GetObjectByTag("ETYKIETA STATUY 1");
object oBeaconB = GetObjectByTag("ETYKIETA STATUY 2");
object oBeaconC = GetObjectByTag("ETYKIETA STATUY 3");
object oBeaconD = GetObjectByTag("ETYKIETA STATUY 4");
effect eVisual = EffectVisualEffect(ETYKIETA EFEKTU WIZUALNEGO);
location lWP = GetLocation(oObject);
int nChance = d100(1);
if(GetIsDead(oBeaconA) && GetIsDead(oBeaconB) && GetIsDead(oBeaconC) && GetIsDead(oBeaconD)) return;
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVisual, oObject, 1.0));
if(nChance < 11)
{
object oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "RESREF POTWORA 1", lWP);
}
if(nChance > 10 && nChance < 41)
{
object oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "RESREF POTWORA 2", lWP);
}
if(nChance > 40 && nChance < 71)
{
object oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "RESREF POTWORA 3", lWP);
}
if(nChance > 70 && nChance < 101)
{
object oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "RESREF POTWORA 4", lWP);
}
}
Gdzie: OnHeartbeat kadzi
Atak rozmówcy
Opis: Rozmówca zaatakuje postać po wybraniu odpowiedniej ścieżki dialogowej.
Skrypt:
void main()
{
object oPC = GetPCSpeaker();
object oSelf = OBJECT_SELF;
SetIsTemporaryEnemy(oSelf, oPC);
SetIsTemporaryEnemy(oPC, oSelf);
AssignCommand(oSelf, ActionAttack(oPC));
}
Gdzie: w zakładce Podjęte Działania wybranej ścieżki dialogowej
Najemnik
Opis: Po wybraniu konkretnej ścieżki dialogowej rozmówca stanie się towarzyszem.
Skrypt:
void main()
{
object oHench = OBJECT_SELF;
object oPC = GetPCSpeaker();
AddHenchman(oPC, oHench);
}
Gdzie: w zakładce Podjęte Działania wybranej ścieżki dialogowej
Portal
Opis: Obiekt, np. snop światła, po dotknięciu przeniesie postać do punktu nawigacyjnego przy jednoczesnym wyświetleniu danego efektu wizualnego nad postacią. We właściwościach obiektu z efektem wizualnym należy zaznaczyć opcję można używać.
Skrypt:
void main()
{
object oPC = GetLastUsedBy ();
object oTarget = GetObjectByTag ("ETYKIETA PUNKTU NAWIGACYJNEGO");
effect eVis = EffectVisualEffect (ETYKIETA EFEKTU WIZUALNEGO);
ApplyEffectToObject (DURATION_TYPE_INSTANT, eVis, oPC);
AssignCommand (oPC, JumpToObject (oTarget));
}
Gdzie: OnUsed obiektu
Lista etykiet efektów wizualnych: VFX_BEAM_*, VFX_COM_*, VFX_DUR_*, VFX_EYES_*, VFX_FNF_*, VFX_IMP_*
Inteligentny przedmiot: Butelka z Dżinem
Opis: Używając butelki, uwolniony zostanie Dżin prowadzący sklep.
- Wpierw stwórz konkretnego Dżina oraz przedmiot będący jego więzieniem, np. butelka. We właściwościach przedmiotu wybierz Rzucanie zaklęcia: Rozmawiaj z.
- Wejdź w panel Maluj Obiekty/Tajemny Obiekt i edytuj Enserric Miecz. Zmień nazwę, etykietę, ResRef oraz portret.
- Otwórz skrypt x2_inc_intweapon, korzystając z filtra wszystkie zasoby. Przejdź do linii IWStartIntelligentWeaponConversation i wstaw ResRef wcześniej stworzonego tajemnego obiektu w miejsce x2_plc_intwp. Zapisz.
- Następnie otwórz konwersację x2_iw_enserric, korzystając z filtra wszystkie zasoby. Usuń wszystkie linie dialogowe i stwórz własne, pamiętając o tej dotyczącej uwolnienia Dżina. W linii odnoszącej się do uwolnienia Dżina w zakładce podjęte działania stwórz poniższy skrypt, który spowoduje przywołanie Dżina oferującego towary przy jednoczesnym wyświetleniu efektu wizualnego nad postacią.
Skrypt:
void main()
{
location locLocation = GetLocation (OBJECT_SELF);
object oSpawn = CreateObject (OBJECT_TYPE_CREATURE, "ResRef DŻINA", locLocation, FALSE);
object oStore = CreateObject (OBJECT_TYPE_STORE, "ResRef PUNKTU KUPIECKIEGO", locLocation, FALSE);
effect eVis = EffectVisualEffect (ETYKIETA EFEKTU WIZUALNEGO);
ApplyEffectToObject (DURATION_TYPE_INSTANT, eVis, OBJECT_SELF);
}
- Powyższą konwersację dodaj wcześniej stworzonemu tajemnemu obiektowi.
- Stwórz nową konwersację odnoszącą się do samego Dżina, pamiętając o liniach dialogowych dotyczących odesłania oraz handlu. W linii dotyczącej handlu w zakładce podjęte działania stwórz skrypt przy pomocy Kreatora Skryptów (czerwonawa szpiczasta czapka czarodzieja), wybierając wykonaj działanie/uruchom kupca. W etykiecie skryptu wpisz etykietę punktu kupieckiego. W linii odnoszącej się do odesłania w zakładce podjęte działania stwórz poniższy skrypt, który spowoduje zniknięcie Dżina oraz punktu kupieckiego przy jednoczesnym wyświetleniu efektu wizualnego nad nim.
Skrypt:
void main()
{
object oObject = OBJECT_SELF;
object oStore = GetObjectByTag ("ETYKIETA PUNKTU KUPIECKIEGO");
effect eVis = EffectVisualEffect(ETYKIETA EFEKTU WIZUALNEGO);
DestroyObject (oStore);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oObject);
DelayCommand (0.5, DestroyObject (oObject));
}
- Powyższą konwersację dodaj wcześniej stworzonemu Dżinowi.
Inteligentny przedmiot: Pierścień Translokacji
Opis: Używając pierścienia posiadającego właściwość Rzucanie zaklęcia: Unikalna moc jedynie na sobie, postać teleportuje się do konkretnego punktu nawigacyjnego bez możliwości powrotu do miejsca aktywacji przy jednoczesnym wyświetleniu efektu wizualnego.
Skrypt:
void main()
{
object oPC = GetItemActivator ();
object oTarget = GetObjectByTag ("ETYKIETA PUNKTU NAWIGACYJNEGO");
effect eVis = EffectVisualEffect (ETYKIETA EFEKTU WIZUALNEGO);
DelayCommand (2.0, AssignCommand (oPC, JumpToObject (oTarget)));
ApplyEffectToObject (DURATION_TYPE_INSTANT, eVis, oPC);
}
Gdzie: Nigdzie, jeżeli edytujesz skrypt x2_mod_def_act znajdujący się w Edytuj/Właściwości Modułu/Zdarzenia/OnActivateItem i dodasz poniższe komendy pomiędzy ostatnim a przedostatnim }.
Skrypt:
object oPC = GetItemActivator();
string sItem = GetTag(oItem);
if (sItem == "ETYKIETA PIERŚCINIA") ExecuteScript("NAZWA POWYŻSZEGO SKRYPTU", oPC);
Hazard: gra w 3 kubki
Opis: Gra hazardowa polegająca na odnalezieniu klejnotu pod jednym z kubków po uprzednim ich wymieszaniu. Wszystko w zależności od testu na Spostrzegawczość.
- Wpierw należy stworzyć skrypt sprawdzający, czy postać posiada minimalną kwotę potrzebną do skorzystania z zabawy. W tym wypadku X = Y-1, np. wejściówka kosztuje 10SZ [Y], więc X = 9SZ, bo gracz musi mieć więcej niż 9SZ, by zagrać.
Skrypt:
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(!(GetGold(oPC) > X))
return FALSE;
return TRUE;
}
Gdzie: w zakładce Tekst Pojawia się Gdy wybranej ścieżki dialogowej
- Kolejno pobierana jest opłata Y.
Skrypt:
void main()
{
object oPC = GetPCSpeaker();
TakeGoldFromCreature(Y, oPC, TRUE);
}
Gdzie: w zakładce Podjęte Działania wybranej ścieżki dialogowej
- Poniższy skrypt sprawdza, czy gracz pomyślnie przeszedł test na Spostrzegawczość. Stopień trudności [ST] powinien zależeć od wysokości wygranej – DC_EASY, DC_MEDIUM, DC_HARD.
Skrypt:
#include "nw_i0_tool"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(AutoDC(STOPIEŃ_TRUDNOŚCI, SKILL_SPOT, oPC))
return FALSE;
return TRUE;
}
Gdzie: w zakładce Tekst Pojawia się Gdy wybranej ścieżki dialogowej
- W przypadku wygranej należy wypłacić wygraną [Z], która powinna być wyższa niż opłata.
Skrypt:
void main()
{
object oPC = GetPCSpeaker();
GiveGoldToCreature(oPC, Z);
}
Gdzie: w zakładce Podjęte Działania wybranej ścieżki dialogowej
Hazard: black jack
Opis: Black Jack jest kasynową wersją gry w Oczko. Zadaniem gracza jest zyskać jak najbliżej 21 punktów, lecz nie więcej. Zebranie ponad 21 punktów oznacza automatyczną przegraną. As ma wartość 1 bądź 11, w zależności od wyboru gracza, a karty 2-10 mają wartość równą wartości karty, czyli 5 ma wartość 5. W przypadku otrzymania Asa oraz 10, następuje automatyczna wygrana z tytułu uzyskania Black Jacka. W każdej rundzie możesz wydać krupierowi polecenie, korzystając z funkcji rozmowy, której belkę widać w lewym dolnym krańcu ekranu. By wydać polecenie, należy wcisnąć klawisz Enter i wpisać konkretne polecenie z dalej wymienionych. Start powoduje przekazanie tobie, graczowi, dwóch kart. Hit oznacza prośbę o jeszcze jedną kartę. Suma pozwala na dowiedzenie się, ile aktualnie gracz posiada w kartach. Natomiast Pass uznawane jest za zakończenie kolejki gracza. Wtedy krupier dobiera własne karty, aż nie osiągnie minimum 17 punktów.
- Na początek należy utworzyć skrypt wprowadzający, który powinien znaleźć się w linii dialogowej oznaczającej zgodę na grę.
Skrypt:
void main()
{
SetListening(OBJECT_SELF, TRUE);
SetLocalInt(GetPCSpeaker(),"nPlayingBlackJack",1);
SetLocalInt(OBJECT_SELF,"nPlayingBlackJack",1);
SetLocalInt(OBJECT_SELF, "nMaxPlayers", 1);
SetLocalInt(OBJECT_SELF, "nNumPlayers", 0);
}
Gdzie: w zakładce Podjęte Działania wybranej ścieżki dialogowej
- Następnie należy stworzyć skrypt sprawdzający, czy postać posiada minimalną kwotę potrzebną do skorzystania z zabawy. W tym wypadku X = Y-1, np. wejściówka kosztuje 10SZ [Y], więc X = 9SZ, bo gracz musi mieć więcej niż 9SZ, by zagrać.
Skrypt:
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(!(GetGold(oPC) > X))
return FALSE;
return TRUE;
}
Gdzie: w zakładce Tekst Pojawia się Gdy wybranej ścieżki dialogowej
- W przeciwieństwei do gry w 3 kubki, nie pobieramy opłaty, lecz zapisujemy ją w formie zmiennej, np. jeżeli stawka wynosiła 20, to zmienna powinna również tyle wynosić [W].
Skrypt:
void main()
{
SetLocalInt(OBJECT_SELF, "nWager", W);
}
Gdzie: w zakładce Podjęte Działania wybranej ścieżki dialogowej
- W przeciwieństwei do gry w 3 kubki, nie pobieramy opłaty, lecz zapisujemy ją w formie zmiennej, np. jeżeli stawka wynosiła 20, to zmienna powinna również tyle wynosić [W].
Skrypt:
void main()
{
SetLocalInt(OBJECT_SELF, "nWager", W);
}
Gdzie: w zakładce Podjęte Działania wybranej ścieżki dialogowej
- Poniższy skrypt zmusi gracza i krupiera do zajęcia miejsc przy stole na konkretnych krzesłach w chwili rozpoczęcia rozgrywki.
Skrypt:
void main()
{
object oPC = GetPCSpeaker();
AssignCommand(OBJECT_SELF, ActionSit(GetObjectByTag("ETYKIETA KRZESŁA 1")));
AssignCommand(oPC, ActionSit(GetObjectByTag("ETYKIETA KRZESŁA 2")));
}
Gdzie: w zakładce Podjęte Działania wybranej ścieżki dialogowej
- Ten skrypt umożliwia wykorzystywanie komend głosowych.
Skrypt:
//::///////////////////////////////////////////////
//:: Default: On Spawn In
//:: NW_C2_DEFAULT9
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 25, 2001
//:://////////////////////////////////////////////
#include "NW_O2_CONINCLUDE"
#include "NW_I0_GENERIC"
void main()
{
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
//SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 – 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR – Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR – Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR – Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR – Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR – Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR – Fire User Defined Event 1003
SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR – Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR – Fire User Defined Event 1007
// DEFAULT GENERIC BEHAVIOR (DO NOT TOUCH) *****************************************************************************************
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
GenerateNPCTreasure(); //* Use this to create a small amount of treasure on the creature
SignalEvent(OBJECT_SELF, EventUserDefined(5000));
}
Gdzie: OnSpawn krupiera
- Najważniejszy skrypt łączący resztę w użyteczną całość. Jego autorem jest Keith Warner, a ja przetłumaczyłem go i nieco usprawniłem.
Skrypt:
//::///////////////////////////////////////////////
//:: Default: BLACK JACK USER DEFINED
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
by the Black Jack dealer during the course of a game
*/
//:://////////////////////////////////////////////
//:: Created By: Keith Warner
//:: Created On: July 15, 2002
//:: Translation to Polish & Modification: Lionel, GameExe.pl
//:://////////////////////////////////////////////
void CardCheck();
void AceCheck(int nCard, object oPC);
void InitialDeal(object oPC);
void DealerDrawRemainingCards();
void main()
{
if (GetUserDefinedEventNumber() == 5000)
{
SetListenPattern(OBJECT_SELF, "Start", 500);
SetListenPattern(OBJECT_SELF, "Hit", 1000);
//SetListenPattern(OBJECT_SELF, "Hit Me", 1000);
SetListenPattern(OBJECT_SELF, "Pass", 2000);
SetListenPattern(OBJECT_SELF, "Suma", 3000);
SetListenPattern(OBJECT_SELF, "Koniec", 4000);
SetListenPattern(OBJECT_SELF, "Join", 5000);
SetListening(OBJECT_SELF,FALSE);
}
if (GetUserDefinedEventNumber() == 1004)
{
if (GetIsListening(OBJECT_SELF))
{
object oPC = GetLastSpeaker();
if (GetIsPC(oPC))
{
int nPattern = GetListenPatternNumber();
if (nPattern == 500)
{
if(GetLocalInt(oPC,"nGameOn") == 1)
{
SpeakString("Co pan wyprawia, " + GetName(oPC) + ", już rozpoczął pan grę.");
}
else
{
if (GetGold(oPC) >= GetLocalInt(OBJECT_SELF,"nWager"))
{
SetLocalInt(OBJECT_SELF,"nNumPlayers",GetLocalInt(OBJECT_SELF,"nNumPlayers") + 1);
SetLocalInt(oPC,"nAceCount",0);
SetLocalInt(oPC,"nGameOn",1);
if (GetLocalInt(OBJECT_SELF,"nNumPlayers") < GetLocalInt(OBJECT_SELF,"nMaxPlayers"))
{
InitialDeal(oPC);
DelayCommand(6.0f,SpeakString(GetName(oPC) + ", you are in. Who else? Please say 'Start'."));
}
else
{
SetLocalInt(OBJECT_SELF,"nAceCount",0);
SetLocalInt(OBJECT_SELF,"nDealerTotal",Random(10)+1);
InitialDeal(oPC);
if (GetLocalInt(OBJECT_SELF,"nDealerTotal") == 1)
{
DelayCommand(6.0f,SpeakString("Krupier pokazuje Asa."));
SetLocalInt(OBJECT_SELF,"nAceCount",1);
}
else
{
DelayCommand(6.0f,SpeakString("Krupier pokazuje " + IntToString(GetLocalInt(OBJECT_SELF,"nDealerTotal")) + "."));
}
DelayCommand(7.5f,SpeakString("Co chce pan zrobić, " + GetLocalString(OBJECT_SELF,"Player1Tag") + "?"));
SetLocalString(OBJECT_SELF,"szCurrentPlayer","1");
}
}
else
{
SpeakString(GetName(oPC) + ", nie masz wystarczającej ilości złota. Proszę odejść od stołu. W innym razie będę zmuszony wezwać ochronę.");
SetListening(OBJECT_SELF,FALSE);
SetLocalInt(OBJECT_SELF, "nPlayingBlackJack", 0);
}
}
}
else if (nPattern == 1000)
{
if (GetLocalInt(OBJECT_SELF,"nNumPlayers") < GetLocalInt(OBJECT_SELF,"nMaxPlayers"))
{
SpeakString("Hold your horses! Not everyone is in yet.");
}
else
{
if (GetName(oPC) != GetLocalString(OBJECT_SELF,"Player"+ GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag"))
{
SpeakString("Hold up, " + GetName(oPC) + ", its not your turn. Its " + GetLocalString(OBJECT_SELF,"Player"+ GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag") + "'s turn");
}
else
{
if (GetLocalInt(oPC,"nGameOn") == 1)
{
SetLocalInt(oPC,"nBlackJackNextCard", Random(10)+1);
AceCheck(GetLocalInt(oPC,"nBlackJackNextCard"),oPC);
SetLocalInt(oPC,"nBlackJackTotal", GetLocalInt(oPC,"nBlackJackTotal") + GetLocalInt(oPC,"nBlackJackNextCard"));
if (GetLocalInt(oPC,"nBlackJackNextCard")==1)
{
SpeakString(GetLocalString(OBJECT_SELF,"Player"+ GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag")+". Orzymał pan Asa.");
}
else
{
SpeakString(GetLocalString(OBJECT_SELF,"Player"+ GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag")+". Orzymał pan " + IntToString(GetLocalInt(oPC,"nBlackJackNextCard")) + ".");
}
if (GetLocalInt(oPC,"nAceCount") > 0)
{
int nTempTotal = GetLocalInt(oPC,"nBlackJackTotal")+ 10;
if(nTempTotal > 21)
{
DelayCommand(2.0f, SpeakString("W sumie ma pan " + IntToString(GetLocalInt(oPC,"nBlackJackTotal")) + ". "));
}
else
{
DelayCommand(2.0f, SpeakString("W sumie ma pan " + IntToString(GetLocalInt(oPC,"nBlackJackTotal")) + " lub " + IntToString(nTempTotal) + ". "));
}
}
else
{
DelayCommand(2.0f, SpeakString("W sumie ma pan " + IntToString(GetLocalInt(oPC,"nBlackJackTotal")) + ". "));
}
if (GetLocalInt(oPC,"nBlackJackTotal") > 21)
{
DelayCommand(1.0f,SpeakString("Przedobrzył pan " + GetName(oPC) + "."));
SetLocalInt(oPC,"nBusted",1);
DelayCommand(1.0f,AssignCommand(oPC,PlaySound("as_pl_laughingm2")));
AssignCommand(OBJECT_SELF,PlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING,1.0,1.0));
AssignCommand(OBJECT_SELF,ActionSit(GetObjectByTag("5_chairdealer")));
if(StringToInt(GetLocalString(OBJECT_SELF,"szCurrentPlayer")) == GetLocalInt(OBJECT_SELF,"nMaxPlayers"))
{
DealerDrawRemainingCards();
CardCheck();
}
else
{
SetLocalString(OBJECT_SELF,"szCurrentPlayer",IntToString(StringToInt(GetLocalString(OBJECT_SELF,"szCurrentPlayer"))+ 1));
DelayCommand(4.0f,SpeakString("Co chce pan zrobić, " + GetLocalString(OBJECT_SELF,"Player" + GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag") + "?"));
}
}
else
{
DelayCommand(4.0f,SpeakString("Co chce pan zrobić, " + GetLocalString(OBJECT_SELF,"Player" + GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag") + "?"));
}
}
else
{
SpeakString("Co pan wyprawia, " + GetName(oPC) + ", nie jest pan w trakcie gry.");
}
}
}
}
else if (nPattern == 2000)
{
if (GetName(oPC) != GetLocalString(OBJECT_SELF,"Player"+ GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag"))
{
if (GetLocalInt(oPC,"nGameOn") != 1)
{
SpeakString("Co pan wyprawia, " + GetName(oPC) + "! Jeszcze nie rozpoczęliśmy gry.");
}
else
{
SpeakString("Hold up, its not your turn, " + GetName(oPC) + "! Its your turn, " + GetLocalString(OBJECT_SELF,"Player" + GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag"));
}
}
else
{
if (GetLocalInt(oPC,"nGameOn") != 1)
{
SpeakString("What are you trying to pull, " + GetName(oPC) + "! We haven't even started yet!");
}
else
{
SpeakString(GetName(oPC) + " pasuje.");
if (GetLocalInt(oPC,"nAceCount") > 0)
{
int nTempTotal = GetLocalInt(oPC,"nBlackJackTotal")+ 10;
if (nTempTotal < 22)
{
SetLocalInt(oPC,"nBlackJackTotal",nTempTotal);
}
}
SetLocalString(OBJECT_SELF,"szCurrentPlayer",IntToString(StringToInt(GetLocalString(OBJECT_SELF,"szCurrentPlayer"))+ 1));
if (StringToInt(GetLocalString(OBJECT_SELF,"szCurrentPlayer")) > GetLocalInt(OBJECT_SELF,"nMaxPlayers"))
{
DealerDrawRemainingCards();
CardCheck();
}
else
{
DelayCommand(1.0f,SpeakString("Ok, "+ GetLocalString(OBJECT_SELF,"Player"+ GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag") + ", its your turn"));
}
}
}
}
else if (nPattern == 3000)
{
if (GetLocalInt(oPC,"nGameOn") != 1)
{
SpeakString("Co pan wyprawia, " + GetName(oPC) + "! Jeszcze nie rozpoczęliśmy gry.");
}
else
{
if (GetLocalInt(oPC,"nAceCount") > 0)
{
int nTempTotal = GetLocalInt(oPC,"nBlackJackTotal") + 10;
if (nTempTotal < 22)
{
SpeakString(GetName(oPC) + ", w sumie ma pan " + IntToString(GetLocalInt(oPC,"nBlackJackTotal")) + " lub " + IntToString(nTempTotal) + ". ");
}
else
{
SpeakString(GetName(oPC) + ", w sumie ma pan " + IntToString(GetLocalInt(oPC,"nBlackJackTotal")));
}
}
else
{
SpeakString(GetName(oPC) + ", w sumie ma pan " + IntToString(GetLocalInt(oPC,"nBlackJackTotal")));
}
}
}
else if (nPattern == 4000)
{
object oWP = GetWaypointByTag("WP_blackjackdealer");
SpeakString("Dziękuję za wspaniałą rundę.");
AssignCommand(OBJECT_SELF, ClearAllActions());
AssignCommand(oPC, ClearAllActions());
DelayCommand(0.3, AssignCommand(OBJECT_SELF, ActionMoveToObject(oWP)));
DelayCommand(2.0, SetFacing(270.0));
SetListening(OBJECT_SELF, FALSE);
SetLocalInt(GetPCSpeaker(),"nPlayingBlackJack", 0);
SetLocalInt(OBJECT_SELF,"nPlayingBlackJack", 0);
}
else if (nPattern == 5000)
{
}
}
}
}
}
void CardCheck()
{
int nMax = GetLocalInt(OBJECT_SELF,"nMaxPlayers");
int nCount;
for (nCount = 1;nCount < nMax+1; nCount++)
{
string szName = GetLocalString(OBJECT_SELF,"Player"+ IntToString(nCount)+"Tag");
int nFound = FALSE;
object oPC = GetFirstPC();
while (nFound == FALSE)
{
if (szName == GetName(oPC))
{
nFound = TRUE;
}
else
{
oPC = GetNextPC();
}
}
SetLocalInt(oPC,"nGameOn",0);
if (GetLocalInt(oPC,"nBusted") == 1)
{
DelayCommand(3.75f,SpeakString(szName + ", przekroczył pan 21 punktów, więc przegrywa."));
DelayCommand(5.5f,TakeGoldFromCreature(GetLocalInt(OBJECT_SELF,"nWager"),oPC));
DelayCommand(5.5f,PlayVoiceChat(VOICE_CHAT_CUSS,oPC));
SetLocalInt(oPC,"nBusted",0);
}
else if(GetLocalInt(oPC,"nBlackJack") == 1)
{
DelayCommand(3.25f,SpeakString("BlackJack dla, " + szName + "!"));
DelayCommand(5.5f, GiveGoldToCreature(oPC,(GetLocalInt(OBJECT_SELF,"nWager")*3)/2));
DelayCommand(5.5f,PlayVoiceChat(VOICE_CHAT_CHEER,oPC));
AssignCommand(oPC,PlaySound("as_mg_telepin1"));
SetLocalInt(oPC,"nBlackJack",0);
}
else
{
if (GetLocalInt(OBJECT_SELF,"nBusted") == 1)
{
DelayCommand(4.25f,SpeakString("Przekroczyłem 21 punktów, więc pan wygrał, " + szName + "!"));
DelayCommand(5.5f, GiveGoldToCreature(oPC,GetLocalInt(OBJECT_SELF,"nWager")));
DelayCommand(5.5f,PlayVoiceChat(VOICE_CHAT_CHEER,oPC));
AssignCommand(oPC,PlaySound("as_mg_telepin1"));
}
else
{
if (GetLocalInt(OBJECT_SELF,"nDealerTotal") > GetLocalInt(oPC,"nBlackJackTotal"))
{
DelayCommand(5.0f,SpeakString(szName + ", przegrał pan."));
DelayCommand(5.5f,TakeGoldFromCreature(GetLocalInt(OBJECT_SELF,"nWager"),oPC));
DelayCommand(5.5f,PlayVoiceChat(VOICE_CHAT_CUSS,oPC));
AssignCommand(oPC, PlaySound("as_mg_telepout1"));
}
else if (GetLocalInt(OBJECT_SELF,"nDealerTotal") < GetLocalInt(oPC,"nBlackJackTotal"))
{
DelayCommand(5.75f,SpeakString(szName + ", wygrał pan."));
DelayCommand(5.5f, GiveGoldToCreature(oPC,GetLocalInt(OBJECT_SELF,"nWager")));
DelayCommand(5.5f,PlayVoiceChat(VOICE_CHAT_CHEER,oPC));
AssignCommand(oPC,PlaySound("as_mg_telepin1"));
}
else
{
DelayCommand(6.5f,SpeakString(szName + ", mamy remis."));
DelayCommand(5.5f,PlayVoiceChat(VOICE_CHAT_TAUNT,oPC));
}
}
}
}
SetLocalInt(OBJECT_SELF,"nNumPlayers",0);
SetLocalInt(OBJECT_SELF,"nBusted",0);
}
void AceCheck(int nCard, object oPC)
{
if (nCard == 1)
{
SetLocalInt(oPC,"nAceCount",GetLocalInt(oPC,"nAceCount") + 1);
}
}
void InitialDeal(object oPC)
{
SetLocalInt(oPC,"nBlackJackCard1",Random(10)+1);
AceCheck(GetLocalInt(oPC,"nBlackJackCard1"), oPC);
SetLocalInt(oPC,"nBlackJackCard2",Random(10)+1);
AceCheck(GetLocalInt(oPC,"nBlackJackCard2"), oPC);
SetLocalInt(oPC,"nBlackJackTotal", GetLocalInt(oPC,"nBlackJackCard1") + GetLocalInt(oPC,"nBlackJackCard2"));
SetLocalString(OBJECT_SELF,"Player"+IntToString(GetLocalInt(OBJECT_SELF,"nNumPlayers"))+"Tag",GetName(oPC));
if(GetLocalInt(oPC,"nBlackJackCard1") == 1)
{
if(GetLocalInt(oPC,"nBlackJackCard2") == 1)
{
DelayCommand(2.0f,SpeakString(GetName(oPC) + ", otrzymał pan Asa oraz drugiego Asa."));
}
else
{
DelayCommand(2.0f,SpeakString(GetName(oPC) + ", otrzymał pan Asa oraz " + IntToString(GetLocalInt(oPC,"nBlackJackCard2")) + ". "));
}
}
else
{
if(GetLocalInt(oPC,"nBlackJackCard2") == 1)
{
DelayCommand(2.0f,SpeakString(GetName(oPC) + ", otrzymał pan " + IntToString(GetLocalInt(oPC,"nBlackJackCard1")) + " oraz Asa."));
}
else
{
DelayCommand(2.0f,SpeakString(GetName(oPC) + ", otrzymał pan " + IntToString(GetLocalInt(oPC,"nBlackJackCard1")) + " oraz " + IntToString(GetLocalInt(oPC,"nBlackJackCard2")) + ". "));
}
}
string szTempString = ".";
int nTempTotal = GetLocalInt(oPC,"nBlackJackTotal");
if (GetLocalInt(oPC,"nAceCount") > 0)
{
int nCount;
nTempTotal = nTempTotal + 10;
if (nTempTotal < 22)
{
szTempString = " lub " + IntToString(nTempTotal);
}
}
DelayCommand(4.0f,SpeakString("W sumie ma pan " + IntToString(GetLocalInt(oPC,"nBlackJackTotal")) + szTempString));
if (GetLocalInt(oPC,"nBlackJackTotal") > 20 && GetLocalInt(oPC,"nBlackJackTotal") < 22)
{
DelayCommand(5.0f,SpeakString("BlackJack!"));
SetLocalInt(oPC,"nBlackJack",1);
AssignCommand(oPC,PlaySound("as_cv_bell2"));
}
}
void DealerDrawRemainingCards()
{
string szTempString = "";
{
SetLocalInt(OBJECT_SELF,"nDealerCard2", Random(10)+1);
AceCheck(GetLocalInt(OBJECT_SELF,"nDealerCard2"),OBJECT_SELF);
SetLocalInt(OBJECT_SELF,"nDealerTotal", GetLocalInt(OBJECT_SELF,"nDealerTotal") + GetLocalInt(OBJECT_SELF,"nDealerCard2"));
if (GetLocalInt(OBJECT_SELF,"nDealerCard2") == 1)
{
int nTempTotal = GetLocalInt(OBJECT_SELF,"nDealerTotal") + 10;
if (nTempTotal > 21)
{
szTempString = szTempString + "Krupier wyciąga jednego Asa, w sumie mając " + IntToString(GetLocalInt(OBJECT_SELF,"nDealerTotal")) + ". ";
}
else if (nTempTotal > 16)
{
SetLocalInt(OBJECT_SELF,"nDealerTotal",nTempTotal);
szTempString = szTempString + "Krupier wyciąga jednego Asa, w sumie mając " + IntToString(nTempTotal)+ ". ";
}
else
{
szTempString = szTempString + "Krupier wyciąga jednego Asa, w sumie mając " + IntToString(nTempTotal)+ ". ";
}
}
else
{
szTempString = szTempString + "Krupier wyciąga " + IntToString(GetLocalInt(OBJECT_SELF,"nDealerCard2")) + ", w sumie mając " + IntToString(GetLocalInt(OBJECT_SELF,"nDealerTotal")) + ". ";
}
}
while (GetLocalInt(OBJECT_SELF,"nDealerTotal") < 17);
SetLocalString(OBJECT_SELF,"szDealerDraw",szTempString);
if (GetLocalInt(OBJECT_SELF,"nDealerTotal") > 21)
{
DelayCommand(3.0f,PlayVoiceChat(VOICE_CHAT_CUSS,OBJECT_SELF));
SetLocalInt(OBJECT_SELF,"nBusted",1);
}
DelayCommand(2.0f,SpeakString(GetLocalString(OBJECT_SELF,"szDealerDraw")));
}
Gdzie: UserDefined krupiera
Komentarze
Oto skrypt przywoływanych potworów. Wprowadzając go do oskryptowania onHearthBeat jakiegoś statycznego przedmiotu, np. u mnie była to kadź wróżebna, co kilka sekund pojawiać będą się losowo przyporządkowane istoty, jeżeli będą spełnione warunki, np. w tym przypadku będą istnieć cztery posągi gargulców.
1. czy mógłbyś przetłumaczyc dla mnie niektóre skrypty i podac mi skrypt, w którym mogę zrobic tak że dany tekst pojawia się PO rozmowie z danym NPCem
2 jak dac głos postaciom np. na moim module gdy Aribeth wypowiada jakąś kwestię co zrobic żeby oprócz tekstu mówiła go swoim słodkim głosem?
2. Musisz zatrudnić tę lektorkę, co podkładała głos Ari... tylko jej nazwisko to dla mnie tajemnica, bo jakoś nie ma bazy lektorów w polskim Internecie. Wtedy ona wypowie tekst, nagrasz ją, stworzysz z niego HAK, dołączysz do modułu, dodasz odpowiednie nagranie do linii dialogowej... czyli NIEWYKONALNE.
Skrypt A
gdzie XXXX musi być unikalnym tokenem, np. ari_freedom
Skrypt B
gdzie XXXX musi być tym samym tokenem, co w skrypcie A
Skrypt A umieszczasz w linii dialogowej w zakładce podjęte działania (prawy, dolny róg), która kończy rozmowę z Ari w tym więzieniu i będzie mówiła grze, że już z nią ją odbyłeś.
Skrypt B umieszczasz w linii dialogowej w zakładce tekst pojawia się, gdy (prawy, dolny róg), która ma zaczynać rozmowę z Nasherem o uwolnieniu Ari, dzięki skryptowi B, gra wie, że już rozmawiałeś o tym z Ari i będziesz mógł o tym wspomnieć Nasherowi.
[Dodano po 51 sekundach]
jak zdobywa się odznaczenia na tym forum?
1.Np po rozmowie w konwersacji z jakąś osobą odpowiadam na zadane pytanie ,, wdziałeś mojego szczurka" , że go ,,widziałem , już po nim leży na dole" to po odpowiedzi , ten dziadek z którym rozmawiam ma mnie zaatakować dodam że etykieta jego to OLDMAN
2. Mam do wyboru kilka odpowiedzi gdy nacisnę ,,choć ze mną" do osoba z którą rozmawialem staje sie moim towarzyszem
3. Jak zrobić by po nacisnieciu pomogę tobie moja postać sama podejdzie do dźwigni i ją naciśnie przez co uwolnie kolegę z celi? / + by zadanie uwolnienie kumpla które on dał było po tym zaliczone wraz z PD otrzymanym
4. Jak zrobić by po rozmowie z daną osobą więcej nie pojawiały sie te same pytania??
5. kolo śpi dałem mu skrypta że spi a gdy go zabijam to nie ma jego ciała choć w jego ekwipunku zaznaczyłem że jego rzeczy są do ukradnięcia i zostają przy zwłokach a dodam również że dałem mu że po śmierci zostawia zwłoki
Wiem żę jesteś mistrzem skryptów i proszę o pomoc a i jak możesz dodaj do skryptorium te najprostsze skrypty z wyjaśnieniem bo z nimi też są problemy ;p
Pozdrawiam:)
object oPC = GetPCSpeaker();
object oSelf = OBJECT_SELF;
SetIsTemporaryEnemy(oSelf, oPC);
SetIsTemporaryEnemy(oPC, oSelf);
AssignCommand(oSelf, ActionAttack(oPC));
2.
object oHench = GetObjectByTag("TAG_NAJEMNIKA");
object oPC = GetPCSpeaker();
AddHenchman(oPC, oHench);
3.
ważne, by dźwignia była ustawiona na Zdezaktywowana (Właściwości/Zaawansowane/Początkowy Stan)
object oPC = GetPCSpeaker();
object oLev = GetObjectByTag("TAG_DŹWIGNI");
object oDoor = GetObjectByTag("TAG_DRZWI");
AssignCommand(oPC, ActionForceMoveToObject(oLev));
DelayCommand(3.0, AssignCommand(oLev, ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE,1.0,1.0)));
DelayCommand(4.0, AssignCommand(oDoor, ActionOpenDoor(oDoor)));
AddJournalQuestEntry("TAG_ZADANIA", CYFRA_WPISU_Z_ZADANIA_KOŃCZĄCEGO_GO, oPC, TRUE, FALSE, FALSE);
4.
tzw. skrypt startowy umieszczanym w Edytuj/Właś.Modułu/Zdarzenia/OnClientEnter
object oPC = GetFirstPC();
SetLocalInt(oPC, "NAZWA_STAŁEJ_NP_hermes", 0);
w zakładce Tekst Pojawia się Gdy (ten skrypt oznacza, że gra sprawdza czy nazwana zmienna (np. hermes) jest równa 0, jeśli to prawda, tekst się pojawi)
object oPC = GetPCSpeaker();
if(!(GetLocalInt(oPC, "TA_SAMA_STAŁA_CO_WCZEŚNIEJ") == 0))
return FALSE;
return TRUE;
w zakładce Podjęte Działania (skrypt zmieniający przyporządkowaną liczbę nazwanej zmiennej na 1, przez co nie równa się już 0, więc wcześniejszy skrypt nie zadziała)
object oPC = GetPCSpeaker();
SetLocalInt(oPC, "TA_SAMA_STAŁA_CO_WCZEŚNIEJ", 1);
5.
nie wiem jak pomóc
I jescze jedno jak zrobić by gracz po stworzeniu postaci był odziany tylko w łachmany bez żadnego ekwipunku ??
i hmm przejscie z lokacji do lokacji chciałbym by był taki duży prostokąt bo na końcu lokacji postawiłem las i troche drzew to tam gdzie jest ciemność żeby był prostokąt do nacisniecia do przejscia lokacji ?
Pozdrawiam:)
Cytat
Uwagi:
SetLocalInt(oGracz, "CZYSTKA", 1);
W takim razie na początku powinno się wstawić linijkę:
if(!GetLocalInt(oGracz, "CZYSTKA"))
A wszystko wziąć w klamry tego warunku.
Ten sposób jest najprostszy i najbardziej naturalny, jednak jeśli chcesz coś bardziej skomplikowanego, a więc brak wczytywania gry, tylko zaczynanie nowego modułu za każdym razem, a nie chcesz, byś stracił rzeczy, proponuję dać przedmiot, którego nie można by było usunąć z inwentarza. Wtedy wyglądałoby to następująco:
Na końcu wędruje linijka:
CreateItemOnObject("sandaly_hermesa", oGracz);
A na początku znów obejmujący cały skrypt warunek:
if(!GetIsObjectValid(GetItemPossessedBy(oGracz, "sandaly_hermesa")))
Jeśli rozwiążesz to w ciekawy sposób, może wyjść niegłupio. Jest właściwie multum sposobów na uporanie się z tym problemem. Jest przecież jeszcze coś takiego jak SetCampaing*zmienna*. W każdym razie najprostsze przekazałem.
Pozdrawiam.
A da sie zrobic cos takiego ze w module mozna chodzic tylko jedna postacia tzn. gotową postacią stworzoną w module?
Powiem tak, w Aurorze można zrobić wszystko, ogranicza nas tylko wyobraźnia. Nie wiem jednak co miałeś na myśli.
1. Można chodzić jedynie postacią, którą stworzyłeś na potrzeby modułu? Inaczej - nie można stworzyć nowej postaci, ani wziąć swojej, tylko grać jakąś predefiniowaną?
To bardzo proste, jest bardzo wiele możliwości. Można sprawdzać imię tej postaci, opis, rasę, bóstwo itd. Albo nawet wszystko na raz. Jednak najmądrzejszym sposobem byłoby stworzenie jakiegoś przedmiotu w ekwipunku bohatera, wtedy mógłbyś być niemal pewny, że nie będzie można zagrać inną postacią. Wyglądałoby to tak:
Te kilka linijeczek wystarczy wstawić do zdarzenia modułu OnClientEnter. Zamiast 'etykiety' oczywiście musisz wstawić właściwą etykietkę rzeczy, którą chcesz sprawdzać.
2. Miałeś na myśli, by każdy gracz mógł stworzyć tylko jedną postać, a po wejściu inną miałby zostać wykopywany?
W takim razie sprawa nieco trudniejsza. Na pewno trzeba by stworzyć listę tych graczy.
Znów w OnClientEnter:
Zamiast "obiekt_z_danymi" wystarczy wstawić ResRef istniejącej rzeczy ustawialnej; "punkt_nawigacyjny" to etykieta punktu, w którym ta rzecz ma się stworzyć (najlepiej, jeśli w miejscu niedostępnym dla graczy.
Ważna uwaga: Jeśli skrypt ma działać w grze jednoosobowej, to musisz zmienić linijki z
"BootPC(oGracz)" na:
AssignCommand(oGracz, JumpToObject(GetWaypointByTag("etykieta_punktu_nawigacyjnego")));
Wtedy dajesz etykietę punktu nawigacyjnego jakiegoś obszaru, do którego mają trafiać ukarani gracze.
Ważna uwaga: Skrypt zapisuje nazwy użytkowników, czyli na każde konto przypada jedna postać, po założeniu nowego konta gracz będzie mógł grać innym bohaterem, można i to zablokować, tylko po co aż tak kombinować?
Mam nadzieję, że ta wiadomość pomogła,
Pozdrawiam.
Otóż nie mam pojęcia, w jaki sposób zrobić coś takiego, że postać najpierw zleca questa. Tylko że później jak podchodzę do niej, to robi to wciąż, prawda? Więc problem polega na tym, jak zrobić tak, żeby po przyjęciu questa następowała inna rozmowa.
object oPC = GetFirstPC();
SetLocalInt(oPC, "NAZWA_STAŁEJ_NP_hermes", 0);
w zakładce Tekst Pojawia się Gdy (ten skrypt oznacza, że gra sprawdza czy nazwana zmienna (np. hermes) jest równa 0, jeśli to prawda, tekst się pojawi)
...Ale nie rozumiem tego : /
W tzw. skrypcie startowym umieszczasz wartość zmiennej, której nadajesz unikalną nazwę coś ci mówiącą, np. gregor, bo odnosi się do postaci o takim imieniu. I właśnie w tym skrypcie zazwyczaj podaje się jej wartość 0.
Natomiast w Tekst Pojawia się Gdy wymuszamy na grze, by sprawdziła, czy rzeczywiście zmienna gregor jest równa 0. Jeżeli tak, to dana kwestia się pojawi, jeśli nie, to gra przejdzie do kolejnego rozgałęzienia dialogu. Czyli taki skrypt powinien wyglądać tak:
if(!(GetLocalInt(oPC, "gregor") == 0))
return FALSE;
return TRUE;
Następnie w zakładce Podjęte Działania tej samej linii dialogowej ustawiamy skrypt, który zmieni wartość zmiennej gregor na różną od 0, np. 1, by więcej ta linia dialogowa się nie pojawiła, bo w zakładce Tekst Pojawia się Gdy znajduje się komenda sprawdzenia, czy zmienna gregor = 0, a nie 1. Więc wygląda to tak:
object oPC = GetPCSpeaker();
SetLocalInt(oPC, "gregor", 1);
Najlepiej naukę skryptów rozpocząć od przejrzenia oskryptowania oficjalnej kampanii. Należy pliki z nwm przekopiować do modules i zmienić im rozszerzenie na .mod, dzięki temu w Aurorze będziemy mogli wczytać moduły oficjalnej kampanii. A już tam sobie sprawdzicie jak co działa, może to pomoże.
tomasz95
2.I jeszcze żeby po włożeniu przedmiotu coś się stało np. otworzą się drzwi, jakiś niezniszczalny wróg zostanie zniszczony, dezaktywowany w przypadku golemów, proszę o szybką odpowiedź.
tomasz95
Bo do tego skryptu z rzucaniem zaklęć trzeba przypisać rodzaj zmiennej.
tomasz95
to napisz jak wymyślisz co z tym zrobić.
tomasz95
Lionel,
Na swoim komputerze rób co chcesz ze skryptami, twórz własne filozofie pisania skryptów, ogłaszaj się skryptowym bóstwem, ale proszę, nie wprowadzaj w błąd użytkowników internetu, to błędne koło, niech zostanie w twoich czterech ścianach. Co jakiś czas się taki ktoś jak ty pojawia, mąci w głowie, a potem każdy mówi, że pisanie skryptów jest trudne. Jest to bardzo logiczne, a twoje pomysły są wręcz absurdalne.
Do rzeczy jednak, do zaakceptowania jest inny sposób pisania skryptów, ale co nowicjusz ma powiedzieć na coś takiego?
albo:
Cytat
opcjonalnie:
Cytat
1.
2. Muszę cię zaskoczyć, że nie ma różnicy, czy zmienna ma wartość 0, czy nie istnieje, poniważ taka funkcja jak "GetIsVariableValid" nie powstała i nigdy nie powstanie. Jeszcze jedna uwaga - jeśli zamierzasz nadać zmienną modułowi już na początku, nie musisz pisać żadnego skryptu, bo we właściwościach modułu (i obszaru a także stworzenia) jest zakładka "zmienne".
3. Nie wiem po co tak sztucznie to robić, kiedy chciałbyś zrobić moduł opierający się na kampanii, wtedy w porządku, ale jeśli chcesz tylko przeglądać zawartość, wystarczy przejść kampanie lub otworzyć ją bezpośrednio Aurorą, ewentualnie od razu wpisać w nwnplayer.ini
Jeszcze jedna sprawa:
Po co pisać skrypt, który już istnieje? To samo jest w oryginale, a nazwę, jeśli nie poprzez szukanie, możesz znaleźć w dialogach najemników.
Ciekawe, że dałeś pewnie uwagi co do skryptu z dźwignią, a tutaj ani słowa, a jest to wiele bardziej znaczące. Ponieważ jeśli nie załadujesz zestawu skryptów najemnika, postać jedynie dołączy do twojej drużyny, ale nie będzie za tobą podążała, nie będzie otwierała zamków, pewnie nawet nie będzie cię broniła. A co to za najemnik? Więc napiszę za ciebie: Wchodzimy w zakładkę "Skrypty" najemnika, klikamy "Wczytaj ustawienia skryptu" i wybieramy zestaw najemnika. Chociaż z tego co pamiętam jest tam tylko zestaw najemnika z dodatku, który mimo, że później stworzony, jest wiele gorszy, więc proponuję pierw stworzyć własny zestaw, bazujący na najemniku z podstawki.
Neś,
Masz rację, rozwiązuje się to zmiennymi, ale żadne tam OnClientEnter.
W edytorze konwersacji masz dwie zakładki "Podjęte działania" oraz "Tekst pojawia się gdy"; skrypt z pierwszej zakładki odpala się po wybraniu danej linii dialogowej, a skrypt z drugiej zakładki daje informację, że warunek w nim zamieszczony musi się spełnić, by dana kwestia się wyświetliła.
Co może być mało wygodne, zwykle ostatnie kwestie umieszcza się na początku, czyli dla przykładu:
Katalog główny
1. Jeszcze raz dziękuję za pomoc.
2. Widzę, że masz mojego kotka, bardzo dziękuję!
3. Nadal nie zdjąłeś mojego kotka, zły człowieku!
4. Pomocy, mój kotek utknął na drzewie!
I co z tym fantem zrobić? Ostatnia, czwarta linia dialogowa nie ma skryptu warunkowego (tekst pojawia się gdy), natomiast ma skrypt działania (podjęte działania), wygląda on ni więcej, ni mniej jak:
obiekt - zależy gdzie ten skrypt ma działać, jeśli jest to moduł jednoosobowy, wstaw zamiast tego OBJECT_SELF (dana postać) lub GetModule() (moduł), a jeśli jako moduł wieloosobowy GetPCSpeaker() (gracz rozmawiający)
"Kotek" to tylko nazwa zmiennej, możesz tu wstawić cokolwiek, jednak jeśli zamiast obiektu wstawisz OBJECT_SELF lub GetModule(), ta nazwa nie może się pokrywać z żadną inną nazwą zmiennej.
Trzecia linia dialogowa, czyli pokazująca się jako druga będzie zawierała tylko skrypt warunkowy, który wygląda ni mniej, ni więcej jak:
obiekt i "Kotek" mają być takie same jak w skrypcie pierwszym - chyba nie ma wątpliwości.
Pozwoliłem sobie użyć skrótu, więc może żeby przedstawić ci to bardziej logicznie napiszę bez nich:
Tak to mniej więcej by wyglądało, może teraz troszkę bardziej jasne.
Druga linia dialogowa "Widzę, że masz mojego kotka, bardzo dziękuję!", ta kwestia ma oba skrypty, ponieważ trzeba sprawdzić, czy zabraliśmy kota, oraz oznaczyć, że już przyszliśmy po nagrodę.
warunek:
działanie:
Mam nadzieję, że wszystko jest jasne.
Pierwsza kwestia, która się pojawia już na końcu, kiedy po odebraniu nagrody przychodzimy do zleceniodawcy. Tam tylko warunek, chyba się już domyślasz jaki:
To by było na tyle, chociaż nie umieściłem tu jednego skryptu, który również jest ważny. Mianowicie po zdjęciu tego kotka z drzewa trzeba ustawić wartość zmiennej "Kotek" na 2, wydaje mi się, że po przeczytaniu dokładnym tego, co napisałem sam już będziesz wiedział jak tego dokonać.
Zapomniałem o ważnej informacji - nie myśl, że ta odwrotna kolejność kwestii to jakiś mój chory wymysł, przypuśćmy, że pozamieniamy kolejność na tą logiczną, co wyjdzie? Poważny zleceniodawca będzie do końca świata powtarzał linijkę "Pomocy, mój kotek utknął na drzewie!", ponieważ gra/komputer uzna, że skoro nie ma w tej kwestii warunków, to ją trzeba wyświetlić.
Pozdrawiam.
Tomasz_95,
Obawiam się, że nie mam czasu na odpowiadanie na twoje pytania, polecam jednak zapoznać się najpierw z samym edytorem, bo pytanie:
Cytat
Jest zabawne. Wszystkie skrypty, o których mówileś są w kampanii, wszystkie Podziemiach Stwórców, czy jak nazwali ten obszar. Skrypty na pewno nie są rzeczą, którą opanować trzeba w pierwszej kolejności, najpierw się zabierz za te rzeczy podstawowe, jak właściwości obiektów. A co jeszcze ważne - poznaj samą grę, to bardzo ułatwia sprawę, będziesz wiedział gdzie szukać.
Pozdrawiam.
P.S. Odsyłam do poradnika podstaw skryptowych autorstwa Rigafilma: http://neverwinter.ph...ghlight=#37059
1. Poradnika pisania skryptów nie napiszę, bo z tym mnóstwo roboty, a mam inne zobowiązania też. Ponadto większość wymaganej wiedzy opisana jest w samem Aurorze lub w internecie. Niestety, wymagana jest znajomość języka angielskiego bądź niemieckiego.
2. Rzucanie zaklęcia
3. Jeżeli chodzi o obiekt, który ustawia się na mapie, to lustro ma opcje posiadania wyposażenia, co do drzwi, to one same w sobie nie mają, ale można stworzyć przedmiot, który będzie miał ekwipunek i będzie wyglądał jak drzwi [można poszukać w internecie], lecz nie będzie pełnił ich funkcji - otwierania/zamykania.
4. W OnDisturbed pojemnika.
void main()
{
object oPC = GetLastDisturbed ();
object oItem = GetObjectByTag ("ETYKIETA PRZEDMIOTU");
if
(GetIsObjectValid (oPC) &&
(GetInventoryDisturbType () == INVENTORY_DISTURB_TYPE_ADDED) &&
(GetInventoryDisturbItem () == oItem))
{
TO CO MA SIĘ ZDARZYĆ PO WŁOŻENIU PRZEDMIOTU
}
}
5. Musisz pokazać, co wpisałeś w tym skrypcie. Wklej go całego.
[Dodano po 10 minutach]
Ja? Skryptowy guru? Boskie (´ε` )♡.
Ten temat powstał, by pomagać i ja się tym zajmuję. Nigdy nie pisałem, że znam się całkowicie na skryptowaniu, bo tak nie jest. Moja wiedza, może znikoma, pochodzi z samouctwa, analizowania cudzych skryptów, metody prób i błędów itd. Dzielę się swoją wiedzą z osobami, które mają ambicje tworzenia modułów, ale skryptowanie wydaje im się mroczne, bo i dal mnie kiedyś takie było i czasami wciąż jest.
Cieszę się, że ktoś taki jak ty również próbuje wyjaśniać takie procesy i z pewnością nie omieszkam wykorzystać twoje rady w przyszłości
PS. Mój pokój ma sześć ścian (*^3^).
Sorry przez następny tydzień nic tutaj nie napiszę.
tomasz95
nie znaczy:
tylko:
Opisowo ta pierwsza linijka znaczy: Jeśli zmienna lokalna "Kotek" zapisana na 'obiekcie' ISTNIEJE. Mając wartość ujemną ona istnieje, ponieważ jest różna od zera.
A teraz do rzeczy
Lionel,
Nie myśl, że szukam tu zwady, ale bardzo mnie irytuje, kiedy chętnych graczy zniechęca się do skryptów w ten sposób.
Umieszczanie rzeczy w drzwiach można rozwiązać znów na kilka sposobów, i to niekoniecznie przy wykorzystaniu haków, a nawet powiem, że niekoniecznie one muszą tracić swoje właściwości.
1. Idąc twoim tokiem myślenia można użyć modeli drzwi z podstawki i dodatków (drewniane i metalowe - z animacjami) lub tych z 1.69, co prawda balkonowe, ale nadal drzwi, tylko nie jestem pewien czy mają jakąkolwiek animację.
2. Można to rozwiązać i na typowych drzwiach umieszczonych w zawiasach, z punktu widzenia edytora będzie to oszukańcze, ale gracz może się w ogóle nie zorientować, że umieszcza zawartość swojego ekwipunku w niewidzialnym obiekcie położonym obok drzwi, wystarczy zmienić portret i wszystko powinno grać.
Sprawa kolejna - twój skrypt. Powiedziałeś, że jesteś samoukiem, tylko proszę mi wierzyć, że lepiej czerpać inspiracje z kodów kampanii, zamiast generatora skryptów - bardzo łatwo jest tamtejsze bazgroły poznać.
Spójrz jakie to może być logiczne i proste:
Po pierwsze zaoszczędziłem 4 linijki, ale co ważniejsze zaoszczędziłem troszkę 'energii', interesujesz się ciężkością skryptów, więc chyba sam stwierdzisz, że definiowanie niepotrzebnych zmiennych i porównynwanie ich jest marnotractwem. Na pewno zauważysz też, że wiele lżej jest porównywać ciąg znaków niż całe obiekty, które są wiele większe.
Odbiegając trochę od tematu, mógłbyś mi powiedzieć, co znaczą te wszystkie twoje tekstowe miny? Pierwszy raz je widzę, i nie wiem co przez nie chcesz mi przekazać. Może np. jedna z nich oznacza martwą rybę, czyli grozisz mi śmiercią po sycylijsku.
I ostatnia, mała uwaga. Może to zabrzmi brutalnie, ale jeśli nie znasz skryptów na tyle, by je sensownie przedstawić, to nie wiem dlaczego wyszedłeś z inicjatywą stworzenia tego tematu. Może tylko dlatego, by w przyszłości dopisać do swojej sygnaturki: "Lionel skryptuje..."? Powiem tak, jeśli naprawdę byłbyś w tym dobry, i myślalbyś matematycznie, od razu nasunąłby ci się wniosek, że lepiej jest napisać poradnik, niż tworzyć temat o gotowcach, niby na pierwszy rzut oka cholernie dużo czasu by zajęło (Ja mówię - dwa miesiące, a jeśli jesteś pracowity to i w jeden), ale teraz policz ile czasu straciłeś na odpowiadanie na te wszystkie... nierozsądne pytania, a w niektórych przypadkach wręcz żądania.
Jeszcze raz napiszę to, co na początku, bez tego, obawiam się że rozpęta się tu wojna.
"Nie myśl, że szukam tu zwady, ale bardzo mnie irytuje, kiedy chętnych graczy zniechęca się do skryptów w ten sposób."
Szanuję cię za to, że przyznałeś się do błędu, ale może to czas na podszkolenie się w skryptowaniu, by aktywnie uczestniczyć w tej dyskusji bez wątków dodatkowych w postaci Niemiłego Aleksandra? Jeśli cię jeszcze nie przekonałem, to wspomnę o jednym. Ktoś chyba nawet w tym temacie nazwał cię "Żywą/chodzącą encyklopedią skryptów", a ty się nawet do tego nie odniosłeś, czyli zaakceptowałeś? Powiem szczerze, że chcąc przyjąć ten chwalebny tytuł na twoim miejscu szybciutko wziąłbym się do roboty, by na niego rzeczywiście zasługiwać.
Pozdrawiam.
Dodaj komentarz