フォーラムへの返信
-
投稿者投稿
-
Line参加者
-
TIPS
-
1.マップに既に設置されているオブジェクトを無敵化orダメージコントロール
既に設置されているオブジェクトの名前を勝手に決めてあげる事によりそれをエディター側で操作することができます。
例
ゲームロジックを置いて、中身に
tower = (position this nearestobject 1594130); tower allowDamage false;
towerと名づけられたオブジェクトはこの構文で無敵になりました。
allowDamageの他にsimulateやsetdamage等色々扱えるようになります。lockする事も可能です。
部位ダメージを与えたければ
tower addEventHandler ["HandleDamage",{hint format ["%1",(_this select 1)]}];
ダメージを受けた場所がhintに表示されるのでその場所をメモし、
tower setHit ["light_1_hitpoint",0.97"]; //OFF
towerが”Lamps_base_F”とした場合灯りがOFFになります。THIS addEventHandler ["HandleDamage",{hint format ["%1",(_this select 1)]}];
は意外と使う物ですので覚えておくと便利です。-
2.setObjectTexture
車両の塗装を差し替えたい時は以下の構文
例:Offroad
this setVariable ["BIS_enableRandomization", false]; this setObjectTextureGlobal [0, "\A3\soft_F\Offroad_01\Data\offroad_01_ext_as.paa"];
Offroadには各色のパターンがランダムで貼り付けられます。
これはBIS_enableRandomizationファンクションで自動的に行われていますので、まずこれを切ります。
そして任意で貼り付ける事が可能です。offroad_01_ext_base01_co.paa offroad_01_ext_base02_co.paa offroad_01_ext_base03_co.paa offroad_01_ext_base04_co.paa offroad_01_ext_base05_co.paa offroad_01_ext_co.paa offroad_01_ext_nohq.paa
Line参加者-
Simple Supply Drop Script
上空から弾薬箱、車両を投下するスクリプトです。
少し話題になっていたので投下します。SupplyDrop.sqf
_temp = [“markerName”,”vehicleType”] execVM “scripts\supplyDrop.sqf”;
_position = _this select 0; _vehicleclass = _this select 1; _createpos = getMarkerpos _position; _chuteType = "B_Parachute_02_F"; _chute = createVehicle [_chuteType, [100, 100, 200], [], 0, 'FLY']; _chute setPos [_createpos select 0, _createpos select 1, 100]; _drop = createVehicle [_vehicleclass, position _chute, [], 0, 'NONE']; _drop attachTo [_chute, [0, 0, -.3]]; waitUntil {position _drop select 2 < 0.5 || isNull _chute}; detach _drop; _drop setPos [position _drop select 0, position _drop select 1, 0];
基本はこれベースでグローブマスター等から投下する事も可能です。
夢ひろがりんぐですが使いどころが限定されますね。ミッション開始時やタスク完了時のインターバル等でどうぞ。
追記(応用編)動作未確認
ミッションに組み込んだ例を紹介します。
syntax : _temp = [“markerName”,”vehicleType”,1000] execVM “scripts\supplyDrop.sqf”;_position = _this select 0; _vehicleclass = _this select 1; _altitude = _this select 2; _createpos = getMarkerpos _position; _drop = createVehicle [_vehicleclass, _createpos, [], _altitude, "FLY"]; [_drop] execVM "scripts\cargo_ammo.sqf"; WaitUntil {getPos _drop select 2 < 250}; _chuteType = "B_Parachute_02_F"; _chute = createVehicle [_chuteType, [100, 100, 250], [], 0, 'FLY']; Sleep 0.1; _d_drop = getposASL _drop; _chute setPos [_d_drop]; _drop attachTo [_chute, [0, 0, -.3]]; waitUntil {position _drop select 2 < 0.5 || isNull _chute}; detach _drop; _drop setPos [position _drop select 0, position _drop select 1, 0];
1000mで生成し、250mでパラシュートが展開されます。
そしてカーゴ内に弾薬生成しました。グローブマスターから投下をしたい場合は
syntax : _temp = [“planeName”,”vehicleType”] execVM “scripts\supplyDrop.sqf”;
_createpos = getMarkerpos _position;
の箇所を_createpos = [getpos _position select 0, getpos _position select 1, getpos _position select 2 - 10]; _chuteType = "B_Parachute_02_F"; _chute = createVehicle [_chuteType, [100, 100, 200], [], 0, 'FLY']; _chute setPos [_createpos select 0, _createpos select 1, _createpos select 2 + 2]; _drop = createVehicle [_vehicleclass, position _chute, [], 0, 'NONE']; _drop attachTo [_chute, [0, 0, -.3]]; waitUntil {position _drop select 2 < 0.5 || isNull _chute}; detach _drop; _drop setPos [position _drop select 0, position _drop select 1, 0];
と書き換え、このスクリプト発動条件を
Plane01 distance getmarkerpos "dropzone" < 200
等に設定すれば出来ると思います。
スクリプトの文頭にwaitUntilをかませてもいいですけどね。Line参加者Akasakaさん
ご指摘ありがとうございます。
見落としてました。
削除しておきました。Line参加者トリさん了解です。
すみません、少し内容不足でした。
削除となった理由を聞きたかったのですが、その件については他の人に話は伺いました。
RHSとユニットが被っている事が削除理由なんですね。
次からは削除理由も付け足しておいた方が良いと思います。Line参加者- missionファイルのロードエラーについて
今まで使用していたアドオンの削除が原因でエディットしようにもロードエラーでミッションが読み込めなくなってしまったというケースが起こる可能性があります。
削除されたアドオンのユニットを削除したのにも関わらず、ミッションが読み込めないという方へ対応策を紹介します。まずmission.sqmを開いてください。
※注意※
開いたらこれから指定する場所以外への記入、削除は絶対に行わないでください。
どこを弄ったか場所がわからなくなり二度と読み込めなくなる可能性があります。version=12; class Mission { addOns[]= { "a3_map_stratis", "agm_medical", "A3_Characters_F_BLUFOR", "a3_characters_f", "maa_uniform", "A3_Static_F_Gamma_AA", "A3_Static_F_Gamma", "a3_static_f", "aia_misc3_config", "rds_staticweapons_core", "CAMisc", "aia_misc_config", "A3_Modules_F_Intel", "A3_Air_F_Beta_Heli_Transport_01", "A3_Armor_F_Panther", "task_force_radio_items", "A3_Characters_F_INDEP", "A3_Soft_F_MRAP_01", "A3_Weapons_F_Ammoboxes", "A3_Static_F_Beta_Mortar_01", "a3_static_f_mortar_01", "A3_Modules_F" }; addOnsAuto[]= { "agm_medical", "A3_Characters_F_BLUFOR", "a3_characters_f", "maa_uniform", "A3_Static_F_Gamma_AA", "A3_Modules_F_Intel", "A3_Characters_F_INDEP", "A3_Static_F_Beta_Mortar_01", "a3_static_f_mortar_01", "A3_Modules_F", "RDS_StaticWeapons_Core", "A3_Static_F_Gamma", "a3_static_f", "aia_misc3_config", "CAMisc", "aia_misc_config", "A3_Air_F_Beta_Heli_Transport_01", "A3_Armor_F_Panther", "task_force_radio_items", "A3_Soft_F_MRAP_01", "A3_Weapons_F_Ammoboxes", "a3_map_stratis" };
sqmファイルを開くと文頭はこんな形で始まっています。
addOns[]= addOnsAuto[]=
ここの中身を全削除します。
version=12; class Mission { addOns[]= { }; addOnsAuto[]= { };
こうする事で開けなかったミッションが開けるようになると思います。
ミッションが開けるようになった後は、通常通りセーブをすれば現在の使用しているアドオンのみ自動保存されますのでご安心を。- この返信は9年、 5ヶ月前にLineが編集しました。
Line参加者-
Variableについて
Variableとはエディター側で任意に決める事が出来ます。
例を踏まえて説明したいと思います。Trigger 1 Condition : not (alive Tank01) or isNull (driver Tank01) Act : TASK1DONE = TRUE; PublicVariable "TASK1DONE"; Trigger 2 Condition : TASK1DONE AND (WEST countSide thislist) > 5 Act : "END" call BIS_fnc_endMission;
この様に二つのトリガーを設定したと想定します。
まずトリガー1の方はTANK01が行動不能になればTASK1DONEというバリアブルが発動します。
そして、TASK1DONEの値TRUEを得たトリガー2にBluforユニットが6名以上トリガー内に入ればミッションエンドという事になります。PublicVariableというのは各クライアントと同期を取る為の命令です。
これが無ければ自分は値を取得しているのに他のプレイヤーは取得していないという状況になる可能性があります。
そしてこの場合トリガー2が発動しない等、いつまで経ってもミッションが終了しない人等が出て来ます。
また、途中参加の人が上手く同期を取ることが出来なくなり、タスク完了してる人としていない人が出て来たりもします。ローカル処理での状態では必須です。(addAction等のsqfファイル)
Variableを数値化
Variableは基本TRUEかFALSEで使い分けを行いますが、数値を当てはめることも出来ます。
例
Init.sqf
Bomb_count = 0;
Initにまずこう記述します。
ミッションが開始されれば全プレイヤーはBomb_countが0ということを知ります。次にトリガーのActに
Trigger 1 Condition : Defuse_Bomb01 Act : Bomb_count = Bomb_count +1; PublicVariable "Bomb_count"; Trigger 2 Condition : Bomb_count == 1 Act : TASK1DONE = TRUE;PublicVariable "TASK1DONE";
トリガー1でBomb_count + 1でBomb_countの値が1になりました。
トリガー2でBomb_count == 1、つまり==というのは1とBomb_countが同じ物として定義されている場合ということです。注意 : 数字を利用する際は必ず前持ってinit.sqfでVariableを定義しておきましょう。
Variableを数値化するのは基本スクリプトで走らせる際に使用したりします。
基本はTRUE or FALSEで大丈夫です。また他のスクリプトでWaitUntilやWhileを使用して待機しているスクリプトがある時は予めinit.sqf内でVariableを認識させておく必要があります。
Init.sqfif (isServer) then { OBJECTFIXED = FALSE; SEQUENCE01START = FALSE; };
この様に予め設定をしておかないとOBJECTFIXEDって何????とサーバー側でエラーを吐き続けます。
色々試すとミッションの幅が広がりますのでチャレンジしてみてください。
しかし、複雑にするとエラー探しが大変になり、ミッションが動かないという状況になりますので注意が必要です。
Line参加者@cha_mi8 削除の件について
今回12月5日に削除となっている理由をお聞かせください。
Line参加者- Teleport Script by Stealer
途中参加の方向けのテレポートスクリプトです。
開始地点に設置していると優しさを感じますね。teleportToLead.sqf
//Teleport to Leader for JIP by Stealer v0.5 //eg: this addAction ["<t color='#0099FF'>Teleport to Your Team Position</t>","scripts\teleportToLead.sqf"]; if !(local player) exitwith {}; private ["_leader","_dir"]; _leader = leader (group (vehicle player)); _dir = getdir _leader; if ((vehicle _leader) == (_leader)) then { titletext ["","BLACK IN",1]; player setpos [(getpos _leader select 0) - ((random(5)+3)*sin(_dir)), (getpos _leader select 1) - ((random(5)+3)*cos(_dir)), 0.5]; player setdir ((_dir) -180); } else { if ((vehicle _leader) emptypositions "cargo"== 0) then { hint "Your Leader is moving on vehicle and Full of passenger.\ntry again later."; } else { titletext ["","BLACK IN",1]; player moveincargo vehicle _leader; }; };
目印とするオブジェクトのイニシャライズに
this addAction ["<t color='#0099FF'>Teleport to Your Team Position</t>","scripts\teleportToLead.sqf"];
と入れます。簡単ですね!
Line参加者- AIスキル設定
今回はAIのスキル設定の仕方について紹介します。
数値がデフォルトのままだと敵AIは強すぎてバランス崩壊を招く場合があります。
特に命中率関係の設定変更は必須と考えます。AIskills.sqf
if (!isServer) exitWith {}; { if (side _x == EAST) then { _x setskill ["aimingAccuracy",0.2];//命中率(全て0~1の値) _x setskill ["aimingShake",0.8];//手ぶれ具合 _x setskill ["aimingSpeed",0.5];//照準速度 _x setskill ["commanding",0.95];//指揮力 _x setskill ["courage",0];//度胸 _x setskill ["general",0.8];//戦略 _x setskill ["reloadSpeed",0.4];//再装填速度 _x setskill ["spotDistance",0.5];//補足範囲 _x setskill ["spotTime",0.8];//補足まで至る時間 _x unassignItem "NVGoggles";//NV除去 _x unassignItem "NVGoggles_INDEP"; _x unassignItem "NVGoggles_OPFOR"; _x removeItem "NVGoggles"; _x removeItem "NVGoggles_INDEP"; _x removeItem "NVGoggles_OPFOR"; _x removeItem "NVGoggles"; _x addPrimaryWeaponItem "RH_SFM952V";//シュアファイヤ追加 _x enablegunlights "forceOn";//点灯 _x addEventHandler ["killed", {handle = [_this select 0] execVM "scripts\bury.sqf"}];//死体削除スクリプト }; } forEach allUnits;//EASTサイドの全てのユニットに対し適用 { if (side _x == INDEPENDENT) then { _x setskill ["aimingAccuracy",0.2];//命中率(全て0~1の値) _x setskill ["aimingShake",0.8];//手ぶれ具合 _x setskill ["aimingSpeed",0.5];//照準速度 _x setskill ["commanding",0.95];//指揮力 _x setskill ["courage",0];//度胸 _x setskill ["general",0.8];//戦略 _x setskill ["reloadSpeed",0.4];//再装填速度 _x setskill ["spotDistance",0.5];//補足範囲 _x setskill ["spotTime",0.8];//補足まで至る時間 _x unassignItem "NVGoggles";//NV除去 _x unassignItem "NVGoggles_INDEP"; _x unassignItem "NVGoggles_OPFOR"; _x removeItem "NVGoggles"; _x removeItem "NVGoggles_INDEP"; _x removeItem "NVGoggles_OPFOR"; _x removeItem "NVGoggles"; _x addPrimaryWeaponItem "RH_SFM952V";//シュアファイヤ追加 _x enablegunlights "forceOn";//点灯 _x addEventHandler ["killed", {handle = [_this select 0] execVM "scripts\bury.sqf"}];//死体削除スクリプト }; } forEach allUnits;//INDEPENDENTサイドの全てのユニットに対し適用
森林での戦闘はプレイヤー側の不利となりますので、
[“aimingAccuracy”,0.2]を[“aimingAccuracy”,0.15]若しくは[“aimingAccuracy”,0.1]に設定しましょう。死体削除スクリプト
bury.sqf// Deletes dead Enemy _unit = _this select 0; if (not (_unit isKindOf "Man")) then { {_x setpos position _unit} forEach crew _unit; sleep 30; deletevehicle _unit; }; if (_unit isKindOf "Man") then { if(not ((vehicle _unit) isKindOf "Man")) then {_unit setpos (position vehicle _unit)} ; sleep 30; hideBody _unit; sleep 4; deleteVehicle _unit; };
死後30秒後に削除します。
これの目的はクライアント側の負荷軽減です。_x addEventHandler ["killed", {handle = [_this select 0] execVM "scripts\bury.sqf"}];
この命令文は_xが殺された場合handle=のスクリプトが_xに対して作動するという事です。
この構文は少し特殊な為追々理解していただければよいです。そしてinit.sqfに構文を足します。
// SKILLS if (isServer) then { execVM "scripts\aiSkill.sqf"; };
戦闘時間を長引かせると同時に、雰囲気をより長く楽しむ為にも是非取り入れてみてください。
敵を勇猛果敢にしたい場合は[“courage”,1]に設定。
Line参加者- ミッション製作編
実際に画像込みで説明したいと思いますので、これはまた後日に。
- 外部スクリプトの注意点
Armaholic等で有志の方が製作した外部スクリプトが種類豊富にありますが、何も手を付け加えず導入できるのは限られています。
また、それらは大変便利な物もありますがよく見ればデメリットもあります。例としていくつか紹介したいと思います。
Urban Patrol Script 通称:UPS
これはマーカーやオブジェクトの範囲内を指定し、AIをパトロールさせるというスクリプトです。
マーカーだけ置いて、ユニットのイニシャライズに1行構文を入れるだけで勝手に徘徊を始めます。
これだけ聞くと便利なもので導入もさほど難しくはないです。デメリット
数秒間の間に、存在している配下ユニットに対してdoMove指示を出し続けています。
即ちそれが何グループにも及ぶとサーバー側に負荷がかかります。それでも使いたいという方は10人くらいの少人数ミッション向けに使用された方が良いと考えます。
Arsenal
みんな大好きお化粧道具箱です。
説明するまでもないでしょう。便利なものです。デメリット
アーセナルに追加した種類が多ければ多い程、参加した人数が多ければ多いほどサーバー側ではなくクライアント側に対しての負荷が高まります。
何故かというと、十人十色、引き出すものが各々違うのでそれを表示させるグラフィックの量が多くなるからです。対応策
大人数ミッションの時はできる限り必要最低限の物で収める事です。createVehicle Scriptの使用
いくつものスクリプトを多重で走らせるとサーバー側に負荷がかかるのと、createVehicleを使用しての多重沸きはクライアント側に対しても相当な負荷となります。
現に私がそれをやって学びました。例として私が書いた構文を記載します。
Create_GUER.sqf
if (!isServer) exitWith {}; _starts = ["inf_spw1","inf_spw2","inf_spw3","inf_spw4","inf_spw5","inf_spw6","inf_spw7","inf_spw8"]; _createpos = getmarkerpos (_starts select (floor random 8)); _squadgroup = creategroup (EAST); _squadgroup = [_createpos, (EAST), ["CAF_AG_EEUR_R_AK47","CAF_AG_EEUR_R_RPK74","CAF_AG_EEUR_R_PKM","CAF_AG_EEUR_R_AK47"]] call BIS_fnc_spawnGroup; sleep 0.1; _leader = leader _squadGroup; if (debug == 1) then { _sumark = [_leader] execVM "scripts\markers\marker_enemy_Inf.sqf"; }; {_x addEventHandler ["killed", {handle = [_this select 0] execVM "scripts\bury.sqf"}]} forEach (units _squadgroup); //Skills { _x setskill ["aimingAccuracy",0.2]; _x setskill ["spotDistance",0.5]; _x setskill ["spotTime",0.8]; _x setskill ["courage",0]; _x setskill ["commanding",0.95]; _x setskill ["aimingShake",0.8]; _x setskill ["aimingSpeed",1]; //_x addPrimaryWeaponItem "acc_flashlight"; //_x enablegunlights "forceOn"; }foreach (units _squadgroup); _squadgroup setSpeedMode "NORMAL"; _squadgroup setCombatMode "RED"; _squadgroup AllowFleeing 0; _squadgroup setBehaviour "AWARE"; _squadgroup setFormation "LINE"; while {alive _leader} do { _waypoints3 = ["WP1","WP2","WP3"]; _wpselect3 = getmarkerpos (_waypoints3 select (floor random 3)); _wp3 setWaypointType "SAD"; _wp3 = _squadgroup addwaypoint [_wpselect3,0]; sleep 300;}; waitUntil{!alive _leader}; execVM "scripts\createvehicle\createinf_guer.sqf";
これの概要を説明すると
まずゲリラ兵を8か所あるうちのマーカーのいずれか1つのマーカーから出現させ、3つあるうちの1つのマーカーに警戒しながら移動させる。
そして5分間経つとまた3つあるうちの1つを選択しそこに移動をはじめ、リーダーが死亡するとまたこのスクリプトが初めからループするというスクリプトです。
要するに無限沸きということです。これが2~3パーティーならまだ許容範囲なのですが、実際のミッションはこれだけではなく他にも色々なスクリプトを同時に走らせる事もあるので使用の際には注意が必要です。
結論
外部スクリプトの使用にあっては、ただミッションに放り込むだけではなく、テキストで開いてみて内容をある程度把握することが大切です。
また実際に眺めてみると勉強になりますし、自分のやりたかった事のヒントもでてくるでしょう。Line参加者- Description.extの設定
init.sqfファイルの次にDescription.extの設定を行いたいと思います。
この中身はinit.sqfよりも重要なファイルで特に、とあるconfigを1つ間違えるとArma3クライアントがクラッシュし、ミッションが読み込めなくなります。
ではざっと中身を見てみましょう。
例として私のミッションからextファイルをここにコピペします。class Header { gameType = COOP; minPlayers = 1; maxPlayers = 24; }; //文頭はまずclass Headerの設定です。 //Game TypeはCoop 他には"DM","CTF","TEAM","DEATHMATCH","CTI","FF"等があります。 //参加最少遂行人数:2人にすると1人しかロビーに居ない場合ミッション開始ができません。 //参加最高人数:必ずプレイアブルスロットの人数分を書き込んでください。Co20なのにここで10に設定すると10人までしか入れなくなります。 allowFunctionsLog = 0; //ファンクションエラーをドキュメントのエラーRPTファイルに書き残す設定です。0=false,1=true onLoadIntroTime = false; //ミッションロード中に時間を表示させるかどうかの設定です。1=true,0=false //イントロは普段使わないのでこの状態で大丈夫です。 onLoadMissionTime = false; //上記と同じロード中に時間を表示させるかの設定。 disabledAI = 0; //これを1に設定しているとミッション開始後空きスロットが削除されてしまいます。 debriefing = 1; //ミッション終了結果を表示するかの設定です。 showGPS = 1; //"ItemGPS"を所持させた場合ミッション中にGPS座標を表示させるかの設定です。1=表示させる 0=表示させない //forceRotorLibSimulation = 1; //force enable //ヘリアドオンが追加され新たに追加されたコマンドです。 //これはヘリ操作をミッション側で強制的にAdvancedモードにさせるかの設定です。1=Advanced 0=none respawn = "BIRD"; respawndelay = 4; respawnDialog = 0; //死亡時の設定 //ミッション中に死亡した場合カモメとして戦場を行動できるようになります。 overviewPicture = "overview.paa"; author = "SQUAD Hrimfaxi authored by Line"; onLoadName = "D A Y A F T E R D A Y"; onLoadMission = "<t color='#7eafde'>triserver</t>"; //ロード画面時の設定 //mission.sqmファイルの置いてある階層に.paaファイルを置く事でロード画面中に任意の画像が表示されます。 //推奨解像度:1024*768 //authorには作者の名前を //OnloadNameにはミッション名を記入しましょう。 //onLoadMissionにはサーバー名や適当なものを。 /* TAW View Distance Script */ #include "taw_vd\dialog.hpp" //視界や芝の表示距離を変更する外部スクリプトです。 //これを使用する場合はinit.sqfにも構文を書き足さないといけません。 //init.sqfにtawvd_disablenone = true;と書き足してください。 //TAW View Distance Scriptはhttp://www.armaholic.com/page.php?id=19751で入手できます。 class CfgFunctions { #include "taw_vd\CfgFunctions.hpp" }; //TAW View Distance Scriptのファンクション設定です。 class CfgSounds { sounds[] = {"bomb_beep"}; class bomb_beep { // how the sound is referred to in the editor (e.g. trigger effects) name = "bomb_beep"; // filename, volume, pitch sound[] = {"sounds\bomb_beep.ogg", 1, 1}; // subtitle delay in seconds, subtitle text titles[] = {0, ""}; }; class car_horn01 { // how the sound is referred to in the editor (e.g. trigger effects) name = "car_horn01"; // filename, volume, pitch sound[] = {"sounds\horn.ogg", 1, 1}; // subtitle delay in seconds, subtitle text titles[] = {0, ""}; }; }; //CfgSoundsとは独自の効果音をミッション中に使用したい場合やsay3D等で音声やBGMを流したい時にここに追加していきます。 class CfgNotifications { class CurrentTask { title = "CURRENT TASK"; iconPicture = "\A3\ui_f\data\map\mapcontrol\taskIcon_ca.paa"; description = "%1"; color[] = {1,1,1,1}; duration = 10; priority = 9; }; class NewTask { title = "NEW TASK"; iconPicture = "\A3\ui_f\data\map\mapcontrol\taskIconcreated_ca.paa"; description = "%1"; color[] = {1,1,1,1}; duration = 10; priority = 8; }; class TaskCanceled { title = "TASK CANCELED"; iconPicture = "\A3\ui_f\data\map\mapcontrol\taskIconcanceled_ca.paa"; description = "%1"; color[] = {1,1,1,1}; duration = 10; priority = 6; }; class TaskDone { title = "TASK SUCCEEDED"; iconPicture = "\A3\ui_f\data\map\mapcontrol\taskIcondone_ca.paa"; description = "%1"; color[] = {0.6,0.8,0.4,1}; duration = 20; priority = 5; }; class TaskFailed { title = "TASK FAILED"; iconPicture = "\A3\ui_f\data\map\mapcontrol\taskIconfailed_ca.paa"; description = "%1"; color[] = {0.8,0.2,0.2,1}; duration = 20; priority = 7; }; }; //TASK表示設定です。 //ここで設定しているとFunctionから呼び起こす事ができます。 //使用例:トリガーのOn Actに //["CurrentTask",["Disablement weapons"]] call BIS_fnc_showNotification; class CfgDebriefing { class End1 { title = "MISSION ACCOMPLISHED"; subtitle = "GREAT WORK!"; description = ""; picture = ""; pictureColor[] = {1.0,1.0,1.0,1}; }; class End2 { title = "MISSION FAILED"; subtitle = "Are you serious?"; description = "try again!"; picture = ""; pictureColor[] = {0,0,0,1}; }; }; //ミッションエンドフラグ設定です。 //これを使用することによりデレレレーン!と音とテレビの様な感じになって終了します。 //使用例 //成功した場合 //Condition : anybody //On Act : "END1" call BIS_fnc_endMission; //失敗した場合 //Condition : anybody //On Act : "END2" call BIS_fnc_endMission; class Params { class Daytime { title = "Time"; texts[] = {"Morning","Day","Evening","Night"}; values[] = {4.5,10,16,0}; default = 4.5; function = "BIS_fnc_paramDaytime"; // (Optional) Function called when player joins, selected value is passed as an argument isGlobal = 1; // (Optional) 1 to execute script / function locally for every player who joins, 0 to do it only on server }; }; //気付く人はあまりいないのですがミッションパラメータの設定項目です。 //時間帯の変更ができます。 //1つのミッションで色々な時間でプレイできると楽しくなりますよね。 //もちろん夜戦もできるように装備も調整してください。 //Skiptimeだけではなく、ここでは色々なパラメーターを記入しミッションに反映させることができます。 //それはそのうちまた紹介したいと思います。
- TexView2
.paaファイルを作成するプログラムです。
アルファチャンネルから.paaを作成したい場合は.pngに一度変換し、.paaで保存してください。
jpgからでも読み込めますがアルファチャンネルはNG
http://www.armaholic.com/page.php?id=1563Line参加者- init.sqf作成編
自分なりのinit.sqf作成を紹介したいと思います。
init.sqfというのはミッションを開始する前の設定ファイルです。
mission.sqmのみでも動くには動きますが、ここでは更に詳しい設定が行えます。
配置階層はmission.sqmと同階層で名前は必ずinit.sqfとしてください。ではinit.sqfを作成したらまずはこれを入力します。
if (!isDedicated) then {waitUntil {!isNull player && isPlayer player};};
これは何かというと参加したプレイヤーにinit.sqfを読み込ませる為の構文です。
訳すと、
もしサーバーではない時、また、プレイヤーがプレイヤーになるまで待つ。
プレイヤーというスロットに参加するプレイヤーが入るまで待たせる為の構文です。
これが無いと過去にinit.sqfが読み込まれないという問題が起きていました。
現在はもう既におまじないレベルですが回避策はいくらでも盛り込んでおいた方がよいです。- init.sqf内設定編
if ((!isServer) && (player != player)) then { waitUntil {player == player}; };
どちらでも良いので使用してください。
次に余計な物を省いておきます。
enableSaving [false,false]; enableRadio false;
マルチでセーブしてどうすんねんという感じなので1行目は必要ありません。
2行目は喧しいラジオチャッターを切りました。
しかし、2行目を切ってしまうとCfgRadioが全く反映されませんので注意してください。さてお次はエディット中、またはテストミッション時に使える便利なコマンドを入れます。
onMapSingleClick "if ((local player) and _alt) then {(vehicle player) setPos _pos;}"; player addAction [">Copy Position","copypos.sqf"]; player addAction [">Copy Objectname","objectname.sqf"];
1行目はAltキーを押しながらマップを左クリックすると任意の場所に飛ぶことができます。
車両に乗った状態でも可能です。
2行目は前投稿で投稿している内容ですので説明は省きます。
3行目はマップ上に設置されている物の名前を調べるスクリプトです。下記にスクリプト内容を書きます。
objectname.sqf_object_type = typeOf cursorTarget; hint format ["%1", _object_type]; copytoclipboard str(_object_type);
アクションメニューから選択した後、メモ帳にコピーできます。
※ミッションを公開する時はこれらは必ずコメントアウトしてください。
- Briefing作成
エディタ上でもDiaryは作成できますが、日本語を使用するのであれば圧倒的にこちらが簡単です。
最初は少し見づらいかもしれませんが慣れるまでの辛抱です。page10 = player createDiaryRecord ["Diary", ["アップデート情報", "H26.ww.ww<br />バランス調整<br />所持品修正<br /><br />H26.xx.xx<br />リリース<br />"]]; page9 = player createDiaryRecord ["Diary", ["CREDIT", "Special Thanks<br /><img image='images\logo.paa' width='128' height='128'/><br />TESTER<br /> <br />テストに参加していただいた方の名前でも <br /> <br /> <br /> Thank you for test!<br /><br />Go to " + (createDiaryLink ["Diary", page10, "アップデート情報"])]]; page8 = player createDiaryRecord ["Diary", ["RADIO PLAN", "COMMON FREQ 30.1<br />Alpha 1 FREQ 31.5<br />Alpha 2 FREQ 32.1 <br />Go to " + (createDiaryLink ["Diary", page9, "CREDIT"])]]; page7 = player createDiaryRecord ["Diary", ["SPECIFICATION", "AGM wounding system unconscious time : Unlimited<br />Only medics can use injection<br /> <br />Go to " + (createDiaryLink ["Diary", page8, "RADIO PLAN"])]]; page6 = player createDiaryRecord ["Diary", ["SUPPLY", "支給品。車両とか <br />Go to " + (createDiaryLink ["Diary", page7, "SPECIFICATION"])]]; page5 = player createDiaryRecord ["Diary", ["EXECUTION", "作戦のチームの実行内容 <br />Go to " + (createDiaryLink ["Diary", page6, "SUPPORT"])]]; page4 = player createDiaryRecord ["Diary", ["MISSION", "ミッション名とか <br />Got to " + (createDiaryLink ["Diary", page5, "EXECUTION"])]]; page3 = player createDiaryRecord ["Diary", ["SITUATION", "開始時刻、天候、民間人の有無等 <br />Go to " + (createDiaryLink ["Diary", page4, "MISSION"])]]; page2 = player createDiaryRecord ["Diary", ["BRIEFING", "ブリーフィング内容を記述。 <br />Go to " + (createDiaryLink ["Diary", page3, "SITUATION"])]]; page1 = player createDiaryRecord ["Diary", ["CONCEPT", "趣旨とかの説明をいれてください。<br />を使って改行ができます。 <br />Go to " + (createDiaryLink ["Diary", page2, "BRIEFING"])]];
ブリーフィング内に写真を挿入する場合は必ず画像の大きさは64の倍数でないと表示されません。
Arma2時代はどの大きさでも表示できてたんですけどね。。例:
<img image='images\logo.paa' width='128' height='128'/>
こうやると表示されます。
また画像は.jpgか専用ファイルの.paaです。
アルファチャンネルをどうしても使いたい方はアルファの状態でpngに変換しTexView2を使用し.paaに変換してください。- スクリプトの読み込み
私はinit.sqfでフィールド上に置いてある弾薬をカスタマイズする時が多いです。
例:if (isServer) then { {[_X] execVM "scripts\cargo_ammo.sqf";} FOREACH [CAR01,CAR02,CAR03,CAR04]; {[_X] execVM "scripts\cargo_repair.sqf";} FOREACH [REPAIR01,REPAIR02]; {[_X] execVM "scripts\cargo_Medical.sqf";} FOREACH [MEDICAL01]; {[_X] execVM "scripts\cargo_truck.sqf";} FOREACH [STRUCTURE04]; {[_X] execVM "scripts\ammo_box.sqf";} FOREACH [box01]; {[_X] execVM "scripts\base_ammobox.sqf";} FOREACH [box02]; [] execVM "scripts\tyers.sqf"; };
文頭にif(isServer)then{をつける事により、サーバー側のみの処理になります。
弾薬箱のスクリプトも公開しておきます。cargo_ammo.sqf
if (!isServer) exitWith {}; _box = _this select 0; clearWeaponCargoGlobal _box; clearMagazineCargoGlobal _box; clearBackpackCargoGlobal _box; clearItemCargoGlobal _box; _box addWeaponCargoGlobal ["STI_M136", 2]; _box addItemCargoGlobal ["B_IR_Grenade", 10]; _box addItemCargoGlobal ["AGM_M84", 10]; _box addItemCargoGlobal ["AGM_CableTie", 5]; _box addItemCargoGlobal ["RH_SFM952V", 2]; _box addItemCargoGlobal ["AGM_SpareBarrel", 2]; _box addItemCargoGlobal ["AGM_M26_Clacker", 5]; _box addMagazineCargoGlobal ["30Rnd_65x39_caseless_mag_Tracer", 30]; _box addMagazineCargoGlobal ["1Rnd_HE_Grenade_shell", 20]; _box addMagazineCargoGlobal ["150Rnd_762x51_Box_Tracer", 5]; _box addMagazineCargoGlobal ["SmokeShell", 10]; _box addMagazineCargoGlobal ["SmokeShellRed", 10]; _box addMagazineCargoGlobal ["SmokeShellGreen", 10]; _box addMagazineCargoGlobal ["HandGrenade", 20]; _box addMagazineCargoGlobal ["DemoCharge_Remote_Mag", 3]; _box addMagazineCargoGlobal ["AGM_HandFlare_White", 20]; _box addMagazineCargoGlobal ["AGM_HandFlare_Red", 10]; _box addMagazineCargoGlobal ["AGM_HandFlare_Green", 10]; _box addMagazineCargoGlobal ["AGM_HandFlare_Yellow", 10]; _box addItemCargoGlobal ["AGM_Bandage", 10]; _box addItemCargoGlobal ["AGM_Morphine", 5];
init.sqfで既にif(isServer)then{};の枠で回避していますが、
if (!isServer) exitWith {};
をつけておかないと、参加している全てのプレイヤーがこのスクリプトを読み込み、弾薬箱の中身がパーティー状態になってしまいますので必ず注意してください。そして、これでもつけてあげといてください。
//TRISERVER if (toLower name player == "trico") then { player addHeadgear "H_Cap_surfer" ; } ;
そして最後はおまじない
// EOF player globalChat format ["Mission Initialisation Complete. Press CONTINUE"]; finishMissionInit;
init.sqfが全て読み込まれると
「Mission Initialisation Complete. Press CONTINUE」と発言します。- Dedicated ServerとListen Server
init.sqfの中身は、どれをプレイヤーに読み込ませ、どれをサーバー側だけ読み込ませるか、が重要です。
プレイヤー側にある命令文を読み込ませてしまうと参加している人数分だけ何かが増殖したり、最悪サーバーがクラッシュする可能性もあります。また、エディット上ではうまく動作するが、Dedicated Serverでは動作しない場合も沢山あります。
この原因としてはエディット上ではListen Serverといって自分自身がDedicated Serverでは無いServerになっている。
プレイヤーでもあり、サーバーでもあるのでこの状態で動作してもDedicated Serverでの挙動は確証得られないですよね。
なので、本チャンでチャレンジするよりもまずは空いているDedicated Serverで一人若しくは数人でテストする事が必須です。それでも私はいつもミスしてるんですけどね・・・
- TIPS
各陣営でブリーフィングを分ける方法
switch (side player) do { case WEST: { Task1 = player createSimpleTask ["トリコさんを排除しましょう"]; Task1 setSimpleTaskDescription ["トリコさんを排除しましょう", "トリコさんを排除しましょう", "トリコさんを排除しましょう"]; player setCurrentTask task1; task1 setSimpleTaskDestination (getMarkerPos "task1"); }; case INDEPENDENT: { Task1 = player createSimpleTask ["トリコさんを排除しましょう"]; Task1 setSimpleTaskDescription ["トリコさんを排除しましょう", "トリコさんを排除しましょう", "トリコさんを排除しましょう"]; player setCurrentTask task1; task1 setSimpleTaskDestination (getMarkerPos "task1"); }; case EAST: { Task1 = player createSimpleTask ["トリコさんはやっぱり守りましょう"]; Task1 setSimpleTaskDescription ["トリコさんはやっぱり守りましょう", "トリコさんはやっぱり守りましょう", "トリコさんはやっぱり守りましょう"]; player setCurrentTask task1; task1 setSimpleTaskDestination (getMarkerPos "task1"); }; };
これで各陣営別にブリーフィングが作成できます。
Line参加者- ミッション製作お役立ちスクリプト
先人でもあり偉人でもあるStealer氏のScriptを自分なりに改良した物です。
下記コードの内容をテキストに張り付け名前をcopypos.sqfに変更し、mission.sqmのある階層に放り込み
init.sqf内にplayer addAction [“>Copy Position”,”copypos.sqf”];と入れるだけです。
ミッションをリリースする時は、必ず「//」コメントアウトするか削除してください。Copy Position Script
copypos.sqf
//player addAction [">Copy Position","copypos.sqf"]; _dir = getdir player; _stance = "NULL"; _canmove = "move"; _pos = getpos player; _posX = _pos select 0; _posY = _pos select 1; _posZ = _pos select 2; _posASL = getposASL player; _neck = player selectionPosition "Neck" select 2; if (_neck <= 0.45) then {_stance = "DOWN";}; if (_neck >= 0.8 && _neck <= 1.2) then {_stance = "MIDDLE";}; if (_neck >= 1.3) then {_stance = "UP";}; if (_stance == "NULL") then {hint "ERROR - Stance capture failed\nkeep your stance horizontality and try again"} else{ hint format ["Position > %1,\nDirection >\n%2\nStance > %3\n\n*Position data copied*",_posASL,_dir,_stance];}; copytoclipboard ("this setPosASL "+str _posASL+"; this setdir "+str _dir+"; this setunitpos "+str _stance+";this disableAI "+str _canmove+";");
getposで三次元座標をgetdirで向きを決め、
モデルの首の位置の高さを計測し、setunitposの値を決めています。
これで実際に歩いてユニットを置きたい場所に移動し、アクションメニューから選択したら裏画面に戻り、メモ帳にCtrl+Vをしてメモしていきましょう。
エディット画面に戻った時に、メモ帳に記録してあるコードをユニットのinitializationにメモ帳からCtrl+XしてCtrl+Vするだけでハッピー!Line参加者ミッション製作における注意点
偉そうに書いてるなと思われるかもしれませんが、これからミッションを作りたいという方向けの投稿です。
- 全体の流れ
ただ物を壊す、殲滅する、だけでは単調になりがちです。
それらのミッションはただ場所が違うだけでやることは一緒ですからね。
それ+αで何か調味料を加えてあげる事で1つのミッションが濃厚な物になります。
しかし長時間(大体1時間半以上)になるのは避けたいところです。工夫としては
メインタスク完了後に敵の増援が来る → 退却? or 撃破?
メインタスク遂行が不可能な状況にさせる → メインをキャンセルし新たなタスクが発生
市街地戦遂行中に何かを見つける → サブタスクが発生する(捕虜や、証拠品等)- 移動距離
徒歩移動の目安としては1km圏内、
車移動ならば3~5km圏内を目安として考えた方が良いです。
またプレイヤーさん達は車を大事にしたり、遠くに乗り捨てて移動をする傾向が強いので武装車両ならば人数構成をきちんと決めておかないと車両在りきでミッションを製作した場合アンバランスな状況になります。
ドライバー、ガンナーを予めチーム内に組み込んで置くと利用しやすいですね。- パワーバランス
味方が使える兵器は1つ入れることでバランスが崩壊したりします。
何かを追加するならば敵にも対抗できる何かを追加しなければなりません。
またHMGかGMGかでも全くバランスが異なります。両サイドに1つでもあると独壇場になる場合もあります。
また、航空兵器を登場させ、華やかな感じにしたい時もありますよね。
しかし、その航空兵器には恐ろしい武装があり味方で登場するとプレイヤーが暇になるか、FFが発生、敵に登場するとクチャクチャにされてプレイヤーが激怒したりします。
そういった場合は航空機の例:O_Heli_Attack_02_Fのロケットとミサイルを取り外します。
this removeMagazinesTurret ["38Rnd_80mm_rockets",[-1]]; this removeMagazinesTurret ["8Rnd_LG_scalpel",[-1]];
戦車の例:O_MBT_02_cannon_FのHE弾を取り外します。
this removeMagazinesTurret ["12Rnd_125mm_HE_T_Green",[0]]; this removeMagazinesTurret ["12Rnd_125mm_HEAT_T_Green",[0]];
こうする事により凶悪な兵器を使用させることはできなくなりました。
- 殲滅系ミッションの注意点
乗組員が初めから搭乗している車両やヘリは乗組員が居なくなった状態でも敵としてカウントされています。
これを破壊しないとタスクが完了しなかったりと不自然な事になってしまいますので解決策としてはEmptyで車両を配置し、エディター上で
this assignAsDriver tank01; this orderGetIn true;
若しくは
this moveinDriver tank01;
こうする事により乗組員が居なくなった状態でも敵として認識されることはなくなります。- 車両破壊系ミッションの注意点
最近RHS等で強固な乗り物が増え、ある一定以上の部分破壊を行わないと爆発しない等の問題があります。
こういった場合の対処法はタスク完了トリガーに
Condition欄
not (alive Tank01) or isNull (driver Tank01)
と表記し、派手に爆破をしたい場合は
On Act欄に
if (alive tank01) then {tank01 setDamage 1;};
こうする事により乗員が降車と同時に爆発が起きます。
車両の爆発を遅らせたい時は、トリガーのTimeoutの所に秒数を入れましょう。
MAX・MID・MINはそれぞれ何秒で実行するかの秒数を記入するところです。
MAX:30/MID:15/MIN:0
に設定した場合3通りのいずれかを選択します。間を取って20秒とかにはなりません。
またTimeoutとCountdownの説明を記入しておきます。Timeout:トリガー内に対象が存続している間は秒数が減って0になると発動。時間内にトリガー外に出ればリセット。
Countdown:トリガー内に侵入した時点でカウントが始まり、自動的に0になる。とりあえずここまで。
何か質問や指摘があればお気軽にどうぞ!
(暇なので会社PCから手書き投稿してるのでミスあるかも)- この返信は9年、 5ヶ月前にLineが編集しました。理由: フォントカラー使えなかった
Line参加者役立ちトリガーコンディション集
あまりこのスレが活性化されてないと思いましたので、私の知っている事を少しずつ綴りたいと思います。
これからエディットを始めてみたい方や、知らなかったという方は是非ご自分のミッションに取り入れてみてください。殲滅系
トリガーの範囲内の敵が居なくなるとOn Actでタスクを完了させたりとよくあるミッションのうちの1つですが、敵を細かい配置にしているとNot Presentのみでは中々完了できない事もあります。エディターの本意としては間延びさせたくはないですよね。
そこで次のトリガーを設定します。ActivateはAnybodyに設定し、Condition欄に
east countSide thislist <= 5
もしくはActivateをOpforに設定し
{Side _x == EAST} count thislist <=5
EASTにしてますが敵軍がBluforならWEST、敵軍がAAFの場合はINDEPENDENTと入力します。こうすることにより、敵の数が5人かそれ以下になった場合On Actが発動します。
5人以下に設定したい場合は
east countSide thislist < 5
=を外すだけでいいです。輸送系
トリガーと目標車両をグループで結ぶという手が大変楽なのですが、複雑になってくると線が邪魔です。また、何台も輸送しないといけない場合1つにまとめたくなりますよね。
そこで次のトリガーを設定します。ActivateはAnybodyに設定し、Condition欄に
{vehicle _x iskindof "I_Truck_02_ammo_F"} count thislist > 1
AAFの弾薬輸送車が2台トリガー内に入るとOn Actが発動する内容です。
またクラスネームを断定せずに車両が2台としたい場合は
{vehicle _x iskindof "LandVehicle"} count thislist > 1
航空機を設定したい場合
{vehicle _x iskindof "Air"} count thislist > 1
このように特定の車両のみならず、指定する物の幅を広げることもできます。
最近追加されたヘリアドオンでコンテナを輸送できるようになりましたが、そのコンテナを特定の場所まで運ぶと達成されるコンディションは
{(vehicle _x iskindof "B_Slingload_01_Ammo_F") and (getPos _x select 2 <= 5)} count thisList > 3
弾薬コンテナが4つトリガー内に入り、尚且つコンテナの高さが地上より5m以下になった場合発動する条件です。市民救出ミッションの場合は
市民にciv01,civ02,civ03とアレイを追加し
ActivationをAnybodyに設定
Civillian countSide thislist > 2
もしくは
{alive _x and (getPos _x select 2 <= 1.5) and _x in thislist} count [civ01,civ02,civ03] == {alive _x} count [civ01,civ02,civ03]
この構文はまずciv01,civ02,civ03が範囲内に入り、次に市民が地上より1.5m以下であること、そして市民が3名とも生存している事が条件です。
タスク失敗条件を別のトリガーに入れる
(!alive civ01) or (!alive civ02) or (!alive civ03)
市民にUnconsciousを追加したい場合は
対象市民のInitializationに
this setVariable ["AGM_AllowUnconscious", true];
を追記することにより即死を間逃れる可能性が高くなります。とりあえずここまでにしておきます。まだまだ沢山バリエーションがありますのでそれはまた後ほど投稿したいと思います。
質問や突っ込みがあればどうぞ!補足でcountという命令はミッション製作の上で重宝しますので覚えておくとミッション構成の幅が広がりますよ。
- この返信は9年、 5ヶ月前にLineが編集しました。理由: 構文説明追記
-
投稿者投稿