Page 1

CreateAll.sqf

v1.01

(Armed Assault)

(Por RAVEN) Es una función diseñada para generar grupos de unidades de combate posteriormente al inicio de una partida SP o MP. Así como se lee, se podría pensar que es otra más de las tantas que hay disponibles. Sí !, es otra más, pero no “como” las demás. La diferencia es que CreateAll, concentra en la misma llamada a la función, la capacidad para crear grupos con las siguientes características: -

De cualquier bando En cualquier lugar, Con cualquier morfología (infantería, blindados, camiones, helicópteros, etc.) o combinación de ellos. Con cantidad de tripulantes definida o con ninguna (vehículos vacíos), o con la máxima que el vehiculo soporte, sin que nos interese saber cuántos son. Con el tipo de unidades oficiales (BIS) o creadas por terceros (mod.) Definiendo un nombre particular para el grupo o no. Con el estado de combate que deseemos (safe, aware, combat, etc.). Usando la distribución que deseemos en la formación (fila, Columna, Ve, etc.). Con un tipo de velocidad específica. Con una ruta de “Way Points” determinado previamente. Con la posibilidad de desencadenar otras acciones (vía funciones o scripts de terceros).

Esto se logra pasando a la función, una serie de parámetros que afectarán a su comportamiento drásticamente: Una llamada típica a CreateAll tiene éste formato: _handler = [Bando, origen, TipoUnidades, CantUnidades, Skill/CantVehiculos, ArrayUnidades, NombreGrupo", EstadoGrupo, TipoFormacion, Velocidadgrupo, ArrayWPs] spawn handCreateAll;

Antes de explicar en detalle cada parámetro, es necesario aclarar tres cosas. 1) CreateAll, como toda función debe ser pre-compilada para ejecutarla en una partida. La forma de hacerlo es utilizar el comando COMPILE en el init.sqf y sólo después de hacerlo, podemos ejecutarla en la partida: handCreateAll = compile preprocessFile "CreateAll.sqf";


2) Luego de compilar la función y ANTES de comenzar a crear grupos de unidades, es necesario establecer la relación entre los diferentes bandos que tomarán parte en la misión. Esto no es otra cosa que indicar a CreateAll cuales son los bandos “amigos” y cuales los “enemigos”. La forma de hacerlo es con una llamada a la función con una estructura especial de parámetros: _handler = ["setsides",[west, resistance],[east]] spawn handCreateAll;

Esto nos da la capacidad para establecer alianzas “poco comunes” a lo que estamos acostumbrados, pudiendo poner a bandos que son enemigos naturales en el simulador, como aliados (Oeste y Este) y pudiendo establecer como sus enemigos a resistencia o incluso al bando civil. Tal es la flexibilidad, que podemos darnos el lujo de llevar más allá las cosas y colocar a unidades civiles distribuidas entre bandos enemigos e incluso hacer que todos los bandos sean enemigos entre sí, obteniendo una partida de 4 bandos oponiendo sus fuerzas al mismo tiempo. El primer parámetro (setsides) debe ser del tipo carácter y los 2 siguientes serán vectores que contendrán los nombres de los bandos (sin comillas). Un vector para los amigos y otro para los enemigos. Si deseamos tener más de 2 bandos antagónicos, solo debemos repetir el establecimiento de las relaciones con los nuevos bandos. _handler = ["setsides",[west],[east]] spawn handCreateAll; _handler = ["setsides",[resistance],[east]] spawn handCreateAll; _handler = ["setsides",[resistance],[west]] spawn handCreateAll; _handler = ["setsides",[east],[west]] spawn handCreateAll; _handler = ["setsides",[civilian, west],[resistance, east]] spawn handCreateAll;

(La version anterior de CreateAll (v1.0) asumía que todos los bandos eran enemigos entre sí.) 3) CreateAll utiliza, para la creación de las objetos, los nombres de los “tipos de unidades”, desde un array de nombres que puede ser especificado en 2 sitios: a) Antes de la llamada a la función en el mismo INIT.SQS unidadesE = ["TeamLeaderE","SoldierEB","SoldierEB","SoldierEB"];

