• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

NPC The Gambling Man, the interactive dicer

Evan

A splendid one to behold
Senator
Premium User
Joined
May 6, 2009
Messages
7,019
Solutions
1
Reaction score
1,029
Location
United States
First and foremost, this script is 1.0 EXCLUSIVE! That means only 1.0 servers can use this script. Also, special thanks to Dalkon <3
If you want to convert it for other versions, be my guest, but the main purpose is to get people to start using 1.0 (because it's 1000x better).

I'm sure you all have heard legendary stories about the Skynet dicer bot in real Tibia.
It's no doubt the owner of that bot is banking in millions of gold every day.

I've decided to release my first 1.0 script on an NPC that imitates the Skynet dicer bot.



Create a new NPC XML file the_gambling_man.xml:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="The Gambling Man" script="data/npc/scripts/dice_gamble.lua" walkinterval="0" floorchange="0">
	<health now="100" max="100"/>
	<look type="494" head="38" body="87" legs="46" feet="46" addons="3"/>
</npc>
Create a new NPC Lua file dice_gamble.lua:
Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid)				npcHandler:onCreatureAppear(cid) 			end
function onCreatureDisappear(cid) 			npcHandler:onCreatureDisappear(cid) 		end
function onCreatureSay(cid, type, msg) 		npcHandler:onCreatureSay(cid, type, msg) 	end
function onThink() 							npcHandler:onThink() 						end
function onPlayerEndTrade(cid)				npcHandler:onPlayerEndTrade(cid)			end
function onPlayerCloseChannel(cid)			npcHandler:onPlayerCloseChannel(cid)		end

local function delayMoneyRemoval(delayRemovedItem)
	delayRemovedItem:remove(delayRemovedItem:getCount())
end

local function placeMoney(amount, table_middle_pos)
	local remain = amount
	local crystal_coins = 0
	local platinum_coins = 0

	if (math.floor(amount / 10000) >= 1) then
		crystal_coins = math.floor(amount / 10000)
		remain = remain - crystal_coins * 10000
	end
	if ((remain / 100) >= 1) then
		platinum_coins = remain / 100
	end
	addEvent(doCreateItem, 550, 2152, platinum_coins, table_middle_pos)
	addEvent(doCreateItem, 600, 2160, crystal_coins, table_middle_pos)
end

local function rollDice(roll, cc_count, pc_count, table_left_pos, table_middle_pos, npc)
	local dice_ids = {5792, 5793, 5794, 5795, 5796, 5797}
	local random_rollval = math.random(1,6)
	local total_g = (10000 * cc_count) + (100 * pc_count)
	local prize_percent = 0.8 -- 80%

	if ((total_g) <= 300000 and (total_g) >= 5000) then
		table_left_pos:sendMagicEffect(CONST_ME_CRAPS)
		
		for _, itemId in pairs(dice_ids) do
				if(getTileItemById(table_left_pos, itemId).uid > 0) then
				doTransformItem(getTileItemById(table_left_pos, itemId).uid, dice_ids[random_rollval])
			end
		end
	
		if (roll == 1 and random_rollval <= 3) then
			placeMoney(total_g + (total_g * prize_percent), table_middle_pos)
			addEvent(Position.sendMagicEffect, 400, table_left_pos, CONST_ME_SOUND_GREEN)
			addEvent(Position.sendMagicEffect, 700, table_left_pos, CONST_ME_SOUND_GREEN)
		elseif (roll == 2 and random_rollval >= 4) then
			placeMoney(total_g + (total_g * prize_percent), table_middle_pos)
			addEvent(Position.sendMagicEffect, 400, table_left_pos, CONST_ME_SOUND_GREEN)
			addEvent(Position.sendMagicEffect, 700, table_left_pos, CONST_ME_SOUND_GREEN)
		else
			addEvent(Position.sendMagicEffect, 400, table_left_pos, CONST_ME_BLOCKHIT)
			addEvent(Position.sendMagicEffect, 700, table_left_pos, CONST_ME_BLOCKHIT)
		end
		npc:say(string.format("%s rolled a %d.", npc:getName(), random_rollval), TALKTYPE_ORANGE_1, false, 0, npc:getPosition())
	else
		addEvent(doCreateItem, 100, 2160, cc_count, table_middle_pos)
		addEvent(doCreateItem, 150, 2152, pc_count, table_middle_pos)
		npc:say("The minimum wager is 5K and the maximum wager is 300K.", TALKTYPE_SAY, false, 0, npc:getPosition())
	end
	return true
