crafted_teleports, teleport pairs/loops, working "0,0,0"
This commit is contained in:
parent
73360b86cd
commit
d264de084c
@ -154,4 +154,8 @@
|
||||
# Set to true to enable experimental features or stuff that is tested
|
||||
# (varies from version to version, usually not useful at all)
|
||||
#enable_experimental = false
|
||||
# 0 - disables crafted teleports. 1 - teleport work if target area exists and there are 2 air/water (clear) tiles
|
||||
# 2 - teleport A works iff it points to clear area containing teleport B, and teleport B points back to teleport A
|
||||
# 3 or more - just like 2 but there can be 3 of more teleports in loop (warning - high value is bad for server performance)
|
||||
#crafted_teleports = 4
|
||||
|
||||
|
@ -109,5 +109,6 @@ void set_default_settings(Settings *settings)
|
||||
settings->setDefault("server_map_save_interval", "10");
|
||||
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
|
||||
settings->setDefault("enable_experimental", "false");
|
||||
settings->setDefault("crafted_teleports", "4");
|
||||
}
|
||||
|
||||
|
@ -40,13 +40,14 @@ Player::Player():
|
||||
craftresult_is_preview(true),
|
||||
hp(20),
|
||||
peer_id(PEER_ID_INEXISTENT),
|
||||
clanOwner(0),
|
||||
m_selected_item(0),
|
||||
m_pitch(0),
|
||||
m_yaw(0),
|
||||
m_speed(0,0,0),
|
||||
m_position(0,0,0),
|
||||
clanOwner(0)
|
||||
m_position(0,0,0)
|
||||
{
|
||||
lastTeleportPos.X=FLT_MAX;
|
||||
updateName("<not set>");
|
||||
resetInventory();
|
||||
}
|
||||
|
@ -171,6 +171,8 @@ public:
|
||||
std::set<int> clans;
|
||||
u16 clanOwner;
|
||||
bool canModify(const ClansManager* clansManager, Map* map, MapBlock* block, MapNode* node, v3s16* nodepos) const;
|
||||
v3f lastTeleportPos; //server: remember position player teleported to, to let him move away.
|
||||
|
||||
|
||||
protected:
|
||||
char m_name[PLAYERNAME_SIZE];
|
||||
|
104
src/server.cpp
104
src/server.cpp
@ -1816,6 +1816,38 @@ void Server::Receive()
|
||||
}
|
||||
}
|
||||
|
||||
bool getTeleportTarget(/*const*/ ServerEnvironment *m_env,/*in+out*/ v3s16 &where,/*out*/v3f &tgt)
|
||||
{
|
||||
// actionstream<<"Is Teleport at: "<<"("<<where.X<<","<<where.Y<<","<<where.Z<<") "<<std::endl;
|
||||
SignNodeMetadata* meta=NULL;
|
||||
if(m_env->getMap().getNodeNoEx(where).getContent() == CONTENT_TELEPORT)
|
||||
meta = (SignNodeMetadata*)m_env->getMap().getNodeMetadata(where);
|
||||
else {
|
||||
where.Y++;
|
||||
if(where.Y<MAP_GENERATION_LIMIT-1)
|
||||
if(m_env->getMap().getNodeNoEx(where).getContent() == CONTENT_TELEPORT)
|
||||
meta = (SignNodeMetadata*)m_env->getMap().getNodeMetadata(where);
|
||||
}
|
||||
|
||||
if(meta){
|
||||
std::string text = meta->getText();
|
||||
if(text == "")
|
||||
return false;
|
||||
str_replace_char(text,',',' ');
|
||||
std::istringstream is(text);
|
||||
is >> tgt.X >> tgt.Y >> tgt.Z;
|
||||
|
||||
if( tgt.X >= MAP_GENERATION_LIMIT || tgt.X <= -MAP_GENERATION_LIMIT ||
|
||||
tgt.Y >= MAP_GENERATION_LIMIT || tgt.Y <= -MAP_GENERATION_LIMIT ||
|
||||
tgt.Z >= MAP_GENERATION_LIMIT || tgt.Z <= -MAP_GENERATION_LIMIT ||
|
||||
( tgt.X == 0 && tgt.Y == 0 && tgt.Z == 0 && text.substr(0,5) != "0 0 0" )
|
||||
) return false;
|
||||
// actionstream<<"It points to: "<<"("<<tgt.X<<","<<tgt.Y<<","<<tgt.Z<<") "<<std::endl;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
@ -2174,30 +2206,58 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||
<<"("<<position.X<<","<<position.Y<<","<<position.Z<<")"
|
||||
<<" pitch="<<pitch<<" yaw="<<yaw<<std::endl;*/
|
||||
|
||||
//j
|
||||
v3s16 pos = floatToInt(position, BS);
|
||||
MapNode n = m_env.getMap().getNodeNoEx(pos);
|
||||
if(n.getContent() == CONTENT_TELEPORT){
|
||||
SignNodeMetadata* meta = (SignNodeMetadata*)m_env.getMap().getNodeMetadata(pos);
|
||||
if(meta){
|
||||
v3f t;
|
||||
std::string text = meta->getText();
|
||||
str_replace_char(text,',',' ');
|
||||
std::istringstream is(text);
|
||||
is >> t.X >> t.Y >> t.Z;
|
||||
//j,placki
|
||||
int teleport_option=g_settings->getU16("crafted_teleports");
|
||||
if(teleport_option) {
|
||||
v3s16 tele_posi = floatToInt(position, BS);
|
||||
|
||||
//TODO: map limits!
|
||||
if( t.X > 32000 || t.X < -32000 ||
|
||||
t.Y > 32000 || t.Y < -32000 ||
|
||||
t.Z > 32000 || t.Z < -32000 ||
|
||||
(t.X == 0 && t.Y == 0 && t.Z == 0)
|
||||
) return;
|
||||
|
||||
dout_server << "Teleporting: " << text << std::endl;
|
||||
player->setPosition(t*BS);
|
||||
SendMovePlayer(player);
|
||||
if(player->lastTeleportPos.X != FLT_MAX){
|
||||
if(player->getPosition().getDistanceFrom(player->lastTeleportPos) <= BS*3/2) //1 tile away
|
||||
return; //allow player to leave teleport destination
|
||||
else
|
||||
player->lastTeleportPos.X=FLT_MAX; //player left previous teleport destination
|
||||
}
|
||||
}
|
||||
|
||||
v3f tgtf;
|
||||
if(getTeleportTarget(&m_env,tele_posi,tgtf)){
|
||||
if(player->lastTeleportPos == tgtf*BS)
|
||||
return; //already checked... and failed, so skip checks.
|
||||
player->lastTeleportPos=tgtf*BS;
|
||||
|
||||
// check: is there known and empty place to teleport to?
|
||||
v3s16 tgti=floatToInt(tgtf, 1);
|
||||
content_t c1,c2;
|
||||
c1=m_env.getMap().getNodeNoEx(tgti).getContent();
|
||||
tgti.Y++;
|
||||
c2=m_env.getMap().getNodeNoEx(tgti).getContent();
|
||||
if((c1==CONTENT_IGNORE)||(c2==CONTENT_IGNORE)) //teleporting to unknown space?
|
||||
return;
|
||||
if(content_features(c1).walkable || content_features(c2).walkable)
|
||||
return;
|
||||
|
||||
if(teleport_option > 1){
|
||||
tgti=floatToInt(tgtf, 1);
|
||||
bool loop=false;
|
||||
while(!loop && teleport_option>1)
|
||||
{ //check if there is teleport at primary teleport target, and it loops back.
|
||||
v3f tgtfnext;
|
||||
if(getTeleportTarget(&m_env,tgti,tgtfnext)){
|
||||
tgti=floatToInt(tgtfnext, 1);
|
||||
loop=(tele_posi.getDistanceFrom(tgti)<=1); // tile away
|
||||
//actionstream<<" D:"<<tele_posi.getDistanceFrom(tgti)<<" from="<<"("<<tgtf.X<<","<<tgtf.Y<<","<<tgtf.Z<<")"<<
|
||||
//" to="<<"("<<tgtfnext.X<<","<<tgtfnext.Y<<","<<tgtfnext.Z<<") "<< std::endl;
|
||||
} else return; //no teleport at destination
|
||||
teleport_option--;
|
||||
}
|
||||
if(!loop)
|
||||
return;
|
||||
}
|
||||
|
||||
dout_server << "Teleporting: " << tgtf.X << " " << tgtf.Y << " " << tgtf.Z << std::endl;
|
||||
player->setPosition(tgtf*BS);
|
||||
SendMovePlayer(player);
|
||||
} //teleport exists
|
||||
} //teleport_option
|
||||
}
|
||||
else if(command == TOSERVER_GOTBLOCKS)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user