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:
Gered 2016-03-03 19:17:40 -05:00
parent 1021b4abc4
commit 68a291cbd6
5 changed files with 132 additions and 132 deletions

View file

@ -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)))))))

View file

@ -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)))

View file

@ -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)

View file

@ -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)

View file

@ -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)