Zaawansowana walka 3404 10

O temacie

Autor Halicor

Zaczęty 7.02.2016 roku

Wyświetleń 3404

Odpowiedzi 10

Halicor

Halicor

Użytkownicy
Hauptsturmfuhrer
posty365
Propsy57
ProfesjaNierób
  • Użytkownicy
  • Hauptsturmfuhrer
Mam kilka problemów:
1.Zrobiłem npc na wzór Poszukiwacza lecz nie atakuje mnie gdy podejdę.
2.W B_SelectSpell wklepałem taki skrypt if(slf.aivar[AIV_MM_REAL_ID] == ID_Dagon)
   {
   if((self.attribute[ATR_HITPOINTS] < 4000) && (Dagonenrage_onetime == FALSE))
       {
AI_PlayAni(self,"T_GETLOST2");
Wld_PlayEffect("SPELLFX_INSTANTFIREBALL",self,other,1,200,DAM_MAGIC,TRUE);
Dagonenrage_onetime = TRUE;
};
if((self.attribute[ATR_HITPOINTS] < 3000) && (Dagonenrage_onetime == FALSE))
{
AI_PlayAni(self,"T_PRACTICEMAGIC5");
Wld_PlayEffect("spellFX_LIGHTSTAR_RED",self,self,0,0,0,FALSE);
Wld_PlayEffect("FX_EarthQuake",self,self,0,0,0,FALSE);
Npc_ChangeAttribute(self,ATR_HITPOINTS,3000);
Wld_SpawnNpcRange(self,Demon,2,220);
Dagonenrage_onetime = TRUE;
};
if((self.attribute[ATR_HITPOINTS] < 2000) && (Dagonenrage_onetime == FALSE))
{
AI_PlayAni(self,"T_PRACTICEMAGIC5");
AI_PlayAni(oth,"T_DEAD");
AI_Wait(other,3);
Npc_ChangeAttribute(self,ATR_HITPOINTS,1000);
hero.attribute[ATR_HITPOINTS] = 500;
Wld_PlayEffect("spellFX_LIGHTSTAR_RED",self,self,0,0,0,FALSE);
Wld_PlayEffect("spellFX_Fear",other,other,0,0,0,FALSE);
Wld_PlayEffect("spellFX_INCOVATION_RED",self,self,0,0,0,FALSE);
Wld_PlayEffect("FX_EarthQuake",self,self,0,0,0,FALSE);
Dagonenrage_onetime = TRUE;
};
};
tak wiem dużo hp lecz problem leży w tym że boss castuje tylko fireballa i na tym kończy się.
3.Dałem bossowi miecz runiczny lecz gdy on go używa to miecz nie działa func void B_W (var C_NPC oth, var C_NPC slf)
{

   if (Hlp_GetInstanceID(oth) == Hlp_GetInstanceID(hero))
   {
      var C_ITEM ready;
      var int randomdmg;
      var int procent_trafienia;
      var int obrazenia;

      ready = Npc_GetReadiedWeapon(hero);
      randomdmg = Hlp_Random (1);
      procent_trafienia = 100;
      obrazenia = 100;

      if (Npc_HasItems(hero,ItMw_Dagon) == TRUE && Hlp_IsItem(ready,ItMw_Dagon) == TRUE) && (randomdmg <= procent_trafienia)
      {
            if (slf.flags != NPC_FLAG_IMMORTAL)
            {
               Wld_PlayEffect("spellFX_Firestorm_SPREAD", slf, slf, 0, 0, 0, FALSE );
               B_MagicHurtNpc (slf, slf, obrazenia);           
            };
            Wld_PlayEffect("spellFX_InstantFireball_FIRECLOUD", hero, hero, 0, 0, 0, FALSE );
      };
   
      if (Npc_HasItems(hero,ItMw_Dagon) == TRUE && Hlp_IsItem(ready,ItMw_Dagon) == TRUE) && (randomdmg <= procent_trafienia)
      {
            Wld_PlayEffect("spellFX_InstantFireball_FIRECLOUD", hero, hero, 0, 0, 0, FALSE );
      };
   };
};
4.Wpisałem npcowi EquipItem (self, instancja amuletu); lecz on nie zakłada tego amuleta.

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Co do pytania nr 2. Zawsze się wykona pierwszy warunek, gdy ma się HP mniej niż 4000. Równie dobrze może być 10. To i tak wykona się tylko ten
if((self.attribute[ATR_HITPOINTS] < 4000) && (Dagonenrage_onetime == FALSE))Albo odwrócisz kolejność instrukcji warunkowych, albo podasz pełny zakres:
if((self.attribute[ATR_HITPOINTS] < 4000 && self.attribute[ATR_HITPOINTS] >= 3000) && (Dagonenrage_onetime == FALSE))Możesz też użyć konstrukcji:
if ()
{}
else
{}
ale to zależy od tego jak chcesz, żeby to wszystko działało.

Halicor

Halicor

Użytkownicy
Hauptsturmfuhrer
posty365
Propsy57
ProfesjaNierób
  • Użytkownicy
  • Hauptsturmfuhrer
Czyli jeżeli skorzystam z konstrukcji else to będzie to wyglądać tak if((self.attribute[ATR_HITPOINTS] < 4000) && (Dagonenrage_onetime == FALSE))
       {
AI_PlayAni(self,"T_GETLOST2");
Wld_PlayEffect("SPELLFX_INSTANTFIREBALL",self,other,1,200,DAM_MAGIC,TRUE);
Dagonenrage_onetime = TRUE;
}
else
{
   Dagonenrage_onetime == FALSE
};
o ile dobrze zrozumiałem

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Chodziło mi bardziej o
if(self.attribute[ATR_HITPOINTS] < 4000 && self.attribute[ATR_HITPOINTS] >= 3000)
{}
else if(self.attribute[ATR_HITPOINTS] < 3000 && self.attribute[ATR_HITPOINTS] >= 2000)
{}
else
{}
Chociaż nie wiem, czy chcesz, żeby tylko raz został rzucony czar czy też żeby były rzucane czary cały czas, ale zmieniające się ze względu na liczbę HP.

Halicor

Halicor

Użytkownicy
Hauptsturmfuhrer
posty365
Propsy57
ProfesjaNierób
  • Użytkownicy
  • Hauptsturmfuhrer
Lepiej żeby był rzucany raz bo inaczej boss będzie nieśmiertelny.

Kranek

Kranek

Użytkownicy
posty35
Propsy14
ProfesjaNierób
  • Użytkownicy
Ten miecz runiczny... mam rozumieć funkcja B_W() i wywołujesz ją w B_AssessDamage()? Jeśli tak to mam dla ciebie złe wieści. Funkcja B_AssessDamage() dla GRACZA zostanie wywołana co najwyżej raz... tak wynika z moich doświadczeń gdy się nią bawiłem. Doszedłem jedynie do wniosków, że być może bierze się to stąd, iż gracz albo nie ma w ogóle ustawionych, albo ma czyszczone percepcje (Perception.d, radzę spojrzeć). Możesz spróbować jakoś je graczowi ustawić i spróbować ochronić go przed ich wyczyszczeniem. Nie mam pewności czy da się to zrobić zwykłymi skryptami bez żadnego Ikarusa czy innych takich.
 

Siemekk

Siemekk

Złote Wrota
posty2143
Propsy1152
ProfesjaProgramista
  • Złote Wrota
Wut? Jeżeli chcesz aby npc się uzdrowił raz podczas walki to skrypt powinien wyglądać tak...
if((self.attribute[ATR_HITPOINTS] < 3000) && (Dagonenrage_onetime ==false))
       {
AI_PlayAni(self,"T_GETLOST2");
Wld_PlayEffect("SPELLFX_INSTANTFIREBALL",self,other,1,200,DAM_MAGIC,TRUE);
self.attribute[ATR_HITPOINTS]=5000;// nie pamiętam formułki :F
                        Dagonenrage_onetime = true;
                        Print("Test");
};
Warunek Else jest w takim skrypcie niepotrzebny... No chyba że ustawiłbyś zmienną jako liczby wtedy by było więcej uzdrowień i końcówka by wyglądała tak
  Dagonenrage_onetime = 1;
                        Print("Test");
}else if(Dagonenrage_onetime ==1)&& (self.attribute[ATR_HITPOINTS]<3000){
i tak dalej
};
Zaklęcia nie pamiętam jak się ustawiało NPC... Gdzieś był tutorial bodajże.
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Halicor

