Fulqrum Publishing Home   |   Register   |   Today Posts   |   Members   |   UserCP   |   Calendar   |   Search   |   FAQ

Go Back   Official Fulqrum Publishing forum > Fulqrum Publishing > IL-2 Sturmovik: Cliffs of Dover > FMB, Mission & Campaign builder Discussions

Reply
 
Thread Tools Display Modes
  #1  
Old 11-16-2011, 02:25 AM
wildwillie wildwillie is offline
Approved Member
 
Join Date: Aug 2010
Posts: 111
Default Stats Questions

I've gotten a good part of the stats stuff done.

It now keeps tracks of Players and what they accomplish:

Shotdown of planes, Destroy ground Objects, damage other planes/ground Objects.

The questions I have is how should these be scored ?

In IL2 you got 100 pts/per engine for an aircraft shotdown.
30 pts for destroying a ground car, 60 pts for a tank, etc

And if you died you only got 10% of those points. If you bailed out you got 20 or 50% of those points.

I do not see Clod or Steam tracking points so the question is should we keep the same point scheme as IL2 ?


Question 2 -

How to tabulate who wins a mission ?

In FBDj/IL2 you had mission objectives either target based (x% of targets destroyed in a target circle), count based (xx number of tanks/cars/ships destroyed), pilot/planes counts or a combination of all of the above.

