Teraz jest Pt 19 kwi, 2024 06:29


Zachowanie cywili

Dział poświęcony edytorowi ArmA II i Operation Arrowhead, czyli tworzeniu misji.
  • Autor
  • Wiadomość
Offline
Avatar użytkownika

tsuki

Porucznik

Porucznik

  • Posty: 491
  • Dołączył(a): Cz 21 sty, 2010 22:33
  • Lokalizacja: z Nienacka

Zachowanie cywili

PostCz 27 maja, 2010 17:17

Przejdę od razu do rzeczy.
To dzieje się, kiedy zginie cywil (onCivKilled.sqf):
Kod: Zaznacz cały
/*do skryptu przekazywane jest: [[Jednostka która zginela,zabojca],miasto w ktorym zginela]
Ma wyswietlac napis kto zabil cywila i w jakim miescie, oraz zminiac zachowanie cywili w okolicy, aby zmienili prędkość poruszania na bieg do wyznaczonych wczesniej waypointow (panika) */

_civ = (_this select 0) select 0; //zabity cywil
_killer = (_this select 0) select 1; //jednostka, ktora zabila
_locName = _this select 1; //nazwa lokacji
if (isPlayer _killer) then //jezeli zabojca byl gracz
{
   _units = nearestObjects [_civ, ["Man"], 100]; //sprawdz wszystkie jednostki w promieniu 100m od _civ
   _unitsCiv = [];
   {
      if ((side _x) == CIVILIAN) then //jezeli jednostka jest cywilem
      {
         _wps = waypoints group(_x); //lista waypointow
         _wpc = (count _wps); //ilosc waypointow
         if(_wpc > 0) then //jezeli sa waypointy
         {
            _wp = [group(_x), (currentWaypoint group _x)]; //_wp = aktualny waypoint
            _wp setWayPointSpeed "FULL"; //pelna predkosc poruszania sie

            group(_x) setCurrentWaypoint _wp; //ponowny nakaz ruszenia sie do miejsca
            _unitsCiv = _unitsCiv + [waypoints group _x]; //dodaj do tablicy jednostek (debug)
         };
      };
      
   } forEach _units; //zrob dla wszystkich znalezionych jednostek
   //_str = format["%1", _unitsCiv]; //debug
   _str = format["%2: %1 zabil(a) cywila.", name _killer, _locName]; //komunikat
   hint _str;
   publicHint = _str;
   publicVariable 'publicHint'; //wyslij do wszystkich (eventHandler w init.sqf)
};
if(true) exitWith {};

To natomiast jest skrypt generujący ruch cywili (wander.sqf):
Kod: Zaznacz cały
if(!isServer) exitWith {};

private["_obj1","_loc","_radius","_str","_r","_a","_dx","_dy","_pos","_vPos","_markerstr"];
_obj1 = _this select 0;  //kontrolowany cywil
_loc = _this select 1; //miasto, w ktorym sie znajduje

waitUntil {alive _obj1}; //poczekaj az jednostka pojawi sie na mapie

_radius = (((size _loc) select 0)+((size _loc) select 1))/2; //sprawdz promien lokacji
//_obj1 setBehaviour "CARELESS";
//_markerstr = createMarker[format["%1",_obj1],position _obj1];
//_markerstr setMarkerShape "ICON";
//_markerstr setMarkerType "DOT";
//-------------------------Marker: debug---------------------------------


while {alive _obj1} do //dopoki cywil zyje
{
   
   //sleep (round(random(15))+10); //stoj troche w waypoincie
   _r = round(random(2*_radius));
   _a = round(random(360));
   
   _dx = ((position _loc) select 0) + _r*cos(_a);
   _dy = ((position _loc) select 1) + _r*sin(_a);   
   
   _pos = [_dx,_dy,0];  //powyzej - losowanie lokacji
   //_vPos = _pos isFlatEmpty [3 ,2*_radius,5,2,0,false,objnull]; //wylaczone dla testow wydajnosci

   _wp = group(_obj1) addWayPoint [_pos, 5]; //stworz nowy waypoint
   _wp setWayPointType "MOVE";
   _wp setWayPointSpeed "LIMITED";  //nadaj atrybuty
   //_markerStr setMarkerPos (getWpPos _wp);  //<- debug
   //hint format["%1", waypoints group _obj1];  //<- debug

              //czekaj az cywil znajdzie sie < 7m od waypointu
   while {((position _obj1) distance getWpPos [group _obj1, currentWaypoint (group _obj1)]) > 7} do
   {
      //_markerstr setMarkerText (waypointSpeed [group _obj1, currentWaypoint (group _obj1)]); //<-debug
      sleep 5;
   };
};

