View Single Post
  #1  
Old 10-06-2011, 09:43 AM
Ataros Ataros is offline
Approved Member
 
Join Date: Jun 2010
Location: USSR
Posts: 2,439
Default Script limiting aircraft types (including multilingual messages)

Here is a current WIP script version from Repka Steppe map. Kodiak and TheEnlightenedFlorist, thank you for your help. Without you it would not be possible.

The script runs on Repka #1 ATM please try it and let me know what you think.

Kodiak, when you have time I would like to ask you for advice how to calculate number of enemy fighter and bomber planes. Ideally I see aircraft limiting script as follows:

Declare percentages for limited aircraft types = X%.
OnPlaceEnter recalculate number of human-controlled enemy fighter and bomber planes (enmyFgtrs & enmyBmbrs) - this is the difficult part
Set curTeamBalance = (friendlyFgtrs + friendlyBmbrs/2) / (enmyFgtrs + enmyBmbrs/2)
Check if
if curTeamBalance > allowedTeamBalance then deny a limited aircraft (with RU and international message).
else Set e.g.
Code:
allowed109s = (X% * (enmyFgtrs + enmyBmbrs/2) * objCompleted) / curTeamBalance
double objCompleted = 1 for now (to be used in the future with triggers probably as a bonus for completing objectives).

Check if (current109s > allowed109s) then deny an aircraft.
Leave a window of opportunity for other players to take a limited aircraft after a player that just flew a limited aircraft takes it again (I do it in code reducing current109s by 1 for 20 seconds and then increasing it again).

I know that other servers experience huge issues trying to find balance between SpitIIs and 109s and this script may be very useful for everyone flying online.

Code:
using System;
using System.Collections;
using maddox.game;
using maddox.game.world;
using System.Collections.Generic;

using System.Diagnostics;


/**
 * Parts of the script were taken from:
 * Operation Dynamo v2.0 by TheEnlightenedFlorist http://forum.1cpublishing.eu/showthread.php?t=23579&highlight=operation+dynamo
 * Messages script by FG28_Kodiak http://forum.1cpublishing.eu/showthread.php?t=26623 
 * 
 * * */


public class Mission : AMission
{

    //allowed and currently flying aircraft
    int allowed109s = 12;
    int current109s = 0;

    int allowedSpit2s = 7;
    int currentSpit2s = 0;

    int allowed110s = 5;
    int current110s = 0;
    //double allowedTeamBalance = 1.2;
    //double currentTeamBalance = 1;

