Questions about generating items in Lua

Now I know how to use lua to define a use action function, and what I want to do next is to generate items dynamically in lua, is that possible?

The first thing I thought is artifacts. They are generated dynamically in game instead of parsing json data. What I want to achieve is to generate different weapons, randomlizing their size, weight, damage, material and other attributes. But I don’t know how to do it in lua or even if it is possible… Is it about wrapping (artifact) class variables/functions? Or should I generate a json obj in lua dynamically and parse it into an item?

Any help would be appreciated. Thanks!

Creating items of brand new item type is most likely not possible (item definitions are stored in memory on game start/load and won’t be changed after that), but you can create instance of items of existing known item types via lua. Also you can change some of the item parameters and you can have custom vars defined for any item (get_var and set_var functions - see \lua\class_definitions.lua).

Adding items to player:

local item_id = "bat"
local item_ref = item(item_id, 1)

player:i_add(item_ref)

local item_id2 = "bat"
local item_ref2 = item(item_id2, 1)

local custom_var_for_item2_value_set = "Name of this bat is: SUPER BAT +2"
item_ref2:set_var("custom_var_for_item2", custom_var_for_item2_value_set)

player:i_add(item_ref2)

local custom_var_for_item2_value_got = item_ref2:get_var("custom_var_for_item2")
game.add_msg(custom_var_for_item2_value_got)

Function to add items (possibly in container):

function add_item(item_id, item_quantity, container_id)

  if (item_quantity > 0) then

    item_quantity = math.floor(item_quantity)

    local LIQUID = enums.phase_id["LIQUID"]
    local item_ref = item(item_id, 1)
    local item_type = item_ref.type
    local item_type_phase = item_type.phase
    local item_default_container_id = item_type.default_container
	
	local cont = item(item_default_container_id, 1)

    container_id = container_id or item_default_container_id

    if (container_id == "can_drink") then -- TODO: bugged container
      container_id = "bottle_plastic"
    end

    if (item_type_phase == LIQUID) then -- TODO: bugged container
      container_id = nil
    end
    
    if (container_id == nil or item_default_container_id == "null") then
      
      item_ref = item(item_id, item_quantity)
      player:i_add(item_ref)
    
    else

      local container = item(container_id, 1)

      for i = 1, item_quantity do

        item_ref = item(item_id, 1)
        container:fill_with(item_ref)

        if (container:get_remaining_capacity_for_liquid(item_ref, false) == 0 or container:is_container_full() or i == item_quantity) then
          player:i_add(container)
          container = item(container_id, 1)

        end

      end
    
    end
  
  end

end

Iterating through items in a map tiles:

  local ScanRadius = 10

  local center = player:pos()

  for x = -ScanRadius, ScanRadius do
    for y = -ScanRadius, ScanRadius do
      local z = 0 --only current Z-level

      local point = tripoint (center.x + x, center.y + y, center.z + z)
      local distance = game.trig_dist(point.x, point.y, center.x, center.y)

      if (distance <= ScanRadius) then
        if map:i_at(point):size() > 0 then
          local item_stack_iterator =  map:i_at(point):cppbegin()
          for _ = 1, map:i_at(point):size() do
            some_lua_function(item_stack_iterator:elem(), point.x, point.y, point.z)
            item_stack_iterator:inc()
          end
        end
      end

    end
  end
1 Like