Już wyjaśniam.
Dlaczego akurat zmiana ma miejsce co 7 dni ? Skrypt tak robi (źródła questów: rpc.a). Popatrzmy, w inicie (wykonuje się na początku gry) są zdefiniowane 2 zdarzenia które determinują co się będzie działo:
Kod:
on event TIMER2+24*7 callm RPC.PlaceRPCs(No)
on event TIMER2+24 callm RPC.PlaceRPCs(No)
tutaj 'event' to zdarzenie, gra będzie go przetwarzać w interwale czasowym
zmienna 'TIMER2' to zegar godzinowy ('TIMER1' to zegar minutowy)
'calmm' to wywołanie procedury 'PlaceRPCs' (relokacji RPC) z parametrem logicznym (czy dzieje się to po raz pierwszy)
A dzieje się to co 7 dni, zapasowo także codziennie - zobaczmy dlaczego:
procedura 'PlaceRPCs', obejrzyjmy:
Kod:
phrase PlaceRPCs (FirstTime)
na początek wszyscy nierekrutowani są wybierani z listy najmitów do zmiennej 'TmpRef' - pomijani są tylko już zabici i w ekipie gracza
Kod:
for (i=1, i<=AllSubjects SIZE, i++)
TmpRef = AllSubjects Get(i)
if (TmpRef.Live==Yes and has TmpRef IsRPC and not has TmpRef WaitingForPlayer and callm Player.HasInTeam(TmpRef)==No)
this.TmpList add next TmpRef
end if
end for
wszyscy oni mają resetowany sektor gdzie się akurat znajdują (gra zaraz przydzieli nowy)
Kod:
for (i=1, i<=this.TmpList SIZE, i++)
TmpRef = this.TmpList Get(i)
if (TmpRef.Loaded==No)
TmpRef.MySector = NULL
end if
end for
wszyscy poza wybraną piątką najmitów (losowo z listy) znikają z pola widzenia (są w sektorze 'nic') a wybrana piątka ma przydzielany nowy sektor i rozpoczyna się migracja. ale uwaga: jeśli gracz siedzi akurat w sektorze danego najmity, to na jego miejsce losowana jest inna ofiara.
Kod:
local Count = 5
while (Count>0 and this.TmpList SIZE>0)
i = call RND(1, this.TmpList SIZE)
TmpRef = this.TmpList Get(i)
if (TmpRef.UsualSector.Loaded==No)
if (FirstTime==No OR TmpRef.UsualSector==Player.MySector)
TmpRef.SetSector(TmpRef.UsualSector, TmpRef.UsualLocation)
Count--
end if
end if
this.ClearTmpListBySector(TmpRef.UsualSector)
end while
end phrase
Zobaczmy jak wygląda zmiana sektorów ('subject.a'):
Procedura 'SetSector' ma dwa argumenty, 'nazwa sektora' i 'nazwa lokacji w sektorze' (bar/ratusz/itp.) gdzie RPC ma się udać. Wytnę trochę bo jest długa:
Kod:
phrase SetSector(Ref NewSector, String Location)
Skrypt od razu sprawdza czy gracz przypadkiem tu nie siedzi, bo może być wrogiem.
Jeśli gracz akurat siedzi w sektorze (ma wczytany sektor) i międzyczasie gracz stał się wrogiem to najmita dostaje rozkaz opuszczenia sektora i za 10 min procedura jest wywoływana ponownie (w celu przyznania nowego sektora - o ile gracz sobie poszedł).
jeśli gracz nie jest wrogiem to najmita spokojnie maszeruje do swojego miejsca
Kod:
if (this.Loaded==Yes)
if (NewSector!=this.MySector)
throw str(this.ININame) + " destination changed"
on event (TIMER1+10 OR "Character "+str(this.ININame)+" left sector") callm this.SetSector(NewSector, Location)
delete when (str(this.ININame)+" exit command deleted")
this.ExitFromSector()
else
if (call DestinationPlace(this.ININame)!=Location)
call SetToPlace(this.ININame, Location)
this.LocationInSector = Location
else
Jeśli gracz akurat nie siedzi w sektorze to najmita mu przyjazny/nautralny tutaj maszeruje na swoje miejsce, lub
jeśli gracz jest wrogiem to najmita dostaje rozkaz wyniesienia się do wrogiego graczowi sektora
Kod:
if (this.MonsterType==mtGlobal AND NewSector!=NULL AND NewSector.Owner!=NULL AND callm NewSector.Owner.IsEnemyToNPC(this)==Yes)
throw str(this.ININame) + " destination changed"
if (HAS this VitalForSide)
this.VitalForSide.TemporaryMoveActor(this, NewSector, Location, Yes)
else
this.Side.TemporaryMoveActor(this, NewSector, Location, Yes)
end if
exit
end if
Najciekawsze rzeczy dzieją się wówczas kiedy ostatnim razem najmita poszedł 'donikąd' i właśnie z stamtąd wraca, gra wylicza mu czas podróży między jego 'domowym' a wylosowanym sektorem - i tu może się zdarzyć poślizg czasowy z którym się spotkałeś - przyjdzie jak dojdzie:
Kod:
if (NewSector==NULL)
this.MySector = NULL
this.LocationInSector = Location
else
on event TIMER2+call GetTravelTime(this.MySector.Name, NewSector.Name, spFast) callm this.SetSector(NewSector, Location)
end phrase
Czy najmita zawsze będzie w swoim sektorze ? Zobaczmy jak chodzi Snajper ('011SergeyChernyshevSniper.a'):
Kiedy gra uzna że pora na zmiany, to gdzie Snajper idzie ? Jego ulubionym miejscem jest:
Kod:
Ref Attribute UsualSector = ref SudadDeOro
String Attribute UsualLocation = "bar"
zwykle bar w SudadDeOro. Ale (chyba już o tym było) niektórzy najmici są stronniczy, np. pracują tylko z graczem który pracuje dla rządu lub Tani. Załóżmy teraz że trwa wojna a podczas losowania jego macierzysty sektor jest zajęty przez wroga - wówczas najmita się wynosi (komentowałem skrypt) do swoich przyjaciół. Więc, nie każdy najmita będzie na swoim miejscu.
Niektórych z nich nie będzie przez całą grę w ogóle, bo statystycznie gra może ich w ogóle nie wylosować, zaczynają w nicości:
Kod:
initial
SergeyChernyshev.SetSector(NULL, "random")
end initial
i gra może ich dopiero wylosuje.
A jak już wiemy, za każdym razem kiedy najmita wraca z nicości to zanim dojdzie do celu upłynie wyliczony czas podróży między jego ulubionym sektorem a docelowym - stąd poślizgi, u Ciebie doszedł o 3 w nocy.