b) O en la llamada misma y en forma explícita. _handler = [Bando, origen, TipoUnidades, CantUnidades, Skill/CantVehiculos, ["TeamLeaderE","SoldierEB"], NombreGrupo", EstadoGrupo, TipoFormacion, Velocidadgrupo, ArrayWPs] spawn handCreateAll;


Especificaciones de parámetros

BANDO Puede ser: WEST, EAST, RESISTANCE, CIVILIAN. (Debe indicarse SIN COMILLAS)

ORIGEN Habitualmente, corresponde al nombre de una unidad utilizada como referencia de posición. Lo más común es utilizar una Unidad Lógica (UL), pero también puede indicarse un array conteniendo las coordenadas de posición del lugar donde se colocará inicialmente, al grupo o vehiculo creado. Los valores pueden indicarse como: Position base ULbase [1500.25,8052,1,0]

TIPO DE UNIDADES Este parámetro es sensiblemente diferente a los demás ya que puede ser una cadena (STRING) indicando un tipo de unidad (hombre o vehiculo) o un array de tipo de vehiculos y cantidad de tripulantes por cada uno. Para que se entienda mejor, veamos éstos ejemplos de valores que puede contener: “UAZMG” (Uaz armado) “BMP2ambul” (BMP ambulancia) “SearchLight” (Reflector) “MI17_MG” (Helicóptero armado) “HMMWV50” (Vehiculo ligero) “AV8B2” (Avion) Estos tipos de unidades/vehiculos indican la clase a crear, pero existe un tipo de unidad especial:

“MAN” Dicho tipo, le indica a CreateAll que se debe generar un grupo de infantería. Los tipos de soldados que conformarán el grupo se explican posteriormente. Anteriormente, expliqué que existe una variante especial de éste parámetro y que tiene la forma de un array de vehículos: [["UAZMG",2],["ural",3+random(8)],["bus_city",-1]]


Esta variante nos permite crear instantáneamente, un grupo armado conteniendo un Uaz artillado, seguido por un Ural y un bus. Si observan con atención, éste array de vehículos, tiene como elementos a varios subarrays donde se especifica el tipo de vehiculo a generar acompañado por un numero que representa la cantidad de tripulantes que el vehiculo llevará. En variante cantidad soldados haría un

el ejemplo de arriba, el Uaz llevará 2 soldados (aunque la artillada puede transportar a 3), el Ural llevará una que tendrá un mínimo de 3 soldados y un anexo de hasta 7 (la función RANDOM nunca alcanza el valor máximo), lo que máximo teórico de 10 soldados.

Finalmente, el convoy lleva –para cerrar la formación-, un bus con su capacidad completa (13 soldados). Esto se logra pasando como cantidad un valor negativo. CreateAll contará cuál es la capacidad máxima del vehiculo y generará a los tripulantes exactos para completarlo. Si indicáramos una cantidad mayor a la que puede transportar el vehiculo (Ejemplo: 8 soldados para un Uaz artillado), solo 3 subirían al mismo y el resto lo seguiría a pie. Esto es particularmente útil en operaciones donde se requiere asistencia de vehículos a las patrullas de infantería a pie. En éste punto es importante aclarar que la prioridad en el orden de creación de unidades, es: -

Conductor Artillero Comandante Área de carga.

Esto significa que si ordenamos generar un T72 (que tiene capacidad para 3 ocupantes) y le indicamos un máximo de 2 tripulantes, los puestos ocupados serán el de conductor y artillero respectivamente y el vehiculo no dispondrá de comandante. Siguiendo con éste parámetro, si indicamos una cantidad de 0 (cero) tripulantes, obviamente se crearán vehículos vacíos. Al crear un grupo de vehículos, los mismos se generan encolumnados (no en formación de columna ya que la formación se indica con otro parámetro), y con una separación en metros con respecto al vehiculo anterior que depende del tipo de vehiculo creado.


-

Clase Clase Clase Clase Clase

CAR: TRUCK: TANK: HELICOPTER: PLANE:

10 15 15 20 30

metros. metros. metros. metros. metros.

Si las coordenadas de posición de origen en la creación fueron indicadas por el nombre de un objeto o Unidad Lógica (UL), la columna de vehículos creada conservará la dirección del mismo objeto. Esto es muy útil en circunstancias donde se necesita una orientación exacta de los objetos creados como por ejemplo, en una pista auxiliar de un aeropuerto (si creamos aviones o helicópteros) o en una calle interior de un poblado o ciudad, si lo que tratamos de crear es un grupo de vehículos civiles estacionados. Hasta ahora hemos explicado los primeros 3 parámetros. Estos son los mínimos necesarios, para crear un vehiculo vacío. _handler = [east, ORIGEN, "URAL"] spawn handCreateAll; Con esto creamos un solo camión (ural) del bando éste y en la posición del objeto ORIGEN (una UL). Pero si quisiéramos crear un grupo de 5 camiones vacíos, necesitaríamos algunos parámetros más.


CANTIDAD DE UNIDADES EN GRUPO CANTIDAD DE TRIPULANTES El cuarto parámetro adquiere importancia dependiendo de los parámetros anteriores. Normalmente, indica la cantidad de soldados a crear si hemos señalado previamente que crearemos un grupo de infantería (tercer parámetro igual a “MAN”): _handler = [East, ORIGEN, "MAN", 12,……] spawn handCreateAll; Pero también puede especificar la cantidad de tripulantes de un vehiculo si previamente señalamos la creación de un vehiculo único. _handler = [east, ORIGEN, "RHS_MI24D", 2,……] spawn handCreateAll;

CANTIDAD DE VEHICULOS/SKILL DE GRUPO El quinto parámetro se refiere a la cantidad de vehículos a crear, si especificamos un tipo de vehiculo como tercer parámetro: _handler = [east, ORIGEN, "BMP", 0, 3,……] spawn handCreateAll; Pero también, indica el nivel de pericia de cada soldado del grupo de infantería a crear, si especificamos el tipo “MAN” en el tercer parámetro: _handler = [east, ORIGEN, "MAN", 12, 0.5,……] spawn handCreateAll; Cuando indicamos el skill de un grupo, cada miembro adquiere el mismo, excepto el líder del grupo que adquiere un skill superior al 50% del informado (en el ejemplo es de 75% y el resto de 50%)


ORIENTACION DE VEHICULOS TIPO DE UNIDADES DE GRUPO El sexto parámetro se refiere a la dirección angular del vehiculo o grupo de vehículos, creado si el mismo está vacío. _handler = [east, ORIGEN, "KA50", 0, 4, 75,……] spawn handCreateAll; En éste ejemplo, se crean 4 helicópteros del tipo KAMOV-50 con una orientación de 75 grados más que la dirección que posee la unidad de ORIGEN. Para aclarar, si ORIGEN tiene una dirección de 0 (cero) grados, los helicópteros aparecerían encolumnados con una dirección de 0 (cero) grados, pero cada helicóptero estaría orientado 45 grados a la derecha (0+45 = 45 grados). Obviamente, con un valor negativo aparecerían orientados hacia la izquierda (0-45 = 315 grados). Este parámetro (el sexto) también sirve para indicar a CreateAll los nombres de los tipos de unidades que se usarán para crear a los soldados de un grupo de infantería o tripulación de vehículos, cuando se informa la creación de vehículos con tripulación (no vacíos). _handler = [East, ORIGEN, "MAN", 3+random(7), 0.5, unidadesE,……] spawn handCreateAll; Es imperativo que dicho array de nombres deba declararse antes de lanzar la ejecución de CreateAll: Ejemplo: unidadesE = ["TeamLeaderE","SoldierEB","SoldierEB","SoldierEB"]; El array se define en una variable del tipo “global” para permitir su empleo desde otras funciones como explicaré más adelante. Cuando se indica la creación de un grupo que estará formado por una cantidad de soldados mayor a la cantidad de unidades indicadas en el array, se reiniciará la creación desde el principio de la lista de nombres con la única excepción que se omitirá utilizar el primer nombre o elemento del array que habitualmente se corresponde con el nombre del tipo de unidad líder de grupo. De ésta forma nos aseguramos que solo habrá un único líder y con un modelo de objeto (archivo p3d). El método de asignación de nombres otorga ventajas importantes al momento de reconfigurar una partida para utilizar unidades de un tipo diferente a las originales y así, con muy poco tiempo podemos aprovechar el trabajo realizado por terceros (otros mods), solo cambiando los nombres de unidades en el array. Como ésa, tarea puede no parecerles fácil, les recomiendo que en el mapa de la partida, coloquen un grupo de unidades del bando que será enemigo de los jugadores y le asignen un nombre específico (Ejemplo: GrpMalo), y en el campo de inicio de su líder coloquen:

GrpMalo = group this


Luego ejecutan en el INIT.SQF: if (not isServer) exitWith {}; unidadesE = []; {unidadesE = unidadesE + [typeOf _x]; deletevehicle _x} foreach (units grpmalo); Desde allí, poseen el array (unidadesE) cargado con los nombres de los tipos de unidades que CreateAll utilizará para la creación. Los miembros del grupo creado en el editor son eliminados luego de “leerlos” porque no se necesitarán.

NOMBRE DEL GRUPO CREADO Ahora que tenemos un grupo de infantería desplegado en el terreno, sería estupendo asignarle un nombre que pudiéramos invocar desde fuera de la función para que otras funciones, scripts o gatillos los aprovechen. Supongamos que creamos un grupo y le damos la orden de moverse sobre un poblado. Necesitaríamos alguna forma de ubicar la posición del grupo cuando es atacado para mandar refuerzos. Pero si desconocemos como se llama el grupo, entonces estamos atorados. _handler = [East, ORIGEN, "Man", 8, 0.5, unidadesE, "GrpEste40",…….] spawn handCreateAll; El séptimo parámetro es quien le indica –si no es una cadena vacía-, el nombre del grupo. En el ejemplo, el grupo se llama GrpEste40. Ahora podemos ejecutar un script o función que mande a otro grupo (GrpEste27) a la posición del anterior. (leader GrpEste27) move (position (leader GrpEste40));

COMPORTAMIENTO INICIAL DE GRUPO Este parámetro (el octavo), indica la disposición inicial, frente a la acción, que tiene el grupo creado: "CARELESS", "SAFE", "AWARE",

"COMBAT" o "STEALTH". _handler = [East, ORIGEN, "Man", 3+random(7), 0.5, unidadesE, "GrpEste40", "aware",………] spawn handCreateAll;

TIPO DE FORMACION DE GRUPO El noveno parámetro, indica el tipo de formación adoptada por el grupo de infantería: "COLUMN", "STAG COLUMN", "WEDGE", "ECH LEFT", "ECH

RIGHT", "DIAMOND", "VEE" , "FILE"o "LINE". _handler = [East, ORIGEN, "Man", 3+random(7), 0.5, unidadesE, "GrpEste", "aware", "diamond",…………] spawn handCreateAll;


MODO DE VELOCIDAD DEL GRUPO El décimo parámetro indica la velocidad asignada para moverse en el terreno: "LIMITED", "NORMAL" o "FULL". _handler = [East, ORIGEN, "Man", 3+random(7), 0.5, unidadesE, "GrpEste", "aware", "ve", "normal",………] spawn handCreateAll;

RUTA DE EVOLUCION DEL GRUPO El decimoprimer parámetro, es un array que contendrá los objetos (generalmente ULs) usados como referencia (CreateAll no admite coordenadas de posición, -por ahora-), para que el grupo creado se mueva en el mapa. Habitualmente adquiere una forma similar a ésta: _ruta = [Pos1, Pos2, Pos3, true]; En el ejemplo, se colocaron 3 Uls (Unidades Lógicas llamadas Pos1, Pos2 y Pos3) en el mapa y en lugares adonde el grupo creado deberá dirigirse. Se alcanzarán en forma lineal, primero el grupo irá a las coordenadas de Pos1, luego a las coordenadas de Pos2 y finalmente a las de Pos3.

Como podemos ver en el ejemplo, existe un último elemento en el array de ruta que no es un nombre de objeto sino un valor lógico (true). Al presentarse éste caso, se asume que el grupo, luego de llegar a las coordenadas de posición del objeto llamado Pos3, deberá REINICIAR la secuencia de traslados como si fuera la primera vez. (desde Pos1 en éste caso).


Esto transforma a la ruta en cíclica, pudiendo establecer de ésta forma, rutas de patrulla en ciudades. Si lo que deseamos es una ruta no-cíclica, podemos incluir un valor lógico falso (false) al final o sencillamente no incluir ninguno y CreateAll, detendrá al grupo en la posición de la ultima coordenada y la mantendrá hasta que las condiciones cambien. _ruta = [Pos1, Pos2, Pos3]; _ruta = [Pos1, Pos2, Pos3, false]; Las rutas no-cíclicas, son útiles para forzar una convergencia de unidades sobre un punto particular para establecer asaltos a puntos defendidos. _handler = [East, ORIGEN, "Man", 3+random(7), 0.5, unidadesE, "GrpEste", "safe", "ve", "normal",_ruta] spawn handCreateAll; O bien: _handler = [East, ORIGEN, "Man", 3+random(7), 0.5, unidadesE, "GrpEste", "safe", "ve", "normal", [Pos1, Pos2, Pos3]] spawn handCreateAll;

RUTAS EXTENDIDAS Observando la estructura de conformación de una ruta de evolución de un grupo, vemos que es del tipo monótona. Vamos desde el punto 1 al 2. Desde el 2 al 3 y así sucesivamente. Si quisiéramos que el segundo punto de ruta coincidiera con la posición de un cruce de caminos o un poblado y que se explorara las inmediaciones para asegurarse la ausencia de fuerzas hostiles en las inmediaciones y entonces (y solo entonces), retomar la secuencia de


traslado para el siguiente punto, necesitaríamos INTERRUMPIR dicha secuencia hasta que se cumplan las condiciones correctas. Eso significa, que el grupo debe saltar a una secuencia alterna de acciones, manteniendo la secuencia original en STAND-BY. Eso se llama acción SINCRONICA (en sincronía, sincronizada o en fase). Esto podemos lograrlo colocando en la ruta de evolución del grupo y detrás del objeto de referencia que coincide con el poblado, a un elemento -que ya no es un objeto-, sino un subarray conteniendo 2 elementos: - El nombre de la función a la que se pasará el control (y que ejecutará la acción alterna) (Ejemplo: “explorar.sqf”) - Un valor lógico verdadero o falso (true/false) que le indica a CreateAll si debe detener su proceso y esperar a que la acción alterna finalice o no hacerlo y continuar simultáneamente. Lo importante aquí es decidir a que tipo de proceso pertenece la acción que realizaremos. (SINCRONICA o ASINCRONICA). Veamos, si nuestro grupo debe llegar a Pos2 y explorar el poblado, deberíamos indicarlo de ésta forma: _ruta = [Pos1, Pos2, ["explorar.sqf", true], Pos3, origen, true];

Vemos que luego de alcanzar Pos2, se ejecutará el subproceso indicado por la función EXPLORAR.SQF. Dicha función es acompañada por un valor lógico verdadero (true), lo que le indica a CreateAll que debe esperar a que EXPLORAR.SQF termine. Entonces y solo entonces, CreateAll enviará al grupo a la posición indicada por el objeto Pos3. Vemos también que al llegar a Pos3, se envía al grupo a la posición ORIGEN (donde el grupo fue creado) y luego desde allí, es obligado a reiniciar la ruta, pasando a Pos1, Pos2 (donde nuevamente, se despliega la patrulla de exploración), a Pos3 y así sucesivamente (y eternamente) mientras no cambien las condiciones.


_ruta = [Pos1, Pos2, ["explorar.sqf", true], Pos3, true]; En éste ejemplo se omite pasar por ORIGEN (donde el grupo se creó) y se va desde Pos3 a Pos1. _ruta = [Pos1, Pos2, ["explorar.sqf", true], Origen]; En éste ejemplo se efectúa un único ciclo de patrulla con revisión del pueblo en Pos2 y se bifurca a Origen (omitiendo Pos3) y terminando allí para mantener posición (ruta no-cíclica). Debemos aclarar –antes de proseguir-, que cuando se pasa desde CreateAll a un subproceso indicado en la ruta, se transfiere como UNICO parámetro al nuevo proceso, el nombre del grupo involucrado. De ésta forma podemos, desde la nueva función-acción, gestionar todo lo relacionado con las tareas del grupo en ése punto. Sin ése parámetro transferido, todo sería imposible!. Volviendo al tema de la simultaneidad de acciones, debemos asegurarnos que la función paralela (refuerzos.sqf) tenga una forma de terminar, (ya sea porque se explora el pueblo moviéndose a 2 o 3 locaciones dentro de él o porque el grupo ha sido neutralizado (todos muertos), para luego abandonar la función (exitwith{}) o de lo contrario CreateAll se quedará eternamente esperando por algo que no ocurrirá. Por otra parte, si lo que queremos es una acción ASINCRONICA (simultánea a CreateAll), como puede ser el caso de recibir refuerzos al grupo mientras éste se desplaza hacia una nueva posición, lo informamos de ésta forma: _ruta = [Pos1, Pos2, ["refuerzos.sqf", false], Pos3, true];


Aquí colocamos un valor falso (false) junto con el nombre de la función (refuerzos.sqf), indicando de ésta forma, a CreateAll que debe llamar a la función alterna (refuerzos.sqf), pero no debe esperar a que la misma termine y debe continuar con el siguiente punto de ruta. El ejemplo forzaría a refuerzos.sqf a mandar un contingente de hombres o vehículos a la posición del grupo de exploración y unirse al mismo o lo que se nos ocurra hacer en dicha función. Esta capacidad de llamar a subprocesos, permite enriquecer enormemente una partida que utilice a CreateAll ya que otros editores y creadores de scripts pueden con un mínimo de esfuerzo, ampliar, agregar o modificar los alcances de la partida, aumentando la jugabilidad solamente respetando el protocolo de recibir como parámetro en su plug-in, el nombre del grupo a tratar. Los límites a ésta capacidad están dictadas por nuestra imaginación.

………lo que realmente puede asustar.


CreateAll.sqf // // // // // // // //

******************************************************************************* ** Script: CreateAll.sqf v1.01 ** Descripcion: Creacion de unidades y vehiculos en forma dinรกmica ******************************************************************************* ** Autor: RAVEN ** Site: www.ArmedAssault.com.ar ** Forum: http://www.armedassault.com.ar/foros/index.php?showtopic=1902 *******************************************************************************

if (not isServer) exitWith {}; private["_init"]; _init = false; if (isnil("RAV_CREATEALL_INIT")) then {RAV_CREATEALL_INIT = false}; if ((count _this) == 0) exitWith {}; if (typename (_this select 0) == "STRING") then { if ((_this select 0) == "setsides") then { private["_friend","_enemy","_CualSide"]; if ((count _this) != 3) then { player globalchat "SetSides error or not defined"; } else { _friend = _this select 1; _enemy = _this select 2; if ((typename _friend != "ARRAY") or (typename _enemy != "ARRAY")) then { player globalchat "Setsides error or not defined"; } else { for [{_CualSide = 0},{_CualSide < count _friend},{_CualSide = _CualSide + 1}] do { {(_friend select _CualSide) setfriend [_x, 1]} foreach _friend; {(_friend select _CualSide) setfriend [_x, -1]} foreach _enemy; }; for [{_CualSide = 0},{_CualSide < count _enemy},{_CualSide = _CualSide + 1}] do { {(_enemy select _CualSide) setfriend [_x, 1]} foreach _enemy; {(_enemy select _CualSide) setfriend [_x, -1]} foreach _friend; }; {nil = createCenter _x} foreach _friend; {nil = createCenter _x} foreach _enemy; }; }; _init = true; RAV_CREATEALL_INIT = true; }; }; if (_init) exitWith {}; waituntil {RAV_CREATEALL_INIT}; _Bando _Origen _Ident

= _this select 0; //East, West, Resistance, Civilian = _this select 1; //Objeto, Posicion = _this select 2; //Man, Tank, Helicopter

private["_bando","_Origen","_Ident","_CanCrew","_destreza","_TipCrew","_Modo","_Form","_ enWP","_maxCrew", "_Ruta","_altura","_PosIni","_Vuela","_tip","_man","_cual","_grupo","_esVeh","_el em","_IdGrp", "_veh","_lider","_puesto","_cualWP","_espera","_vivos","_esAir","_alcance","_nomV eh","_ang","_direccion",


"_canform", "_demora","_esWP","_px","_py","_canParm","_accion","_antWP","_vecVeh","_sep1","_sep2"]; if (typeName _Ident == "ARRAY") then { _vecVeh = _Ident; _canForm = count _vecVeh; _destreza= 1; //Nivel de pericia } else { if (_Ident == "MAN") then { _esVeh = false; _demora = 0; _CanCrew = _this select 3; //Numero de soldados/Tripulacion _destreza= _this select 4; //Nivel de pericia de infanteria (lider +50%) _canForm = 1; _vecVeh = [[_Ident, _canCrew]]; } else { _esVeh = true; if (count _this == 3) then { _canCrew = 0, _canForm = 1; } else { _CanCrew = _this select 3; //Numero de soldados/Tripulacion _canForm = _this select 4; //Cantidad de vehiculos a generar }; _destreza= 1; //Nivel de pericia de infanteria (lider +50%) _vecVeh = []; for [{_i = 0},{_i <= _canForm},{_i = _i + 1}] do { _vecVeh = _vecVeh + [[_Ident, _canCrew]]; }; }; }; _IdGrp = ""; if (count _this > 3) then { _TipCrew = _this select 5; //["soldierW", "soldierWB",....] if (count _this > 6) then { _IdGrp = _this select 6; //Nombre del grupo _modo = _this select 7; //"safe", "Combat", etc / direcci贸n Angular _Form = _this select 8; //"line", "column", etc _Speed = _this select 9; //"limited", "normal", "full" _Ruta = _this select 10; //[objeto/Posicion, objeto/Posicion,.....,true/false] }; }; _altura = 0; _PosIni = [0,0,0]; _Vuela = "FORM"; _alcance = 100; if (typeName _Origen == "OBJECT") then {_PosIni = position _Origen} else {_PosIni = _Origen}; _Cual = 0; _lider = false; _grupo = createGroup _bando; _px = _PosIni select 0; _py = _PosIni select 1; _sep1 = 0; _sep2 = 0; for [{_cualVeh = 0},{_cualVeh < _canForm},{_cualVeh = _cualVeh + 1}] do { _elem = _vecVeh select _cualVeh; _nomVeh = _elem select 0; _cancrew = _elem select 1;


if if if if {

(count _elem > 1) then {_canCrewm = _elem select 1} else {_canCrew = 0}; (_nomVeh == "MAN") then {_esVeh = false; _demora = 0} else {_esVeh = true}; (_nomVeh IsKindOF "AIR") then {_esAir = true} else {_esAir = false}; (_esVeh) then

if (_canCrew != 0 and _esAir) then {_altura = 200; _Vuela = "FLY"; _alcance = 500}; if (_canCrew == 0 and count _this > 5) then {_ang = _tipCrew} else {_ang = 0}; _demora = 2; if if if if if

("CAR" counttype [_veh] > 0) then {_demora = 1; _sep2 = 10}; ("TRUCK" counttype [_veh] > 0) then {_demora = 1; _sep2 = 15}; ("TANK" counttype [_veh] > 0) then {_demora = 1; _sep2 = 15}; ("HELICOPTER" counttype [_veh] > 0) then {_demora = 10; _sep2 = 20}; ("PLANE" counttype [_veh] > 0) then {_demora = 1; _sep2 = 30};

_sep1 = _sep1 + _sep2; if (typeName _origen == "ARRAY") then {_direccion = 0} else {_direccion = direction _origen}; _px = (_PosIni select 0) + _sep1 * sin((_direccion)+180); _py = (_PosIni select 1) + _sep1 * cos((_direccion)+180); _veh = createVehicle [_nomVeh,[_px,_py,_Altura], [], 0, _Vuela]; if (typeName _Origen == "OBJECT") then {_veh setdir (direction (_origen) + _ang)}; _maxCrew = 0; {_maxCrew = _maxCrew + (_veh emptypositions _x)} foreach ["driver","gunner","comander","cargo"]; if (_canCrew < 0) then {_canCrew = _maxCrew}; }; if (_canCrew > 0) then { for [{_i = 0},{_i < _canCrew},{_i = _i + 1}] do { if (_i >= count _tipCrew) then {_cual = 0} else {_cual = _i}; if (_Cual == 0 and _lider) then {_Cual = 1}; _tip = _tipCrew select _cual; _pos = [(_PosIni select 0) + 2 * _i,(_PosIni select 1) + 2 * _i, 0]; _man = _grupo createUnit [_tip,_pos, [], 10, _form]; _man setbehaviour _modo; _man setspeedmode _speed; if (_i == 0) then { if (not _lider) then { _lider = true; _grupo selectleader _man; _unidad setRank "CORPORAL"; _man setSkill (_destreza * 1.5); } else {_man setRank "PRIVATE"; _man setSkill _destreza}; } else { _man setRank "PRIVATE"; _man setSkill _destreza; }; if (_esVeh) then { _Puesto = 0; if (_veh emptypositions "commander" > 0) then {_puesto = 3}; if (_veh emptypositions "gunner" > 0)

then {_puesto =

if (_veh emptypositions "driver" > 0)

then {_puesto =

2}; 1}; if (_esVeh) then { switch (_puesto) do { case 1: {_man moveinDriver _veh};


case 2: {_man moveingunner _veh}; case 3: {_man moveincommander _veh}; default {_man moveincargo _veh;}; }; }; }; sleep 0.01; }; if (_esVeh and _esAir) then { _px = ((position _veh) select 0) + 200 * sin(direction _veh); _py = ((position _veh) select 1) + 200 * cos(direction _veh); _veh move [_px, _py]; }; sleep _demora; }; }; //--- Removedor de unidades eliminadas if (not isnil("RAV_REMOVEDEAD")) then { { _x removeEventHandler ["killed", 0]; _x addeventhandler ["Killed", {_this execVM RAV_REMOVEDEAD}]; if (_x != (vehicle _x)) then { (vehicle _x) addeventhandler ["Killed", {_this execVM RAV_REMOVEDEAD}]; {_x addeventhandler ["Killed", {_this execVM RAV_REMOVEDEAD}]} foreach (crew (vehicle _x)); }; } foreach units _Grupo; }; // Reasigna nombre de Grupo, si fue indicado sleep 1; if (_canCrew > 0) then { if (_IdGrp != "") then { _man = leader _grupo; call compile format ["%1 = group _man", _IdGrp]; }; }; _grupo setformation _form; units _grupo commandfollow (leader _grupo); _antWP = objnull; // Inicia Rutas de WP for [{_i = 0}, {_i < (count _Ruta)}, {_i = _i + 1}] do { if (count (units _grupo) > 0) then { _esWP = false; _cualWP = _Ruta select _i; switch (typeName _cualWP) do { case "BOOL": { if (_cualWP) then {_i = -1; _cualWP}; }; case "ARRAY": { _canParm = count _cualWP; if (_canParm > 0) then { _accion = _cualWP select 0; if (typeName _accion == "STRING") then { _handAccion = compile preprocessFile _accion; _handler = [_grupo] spawn _handAccion; if (_canParm > 1) then


{ _waitHandler = _cualWP select 1; if (typeName _waithandler == "BOOL") then { if (_waithandler) then {waitUntil {scriptDone _handler}}; }; }; }; }; }; default {_esWP = true}; }; if (_esWP) then { (leader _grupo) move (position _cualWP); sleep 1; if (_x != (leader _grupo)) then {_x dofollow (leader _grupo)} foreach (units _grupo); _espera = true; while {_espera} do { _vivos = 0; _enWp = true; {if (alive _x) then {_vivos = _vivos + 1}} foreach (units _grupo); {if (_x distance _cualWP > _alcance) then {_enWP = false}} foreach (units _grupo); if (_vivos == 0 or _enWP) then { if (not isnull(_antWP)) then { if (_enWP) then {_espera = false}; } else {_espera = false}; }; sleep 1; }; _antWP = _cualWP; if (_vivos == 0) then {_i = count _Ruta}; }; } else {_i = count _Ruta}; };