end

function creatureSayCallback(cid, type, msg)
	-- NPC userdata instance
	local npc = Npc(getNpcCid())
	
	-- Participating player userdata instance
	local position = npc:getPosition() + {x = 2, y = 0, z = 0}
	position.stackpos = STACKPOS_TOP_CREATURE
	local player_uid = getThingfromPos(position).uid
	
	-- Game table position userdata instances
	local table_left_pos = Position(1110, 994, 8)
	local table_middle_pos = Position(1111, 994, 8)
	
	-- Search for coins on the left and middle tables and create item userdata instances
	local table_left_cc_uid = getTileItemById(table_left_pos, 2160).uid
	local table_middle_cc_uid = getTileItemById(table_middle_pos, 2160).uid
	local table_left_pc_uid = getTileItemById(table_left_pos, 2152).uid
	local table_middle_pc_uid = getTileItemById(table_middle_pos, 2152).uid
	
	-- Other variables
	local cc_count = 0
	local pc_count = 0
	local ROLL, LOW, HIGH = 0, 1, 2
	
	if (player_uid ~= 0) then
		player = Player(player_uid)
		if ((msgcontains(string.lower(msg), 'high') and (player:isPlayer() and player:getId() == cid)) then
			ROLL = HIGH
		elseif ((msgcontains(string.lower(msg), 'low') and (player:isPlayer() and player:getId() == cid)) then
			ROLL = LOW
		else
			return false
		end
		if (table_middle_cc_uid ~= 0) then
			table_middle_cc = Item(table_middle_cc_uid)
			cc_count = table_middle_cc:getCount()
			table_middle_cc:moveTo(table_left_pos)
			addEvent(delayMoneyRemoval, 300, table_middle_cc)
		end
		if (table_middle_pc_uid ~= 0) then
			table_middle_pc = Item(table_middle_pc_uid)
			pc_count = table_middle_pc:getCount()
			table_middle_pc:moveTo(table_left_pos)
			addEvent(delayMoneyRemoval, 300, table_middle_pc)
		end
		addEvent(rollDice, 500, ROLL, cc_count, pc_count, table_left_pos, table_middle_pos, npc)
	else
		return false
	end
	return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

Basic rules of dice:
- You have two options when you play: low, which are dice values 1, 2, 3 or high, which are dice values 4, 5, 6.
- If the dice lands on a value that is in the correct range (low/high), you will win your money back PLUS 80% of it. If you lose, you get nothing.

Notes:
- The prize percentage can be changed in the script, as well as the minimum and maximum bid values.
- The map set-up is recommended to be like this, especially the 3 tables, dice, and glowing switch tile.
- This NPC does not recognize gold pieces.
- The total winning is floored, not rounded. Give the NPC a break!

Zd8aNTo.png


Short video demonstration: (watch on YouTube to see it bigger)

[video=youtube;aqOT2TVPyQc]http://www.youtube.com/watch?v=aqOT2TVPyQc&feature=youtu.be[/video]


Additional features:

Want an anti-trasher? (optional, script will still find the gold if trashed)

movements.xml:
XML:
	<!-- Dice trash prevention -->
<movevent event="AddItem" pos="1110;994;8" script="trash_prevent.lua"/> <!-- {x = 1110, y = 994, z = 8} -->
<movevent event="AddItem" pos="1111;994;8" script="trash_prevent.lua"/> <!-- {x = 1111, y = 994, z = 8} -->
<movevent event="AddItem" pos="1112;994;8" script="trash_prevent.lua"/> <!-- {x = 1112, y = 994, z = 8} -->
trash_prevent.lua:
Lua:
local item_exceptions = {2152, 2160, 5792, 5793, 5794, 5795, 5796, 5797}

function onAddItem(item, tile, pos)
	if not isInArray(item_exceptions, item.itemid) then
		doRemoveItem(item.uid)
	end
	return true
end



The purpose of this script is to show how I am using the new Lua metatable system.
If anyone has any questions, comments, concerns, please DO NOT hesitate to post!

If you want to download TFS 1.0, please visit:
https://github.com/otland/forgottenserver



Updates:
- Fixed NPC keyword screw-ups, thanks Xagul
 
Last edited:
Pretty awesome npc!


Edit:
For those of you interested, here is the script converted for older versions of TFS (semi-tested on 0.4) Please do not nag Evan for support with this, I am just providing it AS IS for those of you who would like a jump start on the conversion.
I think I changed everything that needs to be but make sure to test well before use.

Edit 2:
Btw Evan, it really annoyed me that he didn't say if you win or lose (even though it is sorta obvious if u don't get money back) but I added it anyway. :)

