Jump to content

Lua code snippets


MXXIV

Recommended Posts

I decided to make list of some code snippets I have used so far. I will try to sort them but generally just use CTRL+F to find what you need.

Lua tricks

I aim to share PZ related Lua tricks. I assume here you understand what prototype inheritance is and how does OOP work in Lua. However some things can work for you well without understanding them.

Subclassing Lua "class"

In PZ files, following function is used to subclass a class:

MyClass = BaseClass:derive("MyClass")

This only works with classes defined in PZ library or classes that inherit from it.

Class constructor

Generally, constructors look like this:

function MyClass:new()
    -- Create a map and set iteself as map prototype
	local o = {}
	setmetatable(o, self)
    -- not sure or care what this is
    -- inheritance actually worked without it too
	o.__index = self
	return o
end

Overriding built-in method

Suppose you want to patch some built-in PZ method but not completely rewrite it. You can do this by saving the old function in local variable. Keep an eye on : and . difference!

 

local old_doStuff = PzOriginalCode.doStuff;
function MyMod:doStuff() 
    -- Do some stuff
    print("Doing stuff real hard");
    -- Call original function
    old_doStuff(self);
    -- Do this to preserve return value
    -- return old_doStuff(self);
end

Loop over numeric items in array

If you have array that contains enumerated list, you can loop over these. Note the difference between pairs and ipairs:

local values = {"first", "second", "third"};
for index,value in ipairs(values) do
    print(value);
end

Loop over named items in table

This comes handy when you have something indexed by item names for example. Note the difference between pairs and ipairs:

local item_type = {Axe="weapon", Berry="food", Lipstick="garbage"};
for item_name,type_name in pairs(item_type) do
    print(item_name.." is "..type_name);
end

Items

Item script files are /media/scripts/items.txt, /media/scripts/newitems.txt, media/scripts/items_radio.txt.

Get item name translation

To do this, use ScriptManager.getItemName which will return English name. Then put English name into getItemText which comes from global lua object. Whole:

getItemText(ScriptManager.getItemName("Base.Axe"));

This method is safe from null pointer errors and returns original string on failure.

Get item texture object

This will provide you with Texture object if you have item name.

local item = InventoryItemFactory.CreateItem("Base.Axe");
local texture = nil;
if item then
    texture = item:getTex();
end

Add item into inventory

Requires instance of IsoGameCharacter (eg. player), uses ItemContainer which is player's inventory:

local inv = player:getInventory()
if inv~=nil then
    inv.addItem("Base.Axe")
end

Spawn item on ground

 Requires instance of IsoGridSquare to spawn the items on:

square:AddWorldInventoryItem("Base.Axe", 0, 0, 0);

World objects

Containers, walls, trees - those are all world objects.

 

Get all world objects player has right-clicked:

 

function objectRightClicked(player, context, worldObjects, test)
  print("Objects right clicked");
  -- Not sure but it's all around production code so probably
  -- important
  if test and ISWorldObjectContextMenu.Test then
     return true
  end
  -- Pick first object in worldObjects as refference one
  local firstObject;
  for _,o in ipairs(worldObjects) do
    if not firstObject then firstObject = o; end
  end
  -- the square this object is in is the clicked square
  local square = firstObject:getSquare()
  -- and all objects on that square will be affected
  local worldObjects = square:getObjects();
  -- Loop over objects on square
  for i=0,worldObjects:size()-1 do
    local object = worldObjects:get(i);
    print("Clicked object!");
    print("      Name:"..(object:getName() or ""));
    print("    Object:"..(object:getObjectName() or ""));
    print("    Sprite:"..(object:getSpriteName() or ""));
    print("   Texture:"..(object:getTextureName() or ""));
  end
end
Events.OnFillWorldObjectContextMenu.Add(objectRightClicked);

Destroy world object:

Requires IsoObject instance:

local square = object:getSquare();
square:transmitRemoveItemFromSquare(object)
square:RemoveTileObject(object);

Put container items on ground before destroying

In case you want to destroy, for example, crate, items should be put on ground first:

local container = object:getContainer();
local square = object:getSquare();
-- If the object has container
if container~=nil then
  local items = container:getItems();
  for i=0,items:size()-1 do
    -- WARNING: this will cause item duplication if the container
    -- is not destroyed
    local item = items:get(i);
    square:AddWorldInventoryItem(item, 0, 0, 0);
  end
end
-- Destroy the object
  -- see above

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...