diff options
Diffstat (limited to 'common/death')
| -rw-r--r-- | common/death/death.go | 132 | ||||
| -rw-r--r-- | common/death/parser.go | 55 | ||||
| -rw-r--r-- | common/death/template.go | 155 |
3 files changed, 342 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 +} diff --git a/common/death/parser.go b/common/death/parser.go new file mode 100644 index 0000000..e86cffb --- /dev/null +++ b/common/death/parser.go @@ -0,0 +1,55 @@ +package death + +import "strings" + +type parser interface { + parse(msg string) (string, string, bool) +} + +type suffixParser struct { + suffix string +} + +func (m suffixParser) parse(msg string) (x, y string, ok bool) { + if !strings.HasSuffix(msg, m.suffix) { + return "", "", false + } + + x = strings.TrimSpace(strings.TrimSuffix(msg, m.suffix)) + if x == "" { + return "", "", false + } + + return x, "", true +} + +type infixParser struct { + sep string + suffix string +} + +func (m infixParser) parse(msg string) (x, y string, ok bool) { + before, after, found := strings.Cut(msg, m.sep) + if !found { + return "", "", false + } + + x = strings.TrimSpace(before) + if x == "" { + return "", "", false + } + + if m.suffix != "" { + if !strings.HasSuffix(after, m.suffix) { + return "", "", false + } + after = strings.TrimSuffix(after, m.suffix) + } + + y = strings.TrimSpace(after) + if y == "" { + return "", "", false + } + + return x, y, true +} diff --git a/common/death/template.go b/common/death/template.go new file mode 100644 index 0000000..3f77c5b --- /dev/null +++ b/common/death/template.go @@ -0,0 +1,155 @@ +package death + +import "strings" + +type templateType uint8 + +const ( + PlayerDeath templateType = iota + PlayerSuicide + XFraggedByY + XFragsY + XTeamKilled + XTeamKills +) + +func toObituaryType(t templateType) Type { + switch t { + case PlayerDeath: + return Death + case PlayerSuicide: + return Suicide + case XFraggedByY, XFragsY: + return Kill + case XTeamKilled: + return TeamKillUnknownKiller + case XTeamKills: + return TeamKillUnknownVictim + default: + return Unknown + } +} + +type template struct { + parser parser + parts []string + priority int + typ templateType + weapon Weapon +} + +func newTemplate(typ templateType, weapon Weapon, parts ...string) template { + prio := 0 + for _, pr := range parts { + prio += len(pr) + } + + var pa parser + switch typ { + case XFraggedByY, XFragsY: + pa = infixParser{ + sep: parts[0], + suffix: strings.Join(parts[1:], ""), + } + default: + pa = suffixParser{ + suffix: strings.Join(parts, ""), + } + } + + return template{ + parser: pa, + parts: parts, + priority: prio, + typ: typ, + weapon: weapon, + } +} + +var templates = []template{ + newTemplate(PlayerDeath, Drown, " sleeps with the fishes"), + newTemplate(PlayerDeath, Drown, " sucks it down"), + newTemplate(PlayerDeath, Fall, " cratered"), + newTemplate(PlayerDeath, Fall, " fell to her death"), + newTemplate(PlayerDeath, Fall, " fell to his death"), + newTemplate(PlayerDeath, Lava, " burst into flames"), + newTemplate(PlayerDeath, Lava, " turned into hot slag"), + newTemplate(PlayerDeath, Lava, " visits the Volcano God"), + newTemplate(PlayerDeath, NoWeapon, " died"), + newTemplate(PlayerDeath, NoWeapon, " tried to leave"), + newTemplate(PlayerDeath, Slime, " can't exist on slime alone"), + newTemplate(PlayerDeath, Slime, " gulped a load of slime"), + newTemplate(PlayerDeath, Squish, " was squished"), + newTemplate(PlayerDeath, Trap, " ate a lavaball"), + newTemplate(PlayerDeath, Trap, " blew up"), + newTemplate(PlayerDeath, Trap, " was spiked"), + newTemplate(PlayerDeath, Trap, " was zapped"), + newTemplate(PlayerSuicide, Discharge, " discharges into the lava"), + newTemplate(PlayerSuicide, Discharge, " discharges into the slime"), + newTemplate(PlayerSuicide, Discharge, " discharges into the water"), + newTemplate(PlayerSuicide, Discharge, " electrocutes herself"), + newTemplate(PlayerSuicide, Discharge, " electrocutes himself"), + newTemplate(PlayerSuicide, Discharge, " heats up the water"), + newTemplate(PlayerSuicide, Discharge, " railcutes herself"), + newTemplate(PlayerSuicide, Discharge, " railcutes himself"), + newTemplate(PlayerSuicide, GrenadeLauncher, " tries to put the pin back in"), + newTemplate(PlayerSuicide, NoWeapon, " suicides"), + newTemplate(PlayerSuicide, RocketLauncher, " becomes bored with life"), + newTemplate(PlayerSuicide, RocketLauncher, " discovers blast radius"), + newTemplate(XFraggedByY, "Axe", " was ax-murdered by "), + newTemplate(XFraggedByY, "Axe", " was axed to pieces by "), + newTemplate(XFraggedByY, QShotgun, " was lead poisoned by "), + newTemplate(XFraggedByY, QSuperNailgun, " was straw-cuttered by "), + newTemplate(XFraggedByY, Discharge, " accepts ", "' discharge"), + newTemplate(XFraggedByY, Discharge, " accepts ", "'s discharge"), + newTemplate(XFraggedByY, Discharge, " drains ", "' batteries"), + newTemplate(XFraggedByY, Discharge, " drains ", "'s batteries"), + newTemplate(XFraggedByY, GrenadeLauncher, " eats ", "' pineapple"), + newTemplate(XFraggedByY, GrenadeLauncher, " eats ", "'s pineapple"), + newTemplate(XFraggedByY, GrenadeLauncher, " was gibbed by ", "' grenade"), + newTemplate(XFraggedByY, GrenadeLauncher, " was gibbed by ", "'s grenade"), + newTemplate(XFraggedByY, LightningGun, " accepts ", "' shaft"), + newTemplate(XFraggedByY, LightningGun, " accepts ", "'s shaft"), + newTemplate(XFraggedByY, Nailgun, " was body pierced by "), + newTemplate(XFraggedByY, Nailgun, " was nailed by "), + newTemplate(XFraggedByY, QLightningGun, " gets a natural disaster from "), + newTemplate(XFraggedByY, QRocketLauncher, " was brutalized by ", "' quad rocket"), + newTemplate(XFraggedByY, QRocketLauncher, " was brutalized by ", "'s quad rocket"), + newTemplate(XFraggedByY, QRocketLauncher, " was smeared by ", "' quad rocket"), + newTemplate(XFraggedByY, QRocketLauncher, " was smeared by ", "'s quad rocket"), + newTemplate(XFraggedByY, QSuperShotgun, " ate 8 loads of ", "' buckshot"), + newTemplate(XFraggedByY, QSuperShotgun, " ate 8 loads of ", "'s buckshot"), + newTemplate(XFraggedByY, RocketLauncher, " rides ", "' rocket"), + newTemplate(XFraggedByY, RocketLauncher, " rides ", "'s rocket"), + newTemplate(XFraggedByY, RocketLauncher, " was gibbed by ", "' rocket"), + newTemplate(XFraggedByY, RocketLauncher, " was gibbed by ", "'s rocket"), + newTemplate(XFraggedByY, Shotgun, " chewed on ", "' boomstick"), + newTemplate(XFraggedByY, Shotgun, " chewed on ", "'s boomstick"), + newTemplate(XFraggedByY, Stomp, " softens ", "' fall"), + newTemplate(XFraggedByY, Stomp, " softens ", "'s fall"), + newTemplate(XFraggedByY, Stomp, " tried to catch "), + newTemplate(XFraggedByY, Stomp, " was crushed by "), + newTemplate(XFraggedByY, Stomp, " was jumped by "), + newTemplate(XFraggedByY, Stomp, " was literally stomped into particles by "), + newTemplate(XFraggedByY, SuperNailgun, " was perforated by "), + newTemplate(XFraggedByY, SuperNailgun, " was punctured by "), + newTemplate(XFraggedByY, SuperNailgun, " was ventilated by "), + newTemplate(XFraggedByY, SuperShotgun, " ate 2 loads of ", "' buckshot"), + newTemplate(XFraggedByY, SuperShotgun, " ate 2 loads of ", "'s buckshot"), + newTemplate(XFraggedByY, Telefrag, " was telefragged by "), + newTemplate(XFragsY, QRocketLauncher, " rips ", " a new one"), + newTemplate(XFragsY, Squish, " squishes "), + newTemplate(XFragsY, Stomp, " stomps "), + newTemplate(XTeamKilled, Stomp, " was crushed by her teammate"), + newTemplate(XTeamKilled, Stomp, " was crushed by his teammate"), + newTemplate(XTeamKilled, Stomp, " was jumped by her teammate"), + newTemplate(XTeamKilled, Stomp, " was jumped by his teammate"), + newTemplate(XTeamKilled, Telefrag, " was telefragged by her teammate"), + newTemplate(XTeamKilled, Telefrag, " was telefragged by his teammate"), + newTemplate(XTeamKills, Squish, " squished a teammate"), + newTemplate(XTeamKills, TeamKill, " checks her glasses"), + newTemplate(XTeamKills, TeamKill, " checks his glasses"), + newTemplate(XTeamKills, TeamKill, " gets a frag for the other team"), + newTemplate(XTeamKills, TeamKill, " loses another friend"), + newTemplate(XTeamKills, TeamKill, " mows down a teammate"), +} |
