mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-07-19 09:15:12 +00:00
650 lines
22 KiB
Lua
650 lines
22 KiB
Lua
--- **Functional** - (R2.5) - Simple and Persistent Player Scoring.
|
|
--
|
|
--
|
|
-- Score!
|
|
--
|
|
--
|
|
-- ## Main Features:
|
|
--
|
|
-- * Good stuff.
|
|
--
|
|
-- ===
|
|
--
|
|
-- ### Author: **funkyfranky**
|
|
-- @module Functional.SimpleScore
|
|
-- @image Functional_SimpleScore.png
|
|
|
|
|
|
--- SCORE class.
|
|
-- @type SCORE
|
|
-- @field #string ClassName Name of the class.
|
|
-- @field #boolean Debug Debug mode. Messages to all about status.
|
|
-- @field #string lid Class id string for output to DCS log file.
|
|
-- @field #table menuadded Table of groups the menu was added for.
|
|
-- @field #boolean menudisabled If true, F10 menu for players is disabled.
|
|
-- @field #table playerscores Player score table.
|
|
-- @extends Core.Fsm#FSM
|
|
|
|
--- Goooooaaaallllll!
|
|
--
|
|
-- ===
|
|
--
|
|
-- 
|
|
--
|
|
-- # The Scoring Concept
|
|
--
|
|
-- Score
|
|
--
|
|
-- # Basic Script
|
|
--
|
|
-- -- Create a new score object.
|
|
-- score=SCORE:New()
|
|
--
|
|
-- -- Start score.
|
|
-- SCORE:Start()
|
|
--
|
|
-- # Training Zones
|
|
--
|
|
-- Players are only protected if they are inside one of the training zones.
|
|
--
|
|
-- -- Create a new missile trainer object.
|
|
-- SCORE=SCORE:New()
|
|
--
|
|
-- -- Add training zones.
|
|
-- SCORE:AddSafeZone(ZONE:New("Training Zone Alpha")
|
|
-- SCORE:AddSafeZone(ZONE:New("Training Zone Bravo")
|
|
--
|
|
-- -- Start missile trainer.
|
|
-- SCORE:Start()
|
|
--
|
|
--
|
|
-- Todo!
|
|
--
|
|
--
|
|
-- @field #SCORE
|
|
SCORE = {
|
|
ClassName = "SCORE",
|
|
Debug = false,
|
|
lid = nil,
|
|
menuadded = {},
|
|
menudisabled = nil,
|
|
playerscores = nil,
|
|
}
|
|
|
|
|
|
--- Player data table holding all important parameters of each player.
|
|
-- @type SCORE.PlayerData
|
|
-- @field Wrapper.Unit#UNIT unit Aircraft of the player.
|
|
-- @field #string unitname Name of the unit.
|
|
-- @field Wrapper.Client#CLIENT client Client object of player.
|
|
-- @field #string callsign Callsign of player.
|
|
-- @field Wrapper.Group#GROUP group Aircraft group of player.
|
|
-- @field #string groupname Name of the the player aircraft group.
|
|
-- @field #string name Player name.
|
|
-- @field #number coalition Coalition number of player.
|
|
-- @field #table hit Table of hit units.
|
|
|
|
--- Hit unit data.
|
|
-- @type SCORE.HitData
|
|
-- @field #string unitname Name of the hit unit.
|
|
-- @field #string category Category of hit unit.
|
|
-- @field #number score Score
|
|
-- @field #boolean friendly If true, unit is friendly.
|
|
-- @field #boolean destroyed If true, unit was destroyed.
|
|
|
|
|
|
|
|
--- Create a new SCORE class object.
|
|
-- @param #SCORE self
|
|
-- @return #SCORE self.
|
|
function SCORE:New()
|
|
|
|
self.lid="SCORE | "
|
|
|
|
-- Inherit everthing from FSM class.
|
|
local self=BASE:Inherit(self, FSM:New()) -- #SCORE
|
|
|
|
-- Defaults:
|
|
self:SetDefaultMissileDestruction(true)
|
|
self:SetDefaultLaunchAlerts(true)
|
|
self:SetDefaultLaunchMarks(true)
|
|
self:SetExplosionPower()
|
|
|
|
-- Start State.
|
|
self:SetStartState("Stopped")
|
|
|
|
-- Add FSM transitions.
|
|
-- From State --> Event --> To State
|
|
self:AddTransition("Stopped", "Start", "Running") -- Start SCORE script.
|
|
self:AddTransition("*", "Status", "*") -- Status update.
|
|
|
|
------------------------
|
|
--- Pseudo Functions ---
|
|
------------------------
|
|
|
|
--- Triggers the FSM event "Start". Starts the SCORE. Initializes parameters and starts event handlers.
|
|
-- @function [parent=#SCORE] Start
|
|
-- @param #SCORE self
|
|
|
|
--- Triggers the FSM event "Start" after a delay. Starts the SCORE. Initializes parameters and starts event handlers.
|
|
-- @function [parent=#SCORE] __Start
|
|
-- @param #SCORE self
|
|
-- @param #number delay Delay in seconds.
|
|
|
|
--- Triggers the FSM event "Stop". Stops the SCORE and all its event handlers.
|
|
-- @param #SCORE self
|
|
|
|
--- Triggers the FSM event "Stop" after a delay. Stops the SCORE and all its event handlers.
|
|
-- @function [parent=#SCORE] __Stop
|
|
-- @param #SCORE self
|
|
-- @param #number delay Delay in seconds.
|
|
|
|
--- Triggers the FSM event "Status".
|
|
-- @function [parent=#SCORE] Status
|
|
-- @param #SCORE self
|
|
|
|
--- Triggers the FSM event "Status" after a delay.
|
|
-- @function [parent=#SCORE] __Status
|
|
-- @param #SCORE self
|
|
-- @param #number delay Delay in seconds.
|
|
|
|
return self
|
|
end
|
|
|
|
|
|
--- On after Start event. Starts the missile trainer and adds event handlers.
|
|
-- @param #SCORE self
|
|
-- @param #string From From state.
|
|
-- @param #string Event Event.
|
|
-- @param #string To To state.
|
|
function SCORE:onafterStart(From, Event, To)
|
|
|
|
-- Short info.
|
|
local text=string.format("Starting SCORE v%s", SCORE.version)
|
|
env.info(text)
|
|
|
|
-- Init player scores table.
|
|
self.playerscores={}
|
|
|
|
-- Event handlers
|
|
self:HandleEvent(EVENTS.Dead, self._EventDeadOrCrash)
|
|
self:HandleEvent(EVENTS.Crash, self._EventDeadOrCrash)
|
|
self:HandleEvent(EVENTS.Hit, self._EventHit)
|
|
self:HandleEvent(EVENTS.Birth)
|
|
self:HandleEvent(EVENTS.PlayerLeaveUnit)
|
|
|
|
-- Handle events:
|
|
self:HandleEvent(EVENTS.Birth)
|
|
self:HandleEvent(EVENTS.Shot)
|
|
|
|
if self.Debug then
|
|
self:TraceClass(self.ClassName)
|
|
self:TraceLevel(2)
|
|
end
|
|
|
|
self:__Status(-10)
|
|
end
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
-- Event Functions
|
|
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
--- SCORE event handler for event birth.
|
|
-- @param #SCORE self
|
|
-- @param Core.Event#EVENTDATA EventData
|
|
function SCORE:OnEventBirth(EventData)
|
|
self:F3({eventbirth = EventData})
|
|
|
|
-- Nil checks.
|
|
if EventData==nil then
|
|
self:E(self.lid.."ERROR: EventData=nil in event BIRTH!")
|
|
self:E(EventData)
|
|
return
|
|
end
|
|
if EventData.IniUnit==nil then
|
|
self:E(self.lid.."ERROR: EventData.IniUnit=nil in event BIRTH!")
|
|
self:E(EventData)
|
|
return
|
|
end
|
|
|
|
-- Player unit and name.
|
|
local _unitName=EventData.IniUnitName
|
|
local playerunit, playername=self:_GetPlayerUnitAndName(_unitName)
|
|
|
|
-- Debug info.
|
|
self:T(self.lid.."BIRTH: unit = "..tostring(EventData.IniUnitName))
|
|
self:T(self.lid.."BIRTH: group = "..tostring(EventData.IniGroupName))
|
|
self:T(self.lid.."BIRTH: player = "..tostring(playername))
|
|
|
|
-- Check if player entered.
|
|
if playerunit and playername then
|
|
|
|
local _uid=playerunit:GetID()
|
|
local _group=playerunit:GetGroup()
|
|
local _callsign=playerunit:GetCallsign()
|
|
|
|
-- Debug output.
|
|
local text=string.format("Pilot %s, callsign %s entered unit %s of group %s.", playername, _callsign, _unitName, _group:GetName())
|
|
self:T(self.lid..text)
|
|
MESSAGE:New(text, 5):ToAllIf(self.Debug)
|
|
|
|
-- Add F10 radio menu for player.
|
|
if not self.menudisabled then
|
|
SCHEDULER:New(nil, self._AddF10Commands, {self,_unitName}, 0.1)
|
|
end
|
|
|
|
-- Player data.
|
|
local playerData={} --#SCORE.PlayerData
|
|
|
|
-- Player unit, client and callsign.
|
|
playerData.unit = playerunit
|
|
playerData.unitname = _unitName
|
|
playerData.group = _group
|
|
playerData.groupname = _group:GetName()
|
|
playerData.name = playername
|
|
playerData.callsign = playerData.unit:GetCallsign()
|
|
playerData.client = CLIENT:FindByName(_unitName, nil, true)
|
|
playerData.coalition = _group:GetCoalition()
|
|
|
|
playerData.hit = playerData.hit or {}
|
|
|
|
-- Init player data.
|
|
self.players[playername]=playerData
|
|
|
|
end
|
|
end
|
|
|
|
|
|
--- Handles the OnHit event for the scoring.
|
|
-- @param #SCORE self
|
|
-- @param Core.Event#EVENTDATA Event
|
|
function SCORE:_EventOnHit(Event)
|
|
self:F( { Event } )
|
|
|
|
local InitUnit = nil
|
|
local InitUNIT = nil
|
|
local InitUnitName = ""
|
|
local InitGroup = nil
|
|
local InitGroupName = ""
|
|
local InitPlayerName = nil
|
|
|
|
local InitCoalition = nil
|
|
local InitCategory = nil
|
|
local InitType = nil
|
|
local InitUnitCoalition = nil
|
|
local InitUnitCategory = nil
|
|
local InitUnitType = nil
|
|
|
|
local TargetUnit = nil
|
|
local TargetUNIT = nil
|
|
local TargetUnitName = ""
|
|
local TargetGroup = nil
|
|
local TargetGroupName = ""
|
|
local TargetPlayerName = nil
|
|
|
|
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
|
|
InitUNIT = Event.IniUnit
|
|
InitUnitName = Event.IniDCSUnitName
|
|
InitGroup = Event.IniDCSGroup
|
|
InitGroupName = Event.IniDCSGroupName
|
|
InitPlayerName = Event.IniPlayerName
|
|
|
|
InitCoalition = Event.IniCoalition
|
|
InitCategory = Event.IniCategory
|
|
InitType = Event.IniTypeName
|
|
|
|
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
|
|
TargetUNIT = Event.TgtUnit
|
|
TargetUnitName = Event.TgtDCSUnitName
|
|
TargetGroup = Event.TgtDCSGroup
|
|
TargetGroupName = Event.TgtDCSGroupName
|
|
TargetPlayerName = Event.TgtPlayerName
|
|
|
|
TargetCoalition = Event.TgtCoalition
|
|
TargetCategory = Event.TgtCategory
|
|
TargetType = Event.TgtTypeName
|
|
|
|
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
|
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
|
TargetUnitType = TargetType
|
|
|
|
end
|
|
|
|
-- Current time.
|
|
local Tnow=timer.getTime()
|
|
|
|
if InitPlayerName~=nil then -- It is a player that is hitting something
|
|
|
|
self:T("Hitting Something")
|
|
|
|
-- What is he hitting?
|
|
if TargetCategory then
|
|
|
|
-- A target got hit, score it.
|
|
-- Player contains the score data from self.Players[InitPlayerName]
|
|
local player=self.Players[InitPlayerName] --#SCORE.PlayerData
|
|
|
|
-- Hit table.
|
|
player.hit[TargetUnitName]=player.hit[TargetUnitName] or {}
|
|
|
|
local hit=player.hit[TargetUnitName] --#SCORE.HitData
|
|
|
|
hit.score = hit.score or 0
|
|
hit.penalty = hit.penalty or 0
|
|
hit.timeStamp = hit.timeStamp or 0
|
|
hit.unit = hit.unit or TargetUNIT
|
|
hit.threatLevel, hit.threatType = hit.unit:GetThreatLevel()
|
|
|
|
-- Only grant hit scores if there was more than one second between the last hit.
|
|
if Tnow-hit.timeStamp>1 then
|
|
|
|
-- Update timestamp
|
|
hit.timeStamp = Tnow
|
|
|
|
if TargetPlayerName~=nil then
|
|
-- It is a player hitting another player ...
|
|
hit.otherplayer=true
|
|
end
|
|
|
|
local Score = 0
|
|
|
|
if InitCoalition then -- A coalition object was hit.
|
|
if InitCoalition == TargetCoalition then
|
|
|
|
------------------
|
|
-- Hit Friendly --
|
|
------------------
|
|
|
|
hit.friendly=true
|
|
|
|
player.penalty = player.penalty-10
|
|
hit.penalty=hit.penalty-10
|
|
|
|
-- Check if target was another player.
|
|
if TargetPlayerName~=nil then -- It is a player hitting another player ...
|
|
|
|
else
|
|
|
|
end
|
|
|
|
-- Write penalty to CSV file.
|
|
--self:ScoreCSV( InitPlayerName, TargetPlayerName, "HIT_PENALTY", 1, -10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
|
|
else
|
|
|
|
----------------
|
|
-- Hit Enemey --
|
|
----------------
|
|
|
|
hit.friendly=true
|
|
|
|
player.score=player.score+1
|
|
hit.score=hit.score+1
|
|
|
|
--hit.scoreHit = hit.ScoreHit + 1
|
|
|
|
-- Check if it was a player.
|
|
if TargetPlayerName~=nil then -- It is a player hitting another player ...
|
|
|
|
else
|
|
|
|
end
|
|
|
|
-- Write score to CSV file. Score 1 PT.
|
|
|
|
end
|
|
|
|
else -- A scenery object was hit.
|
|
|
|
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
--- Track DEAD or CRASH events for the scoring.
|
|
-- @param #SCORING self
|
|
-- @param Core.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.IniUnit
|
|
TargetUnitName = Event.IniDCSUnitName
|
|
TargetGroup = Event.IniDCSGroup
|
|
TargetGroupName = Event.IniDCSGroupName
|
|
TargetPlayerName = Event.IniPlayerName
|
|
|
|
TargetCoalition = Event.IniCoalition
|
|
TargetCategory = Event.IniCategory
|
|
TargetType = Event.IniTypeName
|
|
|
|
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
|
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
|
TargetUnitType = TargetType
|
|
|
|
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } )
|
|
end
|
|
|
|
-- Player contains the score and reference data for the player.
|
|
for PlayerName, _player in pairs(self.Players) do
|
|
local player=_player --#SCORE.PlayerData
|
|
|
|
if player and player.unit and player.unit:IsAlive() then
|
|
|
|
self:T( "Something got destroyed" )
|
|
|
|
-- Some variables
|
|
local InitUnitName = Player.UnitName
|
|
local InitUnitType = Player.UnitType
|
|
local InitCoalition = Player.UnitCoalition
|
|
local InitCategory = Player.UnitCategory
|
|
local InitUnitCoalition = _SCORINGCoalition[InitCoalition]
|
|
local InitUnitCategory = _SCORINGCategory[InitCategory]
|
|
|
|
self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } )
|
|
|
|
local Destroyed = false
|
|
|
|
local hit=player.hit[TargetUnitName] --#SCORE.HitData
|
|
|
|
-- What is the player destroying?
|
|
if hit and hit.timeStamp~=0 then -- Was there a hit for this unit for this player before registered?
|
|
|
|
local TargetThreatLevel = hit.threatLevel
|
|
local TargetThreatType = hit.threatType
|
|
|
|
Player.Destroy[TargetCategory] = Player.Destroy[TargetCategory] or {}
|
|
Player.Destroy[TargetCategory][TargetType] = Player.Destroy[TargetCategory][TargetType] or {}
|
|
|
|
local destroy={} --#SCORE.DestroyData
|
|
|
|
-- PlayerDestroy contains the destroy score data per category and target type of the player.
|
|
local TargetDestroy = Player.Destroy[TargetCategory][TargetType]
|
|
TargetDestroy.Score = TargetDestroy.Score or 0
|
|
TargetDestroy.ScoreDestroy = TargetDestroy.ScoreDestroy or 0
|
|
TargetDestroy.Penalty = TargetDestroy.Penalty or 0
|
|
TargetDestroy.PenaltyDestroy = TargetDestroy.PenaltyDestroy or 0
|
|
|
|
if TargetCoalition then
|
|
if InitCoalition == TargetCoalition then
|
|
|
|
---
|
|
-- Hit Friendly
|
|
---
|
|
|
|
local ThreatLevelTarget = TargetThreatLevel
|
|
local ThreatTypeTarget = TargetThreatType
|
|
local ThreatLevelPlayer = Player.ThreatLevel / 10 + 1
|
|
local ThreatPenalty = math.ceil( ( ThreatLevelTarget / ThreatLevelPlayer ) * self.ScaleDestroyPenalty / 10 )
|
|
self:F( { ThreatLevel = ThreatPenalty, ThreatLevelTarget = ThreatLevelTarget, ThreatTypeTarget = ThreatTypeTarget, ThreatLevelPlayer = ThreatLevelPlayer } )
|
|
|
|
Player.Penalty = Player.Penalty + ThreatPenalty
|
|
TargetDestroy.Penalty = TargetDestroy.Penalty + ThreatPenalty
|
|
TargetDestroy.PenaltyDestroy = TargetDestroy.PenaltyDestroy + 1
|
|
|
|
if Player.HitPlayers[TargetPlayerName] then
|
|
-- A player destroyed another friendly player.
|
|
else
|
|
-- A player destroyed another friendly target.
|
|
end
|
|
|
|
-- Write CSV penalty.
|
|
Destroyed = true
|
|
--self:ScoreCSV( PlayerName, TargetPlayerName, "DESTROY_PENALTY", 1, ThreatPenalty, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
|
|
else
|
|
|
|
---
|
|
-- Hit Enemy
|
|
---
|
|
|
|
local ThreatLevelTarget = TargetThreatLevel
|
|
local ThreatTypeTarget = TargetThreatType
|
|
local ThreatLevelPlayer = Player.ThreatLevel / 10 + 1
|
|
local ThreatScore = math.ceil( ( ThreatLevelTarget / ThreatLevelPlayer ) * self.ScaleDestroyScore / 10 )
|
|
|
|
self:F( { ThreatLevel = ThreatScore, ThreatLevelTarget = ThreatLevelTarget, ThreatTypeTarget = ThreatTypeTarget, ThreatLevelPlayer = ThreatLevelPlayer } )
|
|
|
|
Player.Score = Player.Score + ThreatScore
|
|
TargetDestroy.Score = TargetDestroy.Score + ThreatScore
|
|
TargetDestroy.ScoreDestroy = TargetDestroy.ScoreDestroy + 1
|
|
|
|
if Player.HitPlayers[TargetPlayerName] then
|
|
-- A player destroyed another enemy player.
|
|
else
|
|
-- A player destroyed another enemy target.
|
|
end
|
|
|
|
-- Write CSV.
|
|
Destroyed = true
|
|
--self:ScoreCSV( PlayerName, TargetPlayerName, "DESTROY_SCORE", 1, ThreatScore, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
|
|
local UnitName = TargetUnit:GetName()
|
|
|
|
-- Scoring for special objects.
|
|
local Score = self.ScoringObjects[UnitName]
|
|
|
|
if Score then
|
|
|
|
Player.Score = Player.Score + Score
|
|
TargetDestroy.Score = TargetDestroy.Score + Score
|
|
|
|
MESSAGE
|
|
:NewType( self.DisplayMessagePrefix .. "Special target '" .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " .. " destroyed! " ..
|
|
"Player '" .. PlayerName .. "' receives an extra " .. Score .. " points! Total: " .. Player.Score - Player.Penalty,
|
|
MESSAGE.Type.Information
|
|
)
|
|
:ToAllIf( self:IfMessagesScore() and self:IfMessagesToAll() )
|
|
:ToCoalitionIf( InitCoalition, self:IfMessagesScore() and self:IfMessagesToCoalition() )
|
|
|
|
-- Write CSV file.
|
|
self:ScoreCSV( PlayerName, TargetPlayerName, "DESTROY_SCORE", 1, Score, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
Destroyed = true
|
|
end
|
|
|
|
-- Check if there are Zones where the destruction happened.
|
|
for ZoneName, ScoreZoneData in pairs(self.ScoringZones) do
|
|
self:F( { ScoringZone = ScoreZoneData } )
|
|
|
|
local ScoreZone = ScoreZoneData.ScoreZone -- Core.Zone#ZONE_BASE
|
|
|
|
local Score = ScoreZoneData.Score
|
|
|
|
-- Check if target is in zone.
|
|
if ScoreZone:IsVec2InZone( TargetUnit:GetVec2() ) then
|
|
Player.Score = Player.Score + Score
|
|
TargetDestroy.Score = TargetDestroy.Score + Score
|
|
|
|
MESSAGE
|
|
:NewType( self.DisplayMessagePrefix .. "Target destroyed in zone '" .. ScoreZone:GetName() .. "'." ..
|
|
"Player '" .. PlayerName .. "' receives an extra " .. Score .. " points! " ..
|
|
"Total: " .. Player.Score - Player.Penalty,
|
|
MESSAGE.Type.Information )
|
|
:ToAllIf( self:IfMessagesZone() and self:IfMessagesToAll() )
|
|
:ToCoalitionIf( InitCoalition, self:IfMessagesZone() and self:IfMessagesToCoalition() )
|
|
|
|
-- Write CSV.
|
|
self:ScoreCSV( PlayerName, TargetPlayerName, "DESTROY_SCORE", 1, Score, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
Destroyed = true
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
---
|
|
-- Scenery Destroyed
|
|
---
|
|
|
|
-- Check if there are Zones where the destruction happened.
|
|
for ZoneName, ScoreZoneData in pairs(self.ScoringZones) do
|
|
|
|
local ScoreZone = ScoreZoneData.ScoreZone -- Core.Zone#ZONE_BASE
|
|
local Score = ScoreZoneData.Score
|
|
|
|
if ScoreZone:IsVec2InZone(TargetUnit:GetVec2()) then
|
|
|
|
Player.Score = Player.Score + Score
|
|
TargetDestroy.Score = TargetDestroy.Score + Score
|
|
|
|
-- Player destroyed scenery in scoring zone.
|
|
|
|
--Write CSV.
|
|
Destroyed = true
|
|
--self:ScoreCSV( PlayerName, "", "DESTROY_SCORE", 1, Score, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, "", "Scenery", TargetUnitType )
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
-- Delete now the hit cache if the target was destroyed.
|
|
-- Otherwise points will be granted every time a target gets killed by the players that hit that target.
|
|
-- This is only relevant for player to player destroys.
|
|
if Destroyed then
|
|
Player.Hit[TargetCategory][TargetUnitName].TimeStamp = 0
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|