Code:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
 
function onCreatureAppear(cid)				npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) 			npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) 		npcHandler:onCreatureSay(cid, type, msg) end
function onThink()					    	npcHandler:onThink() end
 
local function delayMoneyRemoval(item, pos)
	doRemoveItem(getTileItemById(pos, item).uid)
	return true
end
 
local function placeMoney(amount, table_middle_pos)
	local remain = amount
	local crystal_coins = 0
	local platinum_coins = 0
 
	if (math.floor(amount / 10000) >= 1) then
		crystal_coins = math.floor(amount / 10000)
		remain = remain - crystal_coins * 10000
	end
	if ((remain / 100) >= 1) then
		platinum_coins = remain / 100
	end
	addEvent(doCreateItem, 550, 2152, platinum_coins, table_middle_pos)
	addEvent(doCreateItem, 600, 2160, crystal_coins, table_middle_pos)
end
 
local function rollDice(roll, cc_count, pc_count, table_left_pos, table_middle_pos, npc)
	local dice_ids = {5792, 5793, 5794, 5795, 5796, 5797}
	local random_rollval = math.random(1,6)
	local total_g = (10000 * cc_count) + (100 * pc_count)
	local prize_percent = 0.8 -- 80%
 
	if ((total_g) <= 300000 and (total_g) >= 5000) then
		doSendMagicEffect(table_left_pos, CONST_ME_CRAPS)
 
		for _, itemId in pairs(dice_ids) do
				if(getTileItemById(table_left_pos, itemId).uid > 0) then
				doTransformItem(getTileItemById(table_left_pos, itemId).uid, dice_ids[random_rollval])
			end
		end
 
		if (roll == 1 and random_rollval <= 3) then
			placeMoney(total_g + (total_g * prize_percent), table_middle_pos)
			addEvent(doSendMagicEffect, 400, table_left_pos, CONST_ME_SOUND_GREEN)
			addEvent(doSendMagicEffect, 700, table_left_pos, CONST_ME_SOUND_GREEN)
			addEvent(doCreatureSay, 500, npc, "You win!", TALKTYPE_SAY, false, 0)
		elseif (roll == 2 and random_rollval >= 4) then
			placeMoney(total_g + (total_g * prize_percent), table_middle_pos)
			addEvent(doSendMagicEffect, 400, table_left_pos, CONST_ME_SOUND_GREEN)
			addEvent(doSendMagicEffect, 700, table_left_pos, CONST_ME_SOUND_GREEN)
			addEvent(doCreatureSay, 500, npc, "You win!", TALKTYPE_SAY, false, 0)
		else
			addEvent(doSendMagicEffect, 400, table_left_pos, CONST_ME_BLOCKHIT)
			addEvent(doSendMagicEffect, 700, table_left_pos, CONST_ME_BLOCKHIT)
			addEvent(doCreatureSay, 500, npc, "Better luck next time.", TALKTYPE_SAY, false, 0)
		end
		doCreatureSay(npc, string.format("%s rolled a %d.", getCreatureName(npc), random_rollval), TALKTYPE_ORANGE_1, false, 0, table_left_pos)
	else
		addEvent(doCreateItem, 100, 2160, cc_count, table_middle_pos)
		addEvent(doCreateItem, 150, 2152, pc_count, table_middle_pos)
		doCreatureSay(npc, "The minimum wager is 5K and the maximum wager is 300K.", TALKTYPE_SAY, false, 0)
	end
	return true
