中国虚拟军事网(VME)- 专注于武装突袭系列虚拟军事游戏

 找回密码
 加入VME

QQ登录

只需一步,快速开始

搜索
查看: 1505|回复: 3

[求助] UPS巡逻脚本??听说很经典 但就是没找到任何有关资料?

[复制链接]
发表于 2014-7-14 20:12:10 | 显示全部楼层 |阅读模式
作为一个新手,从闪点1玩到武装2,编辑器的问题一直没深入下去,就停留在路点和同步线的使用。
最近想试试脚本,编辑一个城市内士兵大范围随机巡逻的效果,我听说有个UPS巡逻很有名?我翻过论坛了,就找出一个地址,还是链接到外网的,我外网根本就是该网页无法显示,也没什么介绍。要么是我眼拙?还是论坛没有关于UPS的有关于UPS脚本的资料?
百度找烂了也没什么有用的讯息,所以问下谁有UPS这个脚本能发下么?最好能说明下使用方法。不然给我一个脚本我还得满世界找这个脚本能达成什么效果
发表于 2014-7-14 20:33:16 | 显示全部楼层
urban partrol system
http://www.armaholic.com/ 右上角点search,然后输入UPS , 搜索
发表于 2014-7-15 02:37:56 | 显示全部楼层
  1. // =========================================================================================================
  2. //  Urban Patrol Script  
  3. //  Version: 2.1.0
  4. //  Author: Kronzky (www.kronzky.info / kronzky@gmail.com)
  5. // ---------------------------------------------------------------------------------------------------------
  6. //  Required parameters:
  7. //    unit          = Unit to patrol area (1st argument)
  8. //    markername    = Name of marker that covers the active area. (2nd argument)
  9. //    (e.g. nul=[this,"town"] execVM "ups.sqf")
  10. //
  11. //  Optional parameters:
  12. //    random        = Place unit at random start position.
  13. //    randomdn      = Only use random positions on ground level.
  14. //    randomup      = Only use random positions at top building positions.
  15. //    min:n/max:n   = Create a random number (between min and max) of 'clones'.
  16. //    init:string   = Cloned units' init string.
  17. //    prefix:string = Cloned units' names will start with this prefix.
  18. //    nomove        = Unit will stay at start position until enemy is spotted.
  19. //    nofollow      = Unit will only follow an enemy within the marker area.
  20. //    delete:n      = Delete dead units after 'n' seconds.
  21. //    nowait        = Do not wait at patrol end points.
  22. //    noslow        = Keep default behaviour of unit (don't change to "safe" and "limited").
  23. //    noai          = Don't use enhanced AI for evasive and flanking maneuvers.
  24. //    showmarker    = Display the area marker.
  25. //    trigger       = Display a message when no more units are left in sector.
  26. //    empty:n       = Consider area empty, even if 'n' units are left.
  27. //    track         = Display a position and destination marker for each unit.
  28. //
  29. // =========================================================================================================

  30. if (!isServer) exitWith {};
  31.        
  32. // how far opfors should move away if they're under attack
  33. // set this to 200-300, when using the script in open areas (rural surroundings)
  34. #define SAFEDIST 75

  35. // how close unit has to be to target to generate a new one
  36. #define CLOSEENOUGH 10

  37. // how close units have to be to each other to share information
  38. #define SHAREDIST 100

  39. // how long AI units should be in alert mode after initially spotting an enemy
  40. #define ALERTTIME 180

  41. // ---------------------------------------------------------------------------------------------------------
  42. //echo format["[K] %1",_this];

  43. // convert argument list to uppercase
  44. _UCthis = [];
  45. for [{_i=0},{_i<count _this},{_i=_i+1}] do {_e=_this select _i; if (typeName _e=="STRING") then {_e=toUpper(_e)};_UCthis set [_i,_e]};

  46. // ***************************************** SERVER INITIALIZATION *****************************************

  47.         // global functions
  48. if (isNil("KRON_UPS_INIT")) then {
  49.         KRON_UPS_INIT=0;

  50.         // find a random position within a radius
  51.         KRON_randomPos = {private["_cx","_cy","_rx","_ry","_cd","_sd","_ad","_tx","_ty","_xout","_yout"];_cx=_this select 0; _cy=_this select 1; _rx=_this select 2; _ry=_this select 3; _cd=_this select 4; _sd=_this select 5; _ad=_this select 6; _tx=random (_rx*2)-_rx; _ty=random (_ry*2)-_ry; _xout=if (_ad!=0) then {_cx+ (_cd*_tx - _sd*_ty)} else {_cx+_tx}; _yout=if (_ad!=0) then {_cy+ (_sd*_tx + _cd*_ty)} else {_cy+_ty}; [_xout,_yout]};
  52.         // find any building (and its possible building positions) near a position
  53.         KRON_PosInfo = {private["_pos","_lst","_bld","_bldpos"];_pos=_this select 0; _lst= nearestObjects [_pos,["House","vbs2_house"],20]; if (count _lst==0) then {_bld=0;_bldpos=0} else {_bld=_lst select 0; _bldpos=[_bld] call KRON_BldPos}; [_bld,_bldpos]};
  54.         /// find the highest building position       
  55.         KRON_BldPos = {private ["_bld","_bi","_bldpos","_maxZ","_bp","_bz","_higher"];_bld=_this select 0;_maxZ=0;_bi=0;_bldpos=0;while {_bi>=0} do {_bp = _bld BuildingPos _bi;if ((_bp select 0)==0) then {_bi=-99} else {_bz=_bp select 2; _higher = ((_bz>_maxZ) || ((abs(_bz-_maxZ)<.5) && (random 1>.5))); if ((_bz>4) && _higher) then {_maxZ=_bz; _bldpos=_bi}};_bi=_bi+1};_bldpos};
  56.         KRON_OnRoad = {private["_pos","_car","_tries","_lst"];_pos=_this select 0; _car=_this select 1; _tries=_this select 2; _lst=_pos nearRoads 4; if ((count _lst!=0) && (_car || !(surfaceIsWater _pos))) then {_tries=99}; (_tries+1)};
  57.         KRON_getDirPos = {private["_a","_b","_from","_to","_return"]; _from = _this select 0; _to = _this select 1; _return = 0; _a = ((_to select 0) - (_from select 0)); _b = ((_to select 1) - (_from select 1)); if (_a != 0 || _b != 0) then {_return = _a atan2 _b}; if ( _return < 0 ) then { _return = _return + 360 }; _return};
  58.         KRON_distancePosSqr = {(((_this select 0) select 0)-((_this select 1) select 0))^2 + (((_this select 0) select 1)-((_this select 1) select 1))^2};
  59.         KRON_relPos = {private["_p","_d","_a","_x","_y","_xout","_yout"];_p=_this select 0; _x=_p select 0; _y=_p select 1; _d=_this select 1; _a=_this select 2; _xout=_x + sin(_a)*_d; _yout=_y + cos(_a)*_d;[_xout,_yout,0]};
  60.         KRON_rotpoint = {private["_cp","_a","_tx","_ty","_cd","_sd","_cx","_cy","_xout","_yout"];_cp=_this select 0; _cx=_cp select 0; _cy=_cp select 1; _a=_this select 1; _cd=cos(_a*-1); _sd=sin(_a*-1); _tx=_this select 2; _ty=_this select 3; _xout=if (_a!=0) then {_cx+ (_cd*_tx - _sd*_ty)} else {_cx+_tx}; _yout=if (_a!=0) then {_cy+ (_sd*_tx + _cd*_ty)} else {_cy+_ty}; [_xout,_yout,0]};
  61.         KRON_stayInside = {
  62.                 private["_np","_nx","_ny","_cp","_cx","_cy","_rx","_ry","_d","_tp","_tx","_ty","_fx","_fy"];
  63.                 _np=_this select 0;        _nx=_np select 0;        _ny=_np select 1;
  64.                 _cp=_this select 1;        _cx=_cp select 0;        _cy=_cp select 1;
  65.                 _rx=_this select 2;        _ry=_this select 3;        _d=_this select 4;
  66.                 _tp = [_cp,_d,(_nx-_cx),(_ny-_cy)] call KRON_rotpoint;
  67.                 _tx = _tp select 0; _fx=_tx;
  68.                 _ty = _tp select 1; _fy=_ty;
  69.                 if (_tx<(_cx-_rx)) then {_fx=_cx-_rx};
  70.                 if (_tx>(_cx+_rx)) then {_fx=_cx+_rx};
  71.                 if (_ty<(_cy-_ry)) then {_fy=_cy-_ry};
  72.                 if (_ty>(_cy+_ry)) then {_fy=_cy+_ry};
  73.                 if ((_fx!=_tx) || (_fy!=_ty)) then {_np = [_cp,_d*-1,(_fx-_cx),(_fy-_cy)] call KRON_rotpoint};
  74.                 _np;
  75.         };
  76.         // Misc
  77.         KRON_getArg = {private["_cmd","_arg","_list","_a","_v"]; _cmd=_this select 0; _arg=_this select 1; _list=_this select 2; _a=-1; {_a=_a+1; _v=format["%1",_list select _a]; if (_v==_cmd) then {_arg=(_list select _a+1)}} foreach _list; _arg};
  78.         KRON_deleteDead = {private["_u","_s"];_u=_this select 0; _s= _this select 1; _u removeAllEventHandlers "killed"; sleep _s; deletevehicle _u};
  79.        
  80.         KRON_AllWest=[];
  81.         KRON_AllEast=[];
  82.         KRON_AllRes=[];
  83.         KRON_KnownEnemy=[objNull,objNull];
  84.        
  85.         // find all units in mission
  86.         {
  87.                 _s = side _x;
  88.                 switch (_s) do {
  89.                         case west:
  90.                                 { KRON_AllWest=KRON_AllWest+[_x]; };
  91.                         case east:
  92.                                 { KRON_AllEast=KRON_AllEast+[_x]; };
  93.                         case resistance:
  94.                                 { KRON_AllRes=KRON_AllRes+[_x]; };
  95.                 };
  96.         }forEach allUnits;

  97.         if (isNil("KRON_UPS_Debug")) then {KRON_UPS_Debug=0};
  98.         KRON_HQ="Logic" createVehicle [0,0];
  99.         KRON_UPS_Instances=0;
  100.         KRON_UPS_Total=0;
  101.         KRON_UPS_Exited=0;
  102.         KRON_UPS_INIT=1;
  103. };
  104. if ((count _this)<2) exitWith {
  105.         if (format["%1",_this]!="INIT") then {hint "UPS: Unit and marker name have to be defined!"};
  106. };
  107. _exit = false;
  108. _onroof = false;

  109. // ---------------------------------------------------------------------------------------------------------
  110. waitUntil {KRON_UPS_INIT==1};
  111. sleep (random 1);

  112. KRON_UPS_Instances =        KRON_UPS_Instances + 1;

  113. // get name of area marker
  114. _areamarker = _this select 1;
  115. if (isNil ("_areamarker")) exitWith {
  116.         hint "UPS: Area marker not defined.\n(Typo, or name not enclosed in quotation marks?)";
  117. };       

  118. _centerpos = [];
  119. _centerX = [];
  120. _centerY = [];
  121. _rangeX = 0;
  122. _rangeY = 0;
  123. _areadir = 0;
  124. _areaname = "";
  125. _areatrigger = objNull;
  126. _showmarker = "HIDEMARKER";
  127. _getAreaInfo = {
  128.         if (typeName _areamarker=="String") then {
  129.                 // remember center position of area marker
  130.                 _centerpos = getMarkerPos _areamarker;
  131.                 _centerX = abs(_centerpos select 0);
  132.                 _centerY = abs(_centerpos select 1);
  133.        
  134.                 // X/Y range of target area
  135.                 _areasize = getMarkerSize _areamarker;
  136.                 _rangeX = _areasize select 0;
  137.                 _rangeY = _areasize select 1;
  138.                 // marker orientation (needed as negative value!)
  139.                 _areadir = (markerDir _areamarker) * -1;
  140.        
  141.                 _areaname = _areamarker;
  142.                
  143.                 // show area marker
  144.                 _showmarker = if ("SHOWMARKER" in _UCthis) then {"SHOWMARKER"} else {"HIDEMARKER"};
  145.                 if (_showmarker=="HIDEMARKER") then {
  146.                         _areamarker setMarkerPos [-abs(_centerX),-abs(_centerY)];
  147.                 };
  148.         } else {
  149.                 _centerpos = getPos _areamarker;
  150.                 _centerX = abs(_centerpos select 0);
  151.                 _centerY = abs(_centerpos select 1);
  152.        
  153.                 // X/Y range of target area
  154.                 _rangeX = triggerArea _areamarker select 0;
  155.                 _rangeY = triggerArea _areamarker select 1;
  156.                 // marker orientation (needed as negative value!)
  157.                 _areadir = (getDir _areamarker) * -1;
  158.                
  159.                 _areaname = vehicleVarName _areamarker;
  160.         };
  161.         // update trigger position
  162.         if !(isNull _areatrigger) then {
  163.                 _areatrigger setPos [_centerX,_centerY];
  164.         };
  165. };
  166. [] call _getAreaInfo;
  167. sleep .01;

  168. // unit that's moving
  169. _obj = _this select 0;               
  170. _npc = _obj;
  171. // is anybody alive in the group?
  172. _exit = true;               
  173. if (typename _obj=="OBJECT") then {
  174.         if (alive _npc) then {_exit = false;}               
  175. } else {
  176.         if (count _obj>0) then {
  177.                 {if (alive _x) then {_npc = _x; _exit = false;}} forEach _obj;
  178.         };
  179. };

  180. // give this group a unique index
  181. _grpidx = format["%1",KRON_UPS_Instances];
  182. _grpname = format["%1_%2",(side _npc),_grpidx];

  183. // remember the original group members, so we can later find a new leader, in case he dies
  184. _members = units _npc;
  185. KRON_UPS_Total = KRON_UPS_Total + (count _members);

  186. // what type of "vehicle" is unit ?
  187. _isman = _npc isKindOf "Man";
  188. _iscar = _npc isKindOf "vbs2_LandVehicles";
  189. _isboat = _npc isKindOf "Ship";
  190. _isplane = _npc isKindOf "Air";

  191. // check to see whether group is an enemy of the player (for attack and avoidance maneuvers)
  192. // since countenemy doesn't count vehicles, and also only counts enemies if they're known,
  193. // we just have to brute-force it for now, and declare *everyone* an enemy who isn't a civilian
  194. _issoldier = side _npc != civilian;

  195. _friends=[];
  196. _enemies=[];       
  197. _sharedenemy=0;
  198. //TODO: FIND A WAY TO DETERMINE ASSOCIATION OF RESISTANCE UNITS
  199. if (_issoldier) then {
  200.         switch (side _npc) do {
  201.                 case west:
  202.                         { _friends=_friends+KRON_AllWest; _enemies=_enemies+KRON_AllEast+KRON_AllRes; _sharedenemy=0; };
  203.                 case east:
  204.                         { _friends=_friends+KRON_AllEast; _enemies=_enemies+KRON_AllWest+KRON_AllRes; _sharedenemy=1; };
  205.                 case resistance:
  206.                         { _enemies=_enemies+KRON_AllEast+KRON_AllWest; _sharedenemy=2; };
  207.         };
  208.         {
  209.                 _friends=_friends-[_x];
  210.                 _x disableAI "autotarget";
  211.         } forEach _members;
  212. };
  213. sleep .01;

  214. // global unit variable to externally influence script
  215. _named = false;
  216. _npcname = str(side _npc);
  217. if ("NAMED" in _UCthis) then {
  218.         _named = true;
  219.         _npcname = format["%1",_npc];
  220.         _grpidx = _npcname;
  221. };
  222. // create global variable for this group
  223. call compile format ["KRON_UPS_%1=1",_npcname];

  224. // store some trig calculations
  225. _cosdir=cos(_areadir);
  226. _sindir=sin(_areadir);

  227. // minimum distance of new target position
  228. if (_rangeX==0) exitWith {
  229.         hint format["UPS: Cannot patrol Sector: %1\nArea Marker doesn't exist",_areaname];
  230. };
  231. _mindist=(_rangeX^2+_rangeY^2)/4;

  232. // remember the original mode & speed
  233. _orgMode = behaviour _npc;
  234. _orgSpeed = speedmode _npc;
  235. _speedmode = _orgSpeed;

  236. // set first target to current position (so we'll generate a new one right away)
  237. _currPos = getpos _npc;
  238. _orgPos = _currPos;
  239. _orgWatch=[_currPos,50,getDir _npc] call KRON_relPos;
  240. _orgDir = getDir _npc;
  241. _avoidPos = [0,0];
  242. _flankPos = [0,0];
  243. _attackPos = [0,0];

  244. _dist = 0;
  245. _lastdist = 0;
  246. _lastmove1 = 0;
  247. _lastmove2 = 0;
  248. _maxmove=0;
  249. _moved=0;

  250. _damm=0;
  251. _dammchg=0;
  252. _lastdamm = 0;
  253. _timeontarget = 0;

  254. _fightmode = "walk";
  255. _fm=0;
  256. _gothit = false;
  257. _hitPos=[0,0,0];
  258. _react = 99;
  259. _lastdamage = 0;
  260. _lastknown = 0;
  261. _opfknowval = 0;

  262. _sin90=1; _cos90=0;
  263. _sin270=-1; _cos270=0;

  264. // set target tolerance high for choppers & planes
  265. _closeenough=CLOSEENOUGH*CLOSEENOUGH;
  266. if (_isplane) then {_closeenough=5000};

  267. sleep .01;
  268. // ***************************************** optional arguments *****************************************

  269. // wait at patrol end points
  270. _pause = if ("NOWAIT" in _UCthis) then {"NOWAIT"} else {"WAIT"};
  271. // don't move until an enemy is spotted
  272. _nomove  = if ("NOMOVE" in _UCthis) then {"NOMOVE"} else {"MOVE"};
  273. // don't follow outside of marker area
  274. _nofollow = if ("NOFOLLOW" in _UCthis) then {"NOFOLLOW"} else {"FOLLOW"};
  275. // share enemy info
  276. _shareinfo = if ("NOSHARE" in _UCthis) then {"NOSHARE"} else {"SHARE"};
  277. // "area cleared" trigger activator
  278. _usetrigger = if ("TRIGGER" in _UCthis) then {"TRIGGER"} else {if ("NOTRIGGER" in _UCthis) then {"NOTRIGGER"} else {"SILENTTRIGGER"}};
  279. // suppress fight behaviour
  280. if ("NOAI" in _UCthis) then {_issoldier=false};
  281. // adjust cycle delay
  282. _cycle = ["CYCLE:",5,_UCthis] call KRON_getArg;
  283. // drop units at random positions
  284. _initpos = "ORIGINAL";
  285. if ("RANDOM" in _UCthis) then {_initpos = "RANDOM"};
  286. if ("RANDOMUP" in _UCthis) then {_initpos = "RANDOMUP"};
  287. if ("RANDOMDN" in _UCthis) then {_initpos = "RANDOMDN"};
  288. // don't position groups or vehicles on rooftops
  289. if ((_initpos!="ORIGINAL") && ((!_isman) || (count _members)>1)) then {_initpos="RANDOMDN"};
  290. // set behaviour modes (or not)
  291. _noslow = if ("NOSLOW" in _UCthis) then {"NOSLOW"} else {"SLOW"};
  292. if (_noslow!="NOSLOW") then {
  293.         _npc setbehaviour "safe";
  294.         _npc setSpeedMode "limited";
  295.         _speedmode = "limited";
  296. };

  297. // make start position random
  298. if (_initpos!="ORIGINAL") then {
  299.         // find a random position (try a max of 20 positions)
  300.         _try=0;
  301.         _bld=0;
  302.         _bldpos=0;
  303.         while {_try<20} do {
  304.                 _currPos=[_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos;
  305.                 if ((_initpos=="RANDOMUP") || ((_initpos=="RANDOM") && (random 1>.75))) then {
  306.                         _posinfo=[_currPos] call KRON_PosInfo;
  307.                         // _posinfo: [0,0]=no house near, [obj,-1]=house near, but no roof positions, [obj,pos]=house near, with roof pos
  308.                         _bld=_posinfo select 0;
  309.                         _bldpos=_posinfo select 1;
  310.                 };
  311.                 if (_isplane || _isboat || !(surfaceiswater _currPos)) then {
  312.                         if (((_initpos=="RANDOM") || (_initpos=="RANDOMUP")) && (_bldpos>0)) then {_try=99};
  313.                         if (((_initpos=="RANDOM") || (_initpos=="RANDOMDN")) && (_bldpos==0)) then {_try=99};
  314.                 };
  315.                 _try=_try+1;
  316.         };
  317.         if (_bldpos==0) then {
  318.                 if (_isman) then {
  319.                         {_x setPos _currPos} foreach units _npc;
  320.                 } else {
  321.                         _npc setPos _currPos;
  322.                 };
  323.         } else {
  324.         // put the unit on top of a building
  325.                 _npc setPos (_bld buildingPos _bldpos);
  326.                 _npc setUnitPos "up";
  327.                 _currPos = getPos _npc;
  328.                 _onroof = true;
  329.                 _exit=true; // don't patrol if on roof
  330.         };
  331. };
  332. sleep .01;

  333. // track unit
  334. _track =         if (("TRACK" in _UCthis) || (KRON_UPS_Debug>0)) then {"TRACK"} else {"NOTRACK"};
  335. _trackername = "";
  336. _destname = "";
  337. if (_track=="TRACK") then {
  338.         _track = "TRACK";
  339.         _trackername=format["trk_%1",_grpidx];
  340.         _markerobj = createMarker[_trackername,[0,0]];
  341.         _markerobj setMarkerShape "ICON";
  342.         _markertype = if (isClass(configFile >> "cfgMarkers" >> "WTF_Dot")) then {"WTF_DOT"} else {"DOT"};
  343.         _trackername setMarkerType _markertype;
  344.         _markercolor = switch (side _npc) do {
  345.                 case west: {"ColorGreen"};
  346.                 case east: {"ColorRed"};
  347.                 case resistance: {"ColorBlue"};
  348.                 default {"ColorBlack"};
  349.         };
  350.         _trackername setMarkerColor _markercolor;
  351.         _trackername setMarkerText format["%1",_grpidx];
  352.         _trackername setmarkerpos _currPos;
  353.         _trackername setMarkerSize [.5,.5];
  354.        
  355.         _destname=format["dest_%1",_grpidx];
  356.         _markerobj = createMarker[_destname,[0,0]];
  357.         _markerobj setMarkerShape "ICON";
  358.         _markertype = if (isClass(configFile >> "cfgMarkers" >> "WTF_Flag")) then {"WTF_FLAG"} else {"FLAG"};
  359.         _destname setMarkerType _markertype;
  360.         _destname setMarkerColor _markercolor;
  361.         _destname setMarkerText format["%1",_grpidx];
  362.         _destname setMarkerSize [.5,.5];
  363. };       
  364. sleep .01;

  365. // delete dead units
  366. _deletedead = ["DELETE:",0,_UCthis] call KRON_getArg;
  367. if (_deletedead>0) then {
  368.         {_x addEventHandler['killed',format["[_this select 0,%1] spawn KRON_deleteDead",_deletedead]]}forEach _members;
  369. };

  370. // how many group clones?
  371. // TBD: add to global side arrays?
  372. _mincopies = ["MIN:",0,_UCthis] call KRON_getArg;
  373. _maxcopies = ["MAX:",0,_UCthis] call KRON_getArg;
  374. if (_mincopies>_maxcopies) then {_maxcopies=_mincopies};
  375. if (_maxcopies>140) exitWith {hint "Cannot create more than 140 groups!"};
  376. if (_maxcopies>0) then {
  377.         if !(_isMan) exitWith {hint "Vehicles cannot be cloned."};
  378.         _copies=_mincopies+round(random (_maxcopies-_mincopies));
  379.         // any init strings?
  380.         _initstr = ["INIT:","",_UCthis] call KRON_getArg;

  381. // name of clones
  382. _nameprefix = ["PREFIX:","UPSCLONE",_UCthis] call KRON_getArg;

  383. // create the clones
  384.         for "_grpcnt" from 1 to _copies do {
  385.                 // group leader
  386.                 _unittype=typeof _npc;
  387.                 // copy groups
  388.                 if (isNil ("KRON_cloneindex")) then {
  389.                         KRON_cloneindex = 0;
  390.                 };
  391.                 // make the clones civilians
  392.                 // use random Civilian models for single unit groups
  393.                 if ((_unittype=="Civilian") && (count _members==1)) then {_rnd=1+round(random 20); if (_rnd>1) then {_unittype=format["Civilian%1",_rnd]}};
  394.                
  395.                 _grp=createGroup side _npc;
  396.                 _lead = _grp createUnit [_unittype, getpos _npc, [], 0, "form"];
  397.                 KRON_cloneindex = KRON_cloneindex+1;
  398.                 _lead setVehicleVarName format["%1%2",_nameprefix,KRON_cloneindex];
  399.                 call compile format["%1%2=_lead",_nameprefix,KRON_cloneindex];
  400.                 _lead setBehaviour _orgMode;
  401.                 _lead setSpeedMode _orgSpeed;
  402.                 _lead setSkill skill _npc;
  403.                 _lead setVehicleInit _initstr;
  404.                 [_lead] join _grp;
  405.                 _grp selectLeader _lead;
  406.                 // copy team members (skip the leader)
  407.                 _c=0;
  408.                 {
  409.                         _c=_c+1;
  410.                         if (_c>1) then {
  411.                                 _newunit = _grp createUnit [typeof _x, getpos _x, [],0,"form"];
  412.                                 KRON_cloneindex = KRON_cloneindex+1;
  413.                                 _newunit setVehicleVarName format["%1%2",_nameprefix,KRON_cloneindex];
  414.                                 call compile format["%1%2=_newunit",_nameprefix,KRON_cloneindex];
  415.                                 _newunit setBehaviour _orgMode;
  416.                                 _newunit setSpeedMode _orgSpeed;
  417.                                 _newunit setSkill skill _x;
  418.                                 _newunit setVehicleInit _initstr;
  419.                                 [_newunit] join _grp;
  420.                         };
  421.                 } foreach _members;
  422.                 _nul=[_lead,_areamarker,_pause,_noslow,_nomove,_nofollow,_initpos,_track,_showmarker,_shareinfo,"DELETE:",_deletedead] execVM "ups.sqf";
  423.                 sleep .05;
  424.         };       
  425.         processInitCommands;
  426. };
  427. sleep .01;


  428. // units that can be left for area to be "cleared"
  429. _zoneempty = ["EMPTY:",0,_UCthis] call KRON_getArg;

  430. // create area trigger
  431. if (_usetrigger!="NOTRIGGER") then {
  432.         _trgside = switch (side _npc) do { case west: {"WEST"}; case east: {"EAST"}; case resistance: {"GUER"}; case civilian: {"CIV"};};
  433.         _trgname="KRON_Trig_"+_trgside+"_"+_areaname;
  434.         _flgname="KRON_Cleared_"+_areaname;
  435.         // has the trigger been created already?
  436.         KRON_TRGFlag=-1;
  437.         call compile format["%1=false",_flgname];
  438.         call compile format["KRON_TRGFlag=%1",_trgname];
  439.         if (isNil ("KRON_TRGFlag")) then {
  440.                 // trigger doesn't exist yet, so create one (make it a bit bigger than the marker, to catch path finding 'excursions' and flanking moves)
  441.                 call compile format["%1=createTrigger['EmptyDetector',[_centerX,_centerY]];",_trgname];
  442.                 call compile format["_areatrigger = %1",_trgname];
  443.                 call compile format["%1 setTriggerArea[_rangeX*1.5,_rangeY*1.5,markerDir _areaname,true]",_trgname];
  444.                 call compile format["%1 setTriggerActivation[_trgside,'PRESENT',true]",_trgname];
  445.                 call compile format["%1 setEffectCondition 'true'",_trgname];
  446.                 call compile format["%1 setTriggerTimeout [5,7,10,true]",_trgname];
  447.                 if (_usetrigger!="SILENTTRIGGER") then {
  448.                         _markerhide = [-_centerX,-_centerY];
  449.                         _markershow = [_centerX,_centerY];
  450.                         if (_showmarker=="HIDEMARKER") then {
  451.                                 _markershow = [-_centerX,-_centerY];
  452.                         };
  453.                         call compile format["%1 setTriggerStatements['count thislist<=%6', 'titletext [''SECTOR <%2> CLEARED'',''PLAIN''];''%2'' setmarkerpos %4;%3=true;', 'titletext [''SECTOR <%2> HAS BEEN RE-OCCUPIED'',''PLAIN''];''%2'' setmarkerpos %5;%3=false;']", _trgname,_areaname,_flgname,_markerhide,_markershow,_zoneempty];
  454.                 } else {
  455.                         call compile format["%1 setTriggerStatements['count thislist<=%3', '%2=true;', '%2=false;']", _trgname,_flgname,_zoneempty];
  456.                 };
  457.         };
  458.         sleep .01;
  459. };

  460. // init done
  461. _makenewtarget=true;
  462. _newpos=false;
  463. _targetPos = _currPos;
  464. _swimming = false;
  465. _waiting = if (_nomove=="NOMOVE") then {9999} else {0};

  466. // exit if something went wrong during initialization (or if unit is on roof)
  467. if (_exit) exitWith {
  468.         if ((KRON_UPS_DEBUG>0) && !_onroof) then {hint "Initialization aborted"};
  469. };

  470. // ***********************************************************************************************************
  471. // ************************************************ MAIN LOOP ************************************************
  472. _loop=true;
  473. _currcycle=_cycle;
  474. while {_loop} do {
  475.         sleep .01;
  476.         // keep track of how long we've been moving towards a destination
  477.         _timeontarget=_timeontarget+_currcycle;
  478.         _react=_react+_currcycle;
  479.                        
  480.         // did anybody in the group got hit?
  481.         _newdamage=0;
  482.         {
  483.                 if((damage _x)>0.2) then {
  484.                         _newdamage=_newdamage+(damage _x);
  485.                         // damage has increased since last round
  486.                         if (_newdamage>_lastdamage) then {
  487.                                 _lastdamage=_newdamage;
  488.                                 _gothit=true;
  489.                         };
  490.                         _hitPos=getpos _x;
  491.                         if (!alive _x) then {
  492.                                 _members=_members-[_x];
  493.                                 _friends=_friends-[_x];
  494.                         };
  495.                 };
  496.         } foreach _members;
  497.         sleep .01;

  498.         // nobody left alive, exit routine
  499.         if (count _members==0) then {
  500.                 _exit=true;
  501.         } else {
  502.                 // did the leader die?
  503.                 if (!alive _npc) then {
  504.                         _npc = _members select 0;
  505.                         group _npc selectLeader _npc;
  506.                         if (isPlayer _npc) then {_exit=true};
  507.                 };
  508.         };
  509.        
  510.         // current position
  511.         _currPos = getpos _npc; _currX = _currPos select 0; _currY = _currPos select 1;
  512.         if (_track=="TRACK") then { _trackername setmarkerpos _currPos; };
  513.        
  514.         // if the AI is a civilian we don't have to bother checking for enemy encounters
  515.         if ((_issoldier) && ((count _enemies)>0) && !(_exit)) then {

  516.                 // if the leader comes across another unit that's either injured or dead, go into combat mode as well.
  517.                 // If the other person is still alive, share enemy information.
  518.                 if ((_shareinfo=="SHARE") && (behaviour _npc=="SAFE")) then {
  519.                         _others=_friends-_members;
  520.                         {
  521.                                 if ((!(isNull _x) && (_npc distance _x<SHAREDIST)) && ((damage _x>.5) || (behaviour _x in ["AWARE","COMBAT"]))) exitWith {
  522.                                         _npc setBehaviour "aware";
  523.                                         _gothit=true;
  524.                                         if ((_hitPos select 0)==0) then {_hitPos = getPos _x};
  525.                                         if (_npc knowsabout _x>3) then {
  526.                                                 if (alive _x) then {_npc reveal (KRON_KnownEnemy select _sharedenemy)};
  527.                                         };
  528.                                 };
  529.                         }forEach _others;
  530.                 };
  531.                 sleep .01;
  532.                        
  533.                 // did the group spot an enemy?
  534.                 _lastknown=_opfknowval;
  535.                 _opfknowval=0;
  536.                 _maxknowledge=0;
  537.                 {
  538.                         _knows=_npc knowsabout _x;
  539.                         if ((alive _x) && (_knows>0.2) && (_knows>_maxknowledge)) then {
  540.                                 KRON_KnownEnemy set [_sharedenemy,_x];
  541.                                 _opfknowval=_opfknowval+_knows;
  542.                                 _maxknowledge=_knows;
  543.                         };
  544.                         if (!alive _x) then {_enemies=_enemies-[_x]};
  545.                         if (_maxknowledge==4) exitWith {};
  546.                 }forEach _enemies;
  547.                 sleep .01;
  548.                
  549.                 _pursue=false;
  550.                 _accuracy=100;
  551.                 // opfor spotted an enemy or got shot, so start pursuit
  552.                 if (_opfknowval>_lastknown || _gothit) then {
  553.                         _npc setbehaviour "combat";
  554.                         _pursue=true;
  555.                         // make the exactness of the target dependent on the knowledge about the shooter
  556.                         _accuracy=21-(_maxknowledge*5);
  557.                 };
  558.                
  559.                 if (isNull (KRON_KnownEnemy select _sharedenemy)) then {
  560.                         _pursue=false;
  561.                 };

  562.                 // don't react to new fatalities if less than 60 seconds have passed since the last one
  563.                 if ((_react<60) && (_fightmode!="walk")) then {_pursue=false};

  564.                 if (_pursue) then        {
  565.                         // get position of spotted unit in player group, and watch that spot
  566.                         _offsx=_accuracy/2-random _accuracy; _offsY=_accuracy/2-random _accuracy;
  567.                         _targetPos = getpos (KRON_KnownEnemy select _sharedenemy);
  568.                         _targetPos = [(_targetPos select 0) + _offsX, (_targetPos select 1) + _offsY];
  569.                         _targetX = _targetPos select 0; _targetY = _targetPos select 1;
  570.                         {_x dowatch _targetPos} foreach units _npc;
  571.                         sleep .01;                       

  572.                         // also go into "combat mode"
  573.                         _npc setSpeedMode "full";
  574.                         _speedmode = "full";
  575.                         _npc setbehaviour "combat";
  576.                         _pause="NOWAIT";
  577.                         _waiting=0;
  578.                        
  579.                         // angle from unit to target
  580.                         _dir1 = [_currPos,_targetPos] call KRON_getDirPos;
  581.                         // angle from target to unit (reverse direction)
  582.                         _dir2 = (_dir1+180) mod 360;
  583.                         // angle from fatality to target
  584.                         _dir3 = if (_hitPos select 0!=0) then {[_hitPos,_targetPos] call KRON_getDirPos} else {_dir1};
  585.                         _dd=(_dir1-_dir3);
  586.                        
  587.                         // unit position offset straight towards target
  588.                         _relUX = sin(_dir1)*SAFEDIST; _relUY = cos(_dir1)*SAFEDIST;
  589.                         // target position offset straight towards unit
  590.                         _relTX = sin(_dir2)*SAFEDIST; _relTY = cos(_dir2)*SAFEDIST;
  591.                         // go either left or right (depending on location of fatality - or randomly if no fatality)
  592.                         _sinU=_sin90; _cosU=_cos90; _sinT=_sin270; _cosT=_cos270;
  593.                         if ((_dd<0) || (_dd==0 && (random 1)>.5)) then {_sinU=_sin270; _cosU=_cos270; _sinT=_sin90; _cosT=_cos90};

  594.                         // avoidance position (right or left of unit)
  595.                         _avoidX = _currX + _cosU*_relUX - _sinU*_relUY;
  596.                         _avoidY = _currY + _sinU*_relUX + _cosU*_relUY;
  597.                         _avoidPos = [_avoidX,_avoidY];
  598.                         // flanking position (right or left of target)
  599.                         _flankX = _targetX + _cosT*_relTX - _sinT*_relTY;
  600.                         _flankY = _targetY + _sinT*_relTX + _cosT*_relTY;
  601.                         _flankPos = [_flankX,_flankY];
  602.                         // final target position
  603.                         _attackPos = _targetPos;
  604.                         // for now we're stepping a bit to the side
  605.                         _targetPos = _avoidPos;

  606.                         if (_nofollow=="NOFOLLOW") then {
  607.                                 _avoidPos = [_avoidPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside;
  608.                                 _flankPos = [_flankPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside;
  609.                                 _attackPos = [_attackPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside;
  610.                                 _targetPos = [_targetPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside;
  611.                         };
  612.                        
  613.                         _react=0;
  614.                         _fightmode="fight";
  615.                         _timeontarget=0;
  616.                         _fm=1;
  617.                          if (KRON_UPS_Debug!=0) then {
  618.                                 "dead" setmarkerpos _hitPos; "avoid" setmarkerpos _avoidPos; "flank" setmarkerpos _flankPos; "target" setmarkerpos _attackPos;
  619.                         };
  620.                         _newpos=true;
  621.                         // speed up the cycle duration after an incident
  622.                         if (_currcycle>=_cycle) then {_currcycle=1};
  623.                 };
  624.         };
  625.         sleep .01;

  626.         if !(_newpos) then {
  627.                 // calculate new distance
  628.                 // if we're waiting at a waypoint, no calculating necessary
  629.                 if (_waiting<=0) then {
  630.                         // distance to target
  631.                         _dist = [_currPos,_targetPos] call KRON_distancePosSqr;
  632.                         if (_lastdist==0) then {_lastdist=_dist};
  633.                         _moved = abs(_dist-_lastdist);
  634.                         // adjust the target tolerance for fast moving vehicles
  635.                         if (_moved>_maxmove) then {_maxmove=_moved; if ((_maxmove/40) > _closeenough) then {_closeenough=_maxmove/40}};
  636.                         // how much did we move in the last three cycles?
  637.                         _totmove=_moved+_lastmove1+_lastmove2;
  638.                         _damm = damage _npc;
  639.                         // is our damage changing (increasing)?
  640.                         _dammchg = abs(_damm - _lastdamm);
  641.                        
  642.                         // we're either close enough, seem to be stuck, or are getting damaged, so find a new target
  643.                         if ((!_swimming) && ((_dist<=_closeenough) || (_totmove<.2) || (_dammchg>0.01) || (_timeontarget>ALERTTIME))) then {_makenewtarget=true;};

  644.                         // in 'attack (approach) mode', so follow the flanking path (don't make it too predictable though)
  645.                         if ((_fightmode!="walk") && (_dist<=_closeenough)) then {
  646.                                 if ((random 1)<.95) then {
  647.                                         if (_flankPos select 0!=0) then {
  648.                                                 _targetPos=_flankPos; _flankPos=[0,0]; _makenewtarget=false; _newpos=true;
  649.                                                 _fm=1;
  650.                                         } else {
  651.                                                 if (_attackPos select 0!=0) then {
  652.                                                         _targetPos=_attackPos; _attackPos=[0,0]; _makenewtarget=false; _newpos=true;
  653.                                                         _fm=2;
  654.                                                 };
  655.                                         };
  656.                                 };
  657.                         };
  658.                         sleep .01;

  659.                         // make new target
  660.                         if (_makenewtarget) then {
  661.                                 if ((_nomove=="NOMOVE") && (_timeontarget>ALERTTIME)) then {
  662.                                         if (([_currPos,_orgPos] call KRON_distancePosSqr)<_closeenough) then {
  663.                                                 _newpos = false;
  664.                                         } else {
  665.                                                 _targetPos=_orgPos;
  666.                                         };
  667.                                 } else {
  668.                                         // re-read marker position/size
  669.                                         [] call _getAreaInfo;
  670.                                         // find a new target that's not too close to the current position
  671.                                         _targetPos=_currPos;
  672.                                         _tries=0;
  673.                                         while {((([_currPos,_targetPos] call KRON_distancePosSqr) < _mindist)) && (_tries<20)} do {
  674.                                                 _tries=_tries+1;
  675.                                                 // generate new target position (on the road)
  676.                                                 _tries=0;
  677.                                                 while {_tries<20} do {
  678.                                                         _targetPos=[_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos;
  679.                                                         if (_iscar) then {
  680.                                                                 _roadlist = _targetPos nearRoads 100;
  681.                                                                 if (count _roadlist>0) then {
  682.                                                                         _targetPos = getPos (_roadlist select 0);
  683.                                                                         _tries=99;
  684.                                                                 };
  685.                                                         } else {
  686.                                                                 _tries=99;
  687.                                                         };
  688.                                                         //_road=[_targetPos,(_isplane||_isboat),_road] call KRON_OnRoad;
  689.                                                         sleep .01;                       
  690.                                                 };
  691.                                         };
  692.                                 };
  693.                                 _avoidPos = [0,0]; _flankPos = [0,0]; _attackPos = [0,0];
  694.                                 _gothit=false;
  695.                                 _hitPos=[0,0,0];
  696.                                 _fm=0;
  697.                                 _npc setSpeedMode _orgSpeed;
  698.                                 _newpos=true;
  699.        
  700.                                 // if we're waiting at patrol end points then don't create a new target right away. Keep cycling though to check for enemy encounters
  701.                                 if ((_pause!="NOWAIT") && (_waiting<0)) then {_waiting = (15 + random 20)};
  702.                         };
  703.                 };
  704.         };
  705.         sleep .01;

  706.         // if in water, get right back out of it again
  707.         if (surfaceIsWater _currPos) then {
  708.                 if (_isman && !_swimming) then {
  709.                         _drydist=999;
  710.                         // look around, to find a dry spot
  711.                         for [{_a=0}, {_a<=270}, {_a=_a+90}] do {
  712.                                 _dp=[_currPos,30,_a] call KRON_relPos;
  713.                                 if !(surfaceIsWater _dp) then {_targetPos=_dp};
  714.                         };
  715.                         _newpos=true;
  716.                         _swimming=true;
  717.                 };
  718.         } else {
  719.                 _swimming=false;
  720.         };
  721.                
  722.         _waiting = _waiting - _currcycle;
  723.         if ((_waiting<=0) && _newpos) then {
  724.                 // tell unit about new target position
  725.                 if (_fightmode!="walk") then {
  726.                         // reset patrol speed after following enemy for a while
  727.                         if (_timeontarget>ALERTTIME) then {
  728.                                 _fightmode="walk";
  729.                                 _speedmode = _orgSpeed;
  730.                                 {
  731.                                         _x setSpeedMode _speedmode;
  732.                                         _x setBehaviour _orgMode;
  733.                                 }forEach _members;
  734.                         };
  735.                         // use individual doMoves if pursuing enemy,
  736.                         // as otherwise the group breaks up too much
  737.                         {_x doMove _targetPos}forEach _members;
  738.                 } else {
  739.                         (group _npc) move _targetPos;
  740.                         (group _npc) setSpeedMode _speedmode;
  741.                 };
  742.                 if (_track=="TRACK") then {
  743.                         switch (_fm) do {
  744.                                 case 1:
  745.                                         {_destname setmarkerSize [.4,.4]};
  746.                                 case 2:
  747.                                         {_destname setmarkerSize [.6,.6]};
  748.                                 default
  749.                                         {_destname setmarkerSize [.5,.5]};
  750.                         };
  751.                         _destname setMarkerPos _targetPos;
  752.                 };
  753.                 _dist=0;
  754.                 _moved=0;
  755.                 _lastmove1=10;
  756.                 _waiting=-1;
  757.                 _newpos=false;
  758.                 _swimming=false;
  759.                 _timeontarget = 0;
  760.         };
  761.        
  762.         // move on
  763.         _lastdist = _dist; _lastmove2 = _lastmove1; _lastmove1 = _moved; _lastdamm = _damm;

  764.         // check external loop switch
  765.         _cont = (call compile format ["KRON_UPS_%1",_npcname]);
  766.         if (_cont==0) then {_exit=true};
  767.        
  768.         _makenewtarget=false;
  769.         if ((_exit) || (isNil("_npc"))) then {
  770.                 _loop=false;
  771.         } else {
  772.                 // slowly increase the cycle duration after an incident
  773.                 if (_currcycle<_cycle) then {_currcycle=_currcycle+.5};
  774.                 sleep _currcycle;
  775.         };
  776. };

  777. if !(isNil("_npc")) then {
  778.         {doStop _x; _x domove getPos _x; _x move getPos _x} forEach _members;
  779. };

  780. KRON_UPS_Exited=KRON_UPS_Exited+1;
  781. if (_track=="TRACK") then {
  782.         _trackername setMarkerType "Dot";
  783.         _destname setMarkerType "Empty";
  784. };
  785. _friends=nil;
  786. _enemies=nil;
复制代码
发表于 2014-7-15 02:39:15 | 显示全部楼层
加菲猫的贴子原话:深入敌后的狙杀非常有挑战性,也最容易让人沉浸其中,一般选择夜晚从橡皮艇出发登岸,或者高空投降,这样隐蔽性好,符合实情,当然隐蔽性最好的是穿平民装上岸,到线人那里拿装备,然后去执行任务......
目标区域最好选择森林(如Chernarus东北角的大片森林地),阿富汗地貌的石头高山地图(如Ranzi)),或如Thirsk的雪地,非常有氛围..........
如果让任务有挑战性,建议用UPS脚本,不定性地增加敌人的巡逻小队,在地图的特定区域放上标记, 标记要命名并设定范围大小(如椭圆形区域1000Mx500M)。
然后在地图任意位置放上一个敌人小队(建议不超过5个人,如果难度极大),然后在队长的Init栏里写上如下语句:
nul=[this,"Nest","random","MIN:",1,"MAX:",5] execVM "ups.sqf";
"Nest"是在地图上放置的标记名称,
"random"表示巡逻小队的初始位置是在标记范围里的任意位置(备用语句“randomup"一般用于单个敌军狙击手,这样任务开始时他会在标记范围内的任意高楼上,而不用你自己放到高楼里去,“randomdn"指小队在地面的任意位置),
"MIN:",1,"MAX:",5  表示任务开始时将会克隆 1 到5 个同样的巡逻小队在标记的区域里的任意位置巡逻,而且每次玩克隆的数量不一样,这样大大增强的重玩性,不过最大的数字不要搞太多了,除非你的CPU很好
巡逻区域搞好后,再来设置任务目标,可让目标固定在一个地方(如器材),也可通过触发器在一定的时间触发他到达(如敌军指挥官,先将其放置在地图上其他位置,设置好路点,在你进入离目标一定的范围内(如1000米),用触发器触发他上车驶向目的地,目的地再设置一个触发器,触发他上车离开,但要延迟触发(如10分钟)。
设置触发器,在目标被击毙后,触发任务的完成(使用 !alive 语句,并设置标记为绿色setMarkerColor "ColorGreen",这样省了写简报里的任务目标),然后撤离到撤离点,触发任务结束。
为了让任务更精彩些,建议在用个FO-ai.sqf脚本,执行方法和ups.sqf一样,此脚本在敌方AI发现了你的位置后会呼叫火炮轰击你,比较复合对付狙击手的一般做法。
-------这类任务非常时候两人联网玩,一个狙击手,一个观察手,最好用到ACE的一些狙击设备,和密位调整,在1000米以上的距离完成任务,我曾在Ranzi地图里在1800米距离,用M107顺利狙击到2人,不过ACE里的AI很强,这么远的距离,我打完一个弹夹后,竟然被他们发现了我的位置,朝我直奔过来...............
编辑这样的一个任务只有10分钟,因为UPS脚本就增加了重玩性,如果你觉得一个地图不过瘾,就多下几个地图,各种地貌的,然后在编辑器了用MERGE(合并)转到其他地图上,别忘了把脚本也复制过去。
在此我征召愿意和我联机狙击的稳重A友,要求:愿意下更多的地图,机器要能承受开3000米视距,有语音通讯..............

nul=[this,"Nest","randomup","MIN:",1,"MAX:",5] execVM "ups.sqf";
您需要登录后才可以回帖 登录 | 加入VME

本版积分规则

小黑屋|中国虚拟军事网

GMT+8, 2024-4-29 22:51

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表