    public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        //listen to events from all missions.
        MissionNumberListener = -1;

    }


    public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
    {
        base.OnPlaceEnter(player, actor, placeIndex);

        if (actor != null && actor is AiAircraft)
        {
            clickFlagMsg(player); // reminds to click flag to change an aircraft

            //checks limited aircraft
            switch ((actor as AiAircraft).InternalTypeName())
            {
                case "bob:Aircraft.Bf-109E-4":
                    {
                        current109s++;
                        // test
                        //GamePlay.gpHUDLogCenter(String.Format("current109s = {0}", current109s));

                        if (current109s > allowed109s)
                        {
                            (actor as AiAircraft).hitNamed(part.NamedDamageTypes.Eng0TotalFailure);
                            notAvailableMsg(player);
                        }
                        else
                            // Возможность для других взять самолет. Window of opportunity for others.
                            current109s--;
                            // test        
                            //Timeout(10, () =>
                            //    {
                            //       GamePlay.gpHUDLogCenter(String.Format("current109s = {0}", current109s));
                            //    });
                              
                            Timeout(20, () =>
                                {
                                    current109s++;
                                    //GamePlay.gpHUDLogCenter(String.Format("current109s = {0}", current109s));
                                });

                        break;
                    }
                case "bob:Aircraft.SpitfireMkIIa":
                    {
                        currentSpit2s++;
                        if (currentSpit2s > allowedSpit2s)
                        {
                            (actor as AiAircraft).hitNamed(part.NamedDamageTypes.Eng0TotalFailure);
                            notAvailableMsg(player);
                            //GamePlay.gpHUDLogCenter(new Player[] { player }, "Aircraft not available! Choose another aircraft.");
                        }
                        else
                            // Возможность для других взять самолет. Window of opportunity for others.
                            currentSpit2s--;
                        // test        
                        //Timeout(10, () =>
                        //    {
                        //       GamePlay.gpHUDLogCenter(String.Format("currentSpit2s = {0}", currentSpit2s));
                        //    });

                        Timeout(20, () =>
                        {
                            currentSpit2s++;
                            //GamePlay.gpHUDLogCenter(String.Format("currentSpit2s = {0}", currentSpit2s));
                        });

                        break;
                    }
                case "bob:Aircraft.Bf-110C-7":
                    {
                        current110s++;
                        if (current110s > allowed110s)
                        {
                            //(actor as AiAircraft).hitNamed(part.NamedDamageTypes.Eng0TotalFailure); // Is this line for single-engined only? только для одномоторных?

                            // Will this do for multi-engine?
                            int iNumOfEngines = ((actor as AiAircraft).Group() as AiAirGroup).aircraftEnginesNum();
                            for (int i = 0; i < iNumOfEngines; i++)
                            {
                                (actor as AiAircraft).hitNamed((part.NamedDamageTypes)Enum.Parse(typeof(part.NamedDamageTypes), "Eng" + i.ToString() + "TotalFailure"));
                            }

                            notAvailableMsg(player);
                            //GamePlay.gpHUDLogCenter(new Player[] { player }, "Aircraft not available! Choose another aircraft.");
                        }
                        else
                            // Возможность для других взять самолет. Window of opportunity for others.
                            current110s--;
                        // test        
                        //Timeout(10, () =>
                        //    {
                        //       GamePlay.gpHUDLogCenter(String.Format("current110s = {0}", current110s));
                        //    });

                        Timeout(20, () =>
                        {
                            current110s++;
                            //GamePlay.gpHUDLogCenter(String.Format("current110s = {0}", current110s));
                        });
                        break;
                    }
            }
        }
    }


    public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
    {
        base.OnPlaceLeave(player, actor, placeIndex);

        if (actor != null && actor is AiAircraft)
        {
          
            //check limited aircraft
            switch ((actor as AiAircraft).InternalTypeName())
            {
                case "bob:Aircraft.Bf-109E-4":
                    current109s--;
                    break;
                case "bob:Aircraft.SpitfireMkIIa":
                    currentSpit2s--;
                    break;
                case "bob:Aircraft.Bf-110C-7":
                    current110s--;
                    break;
            }

        }
    }

    //public override void OnTickGame()
    //   {         
    //    // Reminders (UPD: not needed now.)
    //           if (Time.tickCounter() % 9000 == 0)
    //           {
    //               sendChatMessageTo(-1, null, "Attention! To change an aircraft first click on the side flag in the top right corner of the menu or press ALT-F2 in game!", null);
    //               sendChatMessageTo(0, null, "Attention! To change an aircraft first click on the side flag in the top right corner of the menu or press ALT-F2 in game!", null); 
    //               // Have to separate armies below to make the message show only to RU users. Otherwise it shows to everyone if army=-1. 
    //               // Приходится разделять армии, иначе иностранцам тоже текст покажется.
    //               sendChatMessageTo(1, "ru", "Внимание! Чтобы сменить самолет, сначала кликните на флаге стороны в правом верхнем углу меню или нажмите ALT-F2 в игре!", null);
    //               sendChatMessageTo(2, "ru", "Внимание! Чтобы сменить самолет, сначала кликните на флаге стороны в правом верхнем углу меню или нажмите ALT-F2 в игре!", null);
    //               sendChatMessageTo(0, "ru", "Внимание! Чтобы сменить самолет, сначала кликните на флаге стороны в правом верхнем углу меню или нажмите ALT-F2 в игре!", null); 
    //           }
    //    }

    // Messages
    private void notAvailableMsg(Player player)
    {
        switch (player.LanguageName())
        {
            case "de":
                GamePlay.gpHUDLogCenter(new Player[] { player }, "Limit für diesen Flugzeugtyp erreicht! Wähle ein anderes Muster!");
                break;
            case "ru":
                GamePlay.gpHUDLogCenter(new Player[] { player }, "Слишком много самолетов данного типа! Выберите другой самолет.");
                break;
            default:
                GamePlay.gpHUDLogCenter(new Player[] { player }, "Too many aircrafts of this type! Choose another aircraft.");
                break;
        }
    }

    private void clickFlagMsg(Player player)
    {
        switch (player.LanguageName())
        {
            case "de":
                GamePlay.gpLogServer(new Player[] { player }, "Attention! To change an aircraft first click on the side flag in the top right corner of the menu or press ALT-F2 in game!", null);
                break;
            case "ru":
                GamePlay.gpLogServer(new Player[] { player }, "Внимание! Чтобы сменить самолет, сначала кликните на флаге стороны в правом верхнем углу меню или нажмите ALT-F2 в игре!", null);
                break;
            default:
                GamePlay.gpLogServer(new Player[] { player }, "Attention! To change an aircraft first click on the side flag in the top right corner of the menu or press ALT-F2 in game!", null);
                break;
        }
    }


