Пример #1
0
func (exec basicAttackExec) Push(L *lua.State, g *game.Game) {
	exec.BasicActionExec.Push(L, g)
	if L.IsNil(-1) {
		return
	}
	target := g.EntityById(exec.Target)
	L.PushString("Target")
	game.LuaPushEntity(L, target)
	L.SetTable(-3)
}
Пример #2
0
func (a *Ai) addEntityContext() {
	a.loadUtils("entity")

	game.LuaPushEntity(a.L, a.ent)
	a.L.SetGlobal("Me")

	a.L.NewTable()
	game.LuaPushSmartFunctionTable(a.L, game.FunctionTable{
		"BasicAttack":        func() { a.L.PushGoFunction(DoBasicAttackFunc(a)) },
		"AoeAttack":          func() { a.L.PushGoFunction(DoAoeAttackFunc(a)) },
		"Move":               func() { a.L.PushGoFunction(DoMoveFunc(a)) },
		"DoorToggle":         func() { a.L.PushGoFunction(DoDoorToggleFunc(a)) },
		"InteractWithObject": func() { a.L.PushGoFunction(DoInteractWithObjectFunc(a)) },
	})
	a.L.SetMetaTable(-2)
	a.L.SetGlobal("Do")

	a.L.NewTable()
	game.LuaPushSmartFunctionTable(a.L, game.FunctionTable{
		"AllPathablePoints":          func() { a.L.PushGoFunction(AllPathablePointsFunc(a)) },
		"RangedDistBetweenPositions": func() { a.L.PushGoFunction(RangedDistBetweenPositionsFunc(a)) },
		"RangedDistBetweenEntities":  func() { a.L.PushGoFunction(RangedDistBetweenEntitiesFunc(a)) },
		"NearestNEntities":           func() { a.L.PushGoFunction(NearestNEntitiesFunc(a.ent)) },
		"Waypoints":                  func() { a.L.PushGoFunction(WaypointsFunc(a.ent)) },
		"Exists":                     func() { a.L.PushGoFunction(ExistsFunc(a)) },
		"BestAoeAttackPos":           func() { a.L.PushGoFunction(BestAoeAttackPosFunc(a)) },
		"NearbyUnexploredRooms":      func() { a.L.PushGoFunction(NearbyUnexploredRoomsFunc(a)) },
		"RoomPath":                   func() { a.L.PushGoFunction(RoomPathFunc(a)) },
		"RoomContaining":             func() { a.L.PushGoFunction(RoomContainingFunc(a)) },
		"RoomsAreEqual":              func() { a.L.PushGoFunction(RoomAreEqualFunc(a)) },
		"AllDoorsBetween":            func() { a.L.PushGoFunction(AllDoorsBetween(a)) },
		"AllDoorsOn":                 func() { a.L.PushGoFunction(AllDoorsOn(a)) },
		"DoorPositions":              func() { a.L.PushGoFunction(DoorPositionsFunc(a)) },
		"DoorIsOpen":                 func() { a.L.PushGoFunction(DoorIsOpenFunc(a)) },
		"RoomPositions":              func() { a.L.PushGoFunction(RoomPositionsFunc(a)) },
		"Rand":                       func() { a.L.PushGoFunction(randFunc(a)) },
	})
	a.L.SetMetaTable(-2)
	a.L.SetGlobal("Utils")

	a.L.NewTable()
	game.LuaPushSmartFunctionTable(a.L, game.FunctionTable{
		"GetEntsByName": func() { a.L.PushGoFunction(GetEntsByName(a)) },
	})
	a.L.SetMetaTable(-2)
	a.L.SetGlobal("Cheat")
}
Пример #3
0
func (exec interactExec) Push(L *lua.State, g *game.Game) {
	exec.BasicActionExec.Push(L, g)
	if L.IsNil(-1) {
		return
	}
	L.PushString("Toggle Door")
	L.PushBoolean(exec.Toggle_door)
	L.SetTable(-3)
	if exec.Toggle_door {
		L.PushString("Door")
		game.LuaPushDoor(L, g, exec.getDoor(g))
	} else {
		L.PushString("Target")
		game.LuaPushEntity(L, g.EntityById(exec.Target))
	}
	L.SetTable(-3)
}
Пример #4
0
func allMinions(a *Ai) lua.GoFunction {
	return func(L *lua.State) int {
		if !game.LuaCheckParamsOk(L, "AllMinions") {
			return 0
		}
		L.NewTable()
		count := 0
		for _, ent := range a.game.Ents {
			if ent.HauntEnt != nil {
				count++
				L.PushInteger(count)
				game.LuaPushEntity(L, ent)
				L.SetTable(-3)
			}
		}
		return 1
	}
}
Пример #5
0
func GetEntsByName(a *Ai) lua.GoFunction {
	return func(L *lua.State) int {
		if !game.LuaCheckParamsOk(L, "GetEntsByName", game.LuaString) {
			return 0
		}
		name := L.ToString(-1)
		count := 1
		L.NewTable()
		for _, ent := range a.game.Ents {
			if ent.Name == name {
				L.PushInteger(count)
				count++
				game.LuaPushEntity(L, ent)
				L.SetTable(-3)
			}
		}
		return 1
	}
}
Пример #6
0
// Performs an aoe attack against centered at the specified position.
//    Format:
//    target = BestAoeAttackPos(attack, extra_dist, spec)
//
//    Inputs:
//    attack     - string  - Name of the attack to use.
//    extra_dist - integer - Available distance to move before attacking.
//    spec       - string  - One of the following values:
//                           "allies ok", "minions ok", "enemies only"
//
//    Outputs:
//    pos  - table[x,y] - Position to place aoe for maximum results.
//    hits - array[ents] - Visible entities that will be in the aoe
func BestAoeAttackPosFunc(a *Ai) lua.GoFunction {
	return func(L *lua.State) int {
		if !game.LuaCheckParamsOk(L, "BestAoeAttackPos", game.LuaString, game.LuaInteger, game.LuaString) {
			return 0
		}
		me := a.ent
		name := L.ToString(-3)
		action := getActionByName(me, name)
		if action == nil {
			game.LuaDoError(L, fmt.Sprintf("Entity '%s' (id=%d) has no action named '%s'.", me.Name, me.Id, name))
			return 0
		}
		attack, ok := action.(*actions.AoeAttack)
		if !ok {
			game.LuaDoError(L, fmt.Sprintf("Action '%s' is not an aoe attack.", name))
			return 0
		}
		var spec actions.AiAoeTarget
		switch L.ToString(-1) {
		case "allies ok":
			spec = actions.AiAoeHitAlliesOk
		case "minions ok":
			spec = actions.AiAoeHitMinionsOk
		case "enemies only":
			spec = actions.AiAoeHitNoAllies
		default:
			game.LuaDoError(L, fmt.Sprintf("'%s' is not a valid value of spec for BestAoeAttackPos().", L.ToString(-1)))
			return 0
		}
		x, y, hits := attack.AiBestTarget(me, L.ToInteger(-2), spec)
		game.LuaPushPoint(L, x, y)
		L.NewTable()
		for i := range hits {
			L.PushInteger(i + 1)
			game.LuaPushEntity(L, hits[i])
			L.SetTable(-3)
		}
		return 2
	}
}
Пример #7
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
	}
}