//--------------------- Espero lo aprovechen ---------------------------------//

NOTA: La función puede acoplar a cada unidad creada ingame, con un manejador de eventos por muerte (EVENTHANDLER del tipo “KILLED”) que bifurcará el control a una función externa (puede ser de otro programador) para gestionar el proceso de retiro de unidades eliminadas durante una partida (remoción de cuerpos) o eliminación de vehiculos destruidos (a los que también se les asigna un eventhandler dentro de CreateAll). Para lograr esto, CreateAll busca la existencia de una variable global de nombre particular (RAV_REMOVEDEAD). De existir dicha variable (usualmente creada en el init.sqs o init.sqf de una partida), su va lor contendrá el nombre de la funcion que CreateAll enlazará al eventhandler.


Ejemplo de init.sqf con asignaci贸n de removedor de unidades eliminadas:

//--- Funci贸n encargada de eliminar unidades destruidas en la partida RAV_REMOVEDEAD = "RemoveDead.sqf"; if (isServer or (local player)) then { //--- Precompilacion del codigo de las funciones de soporte a la mision handCreateAll = compile preprocessFile "CreateAll.sqf"; //--- Establece las relaciones entre bandos (Amigos/Enemigos) para que pueda trabajar CreateAll.sqf _handler = ["setsides",[west, resistance],[east]] spawn handCreateAll; //--- Arma vector de tipos de unidades para bando ESTE a partir de grupo inicial en mapa unidadesE = []; {unidadesE = unidadesE + [typeOf _x]; deletevehicle _x} foreach (units grpmalo); //--- Arma vector de tipos de unidades para bando RESISTENCIA a partir de grupo inicial en mapa unidadesR = []; {unidadesR = unidadesR + [typeOf _x]; deletevehicle _x} foreach (units grpbueno); _ruta = [Origen, Pos1, Pos2, true]; _vehiculos = [["UAZMG",2],["uralOpen",3+random(8)],["bus_city",-1]]; _handler = [east, ORIGEN, _vehiculos, 2, 5, unidadesE, "GrpEste", "aware", "File", "limited", _ruta] spawn handCreateAll; };

Manual CreateAll.sqf por Raven  

Manual en castellano sobre la utilizacion del script para la creacion de cualquier unidad ingame. Creado: Raven Probado: Bhelma