To use an English footballing analogy, there are obviously Premier League mission builders, who are writing great missions, often absolutely epic in scope, and who are often pushing scripting where No Man Has Gone Before. This mission is not for them, or for the good jobbing Championship mission builders.
But it might be of interest to mission builders in my league - possibly League One or Two, possibly Vauxhall Conference (Southern).
My squadron flew a coop-style ops mission (of course in our own dogfight server) last night, and most of the bells and whistles worked! In an effort to drag my fellow squadron mission builders out of the non-league rankings so they can gain a foothold in League Two, I thought I'd explain what I'd tried to do and how I did it. A couple of them thought others in the wider CloD world might be interested. Obviously, comments and suggestions and corrections (!!!) would be welcome. (Already I can think of several better ways of doing things, but anyway...)
The Mission was called BoB50. The idea behind the mission was that three squadrons would fly out from Croydon, Kenley and Biggin, engage a largish group of bombers over Maidstone, return to base, respawn and wait for a just-in-time scramble to fight off a low level Jabo attack. Normally as a squadron we'd do something like this as two short missions, but with triggers we found we could do it in one (aiming for that feeling of a chaotic return to base, only to be sent out tired and stressed to face the enemy again straight away.)
There was one main mission (BoB50.mis iteslf, with a script file and a briefing file), which had the spawning locations and airfields and the scenery. That's all it had, plus one trigger (made in the FMB/Edit/Script/"trigger" tab), called "pass_malling". This was tripped when the first red aircraft entered a circle based around Maidstone/West Malling airfield.
The "pass_malling" trigger launched sub-mission 1, which had the bombers and their waypoints and some more triggers. One trigger for each of the three formations launched three new submissions to spawn in snappers and their waypoints (I cut down on the numbers of escort - mistake!).
The "pass_malling" trigger also launched the smoke submission (submission 6) with a 240 second delay. So, 4 minutes after the first red aircraft arrived at West Malling, pillars of smoke at the three starting airfields started up, so they'd be good and ready when we got back to the Biggin/Kenley area. This was to try to simulate the airfields already having been hit, basically to add atmosphere and eye-candy. (Not to be underestimated in a coop mission!)
Sub-mission 1 had one more trigger, which I erroneously called "return_gatwick" (it should obviously have been "return_croydon". Ah well.). This was to be triggered when the first red aircraft returned to Croydon, and this launched the last submission (submission 2, I think) with the second 110 Jabo wave (after a 240 second delay). The idea was that four minutes after the 1st aircaft got back to Croydon (and presumably after players at the nearer airfields were already landing) the new wave would spawn in, together with the message to scramble, leaving a further three minutes' flying time for the wave to get to target.
So, the main mission had just the spawn points, the scenery and the trigger for the first submission, which had the bombers and triggers for everything else, more or less. But the main mission of course had the .cs script that made all the triggers from all the missions work.
Here's the text of the .cs script (the stuff after the onTrigger section is just a bog standard despawn script,):
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using maddox.game;
using maddox.game.world;
public class Mission : AMission
{
public override void OnBattleStarted()
{
base.OnBattleStarted();
MissionNumberListener = -1; // listen for events from this mission & all submissions
}
public override void OnTrigger(int missionNumber, string shortName, bool active)
{
base.OnTrigger(missionNumber, shortName, active);
if ("pass_malling".Equals(shortName) && active)
{
GamePlay.gpHUDLogCenter("The enemy formation is now east of Maidstone, heading roughly 270, Angels 10!");
GamePlay.gpPostMissionLoad("missions\\Multi\\Dogfight\\all_submissions\\BoB50\\BoB50_sub1.mis");
Timeout(240, () =>
{
GamePlay.gpPostMissionLoad("missions\\Multi\\Dogfight\\all_submissions\\BoB50\\BoB50_sub6.mis");
GamePlay.gpHUDLogCenter("Airfields already under attack: Eastchurch, Rochford, Detling, Biggin");
});
GamePlay.gpGetTrigger(shortName).Enable = false;
};
if ("escort_01".Equals(shortName) && active)
{
GamePlay.gpHUDLogCenter("No escort so far?");
GamePlay.gpPostMissionLoad("missions\\Multi\\Dogfight\\all_submissions\\BoB50\\BoB50_sub3.mis");
GamePlay.gpGetTrigger(shortName).Enable = false;
};
if ("escort_02".Equals(shortName) && active)
{
//GamePlay.gpHUDLogCenter("Bugger! Escort! sub4");
GamePlay.gpPostMissionLoad("missions\\Multi\\Dogfight\\all_submissions\\BoB50\\BoB50_sub4.mis");
GamePlay.gpGetTrigger(shortName).Enable = false;
};
if ("escort_03".Equals(shortName) && active)
{
//GamePlay.gpHUDLogCenter("Bugger! Escort! sub5");
GamePlay.gpPostMissionLoad("missions\\Multi\\Dogfight\\all_submissions\\BoB50\\BoB50_sub5.mis");
GamePlay.gpGetTrigger(shortName).Enable = false;
};
if ("return_gatwick".Equals(shortName) && active)
{
GamePlay.gpHUDLogCenter("Spitfire returns to Croydon");
Timeout(240, () =>
{
GamePlay.gpPostMissionLoad("missions\\Multi\\Dogfight\\all_submissions\\BoB50\\BoB50_sub2.mis");
GamePlay.gpHUDLogCenter("SCRAMBLE! Incoming now! 3 or 4 minutes out to the south! Don't just sit there!...");
});
GamePlay.gpGetTrigger(shortName).Enable = false;
};
}
private bool isAiControlledPlane(AiAircraft aircraft)
{
if (aircraft == null)
{
return false;
}
Player[] players = GamePlay.gpRemotePlayers();
foreach (Player p in players)
{
if (p != null && (p.Place() is AiAircraft) && (p.Place() as AiAircraft) == aircraft)
{
return false;
}
}
return true;
}
public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceLeave(player, actor, placeIndex);
Timeout(1, () =>
{ damageAiControlledPlane(actor); }
);
}
private void damageAiControlledPlane(AiActor actor)
{
if (actor == null || !(actor is AiAircraft))
{
return;
}
AiAircraft aircraft = (actor as AiAircraft);
if (!isAiControlledPlane(aircraft))
{
return;
}
if (aircraft == null)
{
return;
}
aircraft.hitNamed(part.NamedDamageTypes.ControlsElevatorDisabled);
aircraft.hitNamed(part.NamedDamageTypes.ControlsAileronsDisabled);
aircraft.hitNamed(part.NamedDamageTypes.ControlsRudderDisabled);
aircraft.hitNamed(part.NamedDamageTypes.FuelPumpFailure);
aircraft.hitNamed(part.NamedDamageTypes.Eng0TotalFailure);
aircraft.hitNamed(part.NamedDamageTypes.Eng1TotalFailure);
Timeout(2, () =>
{ destroyPlane(aircraft); }
);
}
private void destroyPlane(AiAircraft aircraft)
{
if (aircraft != null)
{
aircraft.Destroy();
}
}
}
For people like me who are baffled by things like this, I've tried to explain a few lines (and lots of stuff is wrong or missing, but honestly, I'm not a programmer and don't understand the hows or the whys, and I wish I could add more detailed explanations):
script.jpg
To reiterate, the punctuation in scripts (all the semi-colons and the brackets - ah the brackets!!!) are all crucial. I don't trust myself to get it right, so I cut and paste (and gingerly edit) lines others have written.
Anyway, if people want to have a fiddle, the mission (and its submissions) can be downloaded here: https://app.box.com/s/vcqh6u2lf49hgthhzhg6.
Unzip it into your 1C SoftClub...il2-Mod...missions/Multi/Dogfight folder. The .mis & .cs & .briefing files will be in the Dogfight folder as per normal. You'll find the submissions in the .../all_submissions/BoB50 folder. (Of course, the file structure can be changed to anything you want (more or less), but then you'll have to edit the script, so it can find the right files.)
Hope this helps any non-league mission builders dreaming of one day reaching top flight excellence!
Edit: a couple of extra things...
The main advantage in using submissions is that each submission can have its own triggers. This really increases the scope and complexity of what you can do in a mission. Funnily enough, though, the map for most of these submissions is - of course -very empty, just the waypoints (or objects - or even just another set of triggers!) for a group or two of aircraft!
(One way to do sub-missions with various groups of aircraft meeting and interacting is to compile all the flights as normal on a master map and then cut and paste the aircraft group and waypoint information (i.e. the text) from the master .mis file into a new but empty .mis file. Easy, after you've looked at the text of a few .mis files.)
(By the way, the smoke submission was a bit tricky to do because I had to paste the static and buildings sections - from the main mission's .mis file - into a new mission, add the smoke and then go back to the text of that new .mis file and delete the scenery again. Luckily Notepad++ has a very handy find/replace function, so it was in the end a piece of peess.)
Bookmarks