mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
701 lines
28 KiB
Lua
701 lines
28 KiB
Lua
--- Administers the Initial Sets of the Mission Templates as defined within the Mission Editor.
|
|
-- Administers the Spawning of new Groups within the DCSRTE and administers these new Groups within the DATABASE object(s).
|
|
-- @classmod DATABASE
|
|
|
|
Include.File( "Routines" )
|
|
Include.File( "Base" )
|
|
Include.File( "Menu" )
|
|
|
|
DATABASE = {
|
|
ClassName = "DATABASE",
|
|
Units = {},
|
|
Groups = {},
|
|
NavPoints = {},
|
|
Statics = {},
|
|
Players = {},
|
|
ClientsByName = {},
|
|
ClientsByID = {},
|
|
}
|
|
|
|
DATABASECoalition =
|
|
{
|
|
[1] = "Red",
|
|
[2] = "Blue",
|
|
}
|
|
|
|
DATABASECategory =
|
|
{
|
|
[Unit.Category.AIRPLANE] = "Plane",
|
|
[Unit.Category.HELICOPTER] = "Helicopter",
|
|
[Unit.Category.GROUND_UNIT] = "Ground",
|
|
[Unit.Category.SHIP] = "Ship",
|
|
[Unit.Category.STRUCTURE] = "Structure",
|
|
}
|
|
|
|
|
|
--- Creates a new DATABASE Object to administer the Groups defined and alive within the DCSRTE.
|
|
-- @treturn DATABASE
|
|
-- @usage
|
|
-- -- Define a new DATABASE Object. This DBObject will contain a reference to all Group and Unit Templates defined within the ME and the DCSRTE.
|
|
-- DBObject = DATABASE:New()
|
|
function DATABASE:New()
|
|
trace.f(self.ClassName )
|
|
|
|
-- Inherits from BASE
|
|
local self = BASE:Inherit( self, BASE:New() )
|
|
|
|
self.Navpoints = {}
|
|
self.Units = {}
|
|
--Build routines.db.units and self.Navpoints
|
|
for coa_name, coa_data in pairs(env.mission.coalition) do
|
|
|
|
if (coa_name == 'red' or coa_name == 'blue') and type(coa_data) == 'table' then
|
|
self.Units[coa_name] = {}
|
|
|
|
----------------------------------------------
|
|
-- build nav points DB
|
|
self.Navpoints[coa_name] = {}
|
|
if coa_data.nav_points then --navpoints
|
|
for nav_ind, nav_data in pairs(coa_data.nav_points) do
|
|
|
|
if type(nav_data) == 'table' then
|
|
self.Navpoints[coa_name][nav_ind] = routines.utils.deepCopy(nav_data)
|
|
|
|
self.Navpoints[coa_name][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory.
|
|
self.Navpoints[coa_name][nav_ind]['point'] = {} -- point is used by SSE, support it.
|
|
self.Navpoints[coa_name][nav_ind]['point']['x'] = nav_data.x
|
|
self.Navpoints[coa_name][nav_ind]['point']['y'] = 0
|
|
self.Navpoints[coa_name][nav_ind]['point']['z'] = nav_data.y
|
|
end
|
|
end
|
|
end
|
|
-------------------------------------------------
|
|
if coa_data.country then --there is a country table
|
|
for cntry_id, cntry_data in pairs(coa_data.country) do
|
|
|
|
local countryName = string.lower(cntry_data.name)
|
|
self.Units[coa_name][countryName] = {}
|
|
self.Units[coa_name][countryName]["countryId"] = cntry_data.id
|
|
|
|
if type(cntry_data) == 'table' then --just making sure
|
|
|
|
for obj_type_name, obj_type_data in pairs(cntry_data) do
|
|
|
|
if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then --should be an unncessary check
|
|
|
|
local category = obj_type_name
|
|
|
|
if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's a group!
|
|
|
|
self.Units[coa_name][countryName][category] = {}
|
|
|
|
for group_num, GroupTemplate in pairs(obj_type_data.group) do
|
|
|
|
if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group
|
|
self:_RegisterGroup( GroupTemplate )
|
|
end --if GroupTemplate and GroupTemplate.units then
|
|
end --for group_num, GroupTemplate in pairs(obj_type_data.group) do
|
|
end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then
|
|
end --if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then
|
|
end --for obj_type_name, obj_type_data in pairs(cntry_data) do
|
|
end --if type(cntry_data) == 'table' then
|
|
end --for cntry_id, cntry_data in pairs(coa_data.country) do
|
|
end --if coa_data.country then --there is a country table
|
|
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
|
|
|
|
--self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth )
|
|
self:AddEvent( world.event.S_EVENT_DEAD, self.OnDeadOrCrash )
|
|
self:AddEvent( world.event.S_EVENT_CRASH, self.OnDeadOrCrash )
|
|
|
|
self:AddEvent( world.event.S_EVENT_HIT, self.OnHit)
|
|
|
|
self:EnableEvents()
|
|
|
|
self.SchedulerId = routines.scheduleFunction( DATABASE._FollowPlayers, { self }, 0, 5 )
|
|
|
|
self:ScoreMenu()
|
|
|
|
|
|
return self
|
|
end
|
|
|
|
--- Instantiate new Groups within the DCSRTE.
|
|
-- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined:
|
|
-- SpawnCountryID, SpawnCategoryID
|
|
-- This method is used by the SPAWN class.
|
|
function DATABASE:Spawn( SpawnTemplate )
|
|
trace.f( self.ClassName, SpawnTemplate )
|
|
|
|
trace.i( self.ClassName, { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID, SpawnTemplate.name } )
|
|
|
|
local SpawnCountryID = SpawnTemplate.SpawnCountryID
|
|
local SpawnCategoryID = SpawnTemplate.SpawnCategoryID
|
|
|
|
SpawnTemplate.SpawnCoalitionID = nil
|
|
SpawnTemplate.SpawnCountryID = nil
|
|
SpawnTemplate.SpawnCategoryID = nil
|
|
|
|
self:_RegisterGroup( SpawnTemplate )
|
|
coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate )
|
|
end
|
|
|
|
--- Set a status to a Group within the Database, this to check crossing events for example.
|
|
function DATABASE:SetStatusGroup( GroupName, Status )
|
|
trace.f( self.ClassName, Status )
|
|
|
|
self.Groups[GroupName].Status = Status
|
|
end
|
|
|
|
--- Get a status to a Group within the Database, this to check crossing events for example.
|
|
function DATABASE:GetStatusGroup( GroupName )
|
|
trace.f( self.ClassName, Status )
|
|
|
|
if self.Groups[GroupName] then
|
|
return self.Groups[GroupName].Status
|
|
else
|
|
return ""
|
|
end
|
|
end
|
|
|
|
|
|
--- Private
|
|
-- @section Private
|
|
|
|
--- Registers new Group Templates within the DATABASE Object.
|
|
function DATABASE:_RegisterGroup( GroupTemplate )
|
|
|
|
local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name)
|
|
|
|
if not self.Groups[GroupTemplateName] then
|
|
self.Groups[GroupTemplateName] = {}
|
|
self.Groups[GroupTemplateName].Status = nil
|
|
end
|
|
self.Groups[GroupTemplateName].GroupName = GroupTemplateName
|
|
self.Groups[GroupTemplateName].Template = GroupTemplate
|
|
self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units
|
|
trace.i( self.ClassName, { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } )
|
|
|
|
for unit_num, UnitTemplate in pairs(GroupTemplate.units) do
|
|
|
|
local UnitTemplateName = env.getValueDictByKey(UnitTemplate.name)
|
|
self.Units[UnitTemplateName] = {}
|
|
self.Units[UnitTemplateName].UnitName = UnitTemplateName
|
|
self.Units[UnitTemplateName].Template = UnitTemplate
|
|
self.Units[UnitTemplateName].GroupName = GroupTemplateName
|
|
self.Units[UnitTemplateName].GroupTemplate = GroupTemplate
|
|
self.Units[UnitTemplateName].GroupId = GroupTemplate.groupId
|
|
if UnitTemplate.skill and (UnitTemplate.skill == "Client" or UnitTemplate.skill == "Player") then
|
|
self.ClientsByName[UnitTemplateName] = UnitTemplate
|
|
self.ClientsByID[UnitTemplate.unitId] = UnitTemplate
|
|
end
|
|
trace.i( self.ClassName, { "Unit", self.Units[UnitTemplateName].UnitName } )
|
|
end
|
|
end
|
|
|
|
--- Events
|
|
-- @section Events
|
|
|
|
--- Track DCSRTE DEAD or CRASH events for the internal scoring.
|
|
function DATABASE:OnDeadOrCrash( event )
|
|
trace.f( self.ClassName, { event } )
|
|
|
|
local TargetUnitName = nil
|
|
local TargetGroupName = nil
|
|
local TargetPlayerName = nil
|
|
local TargetCoalition = nil
|
|
local TargetCategory = nil
|
|
local TargetType = nil
|
|
local TargetUnitCoalition = nil
|
|
local TargetUnitCategory = nil
|
|
local TargetUnitType = nil
|
|
|
|
if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then
|
|
TargetUnitName = event.initiator:getName()
|
|
TargetGroupName = Unit.getGroup(event.initiator):getName()
|
|
TargetPlayerName = event.initiator:getPlayerName()
|
|
|
|
TargetCoalition = Unit.getGroup(event.initiator):getCoalition()
|
|
TargetCategory = Unit.getGroup(event.initiator):getCategory()
|
|
TargetType = event.initiator:getTypeName()
|
|
|
|
TargetUnitCoalition = DATABASECoalition[TargetCoalition]
|
|
TargetUnitCategory = DATABASECategory[TargetCategory]
|
|
TargetUnitType = TargetType
|
|
|
|
trace.i( self.ClassName, { 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.
|
|
trace.i( self.ClassName, "Something got killed" )
|
|
|
|
-- Some variables
|
|
local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition]
|
|
local InitUnitCategory = DATABASECategory[PlayerData.UnitCategory]
|
|
local InitUnitType = PlayerData.UnitType
|
|
local InitUnitName = PlayerData.UnitName
|
|
|
|
-- 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 PlayerData.UnitCoalition == TargetCoalition then
|
|
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 target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
|
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Penalty,
|
|
"Game Status: Score", 20, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
|
self:ScoreAdd( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
else
|
|
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 a target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
|
PlayerData.Kill[TargetCategory][TargetType].ScoreKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Score,
|
|
"Game Status: Score", 20, "/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()
|
|
trace.scheduled( self.ClassName, "_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
|
|
trace.l( self.ClassName, "_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 )
|
|
trace.f( self.ClassName, UnitData )
|
|
|
|
if UnitData:isExist() then
|
|
local UnitName = UnitData:getName()
|
|
local GroupData = UnitData:getGroup()
|
|
|
|
if GroupData and GroupData:isExist() then
|
|
local GroupName = GroupData:getName()
|
|
local PlayerName = UnitData:getPlayerName()
|
|
|
|
trace.i(self.ClassName, "Player : " .. PlayerName .. " Unit : " .. UnitName .. " Group : " .. GroupName )
|
|
|
|
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].Penalty = 0
|
|
self.Players[PlayerName].PenaltyCoalition = 0
|
|
end
|
|
|
|
if not self.Players[PlayerName].UnitCoalition then
|
|
self.Players[PlayerName].UnitCoalition = Unit.getGroup(UnitData):getCoalition()
|
|
else
|
|
if self.Players[PlayerName].UnitCoalition ~= Unit.getGroup(UnitData):getCoalition() 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[Unit.getGroup(UnitData):getCoalition()] ..
|
|
"(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.",
|
|
"Game Status: Penalty", 20, "/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, DATABASECategory[Unit.getGroup(UnitData):getCoalition()], DATABASECategory[Unit.getGroup(UnitData):getCategory()], UnitData:getTypeName() )
|
|
end
|
|
end
|
|
self.Players[PlayerName].UnitName = UnitName
|
|
self.Players[PlayerName].GroupName = GroupName
|
|
|
|
self.Players[PlayerName].UnitCoalition = Unit.getGroup(UnitData):getCoalition()
|
|
self.Players[PlayerName].UnitCategory = Unit.getGroup(UnitData):getCategory()
|
|
self.Players[PlayerName].UnitType = UnitData:getTypeName()
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
--- Registers Scores the players completing a Mission Task.
|
|
function DATABASE:_AddMissionTaskScore( PlayerUnit, MissionName, Score )
|
|
trace.f( self.ClassName, { 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.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.",
|
|
"Game Status: Task Completion", 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 )
|
|
trace.f( self.ClassName, { PlayerUnit, MissionName, Score } )
|
|
|
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
|
|
|
if PlayerData.Mission[MissionName] then
|
|
PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score
|
|
MESSAGE:New( "Player '" .. PlayerName .. "' has finished Mission '" .. MissionName .. "'. " ..
|
|
Score .. " Score points added.",
|
|
"Game Status: Mission Completion", 20, "/SCOREMISSION" .. PlayerName ):ToAll()
|
|
_Database:ScoreAdd( PlayerName, "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score )
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Events
|
|
-- @section Events
|
|
|
|
function DATABASE:OnHit( event )
|
|
trace.f( self.ClassName, { event } )
|
|
|
|
local InitUnitName = nil
|
|
local InitGroupName = nil
|
|
local InitPlayerName = nil
|
|
|
|
local InitCoalition = nil
|
|
local InitCategory = nil
|
|
local InitType = nil
|
|
local InitUnitCoalition = nil
|
|
local InitUnitCategory = nil
|
|
local InitUnitType = nil
|
|
|
|
local TargetUnitName = nil
|
|
local TargetGroupName = nil
|
|
local TargetPlayerName = nil
|
|
|
|
local TargetCoalition = nil
|
|
local TargetCategory = nil
|
|
local TargetType = nil
|
|
local TargetUnitCoalition = nil
|
|
local TargetUnitCategory = nil
|
|
local TargetUnitType = nil
|
|
|
|
if event.initiator and event.initiator:getName() then
|
|
|
|
if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then
|
|
|
|
InitUnitName = event.initiator:getName()
|
|
InitGroupName = Unit.getGroup(event.initiator):getName()
|
|
InitPlayerName = event.initiator:getPlayerName()
|
|
|
|
InitCoalition = Unit.getGroup(event.initiator):getCoalition()
|
|
InitCategory = Unit.getGroup(event.initiator):getCategory()
|
|
InitType = event.initiator:getTypeName()
|
|
|
|
InitUnitCoalition = DATABASECoalition[InitCoalition]
|
|
InitUnitCategory = DATABASECategory[InitCategory]
|
|
InitUnitType = InitType
|
|
|
|
trace.i( self.ClassName, { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType , InitUnitCoalition, InitUnitCategory, InitUnitType } )
|
|
end
|
|
|
|
|
|
if event.target and Object.getCategory(event.target) == Object.Category.UNIT then
|
|
|
|
TargetUnitName = event.target:getName()
|
|
TargetGroupName = Unit.getGroup(event.target):getName()
|
|
TargetPlayerName = event.target:getPlayerName()
|
|
|
|
TargetCoalition = Unit.getGroup(event.target):getCoalition()
|
|
TargetCategory = Unit.getGroup(event.target):getCategory()
|
|
TargetType = event.target:getTypeName()
|
|
|
|
TargetUnitCoalition = DATABASECoalition[TargetCoalition]
|
|
TargetUnitCategory = DATABASECategory[TargetCategory]
|
|
TargetUnitType = TargetType
|
|
|
|
trace.i( self.ClassName, { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } )
|
|
end
|
|
|
|
if InitPlayerName ~= nil then -- It is a player that is hitting something
|
|
self:_AddPlayerFromUnit( event.initiator )
|
|
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( event.target )
|
|
self.Players[InitPlayerName].HitPlayers = self.Players[InitPlayerName].HitPlayers + 1
|
|
end
|
|
|
|
trace.i( self.ClassName, "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].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,
|
|
"Game Status: Penalty", 20, "/PENALTY" .. InitPlayerName .. "/" .. InitUnitName ):ToAll()
|
|
self:ScoreAdd( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
else
|
|
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,
|
|
"Game Status: Score", 20, "/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
|
|
end
|
|
|
|
function DATABASE:ReportScoreAll()
|
|
|
|
local ScoreMessage = ""
|
|
local PlayerMessage = ""
|
|
|
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
|
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
|
trace.i( self.ClassName, "Score" )
|
|
|
|
-- 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
|
|
if PlayerData.Hit[CategoryID] then
|
|
local Score = 0
|
|
local ScoreHit = 0
|
|
local Penalty = 0
|
|
local PenaltyHit = 0
|
|
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
|
|
ScoreMessageHits = ScoreMessageHits .. string.format( " %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit )
|
|
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 .. " "
|
|
end
|
|
|
|
local ScoreMessageKills = ""
|
|
for CategoryID, CategoryName in pairs( DATABASECategory ) do
|
|
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
|
|
|
|
ScoreMessageKills = ScoreMessageKills .. string.format( " %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill )
|
|
|
|
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 .. " "
|
|
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: " .. 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 .. " Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ") "
|
|
end
|
|
|
|
PlayerMessage = string.format( " Player '%s' Score = %d ( %d Score, -%d Penalties ):", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty )
|
|
MESSAGE:New( PlayerMessage .. ScoreMessage, "Player Scores", 30, "/SCORE/" .. PlayerName ):ToAll()
|
|
end
|
|
end
|
|
end
|
|
|
|
function DATABASE:ReportScorePlayer()
|
|
|
|
|
|
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()
|
|
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( '"Run-ID";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
|
|
|
|
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[Unit.getGroup(PlayerUnit):getCategory()]
|
|
end
|
|
|
|
if not PlayerUnitCoalition then
|
|
PlayerUnitCoalition = DATABASECoalition[Unit.getGroup(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
|
|
|
|
self.StatFile:write( '"' .. self.RunID .. '";' .. ScoreTime .. ';"' .. PlayerName .. '";"' .. ScoreType .. '";"' ..
|
|
PlayerUnitCoalition .. '";"' .. PlayerUnitCategory .. '";"' .. PlayerUnitType .. '";"' .. PlayerUnitName .. '";"' ..
|
|
TargetUnitCoalition .. '";"' .. TargetUnitCategory .. '";"' .. TargetUnitType .. '";"' .. TargetUnitName .. '";' ..
|
|
ScoreTimes .. ';' .. ScoreAmount )
|
|
self.StatFile:write( "\n" )
|
|
end
|
|
|
|
function LogClose()
|
|
self.StatFile:close()
|
|
end
|
|
|
|
_Database = DATABASE:New()
|
|
_Database:ScoreOpen()
|
|
|