--[[ General stuff ]] -- Returns Handy plugin version number function GetHandyVersion() return HANDY_VERSION end -- Checks if handy is in proper version function CheckForRequiedVersion( 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