- local npc_id = 0;
- --[[
- cost_type
- 1 - gold
- 2 - item
- ]]
- local cost_type = 1;
- --[[
- price based on what option you set 'cost_type' to.
- 1 - amount in gold
- 2 - amount of items of 'item_entry'
- ]]
- local price = 5;
- --[[
- item_name, used for the message.
- Only set this if you set 'cost_type' to 2 (item).
- ]]
- local item_name = "";
- --[[
- item entry, only set this if you set 'cost_type' to 2 (item).
- ]]
- local item_entry = 0;
- --[[
- interval, the amount of seconds for a game to finish.
- ]]
- local interval = 30;
- --[[
- Script
- ]]
- local rps = {};
- -- Messages
- local message_cost = "Cost: %s %s";
- local message_attribute = "%s%s chose: %s";
- -- Event constant
- local PLAYER_EVENT_ON_COMMAND = 42;
- -- 'cost_type' constants
- local COST_TYPE_GOLD = 1;
- local COST_TYPE_ITEM = 2;
- -- Attributes the player can choose from.
- local attributes = {"rock", "paper", "scissors"};
- local function isAttribute(command)
- for _, attribute in ipairs(attributes) do
- if command == attribute then return true; end
- end
- return false;
- end
- -- Might as well do the calculation here.
- local copper = cost_type == COST_TYPE_GOLD and price * 10000 or price;
- local cost_name = cost_type == COST_TYPE_GOLD and "gold" or item_name;
- interval = interval * 1000;
- -- Conditions
- local conditions = {
- ["rockscissors"] = true,
- ["rockpaper"] = false,
- ["scissorspaper"] = true,
- ["scissorsrock"] = false,
- ["paperrock"] = true,
- ["paperscissors"] = false
- };
- -- Crazy knockback spell.
- local SPELL_KNOCK_BACK = 70966;
- -- Function to take and give 'cost_type'.
- local function modify(player, amount)
- if cost_type == COST_TYPE_ITEM then
- if (amount < 0) then
- player:RemoveItem(item_entry, math.abs(amount));
- else--[[if amount > 0]]
- player:AddItem(item_entry, amount);
- end
- elseif cost_type == COST_TYPE_GOLD then
- player:ModifyMoney(amount);
- end
- end
- -- Method to check if the player has the right amount of currency.
- local function check(player)
- if cost_type == COST_TYPE_GOLD then
- return player:GetCoinage() >= copper;
- elseif cost_type == COST_TYPE_ITEM then
- return player:HasItem(item_entry, price);
- end
- return false;
- end
- -- Condition functions
- local function win(player)
- modify(player, copper);
- end
- local function lose(player)
- player:CastSpell(player, SPELL_KNOCK_BACK);
- modify(player, -copper);
- end
- local function tie(player)
- -- Nothing happends.
- end
- -- Event that handles the game.
- local function handle_rps(event_id, _, _, creature)
- local creature_attribute = attributes[math.random(#attributes)];
- for _, player_data in ipairs(rps[creature:GetGUIDLow()]) do
- local player = GetPlayerByGUID(player_data.guid);
- if player ~= nil and player:GetMapId() == creature:GetMapId() or creature:GetDistance(player) <= 40 then
- local player_attribute = player_data.attribute;
- local condition = conditions[player_attribute..creature_attribute];
- if condition == nil then
- tie(player);
- elseif condition then
- win(player);
- else
- lose(player);
- end
- end
- end
- rps[creature:GetGUIDLow()] = nil;
- creature:SendUnitSay(string.format(message_attribute, "", "I", creature_attribute), 0)
- end
- -- Function that adds a player to the table.
- local function findPlayer(creature, player)
- local lowGuid = player:GetGUIDLow();
- for _, player_data in ipairs(rps[creature:GetGUIDLow()]) do
- if player_data.guid == lowGuid then return true; end
- end
- return false;
- end
- local function addPlayer(creature, player, command)
- if not findPlayer(creature, player) then
- table.insert(rps[creature:GetGUIDLow()], {
- guid = player:GetGUIDLow(),
- attribute = command
- });
- return true;
- end
- return false;
- end
- -- Function to create the table if needed, and to register the event.
- local function creatureAddPlayer(creature, player, command)
- if rps[creature:GetGUIDLow()] == nil then
- rps[creature:GetGUIDLow()] = {
- -- Apparently we don't need this.
- --event = creature:RegisterEvent(handle_rps, 30000, 0),
- --players = {}
- };
- creature:RegisterEvent(handle_rps, interval, 1);
- end
- return addPlayer(creature, player, command);
- end
- -- Command handler
- local function onCommand(_, player, command)
- command = string.lower(command);
- if isAttribute(command) then
- if not check(player) then
- player:SendBroadcastMessage(string.format(message_cost, price, cost_name));
- return false;
- end
- local creature = player:GetSelection();
- if creature == nil or creature:GetEntry() ~= npc_id then
- return false;
- end
- if creatureAddPlayer(creature, player, command) then
- for _, plr in ipairs(player:GetPlayersInRange(40)) do
- plr:SendBroadcastMessage(string.format(message_attribute, "|cFFFF8040", player:GetName(), command));
- end
- player:SendBroadcastMessage(string.format(message_attribute, "|cFFFF8040", "You", command));
- end
- return false;
- end
- end
- RegisterPlayerEvent(PLAYER_EVENT_ON_COMMAND, onCommand);