Halicor

Użytkownicy
Hauptsturmfuhrer
posty365
Propsy57
ProfesjaNierób
  • Użytkownicy
  • Hauptsturmfuhrer

Halicor

Zaawansowana walka
#7 2016-02-08, 00:00(Ostatnia zmiana: 2016-02-08, 15:03)
Jak użyłem konstrukcji "if else" to wszystko działało tylko że boss stawał się nie do zabicia :D wykonywał wszystko dobrze tylko że jak się uleczył to tworzyła się pętla. Dodam że przejrzałem sobie skrypty z L'hivera i wyszło że wyglądają tak samo tylko że tam działają a u mnie nie chcą działać.

Post połączony: 2016-02-08, 00:32
Wielki dzięki Adanos i SiemaczyS :D Jednak amulet nie będzie potrzebny, pozostał tylko miecz runiczny : |

Post połączony: 2016-02-08, 15:03
Dobra dzięki za pomoc, temat do zamknięcia :)

Kranek

Kranek

Użytkownicy
posty35
Propsy14
ProfesjaNierób
  • Użytkownicy
Pokombinowałem trochę z tym twoim mieczem i udało mi się go jakoś uruchomić.

Po pierwsze potrzebujesz stworzyć sobie specjalną funkcję do reagowania na obrażenia dla hero. (W teorii można użyć standardowej B_AsssessDamage() ale tam są robione rzeczy, które herosowi na nic)

Ja u siebie nazwałem ją sobie B_Hero_AssessDamage() i umieściłem w tym samym pliku co B_AsssessDamage().
Wygląda to tak:

var int prev_hp;

func void B_Hero_AssessDamage()
{
if (self.attribute[ATR_HITPOINTS] < prev_hp)
{
B_W();
};
prev_hp = self.attribute[ATR_HITPOINTS];
};

Dodałem sobie warunek i dodatkową zmienną, ponieważ występuje taka sytuacja, gdzie podczas unikania, bądź blokowania moglibyśmy oberwać obrażeniami miecza runicznego, nawet jeżeli ta druga postać nas nie trafia.

Dalej, w kodzie instance PC_Hero na samym końcu jego bloku dodaję linijkę:
Npc_PercEnable(self, PERC_ASSESSDAMAGE, B_Hero_AssessDamage);

Dzięki temu faktycznie funkcja B_Hero_AssessDamage będzie wywoływana gdy ktoś bije herosa.
Zostaje jeszcze sprawa taka, że w pewnych miejscach może się to popsuć. Np. podczas tego gdy nasza postać zostanie powalona, wstanie i nagle się okaże, że miecz runiczny przestaje działać. Dlatego w pliku:
_Work\data\Scripts\Content\AI\Human\ZS_Human\ZS_Unconscious.d

we fragmencie:
func void ZS_Unconscious_End ()
{
// ------ AIV nochmal resetten ------
self.aivar[AIV_RANSACKED] = FALSE;

// ------ aufstehen (auch Spieler) ------
AI_StandUp(self);


// EXIT IF...

// ------ self == Spieler ------
if (Npc_IsPlayer(self))
{
Npc_PercEnable(self, PERC_ASSESSDAMAGE, B_Hero_AssessDamage); //Dodajemy tu ponowne przypisanie naszej funkcji.
return; //Spieler bekommt Kontrolle wieder
};
...
Jeszcze raz ustawiamy tą percepcje. Możliwe, że w innych miejscach również nam się coś popsuje i trzeba będzie to korygować.

A teraz sam kod działania miecza runicznego, zmodyfikowałem go trochę by faktycznie robił co do niego należy:
func void B_W() //Nie ma parametrów, bo przy wywołaniu w AssessDamage self i other są już ustawione globalnie i mamy do nich dostęp. Gdzie self <- osoba obrywająca, other <- atakujący
{
var C_ITEM ready;
var int randomdmg;
var int procent_trafienia;
var int obrazenia;

ready = Npc_GetReadiedWeapon(other);
randomdmg = Hlp_Random(100);
procent_trafienia = 50; //Średnio co drugie uderzenie dostajemy.
obrazenia = 100;

if (Npc_HasItems(other,ItMw_Dagon) == TRUE && Hlp_IsItem(ready,ItMw_Dagon) == TRUE) && (randomdmg <= procent_trafienia)
{
if (self.flags != NPC_FLAG_IMMORTAL)
{
   Wld_PlayEffect("spellFX_Firestorm_SPREAD", other, other, 0, 0, 0, FALSE ); //Efekt odpalany na atakującym. Wiem, trochę to dziwne, ale w przeciwnym wypadku atakujący może zacząć się palić i to dziwnie wygląda, skoro to nie on obrywa.
   B_MagicHurtNpc (other, self, obrazenia);         
};
};
};

W takiej formie powinno to działać tylko jeśli bohater obrywa.
 

nergalpl

nergalpl

Użytkownicy
posty4
Propsy1
Profesjabrak
  • Użytkownicy
var int Dagonenrage_onetime;
var int Dagonenrage_twotime;
var int Dagonenrage_threetime;

if(slf.aivar[AIV_MM_REAL_ID] == ID_Dagon)
   {
   if((self.attribute[ATR_HITPOINTS] < 4000) && (Dagonenrage_onetime == FALSE))
       {
Wld_PlayEffect("SPELLFX_INSTANTFIREBALL",self,other,1,200,DAM_MAGIC,TRUE);
Dagonenrage_onetime = TRUE;
};
if((self.attribute[ATR_HITPOINTS] < 3000) && (Dagonenrage_twotime == FALSE))
{

Wld_PlayEffect("spellFX_LIGHTSTAR_RED",self,self,0,0,0,FALSE);
Wld_PlayEffect("FX_EarthQuake",self,self,0,0,0,FALSE);
Npc_ChangeAttribute(self,ATR_HITPOINTS,3000);
Wld_SpawnNpcRange(self,Demon,2,220);
Dagonenrage_twotime = TRUE;
};
if((self.attribute[ATR_HITPOINTS] < 2000) && (Dagonenrage_threetime == FALSE))
{

Npc_ChangeAttribute(self,ATR_HITPOINTS,1000);
hero.attribute[ATR_HITPOINTS] = 500;
Wld_PlayEffect("spellFX_LIGHTSTAR_RED",self,self,0,0,0,FALSE);
Wld_PlayEffect("spellFX_Fear",other,other,0,0,0,FALSE);
Wld_PlayEffect("spellFX_INCOVATION_RED",self,self,0,0,0,FALSE);
Wld_PlayEffect("FX_EarthQuake",self,self,0,0,0,FALSE);
Dagonenrage_threetime = TRUE;
};
};

Tak powinno działać. :) Może się kilka rzeczy różnić bo testowałem to na orku szamanie i nie chcialem animacji mu wrzucać.

Są drobne błędy składowe, bo przy 3 "wkurzeniu" odbiera mu 1k HP, a Hero "dostaje" 500 AKTUALNEGO HP (testowane na 0lvl wiec hp po walce 540/40 :D )
 

Halicor

Halicor

Użytkownicy
Hauptsturmfuhrer
posty365
Propsy57
ProfesjaNierób
  • Użytkownicy
  • Hauptsturmfuhrer
Ogólnie problem rozwiązałem, Kranek nie testowałem tego bo sobie to odpuściłem :D ale dzięki za pomoc wszystkim. Temat proszę zamknąć.


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