From e64a04be39ac7790abcb09de3d4c7d8fc2a2a1e2 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 8 Oct 2014 21:10:18 +0100 Subject: [PATCH] Added Handy --- handy.lua | 28 ++++++ handy_functions.lua | 216 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 244 insertions(+) create mode 100644 handy.lua create mode 100644 handy_functions.lua diff --git a/handy.lua b/handy.lua new file mode 100644 index 0000000..e4e9d3f --- /dev/null +++ b/handy.lua @@ -0,0 +1,28 @@ +-- Global variables +PLUGIN = {} -- Reference to own plugin object +CHEST_WIDTH = 9 +HANDY_VERSION = 2 +--[[ + +Handy is a plugin for other plugins. It contain no commands, no hooks, but functions to ease plugins developers' life. + +API: + + +TODO: +1. GetChestSlot wrapper, so it will detect double chest neighbour chest and will be able to access it. +]] + +function Initialize(Plugin) + PLUGIN = Plugin + PLUGIN:SetName("Handy") + PLUGIN:SetVersion(HANDY_VERSION) + + PluginManager = cRoot:Get():GetPluginManager() + LOG("Initialized " .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion()) + return true +end + +function OnDisable() + LOG(PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " is shutting down...") +end \ No newline at end of file diff --git a/handy_functions.lua b/handy_functions.lua new file mode 100644 index 0000000..af43f66 --- /dev/null +++ b/handy_functions.lua @@ -0,0 +1,216 @@ +--[[ +General stuff +]] +-- Returns Handy plugin version number +function GetHandyVersion() + return HANDY_VERSION +end +-- Checks if handy is in proper version +function CheckForRequiredVersion( inVersion ) + if( inVersion > HANDY_VERSION ) then return false end + return true +end +--[[ +MCS-specific _functions and nasty hacks :D +]] +function GetChestHeightCheat( inChest ) + local chestGrid = inChest:GetContents() + LOGINFO( "This function serves no purpose now! You should consider chest:GetContents():GetHeight() now!" ) + LOGINFO( "Also, you might find Handy's new 'IsChestDouble()' useful for your case" ) + return chestGrid:GetHeight() +end +function IsChestDouble( inChest ) + local chestHeight = inChest:GetContents():GetHeight() + if( chestHeight == 3 ) then + return false + end + return true +end +-- Those two checks how many items of given inItemID chest and player have, and how much they could fit inside them +function ReadChestForItem( inChest, inItemID ) + return ReadGridForItems( inChest:GetContents(), inItemID ) +end +function ReadPlayerForItem( inPlayer, inItemID ) + local inventoryFound, inventoryFree = ReadGridForItems( inPlayer:GetInventory():GetInventoryGrid(), inItemID ) + local hotbarFound, hotbarFree = ReadGridForItems( inPlayer:GetInventory():GetHotbarGrid(), inItemID ) + local itemsFound = inventoryFound + hotbarFound + local freeSpace = inventoryFree + hotbarFree + return itemsFound, freeSpace +end +-- Following functions are for chest-related operations +-- BEWARE! Those assume you did checked if chest has items/space in it! +function ReadGridForItems( inGrid, inItemID ) + local itemsFound = 0 + local freeSpace = 0 + local slotsCount = inGrid:GetNumSlots() + local testerItem = cItem( inItemID ) + local maxStackSize = testerItem:GetMaxStackSize() + for index = 0, (slotsCount - 1) do + slotItem = inGrid:GetSlot( index ) + if( slotItem:IsEmpty() ) then + freeSpace = freeSpace + maxStackSize + else + if( slotItem:IsStackableWith( testerItem ) ) then + itemsFound = itemsFound + slotItem.m_ItemCount + freeSpace = maxStackSize - slotItem.m_ItemCount + end + end + end + return itemsFound, freeSpace +end + +function TakeItemsFromGrid( inGrid, inItem ) + local slotsCount = inGrid:GetNumSlots() + local removedItem = cItem( inItem ) + for index = 0, (slotsCount - 1) do + slotItem = inGrid:GetSlot( index ) + if( slotItem:IsSameType( removedItem ) ) then + if( slotItem.m_ItemCount <= removedItem.m_ItemCount ) then + removedItem.m_ItemCount = removedItem.m_ItemCount - slotItem.m_ItemCount + inGrid:EmptySlot( index ) + else + removedItem.m_ItemCount = slotItem.m_ItemCount - removedItem.m_ItemCount + inGrid:SetSlot( index, removedItem ) + removedItem.m_ItemCount = 0 + end + if( removedItem.m_ItemCount <= 0 ) then break end + end + end + return removedItem.m_ItemCount +end +-------------- +function TakeItemsFromChest( inChest, inItemID, inAmount ) -- MIGHT BE UNSAFE! CHECK FOR ITEMS FIRST!! + local chestGrid = inChest:GetContents() + local removedItem = cItem( inItemID, inAmount ) + TakeItemsFromGrid( chestGrid, removedItem ) +end +function PutItemsToChest( inChest, inItemID, inAmount ) + local chestGrid = inChest:GetContents() + local addedItem = cItem( inItemID, inAmount ) + chestGrid:AddItem( addedItem ) +end +-- Similar to chest-related. +function TakeItemsFromPlayer( inPlayer, inItemID, inAmount ) -- MIGHT BE UNSAFE! CHECK FIRST! + local removedItem = cItem( inItemID, inAmount ) + local inventoryGrid = inPlayer:GetInventory():GetInventoryGrid() + local hotbarGrid = inPlayer:GetInventory():GetHotbarGrid() + local itemsLeft = TakeItemsFromGrid( inventoryGrid, removedItem ) + if( itemsLeft > 0 ) then + removedItem = cItem( inItemID, itemsLeft ) + TakeItemsFromGrid( hotbarGrid, removedItem ) + end +end +function GiveItemsToPlayer( inPlayer, inItemID, inAmount ) + local addedItem = cItem( inItemID, inAmount ) + local inventoryGrid = inPlayer:GetInventory():GetInventoryGrid() + local hotbarGrid = inPlayer:GetInventory():GetHotbarGrid() + local itemsAdded = inventoryGrid:AddItem( addedItem ) + if( itemsAdded < inAmount ) then + addedItem.m_ItemCount = addedItem.m_ItemCount - itemsAdded + hotbarGrid:AddItem( addedItem ) + end +end +-- This function returns item max stack for a given itemID. It uses vanilla max stack size, and uses several non-common items notations; +-- Those are: +-- oneonerecord( because aparently 11record wasn't the best idea in lua scripting application ) +-- carrotonastick( because it wasn't added to items.txt yet ) +-- waitrecord( for same reason ) +-- Feel free to ignore the difference, or to add those to items.txt +function GetItemMaxStack( inItemID ) + local testerItem = cItem( inItemID ) + LOGINFO( "This function serves no real purpose now, maybe consider using cItem:GetMaxStackSize()?" ) + return testerItem:GetMaxStackSize() +end +function ItemIsArmor( inItemID, inCheckForHorseArmor ) + inCheckForHorseArmor = inCheckForHorseArmor or false + if( inItemID == E_ITEM_LEATHER_CAP ) then return true end + if( inItemID == E_ITEM_LEATHER_TUNIC ) then return true end + if( inItemID == E_ITEM_LEATHER_PANTS ) then return true end + if( inItemID == E_ITEM_LEATHER_BOOTS ) then return true end + + if( inItemID == E_ITEM_CHAIN_HELMET ) then return true end + if( inItemID == E_ITEM_CHAIN_CHESTPLATE ) then return true end + if( inItemID == E_ITEM_CHAIN_LEGGINGS ) then return true end + if( inItemID == E_ITEM_CHAIN_BOOTS ) then return true end + + if( inItemID == E_ITEM_IRON_HELMET ) then return true end + if( inItemID == E_ITEM_IRON_CHESTPLATE ) then return true end + if( inItemID == E_ITEM_IRON_LEGGINGS ) then return true end + if( inItemID == E_ITEM_IRON_BOOTS ) then return true end + + if( inItemID == E_ITEM_DIAMOND_HELMET ) then return true end + if( inItemID == E_ITEM_DIAMOND_CHESTPLATE ) then return true end + if( inItemID == E_ITEM_DIAMOND_LEGGINGS ) then return true end + if( inItemID == E_ITEM_DIAMOND_BOOTS ) then return true end + + if( inItemID == E_ITEM_GOLD_HELMET ) then return true end + if( inItemID == E_ITEM_GOLD_CHESTPLATE ) then return true end + if( inItemID == E_ITEM_GOLD_LEGGINGS ) then return true end + if( inItemID == E_ITEM_GOLD_BOOTS ) then return true end + + if( inCheckForHorseArmor ) then + if( inItemID == E_ITEM_IRON_HORSE_ARMOR ) then return true end + if( inItemID == E_ITEM_GOLD_HORSE_ARMOR ) then return true end + if( inItemID == E_ITEM_DIAMOND_HORSE_ARMOR ) then return true end + end + return false +end +-- Returns full-length playername for a short name( usefull for parsing commands ) +function GetExactPlayername( inPlayerName ) + local _result = inPlayerName + local function SetProcessingPlayername( inPlayer ) + _result = inPlayer:GetName() + end + cRoot:Get():FindAndDoWithPlayer( inPlayerName, SetProcessingPlayername ) + return _result +end +function GetPlayerByName( inPlayerName ) + local _player + local PlayerSetter = function( Player ) + _player = Player + end + cRoot:Get():FindAndDoWithPlayer( inPlayerName, PlayerSetter ) + return _player +end +--[[ +Not-so-usual math _functions +]] +-- Rounds floating point number. Because lua guys think this function doesn't deserve to be presented in lua's math +function round( inX ) + if( inX%2 ~= 0.5 ) then + return math.floor( inX + 0.5 ) + end + return inX - 0.5 +end +--[[ +Functions I use for filework and stringswork +]] +function PluralString( inValue, inSingularString, inPluralString ) + local _value_string = tostring( inValue ) + if( _value_string[#_value_string] == "1" ) then + return inSingularString + end + return inPluralString +end +function PluralItemName( inItemID, inAmount ) -- BEWARE! TEMPORAL SOLUTION THERE! :D + local _value_string = tostring( inValue ) + local _name = "" + if( _value_string[#_value_string] == "1" ) then + -- singular names + _name = ItemTypeToString( inItemID ) + else + -- plural names + _name = ItemTypeToString( inItemID ).."s" + end + return _name +end +-- for filewriting purposes. 0 = false, 1 = true +function StringToBool( inValue ) + if( inValue == "1" ) then return true end + return false +end +-- same, but reversal +function BoolToString( inValue ) + if( inValue == true ) then return 1 end + return 0 +end