Example #1
0
// Returns an array of all entities of a specified type that are in this
// entity's los.  The entities in the array will be sorted in ascending order
// of distance from this entity.
//    Format
//    ents = nearestNEntites(max, kind)
//
//    Input:
//    max  - integer - Maximum number of entities to return
//    kind - string  - One of "intruder" "denizen" "minion" "servitor"
//                     "master" "non-minion" "non-servitor" "non-master" and
//                     "all".  The "non-*" parameters indicate denizens only
//                     (i.e. will *not* include intruders) that are not of the
//                     type specified.
//
//    Output:
//    ents - array[integer] - Array of entity ids.
func NearestNEntitiesFunc(me *game.Entity) lua.GoFunction {
	valid_kinds := map[string]bool{
		"intruder": true,
		"denizen":  true,
		"minion":   true,
		"servitor": true,
		"master":   true,
		"object":   true,
	}
	return func(L *lua.State) int {
		if !game.LuaCheckParamsOk(L, "NearestNEntities", game.LuaInteger, game.LuaString) {
			return 0
		}
		g := me.Game()
		max := L.ToInteger(-2)
		kind := L.ToString(-1)
		if !valid_kinds[kind] {
			err_str := fmt.Sprintf("NearestNEntities expects kind in the set ['intruder' 'denizen' 'servitor' 'master' 'minion'], got %s.", kind)
			base.Warn().Printf(err_str)
			L.PushString(err_str)
			L.Error()
			return 0
		}
		var eds entityDistSlice
		for _, ent := range g.Ents {
			if ent.Stats != nil && ent.Stats.HpCur() <= 0 {
				continue
			}
			switch kind {
			case "intruder":
				if ent.Side() != game.SideExplorers {
					continue
				}
			case "denizen":
				if ent.Side() != game.SideHaunt {
					continue
				}
			case "minion":
				if ent.HauntEnt == nil || ent.HauntEnt.Level != game.LevelMinion {
					continue
				}
			case "servitor":
				if ent.HauntEnt == nil || ent.HauntEnt.Level != game.LevelServitor {
					continue
				}
			case "master":
				if ent.HauntEnt == nil || ent.HauntEnt.Level != game.LevelMaster {
					continue
				}
			case "object":
				if ent.ObjectEnt == nil {
					continue
				}
			}
			x, y := ent.Pos()
			dx, dy := ent.Dims()
			if !me.HasTeamLos(x, y, dx, dy) {
				continue
			}
			eds = append(eds, entityDist{rangedDistBetween(me, ent), ent})
		}
		// TODO: ONLY GUYS THAT EXIST
		sort.Sort(eds)
		if max > len(eds) {
			max = len(eds)
		}
		if max < 0 {
			max = 0
		}
		eds = eds[0:max]

		// eds contains the results, in order.  Now we make a lua table and
		// populate it with the entity ids of the results.
		L.NewTable()
		for i := range eds {
			L.PushInteger(i + 1)
			game.LuaPushEntity(L, eds[i].ent)
			L.SetTable(-3)
		}
		return 1
	}
}