aboutsummaryrefslogtreecommitdiffstats
path: root/common/death/death.go
diff options
context:
space:
mode:
Diffstat (limited to 'common/death/death.go')
-rw-r--r--common/death/death.go132
1 files changed, 132 insertions, 0 deletions
diff --git a/common/death/death.go b/common/death/death.go
new file mode 100644
index 0000000..c71f862
--- /dev/null
+++ b/common/death/death.go
@@ -0,0 +1,132 @@
+package death
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+)
+
+type Weapon string
+
+const (
+ Axe Weapon = "axe"
+ Discharge Weapon = "discharge"
+ Drown Weapon = "drown"
+ Fall Weapon = "fall"
+ GrenadeLauncher Weapon = "gl"
+ Lava Weapon = "lava"
+ LightningGun Weapon = "lg"
+ Nailgun Weapon = "ng"
+ NoWeapon Weapon = "no weapon"
+ QLightningGun Weapon = "quad lg"
+ QRocketLauncher Weapon = "quad rl"
+ QShotgun Weapon = "quad sg"
+ QSuperNailgun Weapon = "quad sng"
+ QSuperShotgun Weapon = "quad ssg"
+ RocketLauncher Weapon = "rl"
+ Shotgun Weapon = "sg"
+ Slime Weapon = "slime"
+ Squish Weapon = "squish"
+ Stomp Weapon = "stomp"
+ SuperNailgun Weapon = "sng"
+ SuperShotgun Weapon = "ssg"
+ TeamKill Weapon = "tk"
+ Telefrag Weapon = "telefrag"
+ Trap Weapon = "trap"
+)
+
+type Type uint8
+
+const (
+ Unknown Type = iota
+ Death
+ Suicide
+ Kill
+ TeamKillUnknownKiller
+ TeamKillUnknownVictim
+)
+
+func (t Type) String() string {
+ names := []string{
+ "unknown",
+ "death",
+ "suicide",
+ "kill",
+ "teamkill",
+ "teamkill",
+ }
+
+ if t < 0 || int(t) >= len(names) {
+ return "type(?)"
+ }
+
+ return names[t]
+}
+
+type Obituary struct {
+ Type Type
+ Killer string
+ Victim string
+ Weapon Weapon
+}
+
+func (o Obituary) String() string {
+ hasKiller := o.Killer != ""
+ hasVictim := o.Victim != ""
+
+ switch {
+ case hasKiller && hasVictim:
+ return fmt.Sprintf("%s %s %s %s", o.Type, o.Killer, o.Weapon, o.Victim)
+ case hasKiller:
+ return fmt.Sprintf("%s %s %s", o.Type, o.Killer, o.Weapon)
+ default:
+ return fmt.Sprintf("%s %s %s", o.Type, o.Victim, o.Weapon)
+ }
+}
+
+type Parser struct {
+ templates []template
+}
+
+func init() {
+ sort.SliceStable(templates, func(i, j int) bool {
+ return templates[i].priority > templates[j].priority
+ })
+}
+
+func Parse(input string) (*Obituary, bool) {
+ s := strings.TrimSpace(input)
+
+ for _, t := range templates {
+ x, y, ok := t.parser.parse(s)
+ if !ok {
+ continue
+ }
+
+ ob := &Obituary{Weapon: t.weapon, Type: toObituaryType(t.typ)}
+
+ switch t.typ {
+ case PlayerDeath:
+ ob.Victim = x
+ case PlayerSuicide:
+ ob.Victim = x
+ case XFraggedByY:
+ ob.Victim = x
+ ob.Killer = y
+ case XFragsY:
+ ob.Killer = x
+ ob.Victim = y
+ case XTeamKilled:
+ ob.Victim = x
+ case XTeamKills:
+ ob.Killer = x
+ default:
+ ob.Victim = x
+ ob.Killer = y
+ }
+
+ return ob, true
+ }
+
+ return nil, false
+}