func (a *AoeAttack) Maintain(dt int64, g *game.Game, ae game.ActionExec) game.MaintenanceStatus { if ae != nil { a.exec = ae.(*aoeExec) a.targets = a.getTargetsAt(g, a.exec.X, a.exec.Y) if a.Current_ammo > 0 { a.Current_ammo-- } a.ent = g.EntityById(ae.EntityId()) if !a.ent.HasLos(a.exec.X, a.exec.Y, 1, 1) { base.Error().Printf("Entity %d tried to target position (%d, %d) with an aoe but doesn't have los to it: %v", a.ent.Id, a.exec.X, a.exec.Y, a.exec) return game.Complete } if a.Ap > a.ent.Stats.ApCur() { base.Error().Printf("Got an aoe attack that required more ap than available: %v", a.exec) return game.Complete } a.ent.Stats.ApplyDamage(-a.Ap, 0, status.Unspecified) // Track this information for the ais - the attacking ent will only // remember one ent that it hit, but that's ok for _, target := range a.targets { if target.Side() != a.ent.Side() { target.Info.LastEntThatAttackedMe = a.ent.Id a.ent.Info.LastEntThatIAttacked = target.Id } } } if a.ent.Sprite().State() != "ready" { return game.InProgress } for _, target := range a.targets { if target.Stats.HpCur() > 0 && target.Sprite().State() != "ready" { return game.InProgress } } a.ent.TurnToFace(a.exec.X, a.exec.Y) for _, target := range a.targets { target.TurnToFace(a.ent.Pos()) } a.ent.Sprite().Command(a.Animation) for _, target := range a.targets { if g.DoAttack(a.ent, target, a.Strength, a.Kind) { for _, name := range a.Conditions { target.Stats.ApplyCondition(status.MakeCondition(name)) } target.Stats.ApplyDamage(0, -a.Damage, a.Kind) if target.Stats.HpCur() <= 0 { target.Sprite().CommandN([]string{"defend", "killed"}) } else { target.Sprite().CommandN([]string{"defend", "damaged"}) } } else { target.Sprite().CommandN([]string{"defend", "undamaged"}) } } return game.Complete }
func (a *BasicAttack) Maintain(dt int64, g *game.Game, ae game.ActionExec) game.MaintenanceStatus { if ae != nil { a.exec = ae.(*basicAttackExec) a.ent = g.EntityById(ae.EntityId()) a.target = a.ent.Game().EntityById(a.exec.Target) // Track this information for the ais if a.ent.Side() != a.target.Side() { a.ent.Info.LastEntThatIAttacked = a.target.Id a.target.Info.LastEntThatAttackedMe = a.ent.Id } if a.Ap > a.ent.Stats.ApCur() { base.Error().Printf("Got a basic attack that required more ap than available: %v", a.exec) base.Error().Printf("Ent: %s, Ap: %d", a.ent.Name, a.ent.Stats.ApCur()) return game.Complete } if !a.validTarget(a.ent, a.target) { base.Error().Printf("Got a basic attack that was invalid for some reason: %v", a.exec) return game.Complete } } if a.ent.Sprite().State() == "ready" && a.target.Sprite().State() == "ready" { a.target.TurnToFace(a.ent.Pos()) a.ent.TurnToFace(a.target.Pos()) if a.Current_ammo > 0 { a.Current_ammo-- } a.ent.Stats.ApplyDamage(-a.Ap, 0, status.Unspecified) var defender_cmds []string if g.DoAttack(a.ent, a.target, a.Strength, a.Kind) { for _, name := range a.Conditions { a.target.Stats.ApplyCondition(status.MakeCondition(name)) } a.target.Stats.ApplyDamage(0, -a.Damage, a.Kind) if a.target.Stats.HpCur() <= 0 { defender_cmds = []string{"defend", "killed"} } else { defender_cmds = []string{"defend", "damaged"} } results[a.exec.id] = BasicAttackResult{Hit: true} } else { defender_cmds = []string{"defend", "undamaged"} results[a.exec.id] = BasicAttackResult{Hit: false} } sprites := []*sprite.Sprite{a.ent.Sprite(), a.target.Sprite()} sprite.CommandSync(sprites, [][]string{[]string{a.Animation}, defender_cmds}, "hit") return game.Complete } return game.InProgress }