Last active
September 7, 2016 10:39
-
-
Save dbjorkholm/e27933643684c3c4a63e2dc142745989 to your computer and use it in GitHub Desktop.
Betting NPC, Based on https://otland.net/threads/visual-gambler-npc-tfs-1-x.238812/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
local CURRENCY_GOLD_COIN = 1 | |
local CURRENCY_GOLD_NUGGET = 2 | |
local CURRENCY_EVENT_EMBLEM = 3 | |
local currencyConfig = { | |
[CURRENCY_GOLD_COIN] = { | |
itemIds = {ITEM_GOLD_COIN, ITEM_PLATINUM_COIN, ITEM_CRYSTAL_COIN}, | |
bonusPercentage = 1.9, | |
minBet = 10000, | |
maxBet = 500000 | |
}, | |
[CURRENCY_GOLD_NUGGET] = { | |
itemIds = {ITEM_GOLD_NUGGET}, | |
bonusPercentage = 1.9, | |
minBet = 10, | |
maxBet = 50, | |
}, | |
[CURRENCY_EVENT_EMBLEM] = { | |
itemIds = {ITEM_EVENT_EMBLEM}, | |
bonusPercentage = 1.9, | |
minBet = 10, | |
maxBet = 50, | |
}, | |
} | |
local getCurrencyId = {['gold coins'] = CURRENCY_GOLD_COIN, ['gold nuggets'] = CURRENCY_GOLD_NUGGET, ['event emblems'] = CURRENCY_EVENT_EMBLEM} | |
local getCurrencyName = {'Gold Coins', 'Gold Nuggets', 'Event Emblems'} | |
local function removeItems(position, condition) | |
local tile = Tile(position) | |
if not tile then | |
return | |
end | |
local items = tile:getItems() | |
if not items or type(items) ~= 'table' or #items == 0 then | |
return | |
end | |
for _, item in ipairs(items) do | |
if condition(item) then | |
item:remove() | |
end | |
end | |
end | |
local function getCurrencyAmount(position, currencyType) | |
local amount = 0 | |
local tile = Tile(position) | |
if tile then | |
local items = tile:getItems() | |
if items ~= nil and type(items) == 'table' and #items ~= 0 then | |
for _, item in ipairs(items) do | |
local itemId = item:getId() | |
if currencyType == CURRENCY_GOLD_COIN then | |
if itemId == ITEM_GOLD_COIN then | |
amount = amount + item.type | |
elseif itemId == ITEM_PLATINUM_COIN then | |
amount = amount + item.type * 100 | |
elseif itemId == ITEM_CRYSTAL_COIN then | |
amount = amount + item.type * 10000 | |
end | |
elseif currencyType == CURRENCY_GOLD_NUGGET then | |
if itemId == ITEM_GOLD_NUGGET then | |
amount = amount + item.type | |
end | |
elseif currencyType == CURRENCY_EVENT_EMBLEM then | |
if itemId == ITEM_EVENT_EMBLEM then | |
amount = amount + item.type | |
end | |
end | |
end | |
end | |
end | |
return amount | |
end | |
local function relocateCurrency(position, toPosition, condition) | |
local tile = Tile(position) | |
if not tile then | |
return | |
end | |
if position == toPosition or not Tile(toPosition) then | |
return | |
end | |
for i = tile:getThingCount() - 1, 0, -1 do | |
local thing = tile:getThing(i) | |
if thing then | |
if thing:isItem() then | |
if condition(thing) then | |
thing:moveTo(toPosition) | |
end | |
end | |
end | |
end | |
end | |
local function handleCurrency(npc, player, position, itemIds, amount, bonus, currencyType) | |
if not npc then | |
return | |
end | |
removeItems(position, function(item) return item:getType():isMovable() and isInArray(itemIds, item:getId()) end) | |
-- We lost, no need to continue | |
if bonus == 0 then | |
npc:say("You lost!", TALKTYPE_SAY, false, player) | |
position:sendMagicEffect(CONST_ME_POFF) | |
return | |
end | |
if currencyType == CURRENCY_GOLD_COIN then | |
local goldCoinAmount = amount * bonus | |
local crystalCoinAmount = math.floor(goldCoinAmount / 10000) | |
goldCoinAmount = goldCoinAmount - crystalCoinAmount * 10000 | |
local platinumCoinAmount = math.floor(goldCoinAmount / 100) | |
goldCoinAmount = goldCoinAmount - platinumCoinAmount * 100 | |
if goldCoinAmount > 0 then | |
Game.createItem(ITEM_GOLD_COIN, goldCoinAmount, position) | |
end | |
if platinumCoinAmount > 0 then | |
Game.createItem(ITEM_PLATINUM_COIN, platinumCoinAmount, position) | |
end | |
if crystalCoinAmount > 0 then | |
Game.createItem(ITEM_CRYSTAL_COIN, crystalCoinAmount, position) | |
end | |
elseif currencyType == CURRENCY_GOLD_NUGGET then | |
local nuggetAmount = math.floor(amount * bonus) | |
if nuggetAmount > 0 then | |
Game.createItem(ITEM_GOLD_NUGGET, nuggetAmount, position) | |
end | |
else | |
local emblemAmount = math.floor(amount * bonus) | |
if emblemAmount > 0 then | |
Game.createItem(ITEM_EVENT_EMBLEM, emblemAmount, position) | |
end | |
end | |
position:sendMagicEffect(math.random(CONST_ME_FIREWORK_YELLOW, CONST_ME_FIREWORK_BLUE)) | |
npc:say("You Win!", TALKTYPE_SAY, false, player) | |
end | |
local function startRollDice(npc, position, number) | |
local tile = Tile(position) | |
if tile then | |
for itemId = 5792, 5797 do | |
local diceItem = tile:getItemById(itemId) | |
if diceItem then | |
diceItem:transform(5791 + number) | |
break | |
end | |
end | |
end | |
if npc then | |
npc:say(string.format("%s rolled a %d", npc:getName(), number), TALKTYPE_MONSTER_SAY) | |
end | |
end | |
local function creatureSayCallback(cid, type, msg) | |
-- Npc Variables | |
local npc = Npc() | |
local npcPosition = npc:getPosition() | |
local playerPosition = npcPosition + Position(2, 0, 0) | |
local player = Player(cid) | |
if player:getPosition():getDistance(playerPosition) ~= 0 then | |
npc:say("Please go stand next to me. Place the currency in the middle table between us you wish to bet. Do not put items on the table or they will disappear.", TALKTYPE_SAY, false, player) | |
playerPosition:sendMagicEffect(CONST_ME_TUTORIALARROW, player) | |
playerPosition:sendMagicEffect(CONST_ME_TUTORIALSQUARE, player) | |
return false | |
end | |
local tile = Tile(playerPosition) | |
if not tile then | |
return false | |
end | |
local topCreature = tile:getTopCreature() | |
if not topCreature or not topCreature:isPlayer() then | |
return false | |
end | |
-- Make sure also the player who stand there, is the one who is betting. To keep out people from disturbing | |
if topCreature:getId() ~= cid then | |
return false | |
end | |
if msgcontains(msg, 'currency') or msgcontains(msg, 'setting') then | |
npc:say('You can pick one of the following currencies: {gold coins}, {gold nuggets} or {event emblems}. Which currency would you like to use?', TALKTYPE_SAY, false, player) | |
npcHandler.topic[cid] = 1 | |
elseif npcHandler.topic[cid] == 1 then | |
local msg = msg:trim() | |
local currencyId = getCurrencyId[msg:lower()] | |
if not currencyId then | |
npcHandler:say('This currency is not available. Please try again.', cid) | |
npcHandler.topic[cid] = 0 | |
return false | |
end | |
local currencyName = getCurrencyName[currencyId] | |
player:setStorageValue(STORAGEVALUE_CURRENCYSETTING, currencyId) | |
npc:say(string.format('You have successfully picked %s as your currency, and are now able to place bets!', currencyName), TALKTYPE_SAY, false, player) | |
npcHandler.topic[cid] = 0 | |
else | |
-- Tell the user that they need to pick their currency | |
local currencyStorage = math.max(0, player:getStorageValue(STORAGEVALUE_CURRENCYSETTING)) | |
if currencyStorage == 0 then | |
npc:say('You cannot play just yet. You need to configure your currency {setting}.', TALKTYPE_SAY, false, player) | |
return false | |
end | |
local currencySetting = currencyConfig[currencyStorage] | |
if not currencySetting then | |
npc:say('You have not picked any currency yet. Please configure your settings before you try to play again. Just say {setting}', TALKTYPE_SAY, false, player) | |
return false | |
end | |
local currencyName = getCurrencyName[currencyStorage] | |
-- Check money Got betted | |
local currencyPosition = npcPosition + Position(1, 1, 0) | |
local currencyAmount = getCurrencyAmount(currencyPosition, currencyStorage) | |
if currencyAmount < currencySetting.minBet or currencyAmount > currencySetting.maxBet then | |
npc:say(string.format("You can only bet min: %d and max: %d %s. Do not put items on the table or they will disappear. Say {setting} to change to a different betting currency.", currencySetting.minBet, currencySetting.maxBet, currencyName:lower()), TALKTYPE_SAY, false, player) | |
return false | |
end | |
-- High or Low numbers | |
local rollType = msgcontains(msg, 'low') and 1 or msgcontains(msg, 'high') and 2 or 0 | |
if rollType == 0 then | |
return false | |
end | |
-- Dice | |
local dicePosition = npcPosition + Position(0, 1, 0) | |
relocateCurrency(currencyPosition, dicePosition, function(item) return item:getType():isMovable() and isInArray(currencySetting.itemIds, item:getId()) end) | |
removeItems(dicePosition, function(item) return item:getType():isMovable() and not isInArray({5792, 5793, 5794, 5795, 5796, 5797}, item:getId()) end) | |
-- Roll Number | |
local rollNumber = math.random(6) | |
startRollDice(npc, dicePosition, rollNumber) | |
dicePosition:sendMagicEffect(CONST_ME_CRAPS) | |
-- Win or Lose | |
local bonus = 0 | |
if rollType == 1 and isInArray({1, 2, 3}, rollNumber) then | |
bonus = currencySetting.bonusPercentage | |
elseif rollType == 2 and isInArray({4, 5, 6}, rollNumber) then | |
bonus = currencySetting.bonusPercentage | |
end | |
handleCurrency(npc, player, currencyPosition, currencySetting.itemIds, currencyAmount, bonus, currencyStorage) | |
end | |
return true | |
end | |
function onThink() | |
local npcPosition = Npc():getPosition() | |
local currencyPosition = npcPosition + Position(1, 1, 0) | |
removeItems(currencyPosition, function(item) return item:getType():isMovable() and not isInArray({ITEM_GOLD_COIN, ITEM_PLATINUM_COIN, ITEM_CRYSTAL_COIN, ITEM_GOLD_NUGGET, ITEM_EVENT_EMBLEM}, item:getId()) end) | |
npcHandler:onThink() | |
end | |
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
STORAGEVALUE_CURRENCYSETTING = 250004 | |
ITEM_GOLD_NUGGET = 2157 | |
ITEM_EVENT_EMBLEM = 25839 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment