Files
scummvm-cursorfix/engines/ultima/nuvie/script/script_actor.cpp
2026-02-02 04:50:13 +01:00

1872 lines
48 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/lua/lauxlib.h"
#include "ultima/nuvie/actors/actor.h"
#include "ultima/nuvie/core/nuvie_defs.h"
#include "ultima/nuvie/misc/u6_misc.h"
#include "ultima/nuvie/script/script_actor.h"
#include "ultima/nuvie/core/player.h"
#include "ultima/nuvie/core/game.h"
#include "ultima/nuvie/core/effect.h"
#include "ultima/nuvie/actors/actor_manager.h"
#include "ultima/nuvie/actors/actor.h"
#include "ultima/nuvie/views/view_manager.h"
#include "ultima/nuvie/core/converse.h"
#include "ultima/nuvie/usecode/usecode.h"
#include "ultima/nuvie/views/portrait_view.h"
namespace Ultima {
namespace Nuvie {
///
//@module script
/***
An Actor object
@table Actor
@string[readonly] luatype This returns "actor"
@int[readonly] actor_num
@int align alignment
- 0 = DEFAULT
- 1 = NEUTRAL
- 2 = EVIL
- 3 = GOOD
- 4 = CHAOTIC
@bool[readonly] alive
@bool asleep
@int base_obj_n
@bool charmed
@bool cold (MD) bit 0 on the status flags. Set when the actor is cold.
@int combat_mode
@bool corpser_flag (U6) Has the actor been dragged underground by a corpser
@bool cursed
@int dex dexterity
@int direction The direction that the actor is facing.
- 0 = NORTH
- 1 = EAST
- 2 = SOUTH
- 3 = WEST
- 4 = NORTHEAST
- 5 = SOUTHEAST
- 6 = SOUTHWEST
- 7 = NORTHWEST
- 8 = NONE
@int exp experience
@int frame_n
@bool frenzy (MD) battle frenzy
@bool hit_flag Used by U6 to determine if an actor has been hit.
@int hp hit points
@bool hypoxia (MD) bit 6 on the obj flags. Tells if the actor is oxygen deprived
@bool[readonly] in_party Is the actor a mamber of the party?
@bool[readonly] in_vehicle Is the actor currently in a vehicle?
@int int intelligence
@int level
@int magic
@int[readonly] max_hp
@int mpts movement points
@string[readonly] name
@bool obj_flag_0 obj flag 0
@int obj_n
@int old_align Old alignment
@int[readonly] old_frame_n
@bool paralyzed
@bool poisoned
@bool protected
@int[readonly] sched_loc The location defined for the Actor's currently active schedule entry.
@int[readonly] sched_wt The worktype of the currently active schedule.
@int str strength
@bool[readonly] temp Is this a temporary actor?
@int[readonly] tile_num The tile number based on the obj_n + frame_n combination.
@bool visible Is the actor currently visible?
@int wt worktype
@field[readonly] xyz table containing location
table format
```
{["x"]=x, ["y"]=y, ["z"]=z}
```
@int x
@int y
@int z
*/
extern bool nscript_get_location_from_args(lua_State *L, uint16 *x, uint16 *y, uint8 *z, int lua_stack_offset = 1);
extern Obj *nscript_get_obj_from_args(lua_State *L, int lua_stack_offset);
extern void nscript_new_obj_var(lua_State *L, Obj *obj);
extern int nscript_obj_new(lua_State *L, Obj *obj);
extern int nscript_u6llist_iter(lua_State *L);
extern int nscript_init_u6link_iter(lua_State *L, U6LList *list, bool is_recursive);
static int nscript_actor_new(lua_State *L);
static int nscript_actor_clone(lua_State *L);
static int nscript_get_actor_from_num(lua_State *L);
Actor *nscript_get_actor_from_args(lua_State *L, int lua_stack_offset = 1);
static int nscript_actor_set(lua_State *L);
static int nscript_actor_get(lua_State *L);
static int nscript_get_player_actor(lua_State *L);
static int nscript_actor_kill(lua_State *L);
static int nscript_actor_hit(lua_State *L);
static int nscript_actor_get_range(lua_State *L);
static int nscript_actor_resurrect(lua_State *L);
static int nscript_actor_inv_add_obj(lua_State *L);
static int nscript_actor_inv_remove_obj(lua_State *L);
static int nscript_actor_inv_remove_obj_qty(lua_State *L);
static int nscript_actor_inv_get_readied_obj_n(lua_State *L);
static int nscript_actor_inv_ready_obj(lua_State *L);
static int nscript_actor_inv_unready_obj(lua_State *L);
static int nscript_actor_inv_has_obj_n(lua_State *L);
static int nscript_actor_inv_get_obj_n(lua_State *L);
static int nscript_actor_inv_get_obj_total_qty(lua_State *L);
static int nscript_actor_move(lua_State *L);
static int nscript_actor_walk_path(lua_State *L);
static int nscript_actor_is_at_scheduled_location(lua_State *L);
static int nscript_actor_can_carry_obj(lua_State *L);
static int nscript_actor_can_carry_obj_weight(lua_State *L);
static int nscript_actor_black_fade_effect(lua_State *L);
static int nscript_actor_fade_out_effect(lua_State *L);
static int nscript_actor_show_portrait(lua_State *L);
static int nscript_actor_hide_portrait(lua_State *L);
static int nscript_actor_talk(lua_State *L);
static int nscript_actor_unlink_surrounding_objs(lua_State *L);
static int nscript_actor_use(lua_State *L);
static int nscript_actor_get_talk_flag(lua_State *L);
static int nscript_actor_set_talk_flag(lua_State *L);
static int nscript_actor_clear_talk_flag(lua_State *L);
static int nscript_actor_get_number_of_schedules(lua_State *L);
static int nscript_actor_get_schedule(lua_State *L);
static const struct luaL_Reg nscript_actorlib_f[] = {
{ "new", nscript_actor_new },
{ "clone", nscript_actor_clone },
{ "kill", nscript_actor_kill },
{ "hit", nscript_actor_hit },
{ "get_range", nscript_actor_get_range },
{ "resurrect", nscript_actor_resurrect },
{ "move", nscript_actor_move },
{ "walk_path", nscript_actor_walk_path },
{ "get", nscript_get_actor_from_num },
{ "get_player_actor", nscript_get_player_actor },
{ "inv_add_obj", nscript_actor_inv_add_obj },
{ "inv_remove_obj", nscript_actor_inv_remove_obj },
{ "inv_remove_obj_qty", nscript_actor_inv_remove_obj_qty },
{ "inv_get_readied_obj_n", nscript_actor_inv_get_readied_obj_n },
{ "inv_ready_obj", nscript_actor_inv_ready_obj },
{ "inv_unready_obj", nscript_actor_inv_unready_obj },
{ "inv_has_obj_n", nscript_actor_inv_has_obj_n },
{ "inv_get_obj_n", nscript_actor_inv_get_obj_n },
{ "inv_get_obj_total_qty", nscript_actor_inv_get_obj_total_qty },
{ "is_at_scheduled_location", nscript_actor_is_at_scheduled_location },
{ "can_carry_obj", nscript_actor_can_carry_obj },
{ "can_carry_obj_weight", nscript_actor_can_carry_obj_weight },
{ "black_fade_effect", nscript_actor_black_fade_effect },
{ "fade_out", nscript_actor_fade_out_effect },
{ "show_portrait", nscript_actor_show_portrait },
{ "hide_portrait", nscript_actor_hide_portrait },
{ "talk", nscript_actor_talk },
{ "unlink_surrounding_objs", nscript_actor_unlink_surrounding_objs },
{ "use", nscript_actor_use },
{ "get_talk_flag", nscript_actor_get_talk_flag },
{ "set_talk_flag", nscript_actor_set_talk_flag },
{ "clear_talk_flag", nscript_actor_clear_talk_flag },
{ "get_number_of_schedules", nscript_actor_get_number_of_schedules },
{ "get_schedule", nscript_actor_get_schedule },
{ nullptr, nullptr }
};
static const struct luaL_Reg nscript_actorlib_m[] = {
{ "__index", nscript_actor_get },
{ "__newindex", nscript_actor_set },
{ nullptr, nullptr }
};
//Actor variables - must be in alphabetical order
static const char *const actor_set_vars[] = {
"align",
"asleep",
"base_obj_n",
"charmed",
"cold",
"combat_mode",
"corpser_flag",
"cursed",
"dex",
"direction",
"exp",
"frame_n",
"frenzy",
"hit_flag",
"hp",
"hypoxia",
"int",
"level",
"magic",
"mpts",
"obj_flag_0",
"obj_n",
"old_align",
"paralyzed",
"poisoned",
"protected",
"str",
"visible",
"wt",
"x",
"y",
"z"
};
//Actor variables - must be in alphabetical order
static const char *const actor_get_vars[] = {
"actor_num",
"align",
"alive",
"asleep",
"base_obj_n",
"charmed",
"cold",
"combat_mode",
"corpser_flag",
"cursed",
"dex",
"direction",
"exp",
"frame_n",
"frenzy",
"hit_flag",
"hp",
"hypoxia",
"in_party",
"in_vehicle",
"int",
"level",
"luatype",
"magic",
"max_hp",
"mpts",
"name",
"obj_flag_0",
"obj_n",
"old_align",
"old_frame_n",
"paralyzed",
"poisoned",
"protected",
"sched_loc",
"sched_wt",
"str",
"temp",
"tile_num",
"visible",
"wt",
"x",
"xyz",
"y",
"z"
};
//Actor set
static int nscript_actor_set_align(Actor *actor, lua_State *L);
static int nscript_actor_set_asleep_flag(Actor *actor, lua_State *L);
static int nscript_actor_set_base_obj_n(Actor *actor, lua_State *L);
static int nscript_actor_set_charmed_flag(Actor *actor, lua_State *L);
static int nscript_actor_set_cold_flag(Actor *actor, lua_State *L);
static int nscript_actor_set_combat_mode(Actor *actor, lua_State *L);
static int nscript_actor_set_corpser_flag(Actor *actor, lua_State *L);
static int nscript_actor_set_cursed_flag(Actor *actor, lua_State *L);
static int nscript_actor_set_dexterity(Actor *actor, lua_State *L);
static int nscript_actor_set_direction(Actor *actor, lua_State *L);
static int nscript_actor_set_exp(Actor *actor, lua_State *L);
static int nscript_actor_set_frame_n(Actor *actor, lua_State *L);
static int nscript_actor_set_frenzy(Actor *actor, lua_State *L);
static int nscript_actor_set_hit(Actor *actor, lua_State *L);
static int nscript_actor_set_hp(Actor *actor, lua_State *L);
static int nscript_actor_set_hypoxia(Actor *actor, lua_State *L);
static int nscript_actor_set_intelligence(Actor *actor, lua_State *L);
static int nscript_actor_set_level(Actor *actor, lua_State *L);
static int nscript_actor_set_magic(Actor *actor, lua_State *L);
static int nscript_actor_set_movement_pts(Actor *actor, lua_State *L);
static int nscript_actor_set_obj_flag_0(Actor *actor, lua_State *L);
static int nscript_actor_set_obj_n(Actor *actor, lua_State *L);
static int nscript_actor_set_old_align(Actor *actor, lua_State *L);
static int nscript_actor_set_paralyzed_flag(Actor *actor, lua_State *L);
static int nscript_actor_set_poisoned_flag(Actor *actor, lua_State *L);
static int nscript_actor_set_protected_flag(Actor *actor, lua_State *L);
static int nscript_actor_set_strength(Actor *actor, lua_State *L);
static int nscript_actor_set_visible_flag(Actor *actor, lua_State *L);
static int nscript_actor_set_worktype(Actor *actor, lua_State *L);
static int nscript_actor_set_x(Actor *actor, lua_State *L);
static int nscript_actor_set_y(Actor *actor, lua_State *L);
static int nscript_actor_set_z(Actor *actor, lua_State *L);
int (*const actor_set_func[])(Actor *, lua_State *) = {
nscript_actor_set_align,
nscript_actor_set_asleep_flag,
nscript_actor_set_base_obj_n,
nscript_actor_set_charmed_flag,
nscript_actor_set_cold_flag,
nscript_actor_set_combat_mode,
nscript_actor_set_corpser_flag,
nscript_actor_set_cursed_flag,
nscript_actor_set_dexterity,
nscript_actor_set_direction,
nscript_actor_set_exp,
nscript_actor_set_frame_n,
nscript_actor_set_frenzy,
nscript_actor_set_hit,
nscript_actor_set_hp,
nscript_actor_set_hypoxia,
nscript_actor_set_intelligence,
nscript_actor_set_level,
nscript_actor_set_magic,
nscript_actor_set_movement_pts,
nscript_actor_set_obj_flag_0,
nscript_actor_set_obj_n,
nscript_actor_set_old_align,
nscript_actor_set_paralyzed_flag,
nscript_actor_set_poisoned_flag,
nscript_actor_set_protected_flag,
nscript_actor_set_strength,
nscript_actor_set_visible_flag,
nscript_actor_set_worktype,
nscript_actor_set_x,
nscript_actor_set_y,
nscript_actor_set_z
};
//Actor get
static int nscript_actor_get_actor_num(Actor *actor, lua_State *L);
static int nscript_actor_get_align(Actor *actor, lua_State *L);
static int nscript_actor_get_alive(Actor *actor, lua_State *L);
static int nscript_actor_get_asleep_flag(Actor *actor, lua_State *L);
static int nscript_actor_get_base_obj_n(Actor *actor, lua_State *L);
static int nscript_actor_get_charmed_flag(Actor *actor, lua_State *L);
static int nscript_actor_get_cold_flag(Actor *actor, lua_State *L);
static int nscript_actor_get_combat_mode(Actor *actor, lua_State *L);
static int nscript_actor_get_corpser_flag(Actor *actor, lua_State *L);
static int nscript_actor_get_cursed_flag(Actor *actor, lua_State *L);
static int nscript_actor_get_dexterity(Actor *actor, lua_State *L);
static int nscript_actor_get_direction(Actor *actor, lua_State *L);
static int nscript_actor_get_exp(Actor *actor, lua_State *L);
static int nscript_actor_get_frame_n(Actor *actor, lua_State *L);
static int nscript_actor_get_frenzy(Actor *actor, lua_State *L);
static int nscript_actor_get_hit_flag(Actor *actor, lua_State *L);
static int nscript_actor_get_hp(Actor *actor, lua_State *L);
static int nscript_actor_get_hypoxia(Actor *actor, lua_State *L);
static int nscript_actor_get_in_party_status(Actor *actor, lua_State *L);
static int nscript_actor_get_in_vehicle(Actor *actor, lua_State *L);
static int nscript_actor_get_intelligence(Actor *actor, lua_State *L);
static int nscript_actor_get_level(Actor *actor, lua_State *L);
static int nscript_actor_get_luatype(Actor *actor, lua_State *L);
static int nscript_actor_get_magic(Actor *actor, lua_State *L);
static int nscript_actor_get_max_hp(Actor *actor, lua_State *L);
static int nscript_actor_get_movement_pts(Actor *actor, lua_State *L);
static int nscript_actor_get_name(Actor *actor, lua_State *L);
static int nscript_actor_get_obj_flag_0(Actor *actor, lua_State *L);
static int nscript_actor_get_obj_n(Actor *actor, lua_State *L);
static int nscript_actor_get_old_align(Actor *actor, lua_State *L);
static int nscript_actor_get_old_frame_n(Actor *actor, lua_State *L);
static int nscript_actor_get_paralyzed_flag(Actor *actor, lua_State *L);
static int nscript_actor_get_poisoned_flag(Actor *actor, lua_State *L);
static int nscript_actor_get_protected_flag(Actor *actor, lua_State *L);
static int nscript_actor_get_sched_loc(Actor *actor, lua_State *L);
static int nscript_actor_get_sched_worktype(Actor *actor, lua_State *L);
static int nscript_actor_get_strength(Actor *actor, lua_State *L);
static int nscript_actor_get_temp_status(Actor *actor, lua_State *L);
static int nscript_actor_get_tile_num(Actor *actor, lua_State *L);
static int nscript_actor_get_visible_flag(Actor *actor, lua_State *L);
static int nscript_actor_get_worktype(Actor *actor, lua_State *L);
static int nscript_actor_get_x(Actor *actor, lua_State *L);
static int nscript_actor_get_xyz(Actor *actor, lua_State *L);
static int nscript_actor_get_y(Actor *actor, lua_State *L);
static int nscript_actor_get_z(Actor *actor, lua_State *L);
int (*const actor_get_func[])(Actor *, lua_State *) = {
nscript_actor_get_actor_num,
nscript_actor_get_align,
nscript_actor_get_alive,
nscript_actor_get_asleep_flag,
nscript_actor_get_base_obj_n,
nscript_actor_get_charmed_flag,
nscript_actor_get_cold_flag,
nscript_actor_get_combat_mode,
nscript_actor_get_corpser_flag,
nscript_actor_get_cursed_flag,
nscript_actor_get_dexterity,
nscript_actor_get_direction,
nscript_actor_get_exp,
nscript_actor_get_frame_n,
nscript_actor_get_frenzy,
nscript_actor_get_hit_flag,
nscript_actor_get_hp,
nscript_actor_get_hypoxia,
nscript_actor_get_in_party_status,
nscript_actor_get_in_vehicle,
nscript_actor_get_intelligence,
nscript_actor_get_level,
nscript_actor_get_luatype,
nscript_actor_get_magic,
nscript_actor_get_max_hp,
nscript_actor_get_movement_pts,
nscript_actor_get_name,
nscript_actor_get_obj_flag_0,
nscript_actor_get_obj_n,
nscript_actor_get_old_align,
nscript_actor_get_old_frame_n,
nscript_actor_get_paralyzed_flag,
nscript_actor_get_poisoned_flag,
nscript_actor_get_protected_flag,
nscript_actor_get_sched_loc,
nscript_actor_get_sched_worktype,
nscript_actor_get_strength,
nscript_actor_get_temp_status,
nscript_actor_get_tile_num,
nscript_actor_get_visible_flag,
nscript_actor_get_worktype,
nscript_actor_get_x,
nscript_actor_get_xyz,
nscript_actor_get_y,
nscript_actor_get_z
};
static int nscript_map_get_actor(lua_State *L);
static int nscript_update_actor_schedules(lua_State *L);
static int nscript_actor_inv(lua_State *L);
void nscript_init_actor(lua_State *L) {
luaL_newmetatable(L, "nuvie.Actor");
luaL_register(L, nullptr, nscript_actorlib_m);
luaL_register(L, "Actor", nscript_actorlib_f);
lua_pushcfunction(L, nscript_map_get_actor);
lua_setglobal(L, "map_get_actor");
lua_pushcfunction(L, nscript_update_actor_schedules);
lua_setglobal(L, "update_actor_schedules");
lua_pushcfunction(L, nscript_actor_inv);
lua_setglobal(L, "actor_inventory");
}
bool nscript_new_actor_var(lua_State *L, uint16 actor_num) {
uint16 *userdata;
userdata = (uint16 *)lua_newuserdata(L, sizeof(uint16));
luaL_getmetatable(L, "nuvie.Actor");
lua_setmetatable(L, -2);
*userdata = actor_num;
return true;
}
/***
Create a new temporary Actor.
@function Actor.new
@int obj_n
@int[opt=0] x
@int[opt=0] y
@int[opt=0] z
@int[opt=NEUTRAL] alignment
@int[opt=8] worktype
@treturn Actor|nil
@within Actor
*/
static int nscript_actor_new(lua_State *L) {
Actor *actor;
uint16 obj_n = 0;
uint16 x = 0;
uint16 y = 0;
uint8 z = 0;
ActorAlignment alignment = ACTOR_ALIGNMENT_NEUTRAL;
uint8 worktype = ACTOR_WT_ASSAULT; //FIXME this may be U6 specific.
int nargs = lua_gettop(L);
if (nargs > 1) { // do we have arguments?
uint8 i = nargs;
if (i) {
if (!lua_isnil(L, 1))
obj_n = (uint16)lua_tointeger(L, 1);
i--;
}
if (i) {
if (!lua_isnil(L, 2))
x = (uint16)lua_tointeger(L, 2);
i--;
}
if (i) {
if (!lua_isnil(L, 3))
y = (uint16)lua_tointeger(L, 3);
i--;
}
if (i) {
if (!lua_isnil(L, 4))
z = (uint8)lua_tointeger(L, 4);
i--;
}
if (i) {
if (!lua_isnil(L, 5))
alignment = (ActorAlignment)lua_tointeger(L, 5);
i--;
}
if (i) {
if (!lua_isnil(L, 6))
worktype = (uint8)lua_tointeger(L, 6);
i--;
}
//init here.
if (Game::get_game()->get_actor_manager()->create_temp_actor(obj_n, NO_OBJ_STATUS, x, y, z, alignment, worktype, &actor) == false)
return 0;
//create the new lua Actor variable
if (nscript_new_actor_var(L, actor->get_actor_num()) == false)
return 0;
}
return 1;
}
/***
Clone an actor as a new temporary actor.
@function Actor.clone
@tparam Actor actor Actor to clone
@tparam MapCoord|x,y,z location Location to place newly cloned actor.
@within Actor
*/
static int nscript_actor_clone(lua_State *L) {
Actor *actor, *new_actor;
uint16 x, y;
uint8 z;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
if (nscript_get_location_from_args(L, &x, &y, &z, 2) == false)
return 0;
int stack_offset = lua_istable(L, 2) ? 3 : 5;
if (lua_gettop(L) >= stack_offset) {
//FIXME clone into existing actor here.
}
if (Game::get_game()->get_actor_manager()->clone_actor(actor, &new_actor, MapCoord(x, y, z))) {
if (nscript_new_actor_var(L, actor->get_actor_num()) == true)
return 1;
}
return 0;
}
/***
Get an Actor object from an actor number
@function Actor.get
@int actor_number
@treturn Actor
@within Actor
*/
static int nscript_get_actor_from_num(lua_State *L) {
uint16 actor_num;
actor_num = (uint16)lua_tointeger(L, 1);
assert(actor_num < ACTORMANAGER_MAX_ACTORS);
nscript_new_actor_var(L, actor_num);
return 1;
}
Actor *nscript_get_actor_from_args(lua_State *L, int lua_stack_offset) {
Actor *actor = nullptr;
if (lua_isuserdata(L, lua_stack_offset)) {
uint16 *actor_num = (uint16 *)luaL_checkudata(L, lua_stack_offset, "nuvie.Actor");
if (actor_num != nullptr)
actor = Game::get_game()->get_actor_manager()->get_actor(*actor_num);
} else {
actor = Game::get_game()->get_actor_manager()->get_actor((uint16)lua_tointeger(L, lua_stack_offset));
}
return actor;
}
/***
Get the current player Actor object
@function Actor.get_player_actor
@treturn Actor
@within Actor
*/
static int nscript_get_player_actor(lua_State *L) {
Actor *player_actor = Game::get_game()->get_player()->get_actor();
nscript_new_actor_var(L, player_actor->get_actor_num());
return 1;
}
static int nscript_actor_set(lua_State *L) {
Actor *actor;
const char *key;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
key = lua_tostring(L, 2);
int idx = str_bsearch(actor_set_vars, sizeof(actor_set_vars) / sizeof(actor_set_vars[0]), (const char *)key);
if (idx == -1)
return 0;
(*actor_set_func[idx])(actor, L);
return 0;
}
static int nscript_actor_set_align(Actor *actor, lua_State *L) {
actor->set_alignment((ActorAlignment)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_asleep_flag(Actor *actor, lua_State *L) {
actor->set_asleep(lua_toboolean(L, 3));
return 0;
}
static int nscript_actor_set_charmed_flag(Actor *actor, lua_State *L) {
actor->set_charmed(lua_toboolean(L, 3));
return 0;
}
static int nscript_actor_set_cold_flag(Actor *actor, lua_State *L) {
actor->set_status_flag(ACTOR_MD_STATUS_FLAG_COLD, lua_toboolean(L, 3));
return 0;
}
static int nscript_actor_set_combat_mode(Actor *actor, lua_State *L) {
actor->set_combat_mode((uint8)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_corpser_flag(Actor *actor, lua_State *L) {
actor->set_corpser_flag(lua_toboolean(L, 3));
return 0;
}
static int nscript_actor_set_cursed_flag(Actor *actor, lua_State *L) {
actor->set_cursed(lua_toboolean(L, 3));
return 0;
}
static int nscript_actor_set_dexterity(Actor *actor, lua_State *L) {
actor->set_dexterity((uint8)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_direction(Actor *actor, lua_State *L) {
actor->set_direction((NuvieDir)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_exp(Actor *actor, lua_State *L) {
actor->set_exp((uint16)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_frame_n(Actor *actor, lua_State *L) {
actor->set_frame_n((uint16)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_frenzy(Actor *actor, lua_State *L) {
actor->set_obj_flag(ACTOR_MD_OBJ_FLAG_FRENZY, lua_toboolean(L, 3));
return 0;
}
static int nscript_actor_set_hp(Actor *actor, lua_State *L) {
actor->set_hp((uint8)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_hypoxia(Actor *actor, lua_State *L) {
actor->set_obj_flag(ACTOR_MD_OBJ_FLAG_HYPOXIA, lua_toboolean(L, 3)); //MD uses object bit 6 which is cursed in U6.
return 0;
}
static int nscript_actor_set_hit(Actor *actor, lua_State *L) {
actor->set_hit_flag(lua_toboolean(L, 3));
return 0;
}
static int nscript_actor_set_intelligence(Actor *actor, lua_State *L) {
actor->set_intelligence((uint8)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_level(Actor *actor, lua_State *L) {
actor->set_level((uint8)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_magic(Actor *actor, lua_State *L) {
actor->set_magic((uint8)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_movement_pts(Actor *actor, lua_State *L) {
actor->set_moves_left((sint8)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_obj_flag_0(Actor *actor, lua_State *L) {
actor->set_obj_flag(0, (bool)lua_toboolean(L, 3));
return 0;
}
static int nscript_actor_set_obj_n(Actor *actor, lua_State *L) {
actor->set_obj_n((uint16)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_old_align(Actor *actor, lua_State *L) {
actor->set_old_alignment((ActorAlignment)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_base_obj_n(Actor *actor, lua_State *L) {
actor->change_base_obj_n((uint16)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_paralyzed_flag(Actor *actor, lua_State *L) {
actor->set_paralyzed((bool)lua_toboolean(L, 3));
return 0;
}
static int nscript_actor_set_poisoned_flag(Actor *actor, lua_State *L) {
actor->set_poisoned(lua_toboolean(L, 3));
return 0;
}
static int nscript_actor_set_protected_flag(Actor *actor, lua_State *L) {
actor->set_protected(lua_toboolean(L, 3));
return 0;
}
static int nscript_actor_set_strength(Actor *actor, lua_State *L) {
actor->set_strength((uint8)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_visible_flag(Actor *actor, lua_State *L) {
actor->set_invisible(!lua_toboolean(L, 3)); //negate value before passing back to actor.
return 0;
}
static int nscript_actor_set_worktype(Actor *actor, lua_State *L) {
actor->set_worktype((uint8)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_x(Actor *actor, lua_State *L) {
//actor->set_x((uint16)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_y(Actor *actor, lua_State *L) {
//actor->set_y((uint16)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_set_z(Actor *actor, lua_State *L) {
//actor->set_z((uint8)lua_tointeger(L, 3));
return 0;
}
static int nscript_actor_get(lua_State *L) {
Actor *actor;
const char *key;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
key = lua_tostring(L, 2);
int idx = str_bsearch(actor_get_vars, sizeof(actor_get_vars) / sizeof(actor_get_vars[0]), key);
if (idx == -1)
return 0;
return (*actor_get_func[idx])(actor, L);
}
static int nscript_actor_get_actor_num(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_actor_num());
return 1;
}
static int nscript_actor_get_align(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_alignment());
return 1;
}
static int nscript_actor_get_alive(Actor *actor, lua_State *L) {
lua_pushboolean(L, actor->is_alive());
return 1;
}
static int nscript_actor_get_asleep_flag(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->is_sleeping());
return 1;
}
static int nscript_actor_get_base_obj_n(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_base_obj_n());
return 1;
}
static int nscript_actor_get_cursed_flag(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->is_cursed());
return 1;
}
static int nscript_actor_get_combat_mode(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_combat_mode());
return 1;
}
static int nscript_actor_get_charmed_flag(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->is_charmed());
return 1;
}
static int nscript_actor_get_cold_flag(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->get_status_flag(ACTOR_MD_STATUS_FLAG_COLD));
return 1;
}
static int nscript_actor_get_corpser_flag(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->get_corpser_flag());
return 1;
}
static int nscript_actor_get_dexterity(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_dexterity());
return 1;
}
static int nscript_actor_get_direction(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_direction());
return 1;
}
static int nscript_actor_get_exp(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_exp());
return 1;
}
static int nscript_actor_get_frame_n(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_frame_n());
return 1;
}
static int nscript_actor_get_frenzy(Actor *actor, lua_State *L) {
lua_pushboolean(L, actor->get_obj_flag(ACTOR_MD_OBJ_FLAG_FRENZY));
return 1;
}
static int nscript_actor_get_hit_flag(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->is_hit());
return 1;
}
static int nscript_actor_get_hp(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_hp());
return 1;
}
static int nscript_actor_get_hypoxia(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->get_obj_flag(ACTOR_MD_OBJ_FLAG_HYPOXIA));
return 1;
}
static int nscript_actor_get_in_party_status(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->is_in_party());
return 1;
}
static int nscript_actor_get_in_vehicle(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->is_in_vehicle());
return 1;
}
static int nscript_actor_get_intelligence(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_intelligence());
return 1;
}
static int nscript_actor_get_level(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_level());
return 1;
}
static int nscript_actor_get_luatype(Actor *actor, lua_State *L) {
lua_pushstring(L, "actor");
return 1;
}
static int nscript_actor_get_magic(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_magic());
return 1;
}
static int nscript_actor_get_max_hp(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_maxhp());
return 1;
}
static int nscript_actor_get_movement_pts(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_moves_left());
return 1;
}
static int nscript_actor_get_name(Actor *actor, lua_State *L) {
lua_pushstring(L, actor->get_name());
return 1;
}
static int nscript_actor_get_obj_flag_0(Actor *actor, lua_State *L) {
lua_pushboolean(L, actor->get_obj_flag(0));
return 1;
}
static int nscript_actor_get_obj_n(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_obj_n());
return 1;
}
static int nscript_actor_get_old_frame_n(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_old_frame_n());
return 1;
}
static int nscript_actor_get_old_align(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_old_alignment());
return 1;
}
static int nscript_actor_get_paralyzed_flag(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->is_paralyzed());
return 1;
}
static int nscript_actor_get_poisoned_flag(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->is_poisoned());
return 1;
}
static int nscript_actor_get_protected_flag(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->is_protected());
return 1;
}
static int nscript_actor_get_sched_loc(Actor *actor, lua_State *L) {
MapCoord sched_loc;
if (actor->get_schedule_location(&sched_loc) == false)
return 0;
lua_newtable(L);
lua_pushstring(L, "x");
lua_pushinteger(L, sched_loc.x);
lua_settable(L, -3);
lua_pushstring(L, "y");
lua_pushinteger(L, sched_loc.y);
lua_settable(L, -3);
lua_pushstring(L, "z");
lua_pushinteger(L, sched_loc.z);
lua_settable(L, -3);
return 1;
}
static int nscript_actor_get_sched_worktype(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_sched_worktype());
return 1;
}
static int nscript_actor_get_strength(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_strength());
return 1;
}
static int nscript_actor_get_temp_status(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)actor->is_temp());
return 1;
}
static int nscript_actor_get_tile_num(Actor *actor, lua_State *L) {
Tile *tile = actor->get_tile();
lua_pushinteger(L, (int)tile->tile_num);
return 1;
}
static int nscript_actor_get_visible_flag(Actor *actor, lua_State *L) {
lua_pushboolean(L, (int)(actor->is_invisible() ? false : true));
return 1;
}
static int nscript_actor_get_worktype(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_worktype());
return 1;
}
static int nscript_actor_get_x(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_x());
return 1;
}
static int nscript_actor_get_xyz(Actor *actor, lua_State *L) {
lua_newtable(L);
lua_pushstring(L, "x");
lua_pushinteger(L, actor->get_x());
lua_settable(L, -3);
lua_pushstring(L, "y");
lua_pushinteger(L, actor->get_y());
lua_settable(L, -3);
lua_pushstring(L, "z");
lua_pushinteger(L, actor->get_z());
lua_settable(L, -3);
return 1;
}
static int nscript_actor_get_y(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_y());
return 1;
}
static int nscript_actor_get_z(Actor *actor, lua_State *L) {
lua_pushinteger(L, actor->get_z());
return 1;
}
/***
Call the C++ Actor::die() method
@function Actor.kill
@tparam Actor actor
@bool[opt=true] create_body Create a dead body on the map?
@within Actor
*/
static int nscript_actor_kill(lua_State *L) {
Actor *actor;
bool create_body = true;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
if (lua_gettop(L) >= 2)
create_body = (bool)lua_toboolean(L, 2);
actor->die(create_body);
return 0;
}
/***
Call the C++ Actor::hit() method
@function ultima/nuvie/actors/actor.hit
@tparam Actor actor
@int damage
@within Actor
*/
static int nscript_actor_hit(lua_State *L) {
Actor *actor;
uint8 damage;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
damage = (uint8)luaL_checkinteger(L, 2);
actor->hit(damage, true); //force hit
return 0;
}
/***
Calls the get_combat_range script function with the wrapped absolute x,y distances to the target
@function Actor.get_range
@tparam Actor actor
@int target_x
@int target_y
@treturn int range
@within Actor
*/
static int nscript_actor_get_range(lua_State *L) {
Actor *actor;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
uint16 target_x = (uint16) luaL_checkinteger(L, 2);
uint16 target_y = (uint16) luaL_checkinteger(L, 3);
lua_pushinteger(L, actor->get_range(target_x, target_y));
return 1;
}
/***
Move actor to location.
@function Actor.move
@tparam Actor actor
@tparam MapCoord|x,y,z location
@treturn bool Returns true is the move was successful. False if the move fails.
@within Actor
*/
static int nscript_actor_move(lua_State *L) {
Actor *actor;
uint16 x, y;
uint8 z;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
if (nscript_get_location_from_args(L, &x, &y, &z, 2) == false)
return 0;
lua_pushboolean(L, (int)actor->move(x, y, z));
return 1;
}
/***
Move the actor one space along their pathfinding path.
@function Actor.walk_path
@tparam Actor actor
@within Actor
*/
static int nscript_actor_walk_path(lua_State *L) {
Actor *actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
actor->update(); //FIXME this should be specific to pathfinding.
return 0;
}
/***
Checks to see if the actor is currently at their scheduled worktype location.
@function Actor.is_at_scheduled_location
@tparam Actor actor
@treturn bool
@within Actor
*/
static int nscript_actor_is_at_scheduled_location(lua_State *L) {
Actor *actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
lua_pushboolean(L, actor->is_at_scheduled_location());
return 1;
}
/***
Checks to see if the actor can carry an object.
It first checks that the object is get-able then checks that
the actor can physically carry the object's weight.
@function Actor.can_carry_obj
@tparam Actor actor
@tparam Obj object
@treturn bool
@within Actor
*/
static int nscript_actor_can_carry_obj(lua_State *L) {
Actor *actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
Obj *obj = nscript_get_obj_from_args(L, 2);
if (obj == nullptr)
return 0;
lua_pushboolean(L, (int)actor->can_carry_object(obj));
return 1;
}
/***
Checks to see if the actor can carry an object's weight.
@function Actor.can_carry_obj_weight
@tparam Actor actor
@tparam Obj object
@treturn bool
@within Actor
*/
static int nscript_actor_can_carry_obj_weight(lua_State *L) {
if (Game::get_game()->using_hackmove())
return 1;
Actor *actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
Obj *obj = nscript_get_obj_from_args(L, 2);
if (obj == nullptr)
return 0;
lua_pushboolean(L, (int)actor->can_carry_weight(obj));
return 1;
}
/***
Fade the black pixels in the actor's tile to a specified color.
@function Actor.black_fade_effect
@tparam Actor actor
@int fade_color
@int fade_speed
@within Actor
*/
static int nscript_actor_black_fade_effect(lua_State *L) {
Actor *actor = nscript_get_actor_from_args(L);
uint8 fade_color = (uint8)lua_tointeger(L, 2);
uint16 fade_speed = (uint8)lua_tointeger(L, 3);
if (actor != nullptr) {
AsyncEffect *e = new AsyncEffect(new TileBlackFadeEffect(actor, fade_color, fade_speed));
e->run();
}
return 0;
}
/***
Pixel fade out the actor's tile to nothing.
@function Actor.fade_out
@tparam Actor actor
@int fade_speed
@within Actor
*/
static int nscript_actor_fade_out_effect(lua_State *L) {
Actor *actor = nscript_get_actor_from_args(L);
uint16 fade_speed = (uint8)lua_tointeger(L, 2);
if (actor != nullptr) {
AsyncEffect *e = new AsyncEffect(new TileFadeEffect(actor, fade_speed));
e->run();
}
return 0;
}
/***
Display the actor's portrait
@function Actor.show_portrait
@tparam Actor actor
@within Actor
*/
static int nscript_actor_show_portrait(lua_State *L) {
Actor *actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
Game::get_game()->get_view_manager()->set_portrait_mode(actor, actor->get_name());
return 0;
}
/***
Hide the actor's portrait.
The party view is shown if in original UI mode.
@function ultima/nuvie/actors/actor.hide_portrait
@tparam Actor actor
@within Actor
*/
static int nscript_actor_hide_portrait(lua_State *L) {
if (Game::get_game()->is_new_style())
Game::get_game()->get_view_manager()->get_portrait_view()->Hide();
else
Game::get_game()->get_view_manager()->set_party_mode();
return 0;
}
/***
Talk to actor. The script will pause until the conversation has ended.
@function Actor.talk
@tparam Actor actor
@within Actor
*/
static int nscript_actor_talk(lua_State *L) {
Actor *actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
Game::get_game()->get_converse()->start(actor);
Game::get_game()->update_until_converse_finished();
return 0;
}
/***
For multi-tile actors, disconnect their surrounding objects.
@function Actor.unlink_surrounding_objs
@tparam Actor actor
@bool make_temp Should the objects be made temporary?
@within Actor
*/
static int nscript_actor_unlink_surrounding_objs(lua_State *L) {
Actor *actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
bool make_temp_obj = lua_toboolean(L, 2);
actor->unlink_surrounding_objects(make_temp_obj);
return 0;
}
/***
Call the C++ actor usecode logic.
@function Actor.use
@tparam Actor actor
@within Actor
*/
static int nscript_actor_use(lua_State *L) {
UseCode *usecode = Game::get_game()->get_usecode();
Actor *actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
Obj *my_obj = actor->make_obj();
usecode->use_obj(my_obj, actor);
delete_obj(my_obj);
return 0;
}
/***
Resurrect a dead actor. If the actor's body is not on the map then the actor will
be placed at a random map location around the player.
@function Actor.resurrect
@tparam Actor actor
@tparam MapCoord|x,y,z location Location to put the resurrected actor on the map
@tparam Obj body_obj The dead actor's body object.
@within Actor
*/
static int nscript_actor_resurrect(lua_State *L) {
Actor *actor;
MapCoord loc;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
if (nscript_get_location_from_args(L, &loc.x, &loc.y, &loc.z, 2) == false)
return 0;
Obj *obj = nscript_get_obj_from_args(L, 5);
bool toss = (obj->is_in_inventory() || obj->is_in_container());
if (toss)
loc = Game::get_game()->get_player()->get_actor()->get_location();
actor->resurrect(loc, obj);
if (toss) {
ActorManager *actor_manager = Game::get_game()->get_actor_manager();
if (!actor_manager->toss_actor(actor, 2, 2))
actor_manager->toss_actor(actor, 4, 4);
}
return 0;
}
/***
Add an object to the actor's inventory.
@function Actor.inv_add_obj
@tparam Actor actor
@tparam Obj obj
@bool[opt=false] stack_objs Should we stack obj.qty into existing objects?
@within Actor
*/
static int nscript_actor_inv_add_obj(lua_State *L) {
Actor *actor;
bool stack_objs = false;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
Obj **s_obj = (Obj **)luaL_checkudata(L, 2, "nuvie.Obj");
Obj *obj;
obj = *s_obj;
if (lua_gettop(L) >= 3) {
stack_objs = lua_toboolean(L, 3);
}
actor->inventory_add_object(obj, nullptr, stack_objs);
return 0;
}
/***
Remove an object from the actor's inventory
@function Actor.inv_remove_obj
@tparam Actor actor
@tparam Obj obj
@within Actor
*/
static int nscript_actor_inv_remove_obj(lua_State *L) {
Actor *actor;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
Obj **s_obj = (Obj **)luaL_checkudata(L, 2, "nuvie.Obj");
Obj *obj;
obj = *s_obj;
actor->inventory_remove_obj(obj);
return 0;
}
/***
Remove a number of stackable objects from the actor's inventory
@function Actor.inv_remove_obj_qty
@tparam Actor actor
@int obj_n Type of object to remove.
@int qty Number of objects to remove.
@treturn int returns the number of objects actually removed. This may be less than were requested.
@within Actor
*/
static int nscript_actor_inv_remove_obj_qty(lua_State *L) {
Actor *actor;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
uint16 obj_n = (uint16)lua_tointeger(L, 2);
uint16 qty = (uint16)lua_tointeger(L, 3);
lua_pushinteger(L, actor->inventory_del_object(obj_n, qty, 0));
return 1;
}
/***
Returns the obj_n the object that is readied at a given location.
@function Actor.inv_get_readied_obj_n
@tparam Actor actor
@int location
- 0 = HEAD
- 1 = NECK
- 2 = BODY
- 3 = ARM
- 4 = ARM_2
- 5 = HAND
- 6 = HAND_2
- 7 = FOOT
@treturn int returns obj_n or -1 if nothing is readied at the specified location.
@within Actor
*/
static int nscript_actor_inv_get_readied_obj_n(lua_State *L) {
Actor *actor = nscript_get_actor_from_args(L);
if (actor == nullptr) {
lua_pushinteger(L, -1);
return 1;
}
uint8 location = (uint8)lua_tointeger(L, 2);
lua_pushinteger(L, actor->inventory_get_readied_obj_n(location));
return 1;
}
/***
Ready an object from the actor's inventory.
@function Actor.inv_ready_obj
@tparam Actor actor
@tparam Obj obj
@within Actor
*/
static int nscript_actor_inv_ready_obj(lua_State *L) {
Actor *actor;
MapCoord loc;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
Obj **s_obj = (Obj **)luaL_checkudata(L, 2, "nuvie.Obj");
Obj *obj;
obj = *s_obj;
actor->add_readied_object(obj);
return 0;
}
/***
Unready an object from the actor.
First attempt to unready object using usecode. If there is no unready usecode then just unready the object normally.
@function Actor.inv_unready_obj
@tparam Actor actor
@tparam Obj obj
@within Actor
*/
static int nscript_actor_inv_unready_obj(lua_State *L) {
Actor *actor;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
Obj **s_obj = (Obj **)luaL_checkudata(L, 2, "nuvie.Obj");
Obj *obj;
obj = *s_obj;
UseCode *usecode = Game::get_game()->get_usecode();
//try to unready via usecode.
if (usecode->has_readycode(obj) && (usecode->ready_obj(obj, actor) == false)) {
return 0;
}
actor->remove_readied_object(obj);
return 0;
}
/***
Check if the actor has an object of type obj_n in their inventory.
@function Actor.inv_has_obj_n
@tparam Actor actor
@int obj_n object number to search for
@treturn bool
@within Actor
*/
static int nscript_actor_inv_has_obj_n(lua_State *L) {
Actor *actor;
uint16 obj_n;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
obj_n = (uint16)luaL_checkinteger(L, 2);
lua_pushboolean(L, (int)actor->inventory_has_object(obj_n, 0, false));
return 1;
}
/***
Get the first object of type obj_n from the actor's inventory.
@function Actor.inv_get_obj_n
@tparam Actor actor
@int obj_n object number to search for
@int[opt] frame_n search on frame number
@int[opt] quality search on object quality
@treturn Obj returns an object or nil if no match was found
@within Actor
*/
static int nscript_actor_inv_get_obj_n(lua_State *L) {
Actor *actor;
uint16 obj_n;
uint8 frame_n = 0;
uint8 quality = 0;
bool match_frame_n = false;
bool match_quality = false;
Obj *obj;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
obj_n = (uint16)luaL_checkinteger(L, 2);
if (lua_gettop(L) >= 3 && !lua_isnil(L, 3)) {
frame_n = (uint8)luaL_checkinteger(L, 3);
match_frame_n = true;
}
if (lua_gettop(L) >= 4 && !lua_isnil(L, 4)) {
quality = (uint8)luaL_checkinteger(L, 4);
match_quality = true;
}
obj = actor->inventory_get_object(obj_n, quality, match_quality, frame_n, match_frame_n);
if (obj) {
nscript_new_obj_var(L, obj);
return 1;
}
return 0;
}
/***
Get the total number of objects of type obj_n in the actor's inventory
@function Actor.inv_get_obj_total_qty
@tparam Actor actor
@int obj_n object number to search for
@treturn int
@within Actor
*/
static int nscript_actor_inv_get_obj_total_qty(lua_State *L) {
Actor *actor;
uint16 obj_n;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
obj_n = (uint16)luaL_checkinteger(L, 2);
lua_pushinteger(L, actor->inventory_count_object(obj_n));
return 1;
}
/***
Get the actor at map location.
@function map_get_actor
@tparam MapCoord|x,y,z location
@tparam[opt] Actor excluded_actor Actor to be excluded from search results
@treturn Actor returns the actor or nil if no actor was found
@within Actor
*/
static int nscript_map_get_actor(lua_State *L) {
ActorManager *actor_manager = Game::get_game()->get_actor_manager();
Actor *actor;
uint16 x, y;
uint8 z;
if (nscript_get_location_from_args(L, &x, &y, &z) == false)
return 0;
Actor *excluded_actor = nullptr;
void *p = lua_touserdata(L, 4); // avoid error warnings when null
if (p != nullptr)
excluded_actor = nscript_get_actor_from_args(L, 4);
actor = actor_manager->get_actor(x, y, z, true, excluded_actor);
if (actor == nullptr)
return 0;
if (nscript_new_actor_var(L, actor->get_actor_num()) == false)
return 0;
return 1;
}
/***
Update all actor schedules.
Schedules change on the hour.
@function update_actor_schedules
@bool[opt=false] teleport_actors Should actors teleport to their new scheduled location?
@within Actor
*/
static int nscript_update_actor_schedules(lua_State *L) {
bool teleport;
if (lua_gettop(L) >= 1)
teleport = (bool)lua_toboolean(L, 1);
else
teleport = false;
ActorManager *actor_manager = Game::get_game()->get_actor_manager();
actor_manager->updateSchedules(teleport);
return 0;
}
/***
Iterate through objects in the actor's inventory.
@function actor_inventory
@tparam Actor actor
@bool[opt=false] is_recursive should we search containers inside the inventory?
@usage
local ac = 0
local obj
for obj in actor_inventory(actor) do
if obj.readied then
local armour = armour_tbl[obj.obj_n]
if armour ~= nil then
ac = ac + armour
end
end
end
@within Actor
*/
static int nscript_actor_inv(lua_State *L) {
Actor *actor;
bool is_recursive = false;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
if (lua_gettop(L) >= 2)
is_recursive = lua_toboolean(L, 2);
U6LList *inv = actor->get_inventory_list();
return nscript_init_u6link_iter(L, inv, is_recursive);
}
/***
Set one of the actor's talk flags
@function Actor.set_talk_flag
@tparam Actor actor
@int flag The flag to set. 0..7
@within Actor
*/
static int nscript_actor_set_talk_flag(lua_State *L) {
Actor *actor;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
actor->set_flag((uint8)lua_tointeger(L, 2));
return 0;
}
/***
Get the value of one of the actor's talk flags
@function Actor.get_talk_flag
@tparam Actor actor
@int flag The flag to get. 0..7
@treturn bool returns the flag value
@within Actor
*/
static int nscript_actor_get_talk_flag(lua_State *L) {
Actor *actor;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
lua_pushboolean(L, actor->get_flag((uint8)lua_tointeger(L, 2)));
return 1;
}
/***
Clear one of the actor's talk flags
@function Actor.clear_talk_flag
@tparam Actor actor
@int flag The flag to clear. 0..7
@within Actor
*/
static int nscript_actor_clear_talk_flag(lua_State *L) {
Actor *actor;
actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
actor->clear_flag((uint8)lua_tointeger(L, 2));
return 0;
}
/***
Get the number of schedule entries
@function Actor.get_number_of_schedules
@tparam Actor actor
@treturn int
@within Actor
*/
static int nscript_actor_get_number_of_schedules(lua_State *L) {
Actor *actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
lua_pushinteger(L, actor->get_number_of_schedules());
return 1;
}
/***
Get an Actor schedule entry
@function Actor.get_schedule
@tparam Actor actor
@int index The index of the schedule to retrieve
@treturn Schedule
@within Actor
*/
static int nscript_actor_get_schedule(lua_State *L) {
Actor *actor = nscript_get_actor_from_args(L);
if (actor == nullptr)
return 0;
Schedule *schedule = actor->get_schedule((uint8)lua_tointeger(L, 2));
lua_newtable(L);
lua_pushstring(L, "day_of_week");
lua_pushinteger(L, schedule->day_of_week);
lua_settable(L, -3);
lua_pushstring(L, "worktype");
lua_pushinteger(L, schedule->worktype);
lua_settable(L, -3);
lua_pushstring(L, "x");
lua_pushinteger(L, schedule->x);
lua_settable(L, -3);
lua_pushstring(L, "y");
lua_pushinteger(L, schedule->y);
lua_settable(L, -3);
lua_pushstring(L, "z");
lua_pushinteger(L, schedule->z);
lua_settable(L, -3);
return 1;
}
} // End of namespace Nuvie
} // End of namespace Ultima