示例#1
0
// Hook for linedef executors
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
{
	hook_p hookp;
	boolean hooked = false;
	if (!gL || !(hooksAvailable[hook_LinedefExecute/8] & (1<<(hook_LinedefExecute%8))))
		return 0;

	lua_settop(gL, 0);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_LinedefExecute
		&& !strcmp(hookp->s.funcname, line->text))
		{
			if (lua_gettop(gL) == 0)
			{
				LUA_PushUserdata(gL, line, META_LINE);
				LUA_PushUserdata(gL, mo, META_MOBJ);
				LUA_PushUserdata(gL, sector, META_SECTOR);
			}
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -4);
			lua_pushvalue(gL, -4);
			lua_pushvalue(gL, -4);
			LUA_Call(gL, 3);
			hooked = true;
		}

	lua_settop(gL, 0);
	return hooked;
}
示例#2
0
static int lib_iterateThinkers(lua_State *L)
{
	int state = luaL_checkoption(L, 1, "mobj", iter_opt);

	thinker_t *th = NULL;
	actionf_p1 searchFunc;
	const char *searchMeta;

	lua_settop(L, 2);
	lua_remove(L, 1); // remove state now.

	switch(state)
	{
		case 0:
			searchFunc = NULL;
			searchMeta = NULL;
			break;
		case 1:
		default:
			searchFunc = (actionf_p1)P_MobjThinker;
			searchMeta = META_MOBJ;
			break;
	}

	if (!lua_isnil(L, 1)) {
		if (lua_islightuserdata(L, 1))
			th = (thinker_t *)lua_touserdata(L, 1);
		else if (searchMeta)
			th = *((thinker_t **)luaL_checkudata(L, 1, searchMeta));
		else
			th = *((thinker_t **)lua_touserdata(L, 1));
	} else
		th = &thinkercap;

	if (!th) // something got our userdata invalidated!
		return 0;

	if (searchFunc == NULL)
	{
		if ((th = th->next) != &thinkercap)
		{
			if (th->function.acp1 == (actionf_p1)P_MobjThinker)
				LUA_PushUserdata(L, th, META_MOBJ);
			else
				lua_pushlightuserdata(L, th);
			return 1;
		}
		return 0;
	}

	for (th = th->next; th != &thinkercap; th = th->next)
	{
		if (th->function.acp1 != searchFunc)
			continue;

		LUA_PushUserdata(L, th, searchMeta);
		return 1;
	}
	return 0;
}
示例#3
0
// Hook for B_BuildTailsTiccmd by skin name
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
{
	hook_p hookp;
	boolean hooked = false;
	if (!gL || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8))))
		return false;

	lua_settop(gL, 0);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_BotAI
		&& (hookp->s.skinname == NULL || !strcmp(hookp->s.skinname, ((skin_t*)tails->skin)->name)))
		{
			if (lua_gettop(gL) == 0)
			{
				LUA_PushUserdata(gL, sonic, META_MOBJ);
				LUA_PushUserdata(gL, tails, META_MOBJ);
			}
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -3);
			lua_pushvalue(gL, -3);
			if (lua_pcall(gL, 2, 8, 0)) {
				if (!hookp->error || cv_debug & DBG_LUA)
					CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
				lua_pop(gL, 1);
				hookp->error = true;
				continue;
			}

			// This turns forward, backward, left, right, jump, and spin into a proper ticcmd for tails.
			if (lua_istable(gL, 2+1)) {
				boolean forward=false, backward=false, left=false, right=false, strafeleft=false, straferight=false, jump=false, spin=false;
#define CHECKFIELD(field) \
				lua_getfield(gL, 2+1, #field);\
				if (lua_toboolean(gL, -1))\
					field = true;\
				lua_pop(gL, 1);

				CHECKFIELD(forward)
				CHECKFIELD(backward)
				CHECKFIELD(left)
				CHECKFIELD(right)
				CHECKFIELD(strafeleft)
				CHECKFIELD(straferight)
				CHECKFIELD(jump)
				CHECKFIELD(spin)
#undef CHECKFIELD
				B_KeysToTiccmd(tails, cmd, forward, backward, left, right, strafeleft, straferight, jump, spin);
			} else
				B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, 2+1), lua_toboolean(gL, 2+2), lua_toboolean(gL, 2+3), lua_toboolean(gL, 2+4), lua_toboolean(gL, 2+5), lua_toboolean(gL, 2+6), lua_toboolean(gL, 2+7), lua_toboolean(gL, 2+8));

			lua_pop(gL, 8);
			hooked = true;
		}

	lua_settop(gL, 0);
	return hooked;
}
示例#4
0
// Hook for player chat
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg)
{
	hook_p hookp;
	boolean hooked = false;
	if (!gL || !(hooksAvailable[hook_PlayerMsg/8] & (1<<(hook_PlayerMsg%8))))
		return false;

	lua_settop(gL, 0);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_PlayerMsg)
		{
			if (lua_gettop(gL) == 0)
			{
				LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player
				if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c
					lua_pushinteger(gL, 3); // type
					lua_pushnil(gL); // target
				} else if (target == -1) { // sayteam
					lua_pushinteger(gL, 1); // type
					lua_pushnil(gL); // target
				} else if (target == 0) { // say
					lua_pushinteger(gL, 0); // type
					lua_pushnil(gL); // target
				} else { // sayto
					lua_pushinteger(gL, 2); // type
					LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target
				}
				lua_pushstring(gL, msg); // msg
			}
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -5);
			lua_pushvalue(gL, -5);
			lua_pushvalue(gL, -5);
			lua_pushvalue(gL, -5);
			if (lua_pcall(gL, 4, 1, 0)) {
				if (!hookp->error || cv_debug & DBG_LUA)
					CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
				lua_pop(gL, 1);
				hookp->error = true;
				continue;
			}
			if (lua_toboolean(gL, -1))
				hooked = true;
			lua_pop(gL, 1);
		}

	lua_settop(gL, 0);
	return hooked;
}
示例#5
0
// iterates through the ffloors list in a sector!
static int lib_iterateSectorFFloors(lua_State *L)
{
	ffloor_t *state = NULL;
	ffloor_t *ffloor = NULL;

	if (lua_gettop(L) < 2)
		return luaL_error(L, "Don't call sector.ffloors() directly, use it as 'for rover in sector.ffloors do <block> end'.");

	if (!lua_isnil(L, 1))
		state = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
	else
		return 0; // no ffloors to iterate through sorry!

	lua_settop(L, 2);
	lua_remove(L, 1); // remove state now.

	if (!lua_isnil(L, 1))
	{
		ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
		ffloor = ffloor->next;
	}
	else
		ffloor = state; // state is used as the "start" of the ffloor list

	if (ffloor)
	{
		LUA_PushUserdata(L, ffloor, META_FFLOOR);
		return 1;
	}
	return 0;
}
示例#6
0
// iterates through a sector's thinglist!
static int lib_iterateSectorThinglist(lua_State *L)
{
	mobj_t *state = NULL;
	mobj_t *thing = NULL;

	if (lua_gettop(L) < 2)
		return luaL_error(L, "Don't call sector.thinglist() directly, use it as 'for rover in sector.thinglist do <block> end'.");

	if (!lua_isnil(L, 1))
		state = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
	else
		return 0; // no thinglist to iterate through sorry!

	lua_settop(L, 2);
	lua_remove(L, 1); // remove state now.

	if (!lua_isnil(L, 1))
	{
		thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
		thing = thing->snext;
	}
	else
		thing = state; // state is used as the "start" of the thinglist

	if (thing)
	{
		LUA_PushUserdata(L, thing, META_MOBJ);
		return 1;
	}
	return 0;
}
示例#7
0
static int lib_getMapheaderinfo(lua_State *L)
{
	// i -> mapheaderinfo[i-1]

	//int field;
	lua_settop(L, 2);
	lua_remove(L, 1); // dummy userdata table is unused.
	if (lua_isnumber(L, 1))
	{
		size_t i = lua_tointeger(L, 1)-1;
		if (i >= NUMMAPS)
			return 0;
		LUA_PushUserdata(L, mapheaderinfo[i], META_MAPHEADER);
		//CONS_Printf(mapheaderinfo[i]->lvlttl);
		return 1;
	}/*
	field = luaL_checkoption(L, 1, NULL, array_opt);
	switch(field)
	{
	case 0: // iterate
		lua_pushcfunction(L, lib_iterateSubsectors);
		return 1;
	}*/
	return 0;
}
示例#8
0
static int libd_getColormap(lua_State *L)
{
	INT32 skinnum = TC_DEFAULT;
	skincolors_t color = luaL_optinteger(L, 2, 0);
	UINT8* colormap = NULL;
	HUDONLY
	if (lua_isnoneornil(L, 1))
		; // defaults to TC_DEFAULT
	else if (lua_type(L, 1) == LUA_TNUMBER) // skin number
	{
		skinnum = (INT32)luaL_checkinteger(L, 1);
		if (skinnum < TC_ALLWHITE || skinnum >= MAXSKINS)
			return luaL_error(L, "skin number %d is out of range (%d - %d)", skinnum, TC_ALLWHITE, MAXSKINS-1);
	}
	else // skin name
	{
		const char *skinname = luaL_checkstring(L, 1);
		INT32 i = R_SkinAvailable(skinname);
		if (i != -1) // if -1, just default to TC_DEFAULT as above
			skinnum = i;
	}

	// all was successful above, now we generate the colormap at last!

	colormap = R_GetTranslationColormap(skinnum, color, GTC_CACHE);
	LUA_PushUserdata(L, colormap, META_COLORMAP); // push as META_COLORMAP userdata, specifically for patches to use!
	return 1;
}
示例#9
0
static int lib_getPlayer(lua_State *L)
{
	const char *field;
	// i -> players[i]
	if (lua_type(L, 2) == LUA_TNUMBER)
	{
		lua_Integer i = luaL_checkinteger(L, 2);
		if (i < 0 || i >= MAXPLAYERS)
			return luaL_error(L, "players[] index %d out of range (0 - %d)", i, MAXPLAYERS-1);
		if (!playeringame[i])
			return 0;
		if (!players[i].mo)
			return 0;
		LUA_PushUserdata(L, &players[i], META_PLAYER);
		return 1;
	}

	field = luaL_checkstring(L, 2);
	if (fastcmp(field,"iterate"))
	{
		lua_pushcfunction(L, lib_iteratePlayers);
		return 1;
	}
	return 0;
}
示例#10
0
// Hook for HUD rendering
void LUAh_GameHUD(player_t *stplyr)
{
	if (!gL || !(hudAvailable & (1<<hudhook_game)))
		return;

	hud_running = true;
	lua_pop(gL, -1);

	lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
	I_Assert(lua_istable(gL, -1));
	lua_rawgeti(gL, -1, 2); // HUD[2] = rendering funcs
	I_Assert(lua_istable(gL, -1));

	lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
	I_Assert(lua_istable(gL, -1));
	lua_remove(gL, -3); // pop HUD
	LUA_PushUserdata(gL, stplyr, META_PLAYER);

	lua_pushnil(gL);
	while (lua_next(gL, -4) != 0) {
		lua_pushvalue(gL, -4); // graphics library (HUD[1])
		lua_pushvalue(gL, -4); // stplyr
		LUA_Call(gL, 2);
	}
	lua_pop(gL, -1);
	lua_gc(gL, LUA_GCCOLLECT, 0);

	hud_running = false;
}
示例#11
0
boolean LUAh_PlayerHook(player_t *plr, enum hook which)
{
	hook_p hookp;
	boolean hooked = false;
	if (!gL || !(hooksAvailable[which/8] & (1<<(which%8))))
		return false;

	lua_settop(gL, 0);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == which)
		{
			if (lua_gettop(gL) == 0)
				LUA_PushUserdata(gL, plr, META_PLAYER);
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -2);
			if (lua_pcall(gL, 1, 1, 0)) {
				if (!hookp->error || cv_debug & DBG_LUA)
					CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
				lua_pop(gL, 1);
				hookp->error = true;
				continue;
			}
			if (lua_toboolean(gL, -1))
				hooked = true;
			lua_pop(gL, 1);
		}

	lua_settop(gL, 0);
	return hooked;
}
示例#12
0
static int subsector_get(lua_State *L)
{
	subsector_t *subsector = *((subsector_t **)luaL_checkudata(L, 1, META_SUBSECTOR));
	enum subsector_e field = luaL_checkoption(L, 2, subsector_opt[0], subsector_opt);

	if (!subsector)
	{
		if (field == subsector_valid) {
			lua_pushboolean(L, 0);
			return 1;
		}
		return luaL_error(L, "accessed subsector_t doesn't exist anymore.");
	}

	switch(field)
	{
	case subsector_valid: // valid
		lua_pushboolean(L, 1);
		return 1;
	case subsector_sector:
		LUA_PushUserdata(L, subsector->sector, META_SECTOR);
		return 1;
	case subsector_numlines:
		lua_pushinteger(L, subsector->numlines);
		return 1;
	case subsector_firstline:
		lua_pushinteger(L, subsector->firstline);
		return 1;
	case subsector_validcount:
		lua_pushinteger(L, subsector->validcount);
		return 1;
	}
	return 0;
}
示例#13
0
// Hook for P_DamageMobj by mobj type (Should mobj take damage?)
UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
{
	hook_p hookp;
	UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no.
	if (!gL || !(hooksAvailable[hook_ShouldDamage/8] & (1<<(hook_ShouldDamage%8))))
		return 0;

	lua_settop(gL, 0);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_ShouldDamage
		&& (hookp->s.mt == MT_NULL || hookp->s.mt == target->type))
		{
			if (lua_gettop(gL) == 0)
			{
				LUA_PushUserdata(gL, target, META_MOBJ);
				LUA_PushUserdata(gL, inflictor, META_MOBJ);
				LUA_PushUserdata(gL, source, META_MOBJ);
				lua_pushinteger(gL, damage);
			}
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -5);
			lua_pushvalue(gL, -5);
			lua_pushvalue(gL, -5);
			lua_pushvalue(gL, -5);
			if (lua_pcall(gL, 4, 1, 0)) {
				if (!hookp->error || cv_debug & DBG_LUA)
					CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
				lua_pop(gL, 1);
				hookp->error = true;
				continue;
			}
			if (!lua_isnil(gL, -1))
			{
				if (lua_toboolean(gL, -1))
					shouldDamage = 1; // Force yes
				else
					shouldDamage = 2; // Force no
			}
			lua_pop(gL, 1);
		}

	lua_settop(gL, 0);
	return shouldDamage;
}
示例#14
0
static int libd_cachePatch(lua_State *L)
{
	if (!hud_running)
		return luaL_error(L, "HUD rendering code should not be called outside of rendering hooks!");

	LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_STATIC), META_PATCH);
	return 1;
}
示例#15
0
// Arbitrary S_sfx[] table index -> sfxinfo_t *
static int lib_getSfxInfo(lua_State *L)
{
	UINT32 i;
	lua_remove(L, 1);

	i = luaL_checkinteger(L, 1);
	LUA_PushUserdata(L, &S_sfx[i], META_SFXINFO);
	return 1;
}
示例#16
0
// Arbitrary mobjinfo[] table index -> mobjinfo_t *
static int lib_getMobjInfo(lua_State *L)
{
	UINT32 i;
	lua_remove(L, 1);

	i = luaL_checkinteger(L, 1);
	LUA_PushUserdata(L, &mobjinfo[i], META_MOBJINFO);
	return 1;
}
示例#17
0
// Arbitrary states[] table index -> state_t *
static int lib_getState(lua_State *L)
{
	UINT32 i;
	lua_remove(L, 1);

	i = luaL_checkinteger(L, 1);
	LUA_PushUserdata(L, &states[i], META_STATE);
	return 1;
}
示例#18
0
static int camera_get(lua_State *L)
{
	camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA));
	enum cameraf field = luaL_checkoption(L, 2, NULL, camera_opt);

	// cameras should always be valid unless I'm a nutter
	I_Assert(cam != NULL);

	switch (field)
	{
	case camera_chase:
		lua_pushboolean(L, cam->chase);
		break;
	case camera_aiming:
		lua_pushinteger(L, cam->aiming);
		break;
	case camera_x:
		lua_pushinteger(L, cam->x);
		break;
	case camera_y:
		lua_pushinteger(L, cam->y);
		break;
	case camera_z:
		lua_pushinteger(L, cam->z);
		break;
	case camera_angle:
		lua_pushinteger(L, cam->angle);
		break;
	case camera_subsector:
		LUA_PushUserdata(L, cam->subsector, META_SUBSECTOR);
		break;
	case camera_floorz:
		lua_pushinteger(L, cam->floorz);
		break;
	case camera_ceilingz:
		lua_pushinteger(L, cam->ceilingz);
		break;
	case camera_radius:
		lua_pushinteger(L, cam->radius);
		break;
	case camera_height:
		lua_pushinteger(L, cam->height);
		break;
	case camera_momx:
		lua_pushinteger(L, cam->momx);
		break;
	case camera_momy:
		lua_pushinteger(L, cam->momy);
		break;
	case camera_momz:
		lua_pushinteger(L, cam->momz);
		break;
	}
	return 1;
}
示例#19
0
// Hook for mobj collisions
UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which)
{
	hook_p hookp;
	UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no.
	if (!gL || !(hooksAvailable[which/8] & (1<<(which%8))))
		return 0;

	lua_settop(gL, 0);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == which
		&& (hookp->s.mt == MT_NULL || hookp->s.mt == thing1->type))
		{
			if (lua_gettop(gL) == 0)
			{
				LUA_PushUserdata(gL, thing1, META_MOBJ);
				LUA_PushUserdata(gL, thing2, META_MOBJ);
			}
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -3);
			lua_pushvalue(gL, -3);
			if (lua_pcall(gL, 2, 1, 0)) {
				if (!hookp->error || cv_debug & DBG_LUA)
					CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
				lua_pop(gL, 1);
				hookp->error = true;
				continue;
			}
			if (!lua_isnil(gL, -1))
			{ // if nil, leave shouldCollide = 0.
				if (lua_toboolean(gL, -1))
					shouldCollide = 1; // Force yes
				else
					shouldCollide = 2; // Force no
			}
			lua_pop(gL, 1);
		}

	lua_settop(gL, 0);
	return shouldCollide;
}
示例#20
0
static int lib_getHudInfo(lua_State *L)
{
	UINT32 i;
	lua_remove(L, 1);

	i = luaL_checkinteger(L, 1);
	if (i >= NUMHUDITEMS)
		return luaL_error(L, "hudinfo[] index %d out of range (0 - %d)", i, NUMHUDITEMS-1);
	LUA_PushUserdata(L, &hudinfo[i], META_HUDINFO);
	return 1;
}
示例#21
0
// Hook for P_DamageMobj by mobj type (Mobj actually takes damage!)
boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
{
	hook_p hookp;
	boolean hooked = false;
	if (!gL || !(hooksAvailable[hook_MobjDamage/8] & (1<<(hook_MobjDamage%8))))
		return 0;

	lua_settop(gL, 0);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_MobjDamage
		&& (hookp->s.mt == MT_NULL || hookp->s.mt == target->type))
		{
			if (lua_gettop(gL) == 0)
			{
				LUA_PushUserdata(gL, target, META_MOBJ);
				LUA_PushUserdata(gL, inflictor, META_MOBJ);
				LUA_PushUserdata(gL, source, META_MOBJ);
				lua_pushinteger(gL, damage);
			}
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -5);
			lua_pushvalue(gL, -5);
			lua_pushvalue(gL, -5);
			lua_pushvalue(gL, -5);
			if (lua_pcall(gL, 4, 1, 0)) {
				if (!hookp->error || cv_debug & DBG_LUA)
					CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
				lua_pop(gL, 1);
				hookp->error = true;
				continue;
			}
			if (lua_toboolean(gL, -1))
				hooked = true;
			lua_pop(gL, 1);
		}

	lua_settop(gL, 0);
	return hooked;
}
示例#22
0
// Helper function for "objects" search
static UINT8 lib_searchBlockmap_Objects(lua_State *L, INT32 x, INT32 y, mobj_t *thing)
{
	mobj_t *mobj, *bnext = NULL;

	if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
		return 0;

	// Check interaction with the objects in the blockmap.
	for (mobj = blocklinks[y*bmapwidth + x]; mobj; mobj = bnext)
	{
		P_SetTarget(&bnext, mobj->bnext); // We want to note our reference to bnext here incase it is MF_NOTHINK and gets removed!
		if (mobj == thing)
			continue; // our thing just found itself, so move on
		lua_pushvalue(L, 1); // push function
		LUA_PushUserdata(L, thing, META_MOBJ);
		LUA_PushUserdata(L, mobj, META_MOBJ);
		if (lua_pcall(gL, 2, 1, 0)) {
			if (!blockfuncerror || cv_debug & DBG_LUA)
				CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
			lua_pop(gL, 1);
			blockfuncerror = true;
			return 0; // *shrugs*
		}
		if (!lua_isnil(gL, -1))
		{ // if nil, continue
			if (lua_toboolean(gL, -1))
				return 2; // stop whole search
			else
				return 1; // stop block search
		}
		lua_pop(gL, 1);
		if (P_MobjWasRemoved(thing) // func just popped our thing, cannot continue.
		|| (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue.
		{
			P_SetTarget(&bnext, NULL);
			return (P_MobjWasRemoved(thing)) ? 2 : 1;
		}
	}
	return 0;
}
示例#23
0
// Hook for hurt messages
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source)
{
	hook_p hookp;
	boolean hooked = false;
	if (!gL || !(hooksAvailable[hook_HurtMsg/8] & (1<<(hook_HurtMsg%8))))
		return false;

	lua_settop(gL, 0);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_HurtMsg
		&& (hookp->s.mt == MT_NULL || (inflictor && hookp->s.mt == inflictor->type)))
		{
			if (lua_gettop(gL) == 0)
			{
				LUA_PushUserdata(gL, player, META_PLAYER);
				LUA_PushUserdata(gL, inflictor, META_MOBJ);
				LUA_PushUserdata(gL, source, META_MOBJ);
			}
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -4);
			lua_pushvalue(gL, -4);
			lua_pushvalue(gL, -4);
			if (lua_pcall(gL, 3, 1, 0)) {
				if (!hookp->error || cv_debug & DBG_LUA)
					CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
				lua_pop(gL, 1);
				hookp->error = true;
				continue;
			}
			if (lua_toboolean(gL, -1))
				hooked = true;
			lua_pop(gL, 1);
		}

	lua_settop(gL, 0);
	return hooked;
}
示例#24
0
static int lib_iterateMapthings(lua_State *L)
{
	size_t i = 0;
	lua_remove(L, 1); // state is unused.
	if (!lua_isnil(L, 1))
		i = (size_t)(*((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING)) - mapthings) + 1;
	if (i < nummapthings)
	{
		LUA_PushUserdata(L, &mapthings[i], META_MAPTHING);
		return 1;
	}
	return 0;
}
示例#25
0
// Hook for P_TouchSpecialThing by mobj type
boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher)
{
	hook_p hookp;
	boolean hooked = false;
	if (!gL || !(hooksAvailable[hook_TouchSpecial/8] & (1<<(hook_TouchSpecial%8))))
		return 0;

	lua_settop(gL, 0);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_TouchSpecial
		&& (hookp->s.mt == MT_NULL || hookp->s.mt == special->type))
		{
			if (lua_gettop(gL) == 0)
			{
				LUA_PushUserdata(gL, special, META_MOBJ);
				LUA_PushUserdata(gL, toucher, META_MOBJ);
			}
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -3);
			lua_pushvalue(gL, -3);
			if (lua_pcall(gL, 2, 1, 0)) {
				if (!hookp->error || cv_debug & DBG_LUA)
					CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
				lua_pop(gL, 1);
				hookp->error = true;
				continue;
			}
			if (lua_toboolean(gL, -1))
				hooked = true;
			lua_pop(gL, 1);
		}

	lua_settop(gL, 0);
	return hooked;
}
示例#26
0
boolean LUA_CallAction(const char *csaction, mobj_t *actor)
{
	I_Assert(csaction != NULL);
	I_Assert(actor != NULL);

	if (!gL) // Lua isn't loaded,
		return false; // action not called.

	if (superstack && fasticmp(csaction, superactions[superstack-1])) // the action is calling itself,
		return false; // let it call the hardcoded function instead.

	// grab function by uppercase name.
	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS);
	{
		char *action = Z_StrDup(csaction);
		strupr(action);
		lua_getfield(gL, -1, action);
		Z_Free(action);
	}
	lua_remove(gL, -2); // pop LREG_ACTIONS

	if (lua_isnil(gL, -1)) // no match
	{
		lua_pop(gL, 1); // pop nil
		return false; // action not called.
	}

	if (superstack == MAXRECURSION)
	{
		CONS_Alert(CONS_WARNING, "Max Lua Action recursion reached! Cool it on the calling A_Action functions from inside A_Action functions!\n");
		return true;
	}

	// Found a function.
	// Call it with (actor, var1, var2)
	I_Assert(lua_isfunction(gL, -1));
	LUA_PushUserdata(gL, actor, META_MOBJ);
	lua_pushinteger(gL, var1);
	lua_pushinteger(gL, var2);

	superactions[superstack] = csaction;
	++superstack;

	LUA_Call(gL, 3);

	--superstack;
	superactions[superstack] = NULL;
	return true; // action successfully called.
}
示例#27
0
static int side_get(lua_State *L)
{
	side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE));
	enum side_e field = luaL_checkoption(L, 2, side_opt[0], side_opt);

	if (!side)
	{
		if (field == side_valid) {
			lua_pushboolean(L, 0);
			return 1;
		}
		return luaL_error(L, "accessed side_t doesn't exist anymore.");
	}

	switch(field)
	{
	case side_valid: // valid
		lua_pushboolean(L, 1);
		return 1;
	case side_textureoffset:
		lua_pushinteger(L, side->textureoffset);
		return 1;
	case side_rowoffset:
		lua_pushinteger(L, side->rowoffset);
		return 1;
	case side_toptexture:
		lua_pushinteger(L, side->toptexture);
		return 1;
	case side_bottomtexture:
		lua_pushinteger(L, side->bottomtexture);
		return 1;
	case side_midtexture:
		lua_pushinteger(L, side->midtexture);
		return 1;
	case side_sector:
		LUA_PushUserdata(L, side->sector, META_SECTOR);
		return 1;
	case side_special:
		lua_pushinteger(L, side->special);
		return 1;
	case side_repeatcnt:
		lua_pushinteger(L, side->repeatcnt);
		return 1;
	case side_text:
		lua_pushstring(L, side->text);
		return 1;
	}
	return 0;
}
示例#28
0
// Hook for B_BuildTiccmd
boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd)
{
	hook_p hookp;
	boolean hooked = false;
	if (!gL || !(hooksAvailable[hook_BotTiccmd/8] & (1<<(hook_BotTiccmd%8))))
		return false;

	lua_settop(gL, 0);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_BotTiccmd)
		{
			if (lua_gettop(gL) == 0)
			{
				LUA_PushUserdata(gL, bot, META_PLAYER);
				LUA_PushUserdata(gL, cmd, META_TICCMD);
			}
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -3);
			lua_pushvalue(gL, -3);
			if (lua_pcall(gL, 2, 1, 0)) {
				if (!hookp->error || cv_debug & DBG_LUA)
					CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
				lua_pop(gL, 1);
				hookp->error = true;
				continue;
			}
			if (lua_toboolean(gL, -1))
				hooked = true;
			lua_pop(gL, 1);
		}

	lua_settop(gL, 0);
	return hooked;
}
示例#29
0
static int lib_iterateMapthings(lua_State *L)
{
	size_t i = 0;
	if (lua_gettop(L) < 2)
		return luaL_error(L, "Don't call mapthings.iterate() directly, use it as 'for mapthing in mapthings.iterate do <block> end'.");
	lua_settop(L, 2);
	lua_remove(L, 1); // state is unused.
	if (!lua_isnil(L, 1))
		i = (size_t)(*((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING)) - mapthings) + 1;
	if (i < nummapthings)
	{
		LUA_PushUserdata(L, &mapthings[i], META_MAPTHING);
		return 1;
	}
	return 0;
}
示例#30
0
static int lib_iterateVertexes(lua_State *L)
{
	size_t i = 0;
	if (lua_gettop(L) < 2)
		return luaL_error(L, "Don't call vertexes.iterate() directly, use it as 'for vertex in vertexes.iterate do <block> end'.");
	lua_settop(L, 2);
	lua_remove(L, 1); // state is unused.
	if (!lua_isnil(L, 1))
		i = (size_t)(*((vertex_t **)luaL_checkudata(L, 1, META_VERTEX)) - vertexes)+1;
	if (i < numvertexes)
	{
		LUA_PushUserdata(L, &vertexes[i], META_VERTEX);
		return 1;
	}
	return 0;
}