mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
commit
f536658639
@ -1,32 +1,32 @@
|
|||||||
rem Generate Moose_Embedded.lua
|
del Moose_Embedded.lua
|
||||||
|
|
||||||
copy /b ..\Moose\Routines.lua ^
|
echo env.info( 'Moose Embedded' ) > Moose_Embedded.lua
|
||||||
+ ..\Moose\Base.lua ^
|
|
||||||
+ ..\Moose\Event.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Routines.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Menu.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Base.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Group.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Event.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Unit.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Group.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Zone.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Unit.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Database.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Zone.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Cargo.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Database.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Client.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Scoring.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Message.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Cargo.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Stage.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Client.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Task.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Message.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\GoHomeTask.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Stage.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\DestroyBaseTask.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Task.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\DestroyGroupsTask.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\GoHomeTask.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\DestroyRadarsTask.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\DestroyBaseTask.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\DestroyUnitTypesTask.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\DestroyGroupsTask.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\PickupTask.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\DestroyRadarsTask.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\DeployTask.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\DestroyUnitTypesTask.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\NoTask.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\PickupTask.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\RouteTask.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\DeployTask.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Mission.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\NoTask.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\CleanUp.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\RouteTask.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Spawn.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Mission.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Movement.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\CleanUp.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Sead.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Spawn.lua Moose_Embedded.lua
|
||||||
+ ..\Moose\Escort.lua ^
|
copy /b Moose_Embedded.lua + ..\Moose\Movement.lua Moose_Embedded.lua
|
||||||
Moose_Embedded.lua /y
|
copy /b Moose_Embedded.lua + ..\Moose\Sead.lua Moose_Embedded.lua
|
||||||
|
copy /b Moose_Embedded.lua + ..\Moose\Escort.lua Moose_Embedded.lua
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
env.info( 'Moose Embedded' )
|
||||||
--- Various routines
|
--- Various routines
|
||||||
-- @module routines
|
-- @module routines
|
||||||
-- @author Flightcontrol
|
-- @author Flightcontrol
|
||||||
@ -3508,253 +3509,6 @@ end
|
|||||||
--- Declare the event dispatcher based on the EVENT class
|
--- Declare the event dispatcher based on the EVENT class
|
||||||
_EVENTDISPATCHER = EVENT:New() -- #EVENT
|
_EVENTDISPATCHER = EVENT:New() -- #EVENT
|
||||||
|
|
||||||
--- Encapsulation of DCS World Menu system in a set of MENU classes.
|
|
||||||
-- @module Menu
|
|
||||||
|
|
||||||
Include.File( "Routines" )
|
|
||||||
Include.File( "Base" )
|
|
||||||
|
|
||||||
--- The MENU class
|
|
||||||
-- @type MENU
|
|
||||||
-- @extends Base#BASE
|
|
||||||
MENU = {
|
|
||||||
ClassName = "MENU",
|
|
||||||
MenuPath = nil,
|
|
||||||
MenuText = "",
|
|
||||||
MenuParentPath = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
function MENU:New( MenuText, MenuParentPath )
|
|
||||||
|
|
||||||
-- Arrange meta tables
|
|
||||||
local Child = BASE:Inherit( self, BASE:New() )
|
|
||||||
|
|
||||||
Child.MenuPath = nil
|
|
||||||
Child.MenuText = MenuText
|
|
||||||
Child.MenuParentPath = MenuParentPath
|
|
||||||
return Child
|
|
||||||
end
|
|
||||||
|
|
||||||
--- The COMMANDMENU class
|
|
||||||
-- @type COMMANDMENU
|
|
||||||
-- @extends Menu#MENU
|
|
||||||
COMMANDMENU = {
|
|
||||||
ClassName = "COMMANDMENU",
|
|
||||||
CommandMenuFunction = nil,
|
|
||||||
CommandMenuArgument = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
function COMMANDMENU:New( MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument )
|
|
||||||
|
|
||||||
-- Arrange meta tables
|
|
||||||
|
|
||||||
local MenuParentPath = nil
|
|
||||||
if ParentMenu ~= nil then
|
|
||||||
MenuParentPath = ParentMenu.MenuPath
|
|
||||||
end
|
|
||||||
|
|
||||||
local Child = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
|
|
||||||
|
|
||||||
Child.MenuPath = missionCommands.addCommand( MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument )
|
|
||||||
Child.CommandMenuFunction = CommandMenuFunction
|
|
||||||
Child.CommandMenuArgument = CommandMenuArgument
|
|
||||||
return Child
|
|
||||||
end
|
|
||||||
|
|
||||||
--- The SUBMENU class
|
|
||||||
-- @type SUBMENU
|
|
||||||
-- @extends Menu#MENU
|
|
||||||
SUBMENU = {
|
|
||||||
ClassName = "SUBMENU"
|
|
||||||
}
|
|
||||||
|
|
||||||
function SUBMENU:New( MenuText, ParentMenu )
|
|
||||||
|
|
||||||
-- Arrange meta tables
|
|
||||||
local MenuParentPath = nil
|
|
||||||
if ParentMenu ~= nil then
|
|
||||||
MenuParentPath = ParentMenu.MenuPath
|
|
||||||
end
|
|
||||||
|
|
||||||
local Child = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
|
|
||||||
|
|
||||||
Child.MenuPath = missionCommands.addSubMenu( MenuText, MenuParentPath )
|
|
||||||
return Child
|
|
||||||
end
|
|
||||||
|
|
||||||
-- This local variable is used to cache the menus registered under clients.
|
|
||||||
-- Menus don't dissapear when clients are destroyed and restarted.
|
|
||||||
-- So every menu for a client created must be tracked so that program logic accidentally does not create
|
|
||||||
-- the same menus twice during initialization logic.
|
|
||||||
-- These menu classes are handling this logic with this variable.
|
|
||||||
local _MENUCLIENTS = {}
|
|
||||||
|
|
||||||
--- The MENU_CLIENT class
|
|
||||||
-- @type MENU_CLIENT
|
|
||||||
-- @extends Menu#MENU
|
|
||||||
MENU_CLIENT = {
|
|
||||||
ClassName = "MENU_CLIENT"
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Creates a new menu item for a group
|
|
||||||
-- @param self
|
|
||||||
-- @param Client#CLIENT MenuClient The Client owning the menu.
|
|
||||||
-- @param #string MenuText The text for the menu.
|
|
||||||
-- @param #table ParentMenu The parent menu.
|
|
||||||
-- @return #MENU_CLIENT self
|
|
||||||
function MENU_CLIENT:New( MenuClient, MenuText, ParentMenu )
|
|
||||||
|
|
||||||
-- Arrange meta tables
|
|
||||||
local MenuParentPath = {}
|
|
||||||
if ParentMenu ~= nil then
|
|
||||||
MenuParentPath = ParentMenu.MenuPath
|
|
||||||
end
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
|
|
||||||
self:F( { MenuClient, MenuText, ParentMenu } )
|
|
||||||
|
|
||||||
self.MenuClient = MenuClient
|
|
||||||
self.MenuClientGroupID = MenuClient:GetClientGroupID()
|
|
||||||
self.MenuParentPath = MenuParentPath
|
|
||||||
self.MenuText = MenuText
|
|
||||||
self.ParentMenu = ParentMenu
|
|
||||||
|
|
||||||
self.Menus = {}
|
|
||||||
|
|
||||||
if not _MENUCLIENTS[self.MenuClientGroupID] then
|
|
||||||
_MENUCLIENTS[self.MenuClientGroupID] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
|
|
||||||
|
|
||||||
self:T( { MenuClient:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText } )
|
|
||||||
|
|
||||||
local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText
|
|
||||||
if MenuPath[MenuPathID] then
|
|
||||||
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] )
|
|
||||||
end
|
|
||||||
|
|
||||||
self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath )
|
|
||||||
MenuPath[MenuPathID] = self.MenuPath
|
|
||||||
|
|
||||||
self:T( { MenuClient:GetClientGroupName(), self.MenuPath } )
|
|
||||||
|
|
||||||
if ParentMenu and ParentMenu.Menus then
|
|
||||||
ParentMenu.Menus[self.MenuPath] = self
|
|
||||||
end
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Removes the sub menus recursively of this MENU_CLIENT.
|
|
||||||
-- @param #MENU_CLIENT self
|
|
||||||
-- @return #MENU_CLIENT self
|
|
||||||
function MENU_CLIENT:RemoveSubMenus()
|
|
||||||
self:F( self.MenuPath )
|
|
||||||
|
|
||||||
for MenuID, Menu in pairs( self.Menus ) do
|
|
||||||
Menu:Remove()
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Removes the sub menus recursively of this MENU_CLIENT.
|
|
||||||
-- @param #MENU_CLIENT self
|
|
||||||
-- @return #MENU_CLIENT self
|
|
||||||
function MENU_CLIENT:Remove()
|
|
||||||
self:F( self.MenuPath )
|
|
||||||
|
|
||||||
self:RemoveSubMenus()
|
|
||||||
|
|
||||||
if not _MENUCLIENTS[self.MenuClientGroupID] then
|
|
||||||
_MENUCLIENTS[self.MenuClientGroupID] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
|
|
||||||
|
|
||||||
if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then
|
|
||||||
MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath )
|
|
||||||
self.ParentMenu.Menus[self.MenuPath] = nil
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- The MENU_CLIENT_COMMAND class
|
|
||||||
-- @type MENU_CLIENT_COMMAND
|
|
||||||
-- @extends Menu#MENU
|
|
||||||
MENU_CLIENT_COMMAND = {
|
|
||||||
ClassName = "MENU_CLIENT_COMMAND"
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Creates a new radio command item for a group
|
|
||||||
-- @param self
|
|
||||||
-- @param Client#CLIENT MenuClient The Client owning the menu.
|
|
||||||
-- @param MenuText The text for the menu.
|
|
||||||
-- @param ParentMenu The parent menu.
|
|
||||||
-- @param CommandMenuFunction A function that is called when the menu key is pressed.
|
|
||||||
-- @param CommandMenuArgument An argument for the function.
|
|
||||||
-- @return Menu#MENU_CLIENT_COMMAND self
|
|
||||||
function MENU_CLIENT_COMMAND:New( MenuClient, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument )
|
|
||||||
|
|
||||||
-- Arrange meta tables
|
|
||||||
|
|
||||||
local MenuParentPath = {}
|
|
||||||
if ParentMenu ~= nil then
|
|
||||||
MenuParentPath = ParentMenu.MenuPath
|
|
||||||
end
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
|
|
||||||
|
|
||||||
self.MenuClient = MenuClient
|
|
||||||
self.MenuClientGroupID = MenuClient:GetClientGroupID()
|
|
||||||
self.MenuParentPath = MenuParentPath
|
|
||||||
self.MenuText = MenuText
|
|
||||||
self.ParentMenu = ParentMenu
|
|
||||||
|
|
||||||
if not _MENUCLIENTS[self.MenuClientGroupID] then
|
|
||||||
_MENUCLIENTS[self.MenuClientGroupID] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
|
|
||||||
|
|
||||||
self:T( { MenuClient:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText, CommandMenuFunction, CommandMenuArgument } )
|
|
||||||
|
|
||||||
local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText
|
|
||||||
if MenuPath[MenuPathID] then
|
|
||||||
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] )
|
|
||||||
end
|
|
||||||
|
|
||||||
self.MenuPath = missionCommands.addCommandForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument )
|
|
||||||
MenuPath[MenuPathID] = self.MenuPath
|
|
||||||
|
|
||||||
self.CommandMenuFunction = CommandMenuFunction
|
|
||||||
self.CommandMenuArgument = CommandMenuArgument
|
|
||||||
|
|
||||||
ParentMenu.Menus[self.MenuPath] = self
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
function MENU_CLIENT_COMMAND:Remove()
|
|
||||||
self:F( self.MenuPath )
|
|
||||||
|
|
||||||
if not _MENUCLIENTS[self.MenuClientGroupID] then
|
|
||||||
_MENUCLIENTS[self.MenuClientGroupID] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
|
|
||||||
|
|
||||||
if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then
|
|
||||||
MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath )
|
|
||||||
self.ParentMenu.Menus[self.MenuPath] = nil
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
--- A GROUP class abstraction of a DCSGroup class.
|
--- A GROUP class abstraction of a DCSGroup class.
|
||||||
-- The GROUP class will take an abstraction of the DCSGroup class, providing more methods that can be done with a GROUP.
|
-- The GROUP class will take an abstraction of the DCSGroup class, providing more methods that can be done with a GROUP.
|
||||||
-- @module Group
|
-- @module Group
|
||||||
@ -5599,15 +5353,6 @@ function DATABASE:New()
|
|||||||
end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then
|
end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then
|
||||||
end --for coa_name, coa_data in pairs(mission.coalition) do
|
end --for coa_name, coa_data in pairs(mission.coalition) do
|
||||||
|
|
||||||
--self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth )
|
|
||||||
_EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self )
|
|
||||||
_EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self )
|
|
||||||
_EVENTDISPATCHER:OnHit( self._EventOnHit, self )
|
|
||||||
|
|
||||||
self.SchedulerId = routines.scheduleFunction( DATABASE._FollowPlayers, { self }, 0, 5 )
|
|
||||||
|
|
||||||
self:ScoreMenu()
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -5663,11 +5408,6 @@ function DATABASE:GetStatusGroup( GroupName )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Private
|
|
||||||
-- @section Private
|
|
||||||
|
|
||||||
|
|
||||||
--- Registers new Group Templates within the DATABASE Object.
|
--- Registers new Group Templates within the DATABASE Object.
|
||||||
function DATABASE:_RegisterGroup( GroupTemplate )
|
function DATABASE:_RegisterGroup( GroupTemplate )
|
||||||
|
|
||||||
@ -5702,15 +5442,115 @@ function DATABASE:_RegisterGroup( GroupTemplate )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
_Database = DATABASE:New() -- Database#DATABASE
|
||||||
--- Events
|
|
||||||
-- @section Events
|
|
||||||
|
|
||||||
|
|
||||||
--- Track DCSRTE DEAD or CRASH events for the internal scoring.
|
--- Scoring system for MOOSE.
|
||||||
-- @param #DATABASE self
|
-- This scoring class calculates the hits and kills that players make within a simulation session.
|
||||||
|
-- Scoring is calculated using a defined algorithm.
|
||||||
|
-- With a small change in MissionScripting.lua, the scoring can also be logged in a CSV file, that can then be uploaded
|
||||||
|
-- to a database or a BI tool to publish the scoring results to the player community.
|
||||||
|
-- @module Scoring
|
||||||
|
-- @author FlightControl
|
||||||
|
|
||||||
|
|
||||||
|
Include.File( "Routines" )
|
||||||
|
Include.File( "Base" )
|
||||||
|
Include.File( "Menu" )
|
||||||
|
Include.File( "Group" )
|
||||||
|
Include.File( "Event" )
|
||||||
|
|
||||||
|
|
||||||
|
--- The Scoring class
|
||||||
|
-- @type SCORING
|
||||||
|
-- @field Players A collection of the current players that have joined the game.
|
||||||
|
-- @extends Base#BASE
|
||||||
|
SCORING = {
|
||||||
|
ClassName = "SCORING",
|
||||||
|
ClassID = 0,
|
||||||
|
Players = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
local _SCORINGCoalition =
|
||||||
|
{
|
||||||
|
[1] = "Red",
|
||||||
|
[2] = "Blue",
|
||||||
|
}
|
||||||
|
|
||||||
|
local _SCORINGCategory =
|
||||||
|
{
|
||||||
|
[Unit.Category.AIRPLANE] = "Plane",
|
||||||
|
[Unit.Category.HELICOPTER] = "Helicopter",
|
||||||
|
[Unit.Category.GROUND_UNIT] = "Vehicle",
|
||||||
|
[Unit.Category.SHIP] = "Ship",
|
||||||
|
[Unit.Category.STRUCTURE] = "Structure",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Creates a new SCORING object to administer the scoring achieved by players.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param #string GameName The name of the game. This name is also logged in the CSV score file.
|
||||||
|
-- @return #SCORING self
|
||||||
|
-- @usage
|
||||||
|
-- -- Define a new scoring object for the mission Gori Valley.
|
||||||
|
-- ScoringObject = SCORING:New( "Gori Valley" )
|
||||||
|
function SCORING:New( GameName )
|
||||||
|
|
||||||
|
-- Inherits from BASE
|
||||||
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
|
||||||
|
if GameName then
|
||||||
|
self.GameName = GameName
|
||||||
|
else
|
||||||
|
error( "A game name must be given to register the scoring results" )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
_EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self )
|
||||||
|
_EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self )
|
||||||
|
_EVENTDISPATCHER:OnHit( self._EventOnHit, self )
|
||||||
|
|
||||||
|
self.SchedulerId = routines.scheduleFunction( SCORING._FollowPlayersScheduled, { self }, 0, 5 )
|
||||||
|
|
||||||
|
self:ScoreMenu()
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creates a score radio menu. Can be accessed using Radio -> F10.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @return #SCORING self
|
||||||
|
function SCORING:ScoreMenu()
|
||||||
|
self.Menu = SUBMENU:New( 'Scoring' )
|
||||||
|
self.AllScoresMenu = COMMANDMENU:New( 'Score All Active Players', self.Menu, SCORING.ReportScoreAll, self )
|
||||||
|
--- = COMMANDMENU:New('Your Current Score', ReportScore, SCORING.ReportScorePlayer, self )
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Follows new players entering Clients within the DCSRTE.
|
||||||
|
-- TODO: Need to see if i can catch this also with an event. It will eliminate the schedule ...
|
||||||
|
function SCORING:_FollowPlayersScheduled()
|
||||||
|
self:F3( "_FollowPlayersScheduled" )
|
||||||
|
|
||||||
|
local ClientUnit = 0
|
||||||
|
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers(coalition.side.RED), AlivePlayersBlue = coalition.getPlayers(coalition.side.BLUE) }
|
||||||
|
local unitId
|
||||||
|
local unitData
|
||||||
|
local AlivePlayerUnits = {}
|
||||||
|
|
||||||
|
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||||
|
self:T3( { "_FollowPlayersScheduled", CoalitionData } )
|
||||||
|
for UnitId, UnitData in pairs( CoalitionData ) do
|
||||||
|
self:_AddPlayerFromUnit( UnitData )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Track DEAD or CRASH events for the scoring.
|
||||||
|
-- @param #SCORING self
|
||||||
-- @param Event#EVENTDATA Event
|
-- @param Event#EVENTDATA Event
|
||||||
function DATABASE:_EventOnDeadOrCrash( Event )
|
function SCORING:_EventOnDeadOrCrash( Event )
|
||||||
self:F( { Event } )
|
self:F( { Event } )
|
||||||
|
|
||||||
local TargetUnit = nil
|
local TargetUnit = nil
|
||||||
@ -5738,8 +5578,8 @@ function DATABASE:_EventOnDeadOrCrash( Event )
|
|||||||
TargetCategory = TargetUnit:getDesc().category -- Workaround
|
TargetCategory = TargetUnit:getDesc().category -- Workaround
|
||||||
TargetType = TargetUnit:getTypeName()
|
TargetType = TargetUnit:getTypeName()
|
||||||
|
|
||||||
TargetUnitCoalition = _DATABASECoalition[TargetCoalition]
|
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
||||||
TargetUnitCategory = _DATABASECategory[T1argetCategory]
|
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
||||||
TargetUnitType = TargetType
|
TargetUnitType = TargetType
|
||||||
|
|
||||||
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } )
|
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } )
|
||||||
@ -5754,8 +5594,8 @@ function DATABASE:_EventOnDeadOrCrash( Event )
|
|||||||
local InitUnitType = PlayerData.UnitType
|
local InitUnitType = PlayerData.UnitType
|
||||||
local InitCoalition = PlayerData.UnitCoalition
|
local InitCoalition = PlayerData.UnitCoalition
|
||||||
local InitCategory = PlayerData.UnitCategory
|
local InitCategory = PlayerData.UnitCategory
|
||||||
local InitUnitCoalition = _DATABASECoalition[InitCoalition]
|
local InitUnitCoalition = _SCORINGCoalition[InitCoalition]
|
||||||
local InitUnitCategory = _DATABASECategory[InitCategory]
|
local InitUnitCategory = _SCORINGCategory[InitCategory]
|
||||||
|
|
||||||
self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } )
|
self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } )
|
||||||
|
|
||||||
@ -5781,7 +5621,7 @@ function DATABASE:_EventOnDeadOrCrash( Event )
|
|||||||
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Penalty: -" .. PlayerData.Kill[TargetCategory][TargetType].Penalty ..
|
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Penalty: -" .. PlayerData.Kill[TargetCategory][TargetType].Penalty ..
|
||||||
". Score Total:" .. PlayerData.Score - PlayerData.Penalty,
|
". Score Total:" .. PlayerData.Score - PlayerData.Penalty,
|
||||||
"", 5, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
"", 5, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
||||||
self:ScoreAdd( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
self:ScoreCSV( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
else
|
else
|
||||||
PlayerData.Score = PlayerData.Score + 10
|
PlayerData.Score = PlayerData.Score + 10
|
||||||
PlayerData.Kill[TargetCategory][TargetType].Score = PlayerData.Kill[TargetCategory][TargetType].Score + 10
|
PlayerData.Kill[TargetCategory][TargetType].Score = PlayerData.Kill[TargetCategory][TargetType].Score + 10
|
||||||
@ -5790,7 +5630,7 @@ function DATABASE:_EventOnDeadOrCrash( Event )
|
|||||||
PlayerData.Kill[TargetCategory][TargetType].ScoreKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Score ..
|
PlayerData.Kill[TargetCategory][TargetType].ScoreKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Score ..
|
||||||
". Score Total:" .. PlayerData.Score - PlayerData.Penalty,
|
". Score Total:" .. PlayerData.Score - PlayerData.Penalty,
|
||||||
"", 5, "/SCORE" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
"", 5, "/SCORE" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
||||||
self:ScoreAdd( PlayerName, "KILL_SCORE", 1, 10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
self:ScoreCSV( PlayerName, "KILL_SCORE", 1, 10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -5799,35 +5639,9 @@ function DATABASE:_EventOnDeadOrCrash( Event )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Scheduled
|
|
||||||
-- @section Scheduled
|
|
||||||
|
|
||||||
|
|
||||||
--- Follows new players entering Clients within the DCSRTE.
|
|
||||||
function DATABASE:_FollowPlayers()
|
|
||||||
self:F3( "_FollowPlayers" )
|
|
||||||
|
|
||||||
local ClientUnit = 0
|
|
||||||
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers(coalition.side.RED), AlivePlayersBlue = coalition.getPlayers(coalition.side.BLUE) }
|
|
||||||
local unitId
|
|
||||||
local unitData
|
|
||||||
local AlivePlayerUnits = {}
|
|
||||||
|
|
||||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
|
||||||
self:T3( { "_FollowPlayers", CoalitionData } )
|
|
||||||
for UnitId, UnitData in pairs( CoalitionData ) do
|
|
||||||
self:_AddPlayerFromUnit( UnitData )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Private
|
|
||||||
-- @section Private
|
|
||||||
|
|
||||||
|
|
||||||
--- Add a new player entering a Unit.
|
--- Add a new player entering a Unit.
|
||||||
function DATABASE:_AddPlayerFromUnit( UnitData )
|
function SCORING:_AddPlayerFromUnit( UnitData )
|
||||||
self:F( UnitData )
|
self:F( UnitData )
|
||||||
|
|
||||||
if UnitData:isExist() then
|
if UnitData:isExist() then
|
||||||
@ -5846,7 +5660,7 @@ function DATABASE:_AddPlayerFromUnit( UnitData )
|
|||||||
self.Players[PlayerName].Kill = {}
|
self.Players[PlayerName].Kill = {}
|
||||||
self.Players[PlayerName].Mission = {}
|
self.Players[PlayerName].Mission = {}
|
||||||
|
|
||||||
-- for CategoryID, CategoryName in pairs( DATABASECategory ) do
|
-- for CategoryID, CategoryName in pairs( SCORINGCategory ) do
|
||||||
-- self.Players[PlayerName].Hit[CategoryID] = {}
|
-- self.Players[PlayerName].Hit[CategoryID] = {}
|
||||||
-- self.Players[PlayerName].Kill[CategoryID] = {}
|
-- self.Players[PlayerName].Kill[CategoryID] = {}
|
||||||
-- end
|
-- end
|
||||||
@ -5864,14 +5678,14 @@ function DATABASE:_AddPlayerFromUnit( UnitData )
|
|||||||
if self.Players[PlayerName].UnitCoalition ~= UnitCoalition then
|
if self.Players[PlayerName].UnitCoalition ~= UnitCoalition then
|
||||||
self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50
|
self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50
|
||||||
self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1
|
self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1
|
||||||
MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. _DATABASECoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _DATABASECoalition[UnitCoalition] ..
|
MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. _SCORINGCoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _SCORINGCoalition[UnitCoalition] ..
|
||||||
"(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.",
|
"(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.",
|
||||||
"",
|
"",
|
||||||
2,
|
2,
|
||||||
"/PENALTYCOALITION" .. PlayerName
|
"/PENALTYCOALITION" .. PlayerName
|
||||||
):ToAll()
|
):ToAll()
|
||||||
self:ScoreAdd( PlayerName, "COALITION_PENALTY", 1, -50, self.Players[PlayerName].UnitName, _DATABASECoalition[self.Players[PlayerName].UnitCoalition], _DATABASECategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType,
|
self:ScoreCSV( PlayerName, "COALITION_PENALTY", 1, -50, self.Players[PlayerName].UnitName, _SCORINGCoalition[self.Players[PlayerName].UnitCoalition], _SCORINGCategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType,
|
||||||
UnitName, _DATABASECoalition[UnitCoalition], _DATABASECategory[UnitCategory], UnitData:getTypeName() )
|
UnitName, _SCORINGCoalition[UnitCoalition], _SCORINGCategory[UnitCategory], UnitData:getTypeName() )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.Players[PlayerName].UnitName = UnitName
|
self.Players[PlayerName].UnitName = UnitName
|
||||||
@ -5905,7 +5719,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
--- Registers Scores the players completing a Mission Task.
|
--- Registers Scores the players completing a Mission Task.
|
||||||
function DATABASE:_AddMissionTaskScore( PlayerUnit, MissionName, Score )
|
function SCORING:_AddMissionTaskScore( PlayerUnit, MissionName, Score )
|
||||||
self:F( { PlayerUnit, MissionName, Score } )
|
self:F( { PlayerUnit, MissionName, Score } )
|
||||||
|
|
||||||
local PlayerName = PlayerUnit:getPlayerName()
|
local PlayerName = PlayerUnit:getPlayerName()
|
||||||
@ -5926,13 +5740,13 @@ function DATABASE:_AddMissionTaskScore( PlayerUnit, MissionName, Score )
|
|||||||
Score .. " Score points added.",
|
Score .. " Score points added.",
|
||||||
"", 20, "/SCORETASK" .. PlayerName ):ToAll()
|
"", 20, "/SCORETASK" .. PlayerName ):ToAll()
|
||||||
|
|
||||||
_Database:ScoreAdd( PlayerName, "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:getName() )
|
self:ScoreCSV( PlayerName, "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:getName() )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Registers Mission Scores for possible multiple players that contributed in the Mission.
|
--- Registers Mission Scores for possible multiple players that contributed in the Mission.
|
||||||
function DATABASE:_AddMissionScore( MissionName, Score )
|
function SCORING:_AddMissionScore( MissionName, Score )
|
||||||
self:F( { PlayerUnit, MissionName, Score } )
|
self:F( { MissionName, Score } )
|
||||||
|
|
||||||
for PlayerName, PlayerData in pairs( self.Players ) do
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
||||||
|
|
||||||
@ -5942,20 +5756,15 @@ function DATABASE:_AddMissionScore( MissionName, Score )
|
|||||||
MESSAGE:New( "Player '" .. PlayerName .. "' has finished Mission '" .. MissionName .. "'. " ..
|
MESSAGE:New( "Player '" .. PlayerName .. "' has finished Mission '" .. MissionName .. "'. " ..
|
||||||
Score .. " Score points added.",
|
Score .. " Score points added.",
|
||||||
"", 20, "/SCOREMISSION" .. PlayerName ):ToAll()
|
"", 20, "/SCOREMISSION" .. PlayerName ):ToAll()
|
||||||
_Database:ScoreAdd( PlayerName, "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score )
|
self:ScoreCSV( PlayerName, "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Events
|
|
||||||
-- @section Events
|
|
||||||
|
|
||||||
|
|
||||||
--- Handles the OnHit event for the scoring.
|
--- Handles the OnHit event for the scoring.
|
||||||
-- @param #DATABASE self
|
-- @param #SCORING self
|
||||||
-- @param Event#EVENTDATA Event
|
-- @param Event#EVENTDATA Event
|
||||||
function DATABASE:_EventOnHit( Event )
|
function SCORING:_EventOnHit( Event )
|
||||||
self:F( { Event } )
|
self:F( { Event } )
|
||||||
|
|
||||||
local InitUnit = nil
|
local InitUnit = nil
|
||||||
@ -5998,8 +5807,8 @@ function DATABASE:_EventOnHit( Event )
|
|||||||
InitCategory = InitUnit:getDesc().category
|
InitCategory = InitUnit:getDesc().category
|
||||||
InitType = InitUnit:getTypeName()
|
InitType = InitUnit:getTypeName()
|
||||||
|
|
||||||
InitUnitCoalition = _DATABASECoalition[InitCoalition]
|
InitUnitCoalition = _SCORINGCoalition[InitCoalition]
|
||||||
InitUnitCategory = _DATABASECategory[InitCategory]
|
InitUnitCategory = _SCORINGCategory[InitCategory]
|
||||||
InitUnitType = InitType
|
InitUnitType = InitType
|
||||||
|
|
||||||
self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType , InitUnitCoalition, InitUnitCategory, InitUnitType } )
|
self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType , InitUnitCoalition, InitUnitCategory, InitUnitType } )
|
||||||
@ -6020,8 +5829,8 @@ function DATABASE:_EventOnHit( Event )
|
|||||||
TargetCategory = TargetUnit:getDesc().category
|
TargetCategory = TargetUnit:getDesc().category
|
||||||
TargetType = TargetUnit:getTypeName()
|
TargetType = TargetUnit:getTypeName()
|
||||||
|
|
||||||
TargetUnitCoalition = _DATABASECoalition[TargetCoalition]
|
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
||||||
TargetUnitCategory = _DATABASECategory[TargetCategory]
|
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
||||||
TargetUnitType = TargetType
|
TargetUnitType = TargetType
|
||||||
|
|
||||||
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } )
|
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } )
|
||||||
@ -6060,7 +5869,7 @@ function DATABASE:_EventOnHit( Event )
|
|||||||
2,
|
2,
|
||||||
"/PENALTY" .. InitPlayerName .. "/" .. InitUnitName
|
"/PENALTY" .. InitPlayerName .. "/" .. InitUnitName
|
||||||
):ToAll()
|
):ToAll()
|
||||||
self:ScoreAdd( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
self:ScoreCSV( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
else
|
else
|
||||||
self.Players[InitPlayerName].Score = self.Players[InitPlayerName].Score + 10
|
self.Players[InitPlayerName].Score = self.Players[InitPlayerName].Score + 10
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score + 1
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score + 1
|
||||||
@ -6072,7 +5881,7 @@ function DATABASE:_EventOnHit( Event )
|
|||||||
2,
|
2,
|
||||||
"/SCORE" .. InitPlayerName .. "/" .. InitUnitName
|
"/SCORE" .. InitPlayerName .. "/" .. InitUnitName
|
||||||
):ToAll()
|
):ToAll()
|
||||||
self:ScoreAdd( InitPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
self:ScoreCSV( InitPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -6082,7 +5891,7 @@ function DATABASE:_EventOnHit( Event )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ReportScoreAll()
|
function SCORING:ReportScoreAll()
|
||||||
|
|
||||||
env.info( "Hello World " )
|
env.info( "Hello World " )
|
||||||
|
|
||||||
@ -6096,8 +5905,8 @@ function DATABASE:ReportScoreAll()
|
|||||||
self:T( "Score Player: " .. PlayerName )
|
self:T( "Score Player: " .. PlayerName )
|
||||||
|
|
||||||
-- Some variables
|
-- Some variables
|
||||||
local InitUnitCoalition = _DATABASECoalition[PlayerData.UnitCoalition]
|
local InitUnitCoalition = _SCORINGCoalition[PlayerData.UnitCoalition]
|
||||||
local InitUnitCategory = _DATABASECategory[PlayerData.UnitCategory]
|
local InitUnitCategory = _SCORINGCategory[PlayerData.UnitCategory]
|
||||||
local InitUnitType = PlayerData.UnitType
|
local InitUnitType = PlayerData.UnitType
|
||||||
local InitUnitName = PlayerData.UnitName
|
local InitUnitName = PlayerData.UnitName
|
||||||
|
|
||||||
@ -6108,7 +5917,7 @@ function DATABASE:ReportScoreAll()
|
|||||||
|
|
||||||
local ScoreMessageHits = ""
|
local ScoreMessageHits = ""
|
||||||
|
|
||||||
for CategoryID, CategoryName in pairs( _DATABASECategory ) do
|
for CategoryID, CategoryName in pairs( _SCORINGCategory ) do
|
||||||
self:T( CategoryName )
|
self:T( CategoryName )
|
||||||
if PlayerData.Hit[CategoryID] then
|
if PlayerData.Hit[CategoryID] then
|
||||||
local Score = 0
|
local Score = 0
|
||||||
@ -6136,7 +5945,7 @@ function DATABASE:ReportScoreAll()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local ScoreMessageKills = ""
|
local ScoreMessageKills = ""
|
||||||
for CategoryID, CategoryName in pairs( _DATABASECategory ) do
|
for CategoryID, CategoryName in pairs( _SCORINGCategory ) do
|
||||||
self:T( "Kill scores exist for player " .. PlayerName )
|
self:T( "Kill scores exist for player " .. PlayerName )
|
||||||
if PlayerData.Kill[CategoryID] then
|
if PlayerData.Kill[CategoryID] then
|
||||||
local Score = 0
|
local Score = 0
|
||||||
@ -6195,7 +6004,7 @@ function DATABASE:ReportScoreAll()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ReportScorePlayer()
|
function SCORING:ReportScorePlayer()
|
||||||
|
|
||||||
env.info( "Hello World " )
|
env.info( "Hello World " )
|
||||||
|
|
||||||
@ -6209,8 +6018,8 @@ function DATABASE:ReportScorePlayer()
|
|||||||
self:T( "Score Player: " .. PlayerName )
|
self:T( "Score Player: " .. PlayerName )
|
||||||
|
|
||||||
-- Some variables
|
-- Some variables
|
||||||
local InitUnitCoalition = _DATABASECoalition[PlayerData.UnitCoalition]
|
local InitUnitCoalition = _SCORINGCoalition[PlayerData.UnitCoalition]
|
||||||
local InitUnitCategory = _DATABASECategory[PlayerData.UnitCategory]
|
local InitUnitCategory = _SCORINGCategory[PlayerData.UnitCategory]
|
||||||
local InitUnitType = PlayerData.UnitType
|
local InitUnitType = PlayerData.UnitType
|
||||||
local InitUnitName = PlayerData.UnitName
|
local InitUnitName = PlayerData.UnitName
|
||||||
|
|
||||||
@ -6221,7 +6030,7 @@ function DATABASE:ReportScorePlayer()
|
|||||||
|
|
||||||
local ScoreMessageHits = ""
|
local ScoreMessageHits = ""
|
||||||
|
|
||||||
for CategoryID, CategoryName in pairs( _DATABASECategory ) do
|
for CategoryID, CategoryName in pairs( _SCORINGCategory ) do
|
||||||
self:T( CategoryName )
|
self:T( CategoryName )
|
||||||
if PlayerData.Hit[CategoryID] then
|
if PlayerData.Hit[CategoryID] then
|
||||||
local Score = 0
|
local Score = 0
|
||||||
@ -6249,7 +6058,7 @@ function DATABASE:ReportScorePlayer()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local ScoreMessageKills = ""
|
local ScoreMessageKills = ""
|
||||||
for CategoryID, CategoryName in pairs( _DATABASECategory ) do
|
for CategoryID, CategoryName in pairs( _SCORINGCategory ) do
|
||||||
self:T( "Kill scores exist for player " .. PlayerName )
|
self:T( "Kill scores exist for player " .. PlayerName )
|
||||||
if PlayerData.Kill[CategoryID] then
|
if PlayerData.Kill[CategoryID] then
|
||||||
local Score = 0
|
local Score = 0
|
||||||
@ -6309,18 +6118,7 @@ function DATABASE:ReportScorePlayer()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ScoreMenu()
|
function SCORING:SecondsToClock(sSeconds)
|
||||||
local ReportScore = SUBMENU:New( 'Scoring' )
|
|
||||||
local ReportAllScores = COMMANDMENU:New( 'Score All Active Players', ReportScore, DATABASE.ReportScoreAll, self )
|
|
||||||
local ReportPlayerScores = COMMANDMENU:New('Your Current Score', ReportScore, DATABASE.ReportScorePlayer, self )
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- File Logic for tracking the scores
|
|
||||||
|
|
||||||
function DATABASE:SecondsToClock(sSeconds)
|
|
||||||
local nSeconds = sSeconds
|
local nSeconds = sSeconds
|
||||||
if nSeconds == 0 then
|
if nSeconds == 0 then
|
||||||
--return nil;
|
--return nil;
|
||||||
@ -6333,24 +6131,58 @@ function DATABASE:SecondsToClock(sSeconds)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Opens a score CSV file to log the scores.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param #string ScoringCSV
|
||||||
|
-- @return #SCORING self
|
||||||
|
-- @usage
|
||||||
|
-- -- Open a new CSV file to log the scores of the game Gori Valley. Let the name of the CSV file begin with "Player Scores".
|
||||||
|
-- ScoringObject = SCORING:New( "Gori Valley" )
|
||||||
|
-- ScoringObject:OpenCSV( "Player Scores" )
|
||||||
|
function SCORING:OpenCSV( ScoringCSV )
|
||||||
|
self:F( ScoringCSV )
|
||||||
|
|
||||||
|
if lfs and io and os then
|
||||||
|
if ScoringCSV then
|
||||||
|
self.ScoringCSV = ScoringCSV
|
||||||
|
local fdir = lfs.writedir() .. [[Logs\]] .. self.ScoringCSV .. " " .. os.date( "%Y-%m-%d %H-%M-%S" ) .. ".csv"
|
||||||
|
|
||||||
function DATABASE:ScoreOpen()
|
self.CSVFile, self.err = io.open( fdir, "w+" )
|
||||||
if lfs then
|
if not self.CSVFile then
|
||||||
local fdir = lfs.writedir() .. [[Logs\]] .. "Player_Scores_" .. os.date( "%Y-%m-%d_%H-%M-%S" ) .. ".csv"
|
error( "Error: Cannot open CSV file in " .. lfs.writedir() )
|
||||||
self.StatFile, self.err = io.open(fdir,"w+")
|
end
|
||||||
if not self.StatFile then
|
|
||||||
error( "Error: Cannot open 'Player Scores.csv' file in " .. lfs.writedir() )
|
self.CSVFile:write( '"GameName","RunTime","Time","PlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition","TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n' )
|
||||||
|
|
||||||
|
self.RunTime = os.date("%y-%m-%d_%H-%M-%S")
|
||||||
|
else
|
||||||
|
error( "A string containing the CSV file name must be given." )
|
||||||
end
|
end
|
||||||
self.StatFile:write( '"RunID","Time","PlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition","TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n' )
|
else
|
||||||
|
self:E( "The MissionScripting.lua file has not been changed to allow lfs, io and os modules to be used..." )
|
||||||
self.RunID = os.date("%y-%m-%d_%H-%M-%S")
|
|
||||||
end
|
end
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
--- Registers a score for a player.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param #string PlayerName The name of the player.
|
||||||
|
-- @param #string ScoreType The type of the score.
|
||||||
|
-- @param #string ScoreTimes The amount of scores achieved.
|
||||||
|
-- @param #string ScoreAmount The score given.
|
||||||
|
-- @param #string PlayerUnitName The unit name of the player.
|
||||||
|
-- @param #string PlayerUnitCoalition The coalition of the player unit.
|
||||||
|
-- @param #string PlayerUnitCategory The category of the player unit.
|
||||||
|
-- @param #string PlayerUnitType The type of the player unit.
|
||||||
|
-- @param #string TargetUnitName The name of the target unit.
|
||||||
|
-- @param #string TargetUnitCoalition The coalition of the target unit.
|
||||||
|
-- @param #string TargetUnitCategory The category of the target unit.
|
||||||
|
-- @param #string TargetUnitType The type of the target unit.
|
||||||
|
-- @return #SCORING self
|
||||||
|
function SCORING:ScoreCSV( PlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
--write statistic information to file
|
--write statistic information to file
|
||||||
local ScoreTime = self:SecondsToClock(timer.getTime())
|
local ScoreTime = self:SecondsToClock( timer.getTime() )
|
||||||
PlayerName = PlayerName:gsub( '"', '_' )
|
PlayerName = PlayerName:gsub( '"', '_' )
|
||||||
|
|
||||||
if PlayerUnitName and PlayerUnitName ~= '' then
|
if PlayerUnitName and PlayerUnitName ~= '' then
|
||||||
@ -6358,12 +6190,12 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play
|
|||||||
|
|
||||||
if PlayerUnit then
|
if PlayerUnit then
|
||||||
if not PlayerUnitCategory then
|
if not PlayerUnitCategory then
|
||||||
--PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()]
|
--PlayerUnitCategory = SCORINGCategory[PlayerUnit:getCategory()]
|
||||||
PlayerUnitCategory = _DATABASECategory[PlayerUnit:getDesc().category]
|
PlayerUnitCategory = _SCORINGCategory[PlayerUnit:getDesc().category]
|
||||||
end
|
end
|
||||||
|
|
||||||
if not PlayerUnitCoalition then
|
if not PlayerUnitCoalition then
|
||||||
PlayerUnitCoalition = _DATABASECoalition[PlayerUnit:getCoalition()]
|
PlayerUnitCoalition = _SCORINGCoalition[PlayerUnit:getCoalition()]
|
||||||
end
|
end
|
||||||
|
|
||||||
if not PlayerUnitType then
|
if not PlayerUnitType then
|
||||||
@ -6398,9 +6230,10 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play
|
|||||||
TargetUnitName = ''
|
TargetUnitName = ''
|
||||||
end
|
end
|
||||||
|
|
||||||
if lfs then
|
if lfs and io and os then
|
||||||
self.StatFile:write(
|
self.CSVFile:write(
|
||||||
'"' .. self.RunID .. '"' .. ',' ..
|
'"' .. self.GameName .. '"' .. ',' ..
|
||||||
|
'"' .. self.RunTime .. '"' .. ',' ..
|
||||||
'' .. ScoreTime .. '' .. ',' ..
|
'' .. ScoreTime .. '' .. ',' ..
|
||||||
'"' .. PlayerName .. '"' .. ',' ..
|
'"' .. PlayerName .. '"' .. ',' ..
|
||||||
'"' .. ScoreType .. '"' .. ',' ..
|
'"' .. ScoreType .. '"' .. ',' ..
|
||||||
@ -6416,21 +6249,17 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play
|
|||||||
'' .. ScoreAmount
|
'' .. ScoreAmount
|
||||||
)
|
)
|
||||||
|
|
||||||
self.StatFile:write( "\n" )
|
self.CSVFile:write( "\n" )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function LogClose()
|
function SCORING:CloseCSV()
|
||||||
if lfs then
|
if lfs and io and os then
|
||||||
self.StatFile:close()
|
self.CSVFile:close()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
_Database = DATABASE:New() -- Database#DATABASE
|
|
||||||
_Database:ScoreOpen()
|
|
||||||
|
|
||||||
|
|
||||||
--- CARGO Classes
|
--- CARGO Classes
|
||||||
-- @module CARGO
|
-- @module CARGO
|
||||||
|
|
||||||
@ -10605,7 +10434,9 @@ function MISSIONSCHEDULER.Scheduler()
|
|||||||
|
|
||||||
if MissionComplete then
|
if MissionComplete then
|
||||||
Mission:Completed()
|
Mission:Completed()
|
||||||
_Database:_AddMissionScore( Mission.Name, 100 )
|
if MISSIONSCHEDULER.Scoring then
|
||||||
|
MISSIONSCHEDULER.Scoring:_AddMissionScore( Mission.Name, 100 )
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if TaskComplete then
|
if TaskComplete then
|
||||||
-- Reset for new tasking of active client
|
-- Reset for new tasking of active client
|
||||||
@ -10769,6 +10600,12 @@ function MISSIONSCHEDULER:Time( TimeSeconds, TimeIntervalShow, TimeShow )
|
|||||||
self.TimeShow = TimeShow
|
self.TimeShow = TimeShow
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Adds a mission scoring to the game.
|
||||||
|
function MISSIONSCHEDULER:Scoring( Scoring )
|
||||||
|
|
||||||
|
self.Scoring = Scoring
|
||||||
|
end
|
||||||
|
|
||||||
--- The CLEANUP class keeps an area clean of crashing or colliding airplanes. It also prevents airplanes from firing within this area.
|
--- The CLEANUP class keeps an area clean of crashing or colliding airplanes. It also prevents airplanes from firing within this area.
|
||||||
-- @module CleanUp
|
-- @module CleanUp
|
||||||
-- @author Flightcontrol
|
-- @author Flightcontrol
|
||||||
|
|||||||
@ -110,15 +110,6 @@ function DATABASE:New()
|
|||||||
end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then
|
end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then
|
||||||
end --for coa_name, coa_data in pairs(mission.coalition) do
|
end --for coa_name, coa_data in pairs(mission.coalition) do
|
||||||
|
|
||||||
--self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth )
|
|
||||||
_EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self )
|
|
||||||
_EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self )
|
|
||||||
_EVENTDISPATCHER:OnHit( self._EventOnHit, self )
|
|
||||||
|
|
||||||
self.SchedulerId = routines.scheduleFunction( DATABASE._FollowPlayers, { self }, 0, 5 )
|
|
||||||
|
|
||||||
self:ScoreMenu()
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -174,11 +165,6 @@ function DATABASE:GetStatusGroup( GroupName )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Private
|
|
||||||
-- @section Private
|
|
||||||
|
|
||||||
|
|
||||||
--- Registers new Group Templates within the DATABASE Object.
|
--- Registers new Group Templates within the DATABASE Object.
|
||||||
function DATABASE:_RegisterGroup( GroupTemplate )
|
function DATABASE:_RegisterGroup( GroupTemplate )
|
||||||
|
|
||||||
@ -213,732 +199,6 @@ function DATABASE:_RegisterGroup( GroupTemplate )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Events
|
|
||||||
-- @section Events
|
|
||||||
|
|
||||||
|
|
||||||
--- Track DCSRTE DEAD or CRASH events for the internal scoring.
|
|
||||||
-- @param #DATABASE self
|
|
||||||
-- @param Event#EVENTDATA Event
|
|
||||||
function DATABASE:_EventOnDeadOrCrash( Event )
|
|
||||||
self:F( { Event } )
|
|
||||||
|
|
||||||
local TargetUnit = nil
|
|
||||||
local TargetGroup = nil
|
|
||||||
local TargetUnitName = ""
|
|
||||||
local TargetGroupName = ""
|
|
||||||
local TargetPlayerName = ""
|
|
||||||
local TargetCoalition = nil
|
|
||||||
local TargetCategory = nil
|
|
||||||
local TargetType = nil
|
|
||||||
local TargetUnitCoalition = nil
|
|
||||||
local TargetUnitCategory = nil
|
|
||||||
local TargetUnitType = nil
|
|
||||||
|
|
||||||
if Event.IniDCSUnit then
|
|
||||||
|
|
||||||
TargetUnit = Event.IniDCSUnit
|
|
||||||
TargetUnitName = Event.IniDCSUnitName
|
|
||||||
TargetGroup = Event.IniDCSGroup
|
|
||||||
TargetGroupName = Event.IniDCSGroupName
|
|
||||||
TargetPlayerName = TargetUnit:getPlayerName()
|
|
||||||
|
|
||||||
TargetCoalition = TargetUnit:getCoalition()
|
|
||||||
--TargetCategory = TargetUnit:getCategory()
|
|
||||||
TargetCategory = TargetUnit:getDesc().category -- Workaround
|
|
||||||
TargetType = TargetUnit:getTypeName()
|
|
||||||
|
|
||||||
TargetUnitCoalition = _DATABASECoalition[TargetCoalition]
|
|
||||||
TargetUnitCategory = _DATABASECategory[T1argetCategory]
|
|
||||||
TargetUnitType = TargetType
|
|
||||||
|
|
||||||
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } )
|
|
||||||
end
|
|
||||||
|
|
||||||
for PlayerName, PlayerData in pairs( self.Players ) do
|
|
||||||
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
|
||||||
self:T( "Something got killed" )
|
|
||||||
|
|
||||||
-- Some variables
|
|
||||||
local InitUnitName = PlayerData.UnitName
|
|
||||||
local InitUnitType = PlayerData.UnitType
|
|
||||||
local InitCoalition = PlayerData.UnitCoalition
|
|
||||||
local InitCategory = PlayerData.UnitCategory
|
|
||||||
local InitUnitCoalition = _DATABASECoalition[InitCoalition]
|
|
||||||
local InitUnitCategory = _DATABASECategory[InitCategory]
|
|
||||||
|
|
||||||
self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } )
|
|
||||||
|
|
||||||
-- What is he hitting?
|
|
||||||
if TargetCategory then
|
|
||||||
if PlayerData and PlayerData.Hit and PlayerData.Hit[TargetCategory] and PlayerData.Hit[TargetCategory][TargetUnitName] then -- Was there a hit for this unit for this player before registered???
|
|
||||||
if not PlayerData.Kill[TargetCategory] then
|
|
||||||
PlayerData.Kill[TargetCategory] = {}
|
|
||||||
end
|
|
||||||
if not PlayerData.Kill[TargetCategory][TargetType] then
|
|
||||||
PlayerData.Kill[TargetCategory][TargetType] = {}
|
|
||||||
PlayerData.Kill[TargetCategory][TargetType].Score = 0
|
|
||||||
PlayerData.Kill[TargetCategory][TargetType].ScoreKill = 0
|
|
||||||
PlayerData.Kill[TargetCategory][TargetType].Penalty = 0
|
|
||||||
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
if InitCoalition == TargetCoalition then
|
|
||||||
PlayerData.Penalty = PlayerData.Penalty + 25
|
|
||||||
PlayerData.Kill[TargetCategory][TargetType].Penalty = PlayerData.Kill[TargetCategory][TargetType].Penalty + 25
|
|
||||||
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = PlayerData.Kill[TargetCategory][TargetType].PenaltyKill + 1
|
|
||||||
MESSAGE:New( "Player '" .. PlayerName .. "' killed a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
|
||||||
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Penalty: -" .. PlayerData.Kill[TargetCategory][TargetType].Penalty ..
|
|
||||||
". Score Total:" .. PlayerData.Score - PlayerData.Penalty,
|
|
||||||
"", 5, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
|
||||||
self:ScoreAdd( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
||||||
else
|
|
||||||
PlayerData.Score = PlayerData.Score + 10
|
|
||||||
PlayerData.Kill[TargetCategory][TargetType].Score = PlayerData.Kill[TargetCategory][TargetType].Score + 10
|
|
||||||
PlayerData.Kill[TargetCategory][TargetType].ScoreKill = PlayerData.Kill[TargetCategory][TargetType].ScoreKill + 1
|
|
||||||
MESSAGE:New( "Player '" .. PlayerName .. "' killed an enemy " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
|
||||||
PlayerData.Kill[TargetCategory][TargetType].ScoreKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Score ..
|
|
||||||
". Score Total:" .. PlayerData.Score - PlayerData.Penalty,
|
|
||||||
"", 5, "/SCORE" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
|
||||||
self:ScoreAdd( PlayerName, "KILL_SCORE", 1, 10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Scheduled
|
|
||||||
-- @section Scheduled
|
|
||||||
|
|
||||||
|
|
||||||
--- Follows new players entering Clients within the DCSRTE.
|
|
||||||
function DATABASE:_FollowPlayers()
|
|
||||||
self:F3( "_FollowPlayers" )
|
|
||||||
|
|
||||||
local ClientUnit = 0
|
|
||||||
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers(coalition.side.RED), AlivePlayersBlue = coalition.getPlayers(coalition.side.BLUE) }
|
|
||||||
local unitId
|
|
||||||
local unitData
|
|
||||||
local AlivePlayerUnits = {}
|
|
||||||
|
|
||||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
|
||||||
self:T3( { "_FollowPlayers", CoalitionData } )
|
|
||||||
for UnitId, UnitData in pairs( CoalitionData ) do
|
|
||||||
self:_AddPlayerFromUnit( UnitData )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Private
|
|
||||||
-- @section Private
|
|
||||||
|
|
||||||
|
|
||||||
--- Add a new player entering a Unit.
|
|
||||||
function DATABASE:_AddPlayerFromUnit( UnitData )
|
|
||||||
self:F( UnitData )
|
|
||||||
|
|
||||||
if UnitData:isExist() then
|
|
||||||
local UnitName = UnitData:getName()
|
|
||||||
local PlayerName = UnitData:getPlayerName()
|
|
||||||
local UnitDesc = UnitData:getDesc()
|
|
||||||
local UnitCategory = UnitDesc.category
|
|
||||||
local UnitCoalition = UnitData:getCoalition()
|
|
||||||
local UnitTypeName = UnitData:getTypeName()
|
|
||||||
|
|
||||||
self:T( { PlayerName, UnitName, UnitCategory, UnitCoalition, UnitTypeName } )
|
|
||||||
|
|
||||||
if self.Players[PlayerName] == nil then -- I believe this is the place where a Player gets a life in a mission when he enters a unit ...
|
|
||||||
self.Players[PlayerName] = {}
|
|
||||||
self.Players[PlayerName].Hit = {}
|
|
||||||
self.Players[PlayerName].Kill = {}
|
|
||||||
self.Players[PlayerName].Mission = {}
|
|
||||||
|
|
||||||
-- for CategoryID, CategoryName in pairs( DATABASECategory ) do
|
|
||||||
-- self.Players[PlayerName].Hit[CategoryID] = {}
|
|
||||||
-- self.Players[PlayerName].Kill[CategoryID] = {}
|
|
||||||
-- end
|
|
||||||
self.Players[PlayerName].HitPlayers = {}
|
|
||||||
self.Players[PlayerName].HitUnits = {}
|
|
||||||
self.Players[PlayerName].Score = 0
|
|
||||||
self.Players[PlayerName].Penalty = 0
|
|
||||||
self.Players[PlayerName].PenaltyCoalition = 0
|
|
||||||
self.Players[PlayerName].PenaltyWarning = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
if not self.Players[PlayerName].UnitCoalition then
|
|
||||||
self.Players[PlayerName].UnitCoalition = UnitCoalition
|
|
||||||
else
|
|
||||||
if self.Players[PlayerName].UnitCoalition ~= UnitCoalition then
|
|
||||||
self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50
|
|
||||||
self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1
|
|
||||||
MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. _DATABASECoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _DATABASECoalition[UnitCoalition] ..
|
|
||||||
"(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.",
|
|
||||||
"",
|
|
||||||
2,
|
|
||||||
"/PENALTYCOALITION" .. PlayerName
|
|
||||||
):ToAll()
|
|
||||||
self:ScoreAdd( PlayerName, "COALITION_PENALTY", 1, -50, self.Players[PlayerName].UnitName, _DATABASECoalition[self.Players[PlayerName].UnitCoalition], _DATABASECategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType,
|
|
||||||
UnitName, _DATABASECoalition[UnitCoalition], _DATABASECategory[UnitCategory], UnitData:getTypeName() )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.Players[PlayerName].UnitName = UnitName
|
|
||||||
self.Players[PlayerName].UnitCoalition = UnitCoalition
|
|
||||||
self.Players[PlayerName].UnitCategory = UnitCategory
|
|
||||||
self.Players[PlayerName].UnitType = UnitTypeName
|
|
||||||
|
|
||||||
if self.Players[PlayerName].Penalty > 100 then
|
|
||||||
if self.Players[PlayerName].PenaltyWarning < 1 then
|
|
||||||
MESSAGE:New( "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than 150, you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty,
|
|
||||||
"",
|
|
||||||
30,
|
|
||||||
"/PENALTYCOALITION" .. PlayerName
|
|
||||||
):ToAll()
|
|
||||||
self.Players[PlayerName].PenaltyWarning = self.Players[PlayerName].PenaltyWarning + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.Players[PlayerName].Penalty > 150 then
|
|
||||||
ClientGroup = GROUP:NewFromDCSUnit( UnitData )
|
|
||||||
ClientGroup:Destroy()
|
|
||||||
MESSAGE:New( "Player '" .. PlayerName .. "' committed FRATRICIDE, he will be COURT MARTIALED and is DISMISSED from this mission!",
|
|
||||||
"",
|
|
||||||
10,
|
|
||||||
"/PENALTYCOALITION" .. PlayerName
|
|
||||||
):ToAll()
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Registers Scores the players completing a Mission Task.
|
|
||||||
function DATABASE:_AddMissionTaskScore( PlayerUnit, MissionName, Score )
|
|
||||||
self:F( { PlayerUnit, MissionName, Score } )
|
|
||||||
|
|
||||||
local PlayerName = PlayerUnit:getPlayerName()
|
|
||||||
|
|
||||||
if not self.Players[PlayerName].Mission[MissionName] then
|
|
||||||
self.Players[PlayerName].Mission[MissionName] = {}
|
|
||||||
self.Players[PlayerName].Mission[MissionName].ScoreTask = 0
|
|
||||||
self.Players[PlayerName].Mission[MissionName].ScoreMission = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
self:T( PlayerName )
|
|
||||||
self:T( self.Players[PlayerName].Mission[MissionName] )
|
|
||||||
|
|
||||||
self.Players[PlayerName].Score = self.Players[PlayerName].Score + Score
|
|
||||||
self.Players[PlayerName].Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
|
|
||||||
|
|
||||||
MESSAGE:New( "Player '" .. PlayerName .. "' has finished another Task in Mission '" .. MissionName .. "'. " ..
|
|
||||||
Score .. " Score points added.",
|
|
||||||
"", 20, "/SCORETASK" .. PlayerName ):ToAll()
|
|
||||||
|
|
||||||
_Database:ScoreAdd( PlayerName, "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:getName() )
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Registers Mission Scores for possible multiple players that contributed in the Mission.
|
|
||||||
function DATABASE:_AddMissionScore( MissionName, Score )
|
|
||||||
self:F( { PlayerUnit, MissionName, Score } )
|
|
||||||
|
|
||||||
for PlayerName, PlayerData in pairs( self.Players ) do
|
|
||||||
|
|
||||||
if PlayerData.Mission[MissionName] then
|
|
||||||
PlayerData.Score = PlayerData.Score + Score
|
|
||||||
PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score
|
|
||||||
MESSAGE:New( "Player '" .. PlayerName .. "' has finished Mission '" .. MissionName .. "'. " ..
|
|
||||||
Score .. " Score points added.",
|
|
||||||
"", 20, "/SCOREMISSION" .. PlayerName ):ToAll()
|
|
||||||
_Database:ScoreAdd( PlayerName, "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Events
|
|
||||||
-- @section Events
|
|
||||||
|
|
||||||
|
|
||||||
--- Handles the OnHit event for the scoring.
|
|
||||||
-- @param #DATABASE self
|
|
||||||
-- @param Event#EVENTDATA Event
|
|
||||||
function DATABASE:_EventOnHit( Event )
|
|
||||||
self:F( { Event } )
|
|
||||||
|
|
||||||
local InitUnit = nil
|
|
||||||
local InitUnitName = ""
|
|
||||||
local InitGroup = nil
|
|
||||||
local InitGroupName = ""
|
|
||||||
local InitPlayerName = "dummy"
|
|
||||||
|
|
||||||
local InitCoalition = nil
|
|
||||||
local InitCategory = nil
|
|
||||||
local InitType = nil
|
|
||||||
local InitUnitCoalition = nil
|
|
||||||
local InitUnitCategory = nil
|
|
||||||
local InitUnitType = nil
|
|
||||||
|
|
||||||
local TargetUnit = nil
|
|
||||||
local TargetUnitName = ""
|
|
||||||
local TargetGroup = nil
|
|
||||||
local TargetGroupName = ""
|
|
||||||
local TargetPlayerName = ""
|
|
||||||
|
|
||||||
local TargetCoalition = nil
|
|
||||||
local TargetCategory = nil
|
|
||||||
local TargetType = nil
|
|
||||||
local TargetUnitCoalition = nil
|
|
||||||
local TargetUnitCategory = nil
|
|
||||||
local TargetUnitType = nil
|
|
||||||
|
|
||||||
if Event.IniDCSUnit then
|
|
||||||
|
|
||||||
InitUnit = Event.IniDCSUnit
|
|
||||||
InitUnitName = Event.IniDCSUnitName
|
|
||||||
InitGroup = Event.IniDCSGroup
|
|
||||||
InitGroupName = Event.IniDCSGroupName
|
|
||||||
InitPlayerName = InitUnit:getPlayerName()
|
|
||||||
|
|
||||||
InitCoalition = InitUnit:getCoalition()
|
|
||||||
--TODO: Workaround Client DCS Bug
|
|
||||||
--InitCategory = InitUnit:getCategory()
|
|
||||||
InitCategory = InitUnit:getDesc().category
|
|
||||||
InitType = InitUnit:getTypeName()
|
|
||||||
|
|
||||||
InitUnitCoalition = _DATABASECoalition[InitCoalition]
|
|
||||||
InitUnitCategory = _DATABASECategory[InitCategory]
|
|
||||||
InitUnitType = InitType
|
|
||||||
|
|
||||||
self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType , InitUnitCoalition, InitUnitCategory, InitUnitType } )
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
if Event.TgtDCSUnit then
|
|
||||||
|
|
||||||
TargetUnit = Event.TgtDCSUnit
|
|
||||||
TargetUnitName = Event.TgtDCSUnitName
|
|
||||||
TargetGroup = Event.TgtDCSGroup
|
|
||||||
TargetGroupName = Event.TgtDCSGroupName
|
|
||||||
TargetPlayerName = TargetUnit:getPlayerName()
|
|
||||||
|
|
||||||
TargetCoalition = TargetUnit:getCoalition()
|
|
||||||
--TODO: Workaround Client DCS Bug
|
|
||||||
--TargetCategory = TargetUnit:getCategory()
|
|
||||||
TargetCategory = TargetUnit:getDesc().category
|
|
||||||
TargetType = TargetUnit:getTypeName()
|
|
||||||
|
|
||||||
TargetUnitCoalition = _DATABASECoalition[TargetCoalition]
|
|
||||||
TargetUnitCategory = _DATABASECategory[TargetCategory]
|
|
||||||
TargetUnitType = TargetType
|
|
||||||
|
|
||||||
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } )
|
|
||||||
end
|
|
||||||
|
|
||||||
if InitPlayerName ~= nil then -- It is a player that is hitting something
|
|
||||||
self:_AddPlayerFromUnit( InitUnit )
|
|
||||||
if self.Players[InitPlayerName] then -- This should normally not happen, but i'll test it anyway.
|
|
||||||
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
|
|
||||||
self:_AddPlayerFromUnit( TargetUnit )
|
|
||||||
self.Players[InitPlayerName].HitPlayers = self.Players[InitPlayerName].HitPlayers + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
self:T( "Hitting Something" )
|
|
||||||
-- What is he hitting?
|
|
||||||
if TargetCategory then
|
|
||||||
if not self.Players[InitPlayerName].Hit[TargetCategory] then
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory] = {}
|
|
||||||
end
|
|
||||||
if not self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] then
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] = {}
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = 0
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = 0
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = 0
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = 0
|
|
||||||
end
|
|
||||||
local Score = 0
|
|
||||||
if InitCoalition == TargetCoalition then
|
|
||||||
self.Players[InitPlayerName].Penalty = self.Players[InitPlayerName].Penalty + 10
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty + 10
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit + 1
|
|
||||||
MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit .. " times. Penalty: -" .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty ..
|
|
||||||
". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty,
|
|
||||||
"",
|
|
||||||
2,
|
|
||||||
"/PENALTY" .. InitPlayerName .. "/" .. InitUnitName
|
|
||||||
):ToAll()
|
|
||||||
self:ScoreAdd( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
||||||
else
|
|
||||||
self.Players[InitPlayerName].Score = self.Players[InitPlayerName].Score + 10
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score + 1
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit + 1
|
|
||||||
MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit .. " times. Score: " .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score ..
|
|
||||||
". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty,
|
|
||||||
"",
|
|
||||||
2,
|
|
||||||
"/SCORE" .. InitPlayerName .. "/" .. InitUnitName
|
|
||||||
):ToAll()
|
|
||||||
self:ScoreAdd( InitPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif InitPlayerName == nil then -- It is an AI hitting a player???
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ReportScoreAll()
|
|
||||||
|
|
||||||
env.info( "Hello World " )
|
|
||||||
|
|
||||||
local ScoreMessage = ""
|
|
||||||
local PlayerMessage = ""
|
|
||||||
|
|
||||||
self:T( "Score Report" )
|
|
||||||
|
|
||||||
for PlayerName, PlayerData in pairs( self.Players ) do
|
|
||||||
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
|
||||||
self:T( "Score Player: " .. PlayerName )
|
|
||||||
|
|
||||||
-- Some variables
|
|
||||||
local InitUnitCoalition = _DATABASECoalition[PlayerData.UnitCoalition]
|
|
||||||
local InitUnitCategory = _DATABASECategory[PlayerData.UnitCategory]
|
|
||||||
local InitUnitType = PlayerData.UnitType
|
|
||||||
local InitUnitName = PlayerData.UnitName
|
|
||||||
|
|
||||||
local PlayerScore = 0
|
|
||||||
local PlayerPenalty = 0
|
|
||||||
|
|
||||||
ScoreMessage = ":\n"
|
|
||||||
|
|
||||||
local ScoreMessageHits = ""
|
|
||||||
|
|
||||||
for CategoryID, CategoryName in pairs( _DATABASECategory ) do
|
|
||||||
self:T( CategoryName )
|
|
||||||
if PlayerData.Hit[CategoryID] then
|
|
||||||
local Score = 0
|
|
||||||
local ScoreHit = 0
|
|
||||||
local Penalty = 0
|
|
||||||
local PenaltyHit = 0
|
|
||||||
self:T( "Hit scores exist for player " .. PlayerName )
|
|
||||||
for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do
|
|
||||||
Score = Score + UnitData.Score
|
|
||||||
ScoreHit = ScoreHit + UnitData.ScoreHit
|
|
||||||
Penalty = Penalty + UnitData.Penalty
|
|
||||||
PenaltyHit = UnitData.PenaltyHit
|
|
||||||
end
|
|
||||||
local ScoreMessageHit = string.format( "%s:%d ", CategoryName, Score - Penalty )
|
|
||||||
self:T( ScoreMessageHit )
|
|
||||||
ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit
|
|
||||||
PlayerScore = PlayerScore + Score
|
|
||||||
PlayerPenalty = PlayerPenalty + Penalty
|
|
||||||
else
|
|
||||||
--ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if ScoreMessageHits ~= "" then
|
|
||||||
ScoreMessage = ScoreMessage .. " Hits: " .. ScoreMessageHits .. "\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
local ScoreMessageKills = ""
|
|
||||||
for CategoryID, CategoryName in pairs( _DATABASECategory ) do
|
|
||||||
self:T( "Kill scores exist for player " .. PlayerName )
|
|
||||||
if PlayerData.Kill[CategoryID] then
|
|
||||||
local Score = 0
|
|
||||||
local ScoreKill = 0
|
|
||||||
local Penalty = 0
|
|
||||||
local PenaltyKill = 0
|
|
||||||
|
|
||||||
for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do
|
|
||||||
Score = Score + UnitData.Score
|
|
||||||
ScoreKill = ScoreKill + UnitData.ScoreKill
|
|
||||||
Penalty = Penalty + UnitData.Penalty
|
|
||||||
PenaltyKill = PenaltyKill + UnitData.PenaltyKill
|
|
||||||
end
|
|
||||||
|
|
||||||
local ScoreMessageKill = string.format( " %s:%d ", CategoryName, Score - Penalty )
|
|
||||||
self:T( ScoreMessageKill )
|
|
||||||
ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill
|
|
||||||
|
|
||||||
PlayerScore = PlayerScore + Score
|
|
||||||
PlayerPenalty = PlayerPenalty + Penalty
|
|
||||||
else
|
|
||||||
--ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if ScoreMessageKills ~= "" then
|
|
||||||
ScoreMessage = ScoreMessage .. " Kills: " .. ScoreMessageKills .. "\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
local ScoreMessageCoalitionChangePenalties = ""
|
|
||||||
if PlayerData.PenaltyCoalition ~= 0 then
|
|
||||||
ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition )
|
|
||||||
PlayerPenalty = PlayerPenalty + PlayerData.Penalty
|
|
||||||
end
|
|
||||||
if ScoreMessageCoalitionChangePenalties ~= "" then
|
|
||||||
ScoreMessage = ScoreMessage .. " Coalition Penalties: " .. ScoreMessageCoalitionChangePenalties .. "\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
local ScoreMessageMission = ""
|
|
||||||
local ScoreMission = 0
|
|
||||||
local ScoreTask = 0
|
|
||||||
for MissionName, MissionData in pairs( PlayerData.Mission ) do
|
|
||||||
ScoreMission = ScoreMission + MissionData.ScoreMission
|
|
||||||
ScoreTask = ScoreTask + MissionData.ScoreTask
|
|
||||||
ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; "
|
|
||||||
end
|
|
||||||
PlayerScore = PlayerScore + ScoreMission + ScoreTask
|
|
||||||
|
|
||||||
if ScoreMessageMission ~= "" then
|
|
||||||
ScoreMessage = ScoreMessage .. " Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ")\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score:%d (%d Score -%d Penalties)%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll()
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ReportScorePlayer()
|
|
||||||
|
|
||||||
env.info( "Hello World " )
|
|
||||||
|
|
||||||
local ScoreMessage = ""
|
|
||||||
local PlayerMessage = ""
|
|
||||||
|
|
||||||
self:T( "Score Report" )
|
|
||||||
|
|
||||||
for PlayerName, PlayerData in pairs( self.Players ) do
|
|
||||||
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
|
||||||
self:T( "Score Player: " .. PlayerName )
|
|
||||||
|
|
||||||
-- Some variables
|
|
||||||
local InitUnitCoalition = _DATABASECoalition[PlayerData.UnitCoalition]
|
|
||||||
local InitUnitCategory = _DATABASECategory[PlayerData.UnitCategory]
|
|
||||||
local InitUnitType = PlayerData.UnitType
|
|
||||||
local InitUnitName = PlayerData.UnitName
|
|
||||||
|
|
||||||
local PlayerScore = 0
|
|
||||||
local PlayerPenalty = 0
|
|
||||||
|
|
||||||
ScoreMessage = ""
|
|
||||||
|
|
||||||
local ScoreMessageHits = ""
|
|
||||||
|
|
||||||
for CategoryID, CategoryName in pairs( _DATABASECategory ) do
|
|
||||||
self:T( CategoryName )
|
|
||||||
if PlayerData.Hit[CategoryID] then
|
|
||||||
local Score = 0
|
|
||||||
local ScoreHit = 0
|
|
||||||
local Penalty = 0
|
|
||||||
local PenaltyHit = 0
|
|
||||||
self:T( "Hit scores exist for player " .. PlayerName )
|
|
||||||
for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do
|
|
||||||
Score = Score + UnitData.Score
|
|
||||||
ScoreHit = ScoreHit + UnitData.ScoreHit
|
|
||||||
Penalty = Penalty + UnitData.Penalty
|
|
||||||
PenaltyHit = UnitData.PenaltyHit
|
|
||||||
end
|
|
||||||
local ScoreMessageHit = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit )
|
|
||||||
self:T( ScoreMessageHit )
|
|
||||||
ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit
|
|
||||||
PlayerScore = PlayerScore + Score
|
|
||||||
PlayerPenalty = PlayerPenalty + Penalty
|
|
||||||
else
|
|
||||||
--ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if ScoreMessageHits ~= "" then
|
|
||||||
ScoreMessage = ScoreMessage .. "\n Hits: " .. ScoreMessageHits .. " "
|
|
||||||
end
|
|
||||||
|
|
||||||
local ScoreMessageKills = ""
|
|
||||||
for CategoryID, CategoryName in pairs( _DATABASECategory ) do
|
|
||||||
self:T( "Kill scores exist for player " .. PlayerName )
|
|
||||||
if PlayerData.Kill[CategoryID] then
|
|
||||||
local Score = 0
|
|
||||||
local ScoreKill = 0
|
|
||||||
local Penalty = 0
|
|
||||||
local PenaltyKill = 0
|
|
||||||
|
|
||||||
for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do
|
|
||||||
Score = Score + UnitData.Score
|
|
||||||
ScoreKill = ScoreKill + UnitData.ScoreKill
|
|
||||||
Penalty = Penalty + UnitData.Penalty
|
|
||||||
PenaltyKill = PenaltyKill + UnitData.PenaltyKill
|
|
||||||
end
|
|
||||||
|
|
||||||
local ScoreMessageKill = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill )
|
|
||||||
self:T( ScoreMessageKill )
|
|
||||||
ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill
|
|
||||||
|
|
||||||
PlayerScore = PlayerScore + Score
|
|
||||||
PlayerPenalty = PlayerPenalty + Penalty
|
|
||||||
else
|
|
||||||
--ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if ScoreMessageKills ~= "" then
|
|
||||||
ScoreMessage = ScoreMessage .. "\n Kills: " .. ScoreMessageKills .. " "
|
|
||||||
end
|
|
||||||
|
|
||||||
local ScoreMessageCoalitionChangePenalties = ""
|
|
||||||
if PlayerData.PenaltyCoalition ~= 0 then
|
|
||||||
ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition )
|
|
||||||
PlayerPenalty = PlayerPenalty + PlayerData.Penalty
|
|
||||||
end
|
|
||||||
if ScoreMessageCoalitionChangePenalties ~= "" then
|
|
||||||
ScoreMessage = ScoreMessage .. "\n Coalition: " .. ScoreMessageCoalitionChangePenalties .. " "
|
|
||||||
end
|
|
||||||
|
|
||||||
local ScoreMessageMission = ""
|
|
||||||
local ScoreMission = 0
|
|
||||||
local ScoreTask = 0
|
|
||||||
for MissionName, MissionData in pairs( PlayerData.Mission ) do
|
|
||||||
ScoreMission = ScoreMission + MissionData.ScoreMission
|
|
||||||
ScoreTask = ScoreTask + MissionData.ScoreTask
|
|
||||||
ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; "
|
|
||||||
end
|
|
||||||
PlayerScore = PlayerScore + ScoreMission + ScoreTask
|
|
||||||
|
|
||||||
if ScoreMessageMission ~= "" then
|
|
||||||
ScoreMessage = ScoreMessage .. "\n Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ") "
|
|
||||||
end
|
|
||||||
|
|
||||||
PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score = %d ( %d Score, -%d Penalties ):%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll()
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ScoreMenu()
|
|
||||||
local ReportScore = SUBMENU:New( 'Scoring' )
|
|
||||||
local ReportAllScores = COMMANDMENU:New( 'Score All Active Players', ReportScore, DATABASE.ReportScoreAll, self )
|
|
||||||
local ReportPlayerScores = COMMANDMENU:New('Your Current Score', ReportScore, DATABASE.ReportScorePlayer, self )
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- File Logic for tracking the scores
|
|
||||||
|
|
||||||
function DATABASE:SecondsToClock(sSeconds)
|
|
||||||
local nSeconds = sSeconds
|
|
||||||
if nSeconds == 0 then
|
|
||||||
--return nil;
|
|
||||||
return "00:00:00";
|
|
||||||
else
|
|
||||||
nHours = string.format("%02.f", math.floor(nSeconds/3600));
|
|
||||||
nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours*60)));
|
|
||||||
nSecs = string.format("%02.f", math.floor(nSeconds - nHours*3600 - nMins *60));
|
|
||||||
return nHours..":"..nMins..":"..nSecs
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ScoreOpen()
|
|
||||||
if lfs then
|
|
||||||
local fdir = lfs.writedir() .. [[Logs\]] .. "Player_Scores_" .. os.date( "%Y-%m-%d_%H-%M-%S" ) .. ".csv"
|
|
||||||
self.StatFile, self.err = io.open(fdir,"w+")
|
|
||||||
if not self.StatFile then
|
|
||||||
error( "Error: Cannot open 'Player Scores.csv' file in " .. lfs.writedir() )
|
|
||||||
end
|
|
||||||
self.StatFile:write( '"RunID","Time","PlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition","TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n' )
|
|
||||||
|
|
||||||
self.RunID = os.date("%y-%m-%d_%H-%M-%S")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
||||||
--write statistic information to file
|
|
||||||
local ScoreTime = self:SecondsToClock(timer.getTime())
|
|
||||||
PlayerName = PlayerName:gsub( '"', '_' )
|
|
||||||
|
|
||||||
if PlayerUnitName and PlayerUnitName ~= '' then
|
|
||||||
local PlayerUnit = Unit.getByName( PlayerUnitName )
|
|
||||||
|
|
||||||
if PlayerUnit then
|
|
||||||
if not PlayerUnitCategory then
|
|
||||||
--PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()]
|
|
||||||
PlayerUnitCategory = _DATABASECategory[PlayerUnit:getDesc().category]
|
|
||||||
end
|
|
||||||
|
|
||||||
if not PlayerUnitCoalition then
|
|
||||||
PlayerUnitCoalition = _DATABASECoalition[PlayerUnit:getCoalition()]
|
|
||||||
end
|
|
||||||
|
|
||||||
if not PlayerUnitType then
|
|
||||||
PlayerUnitType = PlayerUnit:getTypeName()
|
|
||||||
end
|
|
||||||
else
|
|
||||||
PlayerUnitName = ''
|
|
||||||
PlayerUnitCategory = ''
|
|
||||||
PlayerUnitCoalition = ''
|
|
||||||
PlayerUnitType = ''
|
|
||||||
end
|
|
||||||
else
|
|
||||||
PlayerUnitName = ''
|
|
||||||
PlayerUnitCategory = ''
|
|
||||||
PlayerUnitCoalition = ''
|
|
||||||
PlayerUnitType = ''
|
|
||||||
end
|
|
||||||
|
|
||||||
if not TargetUnitCoalition then
|
|
||||||
TargetUnitCoalition = ''
|
|
||||||
end
|
|
||||||
|
|
||||||
if not TargetUnitCategory then
|
|
||||||
TargetUnitCategory = ''
|
|
||||||
end
|
|
||||||
|
|
||||||
if not TargetUnitType then
|
|
||||||
TargetUnitType = ''
|
|
||||||
end
|
|
||||||
|
|
||||||
if not TargetUnitName then
|
|
||||||
TargetUnitName = ''
|
|
||||||
end
|
|
||||||
|
|
||||||
if lfs then
|
|
||||||
self.StatFile:write(
|
|
||||||
'"' .. self.RunID .. '"' .. ',' ..
|
|
||||||
'' .. ScoreTime .. '' .. ',' ..
|
|
||||||
'"' .. PlayerName .. '"' .. ',' ..
|
|
||||||
'"' .. ScoreType .. '"' .. ',' ..
|
|
||||||
'"' .. PlayerUnitCoalition .. '"' .. ',' ..
|
|
||||||
'"' .. PlayerUnitCategory .. '"' .. ',' ..
|
|
||||||
'"' .. PlayerUnitType .. '"' .. ',' ..
|
|
||||||
'"' .. PlayerUnitName .. '"' .. ',' ..
|
|
||||||
'"' .. TargetUnitCoalition .. '"' .. ',' ..
|
|
||||||
'"' .. TargetUnitCategory .. '"' .. ',' ..
|
|
||||||
'"' .. TargetUnitType .. '"' .. ',' ..
|
|
||||||
'"' .. TargetUnitName .. '"' .. ',' ..
|
|
||||||
'' .. ScoreTimes .. '' .. ',' ..
|
|
||||||
'' .. ScoreAmount
|
|
||||||
)
|
|
||||||
|
|
||||||
self.StatFile:write( "\n" )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function LogClose()
|
|
||||||
if lfs then
|
|
||||||
self.StatFile:close()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
_Database = DATABASE:New() -- Database#DATABASE
|
_Database = DATABASE:New() -- Database#DATABASE
|
||||||
_Database:ScoreOpen()
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -497,7 +497,9 @@ function MISSIONSCHEDULER.Scheduler()
|
|||||||
|
|
||||||
if MissionComplete then
|
if MissionComplete then
|
||||||
Mission:Completed()
|
Mission:Completed()
|
||||||
_Database:_AddMissionScore( Mission.Name, 100 )
|
if MISSIONSCHEDULER.Scoring then
|
||||||
|
MISSIONSCHEDULER.Scoring:_AddMissionScore( Mission.Name, 100 )
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if TaskComplete then
|
if TaskComplete then
|
||||||
-- Reset for new tasking of active client
|
-- Reset for new tasking of active client
|
||||||
@ -661,3 +663,9 @@ function MISSIONSCHEDULER:Time( TimeSeconds, TimeIntervalShow, TimeShow )
|
|||||||
self.TimeShow = TimeShow
|
self.TimeShow = TimeShow
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Adds a mission scoring to the game.
|
||||||
|
function MISSIONSCHEDULER:Scoring( Scoring )
|
||||||
|
|
||||||
|
self.Scoring = Scoring
|
||||||
|
end
|
||||||
|
|
||||||
|
|||||||
815
Moose/Scoring.lua
Normal file
815
Moose/Scoring.lua
Normal file
@ -0,0 +1,815 @@
|
|||||||
|
--- Scoring system for MOOSE.
|
||||||
|
-- This scoring class calculates the hits and kills that players make within a simulation session.
|
||||||
|
-- Scoring is calculated using a defined algorithm.
|
||||||
|
-- With a small change in MissionScripting.lua, the scoring can also be logged in a CSV file, that can then be uploaded
|
||||||
|
-- to a database or a BI tool to publish the scoring results to the player community.
|
||||||
|
-- @module Scoring
|
||||||
|
-- @author FlightControl
|
||||||
|
|
||||||
|
|
||||||
|
Include.File( "Routines" )
|
||||||
|
Include.File( "Base" )
|
||||||
|
Include.File( "Menu" )
|
||||||
|
Include.File( "Group" )
|
||||||
|
Include.File( "Event" )
|
||||||
|
|
||||||
|
|
||||||
|
--- The Scoring class
|
||||||
|
-- @type SCORING
|
||||||
|
-- @field Players A collection of the current players that have joined the game.
|
||||||
|
-- @extends Base#BASE
|
||||||
|
SCORING = {
|
||||||
|
ClassName = "SCORING",
|
||||||
|
ClassID = 0,
|
||||||
|
Players = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
local _SCORINGCoalition =
|
||||||
|
{
|
||||||
|
[1] = "Red",
|
||||||
|
[2] = "Blue",
|
||||||
|
}
|
||||||
|
|
||||||
|
local _SCORINGCategory =
|
||||||
|
{
|
||||||
|
[Unit.Category.AIRPLANE] = "Plane",
|
||||||
|
[Unit.Category.HELICOPTER] = "Helicopter",
|
||||||
|
[Unit.Category.GROUND_UNIT] = "Vehicle",
|
||||||
|
[Unit.Category.SHIP] = "Ship",
|
||||||
|
[Unit.Category.STRUCTURE] = "Structure",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Creates a new SCORING object to administer the scoring achieved by players.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param #string GameName The name of the game. This name is also logged in the CSV score file.
|
||||||
|
-- @return #SCORING self
|
||||||
|
-- @usage
|
||||||
|
-- -- Define a new scoring object for the mission Gori Valley.
|
||||||
|
-- ScoringObject = SCORING:New( "Gori Valley" )
|
||||||
|
function SCORING:New( GameName )
|
||||||
|
|
||||||
|
-- Inherits from BASE
|
||||||
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
|
||||||
|
if GameName then
|
||||||
|
self.GameName = GameName
|
||||||
|
else
|
||||||
|
error( "A game name must be given to register the scoring results" )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
_EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self )
|
||||||
|
_EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self )
|
||||||
|
_EVENTDISPATCHER:OnHit( self._EventOnHit, self )
|
||||||
|
|
||||||
|
self.SchedulerId = routines.scheduleFunction( SCORING._FollowPlayersScheduled, { self }, 0, 5 )
|
||||||
|
|
||||||
|
self:ScoreMenu()
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creates a score radio menu. Can be accessed using Radio -> F10.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @return #SCORING self
|
||||||
|
function SCORING:ScoreMenu()
|
||||||
|
self.Menu = SUBMENU:New( 'Scoring' )
|
||||||
|
self.AllScoresMenu = COMMANDMENU:New( 'Score All Active Players', self.Menu, SCORING.ReportScoreAll, self )
|
||||||
|
--- = COMMANDMENU:New('Your Current Score', ReportScore, SCORING.ReportScorePlayer, self )
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Follows new players entering Clients within the DCSRTE.
|
||||||
|
-- TODO: Need to see if i can catch this also with an event. It will eliminate the schedule ...
|
||||||
|
function SCORING:_FollowPlayersScheduled()
|
||||||
|
self:F3( "_FollowPlayersScheduled" )
|
||||||
|
|
||||||
|
local ClientUnit = 0
|
||||||
|
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers(coalition.side.RED), AlivePlayersBlue = coalition.getPlayers(coalition.side.BLUE) }
|
||||||
|
local unitId
|
||||||
|
local unitData
|
||||||
|
local AlivePlayerUnits = {}
|
||||||
|
|
||||||
|
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||||
|
self:T3( { "_FollowPlayersScheduled", CoalitionData } )
|
||||||
|
for UnitId, UnitData in pairs( CoalitionData ) do
|
||||||
|
self:_AddPlayerFromUnit( UnitData )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Track DEAD or CRASH events for the scoring.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param Event#EVENTDATA Event
|
||||||
|
function SCORING:_EventOnDeadOrCrash( Event )
|
||||||
|
self:F( { Event } )
|
||||||
|
|
||||||
|
local TargetUnit = nil
|
||||||
|
local TargetGroup = nil
|
||||||
|
local TargetUnitName = ""
|
||||||
|
local TargetGroupName = ""
|
||||||
|
local TargetPlayerName = ""
|
||||||
|
local TargetCoalition = nil
|
||||||
|
local TargetCategory = nil
|
||||||
|
local TargetType = nil
|
||||||
|
local TargetUnitCoalition = nil
|
||||||
|
local TargetUnitCategory = nil
|
||||||
|
local TargetUnitType = nil
|
||||||
|
|
||||||
|
if Event.IniDCSUnit then
|
||||||
|
|
||||||
|
TargetUnit = Event.IniDCSUnit
|
||||||
|
TargetUnitName = Event.IniDCSUnitName
|
||||||
|
TargetGroup = Event.IniDCSGroup
|
||||||
|
TargetGroupName = Event.IniDCSGroupName
|
||||||
|
TargetPlayerName = TargetUnit:getPlayerName()
|
||||||
|
|
||||||
|
TargetCoalition = TargetUnit:getCoalition()
|
||||||
|
--TargetCategory = TargetUnit:getCategory()
|
||||||
|
TargetCategory = TargetUnit:getDesc().category -- Workaround
|
||||||
|
TargetType = TargetUnit:getTypeName()
|
||||||
|
|
||||||
|
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
||||||
|
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
||||||
|
TargetUnitType = TargetType
|
||||||
|
|
||||||
|
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } )
|
||||||
|
end
|
||||||
|
|
||||||
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
||||||
|
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
||||||
|
self:T( "Something got killed" )
|
||||||
|
|
||||||
|
-- Some variables
|
||||||
|
local InitUnitName = PlayerData.UnitName
|
||||||
|
local InitUnitType = PlayerData.UnitType
|
||||||
|
local InitCoalition = PlayerData.UnitCoalition
|
||||||
|
local InitCategory = PlayerData.UnitCategory
|
||||||
|
local InitUnitCoalition = _SCORINGCoalition[InitCoalition]
|
||||||
|
local InitUnitCategory = _SCORINGCategory[InitCategory]
|
||||||
|
|
||||||
|
self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } )
|
||||||
|
|
||||||
|
-- What is he hitting?
|
||||||
|
if TargetCategory then
|
||||||
|
if PlayerData and PlayerData.Hit and PlayerData.Hit[TargetCategory] and PlayerData.Hit[TargetCategory][TargetUnitName] then -- Was there a hit for this unit for this player before registered???
|
||||||
|
if not PlayerData.Kill[TargetCategory] then
|
||||||
|
PlayerData.Kill[TargetCategory] = {}
|
||||||
|
end
|
||||||
|
if not PlayerData.Kill[TargetCategory][TargetType] then
|
||||||
|
PlayerData.Kill[TargetCategory][TargetType] = {}
|
||||||
|
PlayerData.Kill[TargetCategory][TargetType].Score = 0
|
||||||
|
PlayerData.Kill[TargetCategory][TargetType].ScoreKill = 0
|
||||||
|
PlayerData.Kill[TargetCategory][TargetType].Penalty = 0
|
||||||
|
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
if InitCoalition == TargetCoalition then
|
||||||
|
PlayerData.Penalty = PlayerData.Penalty + 25
|
||||||
|
PlayerData.Kill[TargetCategory][TargetType].Penalty = PlayerData.Kill[TargetCategory][TargetType].Penalty + 25
|
||||||
|
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = PlayerData.Kill[TargetCategory][TargetType].PenaltyKill + 1
|
||||||
|
MESSAGE:New( "Player '" .. PlayerName .. "' killed a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||||
|
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Penalty: -" .. PlayerData.Kill[TargetCategory][TargetType].Penalty ..
|
||||||
|
". Score Total:" .. PlayerData.Score - PlayerData.Penalty,
|
||||||
|
"", 5, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
||||||
|
self:ScoreCSV( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
|
else
|
||||||
|
PlayerData.Score = PlayerData.Score + 10
|
||||||
|
PlayerData.Kill[TargetCategory][TargetType].Score = PlayerData.Kill[TargetCategory][TargetType].Score + 10
|
||||||
|
PlayerData.Kill[TargetCategory][TargetType].ScoreKill = PlayerData.Kill[TargetCategory][TargetType].ScoreKill + 1
|
||||||
|
MESSAGE:New( "Player '" .. PlayerName .. "' killed an enemy " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||||
|
PlayerData.Kill[TargetCategory][TargetType].ScoreKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Score ..
|
||||||
|
". Score Total:" .. PlayerData.Score - PlayerData.Penalty,
|
||||||
|
"", 5, "/SCORE" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
||||||
|
self:ScoreCSV( PlayerName, "KILL_SCORE", 1, 10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Add a new player entering a Unit.
|
||||||
|
function SCORING:_AddPlayerFromUnit( UnitData )
|
||||||
|
self:F( UnitData )
|
||||||
|
|
||||||
|
if UnitData:isExist() then
|
||||||
|
local UnitName = UnitData:getName()
|
||||||
|
local PlayerName = UnitData:getPlayerName()
|
||||||
|
local UnitDesc = UnitData:getDesc()
|
||||||
|
local UnitCategory = UnitDesc.category
|
||||||
|
local UnitCoalition = UnitData:getCoalition()
|
||||||
|
local UnitTypeName = UnitData:getTypeName()
|
||||||
|
|
||||||
|
self:T( { PlayerName, UnitName, UnitCategory, UnitCoalition, UnitTypeName } )
|
||||||
|
|
||||||
|
if self.Players[PlayerName] == nil then -- I believe this is the place where a Player gets a life in a mission when he enters a unit ...
|
||||||
|
self.Players[PlayerName] = {}
|
||||||
|
self.Players[PlayerName].Hit = {}
|
||||||
|
self.Players[PlayerName].Kill = {}
|
||||||
|
self.Players[PlayerName].Mission = {}
|
||||||
|
|
||||||
|
-- for CategoryID, CategoryName in pairs( SCORINGCategory ) do
|
||||||
|
-- self.Players[PlayerName].Hit[CategoryID] = {}
|
||||||
|
-- self.Players[PlayerName].Kill[CategoryID] = {}
|
||||||
|
-- end
|
||||||
|
self.Players[PlayerName].HitPlayers = {}
|
||||||
|
self.Players[PlayerName].HitUnits = {}
|
||||||
|
self.Players[PlayerName].Score = 0
|
||||||
|
self.Players[PlayerName].Penalty = 0
|
||||||
|
self.Players[PlayerName].PenaltyCoalition = 0
|
||||||
|
self.Players[PlayerName].PenaltyWarning = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self.Players[PlayerName].UnitCoalition then
|
||||||
|
self.Players[PlayerName].UnitCoalition = UnitCoalition
|
||||||
|
else
|
||||||
|
if self.Players[PlayerName].UnitCoalition ~= UnitCoalition then
|
||||||
|
self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50
|
||||||
|
self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1
|
||||||
|
MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. _SCORINGCoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _SCORINGCoalition[UnitCoalition] ..
|
||||||
|
"(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.",
|
||||||
|
"",
|
||||||
|
2,
|
||||||
|
"/PENALTYCOALITION" .. PlayerName
|
||||||
|
):ToAll()
|
||||||
|
self:ScoreCSV( PlayerName, "COALITION_PENALTY", 1, -50, self.Players[PlayerName].UnitName, _SCORINGCoalition[self.Players[PlayerName].UnitCoalition], _SCORINGCategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType,
|
||||||
|
UnitName, _SCORINGCoalition[UnitCoalition], _SCORINGCategory[UnitCategory], UnitData:getTypeName() )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.Players[PlayerName].UnitName = UnitName
|
||||||
|
self.Players[PlayerName].UnitCoalition = UnitCoalition
|
||||||
|
self.Players[PlayerName].UnitCategory = UnitCategory
|
||||||
|
self.Players[PlayerName].UnitType = UnitTypeName
|
||||||
|
|
||||||
|
if self.Players[PlayerName].Penalty > 100 then
|
||||||
|
if self.Players[PlayerName].PenaltyWarning < 1 then
|
||||||
|
MESSAGE:New( "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than 150, you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty,
|
||||||
|
"",
|
||||||
|
30,
|
||||||
|
"/PENALTYCOALITION" .. PlayerName
|
||||||
|
):ToAll()
|
||||||
|
self.Players[PlayerName].PenaltyWarning = self.Players[PlayerName].PenaltyWarning + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Players[PlayerName].Penalty > 150 then
|
||||||
|
ClientGroup = GROUP:NewFromDCSUnit( UnitData )
|
||||||
|
ClientGroup:Destroy()
|
||||||
|
MESSAGE:New( "Player '" .. PlayerName .. "' committed FRATRICIDE, he will be COURT MARTIALED and is DISMISSED from this mission!",
|
||||||
|
"",
|
||||||
|
10,
|
||||||
|
"/PENALTYCOALITION" .. PlayerName
|
||||||
|
):ToAll()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Registers Scores the players completing a Mission Task.
|
||||||
|
function SCORING:_AddMissionTaskScore( PlayerUnit, MissionName, Score )
|
||||||
|
self:F( { PlayerUnit, MissionName, Score } )
|
||||||
|
|
||||||
|
local PlayerName = PlayerUnit:getPlayerName()
|
||||||
|
|
||||||
|
if not self.Players[PlayerName].Mission[MissionName] then
|
||||||
|
self.Players[PlayerName].Mission[MissionName] = {}
|
||||||
|
self.Players[PlayerName].Mission[MissionName].ScoreTask = 0
|
||||||
|
self.Players[PlayerName].Mission[MissionName].ScoreMission = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
self:T( PlayerName )
|
||||||
|
self:T( self.Players[PlayerName].Mission[MissionName] )
|
||||||
|
|
||||||
|
self.Players[PlayerName].Score = self.Players[PlayerName].Score + Score
|
||||||
|
self.Players[PlayerName].Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
|
||||||
|
|
||||||
|
MESSAGE:New( "Player '" .. PlayerName .. "' has finished another Task in Mission '" .. MissionName .. "'. " ..
|
||||||
|
Score .. " Score points added.",
|
||||||
|
"", 20, "/SCORETASK" .. PlayerName ):ToAll()
|
||||||
|
|
||||||
|
self:ScoreCSV( PlayerName, "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:getName() )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Registers Mission Scores for possible multiple players that contributed in the Mission.
|
||||||
|
function SCORING:_AddMissionScore( MissionName, Score )
|
||||||
|
self:F( { MissionName, Score } )
|
||||||
|
|
||||||
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
||||||
|
|
||||||
|
if PlayerData.Mission[MissionName] then
|
||||||
|
PlayerData.Score = PlayerData.Score + Score
|
||||||
|
PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score
|
||||||
|
MESSAGE:New( "Player '" .. PlayerName .. "' has finished Mission '" .. MissionName .. "'. " ..
|
||||||
|
Score .. " Score points added.",
|
||||||
|
"", 20, "/SCOREMISSION" .. PlayerName ):ToAll()
|
||||||
|
self:ScoreCSV( PlayerName, "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Handles the OnHit event for the scoring.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param Event#EVENTDATA Event
|
||||||
|
function SCORING:_EventOnHit( Event )
|
||||||
|
self:F( { Event } )
|
||||||
|
|
||||||
|
local InitUnit = nil
|
||||||
|
local InitUnitName = ""
|
||||||
|
local InitGroup = nil
|
||||||
|
local InitGroupName = ""
|
||||||
|
local InitPlayerName = "dummy"
|
||||||
|
|
||||||
|
local InitCoalition = nil
|
||||||
|
local InitCategory = nil
|
||||||
|
local InitType = nil
|
||||||
|
local InitUnitCoalition = nil
|
||||||
|
local InitUnitCategory = nil
|
||||||
|
local InitUnitType = nil
|
||||||
|
|
||||||
|
local TargetUnit = nil
|
||||||
|
local TargetUnitName = ""
|
||||||
|
local TargetGroup = nil
|
||||||
|
local TargetGroupName = ""
|
||||||
|
local TargetPlayerName = ""
|
||||||
|
|
||||||
|
local TargetCoalition = nil
|
||||||
|
local TargetCategory = nil
|
||||||
|
local TargetType = nil
|
||||||
|
local TargetUnitCoalition = nil
|
||||||
|
local TargetUnitCategory = nil
|
||||||
|
local TargetUnitType = nil
|
||||||
|
|
||||||
|
if Event.IniDCSUnit then
|
||||||
|
|
||||||
|
InitUnit = Event.IniDCSUnit
|
||||||
|
InitUnitName = Event.IniDCSUnitName
|
||||||
|
InitGroup = Event.IniDCSGroup
|
||||||
|
InitGroupName = Event.IniDCSGroupName
|
||||||
|
InitPlayerName = InitUnit:getPlayerName()
|
||||||
|
|
||||||
|
InitCoalition = InitUnit:getCoalition()
|
||||||
|
--TODO: Workaround Client DCS Bug
|
||||||
|
--InitCategory = InitUnit:getCategory()
|
||||||
|
InitCategory = InitUnit:getDesc().category
|
||||||
|
InitType = InitUnit:getTypeName()
|
||||||
|
|
||||||
|
InitUnitCoalition = _SCORINGCoalition[InitCoalition]
|
||||||
|
InitUnitCategory = _SCORINGCategory[InitCategory]
|
||||||
|
InitUnitType = InitType
|
||||||
|
|
||||||
|
self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType , InitUnitCoalition, InitUnitCategory, InitUnitType } )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if Event.TgtDCSUnit then
|
||||||
|
|
||||||
|
TargetUnit = Event.TgtDCSUnit
|
||||||
|
TargetUnitName = Event.TgtDCSUnitName
|
||||||
|
TargetGroup = Event.TgtDCSGroup
|
||||||
|
TargetGroupName = Event.TgtDCSGroupName
|
||||||
|
TargetPlayerName = TargetUnit:getPlayerName()
|
||||||
|
|
||||||
|
TargetCoalition = TargetUnit:getCoalition()
|
||||||
|
--TODO: Workaround Client DCS Bug
|
||||||
|
--TargetCategory = TargetUnit:getCategory()
|
||||||
|
TargetCategory = TargetUnit:getDesc().category
|
||||||
|
TargetType = TargetUnit:getTypeName()
|
||||||
|
|
||||||
|
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
||||||
|
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
||||||
|
TargetUnitType = TargetType
|
||||||
|
|
||||||
|
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } )
|
||||||
|
end
|
||||||
|
|
||||||
|
if InitPlayerName ~= nil then -- It is a player that is hitting something
|
||||||
|
self:_AddPlayerFromUnit( InitUnit )
|
||||||
|
if self.Players[InitPlayerName] then -- This should normally not happen, but i'll test it anyway.
|
||||||
|
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
|
||||||
|
self:_AddPlayerFromUnit( TargetUnit )
|
||||||
|
self.Players[InitPlayerName].HitPlayers = self.Players[InitPlayerName].HitPlayers + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
self:T( "Hitting Something" )
|
||||||
|
-- What is he hitting?
|
||||||
|
if TargetCategory then
|
||||||
|
if not self.Players[InitPlayerName].Hit[TargetCategory] then
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory] = {}
|
||||||
|
end
|
||||||
|
if not self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] then
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] = {}
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = 0
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = 0
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = 0
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = 0
|
||||||
|
end
|
||||||
|
local Score = 0
|
||||||
|
if InitCoalition == TargetCoalition then
|
||||||
|
self.Players[InitPlayerName].Penalty = self.Players[InitPlayerName].Penalty + 10
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty + 10
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit + 1
|
||||||
|
MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit .. " times. Penalty: -" .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty ..
|
||||||
|
". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty,
|
||||||
|
"",
|
||||||
|
2,
|
||||||
|
"/PENALTY" .. InitPlayerName .. "/" .. InitUnitName
|
||||||
|
):ToAll()
|
||||||
|
self:ScoreCSV( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
|
else
|
||||||
|
self.Players[InitPlayerName].Score = self.Players[InitPlayerName].Score + 10
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score + 1
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit + 1
|
||||||
|
MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||||
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit .. " times. Score: " .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score ..
|
||||||
|
". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty,
|
||||||
|
"",
|
||||||
|
2,
|
||||||
|
"/SCORE" .. InitPlayerName .. "/" .. InitUnitName
|
||||||
|
):ToAll()
|
||||||
|
self:ScoreCSV( InitPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif InitPlayerName == nil then -- It is an AI hitting a player???
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function SCORING:ReportScoreAll()
|
||||||
|
|
||||||
|
env.info( "Hello World " )
|
||||||
|
|
||||||
|
local ScoreMessage = ""
|
||||||
|
local PlayerMessage = ""
|
||||||
|
|
||||||
|
self:T( "Score Report" )
|
||||||
|
|
||||||
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
||||||
|
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
||||||
|
self:T( "Score Player: " .. PlayerName )
|
||||||
|
|
||||||
|
-- Some variables
|
||||||
|
local InitUnitCoalition = _SCORINGCoalition[PlayerData.UnitCoalition]
|
||||||
|
local InitUnitCategory = _SCORINGCategory[PlayerData.UnitCategory]
|
||||||
|
local InitUnitType = PlayerData.UnitType
|
||||||
|
local InitUnitName = PlayerData.UnitName
|
||||||
|
|
||||||
|
local PlayerScore = 0
|
||||||
|
local PlayerPenalty = 0
|
||||||
|
|
||||||
|
ScoreMessage = ":\n"
|
||||||
|
|
||||||
|
local ScoreMessageHits = ""
|
||||||
|
|
||||||
|
for CategoryID, CategoryName in pairs( _SCORINGCategory ) do
|
||||||
|
self:T( CategoryName )
|
||||||
|
if PlayerData.Hit[CategoryID] then
|
||||||
|
local Score = 0
|
||||||
|
local ScoreHit = 0
|
||||||
|
local Penalty = 0
|
||||||
|
local PenaltyHit = 0
|
||||||
|
self:T( "Hit scores exist for player " .. PlayerName )
|
||||||
|
for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do
|
||||||
|
Score = Score + UnitData.Score
|
||||||
|
ScoreHit = ScoreHit + UnitData.ScoreHit
|
||||||
|
Penalty = Penalty + UnitData.Penalty
|
||||||
|
PenaltyHit = UnitData.PenaltyHit
|
||||||
|
end
|
||||||
|
local ScoreMessageHit = string.format( "%s:%d ", CategoryName, Score - Penalty )
|
||||||
|
self:T( ScoreMessageHit )
|
||||||
|
ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit
|
||||||
|
PlayerScore = PlayerScore + Score
|
||||||
|
PlayerPenalty = PlayerPenalty + Penalty
|
||||||
|
else
|
||||||
|
--ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ScoreMessageHits ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. " Hits: " .. ScoreMessageHits .. "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageKills = ""
|
||||||
|
for CategoryID, CategoryName in pairs( _SCORINGCategory ) do
|
||||||
|
self:T( "Kill scores exist for player " .. PlayerName )
|
||||||
|
if PlayerData.Kill[CategoryID] then
|
||||||
|
local Score = 0
|
||||||
|
local ScoreKill = 0
|
||||||
|
local Penalty = 0
|
||||||
|
local PenaltyKill = 0
|
||||||
|
|
||||||
|
for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do
|
||||||
|
Score = Score + UnitData.Score
|
||||||
|
ScoreKill = ScoreKill + UnitData.ScoreKill
|
||||||
|
Penalty = Penalty + UnitData.Penalty
|
||||||
|
PenaltyKill = PenaltyKill + UnitData.PenaltyKill
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageKill = string.format( " %s:%d ", CategoryName, Score - Penalty )
|
||||||
|
self:T( ScoreMessageKill )
|
||||||
|
ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill
|
||||||
|
|
||||||
|
PlayerScore = PlayerScore + Score
|
||||||
|
PlayerPenalty = PlayerPenalty + Penalty
|
||||||
|
else
|
||||||
|
--ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ScoreMessageKills ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. " Kills: " .. ScoreMessageKills .. "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageCoalitionChangePenalties = ""
|
||||||
|
if PlayerData.PenaltyCoalition ~= 0 then
|
||||||
|
ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition )
|
||||||
|
PlayerPenalty = PlayerPenalty + PlayerData.Penalty
|
||||||
|
end
|
||||||
|
if ScoreMessageCoalitionChangePenalties ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. " Coalition Penalties: " .. ScoreMessageCoalitionChangePenalties .. "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageMission = ""
|
||||||
|
local ScoreMission = 0
|
||||||
|
local ScoreTask = 0
|
||||||
|
for MissionName, MissionData in pairs( PlayerData.Mission ) do
|
||||||
|
ScoreMission = ScoreMission + MissionData.ScoreMission
|
||||||
|
ScoreTask = ScoreTask + MissionData.ScoreTask
|
||||||
|
ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; "
|
||||||
|
end
|
||||||
|
PlayerScore = PlayerScore + ScoreMission + ScoreTask
|
||||||
|
|
||||||
|
if ScoreMessageMission ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. " Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ")\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score:%d (%d Score -%d Penalties)%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function SCORING:ReportScorePlayer()
|
||||||
|
|
||||||
|
env.info( "Hello World " )
|
||||||
|
|
||||||
|
local ScoreMessage = ""
|
||||||
|
local PlayerMessage = ""
|
||||||
|
|
||||||
|
self:T( "Score Report" )
|
||||||
|
|
||||||
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
||||||
|
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
||||||
|
self:T( "Score Player: " .. PlayerName )
|
||||||
|
|
||||||
|
-- Some variables
|
||||||
|
local InitUnitCoalition = _SCORINGCoalition[PlayerData.UnitCoalition]
|
||||||
|
local InitUnitCategory = _SCORINGCategory[PlayerData.UnitCategory]
|
||||||
|
local InitUnitType = PlayerData.UnitType
|
||||||
|
local InitUnitName = PlayerData.UnitName
|
||||||
|
|
||||||
|
local PlayerScore = 0
|
||||||
|
local PlayerPenalty = 0
|
||||||
|
|
||||||
|
ScoreMessage = ""
|
||||||
|
|
||||||
|
local ScoreMessageHits = ""
|
||||||
|
|
||||||
|
for CategoryID, CategoryName in pairs( _SCORINGCategory ) do
|
||||||
|
self:T( CategoryName )
|
||||||
|
if PlayerData.Hit[CategoryID] then
|
||||||
|
local Score = 0
|
||||||
|
local ScoreHit = 0
|
||||||
|
local Penalty = 0
|
||||||
|
local PenaltyHit = 0
|
||||||
|
self:T( "Hit scores exist for player " .. PlayerName )
|
||||||
|
for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do
|
||||||
|
Score = Score + UnitData.Score
|
||||||
|
ScoreHit = ScoreHit + UnitData.ScoreHit
|
||||||
|
Penalty = Penalty + UnitData.Penalty
|
||||||
|
PenaltyHit = UnitData.PenaltyHit
|
||||||
|
end
|
||||||
|
local ScoreMessageHit = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit )
|
||||||
|
self:T( ScoreMessageHit )
|
||||||
|
ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit
|
||||||
|
PlayerScore = PlayerScore + Score
|
||||||
|
PlayerPenalty = PlayerPenalty + Penalty
|
||||||
|
else
|
||||||
|
--ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ScoreMessageHits ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. "\n Hits: " .. ScoreMessageHits .. " "
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageKills = ""
|
||||||
|
for CategoryID, CategoryName in pairs( _SCORINGCategory ) do
|
||||||
|
self:T( "Kill scores exist for player " .. PlayerName )
|
||||||
|
if PlayerData.Kill[CategoryID] then
|
||||||
|
local Score = 0
|
||||||
|
local ScoreKill = 0
|
||||||
|
local Penalty = 0
|
||||||
|
local PenaltyKill = 0
|
||||||
|
|
||||||
|
for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do
|
||||||
|
Score = Score + UnitData.Score
|
||||||
|
ScoreKill = ScoreKill + UnitData.ScoreKill
|
||||||
|
Penalty = Penalty + UnitData.Penalty
|
||||||
|
PenaltyKill = PenaltyKill + UnitData.PenaltyKill
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageKill = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill )
|
||||||
|
self:T( ScoreMessageKill )
|
||||||
|
ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill
|
||||||
|
|
||||||
|
PlayerScore = PlayerScore + Score
|
||||||
|
PlayerPenalty = PlayerPenalty + Penalty
|
||||||
|
else
|
||||||
|
--ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ScoreMessageKills ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. "\n Kills: " .. ScoreMessageKills .. " "
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageCoalitionChangePenalties = ""
|
||||||
|
if PlayerData.PenaltyCoalition ~= 0 then
|
||||||
|
ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition )
|
||||||
|
PlayerPenalty = PlayerPenalty + PlayerData.Penalty
|
||||||
|
end
|
||||||
|
if ScoreMessageCoalitionChangePenalties ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. "\n Coalition: " .. ScoreMessageCoalitionChangePenalties .. " "
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageMission = ""
|
||||||
|
local ScoreMission = 0
|
||||||
|
local ScoreTask = 0
|
||||||
|
for MissionName, MissionData in pairs( PlayerData.Mission ) do
|
||||||
|
ScoreMission = ScoreMission + MissionData.ScoreMission
|
||||||
|
ScoreTask = ScoreTask + MissionData.ScoreTask
|
||||||
|
ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; "
|
||||||
|
end
|
||||||
|
PlayerScore = PlayerScore + ScoreMission + ScoreTask
|
||||||
|
|
||||||
|
if ScoreMessageMission ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. "\n Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ") "
|
||||||
|
end
|
||||||
|
|
||||||
|
PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score = %d ( %d Score, -%d Penalties ):%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function SCORING:SecondsToClock(sSeconds)
|
||||||
|
local nSeconds = sSeconds
|
||||||
|
if nSeconds == 0 then
|
||||||
|
--return nil;
|
||||||
|
return "00:00:00";
|
||||||
|
else
|
||||||
|
nHours = string.format("%02.f", math.floor(nSeconds/3600));
|
||||||
|
nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours*60)));
|
||||||
|
nSecs = string.format("%02.f", math.floor(nSeconds - nHours*3600 - nMins *60));
|
||||||
|
return nHours..":"..nMins..":"..nSecs
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Opens a score CSV file to log the scores.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param #string ScoringCSV
|
||||||
|
-- @return #SCORING self
|
||||||
|
-- @usage
|
||||||
|
-- -- Open a new CSV file to log the scores of the game Gori Valley. Let the name of the CSV file begin with "Player Scores".
|
||||||
|
-- ScoringObject = SCORING:New( "Gori Valley" )
|
||||||
|
-- ScoringObject:OpenCSV( "Player Scores" )
|
||||||
|
function SCORING:OpenCSV( ScoringCSV )
|
||||||
|
self:F( ScoringCSV )
|
||||||
|
|
||||||
|
if lfs and io and os then
|
||||||
|
if ScoringCSV then
|
||||||
|
self.ScoringCSV = ScoringCSV
|
||||||
|
local fdir = lfs.writedir() .. [[Logs\]] .. self.ScoringCSV .. " " .. os.date( "%Y-%m-%d %H-%M-%S" ) .. ".csv"
|
||||||
|
|
||||||
|
self.CSVFile, self.err = io.open( fdir, "w+" )
|
||||||
|
if not self.CSVFile then
|
||||||
|
error( "Error: Cannot open CSV file in " .. lfs.writedir() )
|
||||||
|
end
|
||||||
|
|
||||||
|
self.CSVFile:write( '"GameName","RunTime","Time","PlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition","TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n' )
|
||||||
|
|
||||||
|
self.RunTime = os.date("%y-%m-%d_%H-%M-%S")
|
||||||
|
else
|
||||||
|
error( "A string containing the CSV file name must be given." )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:E( "The MissionScripting.lua file has not been changed to allow lfs, io and os modules to be used..." )
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Registers a score for a player.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param #string PlayerName The name of the player.
|
||||||
|
-- @param #string ScoreType The type of the score.
|
||||||
|
-- @param #string ScoreTimes The amount of scores achieved.
|
||||||
|
-- @param #string ScoreAmount The score given.
|
||||||
|
-- @param #string PlayerUnitName The unit name of the player.
|
||||||
|
-- @param #string PlayerUnitCoalition The coalition of the player unit.
|
||||||
|
-- @param #string PlayerUnitCategory The category of the player unit.
|
||||||
|
-- @param #string PlayerUnitType The type of the player unit.
|
||||||
|
-- @param #string TargetUnitName The name of the target unit.
|
||||||
|
-- @param #string TargetUnitCoalition The coalition of the target unit.
|
||||||
|
-- @param #string TargetUnitCategory The category of the target unit.
|
||||||
|
-- @param #string TargetUnitType The type of the target unit.
|
||||||
|
-- @return #SCORING self
|
||||||
|
function SCORING:ScoreCSV( PlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
|
--write statistic information to file
|
||||||
|
local ScoreTime = self:SecondsToClock( timer.getTime() )
|
||||||
|
PlayerName = PlayerName:gsub( '"', '_' )
|
||||||
|
|
||||||
|
if PlayerUnitName and PlayerUnitName ~= '' then
|
||||||
|
local PlayerUnit = Unit.getByName( PlayerUnitName )
|
||||||
|
|
||||||
|
if PlayerUnit then
|
||||||
|
if not PlayerUnitCategory then
|
||||||
|
--PlayerUnitCategory = SCORINGCategory[PlayerUnit:getCategory()]
|
||||||
|
PlayerUnitCategory = _SCORINGCategory[PlayerUnit:getDesc().category]
|
||||||
|
end
|
||||||
|
|
||||||
|
if not PlayerUnitCoalition then
|
||||||
|
PlayerUnitCoalition = _SCORINGCoalition[PlayerUnit:getCoalition()]
|
||||||
|
end
|
||||||
|
|
||||||
|
if not PlayerUnitType then
|
||||||
|
PlayerUnitType = PlayerUnit:getTypeName()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
PlayerUnitName = ''
|
||||||
|
PlayerUnitCategory = ''
|
||||||
|
PlayerUnitCoalition = ''
|
||||||
|
PlayerUnitType = ''
|
||||||
|
end
|
||||||
|
else
|
||||||
|
PlayerUnitName = ''
|
||||||
|
PlayerUnitCategory = ''
|
||||||
|
PlayerUnitCoalition = ''
|
||||||
|
PlayerUnitType = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
if not TargetUnitCoalition then
|
||||||
|
TargetUnitCoalition = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
if not TargetUnitCategory then
|
||||||
|
TargetUnitCategory = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
if not TargetUnitType then
|
||||||
|
TargetUnitType = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
if not TargetUnitName then
|
||||||
|
TargetUnitName = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
if lfs and io and os then
|
||||||
|
self.CSVFile:write(
|
||||||
|
'"' .. self.GameName .. '"' .. ',' ..
|
||||||
|
'"' .. self.RunTime .. '"' .. ',' ..
|
||||||
|
'' .. ScoreTime .. '' .. ',' ..
|
||||||
|
'"' .. PlayerName .. '"' .. ',' ..
|
||||||
|
'"' .. ScoreType .. '"' .. ',' ..
|
||||||
|
'"' .. PlayerUnitCoalition .. '"' .. ',' ..
|
||||||
|
'"' .. PlayerUnitCategory .. '"' .. ',' ..
|
||||||
|
'"' .. PlayerUnitType .. '"' .. ',' ..
|
||||||
|
'"' .. PlayerUnitName .. '"' .. ',' ..
|
||||||
|
'"' .. TargetUnitCoalition .. '"' .. ',' ..
|
||||||
|
'"' .. TargetUnitCategory .. '"' .. ',' ..
|
||||||
|
'"' .. TargetUnitType .. '"' .. ',' ..
|
||||||
|
'"' .. TargetUnitName .. '"' .. ',' ..
|
||||||
|
'' .. ScoreTimes .. '' .. ',' ..
|
||||||
|
'' .. ScoreAmount
|
||||||
|
)
|
||||||
|
|
||||||
|
self.CSVFile:write( "\n" )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function SCORING:CloseCSV()
|
||||||
|
if lfs and io and os then
|
||||||
|
self.CSVFile:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user