diff --git a/src/client.cpp b/src/client.cpp index fddd400..e2f9873 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -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);*/ diff --git a/src/client.h b/src/client.h index 06185f9..e8663b7 100644 --- a/src/client.h +++ b/src/client.h @@ -309,6 +309,12 @@ public: return &m_env; } + //j + void forceSendPlayerPos() + { + m_playerpos_send_timer = 10000.f; + } + private: // Virtual methods from con::PeerHandler diff --git a/src/clientserver.h b/src/clientserver.h index b49f48e..9b66abb 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -155,6 +155,7 @@ enum ToClientCommand v3f1000 player position f1000 player pitch f1000 player yaw + v3f1000 player speed [optional] */ TOCLIENT_ACCESS_DENIED = 0x35, diff --git a/src/game.cpp b/src/game.cpp index 07d2700..1b2b5dc 100644 --- a/src/game.cpp +++ b/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 */ diff --git a/src/player.cpp b/src/player.cpp index b0b03c7..6dd757e 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -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){ diff --git a/src/server.cpp b/src/server.cpp index 4e65d1b..c0ab2e5 100644 --- a/src/server.cpp +++ b/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: "<<"("<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.YgetMap().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:"<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:"<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();