Jump to content

Some questions about LUA functions


Recommended Posts

I was never too familliar with LUA even if it seems easy. So I wanted to ask the experts a few questions.

I have this function:

game.drop_item_with_ownership(item_vnum)

In the system the dropped item stays on the ground for 3 minuets, while character ownership ends after the first minute. Therefore the item stays on the ground without an owner for 2 minutes and then it dissapears. How do I make the ownership for this item only last forever (until it dissapears)?

Another question I have is about the chance for the item to drop. Let's say I need the item to have 20% chance of drop at:

when kill begin

I did a little digging and found this:

when kill begin
	chance = 20

	if math.random(1, 100) < chance then
		game.drop_item_with_ownership(item_vnum)
	end
end

Would something like this work? Or am I wrong?

  • Sad 1
Link to comment
Share on other sites

  • Premium

                    local dropChance = 20.00; --20%
                    if dropChance <= number(0, 10000)/100 then
                        game.drop_item_with_ownership(ITEM_VNUM, 1)
                    end

drop_item_with_ownership():

-time for owner name inside CONFIG ->CORE

-time for item destroy  CONFIG ->CORE

Link to comment
Share on other sites

Quote

I was never too familliar with LUA even if it seems easy. So I wanted to ask the experts a few questions.

I have this function:


game.drop_item_with_ownership(item_vnum)

In the system the dropped item stays on the ground for 3 minuets, while character ownership ends after the first minute. Therefore the item stays on the ground without an owner for 2 minutes and then it dissapears. How do I make the ownership for this item only last forever (until it dissapears)?

On ServerSide source files in questlua_game.cpp the function is defined like this:

int game_drop_item_with_ownership(lua_State* L)
	{
		LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();

		LPITEM item = NULL;
		switch (lua_gettop(L))
		{
		case 1:
			item = ITEM_MANAGER::instance().CreateItem((DWORD) lua_tonumber(L, 1));
			break;
		case 2:
		case 3:
			item = ITEM_MANAGER::instance().CreateItem((DWORD) lua_tonumber(L, 1), (int) lua_tonumber(L, 2));
			break;
		default:
			return 0;
		}

		if ( item == NULL )
		{
			return 0;
		}

		if (lua_isnumber(L, 3))
		{
			int sec = (int) lua_tonumber(L, 3);
			if (sec <= 0)
			{
				item->SetOwnership( ch );
			}
			else
			{
				item->SetOwnership( ch, sec );
			}
		}
		else
			item->SetOwnership( ch );

		PIXEL_POSITION pos;
		pos.x = ch->GetX() + number(-200, 200);
		pos.y = ch->GetY() + number(-200, 200);

		item->AddToGround(ch->GetMapIndex(), pos);
		item->StartDestroyEvent();

		return 0;
	}

So the function you are trying to call is already accepting a second and a third parameter for quantity and ownership duration. You could simply use 

game.drop_item_with_ownership(item_vnum, item_quantity, ownership_duration)

The StartDestroyEvent() function has a default value of sec = 300 defined in item.h but you can enter the time you desire as a parameter:

item->StartDestroyEvent(time_you_desire);

Link to comment
Share on other sites

Thank you so much for replying guys.

17 minutes ago, OtherChoice said:

On ServerSide source files in questlua_game.cpp the function is defined like this:


int game_drop_item_with_ownership(lua_State* L)
	{
		LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();

		LPITEM item = NULL;
		switch (lua_gettop(L))
		{
		case 1:
			item = ITEM_MANAGER::instance().CreateItem((DWORD) lua_tonumber(L, 1));
			break;
		case 2:
		case 3:
			item = ITEM_MANAGER::instance().CreateItem((DWORD) lua_tonumber(L, 1), (int) lua_tonumber(L, 2));
			break;
		default:
			return 0;
		}

		if ( item == NULL )
		{
			return 0;
		}

		if (lua_isnumber(L, 3))
		{
			int sec = (int) lua_tonumber(L, 3);
			if (sec <= 0)
			{
				item->SetOwnership( ch );
			}
			else
			{
				item->SetOwnership( ch, sec );
			}
		}
		else
			item->SetOwnership( ch );

		PIXEL_POSITION pos;
		pos.x = ch->GetX() + number(-200, 200);
		pos.y = ch->GetY() + number(-200, 200);

		item->AddToGround(ch->GetMapIndex(), pos);
		item->StartDestroyEvent();

		return 0;
	}

So the function you are trying to call is already accepting a second and a third parameter for quantity and ownership duration. You could simply use 


game.drop_item_with_ownership(item_vnum, item_quantity, ownership_duration)

