Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Pisanie skryptów, cz. 8


Rekomendowane odpowiedzi

Opublikowano

http://www.mpcforum.pl/topic/1276664-pisanie-skryptow-cz-9/ - Część 9

http://www.mpcforum.pl/topic/1273792-pisanie-skryptow-cz-7/ - Część 7
http://www.mpcforum.pl/topic/1273566-pisanie-skryptow-cz-6/ - Część 6
http://www.mpcforum.pl/topic/1232331-pisanie-skryptow-cz-5/ - Część 5
http://www.mpcforum.pl/topic/1231168-pisanie-skryptow-cz-4/ - Część 4
http://www.mpcforum.pl/topic/1230769-pisanie-skryptow-cz-3/ - Część 3
http://www.mpcforum.pl/topic/1230734-pisanie-skryptow-cz-2/ - Część 2
http://www.mpcforum.pl/topic/1230572-pisanie-skryptow-cz-1/ - Część 1

Czołem!

W tej części poradnika zajmiemy się czymś trudniejszym, mianowicie użyjemy VPrediction. Będzie to dość prosty i podstawowy poradnik na ten temat i niewykluczone, że @Marcoly zrobi ciąg dalszy. Będziemy potrzebowali postaci ze skillshotami, ja użyję Nidalee ze względu na swoje długodystansowe Q.

1. Przygotowania.

Oczywiście na starcie musimy wgrać VPrediction. Pobieramy https://raw.githubusercontent.com/Hellsing/BoL/master/common/VPrediction.lua i wsadzamy do Common.
Teraz tworzymy nowy skrypt
Dodatkowo na starcie, czyli dokładnie w pierwszej linijce swojego skryptu dopisujemy

require "VPrediction"

oraz w naszej funkcji InitVars dopisujemy

VP = VPrediction()

Powyższa linijka służy jedynie skróceniu sobie kodu i zamiast pisać VPrediction():GetLineCastPosition napiszemy VP:GetLineCastPosition.
Dodatkowo będziemy potrzebowali następujących danych spella:
- opóźnienia przy castowaniu spella (w przypadku Q Nidy wynosi ona 0.25 sek)
- szerokości spella
- zasięgu spella
- prędkości spella
Podpowiem już, oto statystyki Q Nidalee:
479331408795448358546.jpg
Teraz tworzymy listę spella Q:
 

SpellQ = {id = "Q", delay = 0.25, width = 40, speed = 1300, range = 1500, ready = false}

Tworzymy także Target Selector z zasięgiem Q

 

ts = TargetSelector(TARGET_LOW_HP_PRIORITY,SpellQ.range)

I sprawdzenie, czy Q jest dostępne
 

SpellQ.ready = (myHero:CanUseSpell(_Q) == READY)

Wszystko to umieszczamy w naszej funkcji InitVars:

function InitVars()
     SpellQ = {id = "Q", delay = 0.25, width = 40, speed = 1300, range = 1500, ready = false}

     SpellQ.ready = (myHero:CanUseSpell(_Q) == READY)

     ts = TargetSelector(TARGET_LOW_HP_PRIORITY,SpellQ.range)

     VP = VPrediction()
end

2. VPrediction w użyciu.

Wreszcie doczekaliście się tego, czas na użycie VP w skrypcie. Oto linijka kodu przedstawiająca przewidywanie skillshota linearnego (czyli np. Q Nidy):

local CastPosition,  HitChance,  Position = VP:GetLineCastPosition(hero, delay, width, range, speed, from, collision)

Nie jest to wcale takie trudne, jak się wydaje. Czas na objaśnienie:
local - zmienna jest tworzona w obrębie danej funkcji.
CastPosition - miejsce, gdzie spell powinien zostać wycastowany.
HitChance - szansa na trafienie (zaraz zostanie to opisane)
Position - miejsce, gdzie wróg powinien się znajdować w momencie dotarcia skillshota
VP:GetLineCastPosition() - funkcja przewidująca skillshota linearnego.
hero - cel, w który chcemy strzelić skillshota.
delay - opóźnienie w sekundach między kliknięciem Q a wystrzeleniem skillshota.
width - szerokość skillshota.
range - zasięg skillshota.
speed - prędkość przemieszczania się skillshota w jednostach na sekundę.
from - miejsce, z którego skillshot ma zostać wystrzelony.
collision - czy kolizja ma być uwzględniana. Typ logiczny - true/false.
 
Wracamy do HitChance. Jest to liczba od -1 do 5, która wskazuje szansę na trafienie.

  • -1: Kolizja wykryta.
  • 0: Brak możliwości na przewidzenie miejsca trafienia celu
  • 1: Mała szansa na trafienie celu.
  • 2: Duża szansa na trafienie celu.
  • 3: Cel spowolniony lub bardzo blisko (szansa na trafienie ~100%)
  • 4: Cel unieruchomiony (szansa na trafienie ~100%)
  • 5: Cel jest w trakcie dashowania (szansa na trafienie ~100%)

Zazwyczaj chcemy trafić skillshotem, więc będziemy musieli sprawdzić, czy HitChance jest większy/równy 2.
 
Skoro już wiemy, co oznaczają te parametry, czas na wstawienie tam wartości spella Q.

local CastPosition,  HitChance,  Position = VP:GetLineCastPosition(ts.target, SpellQ.delay, SpellQ.width, SpellQ.range, SpellQ.speed, myHero, true)

6. parametr to myHero, bo wystrzeliwujemy skillshota z siebie. Huh.
 
Teraz sprawdzamy, czy mamy dużą szansę na trafienie celu. Jeżeli tak, to castujemy spella! Piszemy:

if HitChance >= 2 then
     CastSpell(_Q, CastPosition.x, CastPosition.z)
end

Tłumacząc na polski: Jeżeli HitChance jest większy/równy 2, wycastuj Q w miejsce, gdzie spell powinien zostać wycastowany.
Robimy teraz całą funkcję castowania Q, przy okazji dodając rutynowe checki:

function CastQ()
     if SpellQ.ready then
          local CastPosition,  HitChance,  Position = VP:GetLineCastPosition(ts.target, SpellQ.delay, SpellQ.width, SpellQ.range, SpellQ.speed, myHero, true)
          if HitChance >= 2 then
               CastSpell(_Q, CastPosition.x, CastPosition.z)
          end
     end
end

Dodajmy jeszcze: ts:update(), sprawdzenie, czy cel ~= nil, config i drawing zasięgu Q. Oto końcowy kod:
 

require "VPrediction"

function OnLoad()
     InitVars()
     InitConfig()
end

function OnTick()
     ts:update()
     SpellQ.ready = (myHero:CanUseSpell(_Q) == READY)
     if (ts.target ~= nil) then
          if (Config.useq) then
               CastQ()
          end
     end
end

function OnDraw()
     DrawQ()
end

function CastQ()
     if SpellQ.ready then
          local CastPosition,  HitChance,  Position = VP:GetLineCastPosition(ts.target, SpellQ.delay, SpellQ.width, SpellQ.range, SpellQ.speed, myHero, true)
          if HitChance >= 2 then
               CastSpell(_Q, CastPosition.x, CastPosition.z)
          end
     end
end

function DrawQ()
     if (Config.drawq) then
          DrawCircle(myHero.x, myHero.y, myHero.z, SpellQ.range, 0xFFFF00)
     end
end

function InitConfig()
     Config = scriptConfig("Nidalee Q Script", "nidaqscript")
     Config:addParam("useq", "Uzyj " .. SpellQ.id, SCRIPT_PARAM_ONKEYDOWN, false, 32)
     Config:addParam("drawq", "Rysuj zasieg " .. SpellQ.id, SCRIPT_PARAM_ONKEYTOGGLE, true, string.byte("L"))
end

function InitVars()
     VP = VPrediction()
     
     SpellQ = {id = "Q", delay = 0.25, width = 40, speed = 1300, range = 1500, ready = false}

     ts = TargetSelector(TARGET_LOW_HP_PRIORITY,SpellQ.range)
end

To wszystko na dzisiaj. BYĆ MOŻE dodam później jeszcze poradnik o VPrediction z użyciem spelli AoE.
Jeżeli wyskakują wam jakieś błędy, piszcie tutaj. Postaram się pomóc.
Polecam też bardziej zaawansowane poradniki Marcoly'ego:
http://www.mpcforum.pl/topic/1226948-api-sidas-auto-carry/
http://www.mpcforum.pl/topic/1157768-zastosowanie-lag-free-circles-we-wlasnym-skrypcie/
http://www.mpcforum.pl/topic/1229945-buffy-advanced-callbacks-vip/
Credits:
Marcoly

Skończ proszę się kompromitować. Jesteś nikim.

Opublikowano

Mogę jeszcze wytłumaczyć pokrótce jak wycastować AOE spelle.

 

Wszystko niewiele się różni od linearnych:

function CastQ()
	if ts.target ~= nil and GetDistance(ts.target) <= SpellQ.range and SpellQ.ready then
		local AOECastPosition, MainTargetHitChance, nTargets = VP:GetCircularAOECastPosition(ts.target, SpellQ.delay, SpellQ.width, SpellQ.range, SpellQ.speed, myHero)
		
		if MainTargetHitChance >= 2 then
			CastSpell(_Q, AOECastPosition.x, AOECastPosition.z)
		end
	end
end
  • AOECastPosition - przewidziana pozycja targetu,
  • MainHitChance - prawdopodobieństwo trafienia głównego celu (ts.target),
  • nTargets - liczba celów, które zostaną trafione.

Zmieniają się tylko nazwy zmiennych, ale dodatkowo możemy sprawdzić liczbę targetów, które zostaną trafione, np:

if nTargets <= 2 then return end

Jeśli liczba targetów będzie mniejsza lub równa 2, nic się nie stanie.

Opublikowano

Mogę jeszcze wytłumaczyć pokrótce jak wycastować AOE spelle.

 

Wszystko niewiele się różni od linearnych:

function CastQ()
	if ts.target ~= nil and GetDistance(ts.target) <= SpellQ.range and SpellQ.ready then
		local AOECastPosition, MainTargetHitChance, nTargets = VP:GetCircularAOECastPosition(ts.target, SpellQ.delay, SpellQ.width, SpellQ.range, SpellQ.speed, myHero)
		
		if MainTargetHitChance >= 2 then
			CastSpell(_Q, AOECastPosition.x, AOECastPosition.z)
		end
	end
end
  • AOECastPosition - przewidziana pozycja targetu,
  • MainHitChance - prawdopodobieństwo trafienia głównego celu (ts.target),
  • nTargets - liczba celów, które zostaną trafione.

Zmieniają się tylko nazwy zmiennych, ale dodatkowo możemy sprawdzić liczbę targetów, które zostaną trafione, np:

if nTargets <= 2 then return end

Jeśli liczba targetów będzie mniejsza lub równa 2, nic się nie stanie.

Marcoly zawsze wytłumaczy ;-;

Skończ proszę się kompromitować. Jesteś nikim.

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...