示例#1
0
void Client::sendChangePassword(const std::string &oldpassword,
        const std::string &newpassword)
{
	LocalPlayer *player = m_env.getLocalPlayer();
	if (player == NULL)
		return;

	std::string playername = player->getName();
	if (m_proto_ver >= 25) {
		// get into sudo mode and then send new password to server
		m_password = oldpassword;
		m_new_password = newpassword;
		startAuth(choseAuthMech(m_sudo_auth_methods));
	} else {
		std::string oldpwd = translate_password(playername, oldpassword);
		std::string newpwd = translate_password(playername, newpassword);

		NetworkPacket pkt(TOSERVER_PASSWORD_LEGACY, 2 * PASSWORD_SIZE);

		for (u8 i = 0; i < PASSWORD_SIZE; i++) {
			pkt << (u8) (i < oldpwd.length() ? oldpwd[i] : 0);
		}

		for (u8 i = 0; i < PASSWORD_SIZE; i++) {
			pkt << (u8) (i < newpwd.length() ? newpwd[i] : 0);
		}
		Send(&pkt);
	}
}
int LuaLocalPlayer::l_get_breath(lua_State *L)
{
	LocalPlayer *player = getobject(L, 1);

	lua_pushinteger(L, player->getBreath());
	return 1;
}
示例#3
0
void Client::typeChatMessage(const std::string &message)
{
	// Discard empty line
	if(message.empty())
		return;

	// Send to others
	sendChatMessage(message);

	// Show locally
	if (message[0] == '/')
	{
		m_chat_queue.push("issued command: " + message);
	}

	//freeminer display self message after recieving from server
#if MINETEST_PROTO
	else
	{
		LocalPlayer *player = m_env.getLocalPlayer();
		assert(player != NULL);
		std::string name = (player->getName());
		m_chat_queue.push(std::string() + "<" + name + "> " + message);
	}
#endif
}
int LuaLocalPlayer::l_get_velocity(lua_State *L)
{
	LocalPlayer *player = getobject(L, 1);

	push_v3f(L, player->getSpeed() / BS);
	return 1;
}
int LuaLocalPlayer::l_get_pos(lua_State *L)
{
	LocalPlayer *player = getobject(L, 1);

	push_v3f(L, player->getPosition() / BS);
	return 1;
}
int LuaLocalPlayer::l_get_name(lua_State *L)
{
	LocalPlayer *player = getobject(L, 1);

	lua_pushstring(L, player->getName());
	return 1;
}
示例#7
0
void CharSelectDialog::updatePlayerInfo()
{
    LocalPlayer *pi = mCharInfo->getEntry();

    if (pi)
    {
        mNameLabel->setCaption(strprintf(_("Name: %s"), pi->getName().c_str()));
        mLevelLabel->setCaption(strprintf(_("Level: %d"), pi->mLevel));
        mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), pi->mJobLevel));
        mMoneyLabel->setCaption(strprintf(_("Gold: %d"), pi->mGp));
        if (!mCharSelected)
        {
            mNewDelCharButton->setCaption(_("Delete"));
            mSelectButton->setEnabled(true);
        }
    }
    else
    {
        mNameLabel->setCaption(strprintf(_("Name: %s"), ""));
        mLevelLabel->setCaption(strprintf(_("Level: %d"), 0));
        mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), 0));
        mMoneyLabel->setCaption(strprintf(_("Money: %s"), ""));
        mNewDelCharButton->setCaption(_("New"));
        mSelectButton->setEnabled(false);
    }

    mBeingBox->setBeing(pi);
}
示例#8
0
文件: client.cpp 项目: EXio4/minetest
void Client::typeChatMessage(const std::wstring &message)
{
	// Discard empty line
	if (message.empty())
		return;

	// If message was ate by script API, don't send it to server
	if (m_script->on_sending_message(wide_to_utf8(message))) {
		return;
	}

	// Send to others
	sendChatMessage(message);

	// Show locally
	if (message[0] != L'/') {
		// compatibility code
		if (m_proto_ver < 29) {
			LocalPlayer *player = m_env.getLocalPlayer();
			assert(player);
			std::wstring name = narrow_to_wide(player->getName());
			pushToChatQueue(new ChatMessage(CHATMESSAGE_TYPE_NORMAL, message, name));
		}
	}
}
void Client::handleCommand_AuthAccept(NetworkPacket* pkt)
{
	deleteAuthData();

	v3f playerpos;
	*pkt >> playerpos >> m_map_seed >> m_recommended_send_interval
		>> m_sudo_auth_methods;

	playerpos -= v3f(0, BS / 2, 0);

	// Set player position
	LocalPlayer *player = m_env.getLocalPlayer();
	assert(player != NULL);
	player->setPosition(playerpos);

	infostream << "Client: received map seed: " << m_map_seed << std::endl;
	infostream << "Client: received recommended send interval "
					<< m_recommended_send_interval<<std::endl;

	// Reply to server
	std::string lang = gettext("LANG_CODE");
	if (lang == "LANG_CODE")
		lang = "";

	NetworkPacket resp_pkt(TOSERVER_INIT2, sizeof(u16) + lang.size());
	resp_pkt << lang;
	Send(&resp_pkt);

	m_state = LC_Init;
}
示例#10
0
void			InputMenu::callback(HUDuiControl* w, void* data) {
  HUDuiList* list = (HUDuiList*)w;
  std::vector<std::string> *options = &list->getList();
  std::string selectedOption = (*options)[list->getIndex()];
  switch (((const char*)data)[0]) {
    case 'J':
      BZDB.set("joystickname", selectedOption);
      getMainWindow()->initJoystick(selectedOption);
      break;
    case 'F':
      {
	LocalPlayer*   myTank = LocalPlayer::getMyTank();
	// Do we force or not?
	if (selectedOption == "Do not force") {
	  BZDB.set("allowInputChange", "1");
	} else {
	  BZDB.set("allowInputChange", "0");
	  BZDB.set("forceInputDevice", selectedOption);
	  // Set the current input device to whatever we're forced to
	  if (myTank) {
	    myTank->setInputMethod(BZDB.get("forceInputDevice"));
	  }
	}
      }
      break;
    case 'G':
      bool grabbing = (selectedOption == "yes");
      if (grabbing)
	BZDB.set("mousegrab", "true");
      else
	BZDB.set("mousegrab", "false");
      getMainWindow()->enableGrabMouse(grabbing);
      break;
  }
}
void Client::selectPlayerItem(u16 item)
{
	LocalPlayer *player = m_env.getLocalPlayer();
	assert(player != NULL);

	player->wieldItem(item);

	sendPlayerItem(item);
}
示例#12
0
bool CheckCollision(Tile tile) {
	if (localPlayer.left() <= tile.right() &&
		localPlayer.right() >= tile.left() &&
		localPlayer.top() <= tile.bottom() &&
		localPlayer.bottom() >= tile.top()) {
			return true;
	}

	return false;
}
示例#13
0
文件: client.cpp 项目: EXio4/minetest
void Client::sendPlayerPos()
{
	LocalPlayer *myplayer = m_env.getLocalPlayer();
	if (!myplayer)
		return;

	ClientMap &map = m_env.getClientMap();

	u8 camera_fov    = map.getCameraFov();
	u8 wanted_range  = map.getControl().wanted_range;

	// Save bandwidth by only updating position when something changed
	if(myplayer->last_position        == myplayer->getPosition() &&
			myplayer->last_speed        == myplayer->getSpeed()    &&
			myplayer->last_pitch        == myplayer->getPitch()    &&
			myplayer->last_yaw          == myplayer->getYaw()      &&
			myplayer->last_keyPressed   == myplayer->keyPressed    &&
			myplayer->last_camera_fov   == camera_fov              &&
			myplayer->last_wanted_range == wanted_range)
		return;

	myplayer->last_position     = myplayer->getPosition();
	myplayer->last_speed        = myplayer->getSpeed();
	myplayer->last_pitch        = myplayer->getPitch();
	myplayer->last_yaw          = myplayer->getYaw();
	myplayer->last_keyPressed   = myplayer->keyPressed;
	myplayer->last_camera_fov   = camera_fov;
	myplayer->last_wanted_range = wanted_range;

	NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4 + 1 + 1);

	writePlayerPos(myplayer, &map, &pkt);

	Send(&pkt);
}
示例#14
0
BaseLocalPlayer* getLocalPlayer(PlayerId id)
{
  LocalPlayer *myTank = LocalPlayer::getMyTank();
  if (myTank->getId() == id) return myTank;
#ifdef ROBOT
  for (int i = 0; i < numRobots; i++)
    if (robots[i]->getId() == id)
      return robots[i];
#endif
  return NULL;
}
示例#15
0
Player* lookupPlayer(PlayerId id)
{
  // check my tank first

  LocalPlayer *myTank = LocalPlayer::getMyTank();
  if (myTank->getId() == id)
    return myTank;

  if (id == ServerPlayer)
    return World::getWorld()->getWorldWeapons();

  if (id < curMaxPlayers && player[id] && player[id]->getId() == id)
    return player[id];

  // it's nobody we know about
  return NULL;
}
示例#16
0
void Client::sendPlayerPos()
{
	LocalPlayer *myplayer = m_env.getLocalPlayer();
	if(myplayer == NULL)
		return;

	ClientMap &map = m_env.getClientMap();

	u8 camera_fov    = map.getCameraFov();
	u8 wanted_range  = map.getControl().wanted_range;

	// Save bandwidth by only updating position when something changed
	if(myplayer->last_position        == myplayer->getPosition() &&
			myplayer->last_speed        == myplayer->getSpeed()    &&
			myplayer->last_pitch        == myplayer->getPitch()    &&
			myplayer->last_yaw          == myplayer->getYaw()      &&
			myplayer->last_keyPressed   == myplayer->keyPressed    &&
			myplayer->last_camera_fov   == camera_fov              &&
			myplayer->last_wanted_range == wanted_range)
		return;

	myplayer->last_position     = myplayer->getPosition();
	myplayer->last_speed        = myplayer->getSpeed();
	myplayer->last_pitch        = myplayer->getPitch();
	myplayer->last_yaw          = myplayer->getYaw();
	myplayer->last_keyPressed   = myplayer->keyPressed;
	myplayer->last_camera_fov   = camera_fov;
	myplayer->last_wanted_range = wanted_range;

	//infostream << "Sending Player Position information" << std::endl;

	u16 our_peer_id;
	{
		//MutexAutoLock lock(m_con_mutex); //bulk comment-out
		our_peer_id = m_con.GetPeerID();
	}

	// Set peer id if not set already
	if(myplayer->peer_id == PEER_ID_INEXISTENT)
		myplayer->peer_id = our_peer_id;

	assert(myplayer->peer_id == our_peer_id);

	NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4 + 1 + 1);

	writePlayerPos(myplayer, &map, &pkt);

	Send(&pkt);
}
示例#17
0
文件: client.cpp 项目: EXio4/minetest
Inventory* Client::getInventory(const InventoryLocation &loc)
{
	switch(loc.type){
	case InventoryLocation::UNDEFINED:
	{}
	break;
	case InventoryLocation::CURRENT_PLAYER:
	{
		LocalPlayer *player = m_env.getLocalPlayer();
		assert(player);
		return &player->inventory;
	}
	break;
	case InventoryLocation::PLAYER:
	{
		// Check if we are working with local player inventory
		LocalPlayer *player = m_env.getLocalPlayer();
		if (!player || strcmp(player->getName(), loc.name.c_str()) != 0)
			return NULL;
		return &player->inventory;
	}
	break;
	case InventoryLocation::NODEMETA:
	{
		NodeMetadata *meta = m_env.getMap().getNodeMetadata(loc.p);
		if(!meta)
			return NULL;
		return meta->getInventory();
	}
	break;
	case InventoryLocation::DETACHED:
	{
		if (m_detached_inventories.count(loc.name) == 0)
			return NULL;
		return m_detached_inventories[loc.name];
	}
	break;
	default:
		FATAL_ERROR("Invalid inventory location type.");
		break;
	}
	return NULL;
}
示例#18
0
void HandleCollision(Tile tile) {
	double overlapX, overlapY;
	if (localPlayer.midpoint().x > tile.midpoint().x) overlapX = tile.right() - localPlayer.left();
	else overlapX = -(localPlayer.right() - tile.left());
	if (localPlayer.midpoint().y > tile.midpoint().y) overlapY = tile.bottom() - localPlayer.top();
	else overlapY = -(localPlayer.bottom() - tile.top());

	if (overlapX != 0 && overlapY != 0) {
		if (abs(overlapY) < abs(overlapX)) {
			if (overlapY < 0) {
				if (localPlayer.velocityY > 0) {
					localPlayer.onGround = true;
					localPlayer.position.y += overlapY; localPlayer.velocityY = 0;
					if (std::find(groundTileList.begin(), groundTileList.end(), tile) == groundTileList.end()) groundTileList.push_back(tile);
				}
			}
			else {
				if (localPlayer.velocityY < 0) {
					if (CheckCollisionBottom(tile)) { localPlayer.position.y += overlapY; localPlayer.velocityY = 0; }
				}
			}
		}
		else {
			localPlayer.position.x += overlapX; localPlayer.velocityX = 0;
		}
	}
}
示例#19
0
void Client::typeChatMessage(const std::wstring &message)
{
	// Discard empty line
	if(message == L"")
		return;

	// Send to others
	sendChatMessage(message);

	// Show locally
	if (message[0] == L'/')
	{
		m_chat_queue.push((std::wstring)L"issued command: " + message);
	}
	else
	{
		LocalPlayer *player = m_env.getLocalPlayer();
		assert(player != NULL);
		std::wstring name = narrow_to_wide(player->getName());
		m_chat_queue.push((std::wstring)L"<" + name + L"> " + message);
	}
}
示例#20
0
bool CharSelectDialog::selectByName(const std::string &name)
{
    if (mCharInfo->isLocked())
        return false;

    unsigned int oldPos = mCharInfo->getPos();

    mCharInfo->select(0);
    do
    {
        LocalPlayer *player = mCharInfo->getEntry();

        if (player && player->getName() == name)
            return true;

        mCharInfo->next();
    } while (mCharInfo->getPos());

    mCharInfo->select(oldPos);

    return false;
}
示例#21
0
LocalPlayer* CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
{
    LocalPlayer *tempPlayer = new LocalPlayer;
    slot = msg.readInt8(); // character slot
    tempPlayer->setName(msg.readString());
    tempPlayer->setGender(msg.readInt8() == GENDER_MALE ? GENDER_MALE : GENDER_FEMALE);
    int hs = msg.readInt8(), hc = msg.readInt8();
    tempPlayer->setHairStyle(hs, hc);
    tempPlayer->setLevel(msg.readInt16());
    tempPlayer->setCharacterPoints(msg.readInt16());
    tempPlayer->setCorrectionPoints(msg.readInt16());
    tempPlayer->setMoney(msg.readInt32());

    for (int i = 0; i < 7; i++)
    {
        tempPlayer->setAttributeBase(i, msg.readInt8());
    }

    return tempPlayer;
}
示例#22
0
void ClientEnvironment::step(float dtime)
{
	DSTACK(__FUNCTION_NAME);

	// Get some settings
	bool free_move = g_settings.getBool("free_move");
	bool footprints = g_settings.getBool("footprints");

	// Get local player
	LocalPlayer *lplayer = getLocalPlayer();
	assert(lplayer);
	// collision info queue
	core::list<CollisionInfo> player_collisions;
	
	/*
		Get the speed the player is going
	*/
	bool is_climbing = lplayer->is_climbing;

	f32 player_speed = 0.001; // just some small value
	player_speed = lplayer->getSpeed().getLength();
	
	/*
		Maximum position increment
	*/
	//f32 position_max_increment = 0.05*BS;
	f32 position_max_increment = 0.1*BS;

	// Maximum time increment (for collision detection etc)
	// time = distance / speed
	f32 dtime_max_increment = position_max_increment / player_speed;
	
	// Maximum time increment is 10ms or lower
	if(dtime_max_increment > 0.01)
		dtime_max_increment = 0.01;
	
	// Don't allow overly huge dtime
	if(dtime > 0.5)
		dtime = 0.5;
	
	f32 dtime_downcount = dtime;

	/*
		Stuff that has a maximum time increment
	*/

	u32 loopcount = 0;
	do
	{
		loopcount++;

		f32 dtime_part;
		if(dtime_downcount > dtime_max_increment)
		{
			dtime_part = dtime_max_increment;
			dtime_downcount -= dtime_part;
		}
		else
		{
			dtime_part = dtime_downcount;
			/*
				Setting this to 0 (no -=dtime_part) disables an infinite loop
				when dtime_part is so small that dtime_downcount -= dtime_part
				does nothing
			*/
			dtime_downcount = 0;
		}
		
		/*
			Handle local player
		*/
		
		{
			v3f lplayerpos = lplayer->getPosition();
			
			// Apply physics
			if(free_move == false && is_climbing == false)
			{
				// Gravity
				v3f speed = lplayer->getSpeed();
				if(lplayer->swimming_up == false)
					speed.Y -= 9.81 * BS * dtime_part * 2;

				// Water resistance
				if(lplayer->in_water_stable || lplayer->in_water)
				{
					f32 max_down = 2.0*BS;
					if(speed.Y < -max_down) speed.Y = -max_down;

					f32 max = 2.5*BS;
					if(speed.getLength() > max)
					{
						speed = speed / speed.getLength() * max;
					}
				}

				lplayer->setSpeed(speed);
			}

			/*
				Move the lplayer.
				This also does collision detection.
			*/
			lplayer->move(dtime_part, *m_map, position_max_increment,
					&player_collisions);
		}
	}
	while(dtime_downcount > 0.001);
		
	//std::cout<<"Looped "<<loopcount<<" times."<<std::endl;

	for(core::list<CollisionInfo>::Iterator
			i = player_collisions.begin();
			i != player_collisions.end(); i++)
	{
		CollisionInfo &info = *i;
		if(info.t == COLLISION_FALL)
		{
			//f32 tolerance = BS*10; // 2 without damage
			f32 tolerance = BS*12; // 3 without damage
			f32 factor = 1;
			if(info.speed > tolerance)
			{
				f32 damage_f = (info.speed - tolerance)/BS*factor;
				u16 damage = (u16)(damage_f+0.5);
				if(lplayer->hp > damage)
					lplayer->hp -= damage;
				else
					lplayer->hp = 0;

				ClientEnvEvent event;
				event.type = CEE_PLAYER_DAMAGE;
				event.player_damage.amount = damage;
				m_client_event_queue.push_back(event);
			}
		}
	}
	
	/*
		Stuff that can be done in an arbitarily large dtime
	*/
	for(core::list<Player*>::Iterator i = m_players.begin();
			i != m_players.end(); i++)
	{
		Player *player = *i;
		v3f playerpos = player->getPosition();
		
		/*
			Handle non-local players
		*/
		if(player->isLocal() == false)
		{
			// Move
			player->move(dtime, *m_map, 100*BS);

			// Update lighting on remote players on client
			u8 light = LIGHT_MAX;
			try{
				// Get node at head
				v3s16 p = floatToInt(playerpos + v3f(0,BS+BS/2,0), BS);
				MapNode n = m_map->getNode(p);
				light = n.getLightBlend(getDayNightRatio());
			}
			catch(InvalidPositionException &e) {}
			player->updateLight(light);
		}
		
		/*
			Add footsteps to grass
		*/
		if(footprints)
		{
			// Get node that is at BS/4 under player
			v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0), BS);
			try{
				MapNode n = m_map->getNode(bottompos);
				if(n.getContent() == CONTENT_GRASS)
				{
					n.setContent(CONTENT_GRASS_FOOTSTEPS);
					m_map->setNode(bottompos, n);
					// Update mesh on client
					if(m_map->mapType() == MAPTYPE_CLIENT)
					{
						v3s16 p_blocks = getNodeBlockPos(bottompos);
						MapBlock *b = m_map->getBlockNoCreate(p_blocks);
						//b->updateMesh(getDayNightRatio());
						b->setMeshExpired(true);
					}
				}
			}
			catch(InvalidPositionException &e)
			{
			}
		}
	}
	
	/*
		Step active objects and update lighting of them
	*/
	
	for(core::map<u16, ClientActiveObject*>::Iterator
			i = m_active_objects.getIterator();
			i.atEnd()==false; i++)
	{
		ClientActiveObject* obj = i.getNode()->getValue();
		// Step object
		obj->step(dtime, this);

		if(m_active_object_light_update_interval.step(dtime, 0.21))
		{
			// Update lighting
			//u8 light = LIGHT_MAX;
			u8 light = 0;
			try{
				// Get node at head
				v3s16 p = obj->getLightPosition();
				MapNode n = m_map->getNode(p);
				light = n.getLightBlend(getDayNightRatio());
			}
			catch(InvalidPositionException &e) {}
			obj->updateLight(light);
		}
	}
}
示例#23
0
void CharServerHandler::readPlayerData(Net::MessageIn &msg,
                                       Net::Character *character,
                                       bool withColors)
{
    if (!character)
        return;

    const Token &token =
        static_cast<LoginHandler*>(Net::getLoginHandler())->getToken();

    LocalPlayer *tempPlayer = new LocalPlayer(msg.readInt32(), 0);
    tempPlayer->setGender(token.sex);

    PlayerInfoBackend &data = character->data;
    data.mAttributes[EXP] = msg.readInt32();
    data.mAttributes[MONEY] = msg.readInt32();
    data.mStats[JOB].exp = msg.readInt32();

    int temp = msg.readInt32();
    data.mStats[JOB].base = temp;
    data.mStats[JOB].mod = temp;

    int shoes = msg.readInt16();
    int gloves = msg.readInt16();
    int cape = msg.readInt16();
    int misc1 = msg.readInt16();

    msg.readInt32();                       // option
    msg.readInt32();                       // karma
    msg.readInt32();                       // manner
    msg.readInt16();                       // character points left

    data.mAttributes[HP] = msg.readInt16();
    data.mAttributes[MAX_HP] = msg.readInt16();
    data.mAttributes[MP] = msg.readInt16();
    data.mAttributes[MAX_MP] = msg.readInt16();

    msg.readInt16();                       // speed
    tempPlayer->setSubtype(msg.readInt16()); // class (used for race)
    int hairStyle = msg.readInt16();
    uint16_t weapon = msg.readInt16();  // server not used it. may be need use?
    tempPlayer->setSprite(SPRITE_WEAPON, weapon, "", 1, true);

    data.mAttributes[LEVEL] = msg.readInt16();

    msg.readInt16();                       // skill point
    int bottomClothes = msg.readInt16();
    int shield = msg.readInt16();

    int hat = msg.readInt16(); // head option top
    int topClothes = msg.readInt16();

    tempPlayer->setSprite(SPRITE_HAIR, hairStyle * -1,
        ItemDB::get(-hairStyle).getDyeColorsString(msg.readInt16()));

    int misc2 = msg.readInt16();
    tempPlayer->setName(msg.readString(24));

    character->dummy = tempPlayer;

    for (int i = 0; i < 6; i++)
        character->data.mStats[i + STR].base = msg.readInt8();

    if (withColors)
    {
        tempPlayer->setSprite(SPRITE_SHOE, shoes, "", msg.readInt8());
        tempPlayer->setSprite(SPRITE_GLOVES, gloves, "", msg.readInt8());
        tempPlayer->setSprite(SPRITE_CAPE, cape, "", msg.readInt8());
        tempPlayer->setSprite(SPRITE_MISC1, misc1, "", msg.readInt8());
        tempPlayer->setSprite(SPRITE_BOTTOMCLOTHES, bottomClothes,
            "", msg.readInt8());
        //to avoid show error (error.xml) need remove this sprite
        if (!config.getBoolValue("hideShield"))
            tempPlayer->setSprite(SPRITE_SHIELD, shield, "", msg.readInt8());
        else
            msg.readInt8();

        tempPlayer->setSprite(SPRITE_HAT, hat, "",
            msg.readInt8()); // head option top
        tempPlayer->setSprite(SPRITE_TOPCLOTHES, topClothes, "",
            msg.readInt8());
        tempPlayer->setSprite(SPRITE_MISC2, misc2, "", msg.readInt8());
        msg.skip(5);
        character->slot = msg.readInt8(); // character slot
    }
    else
    {
        tempPlayer->setSprite(SPRITE_SHOE, shoes);
        tempPlayer->setSprite(SPRITE_GLOVES, gloves);
        tempPlayer->setSprite(SPRITE_CAPE, cape);
        tempPlayer->setSprite(SPRITE_MISC1, misc1);
        tempPlayer->setSprite(SPRITE_BOTTOMCLOTHES, bottomClothes);
        //to avoid show error (error.xml) need remove this sprite
        if (!config.getBoolValue("hideShield"))
            tempPlayer->setSprite(SPRITE_SHIELD, shield);

        tempPlayer->setSprite(SPRITE_HAT, hat); // head option top
        tempPlayer->setSprite(SPRITE_TOPCLOTHES, topClothes);
        tempPlayer->setSprite(SPRITE_MISC2, misc2);
        character->slot = msg.readInt8(); // character slot
    }

    msg.readInt8();                        // unknown
}
示例#24
0
void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_control,
	const CameraOrientation &cam, const PointedThing &pointed_old, float dtime)
{
	v2u32 screensize = RenderingEngine::get_instance()->getWindowSize();

	if (m_flags.show_debug) {
		static float drawtime_avg = 0;
		drawtime_avg = drawtime_avg * 0.95 + stats.drawtime * 0.05;
		u16 fps = 1.0 / stats.dtime_jitter.avg;

		std::ostringstream os(std::ios_base::binary);
		os << std::fixed
			<< PROJECT_NAME_C " " << g_version_hash
			<< ", FPS: " << fps
			<< std::setprecision(0)
			<< ", drawtime: " << drawtime_avg << "ms"
			<< std::setprecision(1)
			<< ", dtime jitter: "
			<< (stats.dtime_jitter.max_fraction * 100.0) << "%"
			<< std::setprecision(1)
			<< ", view range: "
			<< (draw_control->range_all ? "All" : itos(draw_control->wanted_range))
			<< std::setprecision(3)
			<< ", RTT: " << client->getRTT() << "s";
		setStaticText(m_guitext, utf8_to_wide(os.str()).c_str());

		m_guitext->setRelativePosition(core::rect<s32>(5, 5, screensize.X,
			5 + g_fontengine->getTextHeight()));
	}

	// Finally set the guitext visible depending on the flag
	m_guitext->setVisible(m_flags.show_debug);

	if (m_flags.show_debug) {
		LocalPlayer *player = client->getEnv().getLocalPlayer();
		v3f player_position = player->getPosition();

		std::ostringstream os(std::ios_base::binary);
		os << std::setprecision(1) << std::fixed
			<< "pos: (" << (player_position.X / BS)
			<< ", " << (player_position.Y / BS)
			<< ", " << (player_position.Z / BS)
			<< "), yaw: " << (wrapDegrees_0_360(cam.camera_yaw)) << "° "
			<< yawToDirectionString(cam.camera_yaw)
			<< ", seed: " << ((u64)client->getMapSeed());

		if (pointed_old.type == POINTEDTHING_NODE) {
			ClientMap &map = client->getEnv().getClientMap();
			const NodeDefManager *nodedef = client->getNodeDefManager();
			MapNode n = map.getNodeNoEx(pointed_old.node_undersurface);

			if (n.getContent() != CONTENT_IGNORE && nodedef->get(n).name != "unknown") {
				os << ", pointed: " << nodedef->get(n).name
					<< ", param2: " << (u64) n.getParam2();
			}
		}

		setStaticText(m_guitext2, utf8_to_wide(os.str()).c_str());

		m_guitext2->setRelativePosition(core::rect<s32>(5,
			5 + g_fontengine->getTextHeight(), screensize.X,
			5 + g_fontengine->getTextHeight() * 2
		));
	}

	m_guitext2->setVisible(m_flags.show_debug);

	setStaticText(m_guitext_info, translate_string(m_infotext).c_str());
	m_guitext_info->setVisible(m_flags.show_hud && g_menumgr.menuCount() == 0);

	static const float statustext_time_max = 1.5f;

	if (!m_statustext.empty()) {
		m_statustext_time += dtime;

		if (m_statustext_time >= statustext_time_max) {
			clearStatusText();
			m_statustext_time = 0.0f;
		}
	}

	setStaticText(m_guitext_status, translate_string(m_statustext).c_str());
	m_guitext_status->setVisible(!m_statustext.empty());

	if (!m_statustext.empty()) {
		s32 status_width  = m_guitext_status->getTextWidth();
		s32 status_height = m_guitext_status->getTextHeight();
		s32 status_y = screensize.Y - 150;
		s32 status_x = (screensize.X - status_width) / 2;

		m_guitext_status->setRelativePosition(core::rect<s32>(status_x ,
			status_y - status_height, status_x + status_width, status_y));

		// Fade out
		video::SColor final_color = m_statustext_initial_color;
		final_color.setAlpha(0);
		video::SColor fade_color = m_statustext_initial_color.getInterpolated_quadratic(
			m_statustext_initial_color, final_color, m_statustext_time / statustext_time_max);
		m_guitext_status->setOverrideColor(fade_color);
		m_guitext_status->enableOverrideColor(true);
	}
}
示例#25
0
void CharServerHandler::readPlayerData(Net::MessageIn &msg, Net::Character *character)
{
    const Token &token =
            static_cast<LoginHandler*>(Net::getLoginHandler())->getToken();

    LocalPlayer *tempPlayer = new LocalPlayer(msg.readInt32(), 0);
    tempPlayer->setGender(token.sex);

    character->data.mAttributes[EXP] = msg.readInt32();
    character->data.mAttributes[MONEY] = msg.readInt32();
    character->data.mStats[JOB].exp = msg.readInt32();

    int temp = msg.readInt32();
    character->data.mStats[JOB].base = temp;
    character->data.mStats[JOB].mod = temp;

    tempPlayer->setSprite(SPRITE_SHOE, msg.readInt16());
    tempPlayer->setSprite(SPRITE_GLOVES, msg.readInt16());
    tempPlayer->setSprite(SPRITE_CAPE, msg.readInt16());
    tempPlayer->setSprite(SPRITE_MISC1, msg.readInt16());

    msg.readInt32();                       // option
    msg.readInt32();                       // karma
    msg.readInt32();                       // manner
    msg.skip(2);                          // unknown

    character->data.mAttributes[HP] = msg.readInt16();
    character->data.mAttributes[MAX_HP] = msg.readInt16();
    character->data.mAttributes[MP] = msg.readInt16();
    character->data.mAttributes[MAX_MP] = msg.readInt16();

    msg.readInt16();                       // speed
    tempPlayer->setSubtype(msg.readInt16()); // class (used for race)
    int hairStyle = msg.readInt16();
    Uint16 weapon = msg.readInt16();
    tempPlayer->setSprite(SPRITE_WEAPON, weapon, "", true);

    character->data.mAttributes[LEVEL] = msg.readInt16();

    msg.readInt16();                       // skill point
    tempPlayer->setSprite(SPRITE_BOTTOMCLOTHES, msg.readInt16()); // head bottom
    tempPlayer->setSprite(SPRITE_SHIELD, msg.readInt16());
    tempPlayer->setSprite(SPRITE_HAT, msg.readInt16()); // head option top
    tempPlayer->setSprite(SPRITE_TOPCLOTHES, msg.readInt16()); // head option mid
    tempPlayer->setSprite(SPRITE_HAIR, hairStyle * -1, ColorDB::get(msg.readInt16()));
    tempPlayer->setSprite(SPRITE_MISC2, msg.readInt16());
    tempPlayer->setName(msg.readString(24));

    character->dummy = tempPlayer;

    for (int i = 0; i < 6; i++)
        character->data.mStats[i + STR].base = msg.readInt8();

    character->slot = msg.readInt8(); // character slot
    msg.readInt8();                        // unknown
}
示例#26
0
文件: client.cpp 项目: EXio4/minetest
void Client::step(float dtime)
{
	// Limit a bit
	if(dtime > 2.0)
		dtime = 2.0;

	if(m_ignore_damage_timer > dtime)
		m_ignore_damage_timer -= dtime;
	else
		m_ignore_damage_timer = 0.0;

	m_animation_time += dtime;
	if(m_animation_time > 60.0)
		m_animation_time -= 60.0;

	m_time_of_day_update_timer += dtime;

	ReceiveAll();

	/*
		Packet counter
	*/
	{
		float &counter = m_packetcounter_timer;
		counter -= dtime;
		if(counter <= 0.0)
		{
			counter = 20.0;

			infostream << "Client packetcounter (" << m_packetcounter_timer
					<< "):"<<std::endl;
			m_packetcounter.print(infostream);
			m_packetcounter.clear();
		}
	}

	// UGLY hack to fix 2 second startup delay caused by non existent
	// server client startup synchronization in local server or singleplayer mode
	static bool initial_step = true;
	if (initial_step) {
		initial_step = false;
	}
	else if(m_state == LC_Created) {
		float &counter = m_connection_reinit_timer;
		counter -= dtime;
		if(counter <= 0.0) {
			counter = 2.0;

			LocalPlayer *myplayer = m_env.getLocalPlayer();
			FATAL_ERROR_IF(myplayer == NULL, "Local player not found in environment.");

			sendInit(myplayer->getName());
		}

		// Not connected, return
		return;
	}

	/*
		Do stuff if connected
	*/

	/*
		Run Map's timers and unload unused data
	*/
	const float map_timer_and_unload_dtime = 5.25;
	if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) {
		ScopeProfiler sp(g_profiler, "Client: map timer and unload");
		std::vector<v3s16> deleted_blocks;
		m_env.getMap().timerUpdate(map_timer_and_unload_dtime,
			g_settings->getFloat("client_unload_unused_data_timeout"),
			g_settings->getS32("client_mapblock_limit"),
			&deleted_blocks);

		/*
			Send info to server
			NOTE: This loop is intentionally iterated the way it is.
		*/

		std::vector<v3s16>::iterator i = deleted_blocks.begin();
		std::vector<v3s16> sendlist;
		for(;;) {
			if(sendlist.size() == 255 || i == deleted_blocks.end()) {
				if(sendlist.empty())
					break;
				/*
					[0] u16 command
					[2] u8 count
					[3] v3s16 pos_0
					[3+6] v3s16 pos_1
					...
				*/

				sendDeletedBlocks(sendlist);

				if(i == deleted_blocks.end())
					break;

				sendlist.clear();
			}

			sendlist.push_back(*i);
			++i;
		}
	}

	/*
		Send pending messages on out chat queue
	*/
	if (!m_out_chat_queue.empty() && canSendChatMessage()) {
		sendChatMessage(m_out_chat_queue.front());
		m_out_chat_queue.pop();
	}

	/*
		Handle environment
	*/
	// Control local player (0ms)
	LocalPlayer *player = m_env.getLocalPlayer();
	assert(player);
	player->applyControl(dtime, &m_env);

	// Step environment
	m_env.step(dtime);
	m_sound->step(dtime);

	/*
		Get events
	*/
	while (m_env.hasClientEnvEvents()) {
		ClientEnvEvent envEvent = m_env.getClientEnvEvent();

		if (envEvent.type == CEE_PLAYER_DAMAGE) {
			if (m_ignore_damage_timer <= 0) {
				u8 damage = envEvent.player_damage.amount;

				if (envEvent.player_damage.send_to_server)
					sendDamage(damage);

				// Add to ClientEvent queue
				ClientEvent *event = new ClientEvent();
				event->type = CE_PLAYER_DAMAGE;
				event->player_damage.amount = damage;
				m_client_event_queue.push(event);
			}
		}
	}

	/*
		Print some info
	*/
	float &counter = m_avg_rtt_timer;
	counter += dtime;
	if(counter >= 10) {
		counter = 0.0;
		// connectedAndInitialized() is true, peer exists.
		float avg_rtt = getRTT();
		infostream << "Client: avg_rtt=" << avg_rtt << std::endl;
	}

	/*
		Send player position to server
	*/
	{
		float &counter = m_playerpos_send_timer;
		counter += dtime;
		if((m_state == LC_Ready) && (counter >= m_recommended_send_interval))
		{
			counter = 0.0;
			sendPlayerPos();
		}
	}

	/*
		Replace updated meshes
	*/
	{
		int num_processed_meshes = 0;
		while (!m_mesh_update_thread.m_queue_out.empty())
		{
			num_processed_meshes++;

			MinimapMapblock *minimap_mapblock = NULL;
			bool do_mapper_update = true;

			MeshUpdateResult r = m_mesh_update_thread.m_queue_out.pop_frontNoEx();
			MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(r.p);
			if (block) {
				// Delete the old mesh
				delete block->mesh;
				block->mesh = nullptr;

				if (r.mesh) {
					minimap_mapblock = r.mesh->moveMinimapMapblock();
					if (minimap_mapblock == NULL)
						do_mapper_update = false;

					bool is_empty = true;
					for (int l = 0; l < MAX_TILE_LAYERS; l++)
						if (r.mesh->getMesh(l)->getMeshBufferCount() != 0)
							is_empty = false;

					if (is_empty)
						delete r.mesh;
					else
						// Replace with the new mesh
						block->mesh = r.mesh;
				}
			} else {
				delete r.mesh;
			}

			if (m_minimap && do_mapper_update)
				m_minimap->addBlock(r.p, minimap_mapblock);

			if (r.ack_block_to_server) {
				/*
					Acknowledge block
					[0] u8 count
					[1] v3s16 pos_0
				*/
				sendGotBlocks(r.p);
			}
		}

		if (num_processed_meshes > 0)
			g_profiler->graphAdd("num_processed_meshes", num_processed_meshes);
	}

	/*
		Load fetched media
	*/
	if (m_media_downloader && m_media_downloader->isStarted()) {
		m_media_downloader->step(this);
		if (m_media_downloader->isDone()) {
			delete m_media_downloader;
			m_media_downloader = NULL;
		}
	}

	/*
		If the server didn't update the inventory in a while, revert
		the local inventory (so the player notices the lag problem
		and knows something is wrong).
	*/
	if(m_inventory_from_server)
	{
		float interval = 10.0;
		float count_before = floor(m_inventory_from_server_age / interval);

		m_inventory_from_server_age += dtime;

		float count_after = floor(m_inventory_from_server_age / interval);

		if(count_after != count_before)
		{
			// Do this every <interval> seconds after TOCLIENT_INVENTORY
			// Reset the locally changed inventory to the authoritative inventory
			LocalPlayer *player = m_env.getLocalPlayer();
			player->inventory = *m_inventory_from_server;
			m_inventory_updated = true;
		}
	}

	/*
		Update positions of sounds attached to objects
	*/
	{
		for (auto &m_sounds_to_object : m_sounds_to_objects) {
			int client_id = m_sounds_to_object.first;
			u16 object_id = m_sounds_to_object.second;
			ClientActiveObject *cao = m_env.getActiveObject(object_id);
			if (!cao)
				continue;
			m_sound->updateSoundPosition(client_id, cao->getPosition());
		}
	}

	/*
		Handle removed remotely initiated sounds
	*/
	m_removed_sounds_check_timer += dtime;
	if(m_removed_sounds_check_timer >= 2.32) {
		m_removed_sounds_check_timer = 0;
		// Find removed sounds and clear references to them
		std::vector<s32> removed_server_ids;
		for (std::unordered_map<s32, int>::iterator i = m_sounds_server_to_client.begin();
				i != m_sounds_server_to_client.end();) {
			s32 server_id = i->first;
			int client_id = i->second;
			++i;
			if(!m_sound->soundExists(client_id)) {
				m_sounds_server_to_client.erase(server_id);
				m_sounds_client_to_server.erase(client_id);
				m_sounds_to_objects.erase(client_id);
				removed_server_ids.push_back(server_id);
			}
		}

		// Sync to server
		if(!removed_server_ids.empty()) {
			sendRemovedSounds(removed_server_ids);
		}
	}

	m_mod_storage_save_timer -= dtime;
	if (m_mod_storage_save_timer <= 0.0f) {
		verbosestream << "Saving registered mod storages." << std::endl;
		m_mod_storage_save_timer = g_settings->getFloat("server_map_save_interval");
		for (std::unordered_map<std::string, ModMetadata *>::const_iterator
				it = m_mod_storages.begin(); it != m_mod_storages.end(); ++it) {
			if (it->second->isModified()) {
				it->second->save(getModStoragePath());
			}
		}
	}

	// Write server map
	if (m_localdb && m_localdb_save_interval.step(dtime,
			m_cache_save_interval)) {
		m_localdb->endSave();
		m_localdb->beginSave();
	}
}
示例#27
0
void Client::sendPlayerPos()
{
	LocalPlayer *myplayer = m_env.getLocalPlayer();
	if(myplayer == NULL)
		return;

	// Save bandwidth by only updating position when something changed
	if(myplayer->last_position        == myplayer->getPosition() &&
			myplayer->last_speed      == myplayer->getSpeed()    &&
			myplayer->last_pitch      == myplayer->getPitch()    &&
			myplayer->last_yaw        == myplayer->getYaw()      &&
			myplayer->last_keyPressed == myplayer->keyPressed)
		return;

	myplayer->last_position   = myplayer->getPosition();
	myplayer->last_speed      = myplayer->getSpeed();
	myplayer->last_pitch      = myplayer->getPitch();
	myplayer->last_yaw        = myplayer->getYaw();
	myplayer->last_keyPressed = myplayer->keyPressed;

	u16 our_peer_id;
	{
		//MutexAutoLock lock(m_con_mutex); //bulk comment-out
		our_peer_id = m_con.GetPeerID();
	}

	// Set peer id if not set already
	if(myplayer->peer_id == PEER_ID_INEXISTENT)
		myplayer->peer_id = our_peer_id;

	assert(myplayer->peer_id == our_peer_id);

	v3f pf         = myplayer->getPosition();
	v3f sf         = myplayer->getSpeed();
	s32 pitch      = myplayer->getPitch() * 100;
	s32 yaw        = myplayer->getYaw() * 100;
	u32 keyPressed = myplayer->keyPressed;

	v3s32 position(pf.X*100, pf.Y*100, pf.Z*100);
	v3s32 speed(sf.X*100, sf.Y*100, sf.Z*100);
	/*
		Format:
		[0] v3s32 position*100
		[12] v3s32 speed*100
		[12+12] s32 pitch*100
		[12+12+4] s32 yaw*100
		[12+12+4+4] u32 keyPressed
	*/

	NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4);

	pkt << position << speed << pitch << yaw << keyPressed;

	Send(&pkt);
}
示例#28
0
void Game::dummyInit()
{
  LocalPlayer *player = new LocalPlayer(this, "Kali", Data::wizard(WizardID::KALI), GREEN, Data::race("barbarians"), 60, 40);
  LocalPlayer *player2 = new LocalPlayer(this, "Antani", Data::wizard(WizardID::MERLIN), BLUE, Data::race("barbarians"), 60, 40);

  
  Army* army2 = new Army(player2, {
    new Hero(Data::unit("hero_dwarf")->as<HeroSpec>()),
    new RaceUnit(Data::unit("barbarian_spearmen")->as<RaceUnitSpec>()),
    new FantasticUnit(Data::unit("funit_magic_spirit")->as<SummonSpec>()),
  });
  
  player2->add(army2);
  placeArmy(army2, Position(2, 2, ARCANUS));
  
  players.push_back(player);
  players.push_back(player2);
  current = players.begin();
  
  world->fill(TILE_WATER, ARCANUS);
  world->fill(TILE_WATER, MYRRAN);
  world->rect(TILE_GRASS, 3, 3, 10, 10, ARCANUS);
  world->rect(TILE_MOUNTAIN, 4, 4, 2, 2, ARCANUS);
  world->line(TILE_HILL, 4, 8, 11, true, ARCANUS);
  world->rect(TILE_GRASS, 1, 1, 6, 6, MYRRAN);
  world->line(TILE_MOUNTAIN, 6, 8, 5, false, MYRRAN);
  world->line(TILE_HILL, 5, 8, 6, true, MYRRAN);
  world->line(TILE_WATER, 2, 6, 6, true, ARCANUS);
  world->set(TILE_WATER, 4, 7, ARCANUS);
  world->set(TILE_HILL, 4,4, ARCANUS);
  world->set(TILE_DESERT, 8,8, ARCANUS);
  world->set(TILE_DESERT, 7,8, ARCANUS);
  world->set(TILE_DESERT, 9,8, ARCANUS);
  world->set(TILE_DESERT, 8,7, ARCANUS);
  world->set(TILE_DESERT, 8,9, ARCANUS);
  world->set(TILE_DESERT, 7,9, ARCANUS);
  world->set(TILE_DESERT, 9,9, ARCANUS);
  world->set(TILE_DESERT, 10,9, ARCANUS);
  
  world->get(7, 8, ARCANUS)->placeManaNode(new ManaNode(School::SORCERY, 0));
    
  //WorldGenerator.generate(world, ARCANUS);
  //WorldGenerator.generate(world, MYRRAN);

  Army* a = new Army(player, {
		new FantasticUnit(Data::unit("funit_great_drake")->as<SummonSpec>()),
    new RaceUnit(Data::unit("barbarian_spearmen")->as<RaceUnitSpec>()),
		new RaceUnit(Data::unit("barbarian_swordsmen")->as<RaceUnitSpec>()),
		new RaceUnit(Data::unit("barbarian_bowmen")->as<RaceUnitSpec>()),
		new RaceUnit(Data::unit("barbarian_cavalry")->as<RaceUnitSpec>()),
    new FantasticUnit(Data::unit("funit_great_drake")->as<SummonSpec>()),
		new RaceUnit(Data::unit("barbarian_berserkers")->as<RaceUnitSpec>()),
  });
  
  SpellCast cast = SpellCast(player, Spells::BLESS);
  a->get(0)->skills()->add(cast);
  
  //map.get(5, 5, ARCANUS).placeManaNode(mapMechanics.generateManaNode(world, 5, 5, ARCANUS));
  //this.meldNode(a, 5, 5, ARCANUS);
  //map.get(5, 6, ARCANUS).placeManaNode(new ManaNode());
  //map.get(6, 5, ARCANUS).placeManaNode(new ManaNode());
  //map.get(6, 6, ARCANUS).placeManaNode(new ManaNode());
  world->get(4, 3, ARCANUS)->placeResource(Resource::COAL);
  world->get(3, 4, ARCANUS)->placeResource(Resource::WILD_GAME);
  //map.rect(TILE_GRASS, 2, 2, 6, 3);
  //map.rect(TILE_GRASS, 8, 4, 1, 1);
  world->get(3,4,ARCANUS)->placeRoad(true);
  world->get(3,5,ARCANUS)->placeRoad(true);
  world->get(4,5,ARCANUS)->placeRoad(true);
  world->get(5,5,ARCANUS)->placeRoad(true);

  world->set(TILE_VOLCANO, 0, 0, ARCANUS);
  world->set(TILE_VOLCANO, 59, 0, ARCANUS);
  world->set(TILE_VOLCANO, 0, 39, ARCANUS);
  world->set(TILE_VOLCANO, 59, 39, ARCANUS);
  world->set(TILE_HILL, 1, 2, MYRRAN);
  
  player->fog()->setRect(0, 0, 60, 40, ARCANUS);
  player->fog()->setRect(0, 0, 60, 40, MYRRAN);
  player->setViewport(5, 5);
  
  player->book()->discoverSpell(Spells::BLESS);
  player->book()->discoverSpell(Spells::CORRUPTION);
  player->book()->discoverSpell(Spells::CHANGE_TERRAIN);
  player->book()->discoverSpell(Spells::RAISE_VOLCANO);
  player->book()->discoverSpell(Spells::GUARDIAN_SPIRIT);
  
  new LocalGame(this);
  
  placeArmy(a, Position(5, 6, ARCANUS));
  placeArmy(new Army(player, {new FantasticUnit(Data::unit("funit_magic_spirit")->as<SummonSpec>()),new FantasticUnit(Data::unit("funit_great_drake")->as<SummonSpec>())}), Position(4, 3, ARCANUS));
  placeArmy(new Army(player, {new FantasticUnit(Data::unit("funit_great_drake")->as<SummonSpec>()), new Hero(Data::unit("hero_dwarf")->as<HeroSpec>())}), Position(4, 8, ARCANUS));
  
  City* florence = new City(player, "Florence", 4000, Position(3, 3, ARCANUS));
  florence->addBuilding(Building::MAGE_FORTRESS);
  florence->addBuilding(Building::SMITHY);
  florence->addBuilding(Building::BUILDERS_HALL);
  florence->addBuilding(Building::BARRACKS);
  florence->addBuilding(Building::FIGHTERS_GUILD);
  florence->addBuilding(Building::SUMMONING_CIRCLE);
  florence->addBuilding(Building::ALCHEMISTS_GUILD);
  settleCity(florence);
  
  world->get(7,6,ARCANUS)->placePlace(new Place(PLACE_TOWER_OF_WIZARDRY, false));
  world->get(8,6,ARCANUS)->placePlace(new Place(PLACE_CAVE, false));
  
  
  world->calcSubTiles();
  world->updateRoads();
  
  init();
}
示例#29
0
void Client::step(float dtime)
{
	DSTACK(FUNCTION_NAME);

	// Limit a bit
	if(dtime > 2.0)
		dtime = 2.0;

	if(m_ignore_damage_timer > dtime)
		m_ignore_damage_timer -= dtime;
	else
		m_ignore_damage_timer = 0.0;

	m_animation_time += dtime;
	if(m_animation_time > 60.0)
		m_animation_time -= 60.0;

	m_time_of_day_update_timer += dtime;

	ReceiveAll();

	/*
		Packet counter
	*/
	{
		float &counter = m_packetcounter_timer;
		counter -= dtime;
		if(counter <= 0.0)
		{
			counter = 20.0;

			infostream << "Client packetcounter (" << m_packetcounter_timer
					<< "):"<<std::endl;
			m_packetcounter.print(infostream);
			m_packetcounter.clear();
		}
	}

	// UGLY hack to fix 2 second startup delay caused by non existent
	// server client startup synchronization in local server or singleplayer mode
	static bool initial_step = true;
	if (initial_step) {
		initial_step = false;
	}
	else if(m_state == LC_Created) {
		float &counter = m_connection_reinit_timer;
		counter -= dtime;
		if(counter <= 0.0) {
			counter = 2.0;

			Player *myplayer = m_env.getLocalPlayer();
			FATAL_ERROR_IF(myplayer == NULL, "Local player not found in environment.");

			// Send TOSERVER_INIT_LEGACY
			// [0] u16 TOSERVER_INIT_LEGACY
			// [2] u8 SER_FMT_VER_HIGHEST_READ
			// [3] u8[20] player_name
			// [23] u8[28] password (new in some version)
			// [51] u16 minimum supported network protocol version (added sometime)
			// [53] u16 maximum supported network protocol version (added later than the previous one)

			char pName[PLAYERNAME_SIZE];
			char pPassword[PASSWORD_SIZE];
			memset(pName, 0, PLAYERNAME_SIZE * sizeof(char));
			memset(pPassword, 0, PASSWORD_SIZE * sizeof(char));

			std::string hashed_password = translatePassword(myplayer->getName(), m_password);
			snprintf(pName, PLAYERNAME_SIZE, "%s", myplayer->getName());
			snprintf(pPassword, PASSWORD_SIZE, "%s", hashed_password.c_str());

			sendLegacyInit(pName, pPassword);
			if (LATEST_PROTOCOL_VERSION >= 25)
				sendInit(myplayer->getName());
		}

		// Not connected, return
		return;
	}

	/*
		Do stuff if connected
	*/

	/*
		Run Map's timers and unload unused data
	*/
	const float map_timer_and_unload_dtime = 5.25;
	if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) {
		ScopeProfiler sp(g_profiler, "Client: map timer and unload");
		std::vector<v3s16> deleted_blocks;
		m_env.getMap().timerUpdate(map_timer_and_unload_dtime,
			g_settings->getFloat("client_unload_unused_data_timeout"),
			g_settings->getS32("client_mapblock_limit"),
			&deleted_blocks);

		/*
			Send info to server
			NOTE: This loop is intentionally iterated the way it is.
		*/

		std::vector<v3s16>::iterator i = deleted_blocks.begin();
		std::vector<v3s16> sendlist;
		for(;;) {
			if(sendlist.size() == 255 || i == deleted_blocks.end()) {
				if(sendlist.empty())
					break;
				/*
					[0] u16 command
					[2] u8 count
					[3] v3s16 pos_0
					[3+6] v3s16 pos_1
					...
				*/

				sendDeletedBlocks(sendlist);

				if(i == deleted_blocks.end())
					break;

				sendlist.clear();
			}

			sendlist.push_back(*i);
			++i;
		}
	}

	/*
		Handle environment
	*/
	// Control local player (0ms)
	LocalPlayer *player = m_env.getLocalPlayer();
	assert(player != NULL);
	player->applyControl(dtime);

	// Step environment
	m_env.step(dtime);

	/*
		Get events
	*/
	for(;;) {
		ClientEnvEvent event = m_env.getClientEvent();
		if(event.type == CEE_NONE) {
			break;
		}
		else if(event.type == CEE_PLAYER_DAMAGE) {
			if(m_ignore_damage_timer <= 0) {
				u8 damage = event.player_damage.amount;

				if(event.player_damage.send_to_server)
					sendDamage(damage);

				// Add to ClientEvent queue
				ClientEvent event;
				event.type = CE_PLAYER_DAMAGE;
				event.player_damage.amount = damage;
				m_client_event_queue.push(event);
			}
		}
		else if(event.type == CEE_PLAYER_BREATH) {
				u16 breath = event.player_breath.amount;
				sendBreath(breath);
		}
	}

	/*
		Print some info
	*/
	float &counter = m_avg_rtt_timer;
	counter += dtime;
	if(counter >= 10) {
		counter = 0.0;
		// connectedAndInitialized() is true, peer exists.
		float avg_rtt = getRTT();
		infostream << "Client: avg_rtt=" << avg_rtt << std::endl;
	}

	/*
		Send player position to server
	*/
	{
		float &counter = m_playerpos_send_timer;
		counter += dtime;
		if((m_state == LC_Ready) && (counter >= m_recommended_send_interval))
		{
			counter = 0.0;
			sendPlayerPos();
		}
	}

	/*
		Replace updated meshes
	*/
	{
		int num_processed_meshes = 0;
		while (!m_mesh_update_thread.m_queue_out.empty())
		{
			num_processed_meshes++;

			MinimapMapblock *minimap_mapblock = NULL;
			bool do_mapper_update = true;

			MeshUpdateResult r = m_mesh_update_thread.m_queue_out.pop_frontNoEx();
			MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(r.p);
			if (block) {
				// Delete the old mesh
				if (block->mesh != NULL) {
					delete block->mesh;
					block->mesh = NULL;
				}

				if (r.mesh) {
					minimap_mapblock = r.mesh->moveMinimapMapblock();
					if (minimap_mapblock == NULL)
						do_mapper_update = false;
				}

				if (r.mesh && r.mesh->getMesh()->getMeshBufferCount() == 0) {
					delete r.mesh;
				} else {
					// Replace with the new mesh
					block->mesh = r.mesh;
				}
			} else {
				delete r.mesh;
			}

			if (do_mapper_update)
				m_mapper->addBlock(r.p, minimap_mapblock);

			if (r.ack_block_to_server) {
				/*
					Acknowledge block
					[0] u8 count
					[1] v3s16 pos_0
				*/
				sendGotBlocks(r.p);
			}
		}

		if (num_processed_meshes > 0)
			g_profiler->graphAdd("num_processed_meshes", num_processed_meshes);
	}

	/*
		Load fetched media
	*/
	if (m_media_downloader && m_media_downloader->isStarted()) {
		m_media_downloader->step(this);
		if (m_media_downloader->isDone()) {
			received_media();
			delete m_media_downloader;
			m_media_downloader = NULL;
		}
	}

	/*
		If the server didn't update the inventory in a while, revert
		the local inventory (so the player notices the lag problem
		and knows something is wrong).
	*/
	if(m_inventory_from_server)
	{
		float interval = 10.0;
		float count_before = floor(m_inventory_from_server_age / interval);

		m_inventory_from_server_age += dtime;

		float count_after = floor(m_inventory_from_server_age / interval);

		if(count_after != count_before)
		{
			// Do this every <interval> seconds after TOCLIENT_INVENTORY
			// Reset the locally changed inventory to the authoritative inventory
			Player *player = m_env.getLocalPlayer();
			player->inventory = *m_inventory_from_server;
			m_inventory_updated = true;
		}
	}

	/*
		Update positions of sounds attached to objects
	*/
	{
		for(std::map<int, u16>::iterator
				i = m_sounds_to_objects.begin();
				i != m_sounds_to_objects.end(); ++i)
		{
			int client_id = i->first;
			u16 object_id = i->second;
			ClientActiveObject *cao = m_env.getActiveObject(object_id);
			if(!cao)
				continue;
			v3f pos = cao->getPosition();
			m_sound->updateSoundPosition(client_id, pos);
		}
	}

	/*
		Handle removed remotely initiated sounds
	*/
	m_removed_sounds_check_timer += dtime;
	if(m_removed_sounds_check_timer >= 2.32) {
		m_removed_sounds_check_timer = 0;
		// Find removed sounds and clear references to them
		std::vector<s32> removed_server_ids;
		for(std::map<s32, int>::iterator
				i = m_sounds_server_to_client.begin();
				i != m_sounds_server_to_client.end();) {
			s32 server_id = i->first;
			int client_id = i->second;
			++i;
			if(!m_sound->soundExists(client_id)) {
				m_sounds_server_to_client.erase(server_id);
				m_sounds_client_to_server.erase(client_id);
				m_sounds_to_objects.erase(client_id);
				removed_server_ids.push_back(server_id);
			}
		}

		// Sync to server
		if(!removed_server_ids.empty()) {
			sendRemovedSounds(removed_server_ids);
		}
	}

	// Write server map
	if (m_localdb && m_localdb_save_interval.step(dtime,
			m_cache_save_interval)) {
		m_localdb->endSave();
		m_localdb->beginSave();
	}
}
示例#30
0
void			RadarRenderer::render(SceneRenderer& renderer,
							bool blank)
{
  const int ox = renderer.getWindow().getOriginX();
  const int oy = renderer.getWindow().getOriginY();
  float opacity = renderer.getPanelOpacity();

  if ((opacity < 1.0f) && (opacity > 0.0f)) {
    glScissor(ox + x - 2, oy + y - 2, w + 4, h + 4);
    glColor4f(0.0f, 0.0f, 0.0f, opacity);
    glRectf((float) x, (float) y, (float)(x + w), (float)(y + h));
  }

  glScissor(ox + x, oy + y, w, h);

  LocalPlayer *myTank = LocalPlayer::getMyTank();

  if (opacity == 1.0f)
	{
  // glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  // glClear(GL_COLOR_BUFFER_BIT);
  }

  if (blank)
    return;

  // prepare transforms
  float worldSize = BZDB.eval(StateDatabase::BZDB_WORLDSIZE);
  float range = BZDB.eval("displayRadarRange") * worldSize;
  // when burrowed, limit radar range
  if (myTank && (myTank->getFlag() == Flags::Burrow) &&
      (myTank->getPosition()[2] < 0.0f)) {
#ifdef _MSC_VER
    range = min(range, worldSize / 4.0f);
#else
    range = std::min(range, worldSize / 4.0f);
#endif
  }
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  const int xSize = renderer.getWindow().getWidth();
  const int ySize = renderer.getWindow().getHeight();
  const double xCenter = double(x) + 0.5 * double(w);
  const double yCenter = double(y) + 0.5 * double(h);
  const double xUnit = 2.0 * range / double(w);
  const double yUnit = 2.0 * range / double(h);
  glOrtho(-xCenter * xUnit, (xSize - xCenter) * xUnit, -yCenter * yUnit, (ySize - yCenter) * yUnit, -1.0, 1.0);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();
  OpenGLGState::resetState();

  TextureManager &tm = TextureManager::instance();
  int noiseTexture = tm.getTextureID( "noise" );

  // if jammed then draw white noise.  occasionally draw a good frame.
  if (jammed && bzfrand() > decay)
	{

    glColor3f(1.0,1.0,1.0);

    if (noiseTexture >= 0 && renderer.useQuality() > 0)
		{
      const int sequences = 10;

      static float np[] = { 0, 0, 1, 1,
														1, 1, 0, 0,
														0.5f, 0.5f, 1.5f, 1.5f,
														1.5f, 1.5f, 0.5f, 0.5f,
														0.25f, 0.25f, 1.25f, 1.25f,
														1.25f, 1.25f, 0.25f, 0.25f,
														0, 0.5f, 1, 1.5f,
														1, 1.5f, 0, 0.5f,
														0.5f, 0, 1.5f, 1,
														1.4f, 1, 0.5f, 0,
														0.75f, 0.75f, 1.75f, 1.75f,
														1.75f, 1.75f, 0.75f, 0.75f,
													};
      int noisePattern = 4 * int(floor(sequences * bzfrand()));

      glEnable(GL_TEXTURE_2D);
      tm.bind(noiseTexture);

      glBegin(GL_QUADS);
				glTexCoord2f(np[noisePattern+0],np[noisePattern+1]);
				glVertex2f(-range,-range);
				glTexCoord2f(np[noisePattern+2],np[noisePattern+1]);
				glVertex2f( range,-range);
				glTexCoord2f(np[noisePattern+2],np[noisePattern+3]);
				glVertex2f( range, range);
				glTexCoord2f(np[noisePattern+0],np[noisePattern+3]);
				glVertex2f(-range, range);
      glEnd();
      glDisable(GL_TEXTURE_2D);
    }
    else if (noiseTexture >= 0 && BZDBCache::texture && renderer.useQuality() == 0)
		{
      glEnable(GL_TEXTURE_2D);
      tm.bind(noiseTexture);

      glBegin(GL_QUADS);
				glTexCoord2f(0,0);
				glVertex2f(-range,-range);
				glTexCoord2f(1,0);
				glVertex2f( range,-range);
				glTexCoord2f(1,1);
				glVertex2f( range, range);
				glTexCoord2f(0,1);
				glVertex2f(-range, range);
      glEnd();

      glDisable(GL_TEXTURE_2D);
    }
    if (decay > 0.015f)
			decay *= 0.5f;
  }
	else if (myTank)  // only draw if there's a local player
	{
    // if decay is sufficiently small then boost it so it's more
    // likely a jammed radar will get a few good frames closely
    // spaced in time.  value of 1 guarantees at least two good
    // frames in a row.
    if (decay <= 0.015f)
			decay = 1.0f;
    else
			decay *= 0.5f;

    // get size of pixel in model space (assumes radar is square)
    ps = 2.0f * range / GLfloat(w);

    // relative to my tank
    const LocalPlayer* myTank = LocalPlayer::getMyTank();
    const float* pos = myTank->getPosition();
    float angle = myTank->getAngle();

    // draw the view angle blewow stuff
    // view frustum edges
    glColor3f(1.0f, 0.625f, 0.125f);
    const float fovx = renderer.getViewFrustum().getFOVx();
    const float viewWidth = range * tanf(0.5f * fovx);
    glBegin(GL_LINE_STRIP);
			glVertex2f(-viewWidth, range);
			glVertex2f(0.0f, 0.0f);
			glVertex2f(viewWidth, range);
    glEnd();

    glPushMatrix();
    glRotatef(90.0f - angle * 180.0f / M_PI, 0.0f, 0.0f, 1.0f);
    glPushMatrix();
    glTranslatef(-pos[0], -pos[1], 0.0f);

    // Redraw buildings
    makeList( renderer);

    // draw my shots
    int maxShots = world.getMaxShots();
    int i;
    float muzzleHeight = BZDB.eval(StateDatabase::BZDB_MUZZLEHEIGHT);
    for (i = 0; i < maxShots; i++)
		{
      const ShotPath* shot = myTank->getShot(i);
      if (shot)
			{
				const float cs = colorScale(shot->getPosition()[2], muzzleHeight, BZDBCache::enhancedRadar);
				glColor3f(1.0f * cs, 1.0f * cs, 1.0f * cs);
				shot->radarRender();
			}
    }

    //draw world weapon shots
    WorldPlayer *worldWeapons = World::getWorld()->getWorldWeapons();
    maxShots = worldWeapons->getMaxShots();
    for (i = 0; i < maxShots; i++)
		{
      const ShotPath* shot = worldWeapons->getShot(i);
      if (shot)
			{
				const float cs = colorScale(shot->getPosition()[2],	muzzleHeight, BZDBCache::enhancedRadar);
				glColor3f(1.0f * cs, 1.0f * cs, 1.0f * cs);
				shot->radarRender();
      }
    }


    // draw other tanks (and any flags on them)
    // note about flag drawing.  each line segment is drawn twice
    // (once in each direction);  this degrades the antialiasing
    // but on systems that don't do correct filtering of endpoints
    // not doing it makes (half) the endpoints jump wildly.
    const int curMaxPlayers = world.getCurMaxPlayers();
    for (i = 0; i < curMaxPlayers; i++) {
      RemotePlayer* player = world.getPlayer(i);
      if (!player || !player->isAlive() || ((player->getFlag() == Flags::Stealth) &&
					    (myTank->getFlag() != Flags::Seer)))
	continue;

      GLfloat x = player->getPosition()[0];
      GLfloat y = player->getPosition()[1];
      GLfloat z = player->getPosition()[2];
      if (player->getFlag() != Flags::Null) {
	glColor3fv(player->getFlag()->getColor());
	drawFlagOnTank(x, y, z);
      }

      if (player->isPaused() || player->isNotResponding()) {
	const float dimfactor = 0.4f;
	const float *color = Team::getRadarColor(myTank->getFlag() ==
			     Flags::Colorblindness ? RogueTeam : player->getTeam());
	float dimmedcolor[3];
	dimmedcolor[0] = color[0] * dimfactor;
	dimmedcolor[1] = color[1] * dimfactor;
	dimmedcolor[2] = color[2] * dimfactor;
	glColor3fv(dimmedcolor);
      } else {
	glColor3fv(Team::getRadarColor(myTank->getFlag() ==
			     Flags::Colorblindness ? RogueTeam : player->getTeam()));
      }
      // If this tank is hunted flash it on the radar
      if (player->isHunted() && myTank->getFlag() != Flags::Colorblindness) {
	if (flashTank.isOn()) {
	  if (!toggleTank) {
	    float flashcolor[3];
	    flashcolor[0] = 0.0f;
	    flashcolor[1] = 0.8f;
	    flashcolor[2] = 0.9f;
	    glColor3fv(flashcolor);
	  }
	} else {
	  toggleTank = !toggleTank;
	  flashTank.setClock(0.2f);
	}
      }
      drawTank(x, y, z);
    }

    bool coloredShot = BZDB.isTrue("coloredradarshots");
    // draw other tanks' shells
    maxShots = World::getWorld()->getMaxShots();
    for (i = 0; i < curMaxPlayers; i++) {
      RemotePlayer* player = world.getPlayer(i);
      if (!player) continue;
      for (int j = 0; j < maxShots; j++) {
	const ShotPath* shot = player->getShot(j);
	if (shot && shot->getFlag() != Flags::InvisibleBullet) {
	  const float *shotcolor;
	  if (coloredShot) {
	    if (myTank->getFlag() == Flags::Colorblindness)
	      shotcolor = Team::getRadarColor(RogueTeam);
	    else
	      shotcolor = Team::getRadarColor(player->getTeam());
	    const float cs = colorScale(shot->getPosition()[2],
		    muzzleHeight, BZDBCache::enhancedRadar);
	    glColor3f(shotcolor[0] * cs, shotcolor[1] * cs, shotcolor[2] * cs);
	  } else {
	    glColor3f(1.0f, 1.0f, 1.0f);
	  }
	  shot->radarRender();
	}
      }
    }

    // draw flags not on tanks.
    const int maxFlags = world.getMaxFlags();
    const bool drawNormalFlags = BZDB.isTrue("displayRadarFlags");
    for (i = 0; i < maxFlags; i++) {
      const Flag& flag = world.getFlag(i);
      // don't draw flags that don't exist or are on a tank
      if (flag.status == FlagNoExist || flag.status == FlagOnTank)
	continue;
      // don't draw normal flags if we aren't supposed to
      if (flag.type->flagTeam == NoTeam && !drawNormalFlags)
	continue;
      // Flags change color by height
      const float cs = colorScale(flag.position[2], muzzleHeight, BZDBCache::enhancedRadar);
      const float *flagcolor = flag.type->getColor();
      glColor3f(flagcolor[0] * cs, flagcolor[1] * cs, flagcolor[2] * cs);
      drawFlag(flag.position[0], flag.position[1], flag.position[2]);
    }
    // draw antidote flag
    const float* antidotePos =
		LocalPlayer::getMyTank()->getAntidoteLocation();
    if (antidotePos) {
      glColor3f(1.0f, 1.0f, 0.0f);
      drawFlag(antidotePos[0], antidotePos[1], antidotePos[2]);
    }

    // draw these markers above all others always centered
    glPopMatrix();

    // north marker
    GLfloat ns = 0.05f * range, ny = 0.9f * range;
    glColor3f(1.0f, 1.0f, 1.0f);
    glBegin(GL_LINE_STRIP);
    glVertex2f(-ns, ny - ns);
    glVertex2f(-ns, ny + ns);
    glVertex2f(ns, ny - ns);
    glVertex2f(ns, ny + ns);
    glEnd();

    // always up
    glPopMatrix();

    // get size of pixel in model space (assumes radar is square)
    GLfloat ps = 2.0f * range / GLfloat(w);

    // forward tick
    glBegin(GL_LINES);
    glVertex2f(0.0f, range - ps);
    glVertex2f(0.0f, range - 4.0f * ps);
    glEnd();

    // my tank
    glColor3f(1.0f, 1.0f, 1.0f);
    drawTank(0.0f, 0.0f, myTank->getPosition()[2]);

    // my flag
    if (myTank->getFlag() != Flags::Null) {
      glColor3fv(myTank->getFlag()->getColor());
      drawFlagOnTank(0.0f, 0.0f, myTank->getPosition()[2]);
    }
  }

  // restore GL state
  glPopMatrix();
}