130 lines
3.3 KiB
Go
130 lines
3.3 KiB
Go
package challenge
|
|
|
|
func (e *Engine) register(event Event, p *Player) {
|
|
if p.Registered || p.InDungeon {
|
|
e.impossible(event)
|
|
return
|
|
}
|
|
p.Registered = true
|
|
e.log(event.At, "Player [%d] registered", p.ID)
|
|
}
|
|
|
|
func (e *Engine) enterDungeon(event Event, p *Player) {
|
|
if p.InDungeon || event.At < e.openAt || event.At >= e.closeAt {
|
|
e.impossible(event)
|
|
return
|
|
}
|
|
p.InDungeon = true
|
|
p.Attempted = true
|
|
p.EnteredAt = event.At
|
|
p.EndedAt = event.At
|
|
p.Floor = 1
|
|
e.startFloorTimer(p, event.At)
|
|
e.log(event.At, "Player [%d] entered the dungeon", p.ID)
|
|
}
|
|
|
|
func (e *Engine) killMonster(event Event, p *Player) {
|
|
if !p.InDungeon || p.Floor < 1 || p.Floor > e.regularFloors || p.MonsterKills[p.Floor] >= e.cfg.Monsters {
|
|
e.impossible(event)
|
|
return
|
|
}
|
|
p.MonsterKills[p.Floor]++
|
|
e.log(event.At, "Player [%d] killed the monster", p.ID)
|
|
if p.MonsterKills[p.Floor] == e.cfg.Monsters {
|
|
e.finishFloorTimer(p, event.At)
|
|
}
|
|
}
|
|
|
|
func (e *Engine) nextFloor(event Event, p *Player) {
|
|
if !p.InDungeon || p.Floor < 1 || p.Floor >= e.cfg.Floors || !e.floorCleared(p, p.Floor) {
|
|
e.impossible(event)
|
|
return
|
|
}
|
|
e.pauseFloorTimer(p, event.At)
|
|
p.Floor++
|
|
e.startFloorTimer(p, event.At)
|
|
e.log(event.At, "Player [%d] went to the next floor", p.ID)
|
|
}
|
|
|
|
func (e *Engine) previousFloor(event Event, p *Player) {
|
|
if !p.InDungeon || p.Floor <= 1 {
|
|
e.impossible(event)
|
|
return
|
|
}
|
|
e.pauseFloorTimer(p, event.At)
|
|
p.Floor--
|
|
e.startFloorTimer(p, event.At)
|
|
e.log(event.At, "Player [%d] went to the previous floor", p.ID)
|
|
}
|
|
|
|
func (e *Engine) enterBoss(event Event, p *Player) {
|
|
if !p.InDungeon || p.BossEntered || p.Floor != e.cfg.Floors || !e.allRegularFloorsCleared(p) {
|
|
e.impossible(event)
|
|
return
|
|
}
|
|
p.BossEntered = true
|
|
p.BossEnterAt = event.At
|
|
e.log(event.At, "Player [%d] entered the boss's floor", p.ID)
|
|
}
|
|
|
|
func (e *Engine) killBoss(event Event, p *Player) {
|
|
if !p.InDungeon || !p.BossEntered || p.BossKilled {
|
|
e.impossible(event)
|
|
return
|
|
}
|
|
p.BossKilled = true
|
|
p.BossTime = event.At - p.BossEnterAt
|
|
e.log(event.At, "Player [%d] killed the boss", p.ID)
|
|
}
|
|
|
|
func (e *Engine) leaveDungeon(event Event, p *Player) {
|
|
if !p.InDungeon {
|
|
e.impossible(event)
|
|
return
|
|
}
|
|
e.pauseFloorTimer(p, event.At)
|
|
p.InDungeon = false
|
|
p.Left = true
|
|
p.Terminal = true
|
|
p.EndedAt = event.At
|
|
e.log(event.At, "Player [%d] left the dungeon", p.ID)
|
|
}
|
|
|
|
func (e *Engine) cannotContinue(event Event, p *Player) {
|
|
p.Disqual = true
|
|
p.Terminal = true
|
|
p.EndedAt = event.At
|
|
e.log(event.At, "Player [%d] cannot continue due to [%s]", p.ID, event.Extra)
|
|
}
|
|
|
|
func (e *Engine) restoreHealth(event Event, p *Player) {
|
|
amount, ok := parseNonNegativeInt(event.Extra)
|
|
if !ok || !p.InDungeon {
|
|
e.impossible(event)
|
|
return
|
|
}
|
|
p.Health = min(100, p.Health+amount)
|
|
e.log(event.At, "Player [%d] has restored [%d] of health", p.ID, amount)
|
|
}
|
|
|
|
func (e *Engine) takeDamage(event Event, p *Player) {
|
|
damage, ok := parseNonNegativeInt(event.Extra)
|
|
if !ok || !p.InDungeon {
|
|
e.impossible(event)
|
|
return
|
|
}
|
|
p.Health = max(0, p.Health-damage)
|
|
e.log(event.At, "Player [%d] recieved [%d] of damage", p.ID, damage)
|
|
if p.Health == 0 {
|
|
e.pauseFloorTimer(p, event.At)
|
|
p.Dead = true
|
|
p.InDungeon = false
|
|
p.Terminal = true
|
|
p.EndedAt = event.At
|
|
e.log(event.At, "Player [%d] is dead", p.ID)
|
|
}
|
|
}
|
|
|
|
func (e *Engine) impossible(event Event) {
|
|
e.log(event.At, "Player [%d] makes imposible move [%d]", event.Player, event.ID)
|
|
}
|