示例#1
0
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
}
示例#2
0
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
}
示例#3
0
func (e *Entity) SetGear(gear_name string) bool {
	if e.ExplorerEnt == nil {
		base.Error().Printf("Tried to set gear on a non-explorer entity.")
		return false
	}
	if e.ExplorerEnt.Gear != nil && gear_name != "" {
		base.Error().Printf("Tried to set gear on an explorer that already had gear.")
		return false
	}
	if e.ExplorerEnt.Gear == nil && gear_name == "" {
		base.Error().Printf("Tried to remove gear from an explorer with no gear.")
		return false
	}
	if gear_name == "" {
		algorithm.Choose(&e.Actions, func(a Action) bool {
			return a.String() != e.ExplorerEnt.Gear.Action
		})
		if e.ExplorerEnt.Gear.Condition != "" {
			e.Stats.RemoveCondition(e.ExplorerEnt.Gear.Condition)
		}
		e.ExplorerEnt.Gear = nil
		return true
	}
	var g Gear
	g.Defname = gear_name
	base.GetObject("gear", &g)
	if g.Name == "" {
		base.Error().Printf("Tried to load gear '%s' that doesn't exist.", gear_name)
		return false
	}
	e.ExplorerEnt.Gear = &g
	if g.Action != "" {
		e.Actions = append(e.Actions, MakeAction(g.Action))
	}
	if g.Condition != "" {
		e.Stats.ApplyCondition(status.MakeCondition(g.Condition))
	}
	return true
}
示例#4
0
func ConditionsSpec(c gospec.Context) {
	c.Specify("Conditions are loaded properly.", func() {
		basic := status.MakeCondition("Basic Test")
		_, ok := basic.(*status.BasicCondition)
		c.Expect(ok, Equals, true)
		c.Expect(basic.Strength(), Equals, 5)
		c.Expect(basic.Kind(), Equals, status.Fire)
		var b status.Base
		b = basic.ModifyBase(b, status.Unspecified)
		c.Expect(b.Attack, Equals, 3)
	})

	c.Specify("Conditions can be gobbed without loss of type.", func() {
		buf := bytes.NewBuffer(nil)
		enc := gob.NewEncoder(buf)

		var cs []status.Condition
		cs = append(cs, status.MakeCondition("Basic Test"))

		err := enc.Encode(cs)
		c.Assume(err, Equals, nil)

		dec := gob.NewDecoder(buf)
		var cs2 []status.Condition
		err = dec.Decode(&cs2)
		c.Assume(err, Equals, nil)

		_, ok := cs2[0].(*status.BasicCondition)
		c.Expect(ok, Equals, true)
	})

	c.Specify("Conditions stack properly", func() {
		var s status.Inst
		fd := status.MakeCondition("Fire Debuff Attack")
		pd := status.MakeCondition("Poison Debuff Attack")
		pd2 := status.MakeCondition("Poison Debuff Attack 2")
		c.Expect(s.AttackBonusWith(status.Unspecified), Equals, 0)
		s.ApplyCondition(pd)
		c.Expect(s.AttackBonusWith(status.Unspecified), Equals, -1)
		s.ApplyCondition(fd)
		c.Expect(s.AttackBonusWith(status.Unspecified), Equals, -2)
		s.ApplyCondition(fd)
		c.Expect(s.AttackBonusWith(status.Unspecified), Equals, -2)
		s.ApplyCondition(pd)
		c.Expect(s.AttackBonusWith(status.Unspecified), Equals, -2)
		s.ApplyCondition(pd2)
		c.Expect(s.AttackBonusWith(status.Unspecified), Equals, -3)
	})

	c.Specify("Resistances work", func() {
		var s status.Inst
		fr1 := status.MakeCondition("Fire Resistance")
		fr2 := status.MakeCondition("Greater Fire Resistance")
		c.Expect(s.CorpusVs("Fire"), Equals, s.CorpusVs("Unspecified"))
		s.ApplyCondition(fr1)
		c.Expect(s.CorpusVs("Fire"), Equals, s.CorpusVs("Unspecified")+1)
		c.Expect(s.CorpusVs("Panic"), Equals, s.CorpusVs("Unspecified"))
		c.Expect(s.CorpusVs("Brutal"), Equals, s.CorpusVs("Unspecified"))
		s.ApplyCondition(fr2)
		c.Expect(s.CorpusVs("Fire"), Equals, s.CorpusVs("Unspecified")+3)
		c.Expect(s.CorpusVs("Panic"), Equals, s.CorpusVs("Unspecified"))
		c.Expect(s.CorpusVs("Brutal"), Equals, s.CorpusVs("Unspecified"))
	})

	c.Specify("Basic conditions last the appropriate amount of time", func() {
		var s status.Inst
		s.UnmarshalJSON([]byte(`
      {
        "Base": {
          "Hp_max": 100,
          "Ap_max": 10
        },
        "Dynamic": {
          "Hp": 100
        }
      }`))
		pd := status.MakeCondition("Poison Debuff Attack")
		pd2 := status.MakeCondition("Poison Debuff Attack 2")
		pd.Strength()
		pd2.Strength()
		c.Expect(s.HpCur(), Equals, 100)
		s.ApplyCondition(status.MakeCondition("Fire Debuff Attack"))
		c.Expect(s.HpCur(), Equals, 100)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 99)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 98)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 97)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 97)

		s.ApplyCondition(status.MakeCondition("Fire Debuff Attack"))
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 96)
		s.ApplyCondition(status.MakeCondition("Fire Debuff Attack"))
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 95)
		s.ApplyCondition(status.MakeCondition("Fire Debuff Attack"))
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 94)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 93)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 92)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 92)

		s.ApplyCondition(status.MakeCondition("Fire Debuff Attack"))
		s.ApplyCondition(status.MakeCondition("Poison Debuff Attack"))
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 90)
		s.ApplyCondition(status.MakeCondition("Fire Debuff Attack"))
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 88)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 86)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 85)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 85)

		s.ApplyCondition(status.MakeCondition("Fire Debuff Attack"))
		s.ApplyCondition(status.MakeCondition("Poison Debuff Attack"))
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 83)
		s.ApplyCondition(status.MakeCondition("Poison Debuff Attack 2"))
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 80)
		s.ApplyCondition(status.MakeCondition("Poison Debuff Attack"))
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 77)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 75)
		s.OnRound()
		c.Expect(s.HpCur(), Equals, 75)
	})
}