// Temporary desabled. Messages script by FG28_Kodiak http://forum.1cpublishing.eu/showthread.php?t=26623 

    //private void sendChatMessageTo(int army, string playerlanguage, string msg, object[] parms)
    //{
    //    if (army != -1)
    //    {
    //        //Singleplayer (for Testing)
    //        if (GamePlay.gpRemotePlayers() == null || GamePlay.gpRemotePlayers().Length <= 0)
    //        {
    //            if (GamePlay.gpPlayer() != null && GamePlay.gpPlayer().Army() == army && GamePlay.gpPlayer().LanguageName().Equals(playerlanguage))
    //                GamePlay.gpLogServer(null, msg, parms);
    //        }
    //        else // Multiplayer
    //        {
    //            List<Player> Players = new List<Player>();

    //            foreach (Player p in GamePlay.gpRemotePlayers())
    //            {
    //                if (p.Army() == army && p.LanguageName().Equals(playerlanguage))
    //                    Players.Add(p);
    //            }
    //            GamePlay.gpLogServer(Players.ToArray(), msg, parms);
    //        }
    //    }
    //    else GamePlay.gpLogServer(null, msg, parms); // this shows Russian text to everyone. Покажет иностранцам русский текст
    //}


        //private void sendScreenMessageTo(int army, string playerlanguage, string msg, object[] parms)
        //{
        //    if (army != -1)
        //    {
        //        //Singleplayer (for Testing)
        //        if (GamePlay.gpRemotePlayers() == null || GamePlay.gpRemotePlayers().Length <= 0)
        //        {
        //            if (GamePlay.gpPlayer() != null && GamePlay.gpPlayer().Army() == army && GamePlay.gpPlayer().LanguageName().Equals(playerlanguage))
        //                GamePlay.gpHUDLogCenter(null, msg, parms);

        //        }
        //        else // Multiplayer
        //        {
        //            List<Player> Players = new List<Player>();

        //            foreach (Player p in GamePlay.gpRemotePlayers())
        //            {
        //                if (p.Army() == army && p.LanguageName().Equals(playerlanguage))
        //                    Players.Add(p);
        //            }
        //            GamePlay.gpHUDLogCenter(Players.ToArray(), msg, parms);
        //        }
        //    }
        //    else GamePlay.gpHUDLogCenter(null, msg, parms);
        //}

}

Regarding messages script it looks like a RU message would be shown to everyone if using sendChatMessageTo(-1, ru, ...)

sendChatMessageTo(-1, null, ...) shows international message to RU users. Ideally I would like to separate messages to RU and international users completely if possible.

Last edited by Ataros; 10-06-2011 at 10:04 AM.
Reply With Quote