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] [data :- RaidAnalysis]
(not (nil? (:active-encounter data)))) (not (nil? (:active-encounter data))))
(s/defn touch-entity :- RaidAnalysis (s/defn touch-entity :- Encounter
"updates an entity within the current active encounter by resetting it's :last-activity-at timestamp "updates an entity within the encounter by resetting it's :last-activity-at timestamp to the timestamp
or adds a new entity under the given name to the active encounter if it does not already exist. returns provided, or adds a new entity under the given name to the active encounter if it does not already
the new parsed data set with the updated entity information." exist. returns encounter with the updated entity information."
[data :- RaidAnalysis [encounter :- Encounter
entity-name :- s/Str entity-name :- s/Str
timestamp :- Date] timestamp :- Date]
(if-not (get-in data [:active-encounter :entities entity-name]) (if-not (get-in encounter [:entities entity-name])
(assoc-in data [:active-encounter :entities entity-name] (assoc-in encounter [:entities entity-name]
{:name entity-name {:name entity-name
:added-at timestamp :added-at timestamp
:last-activity-at timestamp :last-activity-at timestamp
@ -41,12 +41,14 @@
:deaths [] :deaths []
:resurrections [] :resurrections []
:alive-duration 0}) :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) (s/defn get-entity-last-activity :- (s/maybe Date)
[entity-name :- s/Str [entity-name :- s/Str
data :- RaidAnalysis] encounter :- Encounter]
(get-in data [:active-encounter :entities entity-name :last-activity-at])) "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 (s/defn get-entity-alive-time :- Long
"returns the number of milliseconds of the encounter that the entity was alive for" "returns the number of milliseconds of the encounter that the entity was alive for"
@ -112,11 +114,8 @@
; TODO ; TODO
entity) entity)
(s/defn finalize-entities :- RaidAnalysis (s/defn finalize-entities :- Encounter
[data :- RaidAnalysis] [encounter :- Encounter]
(update-active-encounter
data
(fn [encounter]
(-> encounter (-> encounter
(update-all-entities (update-all-entities
#(assoc % :alive-duration (get-entity-alive-time % encounter))) #(assoc % :alive-duration (get-entity-alive-time % encounter)))
@ -130,20 +129,19 @@
(/ (:damage-out-total %) (/ (:damage-out-total %)
(/ (:alive-duration %) (/ (:alive-duration %)
1000))))) 1000)))))
(update-all-entities finalize-entity-auras (:ended-at encounter)))))) (update-all-entities finalize-entity-auras (:ended-at encounter))))
(s/defn calculate-encounter-stats :- RaidAnalysis (s/defn calculate-encounter-stats :- Encounter
[data :- RaidAnalysis] [encounter :- Encounter]
(-> data (let [{:keys [started-at ended-at]} encounter]
(update-active-encounter (-> encounter
(fn [{:keys [started-at ended-at] :as encounter}] (assoc :duration (time-between started-at ended-at))
(assoc encounter :duration (time-between started-at ended-at)))) (finalize-entities))))
(finalize-entities)))
(s/defn count-currently-dead :- s/Num (s/defn count-currently-dead :- s/Num
[data :- RaidAnalysis [encounter :- Encounter
entity-name :- s/Str] 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)) (let [num-deaths (count (:deaths entity))
num-resurrects (count (:resurrections entity))] num-resurrects (count (:resurrections entity))]
(- num-deaths num-resurrects)) (- num-deaths num-resurrects))
@ -207,27 +205,27 @@
(update-in [:num-immune] #(if (= avoidance-method :immune) (inc %) %)) (update-in [:num-immune] #(if (= avoidance-method :immune) (inc %) %))
(update-damage-averages)))) (update-damage-averages))))
(s/defn entity-takes-damage :- RaidAnalysis (s/defn entity-takes-damage :- Encounter
[data :- RaidAnalysis [encounter :- Encounter
entity-name :- s/Str entity-name :- s/Str
from-entity-name :- s/Str from-entity-name :- s/Str
{:keys [skill damage damage-type] {:keys [skill damage damage-type]
:as damage-properties} :- DamageProperties :as damage-properties} :- DamageProperties
timestamp :- Date] timestamp :- Date]
(-> data (-> encounter
(update-entity-field entity-name [:damage-in-total] #(if damage (+ (or % 0) damage) %)) (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-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 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)))) (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 (s/defn entity-deals-damage :- Encounter
[data :- RaidAnalysis [encounter :- Encounter
entity-name :- s/Str entity-name :- s/Str
to-entity-name :- s/Str to-entity-name :- s/Str
{:keys [skill damage damage-type] {:keys [skill damage damage-type]
:as damage-properties} :- DamageProperties :as damage-properties} :- DamageProperties
timestamp :- Date] timestamp :- Date]
(-> data (-> encounter
(update-entity-field entity-name [:damage-out-total] #(if damage (+ (or % 0) damage) %)) (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-totals damage-type] #(if damage (+ (or % 0) damage) %))
(update-entity-field entity-name [:damage-out skill] #(add-from-damage-properties % damage-properties)) (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 ;;; 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 [source-name :- s/Str
target-name :- s/Str target-name :- s/Str
damage-properties :- DamageProperties damage-properties :- DamageProperties
timestamp :- Date timestamp :- Date
data :- RaidAnalysis] encounter :- Encounter]
(-> data (-> encounter
(touch-entity source-name timestamp) (touch-entity source-name timestamp)
(touch-entity target-name timestamp) (touch-entity target-name timestamp)
(entity-takes-damage target-name source-name damage-properties timestamp) (entity-takes-damage target-name source-name damage-properties timestamp)
(entity-deals-damage source-name target-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 [entity-name :- s/Str
timestamp :- Date timestamp :- Date
data :- RaidAnalysis] encounter :- Encounter]
(-> data (-> encounter
(touch-entity entity-name timestamp) (touch-entity entity-name timestamp)
(update-entity-field entity-name [:deaths] #(conj % {:timestamp timestamp})) (update-entity-field entity-name [:deaths] #(conj % {:timestamp timestamp}))
(update-entity entity-name finalize-entity-auras 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 [source-name :- s/Str
target-name :- s/Str target-name :- s/Str
skill-name :- s/Str skill-name :- s/Str
timestamp :- Date timestamp :- Date
data :- RaidAnalysis] encounter :- Encounter]
data) encounter)
(s/defn process-entity-cast :- RaidAnalysis (s/defn process-entity-cast :- Encounter
[entity-name :- s/Str [entity-name :- s/Str
skill-name :- s/Str skill-name :- s/Str
timestamp :- Date timestamp :- Date
data :- RaidAnalysis] encounter :- Encounter]
data) encounter)
(s/defn begin-encounter :- RaidAnalysis (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 "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 (let [data (-> data
(update-active-encounter assoc :ended-at timestamp) (update-active-encounter assoc :ended-at timestamp)
(update-active-encounter assoc :wipe-or-timeout? wipe-or-timeout?) (update-active-encounter assoc :wipe-or-timeout? wipe-or-timeout?)
(calculate-encounter-stats))] (update-active-encounter calculate-encounter-stats))]
(-> data (-> data
(assoc-in [:active-encounter] nil) (assoc-in [:active-encounter] nil)
(update-in [:encounters] #(conj %1 (:active-encounter data))))))) (update-in [:encounters] #(conj %1 (:active-encounter data)))))))

View file

@ -69,21 +69,22 @@
f & args] f & args]
(update-active-encounter data #(update-all-entities % 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 "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 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." 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 entity-name :- s/Str
f & args] 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 "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 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. supplied args, returning the new entity which is 'updated' in the active encounter.
returns the updated full parsed data." returns the updated full parsed data."
[data :- RaidAnalysis (s/defn update-entity-field :- Encounter
[encounter :- Encounter
entity-name :- s/Str entity-name :- s/Str
ks f & args] 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 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." active encounter is not over yet."
[{:keys [^Date timestamp]} :- CombatEvent [{:keys [^Date timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
(let [trigger-entites (get-in data [:active-encounter :trigger-entities])] (let [trigger-entites (:trigger-entities encounter)]
(cond (cond
(every? (every?
(fn [[entity-name {:keys [count must-kill-count]}]] (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)))) (>= count-dead (or must-kill-count count))))
trigger-entites) trigger-entites)
:killed :killed
@ -111,7 +111,7 @@
; and there have been no combat log lines yet for one or more of the trigger entities. ; 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... ; should we have a minimum encounter length time? something like 15-30 seconds? that also feels hacky...
(>= (- (.getTime timestamp) (>= (- (.getTime timestamp)
(.getTime (or (get-entity-last-activity entity-name data) (.getTime (or (get-entity-last-activity entity-name encounter)
timestamp))) timestamp)))
wipe-or-timeout-period)) wipe-or-timeout-period))
trigger-entites) trigger-entites)

View file

@ -9,9 +9,9 @@
(fn [{:keys [event]} _] (fn [{:keys [event]} _]
(keyword 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 [{: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 (analysis/process-source-to-target-damage
source-name source-name
target-name target-name
@ -24,11 +24,11 @@
:partial-resist resisted :partial-resist resisted
:partial-block blocked} :partial-block blocked}
timestamp 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 [{:keys [source-name target-name skill avoidance-method timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
(analysis/process-source-to-target-damage (analysis/process-source-to-target-damage
source-name source-name
target-name target-name
@ -36,11 +36,11 @@
:actual-skill? true :actual-skill? true
:avoidance-method avoidance-method} :avoidance-method avoidance-method}
timestamp 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 [{:keys [source-name target-name damage damage-type timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
(analysis/process-source-to-target-damage (analysis/process-source-to-target-damage
source-name source-name
target-name target-name
@ -50,11 +50,11 @@
:damage-type damage-type :damage-type damage-type
:crit? false} :crit? false}
timestamp 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 [{: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 (analysis/process-source-to-target-damage
source-name source-name
target-name target-name
@ -68,11 +68,11 @@
:partial-resist resisted :partial-resist resisted
:partial-block blocked} :partial-block blocked}
timestamp 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 [{:keys [source-name target-name avoidance-method timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
(analysis/process-source-to-target-damage (analysis/process-source-to-target-damage
source-name source-name
target-name target-name
@ -80,16 +80,16 @@
:actual-skill? false :actual-skill? false
:avoidance-method avoidance-method} :avoidance-method avoidance-method}
timestamp 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 [{:keys [source-name target-name skill timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
data) 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 [{:keys [source-name skill target-name damage damage-type absorbed resisted timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
(analysis/process-source-to-target-damage (analysis/process-source-to-target-damage
source-name source-name
target-name target-name
@ -101,37 +101,37 @@
:partial-absorb absorbed :partial-absorb absorbed
:partial-resist resisted} :partial-resist resisted}
timestamp timestamp
data)) encounter))
(s/defmethod handle-event :cast-begins :- RaidAnalysis (s/defmethod handle-event :cast-begins :- Encounter
[{:keys [source-name skill spell? timestamp]} :- CombatEvent [{:keys [source-name skill spell? timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
; don't think we really care about this ? ; 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 [{:keys [source-name target-name skill spell? extra timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
(analysis/process-source-to-target-cast source-name target-name skill timestamp data)) (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 [{:keys [source-name skill spell? timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
(analysis/process-entity-cast source-name skill timestamp data)) (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 [{:keys [source-name skill crit? target-name amount timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
data) 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 [{:keys [target-name amount resource-type source-name skill timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
data) 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 [{:keys [target-name amount resource-type source-name skill timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
(condp = resource-type (condp = resource-type
:health (analysis/process-source-to-target-damage :health (analysis/process-source-to-target-damage
source-name source-name
@ -142,42 +142,42 @@
:damage-type :physical :damage-type :physical
:crit? false} :crit? false}
timestamp timestamp
data) encounter)
data)) encounter))
(s/defmethod handle-event :special-gained :- RaidAnalysis (s/defmethod handle-event :special-gained :- Encounter
[{:keys [target-name special source timestamp]} :- CombatEvent [{:keys [target-name special source timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
data) 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 [{:keys [target-name aura-name aura-type stacks timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
data) encounter)
(s/defmethod handle-event :aura-lost :- RaidAnalysis (s/defmethod handle-event :aura-lost :- Encounter
[{:keys [target-name aura-name faded? stacks timestamp]} :- CombatEvent [{:keys [target-name aura-name faded? stacks timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
data) 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 [{:keys [target-name damage damage-type resisted absorbed source timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
data) encounter)
(s/defmethod handle-event :death :- RaidAnalysis (s/defmethod handle-event :death :- Encounter
[{:keys [source-name timestamp]} :- CombatEvent [{:keys [source-name timestamp]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
(analysis/process-entity-death source-name timestamp data)) (analysis/process-entity-death source-name timestamp encounter))
(s/defmethod handle-event :ignored :- RaidAnalysis (s/defmethod handle-event :ignored :- Encounter
[{:keys [line]} :- CombatEvent [{:keys [line]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
data) encounter)
(s/defmethod handle-event :default :- RaidAnalysis (s/defmethod handle-event :default :- Encounter
[{:keys [line]} :- CombatEvent [{:keys [line]} :- CombatEvent
data :- RaidAnalysis] encounter :- Encounter]
(println "[WARN] *** UNRECOGNIZED ***" line) (println "[WARN] *** UNRECOGNIZED ***" line)
data) encounter)

View file

@ -5,6 +5,7 @@
[clojure.tools.logging :refer [info error warn]] [clojure.tools.logging :refer [info error warn]]
[clojure.java.io :as io] [clojure.java.io :as io]
[schema.core :as s] [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.detection :refer [detect-encounter-end detect-encounter-triggered]]
[vwowrla.core.encounters.analysis :refer [begin-encounter end-encounter active-encounter?]] [vwowrla.core.encounters.analysis :refer [begin-encounter end-encounter active-encounter?]]
[vwowrla.core.events.handlers :refer [handle-event]] [vwowrla.core.events.handlers :refer [handle-event]]
@ -61,8 +62,8 @@
ends the encounter. ends the encounter.
should only be called if an encounter is currently active in the current should only be called if an encounter is currently active in the current
raid analysis data." raid analysis data."
(let [data (handle-event event data)] (let [data (update-active-encounter data #(handle-event event %))]
(if-let [encounter-end (detect-encounter-end event data)] (if-let [encounter-end (detect-encounter-end event (:active-encounter data))]
(end-encounter event encounter-end data) (end-encounter event encounter-end data)
data))) data)))
@ -76,9 +77,9 @@
should only be called if an encounter is NOT currently active in the should only be called if an encounter is NOT currently active in the
current raid analysis data." current raid analysis data."
(if-let [encounter-name (detect-encounter-triggered event data)] (if-let [encounter-name (detect-encounter-triggered event data)]
(->> data (as-> data x
(begin-encounter encounter-name event) (begin-encounter encounter-name event x)
(handle-event event)) (update-active-encounter x #(handle-event event %)))
data)) data))
(s/defn ^:private parse-log* :- (s/maybe RaidAnalysis) (s/defn ^:private parse-log* :- (s/maybe RaidAnalysis)