to what else would you want to attach meta?
for reference this is the meta system from the cockpit demo, which (aside from player cockpit simulation) offer a number of new features for ships and weapons, like animated gatling turrets and missiles that shout at you. the system is self maintaining. if you try to get meta for a new object, it is created, if you try to get an object from meta that no longer exists, that meta is deleted. the cleanup cycle hunts down dead objects and deletes those every few frames. its a pretty cool little system that works.
-----------------------------------
------------meta system------------
-----------------------------------
--[[
to use this meta system just call init_meta at the start (and end) of a mission, then call get_meta_from_object on any object you want to
assign meta to. this calls the default handler for that object type and adds the default values to the object's meta.
it returns the table containing that object's meta, which may then be read or modified. if you want to get
an object handle from that meta you can also call get_object_from_meta with an objects meta array. the meta system automatically
cleans up dead meta by calling maybe_clean_meta(interval) in the frame/simulation hooks. type specific defaults may be set in
create_default_meta() after the "--breed handlers may be added after this point" line. they may be handled there or passed to other
functions. its a good idea not to handle every kind of object, only ones you require meta for, and even then you may want to only
certain objects of each type, such as all ships with a certain name. anything not added will not have any meta entry and saves
memory.
]]--
--call this at the beginning of a mission (and at the end too)
function init_meta()
--the really large metatable from hell
meta = {}
--reset the cleanup clock
clean_meta_time = 10
end
--look up meta with any object handle, if not found tries to create it, on failure returns nil otherwise meta array
function get_meta_from_object(obj)
--ba.print("Getting meta from object\n")
if obj:isValid() then
local s = obj:getSignature()
if not meta[s] then --no meta found, try to create it
meta[s] = create_default_meta(obj)
end
--maybe return it
if meta[s] then
return meta[s]
end
end
return nil
end
--look up object based on meta array, if the object is invalid then meta is deleted
--returns object handle on success, returns false on deletion, or returns nil on failure
function get_object_from_meta(met)
--ba.print("Getting object from meta\n")
if met and met.sig then
local obj = mn.getObjectFromSignature(met.sig)
if obj:isValid() then
return obj
else --object is no longer valid, no need to keep the meta in the system
meta[met.sig] = nil
return false
end
end
return nil
end
--delete dead meta, returns number remaining and number deleted (or 0,0 if nothing happens)
function clean_meta()
ba.print("Cleaning meta\n")
local deleted, scanned = 0,0
for k in pairs(meta) do
scanned = scanned + 1
local ismeta = get_object_from_meta(meta[k])
if not ismeta and ismeta == false then
deleted = deleted + 1
end
end
return scanned-deleted, deleted
end
--do meta cleanups periodically, call every frame, but will only clean if interval has passed
--dont forget to reset clean_meta_time at mission start
function maybe_clean_meta(interval)
if not interval then interval = 10 end
if mn.getMissionTime() > clean_meta_time then
local r,d = clean_meta()
ba.print("Metadata cleanup cycle, Entries remaining: "..r..", Deleted: "..d.."\n")
--set next clean time
clean_meta_time = clean_meta_time + interval
end
end
--generic meta create, create meta lookup info, and calls the proper defaults function
function create_default_meta(obj)
local s = obj:getSignature()
ba.print("Creating default meta for object with sig: "..tostring(s).."\n")
meta[s] = {}
meta[s].sig = s
meta[s].breed = obj:getBreedName()
--breed handlers may be added after this point
if meta[s].breed == "Ship" then
if create_default_ship_meta(meta[s], obj) then
return meta[s]
end
elseif meta[s].breed == "Weapon" then
if create_default_wep_meta(meta[s], obj) then
return meta[s]
end
end
--breed not handled, clear the meta and return the nil
ba.print("No defaults handled for this object\n")
return meta[s]
end
--type specific default functions, returns true if defaults loaded, false otherwise
--creates weapon meta
function create_default_wep_meta(met, wep)
ba.print("Creating default weapon meta for: "..wep.Class.Name.."\n")
local winfo = drones_tbl.drone_info[wep.Class.Name]
--only apply meta to weapons that have special drone features
if winfo then
--all weapon defaults
--set missile orientation to match ship's
wep.Orientation = wep.Parent.Orientation
--does it belong to player
met.is_player = (wep.Parent == hv.Player)
--drone infofotable link
met.info = winfo
--control information
met.speed_p = 0 --desired turn rates (-1..1)
met.speed_b = 0
met.speed_h = 0
--the place where the missile wants to be
met.lpos = wep.Position + wep.Orientation:unrotateVector(ba.createVector(0,0,wep.Class.Range))
--ucav only fields
if winfo.type == "ucav" then
--drone weapon class
met.weapon = tb.WeaponClasses[winfo.weapon]
--ammo remaining
met.ammo = winfo.ammo
--last firing
met.lastfire = 0
--current fire point
met.curpoint = 1
--control info
met.speed_t = 1 --forward speed (0..1)
--fire weapon
met.trigger = false
elseif winfo.type == "multitarget" then
--name of target ship
met.tname = ""
--stuf would normally go here, if it existed
elseif winfo.type == "lgb" then
--last laser position found
met.last_laser_fix = ba.createVector()
--last time laser was updated
met.last_laser_fix_time = -1
end
return true
end
--no data stored
return false
end
--creates ship and subsysem meta
function create_default_ship_meta(met, shp)
ba.print("Creating default ship meta for: "..shp.Class.Name.."\n")
local class = cockpits_tbl.shipinfo[shp.Class.Name]
if class then
ba.print("Can has special features?\n")
if class.targeting_laser then
ba.print("Can has targeting laser!\n")
--last reported dot position
met.laser_spot_pos = ba.createVector()
--last time stamp at which laser was good
met.laser_spot_time = -1
end
if class.multi_targeting then
ba.print("Can has multi targeting!\n")
met.lock_list = {}
met.lock_list_names = {}
end
if class.turrets then
ba.print("Can has advanced turrets!\n")
--turrets
met.turrets = {}
for i = 1, #class.turrets do
if class.turrets[i] and class.turrets[i].gatling_subsystem and shp[class.turrets[i].gatling_subsystem]:isValid() then
--all ship defaults
met.turrets[class.turrets[i].index_name] = {}
--gun physics
met.turrets[class.turrets[i].index_name].gat_cur_ang = 0
met.turrets[class.turrets[i].index_name].gat_old_ang = 0
met.turrets[class.turrets[i].index_name].gat_cur_rps = 0
--heat level
met.turrets[class.turrets[i].index_name].gun_heat = 0
--ai burst timestamps
met.turrets[class.turrets[i].index_name].burst_start = 0
met.turrets[class.turrets[i].index_name].next_burst = 0
--toggle between ai and player operation
met.turrets[class.turrets[i].index_name].use_ai = true
--player fire command
met.turrets[class.turrets[i].index_name].fire = false
--last used angles (for smooth transition between ai and player operation)
met.turrets[class.turrets[i].index_name].last_base_angle = 0
met.turrets[class.turrets[i].index_name].last_barrel_angle = 0
end
end
end
return true
end
return false
end
last 2 functions are changed to suit the needs of your script, in this case it loads a bunch of data from tables parsed by my table parser. while im only handling ships and weapons here, i could also apply meta to any other object class derivative, as they are needed. if you tried to get meta on object like an asteroid it would still create a blank meta table for that object (with its breed and signature as elements). if you wanted to do anything with that meta, well you might want to create a default handler for that.