text/html; charset=UTF-8
Last-Modified: Mon, 02 Nov 2026 18:20:47 GMT
Expires: Thu, 30 Oct 2036 18:20:47 GMT
staticobject.h « src - minetest.git - modified minetest for gpcfs purposes
blob: 6fb486193c9790fc2727c7283d959e808fe0107b (
plain )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
Minetest
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
#include "irrlichttypes_bloated.h"
#include <string>
#include <sstream>
#include <vector>
#include <map>
#include "debug.h"
class ServerActiveObject;
struct StaticObject
{
u8 type = 0 ;
v3f pos;
std :: string data;
StaticObject () = default ;
StaticObject ( const ServerActiveObject * s_obj, const v3f & pos_);
void serialize ( std :: ostream & os);
void deSerialize ( std :: istream & is, u8 version);
};
class StaticObjectList
{
public :
/*
Inserts an object to the container.
Id must be unique (active) or 0 (stored).
*/
void insert ( u16 id, const StaticObject & obj)
{
if ( id == 0 )
{
m_stored. push_back ( obj);
}
else
{
if ( m_active. find ( id) != m_active. end ())
{
dstream<< "ERROR: StaticObjectList::insert(): "
<< "id already exists" << std :: endl;
FATAL_ERROR ( "StaticObjectList::insert()" );
}
m_active[ id] = obj;
}
}
void remove ( u16 id)
{
assert ( id != 0 ); // Pre-condition
if ( m_active. find ( id) == m_active. end ())
{
warningstream<< "StaticObjectList::remove(): id=" << id
<< " not found" << std :: endl;
return ;
}
m_active. erase ( id);
}
void serialize ( std :: ostream & os);
void deSerialize ( std :: istream & is);
/*
NOTE: When an object is transformed to active, it is removed
from m_stored and inserted to m_active.
The caller directly manipulates these containers.
*/
std :: vector< StaticObject> m_stored;
std :: map< u16, StaticObject> m_active;
private :
};
323
324
325
326
--advtrains by orwell96
--signals.lua
local mrules_wallsignal = advtrains. meseconrules
local function can_dig_func ( pos)
if advtrains. interlocking then
return advtrains. interlocking. signal_can_dig ( pos)
end
return true
end
local function aspect ( b)
return {
main = {
free = b,
speed = - 1 ,
},
shunt = {
free = false ,
},
dst = {
free = true ,
speed = - 1 ,
},
info = {}
}
end
for r, f in pairs ({ on={ as= "off" , ls= "green" , als= "red" }, off={ as= "on" , ls= "red" , als= "green" }}) do
advtrains. trackplacer. register_tracktype ( "advtrains:retrosignal" , "" )
advtrains. trackplacer. register_tracktype ( "advtrains:signal" , "" )
for rotid, rotation in ipairs ({ "" , "_30" , "_45" , "_60" }) do
local crea= 1
if rotid== 1 and r== "off" then crea= 0 end
minetest. register_node ( "advtrains:retrosignal_" .. r.. rotation, {
drawtype = "mesh" ,
paramtype= "light" ,
paramtype2= "facedir" ,
walkable = false ,
selection_box = {
type = "fixed" ,
fixed = {- 1 / 4 , - 1 / 2 , - 1 / 4 , 1 / 4 , 2 , 1 / 4 },
},
mesh = "advtrains_retrosignal_" .. r.. rotation.. ".b3d" ,
tiles = { "advtrains_retrosignal.png" },
inventory_image= "advtrains_retrosignal_inv.png" ,
drop= "advtrains:retrosignal_off" ,
description= attrans ( "Lampless Signal (@1)" , attrans ( r.. rotation)),
sunlight_propagates= true ,
groups = {
cracky= 3 ,
not_blocking_trains= 1 ,
not_in_creative_inventory= crea,
save_in_at_nodedb= 1 ,
advtrains_signal = 2 ,
},
mesecons = { effector = {
rules= advtrains. meseconrules,
[ "action_" .. f. as] = function ( pos, node)
advtrains. ndb. swap_node ( pos, { name = "advtrains:retrosignal_" .. f. as.. rotation, param2 = node. param2}, true )
end
}},
on_rightclick= function ( pos, node, player)
local pname = player: get_player_name ()
local sigd = advtrains. interlocking and advtrains. interlocking. db. get_sigd_for_signal ( pos)
if sigd then
advtrains. interlocking. show_signalling_form ( sigd, pname)
elseif advtrains. interlocking and player: get_player_control (). aux1 then
advtrains. interlocking. show_ip_form ( pos, pname)
elseif advtrains. check_turnout_signal_protection ( pos, player: get_player_name ()) then
advtrains. ndb. swap_node ( pos, { name = "advtrains:retrosignal_" .. f. as.. rotation, param2 = node. param2}, true )
end
end ,
-- new signal API
advtrains = {
set_aspect = function ( pos, node, asp)
if asp. main. free then
advtrains. ndb. swap_node ( pos, { name = "advtrains:retrosignal_on" .. rotation, param2 = node. param2}, true )
else
advtrains. ndb. swap_node ( pos, { name = "advtrains:retrosignal_off" .. rotation, param2 = node. param2}, true )
end
end ,
get_aspect = function ( pos, node)
return aspect ( r== "on" )
end
},
can_dig = can_dig_func,
})
advtrains. trackplacer. add_worked ( "advtrains:retrosignal" , r, rotation, nil )
minetest. register_node ( "advtrains:signal_" .. r.. rotation, {
drawtype = "mesh" ,
paramtype= "light" ,
paramtype2= "facedir" ,
walkable = false ,
selection_box = {
type = "fixed" ,
fixed = {- 1 / 4 , - 1 / 2 , - 1 / 4 , 1 / 4 , 2 , 1 / 4 },
},
mesh = "advtrains_signal" .. rotation.. ".b3d" ,
tiles = { "advtrains_signal_" .. r.. ".png" },
inventory_image= "advtrains_signal_inv.png" ,
drop= "advtrains:signal_off" ,
description= attrans ( "Signal (@1)" , attrans ( r.. rotation)),
groups = {
cracky= 3 ,
not_blocking_trains= 1 ,
not_in_creative_inventory= crea,
save_in_at_nodedb= 1 ,
advtrains_signal = 2 ,
},
light_source = 1 ,
sunlight_propagates= true ,
mesecons = { effector = {
rules= advtrains. meseconrules,
[ "action_" .. f. as] = function ( pos, node)
advtrains. setstate ( pos, f. als, node)
end
}},
on_rightclick= function ( pos, node, player)
local pname = player: get_player_name ()
local sigd = advtrains. interlocking and advtrains. interlocking. db. get_sigd_for_signal ( pos)
if sigd then
advtrains. interlocking. show_signalling_form ( sigd, pname)
elseif advtrains. interlocking and player: get_player_control (). aux1 then
advtrains. interlocking. show_ip_form ( pos, pname)
elseif advtrains. check_turnout_signal_protection ( pos, player: get_player_name ()) then
advtrains. setstate ( pos, f. als, node)
end
end ,
-- new signal API
advtrains = {
set_aspect = function ( pos, node, asp)
if asp. main. free then
advtrains. ndb. swap_node ( pos, { name = "advtrains:signal_on" .. rotation, param2 = node. param2}, true )
else
advtrains. ndb. swap_node ( pos, { name = "advtrains:signal_off" .. rotation, param2 = node. param2}, true )
end
end ,
get_aspect = function ( pos, node)
return aspect ( r== "on" )
end ,
getstate = f. ls,
setstate = function ( pos, node, newstate)
if newstate == f. als then
advtrains. ndb. swap_node ( pos, { name = "advtrains:signal_" .. f. as.. rotation, param2 = node. param2}, true )
end
end ,
},
can_dig = can_dig_func,
})
advtrains. trackplacer. add_worked ( "advtrains:signal" , r, rotation, nil )
end
local crea= 1
if r== "off" then crea= 0 end
--tunnel signals. no rotations.
for loc, sbox in pairs ({ l={- 1 / 2 , - 1 / 2 , - 1 / 4 , 0 , 1 / 2 , 1 / 4 }, r={ 0 , - 1 / 2 , - 1 / 4 , 1 / 2 , 1 / 2 , 1 / 4 }, t={- 1 / 2 , 0 , - 1 / 4 , 1 / 2 , 1 / 2 , 1 / 4 }}) do
minetest. register_node ( "advtrains:signal_wall_" .. loc.. "_" .. r, {
drawtype = "mesh" ,
paramtype= "light" ,
paramtype2= "facedir" ,
walkable = false ,
selection_box = {
type = "fixed" ,
fixed = sbox,
},
mesh = "advtrains_signal_wall_" .. loc.. ".b3d" ,
tiles = { "advtrains_signal_wall_" .. r.. ".png" },
drop= "advtrains:signal_wall_" .. loc.. "_off" ,
description= attrans ( "Wallmounted Signal (" .. loc.. ")" ),
groups = {
cracky= 3 ,
not_blocking_trains= 1 ,
not_in_creative_inventory= crea,
save_in_at_nodedb= 1 ,
advtrains_signal = 2 ,
},
light_source = 1 ,
sunlight_propagates= true ,
mesecons = { effector = {
rules = mrules_wallsignal,
[ "action_" .. f. as] = function ( pos, node)
advtrains. setstate ( pos, f. als, node)
end
}},
on_rightclick= function ( pos, node, player)
local pname = player: get_player_name ()
local sigd = advtrains. interlocking and advtrains. interlocking. db. get_sigd_for_signal ( pos)
if sigd then
advtrains. interlocking. show_signalling_form ( sigd, pname)
elseif advtrains. interlocking and player: get_player_control (). aux1 then
advtrains. interlocking. show_ip_form ( pos, pname)
elseif advtrains. check_turnout_signal_protection ( pos, player: get_player_name ()) then
advtrains. setstate ( pos, f. als, node)
end
end ,
-- new signal API
advtrains = {
set_aspect = function ( pos, node, asp)
if asp. main. free then
advtrains. ndb. swap_node ( pos, { name = "advtrains:signal_wall_" .. loc.. "_on" , param2 = node. param2}, true )
else
advtrains. ndb. swap_node ( pos, { name = "advtrains:signal_wall_" .. loc.. "_off" , param2 = node. param2}, true )
end
end ,
get_aspect = function ( pos, node)
return aspect ( r== "on" )
end ,
getstate = f. ls,
setstate = function ( pos, node, newstate)
if newstate == f. als then
advtrains. ndb. swap_node ( pos, { name = "advtrains:signal_wall_" .. loc.. "_" .. f. as, param2 = node. param2}, true )
end
end ,
},
can_dig = can_dig_func,
})
end
end
-- level crossing
-- german version (Andrew's Cross)
minetest. register_node ( "advtrains:across_off" , {
drawtype = "mesh" ,
paramtype= "light" ,
paramtype2= "facedir" ,
walkable = false ,
selection_box = {
type = "fixed" ,
fixed = {- 1 / 4 , - 1 / 2 , - 1 / 2 , 1 / 4 , 1.5 , 0 },
},
mesh = "advtrains_across.obj" ,
tiles = { "advtrains_across.png" },
drop= "advtrains:across_off" ,
description= attrans ( "Andrew's Cross" ),
groups = {
cracky= 3 ,
not_blocking_trains= 1 ,
save_in_at_nodedb= 1 ,
not_in_creative_inventory= nil ,
},
light_source = 1 ,
sunlight_propagates= true ,
mesecons = { effector = {
rules = advtrains. meseconrules,
action_on = function ( pos, node)
advtrains. ndb. swap_node ( pos, { name = "advtrains:across_on" , param2 = node. param2}, true )
end
}},
advtrains = {
getstate = "off" ,
setstate = function ( pos, node, newstate)
if newstate == "on" then
advtrains. ndb. swap_node ( pos, { name = "advtrains:across_on" , param2 = node. param2}, true )
end
end ,
},
on_rightclick= function ( pos, node, player)
if advtrains. check_turnout_signal_protection ( pos, player: get_player_name ()) then
advtrains. ndb. swap_node ( pos, { name = "advtrains:across_on" , param2 = node. param2}, true )
end
end ,
})
minetest. register_node ( "advtrains:across_on" , {
drawtype = "mesh" ,
paramtype= "light" ,
paramtype2= "facedir" ,
walkable = false ,
selection_box = {
type = "fixed" ,
fixed = {- 1 / 4 , - 1 / 2 , - 1 / 2 , 1 / 4 , 1.5 , 0 },
},
mesh = "advtrains_across.obj" ,
tiles = {{ name= "advtrains_across_anim.png" , animation={ type = "vertical_frames" , aspect_w= 64 , aspect_h= 64 , length= 1.0 }}},
drop= "advtrains:across_off" ,
description= attrans ( "Andrew's Cross (on) (you hacker you)" ),
groups = {
cracky= 3 ,
not_blocking_trains= 1 ,
save_in_at_nodedb= 1 ,
not_in_creative_inventory= 1 ,
},
light_source = 1 ,
sunlight_propagates= true ,
mesecons = { effector = {
rules = advtrains. meseconrules,
action_off = function ( pos, node)
advtrains. ndb. swap_node ( pos, { name = "advtrains:across_off" , param2 = node. param2}, true )
end
}},
advtrains = {
getstate = "on" ,
setstate = function ( pos, node, newstate)
if newstate == "off" then
advtrains. ndb. swap_node ( pos, { name = "advtrains:across_off" , param2 = node. param2}, true )
end
end ,
},
on_rightclick= function ( pos, node, player)
if advtrains. check_turnout_signal_protection ( pos, player: get_player_name ()) then
advtrains. ndb. swap_node ( pos, { name = "advtrains:across_off" , param2 = node. param2}, true )
end
end ,
})
minetest. register_abm (
{
label = "Sound for Level Crossing" ,
nodenames = { "advtrains:across_on" },
interval = 3 ,
chance = 1 ,
action = function ( pos, node, active_object_count, active_object_count_wider)
minetest. sound_play ( "advtrains_crossing_bell" , {
pos = pos,
gain = 1.0 , -- default
max_hear_distance = 16 , -- default, uses an euclidean metric
})
end ,
}
)