end
 
function creatureSayCallback(cid, type, msg)
	-- NPC userdata instance
	local npc = getNpcCid()
 
	-- Participating player userdata instance
	local position = {x = getNpcPos().x+2, y = getNpcPos().y, z = getNpcPos().z}
	position.stackpos = STACKPOS_TOP_CREATURE
	local player_uid = getThingfromPos(position).uid
 
	-- Game table position userdata instances
	local table_left_pos = {x = 120, y = 50, z = 7}
	local table_middle_pos = {x = 121, y = 50, z = 7}
 
	-- Search for coins on the left and middle tables and create item userdata instances
	local table_middle_cc = getTileItemById(table_middle_pos, 2160)
	local table_middle_pc = getTileItemById(table_middle_pos, 2152)
 
	-- Other variables
	local cc_count = 0
	local pc_count = 0
	local ROLL, LOW, HIGH = 0, 1, 2
 
	if (player_uid ~= 0) then
		if ((msgcontains(string.lower(msg), 'high') or msgcontains(string.lower(msg), 'h')) and (isPlayer(player_uid) and player_uid == cid)) then
			ROLL = HIGH
		elseif ((msgcontains(string.lower(msg), 'low') or msgcontains(string.lower(msg), 'l')) and (isPlayer(player_uid) and player_uid == cid)) then
			ROLL = LOW
		else
			return false
		end
		if (table_middle_cc.uid ~= 0) then
			cc_count = table_middle_cc.type
			doTeleportThing(table_middle_cc.uid, table_left_pos)
			addEvent(delayMoneyRemoval, 300, 2160, table_left_pos)
		end
		if (table_middle_pc.uid ~= 0) then
			pc_count = table_middle_pc.type
			doTeleportThing(table_middle_pc.uid, table_left_pos)
			addEvent(delayMoneyRemoval, 300, 2152, table_left_pos)
		end
		addEvent(rollDice, 500, ROLL, cc_count, pc_count, table_left_pos, table_middle_pos, npc)
	else
		return false
	end
	return true
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
 
Last edited:
Good Job. this can be really usefull for everyone :eek:

Is the 1.0 version the (0.5) in premium subversion? Just wondering cause i cant find anything 'bout 1.0 at subversions :x
 
Good Job. this can be really usefull for everyone :eek:

Is the 1.0 version the (0.5) in premium subversion? Just wondering cause i cant find anything 'bout 1.0 at subversions :x

1.0 is not 0.5. 0.5 is Tryller's personal branch, he's on his own.
As far as I know, official TFS will no longer be using the subversions here on this forum, it will be using GitHub.

1.0 is the new official TFS branch that is currently in high levels of development.
You can visit the GitHub repo here: https://github.com/otland/forgottenserver

I am also working on a documentation for metatables, it's obviously going to take time to finish.
https://github.com/EvanMC/forgottenserver/wiki/Metatable:-Container
* I only have most of the Container metatable documentation so far
 
if possible you should make it so you can say have 5 npcs lower max's then others or whatever but have it so the npc can keep track of what it wins/loses, or make it so if someone wants to pay a fee the npc will be there vendor for gambling for a limited time, could add alot of interest ;p
 
Pretty awesome npc!


Edit:
For those of you interested, here is the script converted for older versions of TFS (semi-tested on 0.4) Please do not nag Evan for support with this, I am just providing it AS IS for those of you who would like a jump start on the conversion.
I think I changed everything that needs to be but make sure to test well before use.