if(true) exitWith{};


Pierwszy skrypt odpalany jest eventHandlerem "KILLED" na każdym ze stworzonych cywili. Normalnie postaci mają chodzic sobie spacerkiem po mieście, aż zostanie zabity jakiś przechodzień, wtedy ma się zacząć panika. To właśnie robi ten skrypt - zmienia prędkość poruszania się do WP na "FULL" i wyświetla kto zabił cywila i gdzie.

Drugi skrypt startuje po stworzeniu jednostki w mieście (też cywila) i ma kontrolować aby zawsze dostawał waypointy i "spacerował sobie". Najpierw losuje miejsce, nadaje waypoint i czeka aż _obj1 dojdzie do swojego punktu trasy na 7m. Robi to w kółko, aż ten cywil zginie.

Nie wiem z jakiej paki to nie działa. Te wszystkie zakomentowane markery w drugim skrypcie pokazywały, że _wp po zabiciu cywila miał zmienione waypointSpeed z "LIMITED" na "FULL", a pomimo to obiekt nadal szedł sobie spacerkiem!

Czy ktoś mądrzejszy ode mnie może mnie oświecić dlaczego to nie działa i zaproponować jakieś rozwiązanie?
Obrazek
Offline
Avatar użytkownika

gremdek

Porucznik

Porucznik

  • Posty: 428
  • Dołączył(a): Pn 27 lut, 2006 15:02

PostCz 27 maja, 2010 19:56

zamiast ustawiać prędkości w waypointach to jest komenda setspeedmode dla grupy.
wtedy ten skrypt generujący trasę nigdy nie wymusi ponownego limited na cywilu bo teraz tak masz. a i tam w komentarzach masz ustawienie careless, zadbaj żeby to się nie pojawiło, zdaję się zachowanie też ogranicza prędkość.

czyli wywalasz to z drugiego skryptu:
Kod: Zaznacz cały
 _wp setWayPointSpeed "LIMITED";  //nadaj atrybuty

a przed pętlą while dodajesz
Kod: Zaznacz cały
group(_obj) setSpeedMode "LIMITED";



a w pierwszym
Kod: Zaznacz cały
_wp setWayPointSpeed "FULL"; //pelna predkosc poruszania sie

