aboutsummaryrefslogtreecommitdiff
path: root/src/script/cpp_api
ModeNameSize
-rw-r--r--CMakeLists.txt414logplain
-rw-r--r--s_base.cpp6726logplain
-rw-r--r--s_base.h4724logplain
-rw-r--r--s_entity.cpp7459logplain
-rw-r--r--s_entity.h1542logplain
-rw-r--r--s_env.cpp4504logplain
-rw-r--r--s_env.h1312logplain
-rw-r--r--s_inventory.cpp7112logplain
-rw-r--r--s_inventory.h2342logplain
-rw-r--r--s_item.cpp4404logplain
-rw-r--r--s_item.h1558logplain
-rw-r--r--s_node.cpp5845logplain
-rw-r--r--s_node.h1870logplain
-rw-r--r--s_nodemeta.cpp7234logplain
-rw-r--r--s_nodemeta.h2220logplain
-rw-r--r--s_player.cpp3335logplain
-rw-r--r--s_player.h1372logplain
-rw-r--r--scriptapi.cpp7476logplain
-rw-r--r--scriptapi.h2427logplain
n> train_id, old_val, (0 when entry did not exist before) new_val, (0 when entry was deleted) } --------------------- It turned out that, especially for the TSS, some more, even overlapping zones are required. Packing those into a data structure would just become a huge mess! Instead, this occupation system will store the path indices of positions in the corresponding. train's paths. So, the occupation is a reverse lookup of paths. Then, a callback system will handle changes in those indices, as follows: Whenever the train generates new path items (path_get/path_create), their counterpart indices will be filled in here. Whenever a path gets invalidated or path items are deleted, their index counterpart is erased from here. When a train needs to know whether a position is blocked by another train, it will (and is permitted to) query the train.index and train.end_index and compare them to the blocked position's index. Callback system for 3rd-party path checkers: advtrains.te_register_on_new_path(func(id, train)) -- Called when a train's path is re-initalized, either when it was invalidated -- or the saves were just loaded -- It can be assumed that everything is in the state of when the last run -- of on_update was made, but all indices are shifted by an unknown amount. advtrains.te_register_on_update(func(id, train)) -- Called each step and after a train moved, its length changed or some other event occured -- The path is unmodified, and train.index and train.end_index can be reliably -- queried for the new position and length of the train. -- note that this function might be called multiple times per step, and this -- function being called does not necessarily mean that something has changed. -- It is ensured that on_new_path callbacks are executed prior to these callbacks whenever -- an invalidation or a reload occured. advtrains.te_register_on_create(func(id, train)) -- Called right after a train is created, right after the initial new_path callback advtrains.te_register_on_remove(func(id, train)) -- Called right before a train is deleted All callbacks are allowed to save certain values inside the train table, but they must ensure that those are reinitialized in the on_new_path callback. The on_new_path callback must explicitly set ALL OF those values to nil or to a new updated value, and must not rely on their existence. ]]-- local o = {} local occ = {} local occ_chg = {} local function occget(p) local t = occ[p.y] if not t then occ[p.y] = {} t = occ[p.y] end local s = t t = t[p.x] if not t then s[p.x] = {} t = s[p.x] end return t[p.z] end local function occgetcreate(p) local t = occ[p.y] if not t then occ[p.y] = {} t = occ[p.y] end local s = t t = t[p.x] if not t then s[p.x] = {} t = s[p.x] end s = t t = t[p.z] if not t then s[p.z] = {} t = s[p.z] end return t end function o.set_item(train_id, pos, idx) local t = occgetcreate(pos) local i = 1 while t[i] do if t[i]==train_id then break end i = i + 2 end t[i] = train_id t[i+1] = idx end function o.clear_item(train_id, pos) local t = occget(pos) if not t then return end local i = 1 local moving = false while t[i] do if t[i]==train_id then if moving then -- if, for some occasion, there should be a duplicate entry, erase this one too atwarn("Duplicate occupation entry at",pos,"for train",train_id,":",t) i = i - 2 end moving = true end if moving then t[i] = t[i+2] t[i+1] = t[i+3] end i = i + 2 end end -- Checks whether some other train (apart from train_id) has it's 0 zone here function o.check_collision(pos, train_id) local npos = advtrains.round_vector_floor_y(pos) local t = occget(npos) if not t then return end local i = 1 while t[i] do local ti = t[i] if ti~=train_id then local idx = t[i+1] local train = advtrains.trains[ti] --atdebug("checking train",t[i],"index",idx,"<>",train.index,train.end_index) if idx >= train.end_index and idx <= train.index then --atdebug("collides.") return true end end i = i + 2 end return false end -- Gets a mapping of train id's to indexes of trains that share this path item with this train -- The train itself will not be included. -- If the requested index position is off-track, returns {}. -- returns (table with train_id->index), position function o.get_occupations(train, index) local ppos, ontrack = advtrains.path_get(train, index) if not ontrack then atwarn("Train",train.id,"get_occupations requested off-track",index) return {}, ppos end local pos = advtrains.round_vector_floor_y(ppos) local t = occget(pos) if not t then return {} end local r = {} local i = 1 local train_id = train.id while t[i] do if t[i]~=train_id then r[t[i]] = t[i+1] end i = i + 2 end return r, pos end -- Gets a mapping of train id's to indexes of trains that stand or drive over -- returns (table with train_id->index), position function o.get_trains_at(ppos) local pos = advtrains.round_vector_floor_y(ppos) local t = occget(pos) if not t then return {} end local r = {} local i = 1 while t[i] do local train = advtrains.trains[t[i]] local idx = t[i+1] if train.end_index - 0.5 <= idx and idx <= train.index + 0.5 then r[t[i]] = idx end i = i + 2 end return r end advtrains.occ = o