teleports now work like portals :D
This commit is contained in:
parent
cc66191422
commit
d7e859a49e
@ -1406,6 +1406,10 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||
f32 pitch = readF1000(is);
|
||||
f32 yaw = readF1000(is);
|
||||
player->setPosition(pos);
|
||||
if(datasize > 22){
|
||||
v3f speed = readV3F1000(is);
|
||||
player->setSpeed(speed);
|
||||
}
|
||||
/*player->setPitch(pitch);
|
||||
player->setYaw(yaw);*/
|
||||
|
||||
|
@ -309,6 +309,12 @@ public:
|
||||
return &m_env;
|
||||
}
|
||||
|
||||
//j
|
||||
void forceSendPlayerPos()
|
||||
{
|
||||
m_playerpos_send_timer = 10000.f;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Virtual methods from con::PeerHandler
|
||||
|
@ -155,6 +155,7 @@ enum ToClientCommand
|
||||
v3f1000 player position
|
||||
f1000 player pitch
|
||||
f1000 player yaw
|
||||
v3f1000 player speed [optional]
|
||||
*/
|
||||
|
||||
TOCLIENT_ACCESS_DENIED = 0x35,
|
||||
|
30
src/game.cpp
30
src/game.cpp
@ -1633,7 +1633,8 @@ void the_game(
|
||||
|
||||
//TimeTaker //timer2("//timer2");
|
||||
|
||||
LocalPlayer* player = client.getLocalPlayer();
|
||||
LocalPlayer* player = client.getEnv()->getLocalPlayer();
|
||||
Map * map = &client.getEnv()->getMap();
|
||||
camera.update(player, busytime, screensize);
|
||||
camera.step(dtime);
|
||||
|
||||
@ -1735,7 +1736,7 @@ void the_game(
|
||||
/*
|
||||
Find out which node we are pointing at
|
||||
*/
|
||||
|
||||
|
||||
bool nodefound = false;
|
||||
v3s16 nodepos;
|
||||
v3s16 neighbourpos;
|
||||
@ -1756,8 +1757,6 @@ void the_game(
|
||||
}
|
||||
} else {
|
||||
//j
|
||||
Player* player = client.getEnv()->getLocalPlayer();
|
||||
Map * map = &client.getEnv()->getMap();
|
||||
ClansManager* clansManager = &client.getEnv()->clansManager;
|
||||
MapBlock* block = map->getBlockNoCreateNoEx(getNodeBlockPos(nodepos));
|
||||
MapBlock* block2 = map->getBlockNoCreateNoEx(getNodeBlockPos(neighbourpos));
|
||||
@ -1831,14 +1830,16 @@ void the_game(
|
||||
}
|
||||
else
|
||||
if(content == CONTENT_BORDERSTONE)
|
||||
{ char ts[50];
|
||||
v3s16 tp=getContainerPos(nodepos,MAP_BLOCKSIZE);
|
||||
tp*=MAP_BLOCKSIZE;
|
||||
snprintf(ts, 50, "Protected area: %i<=X<%i, %i<=Y<%i, %i<=Z<%i",
|
||||
tp.X,tp.X+MAP_BLOCKSIZE,
|
||||
tp.Y,tp.Y+MAP_BLOCKSIZE,
|
||||
tp.Z,tp.Z+MAP_BLOCKSIZE);
|
||||
infotext=narrow_to_wide(ts).c_str();
|
||||
{
|
||||
v3s16 tp = getContainerPos(nodepos,MAP_BLOCKSIZE) * MAP_BLOCKSIZE;
|
||||
|
||||
std::wostringstream ts;
|
||||
ts << L"Protected area: "
|
||||
<< L"X [" << tp.X << L":" << tp.X+MAP_BLOCKSIZE-1 << L"], "
|
||||
<< L"Y [" << tp.Y << L":" << tp.Y+MAP_BLOCKSIZE-1 << L"], "
|
||||
<< L"Z [" << tp.Z << L":" << tp.Z+MAP_BLOCKSIZE-1 << L"]";
|
||||
|
||||
infotext = ts.str();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2068,6 +2069,11 @@ void the_game(
|
||||
input->resetLeftReleased();
|
||||
input->resetRightReleased();
|
||||
|
||||
v3s16 standPos = floatToInt(player_position - v3f(0,BS/2,0), BS);
|
||||
MapNode standNode = map->getNodeNoEx(standPos);
|
||||
if(standNode.getContent() == CONTENT_TELEPORT)
|
||||
client.forceSendPlayerPos();
|
||||
|
||||
/*
|
||||
Calculate stuff for drawing
|
||||
*/
|
||||
|
@ -850,6 +850,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
|
||||
Check if standing on a teleport
|
||||
TODO: should it be at the beginning or at the end of this func?
|
||||
*/
|
||||
////j
|
||||
//v3s16 standPos = floatToInt(position - v3f(0,BS/2,0), BS);
|
||||
//MapNode standNode = map.getNodeNoEx(standPos);
|
||||
//if(standNode.getContent() == CONTENT_TELEPORT){
|
||||
|
176
src/server.cpp
176
src/server.cpp
@ -1817,18 +1817,19 @@ void Server::Receive()
|
||||
}
|
||||
|
||||
//TODO: move this to some map class?
|
||||
// throws InvalidPositionException (where = that wrong position)
|
||||
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;
|
||||
// check player "foot block"
|
||||
if(m_env->getMap().getNodeNoEx(where).getContent() == CONTENT_TELEPORT)
|
||||
if(m_env->getMap().getNode(where).getContent() == CONTENT_TELEPORT)
|
||||
meta = (SignNodeMetadata*)m_env->getMap().getNodeMetadata(where);
|
||||
else {
|
||||
// check player "head block"
|
||||
where.Y++;
|
||||
if(where.Y<MAP_GENERATION_LIMIT-1)
|
||||
if(m_env->getMap().getNodeNoEx(where).getContent() == CONTENT_TELEPORT)
|
||||
if(m_env->getMap().getNode(where).getContent() == CONTENT_TELEPORT)
|
||||
meta = (SignNodeMetadata*)m_env->getMap().getNodeMetadata(where);
|
||||
}
|
||||
|
||||
@ -1851,6 +1852,88 @@ bool getTeleportTarget(/*const*/ ServerEnvironment *m_env,/*in+out*/ v3s16 &wher
|
||||
return false;
|
||||
}
|
||||
|
||||
static void getTeleportDirection(const MapNode& in, const MapNode& out, Player& player)
|
||||
{
|
||||
#if 0
|
||||
#define JLOG(x) std::cout << x << std::endl
|
||||
#define JV3(x) '[' << x.X << ',' << x.Y << ',' << x.Z << ']'
|
||||
#else
|
||||
#define JLOG(x)
|
||||
#endif
|
||||
|
||||
JLOG("---------------");
|
||||
|
||||
JLOG("old pitch: " << player.getPitch());
|
||||
JLOG("old yaw: " << player.getYaw());
|
||||
|
||||
v3s16 din = unpackDir(in.param2);
|
||||
v3s16 dout = unpackDir(out.param2);
|
||||
|
||||
JLOG("in: " << JV3(din));
|
||||
JLOG("out: " << JV3(dout));
|
||||
|
||||
v3f dinf(-din.X,-din.Y,-din.Z);
|
||||
v3f doutf(dout.X,dout.Y,dout.Z);
|
||||
|
||||
v3f speed = player.getSpeed();
|
||||
JLOG("old speed: " << JV3(speed));
|
||||
|
||||
f32 pitch = player.getPitch();
|
||||
f32 yaw = player.getYaw();
|
||||
|
||||
if(din.Y==0 && dout.Y==0){
|
||||
//both vertical (on the wall)
|
||||
v3f rotIn = dinf.getHorizontalAngle();
|
||||
v3f rotOut = doutf.getHorizontalAngle();
|
||||
|
||||
f32 rotXZ = rotOut.Y - rotIn.Y;
|
||||
|
||||
JLOG("rotIn: " << JV3(rotIn));
|
||||
JLOG("rotOut: " << JV3(rotOut));
|
||||
|
||||
yaw -= rotXZ;
|
||||
|
||||
speed.rotateXZBy(rotXZ);
|
||||
|
||||
}else if(din.Y!=0 && dout.Y!=0){
|
||||
//both horizontal (floor/roof)
|
||||
if(din.Y == dout.Y) //the same direction
|
||||
speed.Y *= -1.f;
|
||||
}else{
|
||||
//mixed directions
|
||||
f32 speedVal = speed.getLength();
|
||||
speed = -doutf * speedVal;
|
||||
|
||||
if(dout.Y==0){
|
||||
//exit vertical (on the wall)
|
||||
v3f rotOut = doutf.getHorizontalAngle();
|
||||
yaw = rotOut.Y;
|
||||
pitch = 0.f;
|
||||
/*if(dout.X!=0)
|
||||
speed.rotateXYBy(40.f);
|
||||
else
|
||||
speed.rotateYZBy(40.f);*/
|
||||
speed.Y += 40.f;
|
||||
}else if(dout.Y==1){
|
||||
//exit horizontal on the floor
|
||||
speed *= 1.5f;
|
||||
}else{
|
||||
//exit horizontal on the roof
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
player.setYaw(yaw);
|
||||
player.setPitch(pitch);
|
||||
player.setSpeed(speed);
|
||||
|
||||
JLOG("new pitch: " << pitch);
|
||||
JLOG("new yaw: " << yaw);
|
||||
JLOG("new speed: " << JV3(speed));
|
||||
|
||||
JLOG("---------------");
|
||||
}
|
||||
|
||||
void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
@ -2222,45 +2305,63 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||
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;
|
||||
v3s16 posi_temp = tele_posi;
|
||||
try{
|
||||
v3f tgtf;
|
||||
if(getTeleportTarget(&m_env,posi_temp,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;
|
||||
const MapNode entry = m_env.getMap().getNode(posi_temp); //entry teleport
|
||||
JLOG("wejscie: " << JV3(posi_temp));
|
||||
|
||||
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)
|
||||
// check: is there known and empty place to teleport to?
|
||||
posi_temp=floatToInt(tgtf, 1);
|
||||
MapNode n1,n2;
|
||||
content_t c1,c2;
|
||||
n1=m_env.getMap().getNode(posi_temp);
|
||||
c1=n1.getContent();
|
||||
posi_temp.Y++;
|
||||
n2=m_env.getMap().getNode(posi_temp);
|
||||
c2=n2.getContent();
|
||||
if((c1==CONTENT_IGNORE)||(c2==CONTENT_IGNORE))//teleporting to unknown space?
|
||||
return;
|
||||
if(content_features(c1).walkable || content_features(c2).walkable)
|
||||
return;
|
||||
}
|
||||
|
||||
dout_server << "Teleporting: " << tgtf.X << " " << tgtf.Y << " " << tgtf.Z << std::endl;
|
||||
player->setPosition(tgtf*BS);
|
||||
SendMovePlayer(player);
|
||||
} //teleport exists
|
||||
if(teleport_option > 1){
|
||||
posi_temp=floatToInt(tgtf, 1);
|
||||
bool loop=false, first=true;
|
||||
while(!loop && teleport_option>1)
|
||||
{ //check if there is teleport at primary teleport target, and it loops back.
|
||||
v3f tgtfnext;
|
||||
if(getTeleportTarget(&m_env,posi_temp,tgtfnext)){
|
||||
if(first){
|
||||
JLOG("wyjscie: " << JV3(posi_temp));
|
||||
getTeleportDirection(entry,m_env.getMap().getNode(posi_temp),*player);
|
||||
}
|
||||
posi_temp=floatToInt(tgtfnext, 1);
|
||||
loop=(tele_posi.getDistanceFrom(posi_temp)<=1); // tile away
|
||||
//actionstream<<" D:"<<tele_posi.getDistanceFrom(posi_temp)<<" from="<<"("<<tgtf.X<<","<<tgtf.Y<<","<<tgtf.Z<<")"<<
|
||||
//" to="<<"("<<tgtfnext.X<<","<<tgtfnext.Y<<","<<tgtfnext.Z<<") "<< std::endl;
|
||||
} else return; //no teleport at destination
|
||||
teleport_option--;
|
||||
first = false;
|
||||
}
|
||||
if(!loop)
|
||||
return;
|
||||
}
|
||||
|
||||
dout_server << "Teleporting: " << tgtf.X << " " << tgtf.Y << " " << tgtf.Z << std::endl;
|
||||
player->setPosition(tgtf*BS);
|
||||
SendMovePlayer(player);
|
||||
} //teleport exists
|
||||
|
||||
}catch(InvalidPositionException&){
|
||||
//std::cout << "Not existing position: " << posi_temp.X << "," << posi_temp.Y << "," << posi_temp.Z << std::endl;
|
||||
m_emerge_queue.addBlock(0,getNodeBlockPos(posi_temp),BLOCK_EMERGE_FLAG_FROMDISK);
|
||||
}
|
||||
} //teleport_option
|
||||
}
|
||||
else if(command == TOSERVER_GOTBLOCKS)
|
||||
@ -3962,6 +4063,7 @@ void Server::SendMovePlayer(Player *player)
|
||||
writeV3F1000(os, player->getPosition());
|
||||
writeF1000(os, player->getPitch());
|
||||
writeF1000(os, player->getYaw());
|
||||
writeV3F1000(os, player->getSpeed());
|
||||
|
||||
{
|
||||
v3f pos = player->getPosition();
|
||||
|
Loading…
x
Reference in New Issue
Block a user