Edit 2:
Btw Evan, it really annoyed me that he didn't say if you win or lose (even though it is sorta obvious if u don't get money back) but I added it anyway. :)

Code:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
 
function onCreatureAppear(cid)				npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) 			npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) 		npcHandler:onCreatureSay(cid, type, msg) end
function onThink()					    	npcHandler:onThink() end
 
local function delayMoneyRemoval(item, pos)
	doRemoveItem(getTileItemById(pos, item).uid)
	return true
end
 
local function placeMoney(amount, table_middle_pos)
	local remain = amount
	local crystal_coins = 0
	local platinum_coins = 0
 
	if (math.floor(amount / 10000) >= 1) then
		crystal_coins = math.floor(amount / 10000)
		remain = remain - crystal_coins * 10000
	end
	if ((remain / 100) >= 1) then
		platinum_coins = remain / 100
	end
	addEvent(doCreateItem, 550, 2152, platinum_coins, table_middle_pos)
	addEvent(doCreateItem, 600, 2160, crystal_coins, table_middle_pos)
end
 
local function rollDice(roll, cc_count, pc_count, table_left_pos, table_middle_pos, npc)
	local dice_ids = {5792, 5793, 5794, 5795, 5796, 5797}
	local random_rollval = math.random(1,6)
	local total_g = (10000 * cc_count) + (100 * pc_count)
	local prize_percent = 0.8 -- 80%
 
	if ((total_g) <= 300000 and (total_g) >= 5000) then
		doSendMagicEffect(table_left_pos, CONST_ME_CRAPS)
 
		for _, itemId in pairs(dice_ids) do
				if(getTileItemById(table_left_pos, itemId).uid > 0) then
				doTransformItem(getTileItemById(table_left_pos, itemId).uid, dice_ids[random_rollval])
			end
		end
 
		if (roll == 1 and random_rollval <= 3) then
			placeMoney(total_g + (total_g * prize_percent), table_middle_pos)
			addEvent(doSendMagicEffect, 400, table_left_pos, CONST_ME_SOUND_GREEN)
			addEvent(doSendMagicEffect, 700, table_left_pos, CONST_ME_SOUND_GREEN)
			addEvent(doCreatureSay, 500, npc, "You win!", TALKTYPE_SAY, false, 0)
		elseif (roll == 2 and random_rollval >= 4) then
			placeMoney(total_g + (total_g * prize_percent), table_middle_pos)
			addEvent(doSendMagicEffect, 400, table_left_pos, CONST_ME_SOUND_GREEN)
			addEvent(doSendMagicEffect, 700, table_left_pos, CONST_ME_SOUND_GREEN)
			addEvent(doCreatureSay, 500, npc, "You win!", TALKTYPE_SAY, false, 0)
		else
			addEvent(doSendMagicEffect, 400, table_left_pos, CONST_ME_BLOCKHIT)
			addEvent(doSendMagicEffect, 700, table_left_pos, CONST_ME_BLOCKHIT)
			addEvent(doCreatureSay, 500, npc, "Better luck next time.", TALKTYPE_SAY, false, 0)
		end
		doCreatureSay(npc, string.format("%s rolled a %d.", getCreatureName(npc), random_rollval), TALKTYPE_ORANGE_1, false, 0, table_left_pos)
	else
		addEvent(doCreateItem, 100, 2160, cc_count, table_middle_pos)
		addEvent(doCreateItem, 150, 2152, pc_count, table_middle_pos)
		doCreatureSay(npc, "The minimum wager is 5K and the maximum wager is 300K.", TALKTYPE_SAY, false, 0)
	end
	return true
end
 
