View Full Version : how to trigger the big yellow messages?
David198502
06-19-2012, 01:46 PM
i have a training mission, where both sides have a restricted plane amount for their spawn areas(20 planes).
now i want that if one of both spawn areas has only 10 planes left, that a message pops up, warning the team just like "team red only 10 planes left"(although i would like to have this message visible for everybody)
and i want another message to pop up, when eventually one spawn area has all available plane used and when all planes of one side are destroyed just like "team blue has lost the war"
Edit: ok i just found out, that the limit of planes of a spawn area doesnt seem to work...
i restricted one spawn area to only 1 plane, but i could spawn several times from the same area without problems:confused:
FG28_Kodiak
06-19-2012, 03:28 PM
The number of planes is for how many planes a player can create at the same time.
David198502
06-19-2012, 03:59 PM
ah ok....is it then possible, to give a spawnerea a certain amount of planes?
FG28_Kodiak
06-19-2012, 04:10 PM
äh yes you can destroy it. So it vanished from Map. Or destroy the new created planes instantly or block the planes via Player.PlaceLeave.
David198502
06-19-2012, 04:39 PM
äh yes you can destroy it. So it vanished from Map. Or destroy the new created planes instantly or block the planes via Player.PlaceLeave.
thx Kodiak for your answer....but unfortunately i am way too stupid regarding scripting to make any use of this by myself, as you probably already noticed a while ago...
vanishing from the map, would be a fancy solution for this i think, coupled with a message that the opposite team won. but i guesss i would need your help for that...
Edit:
i would like to have this function included in my already excisting script:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using maddox.game;
using maddox.game.world;
public class Mission : AMission
{
Stopwatch MissionTimer = new Stopwatch();
public override void OnBattleStarted()
{
base.OnBattleStarted();
MissionTimer.Start();
MissionNumberListener = -1;
}
public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
{
base.OnActorCreated(missionNumber, shortName, actor);
if (actor is AiAircraft)
{
switch ((actor as AiAircraft).InternalTypeName())
{
case "bob:Aircraft.He-111P-2":
case "bob:Aircraft.BlenheimMkIV":
Timeout(3000, () => // Time in Seconds
{
(actor as AiAircraft).Destroy();
});
break;
}
}
}
public override void OnAircraftCrashLanded(int missionNumber, string shortName, AiAircraft aircraft)
{
base.OnAircraftCrashLanded(missionNumber, shortName, aircraft);
if(IsActorDestroyable(aircraft))
aircraft.Destroy();
}
public override void OnAircraftLanded(int missionNumber, string shortName, AiAircraft aircraft)
{
base.OnAircraftLanded(missionNumber, shortName, aircraft);
if (IsActorDestroyable(aircraft))
aircraft.Destroy();
}
private bool IsActorDestroyable(AiActor actor)
{
bool actorDestroyable = true;
//Check if actor is empty (no Player)
if (actor is AiAircraft)
{
if ((actor as AiAircraft).ExistCabin(0))
for (int i = 0; i < (actor as AiAircraft).Places(); i++)
{
if ((actor as AiAircraft).Player(i) != null)
{
actorDestroyable = false;
break;
}
}
}
else if (actor is AiGroundActor)
{
if ((actor as AiGroundActor).ExistCabin(0))
for (int i = 0; i < (actor as AiGroundActor).Places(); i++)
{
if ((actor as AiGroundActor).Player(i) != null)
{
actorDestroyable = false;
break;
}
}
}
return actorDestroyable;
}
// to remove GroundActors after their Task is completed
public override void OnActorTaskCompleted(int missionNumber, string shortName, AiActor actor)
{
base.OnActorTaskCompleted(missionNumber, shortName, actor);
if (actor is AiGroundActor)
if (IsActorDestroyable(actor))
(actor as AiGroundActor).Destroy();
}
public int GetSumAllPlanes()
{
int planeCount = 0;
List<AiAirGroup> allAirgroups = new List<AiAirGroup>();
if (GamePlay.gpAirGroups(1) != null)
allAirgroups.AddRange(GamePlay.gpAirGroups(1));
if (GamePlay.gpAirGroups(2) != null)
allAirgroups.AddRange(GamePlay.gpAirGroups(2));
allAirgroups.ForEach(item =>
{
foreach (AiAircraft ac in item.GetItems())
{
planeCount++;
}
});
return planeCount;
}
public override void OnTickGame()
{
if(MissionTimer.Elapsed.TotalSeconds >= 130 && GetSumAllPlanes() < 30) //Loads a mission every 130s and only if the sum of all planes < 30
{
Random ZufaelligeMission = new Random();
MissionTimer.Restart(); // Sets timer to 0 and start again
switch (ZufaelligeMission.Next(34,35))
{
case 1:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission1.mis");
break;
case 2:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission2.mis");
break;
case 3:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission3.mis");
break;
case 4:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission4.mis");
break;
case 5:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission5.mis");
break;
case 6:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission6.mis");
break;
case 7:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission7.mis");
break;
case 8:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission8.mis");
break;
case 9:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission9.mis");
break;
case 10:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission10.mis");
break;
case 11:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission11.mis");
break;
case 12:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission12.mis");
break;
case 13:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission13.mis");
break;
case 14:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission14.mis");
break;
case 15:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission15.mis");
break;
case 16:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission16.mis");
break;
case 17:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission17.mis");
break;
case 18:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission18.mis");
break;
case 19:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission19.mis");
break;
case 20:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission20.mis");
break;
case 21:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission21.mis");
break;
case 22:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission22.mis");
break;
case 23:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission23.mis");
break;
case 24:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission24.mis");
break;
case 25:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission25.mis");
break;
case 26:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission26.mis");
break;
case 27:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission27.mis");
break;
case 28:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission28.mis");
break;
case 29:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission29.mis");
break;
case 30:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission30.mis");
break;
case 31:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission31.mis");
break;
case 32:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission32.mis");
break;
case 33:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission33.mis");
break;
case 34:
GamePlay.gpPostMissionLoad("missions\\Blitzkrieg\\mission34.mis");
break;
}
}
}
}
and maybe with the function included, that after one side has shot down a certain amount of AI planes(bombers), no bombers will spawn anymore....
i know i somehow ask for much, and if its sounding demanding in a way, i apologize, i can fully understand if you have better things to do
FG28_Kodiak
06-20-2012, 11:05 AM
Hm saw your edit to late, so i created a mission (in attachment) without your new wishes.
Next time you should create a new post, so i see if there is anything new. :(
David198502
06-20-2012, 11:39 AM
no worries Kodiak....
yeah i was just posting, when it came to my mind, that i should probably include all my wishes into one post, to save you workload,....unfortunately its now the other way round.sorry.
but i will have a look at your mission now...maybe its enough for my squad training mission anyway...
David198502
06-21-2012, 08:12 AM
hey Kodiak, i tried your script, and it seems to work...
i put it into my mission, and adjusted the names of the spawnareas in the script, as well as the messages which pop up.everything works like a treat, even with more waypoints on one side!
thank you very much, i think for now, this is perfect for my use....although if you have spare time and if you are in the mood, then i would really appreciate, if you could inlcude all my wishes from my above post,.....one day.
Edit: now that i have my big yellow messages, i wonder how it is possible, to change the server messages....
i saw on some servers, that the normal messages like "AI SpitfireIa has been destroyed by...."(the small white ones, which appear if you killed someone or get killed) were adjusted..i dont know anymore on which server i saw this, but there the server was stating something like "...JG26_DavidRed kicked Ki SpitfireIa in the ass...."
i will probably not use this phrase, but i think something more funny could be added than the default phrase...
David198502
06-21-2012, 10:51 AM
thx Kodiak again for your limitbirthplace script...works great even with more spawnpoints on one side...
the only thing now is, that if i have more than one spawnpoint on one side, then the message, warining that only 5planes are left on the one side, is dependent on each spawnpoint, and not on the total number of planes available on one side....
i would like to keep the messages, warning that one spawnpoint has only x planes left, but would like to have the message included, warning the team, if the total number of available planes is left to 5....
FG28_Kodiak
06-21-2012, 11:30 AM
Change OnPlaceEnter to:
public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceEnter(player, actor, placeIndex);
AiBirthPlace birthPlace = GetBirthplace(actor);
AiCart cart = actor as AiCart;
if(cart != null)
AvailablePlanes.ForEach(place =>
{
if (place.BirthPlace == birthPlace.Name())
{
place.NumberOfPlanes--;
int numberOfAllAvailablePlanes = CountAvailablePlanes(actor.Army());
if (numberOfAllAvailablePlanes == 5)
{
if(actor.Army() == 1)
GamePlay.gpHUDLogCenter(null, "Attention Reds only {0} Planes are left", new object[] { numberOfAllAvailablePlanes });
if(actor.Army() == 2)
GamePlay.gpHUDLogCenter(null, "Attention Blues only {0} Planes are left", new object[] { numberOfAllAvailablePlanes });
}
if (place.NumberOfPlanes == 0)
{
GamePlay.gpHUDLogCenter(null, "Attention {0} is no longer available", new object[]{place.BirthPlace});
birthPlace.destroy();
}
}
});
}
Edith: Hatte die Seite bei der Meldung nicht berücksichtig.
David198502
06-21-2012, 12:10 PM
ah ok....werds gleich ausprobieren!
FG28_Kodiak
06-21-2012, 12:19 PM
Hm forgotten i am on an english speaking forum :rolleyes:
David198502
06-21-2012, 12:28 PM
mhh me as well:grin:
ok this works, but then the message, warning that only x planes are left for a certain spawnpoint is gone....so i added this, assuming that i can get both messages to pop up, the one warning that a spawnpoint is short on planes, and the one warning the team that it has only 5planes left in total...but this seems to not work...the message warning the team that only 5planes in total are left, is not popping up...unfortunately...i almost thought, that at least once i could sort a problem out for myself:(
public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceEnter(player, actor, placeIndex);
AiBirthPlace birthPlace = GetBirthplace(actor);
AiCart cart = actor as AiCart;
if(cart != null)
AvailablePlanes.ForEach(place =>
{
if (place.BirthPlace == birthPlace.Name())
{
place.NumberOfPlanes--;
int numberOfAllAvailablePlanes = CountAvailablePlanes(actor.Army());
if (numberOfAllAvailablePlanes == 5)
{
if(actor.Army() == 1)
GamePlay.gpHUDLogCenter(null, "Attention Reds only {0} Planes are left", new object[] { numberOfAllAvailablePlanes });
if(actor.Army() == 2)
GamePlay.gpHUDLogCenter(null, "Attention Blues only {0} Planes are left", new object[] { numberOfAllAvailablePlanes });
}
if (place.NumberOfPlanes == 3 )
{
GamePlay.gpHUDLogCenter(null, "Attention only {0} Planes are left on {1}", new object[] { place.NumberOfPlanes, place.BirthPlace });
}
if (place.NumberOfPlanes == 0)
{
GamePlay.gpHUDLogCenter(null, "Attention {0} is no longer available", new object[]{place.BirthPlace});
birthPlace.destroy();
}
}
});
}
David198502
06-21-2012, 12:33 PM
oh and one more thing....is it possible, that if a plane lands safely on a homebase that this plane will "get back" into the list(pool) of available planes?so that the the number of available planes for that spawnpoint(where the plane startet from) will not decrease in numbers, when the plane manage to make it back to a friendly airfield...?
or in other words, if a plane manages to make it back home safely, that "this" plane can be used again
FG28_Kodiak
06-21-2012, 12:43 PM
the message warning the team that only 5planes in total are left, is not popping up...unfortunately...i almost thought, that at least once i could sort a problem out for myself:(
its 'popping up' but its overridden by the next message so you only see the last, to avoid this you can use Timeout
Example:
GamePlay.gpHUDLogCenter(null, "First", null);
Timeout(5, () => {
GamePlay.gpHUDLogCenter(null, "Second", null);
});
oh and one more thing....is it possible, that if a plane lands safely on a homebase that this plane will "get back" into the list(pool) of available planes?so that the the number of available planes for that spawnpoint(where the plane startet from) will not decrease in numbers, when the plane manage to make it back to a friendly airfield...?
or in other words, if a plane manages to make it back home safely, that "this" plane can be used again
Yes its possible but the code then needs some rework.
David198502
06-21-2012, 12:55 PM
its 'popping up' but its overridden by the next message so you only see the last, to avoid this you can use Timeout
Example:
GamePlay.gpHUDLogCenter(null, "First", null);
Timeout(5, () => {
GamePlay.gpHUDLogCenter(null, "Second", null);
});
Yes its possible but the code then needs some rework.
i would really appreciate, if you could do that, if its not too much rework....
David198502
06-21-2012, 01:20 PM
ok tested again, with different numbers of available planes for each spawnpoint, and you are correct, its indeed showing the message that only 5planes are available....so this is good enough for me for now, as i have no glue again how and where to implement the Timeout section, without messing up the whole script....
but thinking again about the possibility, that if planes come back to base, are included again in the pool of the spawnpoint, is really attracting me...again, if you could write that for me, i would be REALLY REALLY HAPPY(maybe with the timeout section included already)
one thing that came to my mind, is that one has to be careful with the messages then, as now, the script gives out a message, as one spawns in a plane...if the feature of returning planes is included, the messages should pop up, when a plane gets destroyed, as otherwise, the warnings/messages could be wrong.......but who i am telling this....if you really decide to write such a script for me, you are certainly aware of that...
again and again and again Kodiak, during the last months, i had sooo much fun, because of your scripts you wrote for me....a BIG THANK YOU
PS:if that all is possible, i really wonder, why this havent been included on servers such like atag already???...in my view, this is a great way of having a dynamic war....besides, with the script i already have, one could for example get rid of the "self destroying" E4s on atag, which suddenly after a few seconds lose their ailerons and elevators on ground, while you are still able to spawn in them....???
FG28_Kodiak
06-21-2012, 01:29 PM
in your code change:
if (numberOfAllAvailablePlanes == 5)
{
if(actor.Army() == 1)
GamePlay.gpHUDLogCenter(null, "Attention Reds only {0} Planes are left", new object[] { numberOfAllAvailablePlanes });
if(actor.Army() == 2)
GamePlay.gpHUDLogCenter(null, "Attention Blues only {0} Planes are left", new object[] { numberOfAllAvailablePlanes });
}
if (place.NumberOfPlanes == 5 )
{
Timeout(5, () => {
GamePlay.gpHUDLogCenter(null, "Attention only {0} Planes are left on {1}", new object[] { place.NumberOfPlanes, place.BirthPlace });
});
}
David198502
06-21-2012, 02:24 PM
doesnt seem to work for me....all the messages are gone(also available/in use -messages)
and i seem to be able to respawn infinitely...
FG28_Kodiak
06-21-2012, 02:31 PM
then there must be a error in code can you show me your changes, may be there is a missing ";" or something else.
David198502
06-21-2012, 02:42 PM
here is the complete code:
using System;
using System.Collections;
using System.Collections.Generic;
using maddox.GP;
using maddox.game;
using maddox.game.world;
using part;
public class Mission : AMission
{
private bool battleEnded = false;
class BirthPlacePlanes
{
public string BirthPlace { get; set; }
public int NumberOfPlanes { get; set; }
public BirthPlacePlanes(string birthPlaceName, int maxNumber)
{
BirthPlace = birthPlaceName;
NumberOfPlanes = maxNumber;
}
}
List<BirthPlacePlanes> AvailablePlanes = new List<BirthPlacePlanes>
{
new BirthPlacePlanes("RAF-5k", 10),
new BirthPlacePlanes("RAF-3k", 10),
new BirthPlacePlanes("RAF-500m", 10),
new BirthPlacePlanes("JG26-5k", 1),
new BirthPlacePlanes("JG26-3k", 1),
new BirthPlacePlanes("JG26-500m", 5)
};
public bool IsActorDown(AiActor actor)
{
AiAircraft aircraft = actor as AiAircraft;
if (aircraft != null && (aircraft.getParameter(ParameterTypes.Z_AltitudeAG L, -1) <= 2.0
&& aircraft.getParameter(ParameterTypes.Z_VelocityTAS , -1) <= 1.0))
return true;
return false;
}
public int CountPlayerUsedPlanes(int army)
{
int count = 0;
foreach (Player pl in AllPlayers())
{
if (pl.Place() != null && pl.Army() == army && pl.PlacePrimary() == 0)
count++;
}
return count;
}
public int CountAvailablePlanes(int army)
{
int count = 0;
foreach (BirthPlacePlanes bpp in AvailablePlanes)
{
AiBirthPlace birthPlace = GetBirthPlaceByName(bpp.BirthPlace);
if (birthPlace != null)
if (birthPlace.Army() == army)
count += bpp.NumberOfPlanes;
}
return count;
}
public AiBirthPlace GetBirthPlaceByName(string birthPlaceName)
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
{
if (bp.Name() == birthPlaceName)
return bp;
}
return null;
}
public AiBirthPlace GetBirthplace(AiActor actor)
{
AiBirthPlace nearestBirthplace = null;
AiBirthPlace[] birthPlaces = GamePlay.gpBirthPlaces();
Point3d pos = actor.Pos();
if (birthPlaces != null)
{
foreach (AiBirthPlace airport in birthPlaces)
{
if (nearestBirthplace != null)
{
if (nearestBirthplace.Pos().distance(ref pos) > airport.Pos().distance(ref pos))
nearestBirthplace = airport;
}
else nearestBirthplace = airport;
}
}
return nearestBirthplace;
}
public override void OnBattleStarted()
{
base.OnBattleStarted();
MissionNumberListener = -1;
}
public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceEnter(player, actor, placeIndex);
AiBirthPlace birthPlace = GetBirthplace(actor);
AiCart cart = actor as AiCart;
if(cart != null)
AvailablePlanes.ForEach(place =>
{
if (place.BirthPlace == birthPlace.Name())
{
place.NumberOfPlanes--;
int numberOfAllAvailablePlanes = CountAvailablePlanes(actor.Army());
if (numberOfAllAvailablePlanes == 5)
{
if(actor.Army() == 1)
GamePlay.gpHUDLogCenter(null, "Attention Reds only {0} Planes are left", new object[] { numberOfAllAvailablePlanes });
if(actor.Army() == 2)
GamePlay.gpHUDLogCenter(null, "Attention Blues only {0} Planes are left", new object[] { numberOfAllAvailablePlanes });
}
if (place.NumberOfPlanes == 3 )
{
Timeout(5, () => {
GamePlay.gpHUDLogCenter(null, "Attention only {0} Planes are left on {1}", new object[] { place.NumberOfPlanes, place.BirthPlace });
}
if (place.NumberOfPlanes == 0)
{
GamePlay.gpHUDLogCenter(null, "Attention {0} is no longer available", new object[]{place.BirthPlace});
birthPlace.destroy();
}
}
});
}
public List<Player> AllPlayers()
{
List<Player> allPlayers = new List<Player>();
if(GamePlay.gpPlayer() != null)
allPlayers.Add(GamePlay.gpPlayer());
if(GamePlay.gpRemotePlayers() != null)
allPlayers.AddRange(GamePlay.gpRemotePlayers());
return allPlayers;
}
public override void OnTickGame()
{
base.OnTickGame();
if (Time.tickCounter() % 300 == 0)
{
// check if Player is grounded
AllPlayers().ForEach(item =>
{
if (item.Place() != null)
if (IsActorDown(item.Place()))
{
AiCart cart = item.Place() as AiCart;
if (cart != null) cart.Destroy();
}
});
//TestMessages remove if no longer needed
GamePlay.gpLogServer(null, "Army: RED, Available: {0}, In Use: {1}", new object[] { CountAvailablePlanes(1), CountPlayerUsedPlanes(1) });
GamePlay.gpLogServer(null, "Army: BLUE, Available: {0}, In Use: {1}", new object[] { CountAvailablePlanes(2), CountPlayerUsedPlanes(2) });
}
}
public override void OnActorDestroyed(int missionNumber, string shortName, AiActor actor)
{
base.OnActorDestroyed(missionNumber, shortName, actor);
AiCart cart = actor as AiCart;
if (cart != null)
{
if (actor.Army() == 1 && CountAvailablePlanes(1) == 0 && CountPlayerUsedPlanes(1) == 0 && !battleEnded)
{
battleEnded = true;
GamePlay.gpHUDLogCenter(null, "JG26 kicked your butts");
}
else if (actor.Army() == 2 && CountAvailablePlanes(2) == 0 && CountPlayerUsedPlanes(2) == 0 && !battleEnded)
{
battleEnded = true;
GamePlay.gpHUDLogCenter(null, "Micky Mouse Team won");
}
}
}
}
FG28_Kodiak
06-21-2012, 03:29 PM
Ok some bracket mismatch, corrected version:
using System;
using System.Collections;
using System.Collections.Generic;
using maddox.GP;
using maddox.game;
using maddox.game.world;
using part;
public class Mission : AMission
{
private bool battleEnded = false;
class BirthPlacePlanes
{
public string BirthPlace { get; set; }
public int NumberOfPlanes { get; set; }
public BirthPlacePlanes(string birthPlaceName, int maxNumber)
{
BirthPlace = birthPlaceName;
NumberOfPlanes = maxNumber;
}
}
List<BirthPlacePlanes> AvailablePlanes = new List<BirthPlacePlanes>
{
new BirthPlacePlanes("RAF-5k", 10),
new BirthPlacePlanes("RAF-3k", 10),
new BirthPlacePlanes("RAF-500m", 10),
new BirthPlacePlanes("JG26-5k", 1),
new BirthPlacePlanes("JG26-3k", 1),
new BirthPlacePlanes("JG26-500m", 5)
};
public bool IsActorDown(AiActor actor)
{
AiAircraft aircraft = actor as AiAircraft;
if (aircraft != null && (aircraft.getParameter(ParameterTypes.Z_AltitudeAG L, -1) <= 2.0
&& aircraft.getParameter(ParameterTypes.Z_VelocityTAS , -1) <= 1.0))
return true;
return false;
}
public int CountPlayerUsedPlanes(int army)
{
int count = 0;
foreach (Player pl in AllPlayers())
{
if (pl.Place() != null && pl.Army() == army && pl.PlacePrimary() == 0)
count++;
}
return count;
}
public int CountAvailablePlanes(int army)
{
int count = 0;
foreach (BirthPlacePlanes bpp in AvailablePlanes)
{
AiBirthPlace birthPlace = GetBirthPlaceByName(bpp.BirthPlace);
if (birthPlace != null)
if (birthPlace.Army() == army)
count += bpp.NumberOfPlanes;
}
return count;
}
public AiBirthPlace GetBirthPlaceByName(string birthPlaceName)
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
{
if (bp.Name() == birthPlaceName)
return bp;
}
return null;
}
public AiBirthPlace GetBirthplace(AiActor actor)
{
AiBirthPlace nearestBirthplace = null;
AiBirthPlace[] birthPlaces = GamePlay.gpBirthPlaces();
Point3d pos = actor.Pos();
if (birthPlaces != null)
{
foreach (AiBirthPlace airport in birthPlaces)
{
if (nearestBirthplace != null)
{
if (nearestBirthplace.Pos().distance(ref pos) > airport.Pos().distance(ref pos))
nearestBirthplace = airport;
}
else nearestBirthplace = airport;
}
}
return nearestBirthplace;
}
public override void OnBattleStarted()
{
base.OnBattleStarted();
MissionNumberListener = -1;
}
public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceEnter(player, actor, placeIndex);
AiBirthPlace birthPlace = GetBirthplace(actor);
AiCart cart = actor as AiCart;
if (cart != null)
AvailablePlanes.ForEach(place =>
{
if (place.BirthPlace == birthPlace.Name())
{
place.NumberOfPlanes--;
int numberOfAllAvailablePlanes = CountAvailablePlanes(actor.Army());
if (numberOfAllAvailablePlanes == 5)
{
if (actor.Army() == 1)
GamePlay.gpHUDLogCenter(null, "Attention Reds only {0} Planes are left", new object[] {numberOfAllAvailablePlanes});
if (actor.Army() == 2)
GamePlay.gpHUDLogCenter(null, "Attention Blues only {0} Planes are left", new object[] {numberOfAllAvailablePlanes});
}
if (place.NumberOfPlanes == 3)
{
Timeout(5, () =>{
GamePlay.gpHUDLogCenter(null, "Attention only {0} Planes are left on {1}", new object[] { place.NumberOfPlanes, place.BirthPlace});
});
}
if (place.NumberOfPlanes == 0)
{
GamePlay.gpHUDLogCenter(null, "Attention {0} is no longer available", new object[] {place.BirthPlace});
birthPlace.destroy();
}
}
});
}
public List<Player> AllPlayers()
{
List<Player> allPlayers = new List<Player>();
if(GamePlay.gpPlayer() != null)
allPlayers.Add(GamePlay.gpPlayer());
if(GamePlay.gpRemotePlayers() != null)
allPlayers.AddRange(GamePlay.gpRemotePlayers());
return allPlayers;
}
public override void OnTickGame()
{
base.OnTickGame();
if (Time.tickCounter() % 300 == 0)
{
// check if Player is grounded
AllPlayers().ForEach(item =>
{
if (item.Place() != null)
if (IsActorDown(item.Place()))
{
AiCart cart = item.Place() as AiCart;
if (cart != null) cart.Destroy();
}
});
//TestMessages remove if no longer needed
GamePlay.gpLogServer(null, "Army: RED, Available: {0}, In Use: {1}", new object[] { CountAvailablePlanes(1), CountPlayerUsedPlanes(1) });
GamePlay.gpLogServer(null, "Army: BLUE, Available: {0}, In Use: {1}", new object[] { CountAvailablePlanes(2), CountPlayerUsedPlanes(2) });
}
}
public override void OnActorDestroyed(int missionNumber, string shortName, AiActor actor)
{
base.OnActorDestroyed(missionNumber, shortName, actor);
AiCart cart = actor as AiCart;
if (cart != null)
{
if (actor.Army() == 1 && CountAvailablePlanes(1) == 0 && CountPlayerUsedPlanes(1) == 0 && !battleEnded)
{
battleEnded = true;
GamePlay.gpHUDLogCenter(null, "JG26 kicked your butts");
}
else if (actor.Army() == 2 && CountAvailablePlanes(2) == 0 && CountPlayerUsedPlanes(2) == 0 && !battleEnded)
{
battleEnded = true;
GamePlay.gpHUDLogCenter(null, "Micky Mouse Team won");
}
}
}
}
David198502
06-21-2012, 04:01 PM
this works now:grin:
ok great,....now last question,...are you willing to write such a script for me, which includes the homecoming planes in the script???
i know im probably a bit annoying, with constantly asking for new things, but my main problem with all the scripts is, that i dont have a clue whats possible and not...then i ask if something is possible, and if the answer is yes, then im really excited, and want to try out the script....and most of the time, while trying such new scripts, improvements or other possibilities come to my mind...then i ask again if its possible and so on...
anyway thx for that script i already have.
David198502
06-21-2012, 04:09 PM
oh before i forget it, if you really write it, please include, that planes who land back safely, will get despawned after the player leaves the plane...thx in advance
FG28_Kodiak
06-21-2012, 06:01 PM
To despawn the plane after grounding, was simple for this people who crashed and then sit a half an hour in their planes and waiting. So they must select a new plane. :rolleyes: But it's no problem to despawn a plane after correct landing after Pilot leaves plane.
David198502
06-21-2012, 06:05 PM
yeah thats what i mean :)
if a player would come back to the home airfield, and lands safely, then leaves the plane, the plane should despawn, but the script should then know that it "puts that plane back into the spawnpoint"
that would be a great script for my purpose
FG28_Kodiak
06-24-2012, 07:36 AM
So enhanced Version, Planes landing on their HomeBases are returned into the "Pool". If no plane is available on the Base the SpawnPlace will be removed, and recreated if a plane returns into the pool.
Planes that are landed or crashlanded are "force"-removed after 60 sec. You can change the Time (in seconds) in
ActorObservation.ForceActorDestroyNotPosChangeAfte r(60);
or if you dont like it remove the line.
If you use SpawnPlaces with Airstart, place it over an existing Airstrip, if a Plane lands on this strip, it returns into the pool.
You can use more than one planetype on a Birthplace, but there is only one counter per Birthplace at the moment, so the script does not differ the types.
Maybe i add this feature in the future, also thinking about a transfer feature.
Script:
http://forum.1cpublishing.eu/showpost.php?p=438212&postcount=40
David198502
06-24-2012, 08:01 AM
thank you sooo much Kodiak!!!
will try that out immediately after i got my morning coffee....
what do you mean with "...the script does not differ the types.."?
would it be theoretically possible, that one airfield/spawnarea has a certain amount of different planetypes?for example 20E1s and 10E4s?is that what you mean with not differing in planetypes?
FG28_Kodiak
06-24-2012, 08:41 AM
for example 20E1s and 10E4s?is that what you mean..
Yes thats what i mean ;), it should be possible.
David198502
06-24-2012, 08:44 AM
ah ok,thats a neat possibility....and the transfer feature is probably, that if a plane spawns at one airfield, but lands at a different one, that it than will be transfered to the other "plane pool"...i guess.
those two features would be great!....but no worries,...im more than happy with the current script.but if you decide to add those features, please let me know...
i will try it out now, and report back...
FG28_Kodiak
06-24-2012, 08:53 AM
BTW I made the script - it's your part to test it ;)
David198502
06-24-2012, 09:45 AM
i will take that duty with joy!
testing it now-report will follow soon:grin:
David198502
06-24-2012, 12:11 PM
well Kodiak...this works perfect from what i have tested so far!great work.thank you!
David198502
06-25-2012, 07:25 AM
ok Kodiak, as already mentioned, the script works perfect!
after a few tests on my own, some of my squad members tried a mission with this script.
it was great fun, and everything works....
but i have seen one minor thing, which is distracting a bit....if one bails out, the plane will disappear immediately.thats the only thing i would like to have changed.
on the other side, i like the fact, that if you spawn on a base(on ground), and leave the plane, it will get back into the pool as well.thats good if you forgot to change your loadout for example....
and i also like the fact, that the planes disappear in general after one leaves the plane...but when you are in a dogfight, it loooks weird, when the pilot in front of you bails out, and the plane suddenly is gone...besides, i think that one doesnt get the kill for it in this situation(though im not sure on this).
i assume, that i probably have to change only one line in the script to cure this problem, but i dont know which one....
FG28_Kodiak
06-25-2012, 08:37 AM
Hm must take a look at this, problem is both leaving the plane via Esc and parachuting called OnPlaceLeaved so i must try a other way to get this fixed.
David198502
06-25-2012, 10:04 AM
ah ok...well its not a major issue...but if it can be solved without too much effort, i would be glad...if not, im happy as well with what i already have.
FG28_Kodiak
06-25-2012, 10:14 AM
Ok new version, should work can't test it at the moment (not at my gaming Pc at the moment):
see new version at
http://forum.1cpublishing.eu/showpost.php?p=438212&postcount=40
David198502
06-25-2012, 10:18 AM
hey Kodiak...no problem, its my duty and a honor to test it!
thx for the really quick fix,.....will try it now..
David198502
06-25-2012, 10:41 AM
seems to work!
i spawned the plane, and left it on the ground with hitting ALT F2, and the plane despawned immediately, just like it used to be.
then i spawned again, took off the runway, bailed out, and the plane kept flying until it crashed into the channel...so everything seems to work now as intended..:grin:
good job Kodiak
FG28_Kodiak
06-26-2012, 04:15 PM
Found a problem by removing the spawnplace more than one time. :rolleyes:
Corrected Version:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using maddox.GP;
using maddox.game;
using maddox.game.world;
using part;
public class Mission : AMission
{
private bool battleEnded;
internal static class ActorObservation
{
internal class ActorDetail
{
public AiActor Actor { get; set; }
private DateTime TimeStamp;
private Point3d LastPosition;
public bool Started { get; private set; }
public bool Destroyed { get; private set; }
public bool IsParachuted { get; set; }
public ActorDetail(AiActor actor)
{
Actor = actor;
TimeStamp = DateTime.Now;
LastPosition = actor.Pos();
}
public TimeSpan CheckActor()
{
TimeSpan positionNotChangedSince = new TimeSpan();
Point3d CurrentPos = Actor.Pos();
if (Actor is AiAircraft)
if ((Actor as AiAircraft).getParameter(ParameterTypes.Z_Altitude AGL, -1) > 20)
// Plane counts as started if Altitude over Ground is larger than 20m
Started = true;
// Actor does not change Position
if (LastPosition.distance(ref CurrentPos) < 0.5 && Started)
positionNotChangedSince = DateTime.Now.Subtract(TimeStamp);
else
{
LastPosition = CurrentPos;
TimeStamp = DateTime.Now;
}
return positionNotChangedSince;
}
public void Destroy()
{
AiCart cart = Actor as AiCart;
if (cart != null)
{
cart.Destroy();
Destroyed = true;
}
}
}
private static List<ActorDetail> ActorsInGame = new List<ActorDetail>();
public static void StoreActor(AiActor actor)
{
if (actor is AiAircraft)
ActorsInGame.Add(new ActorDetail(actor));
}
public static void ForceActorDestroyNotPosChangeAfter(int seconds)
{
ActorsInGame.ForEach(item =>
{
if (item.CheckActor().TotalSeconds > seconds)
item.Destroy();
});
ActorsInGame.RemoveAll(item => item.Destroyed);
}
public static void RemoveActor(AiActor actor)
{
if (ActorsInGame.Exists(item => item.Actor == actor))
{
ActorsInGame.RemoveAll(item => item.Actor == actor);
}
}
public static void MarkAsParachuted(AiActor actor)
{
if (ActorsInGame.Exists(item => item.Actor == actor))
ActorsInGame.Find(item => item.Actor == actor).IsParachuted = true;
}
public static bool IsParachuted(AiActor actor)
{
if (ActorsInGame.Exists(item => item.Actor == actor))
return ActorsInGame.Find(item => item.Actor == actor).IsParachuted;
return false;
}
public static List<AiActor> GetStoredActors()
{
List<AiActor> actors = new List<AiActor>();
ActorsInGame.ForEach(item => actors.Add(item.Actor));
return actors;
}
}
internal class SpawnPlace
{
public int NumberOfPlanes { get; set; }
public AiBirthPlace BirthPlace { get; set; }
public IGamePlay GamePlay { get; set; }
private bool _isAvalable;
private List<AiAircraft> PlanesInUse = new List<AiAircraft>();
public SpawnPlace(IGamePlay gamePlay, AiBirthPlace birthPlace, int maxNumber)
{
GamePlay = gamePlay;
BirthPlace = birthPlace;
NumberOfPlanes = maxNumber;
if (maxNumber > 0)
_isAvalable = true;
}
public void CheckPlaneOut(AiActor actor)
{
if (actor != null && (actor is AiAircraft))
{
if (PlanesInUse.Exists(item => item == actor)) return;
PlanesInUse.Add(actor as AiAircraft);
NumberOfPlanes--;
GamePlay.gpLogServer(null, "Airfield: {0}: {1} plane(s) avaiable, {2} in use.", new object[] { BirthPlace.Name(), NumberOfPlanes, PlanesInUse.Count });
if (NumberOfPlanes <= 0 && _isAvalable)
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
{
if (bp.Name().Equals(BirthPlace.Name()))
bp.destroy();
}
_isAvalable = false;
}
}
}
public void CheckPlaneIn(AiActor actor)
{
if (actor != null && actor is AiAircraft)
if (IsActorDown(actor) && CheckIsHomeBase(actor, 800.0)) // Plane landed on correct Homebase if in 800m Radius from SpawnplaceLocation
{
PlanesInUse.Remove(actor as AiAircraft);
NumberOfPlanes++;
GamePlay.gpLogServer(null, "Airfield: {0}: {1} plane(s) avaiable", new object[] { BirthPlace.Name(), NumberOfPlanes });
if (!_isAvalable)
{
GamePlay.gpPostMissionLoad(CreateBirthPlace(BirthP lace));
_isAvalable = true;
}
}
else PlanesInUse.Remove(actor as AiAircraft); // Plane is lost
}
private bool CheckIsHomeBase(AiActor actor, double maxdistance)
{
Point3d actorPos = actor.Pos();
if (PlanesInUse.Exists(item => item == actor))
{
Point3d HomeBasePos = new Point3d(BirthPlace.Pos().x, BirthPlace.Pos().y, 0.0);
if (HomeBasePos.distance(ref actorPos) < maxdistance)
return true;
}
return false;
}
private bool IsActorDown(AiActor actor)
{
AiAircraft aircraft = actor as AiAircraft;
if (aircraft != null && (aircraft.getParameter(ParameterTypes.Z_AltitudeAG L, -1) <= 2.0
&& aircraft.getParameter(ParameterTypes.Z_VelocityTAS , -1) <= 1.0))
return true;
return false;
}
public int NumberOfPlanesInUse()
{
return PlanesInUse.Count;
}
internal ISectionFile CreateBirthPlace(AiBirthPlace birthPlace)
{
ISectionFile f = GamePlay.gpCreateSectionFile();
string sect;
string key;
string value;
sect = "BirthPlace";
key = birthPlace.Name();
int setOnPark = 0;
if (birthPlace.IsSetOnPark())
setOnPark = 1;
int isParachute = 0;
if (birthPlace.IsParachute())
isParachute = 1;
string country = ".";
if (birthPlace.Country() != null)
country = birthPlace.Country();
string hierachy = ".";
if (birthPlace.Hierarchy() != null)
hierachy = birthPlace.Hierarchy();
string regiment = ".";
if (birthPlace.Regiment() != null)
regiment = birthPlace.Regiment().name();
value = " " + birthPlace.Army().ToString(CultureInfo.InvariantCu lture) + " " + birthPlace.Pos().x.ToString(CultureInfo.InvariantC ulture) + " "
+ birthPlace.Pos().y.ToString(CultureInfo.InvariantC ulture) + " " + birthPlace.Pos().z.ToString(CultureInfo.InvariantC ulture) + " "
+ birthPlace.MaxPlanes().ToString(CultureInfo.Invari antCulture) + " " + setOnPark.ToString(CultureInfo.InvariantCulture) + " "
+ isParachute.ToString(CultureInfo.InvariantCulture) + " " + country + " " + hierachy + " " + regiment;
f.add(sect, key, value);
sect = "BirthPlace0";
string[] planeSet = birthPlace.GetAircraftTypes();
if (planeSet.Length > 0)
for (int j = 0; j < planeSet.Length; j++)
{
key = planeSet[j];
value = "";
f.add(sect, key, value);
}
return f;
}
}
internal static class SpawnPlaceManagement
{
static List<SpawnPlace> _spawnPlaces = new List<SpawnPlace>();
public static IGamePlay GamePlay { get; set; }
public static void Limitations(params KeyValuePair<string, int>[] keyValuePair)
{
foreach (KeyValuePair<string, int> kvp in keyValuePair)
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
{
if(kvp.Key.Equals(bp.Name()))
_spawnPlaces.Add(new SpawnPlace(GamePlay, bp, kvp.Value));
}
}
}
private static AiBirthPlace GetBirthPlaceByName(string birthPlaceName)
{
foreach (SpawnPlace sp in _spawnPlaces)
{
if (sp.BirthPlace.Name().Equals(birthPlaceName))
return sp.BirthPlace;
}
return null;
}
private static AiBirthPlace GetNearestBirthplace(AiActor actor)
{
AiBirthPlace nearestBirthplace = null;
if (actor == null) return null;
Point3d pos = actor.Pos();
if (_spawnPlaces != null)
{
foreach (SpawnPlace airport in _spawnPlaces)
{
if (nearestBirthplace != null)
{
if (nearestBirthplace.Pos().distance(ref pos) > airport.BirthPlace.Pos().distance(ref pos))
nearestBirthplace = airport.BirthPlace;
}
else nearestBirthplace = airport.BirthPlace;
}
}
return nearestBirthplace;
}
public static int CountAvailablePlanes(int army)
{
int count = 0;
_spawnPlaces.ForEach(item =>
{
if (item.BirthPlace != null)
if (item.BirthPlace.Army() == army)
count += item.NumberOfPlanes;
});
return count;
}
public static int CountPlanesInUse(int army)
{
int count = 0;
_spawnPlaces.ForEach(item =>
{
if (item.BirthPlace != null)
if (item.BirthPlace.Army() == army)
count += item.NumberOfPlanesInUse();
});
return count;
}
public static void DebugPrint()
{
_spawnPlaces.ForEach(item => GamePlay.gpLogServer(null, "BirthPlaces: {0} In Store: {1} In Use: {2}", new object[] { item.BirthPlace.Name(), item.NumberOfPlanes, item.NumberOfPlanesInUse() }));
}
public static void CheckPlaneOut(AiActor actor)
{
if (actor == null) return;
AiBirthPlace birthPlace = GetNearestBirthplace(actor);
foreach (SpawnPlace spawnPlace in _spawnPlaces)
{
if (spawnPlace.BirthPlace == birthPlace)
spawnPlace.CheckPlaneOut(actor);
}
}
public static void CheckPlaneIn(AiActor actor)
{
if (actor == null) return;
AiBirthPlace birthPlace = GetNearestBirthplace(actor);
foreach (SpawnPlace spawnPlace in _spawnPlaces)
{
if (spawnPlace.BirthPlace == birthPlace)
spawnPlace.CheckPlaneIn(actor);
}
}
}
public override void OnBattleStarted()
{
base.OnBattleStarted();
MissionNumberListener = -1;
SpawnPlaceManagement.GamePlay = GamePlay;
SpawnPlaceManagement.Limitations(
new KeyValuePair<string, int>("Spits", 10), // Name of Birthplace, Number of Max Available planes
new KeyValuePair<string, int>("Bf109E", 10)
);
}
private bool IsDestroyable(AiActor actor)
{
AiCart cart = actor as AiCart;
if (cart != null)
{
//check if a player is present in actor
for (int i = 0; i < cart.Places(); i++)
if (cart.Player(i) != null)
return false;
}
return true;
}
private void Destroy(AiActor actor)
{
AiCart cart = actor as AiCart;
if(cart != null)
cart.Destroy();
ActorObservation.RemoveActor(actor);
}
public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceEnter(player, actor, placeIndex);
SpawnPlaceManagement.CheckPlaneOut(actor);
if (player.PlacePrimary() <= 0 && player.PlaceSecondary() == -1)
{
if (actor is AiCart)
ActorObservation.StoreActor(actor);
int availablePlanes = SpawnPlaceManagement.CountAvailablePlanes(player.A rmy());
if (availablePlanes == 5) // Message if only 5 planes left, change to your needs
{
if (player.Army() == 1)
GamePlay.gpHUDLogCenter(null, "Attention RED only {0} planes left!", new object[] { availablePlanes } );
if (player.Army() == 2)
GamePlay.gpHUDLogCenter(null, "Attention BLUE only {0} planes left!", new object[] { availablePlanes });
}
}
}
public override void OnPersonMoved(AiPerson person, AiActor fromCart, int fromPlaceIndex)
{
base.OnPersonMoved(person, fromCart, fromPlaceIndex);
if (person.Player() != null)
if (((person.Cart() == null) && (fromCart is AiAircraft)) && (fromCart as AiAircraft).IsAirborne())
ActorObservation.MarkAsParachuted(fromCart);
}
public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceLeave(player, actor, placeIndex);
if(IsDestroyable(actor) && !ActorObservation.IsParachuted(actor))
Destroy(actor);
}
public override void OnActorDestroyed(int missionNumber, string shortName, AiActor actor)
{
base.OnActorDestroyed(missionNumber, shortName, actor);
SpawnPlaceManagement.CheckPlaneIn(actor);
if (actor.Army() == 1 && SpawnPlaceManagement.CountAvailablePlanes(1) == 0 && SpawnPlaceManagement.CountPlanesInUse(1) == 0 && !battleEnded)
{
battleEnded = true;
GamePlay.gpHUDLogCenter(null, "Blue Wins!");
}
else if (actor.Army() == 2 && SpawnPlaceManagement.CountAvailablePlanes(2) == 0 && SpawnPlaceManagement.CountPlanesInUse(2) == 0 && !battleEnded)
{
battleEnded = true;
GamePlay.gpHUDLogCenter(null, "Red Wins");
}
}
public override void OnTickGame()
{
base.OnTickGame();
if (Time.tickCounter() % 300 == 0) // check every 10 sec
{
ActorObservation.ForceActorDestroyNotPosChangeAfte r(60); // if actor not changed position destroy it after 1 min (must be started before)
}
}
}
FG28_Kodiak
06-28-2012, 01:46 PM
So new Version. Now it's possible to limit every PlaneType seperately, it's now possible to transfer one Airplane from one Birthplace to an other (the other must be specify in the Birthcontrol). It's also possible to resupply the places.
Version to test:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using maddox.GP;
using maddox.game;
using maddox.game.world;
using part;
public class Mission : AMission
{
private bool battleEnded;
internal static class ActorObservation
{
internal class ActorDetail
{
public AiActor Actor { get; set; }
private DateTime TimeStamp;
private Point3d LastPosition;
public bool Started { get; private set; }
public bool Destroyed { get; private set; }
public bool IsParachuted { get; set; }
public ActorDetail(AiActor actor)
{
Actor = actor;
TimeStamp = DateTime.Now;
LastPosition = actor.Pos();
}
public TimeSpan CheckActor()
{
TimeSpan positionNotChangedSince = new TimeSpan();
Point3d CurrentPos = Actor.Pos();
if (Actor is AiAircraft)
if ((Actor as AiAircraft).getParameter(ParameterTypes.Z_Altitude AGL, -1) > 20)
// Plane counts as started if Altitude over Ground is larger than 20m
Started = true;
// Actor does not change Position
if (LastPosition.distance(ref CurrentPos) < 0.5 && Started)
positionNotChangedSince = DateTime.Now.Subtract(TimeStamp);
else
{
LastPosition = CurrentPos;
TimeStamp = DateTime.Now;
}
return positionNotChangedSince;
}
public void Destroy()
{
AiCart cart = Actor as AiCart;
if (cart != null)
{
cart.Destroy();
Destroyed = true;
}
}
}
private static List<ActorDetail> ActorsInGame = new List<ActorDetail>();
public static void StoreActor(AiActor actor)
{
if (actor is AiAircraft)
ActorsInGame.Add(new ActorDetail(actor));
}
public static void ForceActorDestroyNotPosChangeAfter(int seconds)
{
ActorsInGame.ForEach(item =>
{
if (item.CheckActor().TotalSeconds > seconds)
item.Destroy();
});
ActorsInGame.RemoveAll(item => item.Destroyed);
}
public static void RemoveActor(AiActor actor)
{
if (ActorsInGame.Exists(item => item.Actor == actor))
{
ActorsInGame.RemoveAll(item => item.Actor == actor);
}
}
public static void MarkAsParachuted(AiActor actor)
{
if (ActorsInGame.Exists(item => item.Actor == actor))
ActorsInGame.Find(item => item.Actor == actor).IsParachuted = true;
}
public static bool IsParachuted(AiActor actor)
{
if (ActorsInGame.Exists(item => item.Actor == actor))
return ActorsInGame.Find(item => item.Actor == actor).IsParachuted;
return false;
}
public static List<AiActor> GetStoredActors()
{
List<AiActor> actors = new List<AiActor>();
ActorsInGame.ForEach(item => actors.Add(item.Actor));
return actors;
}
}
internal class SpawnPlace
{
public AiBirthPlace BirthPlace { get; set; }
public IGamePlay GamePlay { get; set; }
private bool _isAvalable;
private bool _transferAllowed;
private Dictionary<string, int> Store = new Dictionary<string, int>();
private List<AiAircraft> PlanesInUse = new List<AiAircraft>();
public SpawnPlace(IGamePlay gamePlay, AiBirthPlace birthPlace, bool transferAllowed, Dictionary<string, int> stores)
{
GamePlay = gamePlay;
BirthPlace = birthPlace;
_transferAllowed = transferAllowed;
if (stores != null)
{
Store = stores;
if (stores.Count > 0)
_isAvalable = true;
}
}
public int CountAllAvailablePlanes()
{
int count = 0;
foreach (KeyValuePair<string, int> kvp in Store)
count += kvp.Value;
return count;
}
public int NumberOfPlanesInUse()
{
return PlanesInUse.Count;
}
public void CheckPlaneOut(AiActor actor)
{
AiAircraft aircraft = actor as AiAircraft;
if (aircraft != null)
{
if (PlanesInUse.Exists(item => item == aircraft)) return;
PlanesInUse.Add(aircraft);
int numberOfPlanes = 0;
string storedPlaneName = aircraft.InternalTypeName().Replace("bob:", "");
if (Store.TryGetValue(storedPlaneName, out numberOfPlanes))
{
if (numberOfPlanes > 0)
{
numberOfPlanes--;
Store[storedPlaneName] = numberOfPlanes;
ShowStorage();
}
}
if (numberOfPlanes <= 0)
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
{
if (bp.Name().Equals(BirthPlace.Name()))
{
bp.destroy();
}
}
ISectionFile newBirthPlace = RecreateBirthPlace(BirthPlace, GetAircrafts());
if (newBirthPlace != null)
{
GamePlay.gpPostMissionLoad(newBirthPlace);
}
}
}
}
public void CheckPlaneIn(AiActor actor)
{
AiAircraft aircraft = actor as AiAircraft;
bool recreateBirthplace = false;
int numberOfPlanes;
if (aircraft != null)
{
if (IsActorDown(actor) && CheckIsHomeBase(actor, 800.0)) // Plane landed on correct Homebase if in 800m Radius from SpawnplaceLocation
{
PlanesInUse.Remove(actor as AiAircraft);
string storedPlaneName = aircraft.InternalTypeName().Replace("bob:", "");
if (Store.TryGetValue(storedPlaneName, out numberOfPlanes))
{
if (numberOfPlanes <= 0)
recreateBirthplace = true;
numberOfPlanes++;
Store[storedPlaneName] = numberOfPlanes;
ShowStorage();
}
}
else if (IsActorDown(actor) && CheckBase(actor, 800.0) && _transferAllowed) //Plane is landed on other existing Base
{
BirthControl.RemoveActor(actor); // Remove the actor from other Birthplace
GamePlay.gpLogServer(null, "Gelandet auf fremden Platz", null);
string storedPlaneName = aircraft.InternalTypeName().Replace("bob:", "");
if (Store.TryGetValue(storedPlaneName, out numberOfPlanes))
{
if (numberOfPlanes <= 0)
recreateBirthplace = true;
numberOfPlanes++;
Store[storedPlaneName] = numberOfPlanes;
ShowStorage();
}
else
{
Store.Add(storedPlaneName, 1);
recreateBirthplace = true;
ShowStorage();
}
}
else PlanesInUse.Remove(actor as AiAircraft); // Plane is lost
if (recreateBirthplace)
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
if (bp.Name().Equals(BirthPlace.Name()))
bp.destroy();
ISectionFile newBirthPlace = RecreateBirthPlace(BirthPlace, GetAircrafts());
if (newBirthPlace != null)
GamePlay.gpPostMissionLoad(newBirthPlace);
}
}
}
public void RemoveActor(AiActor actor)
{
AiAircraft aircraft = actor as AiAircraft;
if (aircraft != null)
if (PlanesInUse.Exists(item => item == aircraft))
PlanesInUse.Remove(aircraft);
}
public void ResupplyAll(int nrOfAdditionalPlanes, int nrOfMaxPlanes)
{
List<string> keyList = new List<string>();
bool recreateBirthplace = false;
keyList.AddRange(Store.Keys);
foreach (string st in keyList)
{
int value = 0;
if (Store.TryGetValue(st, out value))
{
if (value <= 0)
recreateBirthplace = true;
value += nrOfAdditionalPlanes;
if (value > nrOfMaxPlanes)
value = nrOfMaxPlanes;
Store[st] = value;
}
}
if(recreateBirthplace)
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
if (bp.Name().Equals(BirthPlace.Name()))
bp.destroy();
ISectionFile newBirthPlace = RecreateBirthPlace(BirthPlace, GetAircrafts());
if (newBirthPlace != null)
GamePlay.gpPostMissionLoad(newBirthPlace);
}
ShowStorage();
}
public void Resupply(string planeName, int nrOfAdditionalPlanes, int nrOfMaxPlanes)
{
int value = 0;
bool recreateBirthplace = false;
if (Store.TryGetValue(planeName, out value))
{
if (value <= 0)
recreateBirthplace = true;
value += nrOfAdditionalPlanes;
if(value > nrOfMaxPlanes)
value = nrOfMaxPlanes;
Store[planeName] = value;
}
else
{
recreateBirthplace = true;
Store.Add(planeName, nrOfAdditionalPlanes);
}
if (recreateBirthplace)
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
if (bp.Name().Equals(BirthPlace.Name()))
bp.destroy();
ISectionFile newBirthPlace = RecreateBirthPlace(BirthPlace, GetAircrafts());
if (newBirthPlace != null)
GamePlay.gpPostMissionLoad(newBirthPlace);
}
ShowStorage();
}
private bool CheckIsHomeBase(AiActor actor, double maxdistance)
{
Point3d actorPos = actor.Pos();
if (PlanesInUse.Exists(item => item == actor))
{
Point3d HomeBasePos = new Point3d(BirthPlace.Pos().x, BirthPlace.Pos().y, 0.0);
if (HomeBasePos.distance(ref actorPos) < maxdistance)
return true;
}
return false;
}
private bool CheckBase(AiActor actor, double maxdistance)
{
Point3d actorPos = actor.Pos();
Point3d BasePos = new Point3d(BirthPlace.Pos().x, BirthPlace.Pos().y, 0.0);
if (BasePos.distance(ref actorPos) < maxdistance && actor.Army() == BirthPlace.Army())
return true;
return false;
}
private string ParsePlaneType(string planeName)
{
if (planeName.StartsWith("bob:Aircraft."))
return planeName.Replace("bob:Aircraft.", "");
if (planeName.StartsWith("Aircraft."))
return planeName.Replace("Aircraft.", "");
return planeName;
}
private string[] GetAircrafts()
{
List<string> aircrafts = new List<string>();
foreach (KeyValuePair<string, int> kvp in Store)
{
if (kvp.Value > 0)
{
if (!aircrafts.Exists(item => item == kvp.Key))
{
aircrafts.Add(kvp.Key);
}
}
}
return aircrafts.ToArray();
}
private bool IsActorDown(AiActor actor)
{
AiAircraft aircraft = actor as AiAircraft;
if (aircraft != null && (aircraft.getParameter(ParameterTypes.Z_AltitudeAG L, -1) <= 2.0
&& aircraft.getParameter(ParameterTypes.Z_VelocityTAS , -1) <= 1.0))
return true;
return false;
}
private ISectionFile RecreateBirthPlace(AiBirthPlace birthPlace, string[] aircraftTypes)
{
if (aircraftTypes == null || aircraftTypes.Length == 0)
return null;
ISectionFile f = GamePlay.gpCreateSectionFile();
string sect;
string key;
string value;
sect = "BirthPlace";
key = birthPlace.Name();
int setOnPark = 0;
if (birthPlace.IsSetOnPark())
setOnPark = 1;
int isParachute = 0;
if (birthPlace.IsParachute())
isParachute = 1;
string country = ".";
if (birthPlace.Country() != null)
country = birthPlace.Country();
string hierachy = ".";
if (birthPlace.Hierarchy() != null)
hierachy = birthPlace.Hierarchy();
string regiment = ".";
if (birthPlace.Regiment() != null)
regiment = birthPlace.Regiment().name();
value = " " + birthPlace.Army().ToString(CultureInfo.InvariantCu lture) + " " + birthPlace.Pos().x.ToString(CultureInfo.InvariantC ulture) + " "
+ birthPlace.Pos().y.ToString(CultureInfo.InvariantC ulture) + " " + birthPlace.Pos().z.ToString(CultureInfo.InvariantC ulture) + " "
+ birthPlace.MaxPlanes().ToString(CultureInfo.Invari antCulture) + " " + setOnPark.ToString(CultureInfo.InvariantCulture) + " "
+ isParachute.ToString(CultureInfo.InvariantCulture) + " " + country + " " + hierachy + " " + regiment;
f.add(sect, key, value);
sect = "BirthPlace0";
string[] planeSet = aircraftTypes;
if (planeSet.Length > 0)
for (int j = 0; j < planeSet.Length; j++)
{
key = planeSet[j];
value = "";
f.add(sect, key, value);
}
return f;
}
private void ShowStorage()
{
List<Player> players = new List<Player>();
if (GamePlay.gpPlayer() != null)
players.Add(GamePlay.gpPlayer());
if (GamePlay.gpRemotePlayers() != null)
players.AddRange(GamePlay.gpRemotePlayers());
players.RemoveAll(item => item.Army() != BirthPlace.Army());
if (players.Count > 0)
{
GamePlay.gpLogServer(players.ToArray(), "Available on Airfield {0}:", new object[] { BirthPlace.Name() });
foreach (KeyValuePair<string, int> kvp in Store)
{
GamePlay.gpLogServer(players.ToArray(), "{0} {1}", new object[] { kvp.Value, ParsePlaneType(kvp.Key) });
}
}
}
}
internal static class BirthControl
{
private static List<SpawnPlace> _spawnPlaces = new List<SpawnPlace>();
public static IGamePlay GamePlay { get; set; }
public static void Limitations(bool transferAllowed, params KeyValuePair<string, Dictionary<string, int>>[] keyValuePair)
{
foreach (KeyValuePair<string, Dictionary<string, int>> kvp in keyValuePair)
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
{
if (kvp.Key.Equals(bp.Name()))
_spawnPlaces.Add(new SpawnPlace(GamePlay, bp, transferAllowed, kvp.Value));
}
}
}
public static void CheckPlaneOut(AiActor actor)
{
if (actor == null) return;
AiBirthPlace birthPlace = GetNearestBirthplace(actor);
foreach (SpawnPlace spawnPlace in _spawnPlaces)
{
if (spawnPlace.BirthPlace == birthPlace)
spawnPlace.CheckPlaneOut(actor);
}
}
public static void CheckPlaneIn(AiActor actor)
{
if (actor == null) return;
AiBirthPlace birthPlace = GetNearestBirthplace(actor);
foreach (SpawnPlace spawnPlace in _spawnPlaces)
{
if (spawnPlace.BirthPlace == birthPlace)
spawnPlace.CheckPlaneIn(actor);
}
}
internal static void RemoveActor(AiActor actor)
{
foreach (SpawnPlace sp in _spawnPlaces)
sp.RemoveActor(actor);
}
public static int CountAvailablePlanes(int army)
{
int count = 0;
_spawnPlaces.ForEach(item =>
{
if (item.BirthPlace != null)
if (item.BirthPlace.Army() == army)
count += item.CountAllAvailablePlanes();
});
return count;
}
public static int CountPlanesInUse(int army)
{
int count = 0;
_spawnPlaces.ForEach(item =>
{
if (item.BirthPlace != null)
if (item.BirthPlace.Army() == army)
count += item.NumberOfPlanesInUse();
});
return count;
}
private static AiBirthPlace GetNearestBirthplace(AiActor actor)
{
AiBirthPlace nearestBirthplace = null;
if (actor == null) return null;
Point3d pos = actor.Pos();
if (_spawnPlaces != null)
{
foreach (SpawnPlace airport in _spawnPlaces)
{
if (nearestBirthplace != null)
{
if (nearestBirthplace.Pos().distance(ref pos) > airport.BirthPlace.Pos().distance(ref pos))
nearestBirthplace = airport.BirthPlace;
}
else nearestBirthplace = airport.BirthPlace;
}
}
return nearestBirthplace;
}
public static void Resupply(string birthPlace, string planeType, int nrOfAdditionalPlanes, int nrOfMaxPlanes)
{
_spawnPlaces.ForEach(item =>
{
if (item.BirthPlace.Name().Equals(birthPlace))
item.Resupply(planeType, nrOfAdditionalPlanes, nrOfMaxPlanes);
});
}
public static void Resupply(string birthPlace, int nrOfAdditionalPlanes, int nrOfMaxPlanes)
{
_spawnPlaces.ForEach(item =>
{
if (item.BirthPlace.Name().Equals(birthPlace))
item.ResupplyAll(nrOfAdditionalPlanes, nrOfMaxPlanes);
});
}
public static void ResupplyAll(int nrOfAdditionalPlanes, int nrOfMaxPlanes)
{
_spawnPlaces.ForEach(item => item.ResupplyAll(nrOfAdditionalPlanes, nrOfMaxPlanes));
}
}
private bool IsDestroyable(AiActor actor)
{
AiCart cart = actor as AiCart;
if (cart != null)
{
//check if a player is present in actor
for (int i = 0; i < cart.Places(); i++)
if (cart.Player(i) != null)
return false;
}
return true;
}
private void Destroy(AiActor actor)
{
AiCart cart = actor as AiCart;
if (cart != null)
cart.Destroy();
ActorObservation.RemoveActor(actor);
}
#region Overrides
public override void OnBattleStarted()
{
base.OnBattleStarted();
MissionNumberListener = -1;
BirthControl.GamePlay = GamePlay;
BirthControl.Limitations(true, new KeyValuePair<string, Dictionary<string, int>>("GermanPlace", new Dictionary<string, int>
{
{"Aircraft.Bf-109E-1", 10},
{"Aircraft.Bf-109E-3", 5},
{"Aircraft.Bf-109E-4", 5}
}),
new KeyValuePair<string, Dictionary<string, int>>("GermanPlace2", new Dictionary<string, int>
{
{"Aircraft.Bf-109E-1", 10},
{"Aircraft.Bf-109E-3", 5}
}),
new KeyValuePair<string, Dictionary<string, int>>("BritishPlace", new Dictionary<string, int>
{
{"Aircraft.SpitfireMkIa", 10},
{"Aircraft.SpitfireMkIIa", 5},
{"Aircraft.HurricaneMkI", 20}
}));
}
public override void OnPersonMoved(AiPerson person, AiActor fromCart, int fromPlaceIndex)
{
base.OnPersonMoved(person, fromCart, fromPlaceIndex);
if (person.Player() != null)
if (((person.Cart() == null) && (fromCart is AiAircraft)) && (fromCart as AiAircraft).IsAirborne())
ActorObservation.MarkAsParachuted(fromCart);
}
public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceEnter(player, actor, placeIndex);
BirthControl.CheckPlaneOut(actor);
if (player.PlacePrimary() <= 0 && player.PlaceSecondary() == -1)
{
if (actor is AiCart)
ActorObservation.StoreActor(actor);
}
}
public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceLeave(player, actor, placeIndex);
if (IsDestroyable(actor) && !ActorObservation.IsParachuted(actor))
Destroy(actor);
}
public override void OnActorDestroyed(int missionNumber, string shortName, AiActor actor)
{
base.OnActorDestroyed(missionNumber, shortName, actor);
BirthControl.CheckPlaneIn(actor);
if (actor.Army() == 1 && BirthControl.CountAvailablePlanes(1) == 0 && BirthControl.CountPlanesInUse(1) == 0 && !battleEnded)
{
battleEnded = true;
GamePlay.gpHUDLogCenter(null, "Blue Wins!");
}
else if (actor.Army() == 2 && BirthControl.CountAvailablePlanes(2) == 0 && BirthControl.CountPlanesInUse(2) == 0 && !battleEnded)
{
battleEnded = true;
GamePlay.gpHUDLogCenter(null, "Red Wins");
}
}
public override void OnTickGame()
{
base.OnTickGame();
if (Time.tickCounter() % 216000 == 215999) // Two hours
{
BirthControl.ResupplyAll(4, 10); // All SpawnPlaces get resupply
//BirthControl.Resupply("GermanPlace", 4, 10); // Resupply only the GermanPlace Spawnplace
//BirthControl.Resupply("GermanPlace", "Aircraft.Bf-109E-4", 4, 10); // Resupply only the AircraftType Bf109E-4 on GermanPlace
}
if (Time.tickCounter() % 300 == 299) // check every 10 sec
{
ActorObservation.ForceActorDestroyNotPosChangeAfte r(60); // if actor not changed position destroy it after 1 min (must be started before)
}
}
#endregion
}
Simple Sample Mission in attachment.
David198502
07-02-2012, 09:26 AM
Hey Kodiak!sorry i didnt answers sooner, but i didint recognize until now, that you have improved the script further!thats great!thank you very much!
will have to try it out now....
thx!
David198502
07-04-2012, 06:30 AM
hey Kodiak!
this script works perfect!
the nice thing is, that the messages which show the state of each airfield, are only visible for your own side...
we tested it yesterday, and honestly, i cant think of any possible improvement!!
great work!
David198502
07-04-2012, 09:03 AM
btw Kodiak!
now that you have wrote so many scripts for me/our squad, and we all have great fun with your work, how about jumping in,joining us, and enjoy the fun you have created!?
you are welcome any time...if you are in the mood to fly, look in the lobby section and watch for a lobby called ACG...thats us!i would be pleased.
btw, whats your playername in steam?
FG28_Kodiak
07-04-2012, 02:15 PM
My playername is FG28_Kodiak ;)
David198502
07-04-2012, 02:44 PM
will add you as a friend
Edit: steam doesnt find you...:(
Smokeynz
07-05-2012, 01:36 AM
steam isn't friendly:-)
FG28_Kodiak
07-05-2012, 04:11 AM
will add you as a friend
Edit: steam doesnt find you...:(
Ah mistake steamname for steam nickname so try:
Kodiak1968
David198502
07-05-2012, 12:55 PM
still no joy....
i hate steam regarding this,....i have all the time trouble to find people in steam
FG28_Kodiak
07-05-2012, 02:48 PM
How is yours?
Warhound
07-05-2012, 04:24 PM
This little tutorial should help tell you what your Steam ID is.
It will be a bunch of digits if you haven't changed to a Custom URL yet, share the link and it will bring people to the players page where they can add you to their friendslist.
http://www.youtube.com/watch?v=B0a7gCHq-B0
David198502
07-05-2012, 05:19 PM
How is yours?
JG26_DavidRed
David198502
07-06-2012, 08:14 AM
btw, we as a squad tested the script another time, and while the spawnplaces are all working, when you come back to any of your friendly bases, the winning message didnt show up for some reason....
i dont know why, cause when i tested it alone, with only a few aircraft on both side(for testing puroposes), the message came up, as soon as i smashed all planes into the ground.
maybe it has something to do, that many of us, did crash landings in fields, or ditched in the water??
i dont know, but the message just didnt show up...
FG28_Kodiak
07-06-2012, 08:20 AM
Must take a look at it.
But i don't understand ".. when you come back to any of your friendly bases, the winning message didnt show up for some reason...."
The enemies are all destroyed?
David198502
07-06-2012, 08:26 AM
well, what i was trying to say is, that its working that you can take your plane again,when you come back to any of your friendly bases, from the base where you have landed....
but the only thing that seems not to work every time is the winning message....(though it worked for me when i tested it myself, when i crashed all available planes of one side into the ground on purpose)
yeah, all planes were destroyed, or at least, on the red side there werent any planes available anymore at any of the airbases...i asked our "red squadmates" if they really used all the planes...they confirmed, and then to assure myself, i switched to the red side to have a look myself, and all the spawnpoints disappeared, and nobody on the red side was in a flying plane anymore...(i looked at the online stats)
FG28_Kodiak
07-06-2012, 08:58 AM
Ok, must look at this.
David198502
07-06-2012, 04:22 PM
thx Kodiak,...but dont hurry, as this is only a cosmetic feature...as already mentioned, the rest of it works perfect!
btw, i have accepted your friendsrequest on steam. so if you are in the mood to fly, tell me and we could enjoy your creatons together!
vBulletin® v3.8.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.