With Clod you can now add objectives within a mission and use triggers to see if the objective has been met. (I've not done this, but that is how I understand it)

for this new program should it be based on the mission triggers or the old way it was done in FBDj ?

RAF238thWildWillie
Reply With Quote
  #2  
Old 11-16-2011, 04:00 AM
ATAG_Bliss ATAG_Bliss is offline
Approved Member
 
Join Date: Mar 2010
Posts: 1,156
Default

Hi willie,

Thanks soo much for getting something like this for IL2COD.

As for the answers to your questions, I would keep it exactly like the old game 100 pts 1 engine / 400 pts 4 engine etc.,etc.,. and the same for the mission objectives. Granted while you can do anything you want within the scripting portion of the game, it would be much handier to have a program simplify what exact objects/objectives are set for a mission with a mouse click instead of having to program lines of code for a similar result.

Will this work similar to the current FBDj in regards to being able to use commands such as <gunstats ; <obj<red etc., with the IL2COD interface?

And finally, when will all of us be able to test this?

Thanks again for the hard work!
__________________

ATAG Forums + Stats
Reply With Quote
  #3  
Old 11-16-2011, 07:14 AM
phoenix1963's Avatar
phoenix1963 phoenix1963 is offline
Approved Member
 
Join Date: Oct 2007
Posts: 176
Default

Willie - It's great to see you doing this!
May I suggest you keep a similar points system, but rather than target circles, if you can keep a list of the target objects for each objective then set a points threshold for each objective (low, because 20-30% kills on any unit is enough to destroy morale and set them into retreat) for success.

You'd also be able to keep track of moving or flying objectives that way.

56RAF_phoenix

Quote:
Originally Posted by wildwillie View Post
I've gotten a good part of the stats stuff done.

It now keeps tracks of Players and what they accomplish:

Shotdown of planes, Destroy ground Objects, damage other planes/ground Objects.

The questions I have is how should these be scored ?

In IL2 you got 100 pts/per engine for an aircraft shotdown.
30 pts for destroying a ground car, 60 pts for a tank, etc

And if you died you only got 10% of those points. If you bailed out you got 20 or 50% of those points.

I do not see Clod or Steam tracking points so the question is should we keep the same point scheme as IL2 ?


Question 2 -

How to tabulate who wins a mission ?

In FBDj/IL2 you had mission objectives either target based (x% of targets destroyed in a target circle), count based (xx number of tanks/cars/ships destroyed), pilot/planes counts or a combination of all of the above.

With Clod you can now add objectives within a mission and use triggers to see if the objective has been met. (I've not done this, but that is how I understand it)

for this new program should it be based on the mission triggers or the old way it was done in FBDj ?

RAF238thWildWillie
Reply With Quote
  #4  
Old 11-16-2011, 08:34 AM
SNAFU SNAFU is offline
Approved Member
 
Join Date: Feb 2011
Posts: 324
Default

Hi WildWillie,

I would be great if it would be possible to modify the points for the playerscore depending on the type of target, so have access to the variables, so you can fine-tune the scoring system depending on the scenario and we do not know what is to come in the next 10 years. For the mission objective, we already have the triggers needed, they only need to work correctly, so I would recomment to define certain trigger-names that would need to be set in the mission design (FMB) and would also be recognized by your system, f.e. I used to define triggers "ScoreRedXY" and "ScoreBlueZ" in which YX and Z are integers, which add to the total teams score with the trigger being activated. If ScoreRed >= A the Red Team has won if ScoreBlue >= B the Blue team has won.

Anyhow, you might face some problems with the trigger based on "GROUND UNITS DESTROYED", because static units are not easily to count with the script (AFAIK) and ships are not regarded as ground units in the FMB. Furthermoe the trigger "TPASS" with actor "PLAYER" does not work in the dedicated enviroment and many more anomalie between singleplayer and dedicated server enviroment.
Reply With Quote
  #5  
Old 11-16-2011, 09:36 AM
Ataros Ataros is offline
Approved Member
 
Join Date: Jun 2010
Location: USSR
Posts: 2,439
Default

Thank you for what you do!

Old Il-2 had an issue of kill stealing when the last who shot at an aircraft was credited a kill. The new CloD stat system is better because it allocates score proportionally to damage made which solves the stealing issue.

However as far as I understand there is an issue on the servers running AI removal scripts. When a script removes a slightly damaged plane hit by 1 bullet and safely landed at a friendly airfield it is considered as destroyed by the scoring system and a kill is allocated to the damager.

Pilot kill should have more weight in damage score imho as it is now. 40 to 50% of a kill should be added to attacker who made PK even if the plane was 60-80% damaged by other players. E.g. while unskilled pilots are wasting ammo on a He-111 a skilled pilot can make one pass and kill pilot that stops the bomber from hitting target.
Reply With Quote
  #6  
Old 11-16-2011, 01:15 PM
wildwillie wildwillie is offline
Approved Member
 
Join Date: Aug 2010
Posts: 111
Default

This will be an ongoing process and will take more than just my simple testing to work out all the details.

Right now I am using the OnActorDead method to determine kills. I'm hoping the damageScore.score will provide the appropriate allocation for the kill to each damage initiator. Since it has been just me doing all the killing during testing it will probably need some adjusting.

Also the OnAircraftCrashLanded method never seems to trigger. A few times when I have belly landed or wrecked my plane on landing it only triggers the OnAircraftLanded method.


The .mis file holds all the static objects which are easily tracked during a mission.

I will need some help with the Trigger stuff too.


As far as testing goes, I plan to have something ready the 1st week of December. I'm off for a week of hunting after Thanksgiving so nothing will get done then.

RAF238thWildWillie
Reply With Quote
  #7  
Old 11-16-2011, 02:09 PM
SNAFU SNAFU is offline
Approved Member
 
Join Date: Feb 2011
Posts: 324
Default

Did you manage to recognize static units with OnActorDead, that would be interesting. So far we only accounted for AI units with OnActorDead.

I also had problems with OnCrashLanded-Events but maybe you try landing in water, this is the only way I could reproduce a crash landing.

This is our scoring system (Kodiaks design and my interpretation ) so far, maybe you find it usefull, but is uncommented

Code:
 Dictionary<string, int> LWAvailableAirplanes = new Dictionary<string, int>()
    {
        //Internaltypename, Startcount
        {"bob:Aircraft.Bf-109E-3",60},
        {"bob:Aircraft.Bf-109E-3B",24},
        {"bob:Aircraft.Bf-109E-1",40},
        {"bob:Aircraft.Bf-109E-4",50},
        {"bob:Aircraft.Bf-109E-4B",24},
        {"bob:Aircraft.Bf-110C-4",24},
        {"bob:Aircraft.Bf-110C-7",24},
        {"bob:Aircraft.Ju-87B-2",60},
        {"bob:Aircraft.Ju-88A-1",40},
        {"bob:Aircraft.He-111H-2",60},
        {"bob:Aircraft.He-111P-2",20},
    };
    Dictionary<string, int> RAFAvailableAirplanes = new Dictionary<string, int>()
    {
        //Internaltypename, Startcount
        {"bob:Aircraft.SpitfireMkIa",30},
        {"bob:Aircraft.SpitfireMkI",60},
        {"bob:Aircraft.HurricaneMkI",50},
        {"bob:Aircraft.HurricaneMkI_dH5-20",50},
        {"bob:Aircraft.BlenheimMkIV",40},
        {"bob:Aircraft.SpitfireMkIIa",0},
    };


   Dictionary<AiGroundActorType,int> PointsforGroundTargets = new Dictionary<AiGroundActorType,int>()
    {
        {AiGroundActorType.AAGun, 2},
        {AiGroundActorType.AmmoComposition, 2},
        {AiGroundActorType.Amphibian, 2},
        {AiGroundActorType.ArmoredCar, 2},
        {AiGroundActorType.Artillery, 2},
        {AiGroundActorType.Balloon, 2},
        {AiGroundActorType.Bridge, 2},
        {AiGroundActorType.Bus, 2},
        {AiGroundActorType.Car, 2},
        {AiGroundActorType.ContainerLong, 2},
        {AiGroundActorType.ContainerShort, 2},
        {AiGroundActorType.EngineWagon, 2},
        {AiGroundActorType.FreightWagon, 2},
        {AiGroundActorType.Generator, 2},
        {AiGroundActorType.House, 2},
        {AiGroundActorType.LightTruck, 2},
        {AiGroundActorType.Listener, 2},
        {AiGroundActorType.Medic, 2},
        {AiGroundActorType.Motorcycle, 2},
        {AiGroundActorType.PassengerWagon, 2},
        {AiGroundActorType.Plane, 2},
        {AiGroundActorType.Predictor, 2},
        {AiGroundActorType.Radar, 2},
        {AiGroundActorType.RadioBeacon, 2},
        {AiGroundActorType.RadioBeamProjector, 2},
        {AiGroundActorType.SPG, 2},
        {AiGroundActorType.Tank, 2},
        {AiGroundActorType.Tractor, 2},
        {AiGroundActorType.Trailer, 2},
        {AiGroundActorType.Truck, 2},
        //Schiffe
        //{AiGroundActorType.ShipBattleship, 1},
        //{AiGroundActorType.ShipCarrier, 1},
        //{AiGroundActorType.ShipCruiser, 1},
        //{AiGroundActorType.ShipSubmarine, 1},
        {AiGroundActorType.ShipTransport, 25},
        {AiGroundActorType.ShipMisc,2},
        
        {AiGroundActorType.ShipDestroyer,50},
        {AiGroundActorType.ShipSmallWarship, 50},

        {AiGroundActorType.Unknown, 2}

    };

    Dictionary<string, int> PointsforAirTargets = new Dictionary<string, int>()
    {
        {"DiveBomber", 3},
        {"Bomber", 3},
        {"Bomber, DiveBomber",3},
        {"AmphibiousPlane", 3},
        {"TorpedoBomber", 3},
        {"Transport", 3},
        {"BNZFighter",1},
        {"Fighter",1},
        {"Glider",1},
        {"HeavyFighter",2},
        {"JaBo",1},
        {"SailPlane",1},
        {"Scout",1},
        {"Sturmovik",1},
        {"TNBFighter",1},
        {"UNKNOWN",1}
    };

 public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
    {
        base.OnActorDead(missionNumber, shortName, actor, damages);
		
		
if ((actor as AiGroundActor) != null && damages[0].initiator.Player != null)
            GamePlay.gpLogServer(null, "{0} was destroyed by {1}", new object[] { (actor as AiCart).InternalTypeName().Substring(4), (damages[0].initiator.Player.Name()) });
    	
        foreach (DamagerScore ds in damages)
        {
            int Addpoints = 0;
            int value;
            bool willReportDead = false;
            string TargetName = "";

            if (ds.initiator != null)
            {
                if (ds.initiator.Actor != null)
                {
                    if (actor.Army() != ds.initiator.Actor.Army())
                    {
                        if (actor is AiPerson) break; // At moment Pilotkills are not counted ;)

                        if (actor is AiAircraft)
                        {

							if (PointsforAirTargets.TryGetValue((actor as AiAircraft).Type().ToString(), out value)) // Erstetzt wegen Stukaproblem
                                Addpoints = PointsforAirTargets[(actor as AiAircraft).Type().ToString()];

                            TargetName = SplitName((actor as AiAircraft).InternalTypeName());

                            value = 0;
							if (actor.Army() == ArmyRed)
                                {
								BlueAirKills++;
                            if (RAFAvailableAirplanes.TryGetValue((actor as AiAircraft).InternalTypeName(), out value))
									{
								RAFAvailableAirplanes[(actor as AiAircraft).InternalTypeName()] = value - 1;
                                TargetName += " (" + RAFAvailableAirplanes[(actor as AiAircraft).InternalTypeName()].ToString() + " available)";  // Shows Counter for Planetype
									}
								}
							
							else if (actor.Army() == ArmyBlue)
								{
								RedAirKills++;
							if (LWAvailableAirplanes.TryGetValue((actor as AiAircraft).InternalTypeName(), out value))
									{
								LWAvailableAirplanes[(actor as AiAircraft).InternalTypeName()] = value - 1;
                                TargetName += " (" + LWAvailableAirplanes[(actor as AiAircraft).InternalTypeName()].ToString() + " available)";  // Shows Counter for Planetype
									}
								
								}
						}

                        if (actor is AiGroundActor)
                        {
                            if (PointsforGroundTargets.TryGetValue((actor as AiGroundActor).Type(), out value))
                                Addpoints = PointsforGroundTargets[(actor as AiGroundActor).Type()];

                            TargetName = SplitName((actor as AiGroundActor).InternalTypeName());
                        }

                        
                        willReportDead = true;

                        if (ds.initiator.Actor.Army() == ArmyBlue)
                        {
							BlueGrdKills++;
                            ScoreBlue += Addpoints;
							if (Addpoints <=0)
							{ScoreBlue += 3;}
                            GamePlay.gpLogServer(null, "Britisch {0} destroyed - Team scores now: RAF {1}- LW {2}", new object[] { TargetName, ScoreRed, ScoreBlue });
                            break;
                        }
                        else if (ds.initiator.Actor.Army() == ArmyRed)
                        {
							RedGrdKills++;
                            ScoreRed += Addpoints;
							if (Addpoints <=0)
							{ScoreRed += 3;}
                            GamePlay.gpLogServer(null, "German {0} destroyed - Team scores now: RAF {1}- LW {2}", new object[] { TargetName, ScoreRed, ScoreBlue });
                            break;
                        }
                    }
                }
            }
        }    
    }
Reply With Quote
  #8  
Old 11-16-2011, 02:15 PM
SNAFU SNAFU is offline
Approved Member
 
Join Date: Feb 2011
Posts: 324
Default

This was our solution for scores for triggered events. If the blue team should receive for example 50 points for a mission goal, I named the trigger "ScoreBlue50" and the following On Trigger Method added 50 points to the int ScoreBlue:

Code:
public override void OnTrigger(int missionNumber, string shortName, bool active) 
    {
       base.OnTrigger(missionNumber, shortName, active); 

  if (shortName.StartsWith("ScoreRed"))
        {
            StringBuilder b = new StringBuilder(shortName);
            string Number = b.Replace("ScoreRed", "").ToString();
            int Redresult = 0;

            if (int.TryParse(Number, out Redresult))
                ScoreRed += Redresult; 
  
            GamePlay.gpLogServer(null, "The RAF succesfully accomplished one objective: \nTeam scores - RAF {0}: LW {1}", new object[] {ScoreRed, ScoreBlue });
        }
		  if (shortName.StartsWith("ScoreBlue"))
        {
            StringBuilder b = new StringBuilder(shortName);
            string Number = b.Replace("ScoreBlue", "").ToString();
            int Blueresult = 0;

            if (int.TryParse(Number, out Blueresult))
                ScoreBlue += Blueresult; 
   
            GamePlay.gpLogServer(null, "The LW succesfully accomplished one objective: \nTeam scores - RAF {0}: LW {1}", new object[] {ScoreRed, ScoreBlue });
        }
}
Reply With Quote
  #9  
Old 11-16-2011, 02:23 PM
wildwillie wildwillie is offline
Approved Member
 
Join Date: Aug 2010
Posts: 111
Default

Yes the OnActorDead method picks up Static objects. Here is the line I pass from Clod to my program which identifies the Dead Ground Actor:

Code:
( 11/15/2011 4:01:27 PM ) New (STATS): DeadGA::1321390887075::0:Static24::1::bob:Artillery.3_inch_20_CWT_QF_Mk_I::AAGun::0:Static34::2::272406.84/200908.39
The "::" divides the data parts so it passes:
Event Type (DeadGA)
TimeStamp (In unix format)
Object Destroyed Name (0:Static24)
Object Destroyed Army (1)
Object Destroyed Model (The InternalTypedName )
Object Destroyed Type (AAGUN)
Destroyer (Who killed the object 0:Static34)
Destroyer Army (2)
Location of destroyed object (x/y)

The same goes for Chiefs and Planes. It still needs to be updated with the damage score value.

Thanks for the input. I think I will populate the objects in a database with their total available score there. That way it would be easier for Server Managers to adjust scoring without having to adjust code.

I've only crash landed on land. If I kill myself while doing this then the OnActorDead method gets called after about a million OnAircraftDamaged methods !


WildWillie
Reply With Quote
  #10  
Old 11-16-2011, 02:30 PM
SNAFU SNAFU is offline
Approved Member
 
Join Date: Feb 2011
Posts: 324
Default

Ok, interesting.

With static I meant "enviroment" types like static cars, tanks, planes in listed "Enviroment". Artillery-types are recognized, that`s why I had to rebuilt in all my missions the ground units to artillery types and that`s why I asked. Looking forward for your tool!
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 01:35 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright © 2007 Fulqrum Publishing. All rights reserved.