function creatureSayCallback(cid, type, msg)
	-- NPC userdata instance
	local npc = getNpcCid()
 
	-- Participating player userdata instance
	local position = {x = getNpcPos().x+2, y = getNpcPos().y, z = getNpcPos().z}
	position.stackpos = STACKPOS_TOP_CREATURE
	local player_uid = getThingfromPos(position).uid
 
	-- Game table position userdata instances
	local table_left_pos = {x = 120, y = 50, z = 7}
	local table_middle_pos = {x = 121, y = 50, z = 7}
 
	-- Search for coins on the left and middle tables and create item userdata instances
	local table_middle_cc = getTileItemById(table_middle_pos, 2160)
	local table_middle_pc = getTileItemById(table_middle_pos, 2152)
 
	-- Other variables
	local cc_count = 0
	local pc_count = 0
	local ROLL, LOW, HIGH = 0, 1, 2
 
	if (player_uid ~= 0) then
		if ((msgcontains(string.lower(msg), 'high') or msgcontains(string.lower(msg), 'h')) and (isPlayer(player_uid) and player_uid == cid)) then
			ROLL = HIGH
		elseif ((msgcontains(string.lower(msg), 'low') or msgcontains(string.lower(msg), 'l')) and (isPlayer(player_uid) and player_uid == cid)) then
			ROLL = LOW
		else
			return false
		end
		if (table_middle_cc.uid ~= 0) then
			cc_count = table_middle_cc.type
			doTeleportThing(table_middle_cc.uid, table_left_pos)
			addEvent(delayMoneyRemoval, 300, 2160, table_left_pos)
		end
		if (table_middle_pc.uid ~= 0) then
			pc_count = table_middle_pc.type
			doTeleportThing(table_middle_pc.uid, table_left_pos)
			addEvent(delayMoneyRemoval, 300, 2152, table_left_pos)
		end
		addEvent(rollDice, 500, ROLL, cc_count, pc_count, table_left_pos, table_middle_pos, npc)
	else
		return false
	end
	return true
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

He doesn't reply when I say "hi" .
 
He's not supposed to.

All you need to do is go up, put the money on the table and say high or low.
 
Awesome idea and script! :D :D :D

But imo anti trasher should only teleport invalid items 1 sqm >.

Lua:
local item_exceptions = {2152, 2160, 5792, 5793, 5794, 5795, 5796, 5797}
 
function onAddItem(item, tile, pos)
	if not isInArray(item_exceptions, item.itemid) then
		doTeleportThing(item.uid, {x = pos.x + 1, y = pos.y, z = pos.z})
	end
	return true
end
 
Awesome idea and script! :D :D :D

But imo anti trasher should only teleport invalid items 1 sqm >.

Lua:
local item_exceptions = {2152, 2160, 5792, 5793, 5794, 5795, 5796, 5797}
 
function onAddItem(item, tile, pos)
	if not isInArray(item_exceptions, item.itemid) then
		doTeleportThing(item.uid, {x = pos.x + 1, y = pos.y, z = pos.z})
	end
	return true
end

I thought about it, it definitely would suck to have your soft boots being thrown out.
Also, this way can trash the players depot. It's all open to whichever you prefer.
 
Awesome idea and script! :D :D :D

But imo anti trasher should only teleport invalid items 1 sqm >.

Lua:
local item_exceptions = {2152, 2160, 5792, 5793, 5794, 5795, 5796, 5797}

function onAddItem(item, tile, pos)
if not isInArray(item_exceptions, item.itemid) then
doTeleportThing(item.uid, {x = pos.x + 1, y = pos.y, z = pos.z})
end
return true
end
The Npc works but the Trash remover dont works for me....
None of your 2 solutions for a item remover
 
