update lots of functions to take just the encounter being processed
as opposed to taking the entire log analysis data and forcing all these functions to only update :active-encounter within it. kind of makes it slightly clumsy to write the code that way
This commit is contained in:
parent
1021b4abc4
commit
68a291cbd6
|
@ -13,15 +13,15 @@
|
|||
[data :- RaidAnalysis]
|
||||
(not (nil? (:active-encounter data))))
|
||||
|
||||
(s/defn touch-entity :- RaidAnalysis
|
||||
"updates an entity within the current active encounter by resetting it's :last-activity-at timestamp
|
||||
or adds a new entity under the given name to the active encounter if it does not already exist. returns
|
||||
the new parsed data set with the updated entity information."
|
||||
[data :- RaidAnalysis
|
||||
(s/defn touch-entity :- Encounter
|
||||
"updates an entity within the encounter by resetting it's :last-activity-at timestamp to the timestamp
|
||||
provided, or adds a new entity under the given name to the active encounter if it does not already
|
||||
exist. returns encounter with the updated entity information."
|
||||
[encounter :- Encounter
|
||||
entity-name :- s/Str
|
||||
timestamp :- Date]
|
||||
(if-not (get-in data [:active-encounter :entities entity-name])
|
||||
(assoc-in data [:active-encounter :entities entity-name]
|
||||
(if-not (get-in encounter [:entities entity-name])
|
||||
(assoc-in encounter [:entities entity-name]
|
||||
{:name entity-name
|
||||
:added-at timestamp
|
||||
:last-activity-at timestamp
|
||||
|
@ -41,12 +41,14 @@
|
|||
:deaths []
|
||||
:resurrections []
|
||||
:alive-duration 0})
|
||||
(assoc-in data [:active-encounter :entities entity-name :last-activity-at] timestamp)))
|
||||
(assoc-in encounter [:entities entity-name :last-activity-at] timestamp)))
|
||||
|
||||
(s/defn get-entity-last-activity :- (s/maybe Date)
|
||||
[entity-name :- s/Str
|
||||
data :- RaidAnalysis]
|
||||
(get-in data [:active-encounter :entities entity-name :last-activity-at]))
|
||||
encounter :- Encounter]
|
||||
"returns timestamp of the given entity's last activity (that is, the timestamp of the most
|
||||
recent combat event that was regarding the named entity)"
|
||||
(get-in encounter [:entities entity-name :last-activity-at]))
|
||||
|
||||
(s/defn get-entity-alive-time :- Long
|
||||
"returns the number of milliseconds of the encounter that the entity was alive for"
|
||||
|
@ -112,38 +114,34 @@
|
|||
; TODO
|
||||
entity)
|
||||
|
||||
(s/defn finalize-entities :- RaidAnalysis
|
||||
[data :- RaidAnalysis]
|
||||
(update-active-encounter
|
||||
data
|
||||
(fn [encounter]
|
||||
(-> encounter
|
||||
(update-all-entities
|
||||
#(assoc % :alive-duration (get-entity-alive-time % encounter)))
|
||||
(update-all-entities
|
||||
#(assoc %
|
||||
:encounter-dps (Math/round ^double
|
||||
(/ (:damage-out-total %)
|
||||
(/ (:duration encounter)
|
||||
1000)))
|
||||
:alive-dps (Math/round ^double
|
||||
(s/defn finalize-entities :- Encounter
|
||||
[encounter :- Encounter]
|
||||
(-> encounter
|
||||
(update-all-entities
|
||||
#(assoc % :alive-duration (get-entity-alive-time % encounter)))
|
||||
(update-all-entities
|
||||
#(assoc %
|
||||
:encounter-dps (Math/round ^double
|
||||
(/ (:damage-out-total %)
|
||||
(/ (:alive-duration %)
|
||||
1000)))))
|
||||
(update-all-entities finalize-entity-auras (:ended-at encounter))))))
|
||||
(/ (:duration encounter)
|
||||
1000)))
|
||||
:alive-dps (Math/round ^double
|
||||
(/ (:damage-out-total %)
|
||||
(/ (:alive-duration %)
|
||||
1000)))))
|
||||
(update-all-entities finalize-entity-auras (:ended-at encounter))))
|
||||
|
||||
(s/defn calculate-encounter-stats :- RaidAnalysis
|
||||
[data :- RaidAnalysis]
|
||||
(-> data
|
||||
(update-active-encounter
|
||||
(fn [{:keys [started-at ended-at] :as encounter}]
|
||||
(assoc encounter :duration (time-between started-at ended-at))))
|
||||
(finalize-entities)))
|
||||
(s/defn calculate-encounter-stats :- Encounter
|
||||
[encounter :- Encounter]
|
||||
(let [{:keys [started-at ended-at]} encounter]
|
||||
(-> encounter
|
||||
(assoc :duration (time-between started-at ended-at))
|
||||
(finalize-entities))))
|
||||
|
||||
(s/defn count-currently-dead :- s/Num
|
||||
[data :- RaidAnalysis
|
||||
[encounter :- Encounter
|
||||
entity-name :- s/Str]
|
||||
(if-let [entity (get-in data [:active-encounter :entities entity-name])]
|
||||
(if-let [entity (get-in encounter [:entities entity-name])]
|
||||
(let [num-deaths (count (:deaths entity))
|
||||
num-resurrects (count (:resurrections entity))]
|
||||
(- num-deaths num-resurrects))
|
||||
|
@ -207,27 +205,27 @@
|
|||
(update-in [:num-immune] #(if (= avoidance-method :immune) (inc %) %))
|
||||
(update-damage-averages))))
|
||||
|
||||
(s/defn entity-takes-damage :- RaidAnalysis
|
||||
[data :- RaidAnalysis
|
||||
(s/defn entity-takes-damage :- Encounter
|
||||
[encounter :- Encounter
|
||||
entity-name :- s/Str
|
||||
from-entity-name :- s/Str
|
||||
{:keys [skill damage damage-type]
|
||||
:as damage-properties} :- DamageProperties
|
||||
timestamp :- Date]
|
||||
(-> data
|
||||
(-> encounter
|
||||
(update-entity-field entity-name [:damage-in-total] #(if damage (+ (or % 0) damage) %))
|
||||
(update-entity-field entity-name [:damage-in-totals damage-type] #(if damage (+ (or % 0) damage) %))
|
||||
(update-entity-field entity-name [:damage-in skill] #(add-from-damage-properties % damage-properties))
|
||||
(update-entity-field entity-name [:damage-in-by-entity from-entity-name skill] #(add-from-damage-properties % damage-properties))))
|
||||
|
||||
(s/defn entity-deals-damage :- RaidAnalysis
|
||||
[data :- RaidAnalysis
|
||||
(s/defn entity-deals-damage :- Encounter
|
||||
[encounter :- Encounter
|
||||
entity-name :- s/Str
|
||||
to-entity-name :- s/Str
|
||||
{:keys [skill damage damage-type]
|
||||
:as damage-properties} :- DamageProperties
|
||||
timestamp :- Date]
|
||||
(-> data
|
||||
(-> encounter
|
||||
(update-entity-field entity-name [:damage-out-total] #(if damage (+ (or % 0) damage) %))
|
||||
(update-entity-field entity-name [:damage-out-totals damage-type] #(if damage (+ (or % 0) damage) %))
|
||||
(update-entity-field entity-name [:damage-out skill] #(add-from-damage-properties % damage-properties))
|
||||
|
@ -237,42 +235,42 @@
|
|||
;;; main combat log entry processing entry points
|
||||
;;;
|
||||
|
||||
(s/defn process-source-to-target-damage :- RaidAnalysis
|
||||
(s/defn process-source-to-target-damage :- Encounter
|
||||
[source-name :- s/Str
|
||||
target-name :- s/Str
|
||||
damage-properties :- DamageProperties
|
||||
timestamp :- Date
|
||||
data :- RaidAnalysis]
|
||||
(-> data
|
||||
encounter :- Encounter]
|
||||
(-> encounter
|
||||
(touch-entity source-name timestamp)
|
||||
(touch-entity target-name timestamp)
|
||||
(entity-takes-damage target-name source-name damage-properties timestamp)
|
||||
(entity-deals-damage source-name target-name damage-properties timestamp))
|
||||
)
|
||||
|
||||
(s/defn process-entity-death :- RaidAnalysis
|
||||
(s/defn process-entity-death :- Encounter
|
||||
[entity-name :- s/Str
|
||||
timestamp :- Date
|
||||
data :- RaidAnalysis]
|
||||
(-> data
|
||||
encounter :- Encounter]
|
||||
(-> encounter
|
||||
(touch-entity entity-name timestamp)
|
||||
(update-entity-field entity-name [:deaths] #(conj % {:timestamp timestamp}))
|
||||
(update-entity entity-name finalize-entity-auras timestamp)))
|
||||
|
||||
(s/defn process-source-to-target-cast :- RaidAnalysis
|
||||
(s/defn process-source-to-target-cast :- Encounter
|
||||
[source-name :- s/Str
|
||||
target-name :- s/Str
|
||||
skill-name :- s/Str
|
||||
timestamp :- Date
|
||||
data :- RaidAnalysis]
|
||||
data)
|
||||
encounter :- Encounter]
|
||||
encounter)
|
||||
|
||||
(s/defn process-entity-cast :- RaidAnalysis
|
||||
(s/defn process-entity-cast :- Encounter
|
||||
[entity-name :- s/Str
|
||||
skill-name :- s/Str
|
||||
timestamp :- Date
|
||||
data :- RaidAnalysis]
|
||||
data)
|
||||
encounter :- Encounter]
|
||||
encounter)
|
||||
|
||||
(s/defn begin-encounter :- RaidAnalysis
|
||||
"sets up a new active encounter in the parsed data, returning the new parsed data set ready to use for
|
||||
|
@ -302,7 +300,7 @@
|
|||
(let [data (-> data
|
||||
(update-active-encounter assoc :ended-at timestamp)
|
||||
(update-active-encounter assoc :wipe-or-timeout? wipe-or-timeout?)
|
||||
(calculate-encounter-stats))]
|
||||
(update-active-encounter calculate-encounter-stats))]
|
||||
(-> data
|
||||
(assoc-in [:active-encounter] nil)
|
||||
(update-in [:encounters] #(conj %1 (:active-encounter data)))))))
|
|
@ -69,21 +69,22 @@
|
|||
f & args]
|
||||
(update-active-encounter data #(update-all-entities % f args)))
|
||||
|
||||
(s/defn update-entity :- RaidAnalysis
|
||||
"updates an entity in the full parsed data's active encounter using function f
|
||||
which takes the current entity and any supplied args, returning the new entity
|
||||
which is 'updated' in the active encounter. returns the updated full parsed data."
|
||||
[data :- RaidAnalysis
|
||||
(s/defn update-entity :- Encounter
|
||||
[encounter :- Encounter
|
||||
entity-name :- s/Str
|
||||
f & args]
|
||||
(apply update-in data [:active-encounter :entities entity-name] f args))
|
||||
(apply update-in encounter [:entities entity-name] f args))
|
||||
|
||||
(s/defn update-entity-field :- RaidAnalysis
|
||||
"updates a specific field within an entity pointed to by ks in the full parsed
|
||||
data's active encounter using function f which takes the current entity and any
|
||||
supplied args, returning the new entity which is 'updated' in the active encounter.
|
||||
returns the updated full parsed data."
|
||||
[data :- RaidAnalysis
|
||||
(s/defn update-entity-field :- Encounter
|
||||
[encounter :- Encounter
|
||||
entity-name :- s/Str
|
||||
ks f & args]
|
||||
(apply update-in data (concat [:active-encounter :entities entity-name] ks) f args))
|
||||
(let [ks (concat [:entities entity-name] ks)]
|
||||
(apply update-in encounter ks f args)))
|
||||
|
|
|
@ -94,12 +94,12 @@
|
|||
encounter was found to be over due to a raid wipe or other non-activity timeout, or nil if the
|
||||
active encounter is not over yet."
|
||||
[{:keys [^Date timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
(let [trigger-entites (get-in data [:active-encounter :trigger-entities])]
|
||||
encounter :- Encounter]
|
||||
(let [trigger-entites (:trigger-entities encounter)]
|
||||
(cond
|
||||
(every?
|
||||
(fn [[entity-name {:keys [count must-kill-count]}]]
|
||||
(let [count-dead (count-currently-dead data entity-name)]
|
||||
(let [count-dead (count-currently-dead encounter entity-name)]
|
||||
(>= count-dead (or must-kill-count count))))
|
||||
trigger-entites)
|
||||
:killed
|
||||
|
@ -111,7 +111,7 @@
|
|||
; and there have been no combat log lines yet for one or more of the trigger entities.
|
||||
; should we have a minimum encounter length time? something like 15-30 seconds? that also feels hacky...
|
||||
(>= (- (.getTime timestamp)
|
||||
(.getTime (or (get-entity-last-activity entity-name data)
|
||||
(.getTime (or (get-entity-last-activity entity-name encounter)
|
||||
timestamp)))
|
||||
wipe-or-timeout-period))
|
||||
trigger-entites)
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
(fn [{:keys [event]} _]
|
||||
(keyword event)))
|
||||
|
||||
(s/defmethod handle-event :skill-damage-to-target :- RaidAnalysis
|
||||
(s/defmethod handle-event :skill-damage-to-target :- Encounter
|
||||
[{:keys [source-name skill target-name damage damage-type absorbed resisted blocked crit? timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
encounter :- Encounter]
|
||||
(analysis/process-source-to-target-damage
|
||||
source-name
|
||||
target-name
|
||||
|
@ -24,11 +24,11 @@
|
|||
:partial-resist resisted
|
||||
:partial-block blocked}
|
||||
timestamp
|
||||
data))
|
||||
encounter))
|
||||
|
||||
(s/defmethod handle-event :skill-avoided-by-target :- RaidAnalysis
|
||||
(s/defmethod handle-event :skill-avoided-by-target :- Encounter
|
||||
[{:keys [source-name target-name skill avoidance-method timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
encounter :- Encounter]
|
||||
(analysis/process-source-to-target-damage
|
||||
source-name
|
||||
target-name
|
||||
|
@ -36,11 +36,11 @@
|
|||
:actual-skill? true
|
||||
:avoidance-method avoidance-method}
|
||||
timestamp
|
||||
data))
|
||||
encounter))
|
||||
|
||||
(s/defmethod handle-event :damage-reflected :- RaidAnalysis
|
||||
(s/defmethod handle-event :damage-reflected :- Encounter
|
||||
[{:keys [source-name target-name damage damage-type timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
encounter :- Encounter]
|
||||
(analysis/process-source-to-target-damage
|
||||
source-name
|
||||
target-name
|
||||
|
@ -50,11 +50,11 @@
|
|||
:damage-type damage-type
|
||||
:crit? false}
|
||||
timestamp
|
||||
data))
|
||||
encounter))
|
||||
|
||||
(s/defmethod handle-event :melee-damage-to-target :- RaidAnalysis
|
||||
(s/defmethod handle-event :melee-damage-to-target :- Encounter
|
||||
[{:keys [source-name target-name damage damage-type hit-type absorbed resisted blocked crit? timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
encounter :- Encounter]
|
||||
(analysis/process-source-to-target-damage
|
||||
source-name
|
||||
target-name
|
||||
|
@ -68,11 +68,11 @@
|
|||
:partial-resist resisted
|
||||
:partial-block blocked}
|
||||
timestamp
|
||||
data))
|
||||
encounter))
|
||||
|
||||
(s/defmethod handle-event :melee-avoided-by-target :- RaidAnalysis
|
||||
(s/defmethod handle-event :melee-avoided-by-target :- Encounter
|
||||
[{:keys [source-name target-name avoidance-method timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
encounter :- Encounter]
|
||||
(analysis/process-source-to-target-damage
|
||||
source-name
|
||||
target-name
|
||||
|
@ -80,16 +80,16 @@
|
|||
:actual-skill? false
|
||||
:avoidance-method avoidance-method}
|
||||
timestamp
|
||||
data))
|
||||
encounter))
|
||||
|
||||
(s/defmethod handle-event :skill-interrupted-by-target :- RaidAnalysis
|
||||
(s/defmethod handle-event :skill-interrupted-by-target :- Encounter
|
||||
[{:keys [source-name target-name skill timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
data)
|
||||
encounter :- Encounter]
|
||||
encounter)
|
||||
|
||||
(s/defmethod handle-event :dot-damages-target :- RaidAnalysis
|
||||
(s/defmethod handle-event :dot-damages-target :- Encounter
|
||||
[{:keys [source-name skill target-name damage damage-type absorbed resisted timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
encounter :- Encounter]
|
||||
(analysis/process-source-to-target-damage
|
||||
source-name
|
||||
target-name
|
||||
|
@ -101,37 +101,37 @@
|
|||
:partial-absorb absorbed
|
||||
:partial-resist resisted}
|
||||
timestamp
|
||||
data))
|
||||
encounter))
|
||||
|
||||
(s/defmethod handle-event :cast-begins :- RaidAnalysis
|
||||
(s/defmethod handle-event :cast-begins :- Encounter
|
||||
[{:keys [source-name skill spell? timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
encounter :- Encounter]
|
||||
; don't think we really care about this ?
|
||||
data)
|
||||
encounter)
|
||||
|
||||
(s/defmethod handle-event :skill-performed-on-target :- RaidAnalysis
|
||||
(s/defmethod handle-event :skill-performed-on-target :- Encounter
|
||||
[{:keys [source-name target-name skill spell? extra timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
(analysis/process-source-to-target-cast source-name target-name skill timestamp data))
|
||||
encounter :- Encounter]
|
||||
(analysis/process-source-to-target-cast source-name target-name skill timestamp encounter))
|
||||
|
||||
(s/defmethod handle-event :cast :- RaidAnalysis
|
||||
(s/defmethod handle-event :cast :- Encounter
|
||||
[{:keys [source-name skill spell? timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
(analysis/process-entity-cast source-name skill timestamp data))
|
||||
encounter :- Encounter]
|
||||
(analysis/process-entity-cast source-name skill timestamp encounter))
|
||||
|
||||
(s/defmethod handle-event :skill-heals-target :- RaidAnalysis
|
||||
(s/defmethod handle-event :skill-heals-target :- Encounter
|
||||
[{:keys [source-name skill crit? target-name amount timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
data)
|
||||
encounter :- Encounter]
|
||||
encounter)
|
||||
|
||||
(s/defmethod handle-event :resource-gained :- RaidAnalysis
|
||||
(s/defmethod handle-event :resource-gained :- Encounter
|
||||
[{:keys [target-name amount resource-type source-name skill timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
data)
|
||||
encounter :- Encounter]
|
||||
encounter)
|
||||
|
||||
(s/defmethod handle-event :resource-lost :- RaidAnalysis
|
||||
(s/defmethod handle-event :resource-lost :- Encounter
|
||||
[{:keys [target-name amount resource-type source-name skill timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
encounter :- Encounter]
|
||||
(condp = resource-type
|
||||
:health (analysis/process-source-to-target-damage
|
||||
source-name
|
||||
|
@ -142,42 +142,42 @@
|
|||
:damage-type :physical
|
||||
:crit? false}
|
||||
timestamp
|
||||
data)
|
||||
data))
|
||||
encounter)
|
||||
encounter))
|
||||
|
||||
(s/defmethod handle-event :special-gained :- RaidAnalysis
|
||||
(s/defmethod handle-event :special-gained :- Encounter
|
||||
[{:keys [target-name special source timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
data)
|
||||
encounter :- Encounter]
|
||||
encounter)
|
||||
|
||||
(s/defmethod handle-event :aura-gained :- RaidAnalysis
|
||||
(s/defmethod handle-event :aura-gained :- Encounter
|
||||
[{:keys [target-name aura-name aura-type stacks timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
data)
|
||||
encounter :- Encounter]
|
||||
encounter)
|
||||
|
||||
(s/defmethod handle-event :aura-lost :- RaidAnalysis
|
||||
(s/defmethod handle-event :aura-lost :- Encounter
|
||||
[{:keys [target-name aura-name faded? stacks timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
data)
|
||||
encounter :- Encounter]
|
||||
encounter)
|
||||
|
||||
(s/defmethod handle-event :other-damage :- RaidAnalysis
|
||||
(s/defmethod handle-event :other-damage :- Encounter
|
||||
[{:keys [target-name damage damage-type resisted absorbed source timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
data)
|
||||
encounter :- Encounter]
|
||||
encounter)
|
||||
|
||||
(s/defmethod handle-event :death :- RaidAnalysis
|
||||
(s/defmethod handle-event :death :- Encounter
|
||||
[{:keys [source-name timestamp]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
(analysis/process-entity-death source-name timestamp data))
|
||||
encounter :- Encounter]
|
||||
(analysis/process-entity-death source-name timestamp encounter))
|
||||
|
||||
|
||||
(s/defmethod handle-event :ignored :- RaidAnalysis
|
||||
(s/defmethod handle-event :ignored :- Encounter
|
||||
[{:keys [line]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
data)
|
||||
encounter :- Encounter]
|
||||
encounter)
|
||||
|
||||
(s/defmethod handle-event :default :- RaidAnalysis
|
||||
(s/defmethod handle-event :default :- Encounter
|
||||
[{:keys [line]} :- CombatEvent
|
||||
data :- RaidAnalysis]
|
||||
encounter :- Encounter]
|
||||
(println "[WARN] *** UNRECOGNIZED ***" line)
|
||||
data)
|
||||
encounter)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
[clojure.tools.logging :refer [info error warn]]
|
||||
[clojure.java.io :as io]
|
||||
[schema.core :as s]
|
||||
[vwowrla.core.encounters.core :refer [update-active-encounter]]
|
||||
[vwowrla.core.encounters.detection :refer [detect-encounter-end detect-encounter-triggered]]
|
||||
[vwowrla.core.encounters.analysis :refer [begin-encounter end-encounter active-encounter?]]
|
||||
[vwowrla.core.events.handlers :refer [handle-event]]
|
||||
|
@ -61,8 +62,8 @@
|
|||
ends the encounter.
|
||||
should only be called if an encounter is currently active in the current
|
||||
raid analysis data."
|
||||
(let [data (handle-event event data)]
|
||||
(if-let [encounter-end (detect-encounter-end event data)]
|
||||
(let [data (update-active-encounter data #(handle-event event %))]
|
||||
(if-let [encounter-end (detect-encounter-end event (:active-encounter data))]
|
||||
(end-encounter event encounter-end data)
|
||||
data)))
|
||||
|
||||
|
@ -76,9 +77,9 @@
|
|||
should only be called if an encounter is NOT currently active in the
|
||||
current raid analysis data."
|
||||
(if-let [encounter-name (detect-encounter-triggered event data)]
|
||||
(->> data
|
||||
(begin-encounter encounter-name event)
|
||||
(handle-event event))
|
||||
(as-> data x
|
||||
(begin-encounter encounter-name event x)
|
||||
(update-active-encounter x #(handle-event event %)))
|
||||
data))
|
||||
|
||||
(s/defn ^:private parse-log* :- (s/maybe RaidAnalysis)
|
||||
|
|
Reference in a new issue