zamień na
Kod: Zaznacz cały
group(_x) setSpeedMode "FULL";
:(
Offline
Avatar użytkownika

Kadryl

Major

Major

  • Posty: 883
  • Dołączył(a): Cz 14 wrz, 2006 14:04
  • Lokalizacja: Wa-wa

PostCz 27 maja, 2010 22:21

Strasznie zakręcony skrypt :twisted:
Tak na pierwszy rzut oka to problem może być w aktywacji waypointów.
Jeżeli "Switches the group speed mode when the waypoint becomes active." to oznacza że parametry mozna wprowadzić tylko wtedy gdy aktywuje się waypoint, a nie gdy jest już aktywny.
W tym przypadku rozwiązanie Gremdka powinno rozwiązać problem.

-------------
Ze swojej strony powiem że podobny skrypt również zrealizowałem lecz działanie nieco inne. Mianowicie w pierwszym waypoincie jednostki wstawiłem w aktywacji wywołanie skryptu który przenosi tenże waypoint w nowe losowe miejsce.
Zaleta tego rozwiązania jest to, że skrypt zadziała tylko wtedy, gdy jednostka dojdzie i aktywuje waypoint oraz nie tworzy się ścieżki waypointów.

Kod: Zaznacz cały
;plik zrobiony w sqs.
; losowe sterownie cywilami
;wpisuje w aktywacji następujące wywołanie
;[jednostka, "marker", 200,"LOS","MOVE",  true/false(sledzenie_działania)] exec "k_ster_cyw.sqs"
;wpisy konieczne w init: walka = false; blok_cyw = true

? (!isServer) exitWith {}

@blok_cyw
blok_cyw = false
_zm = count _this
_ob = _this select 0
_cetr = _this select 1
_dys = _this select 2
_beh = _this select 3
_typ = _this select 4
_pokaz = _this select 5

_grp = group _ob
_wek = waypoints _grp
_nr = count _wek
_nr = _nr - 1

_pos = [((getMarkerpos _cetr) select 0) +_dys - random (2*_dys), ((getMarkerpos _cetr) select 1) +_dys - random (2*_dys)]

_wbeh = ["UNCHANGED","CARELESS","SAFE","CARELESS","SAFE","CARELESS","SAFE"]
? (walka) : _wbeh = ["UNCHANGED","AWARE","COMBAT","STEALTH"]

_nrwbeh = count _wbeh
? (_beh == "LOS") : _beh = _wbeh select (floor(random _nrwbeh))

[_grp, _nr] setWaypointBehaviour _beh
[_grp, _nr] setWaypointType _typ
[_grp, _nr] setWaypointPosition [_pos, 10]

? !(_pokaz) : goto "dalej"
_typ = waypointType [_grp, _nr]

_odl = round sqrt( ( ((getpos _ob) select 0) - (_pos select 0) )^2 + ( ((getpos _ob) select 1) - (_pos select 1) )^2)

player globalchat format ["%1, %2, %3, %4", _grp, _typ, _beh, _odl]
_markerstr = createMarker ["blebleble",_pos]
_markerstr setMarkerShape "ICON";"blebleble" setMarkerType "DOT"
_tekst = format ["%1", _grp]; "blebleble" setMarkerText _tekst
"blebleble" setMarkerpos _pos
#dalej
blok_cyw = true
exit

jak widać parametr walka = true aktywuje inne zachowanie się cywili.
Ostatnio edytowano Cz 27 maja, 2010 22:27 przez Kadryl, łącznie edytowano 1 raz
Offline
Avatar użytkownika

tsuki

Porucznik

Porucznik

  • Posty: 491
  • Dołączył(a): Cz 21 sty, 2010 22:33
  • Lokalizacja: z Nienacka

PostCz 27 maja, 2010 22:25

Dzięki ci Gremdziu o Wielki.
Działa.

Jezeli ktoś chce wykorzystać, to mała uwaga (wpadłem na to dopiero teraz):
Jeżeli cywil zostanie zabity, to wszystkie jednostki będą szalały aż do wyznaczenia nowego waypointu. Trzeba "zapamiętać aktualny stan i ustawić go w nowym waypoincie.

KADRYL!
Dałem pomógł tobie zamiast Gremdekowi (tak to się odmienia?). Nie pisz postów jak ja piszę ;P
Obrazek
Offline
Avatar użytkownika

Kadryl

Major

Major

  • Posty: 883
  • Dołączył(a): Cz 14 wrz, 2006 14:04
  • Lokalizacja: Wa-wa

PostCz 27 maja, 2010 22:34

tsuki napisał(a):KADRYL!
Dałem pomógł tobie zamiast Gremdekowi (tak to się odmienia?). Nie pisz postów jak ja piszę ;P

Zaczołem wcześniej, a jak piszę się o skryptach to w 1 min. nie da się skończyć.
Wcale o tego plusa nie walczę, także jak admin potrafi niech zmieni :jezor:


Ależ proszę bardzo ;)
Ostatnio edytowano Pt 28 maja, 2010 11:03 przez Kadryl, łącznie edytowano 2 razy
Offline
Avatar użytkownika

tsuki

Porucznik

Porucznik

  • Posty: 491
  • Dołączył(a): Cz 21 sty, 2010 22:33
  • Lokalizacja: z Nienacka

PostPt 28 maja, 2010 07:41

To był żart, twój skrypt też się przyda. Może nie mi (nie znam sqs), ale komuś innemu. Zasłużyłeś ;).

Swoją drogą, to dlaczego uważasz, że zakręcony? Moim zdaniem zupełnie logiczny:

wander.sqf:

start -> dopóki żyje - wykonuj: [przydziel waypoint => nadaj atrybuty => czekaj aż _obj się zbliży] -> koniec.

onCivKilled.sqf:

start -> jeżeli zabił gracz: [znajdź cywili w okolicy -> każ im biegać -> wyświetl komunikat] -> koniec.

Gdzie tu zagmatwanie?
Obrazek

Powrót do [ArmA II] Edytor

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 31 gości

cron