First and foremost, this script is 1.0 EXCLUSIVE! That means only 1.0 servers can use this script. Also, special thanks to Dalkon <3
If you want to convert it for other versions, be my guest, but the main purpose is to get people to start using 1.0 (because it's 1000x better).

I'm sure you all have heard legendary stories about the Skynet dicer bot in real Tibia.
It's no doubt the owner of that bot is banking in millions of gold every day.

I've decided to release my first 1.0 script on an NPC that imitates the Skynet dicer bot.



Create a new NPC XML file the_gambling_man.xml:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="The Gambling Man" script="data/npc/scripts/dice_gamble.lua" walkinterval="0" floorchange="0">
    <health now="100" max="100"/>
    <look type="494" head="38" body="87" legs="46" feet="46" addons="3"/>
</npc>
Create a new NPC Lua file dice_gamble.lua:
Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid)                npcHandler:eek:nCreatureAppear(cid)             end
function onCreatureDisappear(cid)             npcHandler:eek:nCreatureDisappear(cid)         end
function onCreatureSay(cid, type, msg)         npcHandler:eek:nCreatureSay(cid, type, msg)     end
function onThink()                             npcHandler:eek:nThink()                         end
function onPlayerEndTrade(cid)                npcHandler:eek:nPlayerEndTrade(cid)            end
function onPlayerCloseChannel(cid)            npcHandler:eek:nPlayerCloseChannel(cid)        end

local function delayMoneyRemoval(delayRemovedItem)
    delayRemovedItem:remove(delayRemovedItem:getCount())
end

local function placeMoney(amount, table_middle_pos)
    local remain = amount
    local crystal_coins = 0
    local platinum_coins = 0

    if (math.floor(amount / 10000) >= 1) then
        crystal_coins = math.floor(amount / 10000)
        remain = remain - crystal_coins * 10000
    end
    if ((remain / 100) >= 1) then
        platinum_coins = remain / 100
    end
    addEvent(doCreateItem, 550, 2152, platinum_coins, table_middle_pos)
    addEvent(doCreateItem, 600, 2160, crystal_coins, table_middle_pos)
end

local function rollDice(roll, cc_count, pc_count, table_left_pos, table_middle_pos, npc)
    local dice_ids = {5792, 5793, 5794, 5795, 5796, 5797}
    local random_rollval = math.random(1,6)
    local total_g = (10000 * cc_count) + (100 * pc_count)
    local prize_percent = 0.8 -- 80%

    if ((total_g) <= 300000 and (total_g) >= 5000) then
        table_left_pos:sendMagicEffect(CONST_ME_CRAPS)
    
        for _, itemId in pairs(dice_ids) do
                if(getTileItemById(table_left_pos, itemId).uid > 0) then
                doTransformItem(getTileItemById(table_left_pos, itemId).uid, dice_ids[random_rollval])
            end
        end

        if (roll == 1 and random_rollval <= 3) then
            placeMoney(total_g + (total_g * prize_percent), table_middle_pos)
            addEvent(Position.sendMagicEffect, 400, table_left_pos, CONST_ME_SOUND_GREEN)
            addEvent(Position.sendMagicEffect, 700, table_left_pos, CONST_ME_SOUND_GREEN)
        elseif (roll == 2 and random_rollval >= 4) then
            placeMoney(total_g + (total_g * prize_percent), table_middle_pos)
            addEvent(Position.sendMagicEffect, 400, table_left_pos, CONST_ME_SOUND_GREEN)
            addEvent(Position.sendMagicEffect, 700, table_left_pos, CONST_ME_SOUND_GREEN)
        else
            addEvent(Position.sendMagicEffect, 400, table_left_pos, CONST_ME_BLOCKHIT)
            addEvent(Position.sendMagicEffect, 700, table_left_pos, CONST_ME_BLOCKHIT)
        end
        npc:say(string.format("%s rolled a %d.", npc:getName(), random_rollval), TALKTYPE_ORANGE_1, false, 0, npc:getPosition())
    else
        addEvent(doCreateItem, 100, 2160, cc_count, table_middle_pos)
        addEvent(doCreateItem, 150, 2152, pc_count, table_middle_pos)
        npc:say("The minimum wager is 5K and the maximum wager is 300K.", TALKTYPE_SAY, false, 0, npc:getPosition())
    end
    return true
end