The StartDestroyEvent() function has a default value of sec = 300 defined in item.h but you can enter the time you desire as a parameter:

item->StartDestroyEvent(time_you_desire);

Thanks! It worked out perfectly :)

9 hours ago, WeedHex said:

                    local dropChance = 20.00; --20%
                    if dropChance <= number(0, 10000)/100 then
                        game.drop_item_with_ownership(ITEM_VNUM, 1)
                    end

drop_item_with_ownership():

-time for owner name inside CONFIG ->CORE

-time for item destroy  CONFIG ->CORE

I tried that, it didn't make any difference but thanks anw :)

14 hours ago, boaspessoal said:

In theory it should, but to use math.random properly you need to use math.randomseed before, otherwise it's going to keep generating the same number.

I would personally use number instead of math.random, also use local before declaring any new variable, you can change it after if you want.

I do not know how to use randomseed but I tried without it and I saw your point.

Then I did this:

local drop_chance = 80
local random_chance = math.randomseed(math.random(1,100))
if random_chance <= drop_chance then
  ...

but now it doesn't drop.

Link to comment
Share on other sites

8 hours ago, PACI said:

The best results are achieved using os.time() for seeding.


math.randomseed(os.time())
local random = math.random(1, 100)
print(random)

However, I prefer to use the built-in function for these kind of matters: number(min, max).

Thanks for the response. I tried the following:

local drop_chance = 20.00

if drop_chance <= number(1, 10000) / 100 then
	game.drop_item_with_ownership(vnum, 1, ownership_time)
end

but nothing changed about the drop chance.

I also tried math.randomseed but got this on QC:

Calls undeclared function! :
math.randomseed
Error occured on compile questfile

I know what that error means but my question is if I give it a variable for example local var = math.randomseed(os.time()) how do I use the var in the function?

If there is a way to do it with number instead of math I would prefer that since you say it's a better way

BTW I'm using Lua 5.3

Link to comment
Share on other sites

  • Developer

It is not the seed you have to use for comparison, but the random number generated by math.random(). Calling it once - math.randomseed(os.time()) - is enough, otherwise the randomness could break.

Anyhow, 'nothing changed about the drop chance' as in? Doesn't even drops, drops too much, not enough?
My suggestion is to use a simple debug message just to be sure which values number(a, z) is returning, and comparing it to your chance constant.

when you return 0 and server doesn't boot:

unknown.png

Link to comment
Share on other sites

I made it! Seems I was using number wrong.

Was:

if number(1, 100) > drop_chance then
	game.drop_item_with_ownership(vnum, 1, ownership_time)
end

Edited:

if number(1, 100) > (100 - drop_chance) then
	game.drop_item_with_ownership(vnum, 1, ownership_time)
end

I would like to say thanks to all of you who helped me figure it out :) I couldn't do it without you guys.

Link to comment
Share on other sites

Sorry mate but for the sake of a clean and readable code you should change this

Quote

if number(1, 100) > (100 - drop_chance) then

To something like this: If number(0,(denominator-1)) <= (numerator-1)

where your chance is: numerator/denominator 

Lets say you want a 10% droprate so 1/10 chance: If number(0,9) <= 0 then

or a 0,03% droprate  ==  3/10000 you will use: If number(0,9999) <= 2 then

The best suggestion i can give you is to make a function inside your game source to call anytime you want to output a result of a chance:

int game_rnd_chance(lua_State * L)
{
	if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2))
	{
		lua_pushboolean(L, false);
	}
	if (number(0,(int)lua_tonumber(L, 2)-1) <= (int)lua_tonumber(L,1)-1)
		lua_pushboolean(L, true);
	else
		lua_pushboolean(L, false);
	return 0;
}
void RegisterGameFunctionTable()
{
	luaL_reg game_functions[] = 
	{
		.....
		{ "rnd_chance",			game_rnd_chance			},
	}
}

and then call it like this:  if game.rnd_chance(numerator,  denominator) == true then

Anyway if you still want to stick with the code you wrote i suggest you to at least remove the redundant part:

if number(1,100) > (100 - drop_chance) then      // --> to --> //       if number(1,100) <= (drop_chance) then

  • Love 1
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



  • Similar Content

  • Activity

    1. 0

      We are looking for a C++ and Python programmer

    2. 0

      [Quest Scheduler Request] Is there a way to make a quest run independet of player events? Lets say start quest automatically at server startup?

    3. 111

      Ulthar SF V2 (TMP4 Base)

    4. 0

      Quest function when 102.kill definition whereabouts help

    5. 5

      [M2 FILTER] Customized Client Filter

    6. 0

      [INGAME] RGB Color on chat broken

  • Recently Browsing

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.