func execIntruder(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaNumParamsOk(L, 1, "ExecIntruder") { return 0 } ent := game.LuaToEntity(L, a.game, -1) if ent == nil { game.LuaDoError(L, "Tried to ExecIntruder on an invalid entity.") return 0 } if ent.ExplorerEnt == nil { game.LuaDoError(L, "Tried to ExecIntruder on a non-intruder.") return 0 } if !ent.Ai.Active() { game.LuaDoError(L, fmt.Sprintf("Tried to ExecIntruder '%s', who is not active.", ent.Name)) return 0 } exec := <-ent.Ai.ActionExecs() if exec != nil { a.execs <- exec } <-a.pause return 0 } }
func DoInteractWithObjectFunc(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "DoInteractWithObject", game.LuaEntity) { return 0 } object := game.LuaToEntity(L, a.ent.Game(), -1) var interact *actions.Interact for _, action := range a.ent.Actions { var ok bool interact, ok = action.(*actions.Interact) if ok { break } } if interact == nil { game.LuaDoError(L, "Tried to interact with an object, but don't have an interact action.") L.PushNil() return 1 } exec := interact.AiInteractWithObject(a.ent, object) if exec != nil { a.execs <- exec <-a.pause L.PushBoolean(true) } else { L.PushNil() } return 1 } }
func setIntruderMasterInfo(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "SetEntityMasterInfo", game.LuaEntity, game.LuaString, game.LuaAnything) { return 0 } ent := game.LuaToEntity(L, a.game, -3) if ent == nil { game.LuaDoError(L, "Tried to ExecIntruder on an invalid entity.") return 0 } if ent.ExplorerEnt == nil { game.LuaDoError(L, "Tried to ExecIntruder on a non-intruder.") return 0 } if ent.Ai_data == nil { ent.Ai_data = make(map[string]string) } if L.IsNil(-1) { delete(ent.Ai_data, L.ToString(-2)) } else { ent.Ai_data[L.ToString(-2)] = L.ToString(-1) } return 0 } }
func execMinionFunc(a *Ai) lua.GoFunction { return func(L *lua.State) int { base.Log().Printf("Exec minion") if !game.LuaNumParamsOk(L, 1, "execMinion") { return 0 } ent := game.LuaToEntity(L, a.game, -1) if ent == nil { game.LuaDoError(L, "Tried to execMinion entity which doesn't exist.") return 0 } if ent.HauntEnt == nil || ent.HauntEnt.Level != game.LevelMinion { game.LuaDoError(L, fmt.Sprintf("Tried to execMinion entity with Id=%d, which is not a minion.", ent.Id)) return 0 } if !ent.Ai.Active() { game.LuaDoError(L, fmt.Sprintf("Tried to execMinion entity with Id=%d, which is not active.", ent.Id)) return 0 } exec := <-ent.Ai.ActionExecs() if exec != nil { a.execs <- exec } <-a.pause return 0 } }
func execMinion(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaNumParamsOk(L, 1, "ExecMinion") { return 0 } ent := game.LuaToEntity(L, a.game, -1) if ent == nil { game.LuaDoError(L, "Tried to ExecMinion on an invalid entity.") return 0 } if ent.HauntEnt == nil || ent.HauntEnt.Level != game.LevelMinion { game.LuaDoError(L, "Tried to ExecMinion on a non-minion.") return 0 } if !ent.Ai.Active() { game.LuaDoError(L, fmt.Sprintf("Tried to ExecMinion '%s', who is not active.", ent.Name)) return 0 } exec := <-ent.Ai.ActionExecs() if exec != nil { a.execs <- exec } <-a.pause return 0 } }
// Queries whether or not an entity still exists. An entity existing implies // that it currently alive. // Format: // e = exists(id) // // Input: // id - integer - Entity id of the entity whose existence we are querying. // // Output: // e - boolean - True if the entity exists and has positive hp. func ExistsFunc(a *Ai) lua.GoFunction { return func(L *lua.State) int { // if !game.LuaCheckParamsOk(L, "exists", game.LuaTable) { // return 0 // } if L.IsNil(-1) { return 0 } ent := game.LuaToEntity(L, a.ent.Game(), -1) L.PushBoolean(ent != nil && ent.Stats != nil && ent.Stats.HpCur() > 0) return 1 } }
// Computes the ranged distance between two entities. // Format: // dist = RangedDistBetweenEntities(e1, e2) // // Input: // e1 - integer - An entity id. // e2 - integer - Another entity id. // // Output: // dist - integer - The ranged distance between the two specified entities, // this will not necessarily be the same as // RangedDistBetweenPositions(pos(e1), pos(e2)) if at // least one of the entities isn't 1x1. func RangedDistBetweenEntitiesFunc(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "RangedDistBetweenEntities", game.LuaEntity, game.LuaEntity) { return 0 } e1 := game.LuaToEntity(L, a.ent.Game(), -2) e2 := game.LuaToEntity(L, a.ent.Game(), -1) for _, e := range []*game.Entity{e1, e2} { if e == nil { L.PushNil() return 1 } x, y := e.Pos() dx, dy := e.Dims() if !a.ent.HasLos(x, y, dx, dy) { L.PushNil() return 1 } } L.PushInteger(rangedDistBetween(e1, e2)) return 1 } }
// Returns the room that the specified entity is currently in. The specified // entity must be in los of a unit on the acting entity's team, or be on the // acting entity's team, otherwise this function returns nil. // Format // r = roomContaining(id) // // Input: // id - An entity id. // // Output: // r - room - The room the specified entity is in, or nil if it can't be // seen right now. func RoomContainingFunc(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "roomContaining", game.LuaEntity) { return 0 } ent := game.LuaToEntity(L, a.ent.Game(), -1) side := a.ent.Side() x, y := a.ent.Pos() dx, dy := a.ent.Dims() if ent == nil || (ent.Side() != side && !a.ent.Game().TeamLos(side, x, y, dx, dy)) { L.PushNil() } else { game.LuaPushRoom(L, ent.Game(), ent.Game().House.Floors[0].Rooms[ent.CurrentRoom()]) } return 1 } }
func isActiveIntruder(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "IsActive", game.LuaEntity) { return 0 } ent := game.LuaToEntity(L, a.game, -1) if ent == nil { game.LuaDoError(L, "Tried to IsActive on an invalid entity.") return 0 } if ent.ExplorerEnt == nil { game.LuaDoError(L, "Tried to IsActive on a non-intruder.") return 0 } L.PushBoolean(ent.Ai.Active()) return 1 } }
// Performs a basic attack against the specifed target. // Format: // res = DoBasicAttack(attack, target) // // Inputs: // attack - string - Name of the attack to use. // target - integer - Entity id of the target of this attack. // // Outputs: // res - table - Table containing the following values: // hit (boolean) - true iff the attack hit its target. // If the attack was invalid for some reason res will be nil. func DoBasicAttackFunc(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "DoBasicAttack", game.LuaString, game.LuaEntity) { return 0 } me := a.ent name := L.ToString(-2) 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 } target := game.LuaToEntity(L, a.ent.Game(), -1) if action == nil { game.LuaDoError(L, fmt.Sprintf("Tried to target an entity who doesn't exist.")) return 0 } attack, ok := action.(*actions.BasicAttack) if !ok { game.LuaDoError(L, fmt.Sprintf("Action '%s' is not a basic attack.", name)) return 0 } exec := attack.AiAttackTarget(me, target) if exec != nil { a.execs <- exec <-a.pause result := actions.GetBasicAttackResult(exec) if result == nil { L.PushNil() } else { L.NewTable() L.PushString("hit") L.PushBoolean(result.Hit) L.SetTable(-3) } } else { L.PushNil() } return 1 } }