function creatureSayCallback(cid, type, msg)
    -- NPC userdata instance
    local npc = Npc(getNpcCid())

    -- Participating player userdata instance
    local position = npc:getPosition() + {x = 2, y = 0, z = 0}
    position.stackpos = STACKPOS_TOP_CREATURE
    local player_uid = getThingfromPos(position).uid

    -- Game table position userdata instances
    local table_left_pos = Position(1110, 994, 8)
    local table_middle_pos = Position(1111, 994, 8)

    -- Search for coins on the left and middle tables and create item userdata instances
    local table_left_cc_uid = getTileItemById(table_left_pos, 2160).uid
    local table_middle_cc_uid = getTileItemById(table_middle_pos, 2160).uid
    local table_left_pc_uid = getTileItemById(table_left_pos, 2152).uid
    local table_middle_pc_uid = getTileItemById(table_middle_pos, 2152).uid

    -- Other variables
    local cc_count = 0
    local pc_count = 0
    local ROLL, LOW, HIGH = 0, 1, 2

    if (player_uid ~= 0) then
        player = Player(player_uid)
        if ((msgcontains(string.lower(msg), 'high') and (player:isPlayer() and player:getId() == cid)) then
            ROLL = HIGH
        elseif ((msgcontains(string.lower(msg), 'low') and (player:isPlayer() and player:getId() == cid)) then
            ROLL = LOW
        else
            return false
        end
        if (table_middle_cc_uid ~= 0) then
            table_middle_cc = Item(table_middle_cc_uid)
            cc_count = table_middle_cc:getCount()
            table_middle_cc:moveTo(table_left_pos)
            addEvent(delayMoneyRemoval, 300, table_middle_cc)
        end
        if (table_middle_pc_uid ~= 0) then
            table_middle_pc = Item(table_middle_pc_uid)
            pc_count = table_middle_pc:getCount()
            table_middle_pc:moveTo(table_left_pos)
            addEvent(delayMoneyRemoval, 300, table_middle_pc)
        end
        addEvent(rollDice, 500, ROLL, cc_count, pc_count, table_left_pos, table_middle_pos, npc)
    else
        return false
    end
    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

Basic rules of dice:
- You have two options when you play: low, which are dice values 1, 2, 3 or high, which are dice values 4, 5, 6.
- If the dice lands on a value that is in the correct range (low/high), you will win your money back PLUS 80% of it. If you lose, you get nothing.

Notes:
- The prize percentage can be changed in the script, as well as the minimum and maximum bid values.
- The map set-up is recommended to be like this, especially the 3 tables, dice, and glowing switch tile.
- This NPC does not recognize gold pieces.
- The total winning is floored, not rounded. Give the NPC a break!

Zd8aNTo.png


Short video demonstration: (watch on YouTube to see it bigger)

[video=youtube;aqOT2TVPyQc]


Additional features:

Want an anti-trasher? (optional, script will still find the gold if trashed)

movements.xml:
XML:
    <!-- Dice trash prevention -->
<movevent event="AddItem" pos="1110;994;8" script="trash_prevent.lua"/> <!-- {x = 1110, y = 994, z = 8} -->
<movevent event="AddItem" pos="1111;994;8" script="trash_prevent.lua"/> <!-- {x = 1111, y = 994, z = 8} -->
<movevent event="AddItem" pos="1112;994;8" script="trash_prevent.lua"/> <!-- {x = 1112, y = 994, z = 8} -->
trash_prevent.lua:
Lua:
local item_exceptions = {2152, 2160, 5792, 5793, 5794, 5795, 5796, 5797}

function onAddItem(item, tile, pos)
    if not isInArray(item_exceptions, item.itemid) then
        doRemoveItem(item.uid)
    end
    return true
end



The purpose of this script is to show how I am using the new Lua metatable system.
If anyone has any questions, comments, concerns, please DO NOT hesitate to post!

If you want to download TFS 1.0, please visit:
https://github.com/otland/forgottenserver



Updates:
- Fixed NPC keyword screw-ups, thanks Xagul

Will you update this so its properly [coded] please? My script illiterate eyes cannot read it when its like that :( Or maybe another mod can do it? @Limos @Mark @Printer @Ninja
@Evan
 
Last edited:
Back
Top