NAZWA: Zadania | Zabicie mutanta “Press F To Win” [CoP]
TWÓRCA: FantomICW, użyto prac z NPŚ
POZIOM TRUDNOŚCI: ŚREDNI
Stosunkowo niedawno użytkownik ap-pro Telnov1996 zadał jedno pytanie:
Cytat
Czy możliwe jest zorganizowanie oskryptowanych scen walki z mutantami ‘Press “F” to win’?
*Do dyskusji włączył się drogi Dorian23Grey, i właściwie ja. Sytuacja wygląda następująco:
- Po pierwsze, na X-Ray sceny z animacjami w stylu CoD, Metro itp. nie są zbyt wygodne do zrobienia.
- Wymagana jest doskonała umiejętność animacji obiektów.
- Musisz ustawić interakcję logiki z timerami i animacjami.
W tej chwili bardzo mało kto to zrobił. Jednak wariant, gdy GG zbliża się do mutanta i zostaje uruchamiony samouczek, po którym następuje wykonanie zabójstwa, jest całkowicie wykonalną funkcją.
Załóżmy, że na Zatonie w obrębie Północnego jeziora osiedlił się wyjątkowy bagienny pseudo-olbrzym, którego nie biorą kule stalkerów. Jedynym szybkim sposobem na pozbycie się go, jest aktywacja artefaktu grawitacyjnego. Gdy GG podejdzie do mutanta z artefaktem, rozpocznie się samouczek z napisem “Aktywuj artefakt”. Po wciśnięciu F, uruchomi się funkcja, która stworzy na miejscu mutanta cząsteczkę rozerwania od anomalii grawitacyjnej.*
PRZYGOTOWANIE DO DZIAŁANIA:
Spoiler
NARZĘDZIA:
Spoiler
-
Notepad++
-
Paint.NET, Adobe Photoshop lub inny edytor tekstur (jeśli ktoś zechce tworzyć unikalną teksturę)
TEKSTURA:
Spoiler
Jeszcze raz, jeśli chcesz stworzyć unikalną teksturę dla swojego mutanta to proszę. Warto zrobić nowy model lub teksturę, bo super fajny pseudo-gigant powinien się jakoś wyróżniać na tle swoich krewnych. Twórca lekcji zrobił słowną “reteksturę” (w cudzysłowie, bo żeby wymazać trochę krwi i “zazielenieć” teksturę - nie można tego nazwać reteksturą) potwora do bagna:
Jeśli ktoś potrzebuje tekstury, to bierzcie (dołączony jest standardowy bump).
CZĄSTECZKI/PARTICLES:
Spoiler
Dla dobrego efektu rozerwania ciała w anomalię, warto użyć cząsteczek od AMK:
amk\\blow_body
amk\\zomb_explode
Kto je ma (lub ma zamiennik) - super, dobrze. Dla tych, którzy ich nie mają, nie martwcie się, trochę później zostaną wrzucone gotowe particles.xr, ale na razie zostaną dołączone dwie wersje tabeli cząsteczek dla obu przypadków.
KOORDYNATY/WSPÓŁRZĘDNE:
Spoiler
Jeśli pracujecie nie w SDK, ale z ACDC, to będziecie musieli wziąć współrzędne miejsca, w którym będzie znajdował się mutant. Miejsce akcji (w przybliżeniu) zaznaczono na mapie:
Twórca pochodził trochę do przodu do wody i odczytał współrzędne:
-19.00901222229,-7.0012526512146,526.37811279297,907875,47
PRAKTYKA:
Spoiler
CZĘŚĆ I - KONFIGI DIALOGÓW:
Spoiler
- W configs/gameplay/dialogs_zaton.xml dodajemy dwa nowe dialogi:
<dialog id="zat_super_psevdogig_take_task_dialog"> <!--Wzięcie zadania-->
<dont_has_info>psevdogig_task_dialog_done</dont_has_info>
<phrase_list>
<phrase id="0">
<text>zat_super_psevdogig_take_task_dialog_0</text>
<next>1</next>
</phrase>
<phrase id="1">
<text>zat_super_psevdogig_take_task_dialog_1</text>
<next>2</next>
</phrase>
<phrase id="2">
<text>zat_super_psevdogig_take_task_dialog_2</text>
<next>3</next>
</phrase>
<phrase id="3">
<text>zat_super_psevdogig_take_task_dialog_3</text>
<next>4</next>
</phrase>
<phrase id="4">
<text>zat_super_psevdogig_take_task_dialog_4</text>
<next>5</next>
</phrase>
<phrase id="5">
<text>zat_super_psevdogig_take_task_dialog_5</text>
<give_info>psevdogig_task_dialog_done</give_info>
<action>dialogs_zaton.give_super_psevdogig_task</action> <!--Wydajemy GG zadanie i artefakt-->
</phrase>
</phrase_list>
</dialog>
<dialog id="zat_super_psevdogig_task_end_dialog">
<has_info>zat_super_psevdogig_af_activation</has_info>
<dont_has_info>psevdogig_task_finished</dont_has_info>
<phrase_list>
<phrase id="0">
<text>zat_super_psevdogig_task_end_dialog_0</text>
<next>1</next>
</phrase>
<phrase id="1">
<text>zat_super_psevdogig_task_end_dialog_1</text>
<give_info>psevdogig_task_finished</give_info>
<action>dialogs_zaton.give_super_psevdogig_task_reward</action> <!--Wydajemy nagrodę-->
</phrase>
</phrase_list>
</dialog>
- Dopisujemy je Brodaczowi (sekcja zat_a2_stalker_barmen, plik character_desc_zaton.xml)
<actor_dialog>zat_super_psevdogig_take_task_dialog</actor_dialog>
<actor_dialog>zat_super_psevdogig_task_end_dialog</actor_dialog>
- W configs/text/rus/st_dialogs_zaton.xml umieszczamy tekst dialogów:
<string id="zat_super_psevdogig_take_task_dialog_0">
<text>Co słychać, Broda? Jest coś nowego?</text>
</string>
<string id="zat_super_psevdogig_take_task_dialog_1">
<text>Cześć. Nic ciekawego nie ma z wyjątkiem tego, że na Północnym jeziorze pojawił się uber-pseudogigant, który nie daje stalkerom (i pseudomięsaczom też, co tu dużo mówić) spokoju... Stwór jest nie do zabicia.. Po naradzie z Gontą, postanowiliśmy spróbować usunąć go za pomocą artefaktu (mówię o pseudogigancie). Odpowiedni artefakt mam, brakuje tylko ochotnika dla tego zadania...</text>
</string>
<string id="zat_super_psevdogig_take_task_dialog_2">
<text>Wiesz.. mógłbym wam pomóc.</text>
</string>
<string id="zat_super_psevdogig_take_task_dialog_3">
<text>Spadłeś z Cementowni? Ta cholera może ciebie w trymiga położyć... Kto później będzie mi arty przynosił? Na kim Pilot będzie zarabiał? Krótko mówiąc, jesteś pewien, że chcesz pomóc?</text>
</string>
<string id="zat_super_psevdogig_take_task_dialog_4">
<text>Tak. Nudzę się, po prostu)00)).</text>
</string>
<string id="zat_super_psevdogig_take_task_dialog_5">
<text>A, okej, powodzenia. Trzymaj "Grawi" dla aktywacji. Bądź ostrożnyБудь аккуратен.</text>
</string>
<string id="zat_super_psevdogig_task_end_dialog_0">
<text>Możesz spać spokojnie, staruszku. Nie ma więcej twojego uber-pseudogigabajta.</text>
</string>
<string id="zat_super_psevdogig_task_end_dialog_1">
<text>Wow, słuchaj, co za spoko gość! Weź sobie ciastko.</text>
</string>
I to wszystko, jeśli chodzi o dialogi. Tutaj wszystko jest proste, więc twórca uznał, aby się szczegółowo o nich nie rozpisywać. Jeśli ta część wydawała ci się trudna, sorry, ale ta lekcja nie jest dla twojego poziomu wiedzy.
CZĘŚĆ II - KONFIG ZADANIA:
Spoiler
- W configs/misc/tm_zaton.ltx dodajemy sekcję zadania:
[zat_super_psevdogig_task]
icon = ui_inGame2_Logovo_krovososov
prior = 10
storyline = false
title = {+zat_super_psevdogig_af_activation} zat_super_psevdogig_task_2, zat_super_psevdogig_task_1
descr = {+zat_super_psevdogig_af_activation} zat_super_psevdogig_task_2_text, at_super_psevdogig_task_1_text
target = {+zat_super_psevdogig_af_activation} zat_a2_stalker_barmen, zat_super_psevdogig_squad
condlist_0 = {+psevdogig_task_finished} complete
Trochę analizy:
- ikonka jest z zadania na usunięcie legowiska pijawek
- zadanie ma dwie fazy: część na likwidację mutanta i część, która wymaga rozmowy z Brodaczem (na tą część, aktualizacja następuje po otrzymaniu infoportion zat_super_psevdogig_af_activation, wrócimy do niej później)
- w pierwszej części, znaczek zadania pada na oddział/squad/obóz mutanta (jego story_id - zat_super_psevdogig_squad), w drugiej - na Brodacza
- zadanie kończy się po otrzymaniu informacji psevdogig_task_finished, która jest wydawana w już stworzonym przez nas dialogu
Jak widzicie, struktura zadania jest bardzo prosta.
- Dopisujemy do configs/text/rus/st_quests_zaton.xml jego tekstową część:
<string id="zat_super_psevdogig_task_1">
<text>Pomoc leworękim: zlikwidować uber-pseudogiganta</text>
</string>
<string id="zat_super_psevdogig_task_1_text">
<text>Miałem rację: wszyscy stalkerzy na Zatonie to krzyworękie bałwany. Muszę za nich usunąć bardzo silnego mutanta na Północnym jeziorze na Zatonie.</text>
</string>
<string id="zat_super_psevdogig_task_2">
<text>Pomoc leworękim: złamać Brodzie nos</text>
</string>
<string id="zat_super_psevdogig_task_2_text">
<text>Chcę powiedzieć kilka słów Brodaczowi. Czemu do jasnej cholery, ten grubas w egzoszkielecie nie powiedział, że na jeziorze czeka na mnie nie uber-pseudogigant, a Zatonowska Hydra?</text>
</string>
Przechodzimy do konfigów mutanta.
CZĘŚĆ III - KONFIGI MUTANTA:
Spoiler
- Plik configs/creatures/m_giant.ltx. Robimy sekcję naszego unikalnego pseudogiganta. Będzie ona praktycznie podobna do zwykłego pseudogiganta:
[super_psevdogig]:m_gigant_e
$spawn = "monsters\gigants\super_psevdogig"
visual = monsters\psevdogigant\psevdogigant_uber ;To nowy model
corpse_visual = monsters\psevdogigant\psevdogigant_uber_dead ;To też
rank = 50 ;Zwiększamy rangę
spec_rank = strong ;Pseudogigant Strong!
radiation_pp_effector_name = postprocess_acidic ;Dodajemy kwaśny/chemiczny postprocess
attack_params = super_psevdogig_attack_params ;Nowa sekcja parametrów ataku
[super_psevdogig_attack_params] ;Zwiększony impuls
;-------------------------------------------------------------------------------------------------------------------------------------------- -
; anim | time[0..1] | hit_power | impulse | impulse_dir (x,y,z) | Field of hit_test (left,right, top, bottom) | Test Dist
;-------------------------------------------------------------------------------------------------------------------------------------------- -
;Bite
stand_attack_0 = 0.25, 0.9, 200, 0.5, 1.0, 0.5, -0.8, 0.8, -1.8, 1.8, 2.6
;Left leg Strike
stand_attack_1 = 0.40, 0.9, 150, 5.0, 2.5, 4.0, -0.6, 0.6, -1.8, 1.8, 3.2
;Bite2
stand_attack_2 = 0.25, 0.9, 200, 0.5, 1.0, 5.0, -0.8, 0.8, -1.8, 1.8, 2.6
stand_attack_run_0= 0.5, 0.9, 600, 0.5, 1.0, 5.0, -0.6, 1.3, -1.8, 1.8, 3.3
jump_attack_1 = 0.1, 2.00, 1600, 0.5, 1.0, 5.0, -1.0, 1.3, -1.6, 1.6, 5.5
- Następnie trzeba stworzyć oddział/obóz mutantowi w configs/misc/squad_descr_zaton.xml:
[zat_super_psevdogig_squad]:online_offline_group
faction = monster_special
npc = super_psevdogig ;NPC w oddziale - nasz pseudogigant
target_smart = zat_sim_2 ;Docelowy smart - wysepka na Północnym jeziorze
spawn_point = zat_sim_2_giant_home ;Spawn point - punkt "legowiska" dla mutanta
story_id = zat_super_psevdogig_squad ;Sid zbiega się z nazwą sekcji (wasz Кэп)
CZĘŚĆ IV - LOGIKA MUTANTA:
Spoiler
- Przede wszystkim otwórz plik logiki smartu wysepki - configs/scripts/zaton/smart/zat_sim_2.ltx, a na dole dodaj sekcję exclusive z linkiem do ekskluzywnej logiki giganta:
[exclusive]
giant = zaton\zat_sim_2_super_psevdogig.ltx
W związku z tym, logika naszego mutanta nazywa się giant.
- Przechodzimy do samej logiki. Tworzymy plik zaton\zat_sim_2_super_psevdogig.ltx. Dopełniamy go:
[logic@giant] ;Nazwa logiki - giant (patrzymy wyżej)
suitable = {=target_squad_name(zat_super_psevdogig_squad)} true ;Logika jest dostępna tylko dla potwora z naszego squada/obozu/oddziału
monster_job = true
prior = 200
active = mob_home@giant
[mob_home@giant]
on_info = %=restore_health% ;Zdrowie mutanta ciągle się zwiększa
;Jeśli dystans do GG jest mniejszy niż 7 metrów i GG ma kwestowy artefakt, a aktywnego tutorialu nie ma, to uruchamia się tutorial rozwalenia pseudogiganta:
on_info2 = {=dist_to_actor_le(7) =actor_has_item(super_psevdogig_af_gravi) !has_active_tutorial} %=run_tutorial(zat_super_psevdogig_af_tutor)%
;Jeśli dystans do GG jest większy niż 7 metrów i GG ma kwestowy artefakt, a tutorial został uruchomiony, to włącza się tutorial likwidacji pseudogiganta:
on_info3 = {=dist_to_actor_ge(7) =actor_has_item(super_psevdogig_af_gravi) =has_active_tutorial} %=stop_tutorial%
;Po otrzymaniu informacji "zat_super_psevdogig_af_activation", zabijamy NPC funkcji "kill_npc" z xr_effects.script:
on_info4 = {+zat_super_psevdogig_af_activation} %=kill_npc%
;Po otrzymaniu informacji "zat_super_psevdogig_af_activation_begin", usuwamy NPC wogóle i uruchamiamy cząsteczki anomalii/rozerwania za pomocą nowej funkcji
on_info5 = {+zat_super_psevdogig_af_activation_begin} %=zat_super_psevdogig_explode_2%
path_home = giant_home ;W way_zaton.ltx to - zat_sim_2_giant_home ("legowisko")
;Ustawienia ochrony "legowiska":
home_min_radius = 20
home_max_radius = 50
aggressive = true
- Nadszedł czas użycia wcześniej uzyskanych koordynatów/współrzędnych. Rozpakowujemy all.spawn z pomocą ACDC lub używamy SDK Level Editor, aby stworzyć punkt dla potwora w way_zaton.ltx:
[zat_sim_2_giant_home]
points = p0
p0:name = wp00
p0:flags = 0x1
p0:position = -19.00901222229,-7.0012526512146,526.37811279297
p0:game_vertex_id = 47
p0:level_vertex_id = 907875
Zbieramy do kupy spawn.
CZĘŚĆ V - KONFIG KWESTOWEGO ARTEFAKTU I TUTORIALU:
Spoiler
- W logice wspomnieliśmy już o przedmiocie super_psevdogig_af_gravi. To jest sekcja kwestowego artefaktu, który będziemy aktywować. Otwieramy configs/misc/quest_items.ltx i dodaj go tam:
[super_psevdogig_af_gravi]:device_pda
visual = dynamics\artefacts\af_gravi.ogf
description = st_af_gravi_descr
inv_name = st_af_gravi_name
inv_name_short = st_af_gravi_name
inv_weight = 0.5
inv_grid_x = 15
inv_grid_y = 0
cost = 12000
can_trade = false ;Nie wolno sprzedać
quest_item = true ;Nie wolno wyrzucić
story_id = super_psevdogig_af_gravi
Standardowa sekcja kwestowego przedmiotu z “rodzicem” device_pda.
- Również w logice ogłosiliśmy uruchomienie tutorialu:
%=run_tutorial(zat_super_psevdogig_af_tutor)%
Wszystkie tutoriale gry znajdują się w pliku configs/ui/game_tutorials.xml. Jest całkiem możliwe, że poniższa sekcja może wydawać się dziwna. W rzeczywistości wszystko jest proste, ale warto lepiej przeanalizować to w osobnych lekcjach odnośnie HUD’a i GUI, więc teraz nie musisz się tym martwić. Najważniejsze parametry:
<zat_super_psevdogig_af_tutor> <!--Nazwa-->
<global_wnd/>
<item>
<disabled_key>quit</disabled_key>
<length_sec/>
<!--Po naciśnięciu F, jest uruchamia się funkcja xr_effects.zat_super_psevdogig_explode_1-->
<action id="use" finalize="1">xr_effects.zat_super_psevdogig_explode_1</action>
<guard_key>use</guard_key>
<!----Niżej są już inne parametry-->
<grab_input>0</grab_input>
<main_wnd>
<!--Różne parametry tekstu. Ustawiono czcionkę na 32 i czerwony kolor (RGB). Sekcja tekstu - st_tutor_af_activation-->
<auto_static start_time="0" length_sec="5000" x="512" y="660" width="300" height="60" alignment="c" stretch="1"la_cyclic="1" la_texture="1" la_alpha="1">
<text font="graffiti32" r="225" g="36" b="36" a="255" align="c">st_tutor_af_activation</text>
</auto_static>
</main_wnd>
</item>
</zat_super_psevdogig_af_tutor> <!--Tutaj sekcja tutorialu kończy się-->
- Następnie dodajemy sekcję tekstową st_tutor_af_activation, na przykład do pliku ui_st_screen.xml:
<string id="st_tutor_af_activation">
<text>Aktywować artefakt ($$ACTION_USE$$)</text>
</string>
$$ACTION_USE$$ oznacza klawisz “Użyj”. Jest to domyślnie klawisz F.
CZĘŚĆ VI - SKRYPTY WSZYSTKIEGO:
Spoiler
- Zacznijmy od dialogów. W każdym z dwóch uruchamiamy po jednej funkcji. Obie funkcje są w dialogs_zaton.script. Pierwsza:
function give_super_psevdogig_task(first_speaker, second_speaker)
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "super_psevdogig_af_gravi") --Wydajemy "Grawi"
task_manager.get_task_manager():give_task("zat_super_psevdogig_task") --Wydajemy zadanie
xr_effects.create_squad(nil, nil, {"zat_super_psevdogig_squad", "zat_sim_2"}) --Spawnujemy squad/obóz/oddział potwora na smart'cie "zat_sim_2"
end
W drugiej będziemy wydawać nagrodę:
function give_super_psevdogig_task_reward(first_speaker, second_speaker)
local items_pack = {
{item = "energy_drink", amount = 2},
{item = "medkit_army", amount = 3},
{item = "antirad", amount = 2},
{item = "vodka", amount = 1},
{item = "conserva", amount = 3},
}
for k,v in pairs(items_pack) do
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, v.item, v.amount)
end
dialogs.relocate_money_to_actor(first_speaker, second_speaker, 3000)
end
Używamy słownie złożonej tablicy items_pack. Każdy jej element składa się z dwóch punktów:
item - sekcja przedmiotu
amount - ilość, którą trzeba wydać
Później jest cykl w postaci standardowego
for k,v in pairs(nazwaTablicy)do
To oznacza, że funkcja niżej może zostać wykonana dla każdego elementu tablicy (v). U nas jest to:
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, v.item, v.amount)
Zwróćcie uwagę na v.item i v.amount.
Cóż, nie widać nic skomplikowanego w wydawaniu pieniędzy dla GG.
- Ostatnią rzeczą, którą musimy zrobić, są dwie funkcje: jedna jest wydawana podczas korzystania z tutoriala, a druga z logiki. Dodajemy pierwszą funkcję do xr_effects.script:
function zat_super_psevdogig_explode_1(actor, npc)
db.actor:give_info_portion("zat_super_psevdogig_af_activation_begin") --Wydajemy informację
remove_item(actor, npc, {"super_psevdogig_af_gravi"}) --Zabieramy GG artefakt (zostaje aktywowany)
end
Znowu nic skomplikowanego. Dwie proste akcje. Warto zauważyć, że remove_item jest również funkcją z xr_effects.script. Teraz dodajemy drugą:
function zat_super_psevdogig_explode_2(actor, npc)
local fx_table_1 = {
[1] = {particle = particles_object("anomaly2\\gravity_blast_final00")},
[2] = {particle = particles_object("anomaly2\\gravity_blast_03")},
[3] = {particle = particles_object("anomaly2\\gravity_blast_05")},
}
local npc_position = npc:position()
for i = 1,3 do
fx_table_1[i].particle:play_at_pos(npc_position)
end
db.actor:give_info_portion("zat_super_psevdogig_af_activation")
remove_squad(nil, nil, {"zat_super_psevdogig_squad"})
local fx_table_2 = {
[1] = {particle = particles_object("anomaly2\\body_tear_00")},
[2] = {particle = particles_object("amk\\blow_body")},
[3] = {particle = particles_object("amk\\zomb_explode")},
}
for i = 1,3 do
fx_table_2[i].particle:play_at_pos(npc_position)
end
end
Mamy dwie tablicy. Każda ma trzy cząsteczki (każda cząsteczka w poniższych funkcjach jest zadeklarowana jako: tablica.particle). Po co trzeba było dzielić ją na dwie tablice? Po prostu lepiej, żeby cząsteczki anomalii grawitacyjnej zostały odtworzone trochę wcześniej, niż cząsteczki ciała rozerwania ciała. Cykl tutaj jest zdefiniowany trochę inaczej:
for i = 1,3 do
Spójrz na ponumerowane elementy tablic, a wszystko stanie się jasne w tym cyklu.
Należy również zauważyć, że skoro funkcja jest wywoływana bezpośrednio z logiki NPC, możemy ustawić wygodną zmienną lokalną, aby zadeklarować pozycję tego NPC w czasie rzeczywistym:
local npc_position = npc:position()
To jest npc, po którym dwukropek to pseudo-gigant (w zasadzie pozycja pseudogiganta). Spójrzcie na argumenty funkcji:
(actor, npc)
Używamy więc zmiennej lokalnej do wykonania funkcji z pętlą/tablicą:
fx_table_1[i].particle:play_at_pos(npc_position)
Przypisano wykonanie silnikowej funkcji play_at_pos przeznaczonej konkretnie dla cząsteczek. Jeśli nie masz cząsteczek AMK, zmieniamy drugą tablicę:
local fx_table_2 = {
[1] = {particle = particles_object("anomaly2\\body_tear_00")},
[2] = {particle = particles_object("anomaly2\\body_tear_01")},
[3] = {particle = particles_object("anomaly2\\body_tear_02")},
}
Poradziliśmy sobie ze wszystkim. Zobaczmy efekty pracy.
EFEKT:
ŹRÓDŁO:
https://ap-pro.ru/forums/topic/1031-cop-kvesty-ubiystvo-mutanta-press-f-to-win/



