Exemple #1
0
int32_t NpcScriptInterface::luaActionSay(lua_State* L)
{
	//selfSay(words [[, target], publicize])
	// publicize defaults to true if there is no target, false otherwise
	uint32_t parameters = lua_gettop(L);
	uint32_t target = 0;
	bool publicize;
	if (parameters >= 3) {
		publicize = popBoolean(L);
	} else {
		publicize = true;
	}

	if (parameters >= 2) {
		target = popNumber(L);
		if (target != 0) {
			publicize = false;
		}
	}

	std::string text = popString(L);

	Npc* npc = getScriptEnv()->getNpc();
	if (npc) {
		if (publicize) {
			npc->doSay(text);
		} else {
			npc->doSayToPlayer(g_game.getPlayerByID(target), text);
		}
	}

	return 0;
}
Exemple #2
0
int32_t NpcScriptInterface::luaDoSellItem(lua_State* L)
{
	//doSellItem(cid, itemid, amount, <optional> subtype, <optional> actionid, <optional: default: 1> canDropOnMap)
	int32_t parameters = lua_gettop(L);

	bool canDropOnMap;
	if (parameters > 5) {
		canDropOnMap = popBoolean(L);
	} else {
		canDropOnMap = true;
	}

	uint32_t actionId = 0;
	if (parameters > 4) {
		actionId = popNumber(L);
	}

	uint32_t subType = 1;
	if (parameters > 3) {
		int32_t n = popNumber(L);
		if (n != -1) {
			subType = n;
		}
	}

	uint32_t amount = popNumber(L);
	uint32_t itemId = popNumber(L);

	Player* player = g_game.getPlayerByID(popNumber(L));
	if (!player) {
		reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
		pushBoolean(L, false);
		return 1;
	}

	uint32_t sellCount = 0;

	const ItemType& it = Item::items[itemId];
	if (it.stackable) {
		while (amount > 0) {
			int32_t stackCount = std::min<int32_t>(100, amount);
			Item* item = Item::CreateItem(it.id, stackCount);
			if (item && actionId != 0) {
				item->setActionId(actionId);
			}

			if (g_game.internalPlayerAddItem(player, item, canDropOnMap) != RET_NOERROR) {
				delete item;
				lua_pushnumber(L, sellCount);
				return 1;
			}

			amount = amount - stackCount;
			sellCount += stackCount;
		}
	} else {
		for (uint32_t i = 0; i < amount; ++i) {
			Item* item = Item::CreateItem(it.id, subType);
			if (item && actionId != 0) {
				item->setActionId(actionId);
			}

			if (g_game.internalPlayerAddItem(player, item, canDropOnMap) != RET_NOERROR) {
				delete item;
				lua_pushnumber(L, sellCount);
				return 1;
			}

			++sellCount;
		}
	}

	lua_pushnumber(L, sellCount);
	return 1;
}
Exemple #3
0
int LuaInterface::signalCall(int numArgs, int numRets)
{
    int rets = 0;
    int funcIndex = -numArgs-1;

    try {
        // must be a function
        if(isFunction(funcIndex)) {
            rets = safeCall(numArgs);

            if(numRets != -1) {
                if(rets != numRets)
                    throw LuaException("function call didn't return the expected number of results", 0);
            }
        }
        // can also calls table of functions
        else if(isTable(funcIndex)) {
            // loop through table values
            pushNil();
            bool done = false;
            while(next(funcIndex-1)) {
                if(isFunction()) {
                    // repush arguments
                    for(int i=0;i<numArgs;++i)
                        pushValue(-numArgs-2);

                    int rets = safeCall(numArgs);
                    if(rets == 1) {
                        done = popBoolean();
                        if(done) {
                            pop();
                            break;
                        }
                    } else if(rets != 0)
                        throw LuaException("function call didn't return the expected number of results", 0);
                } else {
                    throw LuaException("attempt to call a non function", 0);
                }
            }
            pop(numArgs + 1); // pops the table of function and arguments

            if(numRets == 1 || numRets == -1) {
                rets = 1;
                pushBoolean(done);
            }
        }
        // nil values are ignored
        else if(isNil(funcIndex)) {
            pop(numArgs + 1); // pops the function and arguments
        }
        // if not nil, warn
        else {
            throw LuaException("attempt to call a non function value", 0);
        }
    } catch(stdext::exception& e) {
        g_logger.error(stdext::format("protected lua call failed: %s", e.what()));
    }

    // pushes nil values if needed
    while(numRets != -1 && rets < numRets) {
        pushNil();
        rets++;
    }

    // returns the number of results on the stack
    return rets;
}
Exemple #4
0
int32_t MoveEventScript::luaCallFunction(lua_State* L)
{
	//callFunction(...)
	MoveEvent* event = MoveEventScript::event;
	if(!event)
	{
		error(__FUNCTION__, "MoveEvent not set!");
		lua_pushboolean(L, false);
		return 1;
	}

	if(event->getEventType() == MOVE_EVENT_EQUIP || event->getEventType() == MOVE_EVENT_DE_EQUIP)
	{
		ScriptEnviroment* env = getEnv();
		bool boolean = popBoolean(L);
		slots_t slot = (slots_t)popNumber(L);

		Item* item = env->getItemByUID(popNumber(L));
		if(!item)
		{
			error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND));
			lua_pushboolean(L, false);
			return 1;
		}

		Player* player = env->getPlayerByUID(popNumber(L));
		if(!player)
		{
			error(__FUNCTION__, getError(LUA_ERROR_PLAYER_NOT_FOUND));
			lua_pushboolean(L, false);
			return 1;
		}

		if(event->getEventType() != MOVE_EVENT_EQUIP)
			lua_pushboolean(L, MoveEvent::DeEquipItem(event, player, item, slot, boolean));
		else
			lua_pushboolean(L, MoveEvent::EquipItem(event, player, item, slot, boolean));

		return 1;
	}
	else if(event->getEventType() == MOVE_EVENT_STEP_IN)
	{
		ScriptEnviroment* env = getEnv();
		Item* item = env->getItemByUID(popNumber(L));
		if(!item)
		{
			error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND));
			lua_pushboolean(L, false);
			return 1;
		}

		Creature* creature = env->getCreatureByUID(popNumber(L));
		if(!creature)
		{
			error(__FUNCTION__, getError(LUA_ERROR_CREATURE_NOT_FOUND));
			lua_pushboolean(L, false);
			return 1;
		}

		lua_pushboolean(L, MoveEvent::StepInField(creature, item));
		return 1;
	}
	else if(event->getEventType() == MOVE_EVENT_ADD_ITEM)
	{
		ScriptEnviroment* env = getEnv();
		Item* item = env->getItemByUID(popNumber(L));
		if(!item)
		{
			error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND));
			lua_pushboolean(L, false);
			return 1;
		}

		lua_pushboolean(L, MoveEvent::AddItemField(item));
		return 1;
	}

	error(__FUNCTION__, "callFunction not available for current event.");
	lua_pushboolean(L, false);
	return 1;
}