Exemplo n.º 1
0
void GUIVolumeChange::regenerateGui(v2u32 screensize)
{
	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	core::rect<s32> rect(
			screensize.X/2 - 380/2,
			screensize.Y/2 - 200/2,
			screensize.X/2 + 380/2,
			screensize.Y/2 + 200/2
	);
	
	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 size = rect.getSize();
	v2s32 topleft_client(40, 0);
	v2s32 size_client = size - v2s32(40, 0);
	int volume=(int)(g_settings->getFloat("sound_volume")*100);
	/*
		Add stuff
	*/
	changeCtype("");
	{
		core::rect<s32> rect(0, 0, 120, 20);
		rect = rect + v2s32(size.X/2-60, size.Y/2-35);
		wchar_t* text = wgettext("Sound Volume: ");
		Environment->addStaticText(text, rect, false,
				true, this, ID_soundText1);
		delete[] text;
	}
	{
		core::rect<s32> rect(0, 0, 30, 20);
		rect = rect + v2s32(size.X/2+40, size.Y/2-35);
		Environment->addStaticText(core::stringw(volume).c_str(), rect, false,
				true, this, ID_soundText2);
	}
	{
		core::rect<s32> rect(0, 0, 80, 30);
		rect = rect + v2s32(size.X/2-80/2, size.Y/2+55);
		wchar_t* text = wgettext("Exit");
		Environment->addButton(rect, this, ID_soundExitButton,
			text);
		delete[] text;
	}
	{
		core::rect<s32> rect(0, 0, 300, 20);
		rect = rect + v2s32(size.X/2-150, size.Y/2);
		gui::IGUIScrollBar *e = Environment->addScrollBar(true,
			rect, this, ID_soundSlider);
		e->setMax(100);
		e->setPos(volume);
	}
	changeCtype("");
}
Exemplo n.º 2
0
void GUIConfirmMenu::regenerateGui(v2u32 screensize)
{
	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	core::rect<s32> rect(
			screensize.X/2 - 580/2,
			screensize.Y/2 - 300/2,
			screensize.X/2 + 580/2,
			screensize.Y/2 + 300/2
	);
	
	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 size = rect.getSize();

	/*
		Add stuff
	*/
	{
		core::rect<s32> rect(0, 0, 300, 20);
		rect += v2s32(size.X/2-300/2, size.Y/2-30/2-25);
		Environment->addStaticText(m_message_text.c_str(),
			rect, false, true, this, -1);
	}
	changeCtype("");
	int bw = 100;
	{
		core::rect<s32> rect(0, 0, bw, 30);
		rect = rect + v2s32(size.X/2-bw/2-(bw/2+5), size.Y/2-30/2+25);
		Environment->addButton(rect, this, GUI_ID_YES,
			wgettext("Yes"));
	}
	{
		core::rect<s32> rect(0, 0, bw, 30);
		rect = rect + v2s32(size.X/2-bw/2+(bw/2+5), size.Y/2-30/2+25);
		Environment->addButton(rect, this, GUI_ID_NO,
			wgettext("No"));
	}
	changeCtype("C");
}
Exemplo n.º 3
0
void GUIDeathScreen::regenerateGui(v2u32 screensize)
{
  m_screensize = screensize;
  
  /*
    Remove stuff
  */
  removeChildren();
  
  /*
    Calculate new sizes and positions
  */
  core::rect<s32> rect(
		       screensize.X/2 - 500/2,
		       screensize.Y/2 - 200/2,
		       screensize.X/2 + 500/2,
		       screensize.Y/2 + 200/2
		       );
  
  DesiredRect = rect;
  recalculateAbsolutePosition(false);
  
  v2s32 size = rect.getSize();
  
  /*
    Add stuff
  */
  
  {
    core::rect<s32> rect(0, 0, 400, 50);
    rect = rect + v2s32(size.X/2-400/2, size.Y/2-50/2-25);
    wchar_t* text = wgettext("Death has overcome you! D:");
    Environment->addStaticText(text, rect, false,
			       true, this, 256);
    delete[] text;
  }
  {
    core::rect<s32> rect(0, 0, 140, 30);
    rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);
    wchar_t* text = wgettext("Respawn");
    gui::IGUIElement *e = 
      Environment->addButton(rect, this, 257,
			     text);
    delete[] text;
    Environment->setFocus(e);
  }
}
Exemplo n.º 4
0
void GUIMainMenu::deleteWorld(const std::vector<std::string> &paths)
{
	// Delete files
	bool did = fs::DeletePaths(paths);
	if(!did){
		GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
				-1, menumgr, wgettext("Failed to delete all world files"));
		menu->drop();
	}
	// Quit menu to refresh it
	acceptInput();
	m_data->only_refresh = true;
	quitMenu();
}
Exemplo n.º 5
0
	void accepted(std::wstring name, std::string gameid)
	{
		std::string name_narrow = wide_to_narrow(name);
		if(!string_allowed_blacklist(name_narrow, WORLDNAME_BLACKLISTED_CHARS))
		{
			wchar_t* text = wgettext("Cannot create world: Name contains invalid characters");
			m_menu->displayMessageMenu(text);
			delete[] text;
			return;
		}
		std::vector<WorldSpec> worlds = getAvailableWorlds();
		for(std::vector<WorldSpec>::iterator i = worlds.begin();
		    i != worlds.end(); i++)
		{
			if((*i).name == name_narrow)
			{
				wchar_t* text = wgettext("Cannot create world: A world by this name already exists");
				m_menu->displayMessageMenu(text);
				delete[] text;
				return;
			}
		}
		m_menu->createNewWorld(name, gameid);
	}
Exemplo n.º 6
0
void GameUI::toggleProfiler()
{
	m_profiler_current_page = (m_profiler_current_page + 1) % (m_profiler_max_page + 1);

	// FIXME: This updates the profiler with incomplete values
	updateProfiler();

	if (m_profiler_current_page != 0) {
		wchar_t buf[255];
		const wchar_t* str = wgettext("Profiler shown (page %d of %d)");
		swprintf(buf, sizeof(buf) / sizeof(wchar_t), str,
			m_profiler_current_page, m_profiler_max_page);
		delete[] str;
		showStatusText(buf);
	} else {
		showTranslatedStatusText("Profiler hidden");
	}
}
Exemplo n.º 7
0
void GUIMessage::regenerateGui(v2u32 screensize)
{
	m_screensize = screensize;

	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	core::rect<s32> rect(
			screensize.X - screensize.X/4,
			0,
			screensize.X,
			screensize.Y/4
	);
	
	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 size = rect.getSize();
	const s32 btn_height = 30;
	const s32 btn_gap = 50;
	const s32 btn_gap_hor = 50;
	const s32 btn_num = 2;
	const s32 btn_width = 140;

	/*
		Add stuff
	*/
	changeCtype("");
	{
		core::rect<s32> rect(0, 0, size.X, size.Y);
		rect = rect + v2s32(size.X/2-400/2, size.Y/2-50/2-25);
		gui::IGUIStaticText *e = 
		Environment->addStaticText(wgettext(m_text.c_str()), rect, false,
				true, this, 256);
		e->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
	}
	changeCtype("C");
}
Exemplo n.º 8
0
void GUIMessageMenu::regenerateGui(v2u32 screensize)
{
	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	core::rect<s32> rect(
			screensize.X/2 - 580/2,
			screensize.Y/2 - 300/2,
			screensize.X/2 + 580/2,
			screensize.Y/2 + 300/2
	);
	
	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 size = rect.getSize();

	/*
		Add stuff
	*/
	{
		core::rect<s32> rect(0, 0, 400, 50);
		rect = rect + v2s32(size.X/2-400/2, size.Y/2-50/2-25);
		Environment->addStaticText(m_message_text.c_str(), rect, false,
				true, this, 256);
	}
	changeCtype("");
	{
		core::rect<s32> rect(0, 0, 140, 30);
		rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);
		gui::IGUIElement *e = 
		Environment->addButton(rect, this, 257,
			wgettext("Proceed"));
		Environment->setFocus(e);
	}
	changeCtype("C");
}
Exemplo n.º 9
0
bool GUIKeyChangeMenu::resetMenu()
{
	if (activeKey >= 0)
	{
		for(size_t i = 0; i < key_settings.size(); i++)
		{
			key_setting *k = key_settings.at(i);
			if(k->id == activeKey)
			{
				const wchar_t *text = wgettext(k->key.name());
				k->button->setText(text);
				delete[] text;
				break;
			}
		}
		activeKey = -1;
		return false;
	}
	return true;
}
Exemplo n.º 10
0
void GUITextInputMenu::regenerateGui(v2u32 screensize)
{
	std::wstring text;

	{
		gui::IGUIElement *e = getElementFromId(256);
		if(e != NULL)
		{
			text = e->getText();
		}
		else
		{
			text = m_initial_text;
			m_initial_text = L"";
		}
	}

	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	core::rect<s32> rect(
			screensize.X/2 - 580/2,
			screensize.Y/2 - 300/2,
			screensize.X/2 + 580/2,
			screensize.Y/2 + 300/2
	);
	
	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 size = rect.getSize();

	/*
		Add stuff
	*/
	{
		core::rect<s32> rect(0, 0, 300, 30);
		rect = rect + v2s32(size.X/2-300/2, size.Y/2-30/2-25);
		#if USE_FREETYPE
		gui::IGUIElement *e = (gui::IGUIElement *) new gui::intlGUIEditBox(text.c_str(), true, Environment, this, 256, rect);
		e->drop();
		#else
		gui::IGUIElement *e = Environment->addEditBox(text.c_str(), rect, true, this, 256);
		#endif
		Environment->setFocus(e);

		irr::SEvent evt;
		evt.EventType = EET_KEY_INPUT_EVENT;
		evt.KeyInput.Key = KEY_END;
		evt.KeyInput.PressedDown = true;
		e->OnEvent(evt);
	}
	changeCtype("");
	{
		core::rect<s32> rect(0, 0, 140, 30);
		rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);
		wchar_t* text = wgettext("Proceed");
		Environment->addButton(rect, this, 257,
			text);
		delete[] text;
	}
	changeCtype("C");
}
Exemplo n.º 11
0
void GUIKeyChangeMenu::init_keys()
{
	this->add_key(GUI_ID_KEY_FORWARD_BUTTON,   wgettext("Forward"),          "keymap_forward");
	this->add_key(GUI_ID_KEY_BACKWARD_BUTTON,  wgettext("Backward"),         "keymap_backward");
	this->add_key(GUI_ID_KEY_LEFT_BUTTON,      wgettext("Left"),             "keymap_left");
	this->add_key(GUI_ID_KEY_RIGHT_BUTTON,     wgettext("Right"),            "keymap_right");
	this->add_key(GUI_ID_KEY_USE_BUTTON,       wgettext("Use"),              "keymap_special1");
	this->add_key(GUI_ID_KEY_JUMP_BUTTON,      wgettext("Jump"),             "keymap_jump");
	this->add_key(GUI_ID_KEY_SNEAK_BUTTON,     wgettext("Sneak"),            "keymap_sneak");
	this->add_key(GUI_ID_KEY_DROP_BUTTON,      wgettext("Drop"),             "keymap_drop");
	this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, wgettext("Inventory"),        "keymap_inventory");
	this->add_key(GUI_ID_KEY_CHAT_BUTTON,      wgettext("Chat"),             "keymap_chat");
	this->add_key(GUI_ID_KEY_CMD_BUTTON,       wgettext("Command"),          "keymap_cmd");
	this->add_key(GUI_ID_KEY_CONSOLE_BUTTON,   wgettext("Console"),          "keymap_console");
	this->add_key(GUI_ID_KEY_FLY_BUTTON,       wgettext("Toggle fly"),       "keymap_freemove");
	this->add_key(GUI_ID_KEY_FAST_BUTTON,      wgettext("Toggle fast"),      "keymap_fastmove");
	this->add_key(GUI_ID_KEY_CINEMATIC_BUTTON, wgettext("Toggle Cinematic"), "keymap_cinematic");
	this->add_key(GUI_ID_KEY_NOCLIP_BUTTON,    wgettext("Toggle noclip"),    "keymap_noclip");
	this->add_key(GUI_ID_KEY_RANGE_BUTTON,     wgettext("Range select"),     "keymap_rangeselect");
	this->add_key(GUI_ID_KEY_DUMP_BUTTON,      wgettext("Print stacks"),     "keymap_print_debug_stacks");
}
Exemplo n.º 12
0
bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
{
	if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
		&& event.KeyInput.PressedDown)
	{
		
		bool prefer_character = shift_down;
		KeyPress kp(event.KeyInput, prefer_character);
		
		bool shift_went_down = false;
		if(!shift_down &&
				(event.KeyInput.Key == irr::KEY_SHIFT ||
				event.KeyInput.Key == irr::KEY_LSHIFT ||
				event.KeyInput.Key == irr::KEY_RSHIFT))
			shift_went_down = true;

		// Remove Key already in use message
		if(this->key_used_text)
		{
			this->key_used_text->remove();
			this->key_used_text = NULL;
		}
		// Display Key already in use message
		if (std::find(this->key_used.begin(), this->key_used.end(), kp) != this->key_used.end())
		{
			core::rect < s32 > rect(0, 0, 600, 40);
			rect += v2s32(0, 0) + v2s32(25, 30);
			const wchar_t *text = wgettext("Key already in use");
			this->key_used_text = Environment->addStaticText(text,
					rect, false, true, this, -1);
			delete[] text;
			//infostream << "Key already in use" << std::endl;
		}

		// But go on
		{
			key_setting *k = NULL;
			for(size_t i = 0; i < key_settings.size(); i++)
			{
				if(key_settings.at(i)->id == activeKey)
				{
					k = key_settings.at(i);
					break;
				}
			}
			FATAL_ERROR_IF(k == NULL, "Key setting not found");
			k->key = kp;
			const wchar_t *text = wgettext(k->key.name());
			k->button->setText(text);
			delete[] text;

			this->key_used.push_back(kp);

			// Allow characters made with shift
			if(shift_went_down){
				shift_down = true;
				return false;
			}else{
				activeKey = -1;
				return true;
			}
		}
	}
	if (event.EventType == EET_GUI_EVENT)
	{
		if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
			&& isVisible())
		{
			if (!canTakeFocus(event.GUIEvent.Element))
			{
				dstream << "GUIMainMenu: Not allowing focus change."
				<< std::endl;
				// Returning true disables focus change
				return true;
			}
		}
		if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
		{
			switch (event.GUIEvent.Caller->getID())
			{
				case GUI_ID_BACK_BUTTON: //back
					acceptInput();
					quitMenu();
					return true;
				case GUI_ID_ABORT_BUTTON: //abort
					quitMenu();
					return true;
				default:
					key_setting *k = NULL;
					for(size_t i = 0; i < key_settings.size(); i++)
					{
						if(key_settings.at(i)->id == event.GUIEvent.Caller->getID())
						{
							k = key_settings.at(i);
							break;
						}
					}
					FATAL_ERROR_IF(k == NULL, "Key setting not found");

					resetMenu();
					shift_down = false;
					activeKey = event.GUIEvent.Caller->getID();
					const wchar_t *text = wgettext("press key");
					k->button->setText(text);
					delete[] text;
					this->key_used.erase(std::remove(this->key_used.begin(),
							this->key_used.end(), k->key), this->key_used.end());
					break;
			}
			Environment->setFocus(this);
		}
	}
	return Parent ? Parent->OnEvent(event) : false;
}
Exemplo n.º 13
0
void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
	removeChildren();
	v2s32 size(620, 430);
	
	core::rect < s32 > rect(screensize.X / 2 - size.X / 2,
							screensize.Y / 2 - size.Y / 2, screensize.X / 2 + size.X / 2,
							screensize.Y / 2 + size.Y / 2);

	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 topleft(0, 0);
	
	{
		core::rect < s32 > rect(0, 0, 600, 40);
		rect += topleft + v2s32(25, 3);
		//gui::IGUIStaticText *t =
		const wchar_t *text = wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)");
		Environment->addStaticText(text,
								   rect, false, true, this, -1);
		delete[] text;
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	// Build buttons

	v2s32 offset(25, 60);

	for(size_t i = 0; i < key_settings.size(); i++)
	{
		key_setting *k = key_settings.at(i);
		{
			core::rect < s32 > rect(0, 0, 110, 20);
			rect += topleft + v2s32(offset.X, offset.Y);
			Environment->addStaticText(k->button_name, rect, false, true, this, -1);
		}

		{
			core::rect < s32 > rect(0, 0, 100, 30);
			rect += topleft + v2s32(offset.X + 115, offset.Y - 5);
			const wchar_t *text = wgettext(k->key.name());
			k->button = Environment->addButton(rect, this, k->id, text);
			delete[] text;
		}
		if(i + 1 == KMaxButtonPerColumns)
			offset = v2s32(260, 60);
		else
			offset += v2s32(0, 25);
	}
	
	{
		s32 option_x = offset.X;
		s32 option_y = offset.Y + 5;
		u32 option_w = 180;
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += topleft + v2s32(option_x, option_y);
			const wchar_t *text = wgettext("\"Use\" = climb down");
			Environment->addCheckBox(g_settings->getBool("aux1_descends"), rect, this,
					GUI_ID_CB_AUX1_DESCENDS, text);
			delete[] text;
		}
		offset += v2s32(0, 25);
	}

	{
		s32 option_x = offset.X;
		s32 option_y = offset.Y + 5;
		u32 option_w = 280;
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += topleft + v2s32(option_x, option_y);
			const wchar_t *text = wgettext("Double tap \"jump\" to toggle fly");
			Environment->addCheckBox(g_settings->getBool("doubletap_jump"), rect, this,
					GUI_ID_CB_DOUBLETAP_JUMP, text);
			delete[] text;
		}
		offset += v2s32(0, 25);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
		const wchar_t *text =  wgettext("Save");
		Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
				 text);
		delete[] text;
	}
	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
		const wchar_t *text = wgettext("Cancel");
		Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
				text);
		delete[] text;
	}	
}
Exemplo n.º 14
0
bool GUISettingsMenu::OnEvent(const SEvent& event)
{
	if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0 && event.KeyInput.PressedDown) {
		KeyPress kp(event.KeyInput);
		gui::IGUIElement *e = getElementFromId(activeKey);
		if (e != NULL && e->getType() == gui::EGUIET_BUTTON) {
			e->setEnabled(true);
			e->setText(kp.guiName().c_str());
			keys[activeKey-GUI_ID_KEYSETTINGS_BASE] = kp;
		}
		activeKey = -1;
		return true;
	}
	if (event.EventType == EET_GUI_EVENT) {
		if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST && isVisible()) {
			if (!canTakeFocus(event.GUIEvent.Element)) {
				dstream << "GUIMainMenu: Not allowing focus change."
						<< std::endl;
				// Returning true disables focus change
				return true;
			}
		}
		if (event.GUIEvent.EventType==gui::EGET_CHECKBOX_CHANGED) {
			acceptInput();
			m_accepted = false;
			regenerateGui(m_screensize);
		}
		if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) {
			s32 id = event.GUIEvent.Caller->getID();
			if (id >= GUI_ID_KEYSETTINGS_BASE) {
				resetMenu();
				activeKey = id;
				gui::IGUIElement *e = getElementFromId(id);
				if (e != NULL && e->getType() == gui::EGUIET_BUTTON) {
					e->setText(wgettext("press Key"));
					e->setEnabled(false);
					return true;
				}
			}else{
				switch (event.GUIEvent.Caller->getID()) {
				case GUI_ID_TAB_SETTINGS_CONTROLS:
					acceptInput();
					m_accepted = false;
					m_data.selected_tab = TAB_SETTINGS_CONTROLS;
					regenerateGui(m_screensize);
					return true;
				case GUI_ID_TAB_SETTINGS_GRAPHICS:
					acceptInput();
					m_accepted = false;
					m_data.selected_tab = TAB_SETTINGS_GRAPHICS;
					regenerateGui(m_screensize);
					return true;
				case GUI_ID_TAB_SETTINGS_VIDEO:
					acceptInput();
					m_accepted = false;
					m_data.selected_tab = TAB_SETTINGS_VIDEO;
					regenerateGui(m_screensize);
					return true;
				case GUI_ID_TAB_SETTINGS_SOUND:
					acceptInput();
					m_accepted = false;
					m_data.selected_tab = TAB_SETTINGS_SOUND;
					regenerateGui(m_screensize);
					return true;
				case GUI_ID_TAB_MAINMENU: //back
					acceptInput();
					save();
					quitMenu();
					return true;
				}
			}
		}
		if (event.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED) {
			switch (event.GUIEvent.Caller->getID()) {
			case GUI_ID_VOLUME_SB:
				gui::IGUIElement *vsb = getElementFromId(GUI_ID_VOLUME_SB);
				if(vsb != NULL && vsb->getType() == gui::EGUIET_SCROLL_BAR) {
					m_data.volume = (float)((gui::IGUIScrollBar*)vsb)->getPos();
					if (g_sound)
						g_sound->setListenerGain(m_data.volume/100.0);
				}
				return true;
			}
		}
	}
	return Parent ? Parent->OnEvent(event) : false;
}
Exemplo n.º 15
0
void content_mapnode_plants(bool repeat)
{
	bool new_style_leaves = g_settings->getBool("new_style_leaves");
	content_t i;
	ContentFeatures *f = NULL;


	i = CONTENT_TREE;
	f = &content_features(i);
	f->description = wgettext("Tree");
	f->setAllTextures("tree.png");
	f->setTexture(0, "tree_top.png");
	f->setTexture(1, "tree_top.png");
	f->setInventoryTextureCube("tree_top.png", "tree.png", "tree.png");
	f->draw_type = CDT_TRUNKLIKE;
	f->is_ground_content = true;
	f->flammable = 2; // can be set on fire
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->cook_result = std::string("CraftItem lump_of_charcoal 1");
	f->fuel_time = 30;
	f->type = CMT_TREE;
	f->hardness = 1.0;
	f->ondig_special_drop = CONTENT_WOOD;
	f->ondig_special_drop_count = 6;
	f->ondig_special_tool = TT_AXE;
	lists::add("creative",i);
	lists::add("cooking",i);

	i = CONTENT_APPLE_TREE;
	f = &content_features(i);
	f->description = wgettext("Apple Tree");
	f->setAllTextures("apple_tree.png");
	f->setTexture(0, "apple_tree_top.png");
	f->setTexture(1, "apple_tree_top.png");
	f->setInventoryTextureCube("apple_tree_top.png", "apple_tree.png", "apple_tree.png");
	f->draw_type = CDT_TRUNKLIKE;
	f->is_ground_content = true;
	f->flammable = 2; // can be set on fire
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->cook_result = std::string("CraftItem lump_of_charcoal 1");
	f->fuel_time = 30;
	f->type = CMT_TREE;
	f->hardness = 1.0;
	f->ondig_special_drop = CONTENT_WOOD;
	f->ondig_special_drop_count = 6;
	f->ondig_special_tool = TT_AXE;
	lists::add("creative",i);
	lists::add("cooking",i);

	i = CONTENT_JUNGLETREE;
	f = &content_features(i);
	f->description = wgettext("Jungle Tree");
	f->setAllTextures("jungletree.png");
	f->setTexture(0, "jungletree_top.png");
	f->setTexture(1, "jungletree_top.png");
	f->setInventoryTextureCube("jungletree_top.png", "jungletree.png", "jungletree.png");
	f->draw_type = CDT_TRUNKLIKE;
	//f->is_ground_content = true;
	f->flammable = 2; // can be set on fire
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->cook_result = std::string("CraftItem lump_of_charcoal 1");
	f->fuel_time = 30;
	f->type = CMT_TREE;
	f->hardness = 1.0;
	f->ondig_special_drop = CONTENT_JUNGLEWOOD;
	f->ondig_special_drop_count = 6;
	f->ondig_special_tool = TT_AXE;
	lists::add("creative",i);

	i = CONTENT_CONIFER_TREE;
	f = &content_features(i);
	f->description = wgettext("Conifer Tree");
	f->setAllTextures("conifer_tree.png");
	f->setTexture(0, "conifer_tree_top.png");
	f->setTexture(1, "conifer_tree_top.png");
	f->setInventoryTextureCube("conifer_tree_top.png", "conifer_tree.png", "conifer_tree.png");
	f->draw_type = CDT_TRUNKLIKE;
	f->is_ground_content = true;
	f->flammable = 2; // can be set on fire
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->cook_result = std::string("CraftItem lump_of_charcoal 1");
	f->fuel_time = 25;
	f->type = CMT_TREE;
	f->hardness = 0.8;
	f->ondig_special_drop = CONTENT_WOOD_PINE;
	f->ondig_special_drop_count = 6;
	f->ondig_special_tool = TT_AXE;
	lists::add("creative",i);
	lists::add("cooking",i);

	i = CONTENT_YOUNG_TREE;
	f = &content_features(i);
	f->description = wgettext("Young Tree");
	f->setAllTextures("tree.png");
	f->setTexture(0, "tree_top.png");
	f->setTexture(1, "tree_top.png");
	f->draw_type = CDT_NODEBOX;
	f->solidness = 0; // drawn separately, makes no faces
	f->param_type = CPT_LIGHT;
	f->light_propagates = true;
	content_nodebox_youngtree(f);
	f->setInventoryTextureNodeBox(i,"tree_top.png", "tree.png", "tree.png");
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->special_alternate_node = CONTENT_LEAVES;
	f->fuel_time = 20;
	f->type = CMT_TREE;
	f->hardness = 1.0;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_YOUNG_JUNGLETREE;
	f = &content_features(i);
	f->description = wgettext("Young Jungle Tree");
	f->setAllTextures("jungletree.png");
	f->setTexture(0, "jungletree_top.png");
	f->setTexture(1, "jungletree_top.png");
	f->draw_type = CDT_NODEBOX;
	f->solidness = 0; // drawn separately, makes no faces
	f->param_type = CPT_LIGHT;
	f->light_propagates = true;
	content_nodebox_youngtree(f);
	f->setInventoryTextureNodeBox(i,"jungletree_top.png", "jungletree.png", "jungletree.png");
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->special_alternate_node = CONTENT_JUNGLELEAVES;
	f->fuel_time = 20;
	f->type = CMT_TREE;
	f->hardness = 1.0;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_YOUNG_APPLE_TREE;
	f = &content_features(i);
	f->description = wgettext("Young Apple Tree");
	f->setAllTextures("apple_tree.png");
	f->setTexture(0, "apple_tree_top.png");
	f->setTexture(1, "apple_tree_top.png");
	f->draw_type = CDT_NODEBOX;
	f->solidness = 0; // drawn separately, makes no faces
	f->param_type = CPT_LIGHT;
	f->light_propagates = true;
	content_nodebox_youngtree(f);
	f->setInventoryTextureNodeBox(i,"apple_tree_top.png", "apple_tree.png", "apple_tree.png");
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->special_alternate_node = CONTENT_APPLE_LEAVES;
	f->fuel_time = 20;
	f->type = CMT_TREE;
	f->hardness = 1.0;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_YOUNG_CONIFER_TREE;
	f = &content_features(i);
	f->description = wgettext("Young Conifer Tree");
	f->setAllTextures("conifer_tree.png");
	f->setTexture(0, "conifer_tree_top.png");
	f->setTexture(1, "conifer_tree_top.png");
	f->draw_type = CDT_NODEBOX;
	f->solidness = 0; // drawn separately, makes no faces
	f->param_type = CPT_LIGHT;
	f->light_propagates = true;
	content_nodebox_youngtree(f);
	f->setInventoryTextureNodeBox(i,"conifer_tree_top.png", "conifer_tree.png", "conifer_tree.png");
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->special_alternate_node = CONTENT_CONIFER_LEAVES;
	f->fuel_time = 20;
	f->type = CMT_TREE;
	f->hardness = 1.0;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_JUNGLEGRASS;
	f = &content_features(i);
	f->description = wgettext("Jungle Grass");
	f->setInventoryTexture("junglegrass.png");
	f->setAllTextures("junglegrass.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE_LGE;
	//f->is_ground_content = true;
	f->air_equivalent = true;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->type = CMT_PLANT;
	f->hardness = 0.20;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_LEAVES;
	f = &content_features(i);
	f->description = wgettext("Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	//f->is_ground_content = true;
	if (new_style_leaves) {
		f->draw_type = CDT_LEAFLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->setAllTextures("leaves.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
		f->setAllTextureFlags(0);
#endif
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:leaves.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem lump_of_resin 1");
	f->extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAPLING)+" 1";
	f->extra_dug_item_rarity = 20;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->ondig_special_drop = CONTENT_TRIMMED_LEAVES;
	f->ondig_special_drop_count = 1;
	f->ondig_special_tool = TT_SHEAR;
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("decrafting",i);
	lists::add("cooking",i);

	i = CONTENT_LEAVES_AUTUMN;
	f = &content_features(i);
	f->description = wgettext("Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	//f->is_ground_content = true;
	if (new_style_leaves) {
		f->draw_type = CDT_LEAFLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->setAllTextures("leaves_autumn.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
		f->setAllTextureFlags(0);
#endif
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:leaves_autumn.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem lump_of_resin 1");
	f->extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAPLING)+" 1";
	f->extra_dug_item_rarity = 20;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->ondig_special_drop = CONTENT_TRIMMED_LEAVES_AUTUMN;
	f->ondig_special_drop_count = 1;
	f->ondig_special_tool = TT_SHEAR;
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("decrafting",i);
	lists::add("cooking",i);

	i = CONTENT_LEAVES_WINTER;
	f = &content_features(i);
	f->description = wgettext("Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	//f->is_ground_content = true;
	if (new_style_leaves) {
		f->draw_type = CDT_LEAFLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->setAllTextures("leaves_winter.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
		f->setAllTextureFlags(0);
#endif
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:leaves_winter.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem2 ")+itos(CONTENT_CRAFTITEM_ASH)+" 1";
	f->extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAPLING)+" 1";
	f->extra_dug_item_rarity = 20;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->ondig_special_drop = CONTENT_TRIMMED_LEAVES_WINTER;
	f->ondig_special_drop_count = 1;
	f->ondig_special_tool = TT_SHEAR;
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("decrafting",i);
	lists::add("cooking",i);

	i = CONTENT_LEAVES_SNOWY;
	f = &content_features(i);
	f->description = wgettext("Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	//f->is_ground_content = true;
	if (new_style_leaves) {
		f->draw_type = CDT_LEAFLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->setAllTextures("leaves_snowy.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
		f->setAllTextureFlags(0);
#endif
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:leaves_snowy.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem2 ")+itos(CONTENT_CRAFTITEM_ASH)+" 1";
	f->extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAPLING)+" 1";
	f->extra_dug_item_rarity = 20;
	f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_LEAVES_WINTER)+" 1";
	f->ondig_special_drop = CONTENT_TRIMMED_LEAVES_WINTER;
	f->ondig_special_drop_count = 1;
	f->ondig_special_tool = TT_SHEAR;
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("decrafting",i);
	lists::add("cooking",i);

	i = CONTENT_APPLE_LEAVES;
	f = &content_features(i);
	f->description = wgettext("Apple Tree Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	f->special_alternate_node = CONTENT_APPLE_BLOSSOM;
	if (new_style_leaves) {
		f->draw_type = CDT_LEAFLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->setAllTextures("apple_leaves.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
		f->setAllTextureFlags(0);
#endif
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:apple_leaves.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem lump_of_resin 1");
	f->extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_APPLE_SAPLING)+" 1";
	f->extra_dug_item_rarity = 20;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->ondig_special_drop = CONTENT_TRIMMED_APPLE_LEAVES;
	f->ondig_special_drop_count = 1;
	f->ondig_special_tool = TT_SHEAR;
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("decrafting",i);
	lists::add("cooking",i);

	i = CONTENT_JUNGLELEAVES;
	f = &content_features(i);
	f->description = wgettext("Jungle Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	//f->is_ground_content = true;
	if (new_style_leaves) {
		f->draw_type = CDT_LEAFLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->setAllTextures("jungleleaves.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
		f->setAllTextureFlags(0);
#endif
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:jungleleaves.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem lump_of_resin 1");
	f->extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_JUNGLESAPLING)+" 1";
	f->extra_dug_item_rarity = 20;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->ondig_special_drop = CONTENT_TRIMMED_JUNGLE_LEAVES;
	f->ondig_special_drop_count = 1;
	f->ondig_special_tool = TT_SHEAR;
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("decrafting",i);
	lists::add("cooking",i);

	i = CONTENT_CONIFER_LEAVES;
	f = &content_features(i);
	f->description = wgettext("Conifer Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	//f->is_ground_content = true;
	if (new_style_leaves) {
		f->draw_type = CDT_LEAFLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->setAllTextures("conifer_leaves.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
		f->setAllTextureFlags(0);
#endif
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:conifer_leaves.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem lump_of_resin 1");
	f->extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_CONIFER_SAPLING)+" 1";
	f->extra_dug_item_rarity = 20;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->ondig_special_drop = CONTENT_TRIMMED_CONIFER_LEAVES;
	f->ondig_special_drop_count = 1;
	f->ondig_special_tool = TT_SHEAR;
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("decrafting",i);
	lists::add("cooking",i);

	i = CONTENT_TRIMMED_LEAVES;
	f = &content_features(i);
	f->description = wgettext("Trimmed Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	if (new_style_leaves) {
		f->draw_type = CDT_GLASSLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->visual_solidness = 1;
		f->setAllTextures("leaves.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
#endif
		f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png");
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:leaves.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem lump_of_resin 1");
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);
	lists::add("cooking",i);

	i = CONTENT_TRIMMED_LEAVES_AUTUMN;
	f = &content_features(i);
	f->description = wgettext("Trimmed Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	if (new_style_leaves) {
		f->draw_type = CDT_GLASSLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->visual_solidness = 1;
		f->setAllTextures("leaves_autumn.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
#endif
		f->setInventoryTextureCube("leaves_autumn.png", "leaves_autumn.png", "leaves_autumn.png");
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:leaves_autumn.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem lump_of_resin 1");
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);
	lists::add("cooking",i);

	i = CONTENT_TRIMMED_LEAVES_WINTER;
	f = &content_features(i);
	f->description = wgettext("Trimmed Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	if (new_style_leaves) {
		f->draw_type = CDT_GLASSLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->visual_solidness = 1;
		f->setAllTextures("leaves_winter.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
#endif
		f->setInventoryTextureCube("leaves_winter.png", "leaves_winter.png", "leaves_winter.png");
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:leaves_winter.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem2 ")+itos(CONTENT_CRAFTITEM_ASH)+" 1";
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);
	lists::add("cooking",i);

	i = CONTENT_TRIMMED_APPLE_LEAVES;
	f = &content_features(i);
	f->description = wgettext("Trimmed Apple Tree Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	if (new_style_leaves) {
		f->draw_type = CDT_GLASSLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->visual_solidness = 1;
		f->setAllTextures("apple_leaves.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
#endif
		f->setInventoryTextureCube("apple_leaves.png", "apple_leaves.png", "apple_leaves.png");
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:apple_leaves.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem lump_of_resin 1");
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);
	lists::add("cooking",i);

	i = CONTENT_TRIMMED_JUNGLE_LEAVES;
	f = &content_features(i);
	f->description = wgettext("Trimmed Jungle Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	if (new_style_leaves) {
		f->draw_type = CDT_GLASSLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->visual_solidness = 1;
		f->setAllTextures("jungleleaves.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
#endif
		f->setInventoryTextureCube("jungleleaves.png", "jungleleaves.png", "jungleleaves.png");
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:jungleleaves.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem lump_of_resin 1");
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);
	lists::add("cooking",i);

	i = CONTENT_TRIMMED_CONIFER_LEAVES;
	f = &content_features(i);
	f->description = wgettext("Trimmed Conifer Leaves");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	if (new_style_leaves) {
		f->draw_type = CDT_GLASSLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->visual_solidness = 1;
		f->setAllTextures("conifer_leaves.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
#endif
		f->setInventoryTextureCube("conifer_leaves.png", "conifer_leaves.png", "conifer_leaves.png");
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:conifer_leaves.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/16;
	f->cook_result = std::string("CraftItem lump_of_resin 1");
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);
	lists::add("cooking",i);

	i = CONTENT_APPLE_BLOSSOM;
	f = &content_features(i);
	f->description = wgettext("Apple Tree Blossom");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	f->special_alternate_node = CONTENT_APPLE_LEAVES;
	if (new_style_leaves) {
		f->draw_type = CDT_LEAFLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->visual_solidness = 1;
		f->setAllTextures("apple_leaves.png^apple_blossom.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
		f->setAllTextureFlags(0);
#endif
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:apple_leaves.png^apple_blossom.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->extra_dug_item = std::string("CraftItem apple_blossom 1");
	f->extra_dug_item_rarity = 1;
	f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_APPLE_LEAVES)+" 1";
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("decrafting",i);

	i = CONTENT_TRIMMED_APPLE_BLOSSOM;
	f = &content_features(i);
	f->description = wgettext("Trimmed Apple Tree Blossom");
	f->light_propagates = true;
	f->air_equivalent = true;
	f->walkable = false;
	f->climbable = true;
	f->param_type = CPT_LIGHT;
	if (new_style_leaves) {
		f->draw_type = CDT_GLASSLIKE;
		f->solidness = 0; // drawn separately, makes no faces
		f->visual_solidness = 1;
		f->setAllTextures("apple_leaves.png^apple_blossom.png");
#ifndef SERVER
		f->setAllTextureTypes(MATERIAL_ALPHA_SIMPLE);
#endif
		f->setInventoryTextureCube("apple_leaves.png^apple_blossom.png", "apple_leaves.png^apple_blossom.png", "apple_leaves.png^apple_blossom.png");
	}else{
		f->draw_type = CDT_CUBELIKE;
		f->setAllTextures("[noalpha:apple_leaves.png^apple_blossom.png");
	}
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_CACTUS_BLOSSOM;
	f = &content_features(i);
	f->description = wgettext("Cactus Blossom");
	f->setInventoryTexture("cactus_blossom.png");
	f->setAllTextures("cactus_blossom.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->air_equivalent = false; // grass grows underneath
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->type = CMT_PLANT;
	f->hardness = 0.20;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_CACTUS_FLOWER;
	f = &content_features(i);
	f->description = wgettext("Cactus Flower");
	f->setInventoryTexture("cactus_flower.png");
	f->setAllTextures("cactus_flower.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->air_equivalent = true;
	f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_CACTUS_BLOSSOM)+" 1";
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->type = CMT_PLANT;
	f->hardness = 0.20;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);
	lists::add("decrafting",i);

	i = CONTENT_CACTUS_FRUIT;
	f = &content_features(i);
	f->description = wgettext("Cactus Berry");
	f->setInventoryTexture("cactus_fruit.png");
	f->setAllTextures("cactus_fruit.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->air_equivalent = true;
	f->dug_item = std::string("CraftItem cactus_fruit 1");
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->type = CMT_PLANT;
	f->hardness = 0.20;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_CACTUS;
	f = &content_features(i);
	f->description = wgettext("Cactus");
	f->setAllTextures("cactus_side.png");
	f->setTexture(0, "cactus_top.png");
	f->setTexture(1, "cactus_top.png");
	f->draw_type = CDT_NODEBOX;
	f->param_type = CPT_LIGHT;
	f->light_propagates = true;
	f->sunlight_propagates = true;
	f->damage_per_second = 2;
	f->solidness = 0; // drawn separately, makes no faces
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/4;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->extra_dug_item = std::string("CraftItem2 ") + itos (CONTENT_CRAFTITEM_MUSH) + " 1";
	f->extra_dug_item_rarity = 10;
	f->setNodeBox(core::aabbox3d<f32>(
		-0.4375*BS,
		-0.5*BS,
		-0.4375*BS,
		0.4375*BS,
		0.5*BS,
		0.4375*BS
	));
	f->addNodeBox(core::aabbox3d<f32>(
		-0.5*BS,
		0.3125*BS,
		-0.5*BS,
		-0.4375*BS,
		0.375*BS,
		-0.4375*BS
	));
	f->addNodeBox(core::aabbox3d<f32>(
		0.4375*BS,
		0.125*BS,
		0.4375*BS,
		0.5*BS,
		0.1875*BS,
		0.5*BS
	));
	f->addNodeBox(core::aabbox3d<f32>(
		0.4375*BS,
		-0.1875*BS,
		-0.5*BS,
		0.5*BS,
		-0.125*BS,
		-0.4375*BS
	));
	f->addNodeBox(core::aabbox3d<f32>(
		-0.5*BS,
		-0.375*BS,
		0.4375*BS,
		-0.4375*BS,
		-0.3125*BS,
		0.5*BS
	));
	f->setInventoryTextureCube("cactus_top.png", "cactus_side.png", "cactus_side.png");
	f->type = CMT_WOOD;
	f->hardness = 0.75;
	f->pressure_type = CST_CRUSHABLE;
	lists::add("creative",i);

	i = CONTENT_PAPYRUS;
	f = &content_features(i);
	f->description = wgettext("Papyrus");
	f->setInventoryTexture("papyrus.png");
	f->setAllTextures("papyrus.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->param_type = CPT_LIGHT;
	f->param2_type = CPT_PLANTGROWTH;
	f->draw_type = CDT_PLANTLIKE;
	f->plantgrowth_large_dug_node = CONTENT_PAPYRUS;
	f->plantgrowth_large_count = 1;
	f->plantgrowth_max_height = 5;
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->type = CMT_PLANT;
	f->hardness = 0.25;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_SAPLING;
	f = &content_features(i);
	f->description = wgettext("Sapling");
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->setAllTextures("sapling.png");
	f->setInventoryTexture("sapling.png");
	f->setAllTextureFlags(0);
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->light_propagates = true;
	f->air_equivalent = false;
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 1;
	f->type = CMT_WOOD;
	f->hardness = 0.1;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	f->fertilizer_affects = true;
	lists::add("creative",i);

	i = CONTENT_APPLE_SAPLING;
	f = &content_features(i);
	f->description = wgettext("Apple Tree Sapling");
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->setAllTextures("apple_sapling.png");
	f->setInventoryTexture("apple_sapling.png");
	f->setAllTextureFlags(0);
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->light_propagates = true;
	f->air_equivalent = false;
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 1;
	f->type = CMT_WOOD;
	f->hardness = 0.1;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	f->fertilizer_affects = true;
	lists::add("creative",i);

	i = CONTENT_JUNGLESAPLING;
	f = &content_features(i);
	f->description = wgettext("Jungle Sapling");
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->setAllTextures("junglesapling.png");
	f->setInventoryTexture("junglesapling.png");
	f->setAllTextureFlags(0);
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->light_propagates = true;
	f->air_equivalent = false;
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 1;
	f->type = CMT_WOOD;
	f->hardness = 0.1;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	f->fertilizer_affects = true;
	lists::add("creative",i);

	i = CONTENT_CONIFER_SAPLING;
	f = &content_features(i);
	f->description = wgettext("Conifer Sapling");
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->setAllTextures("conifer_sapling.png");
	f->setInventoryTexture("conifer_sapling.png");
	f->setAllTextureFlags(0);
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->light_propagates = true;
	f->air_equivalent = false;
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 1;
	f->type = CMT_WOOD;
	f->hardness = 0.1;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	f->fertilizer_affects = true;
	lists::add("creative",i);

	i = CONTENT_APPLE;
	f = &content_features(i);
	f->description = wgettext("Apple");
	f->setInventoryTexture("apple.png");
	f->setAllTextures("apple.png");
	f->setAllTextureFlags(0);
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE_SML;
	f->light_propagates = true;
	f->sunlight_propagates = true;
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->air_equivalent = true;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 1;
	f->dug_item = std::string("CraftItem apple 1");
	f->ondig_replace_node = CONTENT_APPLE_LEAVES;
	f->ondig_replace_node_requires = CONTENT_APPLE_TREE;
	f->type = CMT_WOOD;
	f->hardness = 0.0;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	// plants
	i = CONTENT_WILDGRASS_SHORT;
	f = &content_features(i);
	f->description = wgettext("Wild Grass");
	f->setInventoryTexture("wildgrass_short.png");
	f->setAllTextures("wildgrass_short.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->sunlight_propagates = true;
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->air_equivalent = true;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->material_pointable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	//f->pointable = false;
	f->buildable_to = true;
	f->type = CMT_PLANT;
	f->hardness = 0.10;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;

	i = CONTENT_WILDGRASS_LONG;
	f = &content_features(i);
	f->description = wgettext("Wild Grass");
	f->setInventoryTexture("wildgrass_long.png");
	f->setAllTextures("wildgrass_long.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->sunlight_propagates = true;
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->air_equivalent = true;
	f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_WILDGRASS_SHORT)+" 1";
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->material_pointable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->buildable_to = true;
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;

	i = CONTENT_DEADGRASS;
	f = &content_features(i);
	f->description = wgettext("Dead Grass");
	f->setInventoryTexture("deadgrass.png");
	f->setAllTextures("deadgrass.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->sunlight_propagates = true;
	f->air_equivalent = true;
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->material_pointable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->buildable_to = true;
	f->type = CMT_PLANT;
	f->hardness = 0.10;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;

	i = CONTENT_FLOWER_STEM;
	f = &content_features(i);
	f->description = wgettext("Flower Stem");
	f->setInventoryTexture("flower_stem.png");
	f->setAllTextures("flower_stem.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->sunlight_propagates = true;
	f->air_equivalent = true;
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->material_pointable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->buildable_to = true;
	f->type = CMT_PLANT;
	f->hardness = 0.10;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;

	i = CONTENT_FLOWER_ROSE;
	f = &content_features(i);
	f->description = wgettext("Rose");
	f->setInventoryTexture("flower_rose.png");
	f->setAllTextures("flower_rose.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->sunlight_propagates = true;
	f->air_equivalent = true;
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->material_pointable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->buildable_to = true;
	f->type = CMT_PLANT;
	f->hardness = 0.10;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_FLOWER_DAFFODIL;
	f = &content_features(i);
	f->description = wgettext("Daffodil");
	f->setInventoryTexture("flower_daffodil.png");
	f->setAllTextures("flower_daffodil.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->sunlight_propagates = true;
	f->air_equivalent = true;
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->material_pointable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->buildable_to = true;
	f->type = CMT_PLANT;
	f->hardness = 0.10;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_FLOWER_TULIP;
	f = &content_features(i);
	f->description = wgettext("Tulip");
	f->setInventoryTexture("flower_tulip.png");
	f->setAllTextures("flower_tulip.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->sunlight_propagates = true;
	f->air_equivalent = true;
	f->param_type = CPT_LIGHT;
	f->draw_type = CDT_PLANTLIKE;
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->material_pointable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->buildable_to = true;
	f->type = CMT_PLANT;
	f->hardness = 0.10;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_SEEDS_TEA;
	f = &content_features(i);
	f->description = wgettext("Tea Seeds");
	f->setAllTextures("farm_seeds_tea.png");
	f->draw_type = CDT_PLANTLIKE;
	f->param_type = CPT_LIGHT;
	f->setAllTextureFlags(0);
	f->walkable = false;
	f->light_propagates = true;
	f->sunlight_propagates = true;
	f->air_equivalent = true;
	f->special_alternate_node = CONTENT_TEA;
	f->solidness = 0; // drawn separately, makes no faces
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->type = CMT_PLANT;
	f->hardness = 0.4;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_TEA;
	f = &content_features(i);
	f->description = wgettext("Tea Plant");
	f->setInventoryTexture("plant_tea.png");
	f->setAllTextures("plant_tea.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->param_type = CPT_LIGHT;
	f->param2_type = CPT_PLANTGROWTH;
	f->draw_type = CDT_PLANTLIKE;
	f->plantgrowth_small_dug_node = CONTENT_SEEDS_TEA;
	f->plantgrowth_large_dug_node = CONTENT_CRAFTITEM_TEA_LEAVES;
	f->plantgrowth_large_gives_small = true;
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->buildable_to = true;
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_BEANS_COFFEE;
	f = &content_features(i);
	f->description = wgettext("Coffee Beans");
	f->setAllTextures("farm_seeds_coffee.png");
	f->draw_type = CDT_PLANTLIKE;
	f->param_type = CPT_LIGHT;
	f->setAllTextureFlags(0);
	f->walkable = false;
	f->light_propagates = true;
	f->sunlight_propagates = true;
	f->air_equivalent = true;
	f->special_alternate_node = CONTENT_COFFEE;
	f->solidness = 0; // drawn separately, makes no faces
	f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
	f->cook_result = std::string("CraftItem2 ")+itos(CONTENT_CRAFTITEM_COFFEE_BEANS)+" 1";
	f->type = CMT_PLANT;
	f->hardness = 0.4;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);

	i = CONTENT_COFFEE;
	f = &content_features(i);
	f->description = wgettext("Coffee Plant");
	f->setInventoryTexture("plant_coffe.png");
	f->setAllTextures("plant_coffee.png");
	f->setAllTextureFlags(0);
	f->light_propagates = true;
	f->param_type = CPT_LIGHT;
	f->param2_type = CPT_PLANTGROWTH;
	f->draw_type = CDT_PLANTLIKE;
	f->plantgrowth_small_dug_node = CONTENT_BEANS_COFFEE;
	f->plantgrowth_large_dug_node = CONTENT_BEANS_COFFEE;
	f->solidness = 0; // drawn separately, makes no faces
	f->walkable = false;
	f->flammable = 1; // can be replaced by fire if the node under it is set on fire
	f->fuel_time = 30/32;
	f->buildable_to = true;
	f->type = CMT_PLANT;
	f->hardness = 0.15;
	f->pressure_type = CST_CRUSHABLE;
	f->suffocation_per_second = 0;
	lists::add("creative",i);
}
Exemplo n.º 16
0
void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
	/*
	 Remove stuff
	 */
	removeChildren();

	/*
	 Calculate new sizes and positions
	 */

	v2s32 size(620, 430);

	core::rect < s32 > rect(screensize.X / 2 - size.X / 2,
			screensize.Y / 2 - size.Y / 2, screensize.X / 2 + size.X / 2,
			screensize.Y / 2 + size.Y / 2);

	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 topleft(0, 0);
	changeCtype("");
	{
		core::rect < s32 > rect(0, 0, 500, 20);
		rect += topleft + v2s32(25, 3);
		//gui::IGUIStaticText *t =
		Environment->addStaticText(wgettext("KEYBINDINGS (If this menu screws up, see minetest.conf)"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}
	v2s32 offset(25, 40);
	// buttons

	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Forward"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->forward = Environment->addButton(rect, this,
				GUI_ID_KEY_FORWARD_BUTTON,
				wgettext(key_forward.name()));
	}

	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Backward"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->backward = Environment->addButton(rect, this,
				GUI_ID_KEY_BACKWARD_BUTTON,
				wgettext(key_backward.name()));
	}
	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Left"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->left = Environment->addButton(rect, this, GUI_ID_KEY_LEFT_BUTTON,
				wgettext(key_left.name()));
	}
	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Right"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->right = Environment->addButton(rect, this,
				GUI_ID_KEY_RIGHT_BUTTON,
				wgettext(key_right.name()));
	}
	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Use"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->use = Environment->addButton(rect, this, GUI_ID_KEY_USE_BUTTON,
				wgettext(key_use.name()));
	}
	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Sneak"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->sneak = Environment->addButton(rect, this,
				GUI_ID_KEY_SNEAK_BUTTON,
				wgettext(key_sneak.name()));
	}
	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Jump"), rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->jump = Environment->addButton(rect, this, GUI_ID_KEY_JUMP_BUTTON,
				wgettext(key_jump.name()));
	}

	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Drop"), rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->dropbtn = Environment->addButton(rect, this, GUI_ID_KEY_DROP_BUTTON,
				wgettext(key_drop.name()));
	}

	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Inventory"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->inventory = Environment->addButton(rect, this,
				GUI_ID_KEY_INVENTORY_BUTTON,
				wgettext(key_inventory.name()));
	}
	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Chat"), rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->chat = Environment->addButton(rect, this, GUI_ID_KEY_CHAT_BUTTON,
				wgettext(key_chat.name()));
	}
	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Command"), rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->cmd = Environment->addButton(rect, this, GUI_ID_KEY_CMD_BUTTON,
				wgettext(key_cmd.name()));
	}
	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Console"), rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->console = Environment->addButton(rect, this, GUI_ID_KEY_CONSOLE_BUTTON,
				wgettext(key_console.name()));
	}

	//next col
	offset = v2s32(250, 40);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Toggle fly"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->fly = Environment->addButton(rect, this, GUI_ID_KEY_FLY_BUTTON,
				wgettext(key_fly.name()));
	}
	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Toggle fast"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->fast = Environment->addButton(rect, this, GUI_ID_KEY_FAST_BUTTON,
				wgettext(key_fast.name()));
	}
	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Range select"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->range = Environment->addButton(rect, this,
				GUI_ID_KEY_RANGE_BUTTON,
				wgettext(key_range.name()));
	}

	offset += v2s32(0, 25);
	{
		core::rect < s32 > rect(0, 0, 100, 20);
		rect += topleft + v2s32(offset.X, offset.Y);
		Environment->addStaticText(wgettext("Print stacks"),
				rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
		this->dump = Environment->addButton(rect, this, GUI_ID_KEY_DUMP_BUTTON,
				wgettext(key_dump.name()));
	}
	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
		Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
		wgettext("Save"));
	}
	{
		core::rect < s32 > rect(0, 0, 100, 30);
		rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
		Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
		wgettext("Cancel"));
	}
	changeCtype("C");
}
Exemplo n.º 17
0
GUISettingsMenu::GUISettingsMenu(
	gui::IGUIEnvironment* env,
	gui::IGUIElement*
	parent,
	s32 id,
	IMenuManager *menumgr,
	bool is_ingame
):
	GUIModalMenu(env, parent, id, menumgr),
	m_accepted(false),
	m_is_ingame(is_ingame)
{
	activeKey = -1;
	init_keys();
	m_data.fancy_trees = g_settings->getBool("new_style_leaves");
	m_data.smooth_lighting = g_settings->getBool("smooth_lighting");
	m_data.clouds_3d = g_settings->getBool("enable_3d_clouds");
	m_data.opaque_water = g_settings->getBool("opaque_water");
	m_data.fullscreen = g_settings->getBool("fullscreen");
	m_data.particles = g_settings->getBool("enable_particles");
	m_data.mip_map = g_settings->getBool("mip_map");
	m_data.anisotropic_filter = g_settings->getBool("anisotropic_filter");
	m_data.bilinear_filter = g_settings->getBool("bilinear_filter");
	m_data.trilinear_filter = g_settings->getBool("trilinear_filter");
	m_data.hotbar = g_settings->getBool("old_hotbar");
	m_data.wield_index = g_settings->getBool("enable_wieldindex");
	m_data.volume = g_settings->getFloat("sound_volume");

	keynames[VLKC_FORWARD] = wgettext("Forward");
	keynames[VLKC_BACKWARD] = wgettext("Backward");
	keynames[VLKC_LEFT] = wgettext("Left");
	keynames[VLKC_RIGHT] = wgettext("Right");
	keynames[VLKC_JUMP] = wgettext("Jump");
	keynames[VLKC_SNEAK] = wgettext("Sneak");
	keynames[VLKC_INVENTORY] = wgettext("Inventory");
	keynames[VLKC_USE] = wgettext("Use Item");
	keynames[VLKC_CHAT] = wgettext("Chat");
	keynames[VLKC_COMMAND] = wgettext("Command");
	keynames[VLKC_RANGE] = wgettext("Range Select");
	keynames[VLKC_FREEMOVE] = wgettext("Toggle Fly");
	keynames[VLKC_UP] = wgettext("Up");
	keynames[VLKC_DOWN] = wgettext("Down");
	keynames[VLKC_RUN] = wgettext("Run");
	keynames[VLKC_EXAMINE] = wgettext("Examine/Open");
	keynames[VLKC_SCREENSHOT] = wgettext("Take Screenshot");
	keynames[VLKC_TOGGLE_HUD] = wgettext("Show/Hide HUD");
	keynames[VLKC_TOGGLE_CHAT] = wgettext("Show/Hide Chat");
	keynames[VLKC_TOGGLE_FOG] = wgettext("Toggle Fog");
	keynames[VLKC_TOGGLE_CAMERA] = NULL;
	keynames[VLKC_TOGGLE_DEBUG] = NULL;
	keynames[VLKC_TOGGLE_PROFILER] = NULL;
	keynames[VLKC_RANGE_PLUS] = wgettext("Increase Viewing Range");
	keynames[VLKC_RANGE_MINUS] = wgettext("Decrease Viewing Range");
	keynames[VLKC_PRINT_DEBUG] = NULL;
	keynames[VLKC_SELECT_PREV] = wgettext("Previous Item");
	keynames[VLKC_SELECT_NEXT] = wgettext("Next Item");
}
Exemplo n.º 18
0
void GUIPauseMenu::regenerateGui(v2u32 screensize)
{
	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	core::rect<s32> rect(
			screensize.X/2 - 580/2,
			screensize.Y/2 - 300/2,
			screensize.X/2 + 580/2,
			screensize.Y/2 + 300/2
	);
	
	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 size = rect.getSize();

	/*
		Add stuff
	*/
	const s32 btn_height = 30;
	const s32 btn_gap = 20;
	const s32 btn_num = 4;
	s32 btn_y = size.Y/2-((btn_num*btn_height+(btn_num-1)*btn_gap))/2;
	changeCtype("");
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 256,
			wgettext("Continue"));
	}
	btn_y += btn_height + btn_gap;
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 261,
			wgettext("Change Password"));
	}
	btn_y += btn_height + btn_gap;
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 260,
			wgettext("Disconnect"));
	}
	btn_y += btn_height + btn_gap;
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 257,
			wgettext("Exit to OS"));
	}

	{
		core::rect<s32> rect(0, 0, 180, 240);
		rect = rect + v2s32(size.X/2 + 90, size.Y/2-rect.getHeight()/2);
		Environment->addStaticText(chartowchar_t(gettext(
		"Default Controls:\n"
		"- WASD: Walk\n"
		"- Mouse left: dig/hit\n"
		"- Mouse right: place/use\n"
		"- Mouse wheel: select item\n"
		"- 0...9: select item\n"
		"- Shift: sneak\n"
		"- R: Toggle viewing all loaded chunks\n"
		"- I: Inventory menu\n"
		"- ESC: This menu\n"
		"- T: Chat\n"
		)), rect, false, true, this, 258);
	}
	{
		core::rect<s32> rect(0, 0, 180, 220);
		rect = rect + v2s32(size.X/2 - 90 - rect.getWidth(), size.Y/2-rect.getHeight()/2);
	
		v2u32 max_texture_size;
		{
			video::IVideoDriver* driver = Environment->getVideoDriver();
			max_texture_size = driver->getMaxTextureSize();
		}

		/*wchar_t text[200];
		swprintf(text, 200,
				L"Minetest-c55\n"
				L"by Perttu Ahola\n"
				L"[email protected]\n\n"
				SWPRINTF_CHARSTRING L"\n"
				L"userdata path = "
				SWPRINTF_CHARSTRING
				,
				BUILD_INFO,
				porting::path_userdata.c_str()
		);*/

		std::ostringstream os;
		os<<"Minetest-delta\n";
		os<<"by Perttu Ahola and contributors\n";
		os<<"[email protected]\n";
		os<<BUILD_INFO<<"\n";
		os<<"ud_path = "<<wrap_rows(porting::path_userdata, 20)<<"\n";
	
		Environment->addStaticText(narrow_to_wide(os.str()).c_str(), rect, false, true, this, 259);
	}
	changeCtype("C");
}
Exemplo n.º 19
0
bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
{
    init_args(game_params, cmd_args);

    // List video modes if requested
    if (list_video_modes)
        return print_video_modes();

    if (!init_engine(game_params.log_level)) {
        errorstream << "Could not initialize game engine." << std::endl;
        return false;
    }

    // Create time getter
    g_timegetter = new IrrlichtTimeGetter(device);

    // Speed tests (done after irrlicht is loaded to get timer)
    if (cmd_args.getFlag("speedtests")) {
        dstream << "Running speed tests" << std::endl;
        speed_tests();
        return true;
    }

    video::IVideoDriver *video_driver = device->getVideoDriver();
    if (video_driver == NULL) {
        errorstream << "Could not initialize video driver." << std::endl;
        return false;
    }

    porting::setXorgClassHint(video_driver->getExposedVideoData(), PROJECT_NAME_C);

    /*
    	This changes the minimum allowed number of vertices in a VBO.
    	Default is 500.
    */
    //driver->setMinHardwareBufferVertexCount(50);

    // Create game callback for menus
    g_gamecallback = new MainGameCallback(device);

    device->setResizable(true);

    if (random_input)
        input = new RandomInputHandler();
    else
        input = new RealInputHandler(device, receiver);

    smgr = device->getSceneManager();
    smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);

    guienv = device->getGUIEnvironment();
    skin = guienv->getSkin();
    skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255));
    skin->setColor(gui::EGDC_3D_LIGHT, video::SColor(0, 0, 0, 0));
    skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 30, 30, 30));
    skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255, 0, 0, 0));
    skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255, 70, 120, 50));
    skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255, 255, 255, 255));

    g_fontengine = new FontEngine(g_settings, guienv);
    FATAL_ERROR_IF(g_fontengine == NULL, "Font engine creation failed.");

#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
    // Irrlicht 1.8 input colours
    skin->setColor(gui::EGDC_EDITABLE, video::SColor(255, 128, 128, 128));
    skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255, 96, 134, 49));
#endif

    // Create the menu clouds
    if (!g_menucloudsmgr)
        g_menucloudsmgr = smgr->createNewSceneManager();
    if (!g_menuclouds)
        g_menuclouds = new Clouds(g_menucloudsmgr->getRootSceneNode(),
                                  g_menucloudsmgr, -1, rand(), 100);
    g_menuclouds->update(v2f(0, 0), video::SColor(255, 200, 200, 255));
    scene::ICameraSceneNode* camera;
    camera = g_menucloudsmgr->addCameraSceneNode(0,
             v3f(0, 0, 0), v3f(0, 60, 100));
    camera->setFarValue(10000);

    /*
    	GUI stuff
    */

    ChatBackend chat_backend;

    // If an error occurs, this is set to something by menu().
    // It is then displayed before	the menu shows on the next call to menu()
    std::string error_message;

    bool first_loop = true;

    /*
    	Menu-game loop
    */
    bool retval = true;
    bool *kill = porting::signal_handler_killstatus();

    while (device->run() && !*kill && !g_gamecallback->shutdown_requested)
    {
        // Set the window caption
        const wchar_t *text = wgettext("Main Menu");
        device->setWindowCaption((narrow_to_wide("MultiCraft") + L" [" + text + L"]").c_str());
        delete[] text;

#ifdef ANDROID
        porting::handleAndroidActivityEvents();
#endif

        try {	// This is used for catching disconnects

            guienv->clear();

            /*
            	We need some kind of a root node to be able to add
            	custom gui elements directly on the screen.
            	Otherwise they won't be automatically drawn.
            */
            guiroot = guienv->addStaticText(L"", core::rect<s32>(0, 0, 10000, 10000));

            bool game_has_run = launch_game(error_message, game_params, cmd_args);

            // If skip_main_menu, we only want to startup once
            if (skip_main_menu && !first_loop)
                break;

            first_loop = false;

            if (!game_has_run) {
                if (skip_main_menu)
                    break;
                else
                    continue;
            }

            // Break out of menu-game loop to shut down cleanly
            if (!device->run() || *kill) {
                if (g_settings_path != "")
                    g_settings->updateConfigFile(g_settings_path.c_str());
                break;
            }

            if (current_playername.length() > PLAYERNAME_SIZE-1) {
                error_message = gettext("Player name too long.");
                playername = current_playername.substr(0, PLAYERNAME_SIZE-1);
                g_settings->set("name", playername);
                continue;
            }

            device->getVideoDriver()->setTextureCreationFlag(
                video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));

#ifdef HAVE_TOUCHSCREENGUI
            receiver->m_touchscreengui = new TouchScreenGUI(device, receiver);
            g_touchscreengui = receiver->m_touchscreengui;
#endif
            the_game(
                kill,
                random_input,
                input,
                device,
                worldspec.path,
                current_playername,
                current_password,
                current_address,
                current_port,
                error_message,
                chat_backend,
                gamespec,
                simple_singleplayer_mode
            );
            smgr->clear();

#ifdef HAVE_TOUCHSCREENGUI
            delete g_touchscreengui;
            g_touchscreengui = NULL;
            receiver->m_touchscreengui = NULL;
#endif

        } //try
        catch (con::PeerNotFoundException &e) {
            error_message = gettext("Connection error (timed out?)");
            errorstream << error_message << std::endl;
        }

#ifdef NDEBUG
        catch (std::exception &e) {
            std::string error_message = "Some exception: \"";
            error_message += e.what();
            error_message += "\"";
            errorstream << error_message << std::endl;
        }
#endif

        // If no main menu, show error and exit
        if (skip_main_menu) {
            if (!error_message.empty()) {
                verbosestream << "error_message = "
                              << error_message << std::endl;
                retval = false;
            }
            break;
        }
    } // Menu-game loop

    g_menuclouds->drop();
    g_menucloudsmgr->drop();

    return retval;
}
Exemplo n.º 20
0
void Client::afterContentReceived()
{
	infostream<<"Client::afterContentReceived() started"<<std::endl;
	assert(m_itemdef_received); // pre-condition
	assert(m_nodedef_received); // pre-condition
	assert(mediaReceived()); // pre-condition

	const wchar_t* text = wgettext("Loading textures...");

	// Clear cached pre-scaled 2D GUI images, as this cache
	// might have images with the same name but different
	// content from previous sessions.
	guiScalingCacheClear();

	// Rebuild inherited images and recreate textures
	infostream<<"- Rebuilding images and textures"<<std::endl;
	RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 70);
	m_tsrc->rebuildImagesAndTextures();
	delete[] text;

	// Rebuild shaders
	infostream<<"- Rebuilding shaders"<<std::endl;
	text = wgettext("Rebuilding shaders...");
	RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 71);
	m_shsrc->rebuildShaders();
	delete[] text;

	// Update node aliases
	infostream<<"- Updating node aliases"<<std::endl;
	text = wgettext("Initializing nodes...");
	RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 72);
	m_nodedef->updateAliases(m_itemdef);
	std::string texture_path = g_settings->get("texture_path");
	if (!texture_path.empty() && fs::IsDir(texture_path))
		m_nodedef->applyTextureOverrides(texture_path + DIR_DELIM + "override.txt");
	m_nodedef->setNodeRegistrationStatus(true);
	m_nodedef->runNodeResolveCallbacks();
	delete[] text;

	// Update node textures and assign shaders to each tile
	infostream<<"- Updating node textures"<<std::endl;
	TextureUpdateArgs tu_args;
	tu_args.guienv = guienv;
	tu_args.last_time_ms = porting::getTimeMs();
	tu_args.last_percent = 0;
	tu_args.text_base =  wgettext("Initializing nodes");
	tu_args.tsrc = m_tsrc;
	m_nodedef->updateTextures(this, texture_update_progress, &tu_args);
	delete[] tu_args.text_base;

	// Start mesh update thread after setting up content definitions
	infostream<<"- Starting mesh update thread"<<std::endl;
	m_mesh_update_thread.start();

	m_state = LC_Ready;
	sendReady();

	if (g_settings->getBool("enable_client_modding")) {
		m_script->on_client_ready(m_env.getLocalPlayer());
		m_script->on_connect();
	}

	text = wgettext("Done!");
	RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 100);
	infostream<<"Client::afterContentReceived() done"<<std::endl;
	delete[] text;
}
Exemplo n.º 21
0
void GUIMultiplayerMenu::regenerateGui(v2u32 screensize)
{
	std::wstring text_name;
	std::wstring text_address;
	std::wstring text_port;

	m_screensize = screensize;

	// Client options
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
		if (e != NULL) {
			text_name = e->getText();
		}else{
			text_name = m_data.mmdata->name;
		}
		if (text_name == L"")
			text_name = narrow_to_wide(porting::getUser());
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_ADDRESS_INPUT);
		if (e != NULL) {
			text_address = e->getText();
		}else{
			text_address = m_data.mmdata->address;
		}
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_PORT_INPUT);
		if (e != NULL) {
			text_port = e->getText();
		}else{
			text_port = m_data.mmdata->port;
		}
	}

	/*
	 Remove stuff
	 */
	removeChildren();

	/*
	 Calculate new sizes and positions
	 */

	v2s32 size(800, 500);

	core::rect<s32> rect(
			screensize.X/2 - size.X/2,
			screensize.Y/2 - size.Y/2,
			screensize.X/2 + size.X/2,
			screensize.Y/2 + size.Y/2
	);

	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	// Main Menu button
	{
		core::rect<s32> rect(0, 0, 200, 40);
		rect += v2s32(25, 200);
		Environment->addButton(rect, this, GUI_ID_TAB_MP_MAINMENU, wgettext("Main Menu"));
	}

	// Dynamic List button
	{
		core::rect<s32> rect(0, 0, 180, 40);
		rect += v2s32(35, 260);
		Environment->addButton(rect, this, GUI_ID_TAB_MP_LIST, wgettext("All Servers"));
	}
	// Favourites List button
	{
		core::rect<s32> rect(0, 0, 180, 40);
		rect += v2s32(35, 305);
		Environment->addButton(rect, this, GUI_ID_TAB_MP_FAVOURITES, wgettext("Favourite Servers"));
	}
	// Custom Connect button (the old multiplayer menu)
	{
		core::rect<s32> rect(0, 0, 180, 40);
		rect += v2s32(35, 350);
		Environment->addButton(rect, this, GUI_ID_TAB_MP_CUSTOM, wgettext("Custom Connect"));
	}

	v2s32 topleft_content(250, 0);
	{
		core::rect<s32> rect(0, 0, 550, 20);
		rect += topleft_content + v2s32(0, 10);
		gui::IGUIStaticText *t = Environment->addStaticText(wgettext("Multi Player"), rect, false, true, this, -1);
		t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	if (m_data.selected_tab == TAB_MP_CUSTOM) {
		{
			core::rect<s32> rect(0, 0, 550, 20);
			rect += topleft_content + v2s32(0, 30);
			gui::IGUIStaticText *t = Environment->addStaticText(wgettext("Custom Connection"), rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
		}
		// Address + port
		{
			core::rect<s32> rect(0, 0, 110, 20);
			rect += topleft_content + v2s32(120, 60);
			Environment->addStaticText(wgettext("Address/Port"), rect, false, true, this, -1);
		}
		{
			if (text_address == L"")
				text_address = L"servers.voxelands.com";
			core::rect<s32> rect(0, 0, 230, 30);
			rect += topleft_content + v2s32(135, 90);
#if USE_FREETYPE
			new gui::intlGUIEditBox(text_address.c_str(), true, Environment, this, GUI_ID_ADDRESS_INPUT, rect);
#else
			Environment->addEditBox(text_address.c_str(), rect, false, this, GUI_ID_ADDRESS_INPUT);
#endif
		}
		{
			core::rect<s32> rect(0, 0, 120, 30);
			rect += topleft_content + v2s32(245, 125);
#if USE_FREETYPE
			new gui::intlGUIEditBox(text_port.c_str(), true, Environment, this, GUI_ID_PORT_INPUT, rect);
#else
			Environment->addEditBox(text_port.c_str(), rect, false, this, GUI_ID_PORT_INPUT);
#endif
		}
		{
			core::rect<s32> rect(0, 0, 180, 30);
			rect += topleft_content + v2s32(80, 160);
			Environment->addButton(rect, this, GUI_ID_ADDFAV_BUTTON, wgettext("Add to Favourites"));
		}
		{
			core::rect<s32> rect(0, 0, 180, 30);
			rect += topleft_content + v2s32(270, 160);
			Environment->addButton(rect, this, GUI_ID_CONNECT_BUTTON, wgettext("Connect"));
		}
	}else if (m_data.selected_tab == TAB_MP_CONNECT) {
		// Nickname + password
		{
			core::rect<s32> rect(0, 0, 110, 20);
			rect += topleft_content + v2s32(120, 60);
			Environment->addStaticText(wgettext("Name/Password"), rect, false, true, this, -1);
		}
		{
			core::rect<s32> rect(0, 0, 230, 30);
			rect += topleft_content + v2s32(135, 90);
#if USE_FREETYPE
			new gui::intlGUIEditBox(text_name.c_str(), true, Environment, this, GUI_ID_NAME_INPUT, rect);
#else
			Environment->addEditBox(text_name.c_str(), rect, false, this, GUI_ID_NAME_INPUT);
#endif
		}
		{
			core::rect<s32> rect(0, 0, 230, 30);
			rect += topleft_content + v2s32(135, 125);
			gui::IGUIEditBox *e;
#if USE_FREETYPE
			e = (gui::IGUIEditBox *) new gui::intlGUIEditBox(L"", true, Environment, this, GUI_ID_PW_INPUT, rect);
#else
			e = Environment->addEditBox(L"", rect, false, this, GUI_ID_PW_INPUT);
#endif
			e->setPasswordBox(true);
			Environment->setFocus(e);

		// Start game button
		{
			core::rect<s32> rect(0, 0, 180, 30);
			rect += topleft_content + v2s32(160, 160);
			Environment->addButton(rect, this, GUI_ID_START_BUTTON, wgettext("Join Server"));
		}
		}
	}else{
		gui::IGUIListBox *box = NULL;
		gui::IGUIStaticText *header = NULL;
		std::vector<ServerInfo> *list = NULL;

		{
			core::rect<s32> rect(0, 0, 550, 20);
			rect += topleft_content + v2s32(0, 30);
			header = Environment->addStaticText(L"", rect, false, true, this, -1);
			header->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
		}
		{
			core::rect<s32> rect(0, 0, 350, 200);
			rect += topleft_content + v2s32(100, 60);
			box = Environment->addListBox(rect, this, GUI_ID_SERVER_LIST, true);
			box->setItemHeight(25);
		}

		if (m_data.selected_tab == TAB_MP_FAVOURITES) {
			header->setText(wgettext("My Favourites"));
			list = &m_data.favourites;
		}else{
			header->setText(wgettext("Server List"));
			list = &m_data.servers;
			{
				core::rect<s32> rect(0, 0, 180, 25);
				rect += topleft_content + v2s32(270, 260);
				Environment->addButton(rect, this, GUI_ID_REFRESH_BUTTON, wgettext("Get New List"));
			}
		}

		for (std::vector<ServerInfo>::iterator i = list->begin(); i != list->end(); i++) {
			box->addItem(i->name.c_str());
		}

		if (m_data.selected_row > -1) {
			ServerInfo info = list->at(m_data.selected_row);
			if (info.name == L"") {
				m_data.selected_row = -1;
			}else{
				box->setSelected(m_data.selected_row);
				{
					core::rect<s32> rect(0, 0, 550, 20);
					rect += topleft_content + v2s32(0, 300);
					gui::IGUIStaticText *t = Environment->addStaticText(info.name.c_str(), rect, false, true, this, -1);
					t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
				}
				{
					core::rect<s32> rect(0, 0, 350, 20);
					rect += topleft_content + v2s32(100, 330);
					gui::IGUIStaticText *t = Environment->addStaticText(info.addr.c_str(), rect, false, true, this, -1);
					t->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_UPPERLEFT);
				}
				{
					core::rect<s32> rect(0, 0, 350, 20);
					rect += topleft_content + v2s32(100, 350);
					gui::IGUIStaticText *t = Environment->addStaticText(info.mode.c_str(), rect, false, true, this, -1);
					t->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_UPPERLEFT);
				}

				if (info.is_favourite) {
					{
						core::rect<s32> rect(0, 0, 180, 30);
						rect += topleft_content + v2s32(80, 390);
						Environment->addButton(rect, this, GUI_ID_REMFAV_BUTTON, wgettext("Remove from Favourites"));
					}
				}else{
					{
						core::rect<s32> rect(0, 0, 180, 30);
						rect += topleft_content + v2s32(80, 390);
						Environment->addButton(rect, this, GUI_ID_ADDFAV_BUTTON, wgettext("Add to Favourites"));
					}
				}

				{
					core::rect<s32> rect(0, 0, 180, 30);
					rect += topleft_content + v2s32(270, 390);
					Environment->addButton(rect, this, GUI_ID_CONNECT_BUTTON, wgettext("Connect"));
				}
			}
		}
	}
}
Exemplo n.º 22
0
void GUIMainMenu::regenerateGui(v2u32 screensize)
{
	std::wstring text_name;
	std::wstring text_address;
	std::wstring text_port;
	bool creative_mode;
	bool enable_damage;
	bool fancy_trees;
	bool smooth_lighting;
	
	// Client options
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
		if(e != NULL)
			text_name = e->getText();
		else
			text_name = m_data->name;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_ADDRESS_INPUT);
		if(e != NULL)
			text_address = e->getText();
		else
			text_address = m_data->address;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_PORT_INPUT);
		if(e != NULL)
			text_port = e->getText();
		else
			text_port = m_data->port;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_FANCYTREE_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			fancy_trees = ((gui::IGUICheckBox*)e)->isChecked();
		else
			fancy_trees = m_data->fancy_trees;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_SMOOTH_LIGHTING_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			smooth_lighting = ((gui::IGUICheckBox*)e)->isChecked();
		else
			smooth_lighting = m_data->smooth_lighting;
	}
	
	// Server options
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_CREATIVE_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			creative_mode = ((gui::IGUICheckBox*)e)->isChecked();
		else
			creative_mode = m_data->creative_mode;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_DAMAGE_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
		else
			enable_damage = m_data->enable_damage;
	}

	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	
	v2s32 size(620, 430);

	core::rect<s32> rect(
			screensize.X/2 - size.X/2,
			screensize.Y/2 - size.Y/2,
			screensize.X/2 + size.X/2,
			screensize.Y/2 + size.Y/2
	);

	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	//v2s32 size = rect.getSize();

	/*
		Add stuff
	*/

	/*
		Client section
	*/

	v2s32 topleft_client(40, 0);
	v2s32 size_client = size - v2s32(40, 0);
	
	changeCtype("");
	{
		core::rect<s32> rect(0, 0, 20, 125);
		rect += topleft_client + v2s32(-15, 60);
		const wchar_t *text = L"C\nL\nI\nE\nN\nT";
		//gui::IGUIStaticText *t =
		Environment->addStaticText(text, rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	// Nickname + password
	{
		core::rect<s32> rect(0, 0, 110, 20);
		rect += topleft_client + v2s32(35, 50+6);
		Environment->addStaticText(wgettext("Name/Password"), 
			rect, false, true, this, -1);
	}
	changeCtype("C");
	{
		core::rect<s32> rect(0, 0, 230, 30);
		rect += topleft_client + v2s32(160, 50);
		gui::IGUIElement *e = 
		Environment->addEditBox(text_name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
		if(text_name == L"")
			Environment->setFocus(e);
	}
	{
		core::rect<s32> rect(0, 0, 120, 30);
		rect += topleft_client + v2s32(size_client.X-60-100, 50);
		gui::IGUIEditBox *e =
		Environment->addEditBox(L"", rect, true, this, 264);
		e->setPasswordBox(true);
		if(text_name != L"" && text_address != L"")
			Environment->setFocus(e);

	}
	changeCtype("");
	// Address + port
	{
		core::rect<s32> rect(0, 0, 110, 20);
		rect += topleft_client + v2s32(35, 100+6);
		Environment->addStaticText(wgettext("Address/Port"),
			rect, false, true, this, -1);
	}
	changeCtype("C");
	{
		core::rect<s32> rect(0, 0, 230, 30);
		rect += topleft_client + v2s32(160, 100);
		gui::IGUIElement *e = 
		Environment->addEditBox(text_address.c_str(), rect, true, this, GUI_ID_ADDRESS_INPUT);
		if(text_name != L"" && text_address == L"")
			Environment->setFocus(e);
	}
	{
		core::rect<s32> rect(0, 0, 120, 30);
		//rect += topleft_client + v2s32(160+250+20, 125);
		rect += topleft_client + v2s32(size_client.X-60-100, 100);
		Environment->addEditBox(text_port.c_str(), rect, true, this, GUI_ID_PORT_INPUT);
	}
	changeCtype("");
	{
		core::rect<s32> rect(0, 0, 400, 20);
		rect += topleft_client + v2s32(160, 100+35);
		Environment->addStaticText(wgettext("Leave address blank to start a local server."),
			rect, false, true, this, -1);
	}
	{
		core::rect<s32> rect(0, 0, 250, 30);
		rect += topleft_client + v2s32(35, 150);
		Environment->addCheckBox(fancy_trees, rect, this, GUI_ID_FANCYTREE_CB,
			wgettext("Fancy trees")); 
	}
	{
		core::rect<s32> rect(0, 0, 250, 30);
		rect += topleft_client + v2s32(35, 150+30);
		Environment->addCheckBox(smooth_lighting, rect, this, GUI_ID_SMOOTH_LIGHTING_CB,
				wgettext("Smooth Lighting"));
	}
	// Start game button
	{
		core::rect<s32> rect(0, 0, 180, 30);
		//rect += topleft_client + v2s32(size_client.X/2-180/2, 225-30/2);
		rect += topleft_client + v2s32(size_client.X-180-40, 150+25);
		Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
			wgettext("Start Game / Connect"));
	}

	// Key change button
	{
		core::rect<s32> rect(0, 0, 100, 30);
		//rect += topleft_client + v2s32(size_client.X/2-180/2, 225-30/2);
		rect += topleft_client + v2s32(size_client.X-180-40-100-20, 150+25);
		Environment->addButton(rect, this, GUI_ID_CHANGE_KEYS_BUTTON,
			wgettext("Change keys"));
	}
	/*
		Server section
	*/

	v2s32 topleft_server(40, 250);
	v2s32 size_server = size - v2s32(40, 0);
	
	{
		core::rect<s32> rect(0, 0, 20, 125);
		rect += topleft_server + v2s32(-15, 40);
		const wchar_t *text = L"S\nE\nR\nV\nE\nR";
		//gui::IGUIStaticText *t =
		Environment->addStaticText(text, rect, false, true, this, -1);
		//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
	}

	// Server parameters
	{
		core::rect<s32> rect(0, 0, 250, 30);
		rect += topleft_server + v2s32(35, 30);
		Environment->addCheckBox(creative_mode, rect, this, GUI_ID_CREATIVE_CB,
			wgettext("Creative Mode"));
	}
	{
		core::rect<s32> rect(0, 0, 250, 30);
		rect += topleft_server + v2s32(35, 60);
		Environment->addCheckBox(enable_damage, rect, this, GUI_ID_DAMAGE_CB,
			wgettext("Enable Damage"));
	}
	// Map delete button
	{
		core::rect<s32> rect(0, 0, 130, 30);
		//rect += topleft_server + v2s32(size_server.X-40-130, 100+25);
		rect += topleft_server + v2s32(40, 100+25);
		Environment->addButton(rect, this, GUI_ID_DELETE_MAP_BUTTON,
			  wgettext("Delete map"));
	}
	changeCtype("C");
}
Exemplo n.º 23
0
void GUIMainMenu::regenerateGui(v2u32 screensize)
{
	m_is_regenerating = true;
	/*
		Read stuff from elements into m_data
	*/
	readInput(m_data);

	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	
	v2s32 size(screensize.X, screensize.Y);

	core::rect<s32> rect(
			screensize.X/2 - size.X/2,
			screensize.Y/2 - size.Y/2,
			screensize.X/2 + size.X/2,
			screensize.Y/2 + size.Y/2
	);

	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	//v2s32 size = rect.getSize();

	/*
		Add stuff
	*/

	changeCtype("");

	// Version
	//if(m_data->selected_tab != TAB_CREDITS)
	{
		core::rect<s32> rect(0, 0, size.X, 40);
		rect += v2s32(4, 0);
		Environment->addStaticText(narrow_to_wide(
				"Minetest-c55 " VERSION_STRING).c_str(),
				rect, false, true, this, -1);
	}

	//v2s32 center(size.X/2, size.Y/2);
	v2s32 c800(size.X/2-400, size.Y/2-300);
	
	m_topleft_client = c800 + v2s32(90, 70+50+30);
	m_size_client = v2s32(620, 270);

	m_size_server = v2s32(620, 140);

	if(m_data->selected_tab == TAB_ADVANCED)
	{
		m_topleft_client = c800 + v2s32(90, 70+50+30);
		m_size_client = v2s32(620, 200);

		m_size_server = v2s32(620, 140);
	}

	m_topleft_server = m_topleft_client + v2s32(0, m_size_client.Y+20);
	
	// Tabs
#if 1
	{
		core::rect<s32> rect(0, 0, m_size_client.X, 30);
		rect += m_topleft_client + v2s32(0, -30);
		gui::IGUITabControl *e = Environment->addTabControl(
				rect, this, true, true, GUI_ID_TAB_CONTROL);
		e->addTab(L"Singleplayer");
		e->addTab(L"Multiplayer");
		e->addTab(L"Advanced");
		e->addTab(L"Settings");
		e->addTab(L"Credits");
		e->setActiveTab(m_data->selected_tab);
	}
#endif
	
	if(m_data->selected_tab == TAB_SINGLEPLAYER)
	{
		// HYBRID
		{
			core::rect<s32> rect(0, 0, 10, m_size_client.Y);
			rect += m_topleft_client + v2s32(15, 0);
			//const wchar_t *text = L"H\nY\nB\nR\nI\nD";
			const wchar_t *text = L"T\nA\nP\nE\n\nA\nN\nD\n\nG\nL\nU\nE";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		u32 bs = 5;
		// World selection listbox
		u32 world_sel_h = 160;
		u32 world_sel_w = 365;
		//s32 world_sel_x = 50;
		s32 world_sel_x = m_size_client.X-world_sel_w-30;
		s32 world_sel_y = 30;
		u32 world_button_count = 3;
		u32 world_button_w = (world_sel_w)/world_button_count - bs
				+ bs/(world_button_count-1);
		{
			core::rect<s32> rect(0, 0, world_sel_w-4, 20);
			rect += m_topleft_client + v2s32(world_sel_x+4, world_sel_y-20);
			/*gui::IGUIStaticText *e =*/ Environment->addStaticText(
					wgettext("Select World:"), 
					rect, false, true, this, -1);
			/*e->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);*/
		}
		{
			core::rect<s32> rect(0, 0, world_sel_w, world_sel_h);
			rect += m_topleft_client + v2s32(world_sel_x, world_sel_y);
			gui::IGUIListBox *e = Environment->addListBox(rect, this,
					GUI_ID_WORLD_LISTBOX);
			e->setDrawBackground(true);
			for(std::vector<WorldSpec>::const_iterator i = m_data->worlds.begin();
					i != m_data->worlds.end(); i++){
				e->addItem(narrow_to_wide(i->name+" ["+i->gameid+"]").c_str());
			}
			e->setSelected(m_data->selected_world);
			Environment->setFocus(e);
		}
		// Delete world button
		{
			core::rect<s32> rect(0, 0, world_button_w, 30);
			rect += m_topleft_client + v2s32(world_sel_x, world_sel_y+world_sel_h+0);
			Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
				  wgettext("Delete"));
		}
		// Create world button
		{
			core::rect<s32> rect(0, 0, world_button_w, 30);
			rect += m_topleft_client + v2s32(world_sel_x+world_button_w+bs, world_sel_y+world_sel_h+0);
			Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
				  wgettext("New"));
		}
		// Configure world button
		{
			core::rect<s32> rect(0, 0, world_button_w, 30);
			rect += m_topleft_client + v2s32(world_sel_x+(world_button_w+bs)*2,
					world_sel_y+world_sel_h+0);
			Environment->addButton(rect, this, GUI_ID_CONFIGURE_WORLD_BUTTON,
				  wgettext("Configure"));
		}
		// Start game button
		{
			/*core::rect<s32> rect(0, 0, world_button_w, 30);
			rect += m_topleft_client + v2s32(world_sel_x+(world_button_w+bs)*3,
					world_sel_y+world_sel_h+0);*/
			u32 bw = 160;
			/*core::rect<s32> rect(0, 0, bw, 30);
			rect += m_topleft_client + v2s32(m_size_client.X-bw-30,
					m_size_client.Y-30-15);*/
			core::rect<s32> rect(0, 0, bw, 30);
			rect += m_topleft_client + v2s32(world_sel_x+world_sel_w-bw,
					world_sel_y+world_sel_h+30+bs);
			Environment->addButton(rect, this,
					GUI_ID_JOIN_GAME_BUTTON, wgettext("Play"));
		}
		// Options
		s32 option_x = 50;
		//s32 option_x = 50+world_sel_w+20;
		s32 option_y = 30;
		u32 option_w = 150;
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y+20*0);
			Environment->addCheckBox(m_data->creative_mode, rect, this,
					GUI_ID_CREATIVE_CB, wgettext("Creative Mode"));
		}
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y+20*1);
			Environment->addCheckBox(m_data->enable_damage, rect, this,
					GUI_ID_DAMAGE_CB, wgettext("Enable Damage"));
		}
		changeCtype("C");
	}
	else if(m_data->selected_tab == TAB_MULTIPLAYER)
	{
		changeCtype("");
		// CLIENT
		{
			core::rect<s32> rect(0, 0, 10, m_size_client.Y);
			rect += m_topleft_client + v2s32(15, 0);
			const wchar_t *text = L"C\nL\nI\nE\nN\nT";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		// Nickname + password
		{
			core::rect<s32> rect(0, 0, 110, 20);
			rect += m_topleft_client + v2s32(35+30, 50+6);
			Environment->addStaticText(wgettext("Name/Password"), 
				rect, false, true, this, -1);
		}
		changeCtype("C");
		{
			core::rect<s32> rect(0, 0, 230, 30);
			rect += m_topleft_client + v2s32(160+30, 50);
			gui::IGUIElement *e = 
			Environment->addEditBox(m_data->name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
			if(m_data->name == L"")
				Environment->setFocus(e);
		}
		{
			core::rect<s32> rect(0, 0, 120, 30);
			rect += m_topleft_client + v2s32(m_size_client.X-60-100, 50);
			gui::IGUIEditBox *e =
			Environment->addEditBox(L"", rect, true, this, 264);
			e->setPasswordBox(true);
			if(m_data->name != L"" && m_data->address != L"")
				Environment->setFocus(e);

		}
		changeCtype("");
		// Address + port
		{
			core::rect<s32> rect(0, 0, 110, 20);
			rect += m_topleft_client + v2s32(35+30, 100+6);
			Environment->addStaticText(wgettext("Address/Port"),
				rect, false, true, this, -1);
		}
		changeCtype("C");
		{
			core::rect<s32> rect(0, 0, 230, 30);
			rect += m_topleft_client + v2s32(160+30, 100);
			gui::IGUIElement *e = 
			Environment->addEditBox(m_data->address.c_str(), rect, true,
					this, GUI_ID_ADDRESS_INPUT);
			if(m_data->name != L"" && m_data->address == L"")
				Environment->setFocus(e);
		}
		{
			core::rect<s32> rect(0, 0, 120, 30);
			rect += m_topleft_client + v2s32(m_size_client.X-60-100, 100);
			Environment->addEditBox(m_data->port.c_str(), rect, true,
					this, GUI_ID_PORT_INPUT);
		}
		changeCtype("");
		// Start game button
		{
			core::rect<s32> rect(0, 0, 180, 30);
			rect += m_topleft_client + v2s32(m_size_client.X-180-30,
					m_size_client.Y-30-15);
			Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
				wgettext("Start Game / Connect"));
		}
		changeCtype("C");
	}
	else if(m_data->selected_tab == TAB_ADVANCED)
	{
		changeCtype("");
		// CLIENT
		{
			core::rect<s32> rect(0, 0, 10, m_size_client.Y);
			rect += m_topleft_client + v2s32(15, 0);
			const wchar_t *text = L"C\nL\nI\nE\nN\nT";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		// Nickname + password
		{
			core::rect<s32> rect(0, 0, 110, 20);
			rect += m_topleft_client + v2s32(35+30, 35+6);
			Environment->addStaticText(wgettext("Name/Password"), 
				rect, false, true, this, -1);
		}
		changeCtype("C");
		{
			core::rect<s32> rect(0, 0, 230, 30);
			rect += m_topleft_client + v2s32(160+30, 35);
			gui::IGUIElement *e = 
			Environment->addEditBox(m_data->name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
			if(m_data->name == L"")
				Environment->setFocus(e);
		}
		{
			core::rect<s32> rect(0, 0, 120, 30);
			rect += m_topleft_client + v2s32(m_size_client.X-60-100, 35);
			gui::IGUIEditBox *e =
			Environment->addEditBox(L"", rect, true, this, 264);
			e->setPasswordBox(true);
			if(m_data->name != L"" && m_data->address != L"")
				Environment->setFocus(e);

		}
		changeCtype("");
		// Address + port
		{
			core::rect<s32> rect(0, 0, 110, 20);
			rect += m_topleft_client + v2s32(35+30, 75+6);
			Environment->addStaticText(wgettext("Address/Port"),
				rect, false, true, this, -1);
		}
		changeCtype("C");
		{
			core::rect<s32> rect(0, 0, 230, 30);
			rect += m_topleft_client + v2s32(160+30, 75);
			gui::IGUIElement *e = 
			Environment->addEditBox(m_data->address.c_str(), rect, true,
					this, GUI_ID_ADDRESS_INPUT);
			if(m_data->name != L"" && m_data->address == L"")
				Environment->setFocus(e);
		}
		{
			core::rect<s32> rect(0, 0, 120, 30);
			rect += m_topleft_client + v2s32(m_size_client.X-60-100, 75);
			Environment->addEditBox(m_data->port.c_str(), rect, true,
					this, GUI_ID_PORT_INPUT);
		}
		changeCtype("");
		{
			core::rect<s32> rect(0, 0, 400, 20);
			rect += m_topleft_client + v2s32(160+30, 75+35);
			Environment->addStaticText(wgettext("Leave address blank to start a local server."),
				rect, false, true, this, -1);
		}
		// Start game button
		{
			core::rect<s32> rect(0, 0, 180, 30);
			rect += m_topleft_client + v2s32(m_size_client.X-180-30,
					m_size_client.Y-30-20);
			Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
				wgettext("Start Game / Connect"));
		}
		/*
			Server section
		*/
		// SERVER
		{
			core::rect<s32> rect(0, 0, 10, m_size_server.Y);
			rect += m_topleft_server + v2s32(15, 0);
			const wchar_t *text = L"S\nE\nR\nV\nE\nR";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		// Server parameters
		{
			core::rect<s32> rect(0, 0, 250, 30);
			rect += m_topleft_server + v2s32(30+20+250+20, 20);
			Environment->addCheckBox(m_data->creative_mode, rect, this, GUI_ID_CREATIVE_CB,
				wgettext("Creative Mode"));
		}
		{
			core::rect<s32> rect(0, 0, 250, 30);
			rect += m_topleft_server + v2s32(30+20+250+20, 40);
			Environment->addCheckBox(m_data->enable_damage, rect, this, GUI_ID_DAMAGE_CB,
				wgettext("Enable Damage"));
		}
		// Delete world button
		{
			core::rect<s32> rect(0, 0, 130, 30);
			rect += m_topleft_server + v2s32(30+20+250+20, 90);
			Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
				  wgettext("Delete world"));
		}
		// Create world button
		{
			core::rect<s32> rect(0, 0, 130, 30);
			rect += m_topleft_server + v2s32(30+20+250+20+140, 90);
			Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
				  wgettext("Create world"));
		}
		// World selection listbox
		{
			core::rect<s32> rect(0, 0, 250, 120);
			rect += m_topleft_server + v2s32(30+20, 10);
			gui::IGUIListBox *e = Environment->addListBox(rect, this,
					GUI_ID_WORLD_LISTBOX);
			e->setDrawBackground(true);
			for(std::vector<WorldSpec>::const_iterator i = m_data->worlds.begin();
					i != m_data->worlds.end(); i++){
				e->addItem(narrow_to_wide(i->name+" ["+i->gameid+"]").c_str());
			}
			e->setSelected(m_data->selected_world);
		}
		changeCtype("C");
	}
	else if(m_data->selected_tab == TAB_SETTINGS)
	{
		{
			core::rect<s32> rect(0, 0, 10, m_size_client.Y);
			rect += m_topleft_client + v2s32(15, 0);
			const wchar_t *text = L"S\nE\nT\nT\nI\nN\nG\nS";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		s32 option_x = 70;
		s32 option_y = 50;
		u32 option_w = 150;
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y);
			Environment->addCheckBox(m_data->fancy_trees, rect, this,
					GUI_ID_FANCYTREE_CB, wgettext("Fancy trees")); 
		}
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y+20);
			Environment->addCheckBox(m_data->smooth_lighting, rect, this,
					GUI_ID_SMOOTH_LIGHTING_CB, wgettext("Smooth Lighting"));
		}
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y+20*2);
			Environment->addCheckBox(m_data->clouds_3d, rect, this,
					GUI_ID_3D_CLOUDS_CB, wgettext("3D Clouds"));
		}
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y+20*3);
			Environment->addCheckBox(m_data->opaque_water, rect, this,
					GUI_ID_OPAQUE_WATER_CB, wgettext("Opaque water"));
		}
		// Key change button
		{
			core::rect<s32> rect(0, 0, 120, 30);
			/*rect += m_topleft_client + v2s32(m_size_client.X-120-30,
					m_size_client.Y-30-20);*/
			rect += m_topleft_client + v2s32(option_x, option_y+120);
			Environment->addButton(rect, this,
					GUI_ID_CHANGE_KEYS_BUTTON, wgettext("Change keys"));
		}
		changeCtype("C");
	}
	else if(m_data->selected_tab == TAB_CREDITS)
	{
		// CREDITS
		{
			core::rect<s32> rect(0, 0, 10, m_size_client.Y);
			rect += m_topleft_client + v2s32(15, 0);
			const wchar_t *text = L"C\nR\nE\nD\nI\nT\nS";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		{
			core::rect<s32> rect(0, 0, 620, 250);
			rect += m_topleft_client + v2s32(130+14, 50+35);
			Environment->addStaticText(narrow_to_wide(
			"Minetest-c55 " VERSION_STRING "\n"
			"http://c55.me/minetest/\n"
			"\n"
			"by Perttu Ahola <*****@*****.**>\n"
			"and contributors"
			).c_str(), rect, false, true, this, -1);
		}
	}

	m_is_regenerating = false;
}
Exemplo n.º 24
0
bool GUIMainMenu::OnEvent(const SEvent& event)
{
	if(event.EventType==EET_KEY_INPUT_EVENT)
	{
		if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
		{
			m_gamecallback->exitToOS();
			quitMenu();
			return true;
		}
		if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown)
		{
			acceptInput();
			quitMenu();
			return true;
		}
	}
	if(event.EventType==EET_GUI_EVENT)
	{
		if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST
				&& isVisible())
		{
			if(!canTakeFocus(event.GUIEvent.Element))
			{
				dstream<<"GUIMainMenu: Not allowing focus change."
						<<std::endl;
				// Returning true disables focus change
				return true;
			}
		}
		if(event.GUIEvent.EventType==gui::EGET_TAB_CHANGED)
		{
			if(!m_is_regenerating)
				regenerateGui(m_screensize_old);
			return true;
		}
		if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
		{
			switch(event.GUIEvent.Caller->getID())
			{
			case GUI_ID_JOIN_GAME_BUTTON: {
				MainMenuData cur;
				readInput(&cur);
				if(cur.address == L"" && getTab() == TAB_MULTIPLAYER){
					(new GUIMessageMenu(env, parent, -1, menumgr,
							wgettext("Address required."))
							)->drop();
					return true;
				}
				acceptInput();
				quitMenu();
				return true;
			}
			case GUI_ID_CHANGE_KEYS_BUTTON: {
				GUIKeyChangeMenu *kmenu = new GUIKeyChangeMenu(env, parent, -1,menumgr);
				kmenu->drop();
				return true;
			}
			case GUI_ID_DELETE_WORLD_BUTTON: {
				MainMenuData cur;
				readInput(&cur);
				if(cur.selected_world == -1){
					(new GUIMessageMenu(env, parent, -1, menumgr,
							wgettext("Cannot delete world: Nothing selected"))
							)->drop();
				} else {
					WorldSpec spec = m_data->worlds[cur.selected_world];
					ConfirmDestDeleteWorld *dest = new
							ConfirmDestDeleteWorld(spec, this);
					(new GUIConfirmMenu(env, parent, -1, menumgr, dest,
							(std::wstring(wgettext("Delete world "))
							+L"\""+narrow_to_wide(spec.name)+L"\"?").c_str()
							))->drop();
				}
				return true;
			}
			case GUI_ID_CREATE_WORLD_BUTTON: {
				std::vector<SubgameSpec> games = getAvailableGames();
				if(games.size() == 0){
					GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
							-1, menumgr,
							wgettext("Cannot create world: No games found"));
					menu->drop();
				} else {
					CreateWorldDest *dest = new CreateWorldDestMainMenu(this);
					GUICreateWorld *menu = new GUICreateWorld(env, parent, -1,
							menumgr, dest, games);
					menu->drop();
				}
				return true;
			}
			case GUI_ID_CONFIGURE_WORLD_BUTTON: {
				GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
						-1, menumgr,
						wgettext("Nothing here"));
				menu->drop();
				return true;
			}
			}
		}
		if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
		{
			switch(event.GUIEvent.Caller->getID())
			{
				case GUI_ID_ADDRESS_INPUT: case GUI_ID_PORT_INPUT: case GUI_ID_NAME_INPUT: case 264:
				acceptInput();
				quitMenu();
				return true;
			}
		}
		if(event.GUIEvent.EventType==gui::EGET_LISTBOX_SELECTED_AGAIN)
		{
			switch(event.GUIEvent.Caller->getID())
			{
			case GUI_ID_WORLD_LISTBOX:
				acceptInput();
				if(getTab() != TAB_SINGLEPLAYER)
					m_data->address = L""; // Force local game
				quitMenu();
				return true;
			}
		}
	}

	return Parent ? Parent->OnEvent(event) : false;
}
Exemplo n.º 25
0
void Client::afterContentReceived(IrrlichtDevice *device)
{
	infostream<<"Client::afterContentReceived() started"<<std::endl;
	assert(m_itemdef_received); // pre-condition
	assert(m_nodedef_received); // pre-condition
	assert(mediaReceived()); // pre-condition

	const wchar_t* text = wgettext("Loading textures...");

	// Clear cached pre-scaled 2D GUI images, as this cache
	// might have images with the same name but different
	// content from previous sessions.
	guiScalingCacheClear(device->getVideoDriver());

	// Rebuild inherited images and recreate textures
	infostream<<"- Rebuilding images and textures"<<std::endl;
	draw_load_screen(text,device, guienv, 0, 70);
	m_tsrc->rebuildImagesAndTextures();
	delete[] text;

	// Rebuild shaders
	infostream<<"- Rebuilding shaders"<<std::endl;
	text = wgettext("Rebuilding shaders...");
	draw_load_screen(text, device, guienv, 0, 71);
	m_shsrc->rebuildShaders();
	delete[] text;

	// Update node aliases
	infostream<<"- Updating node aliases"<<std::endl;
	text = wgettext("Initializing nodes...");
	draw_load_screen(text, device, guienv, 0, 72);
	m_nodedef->updateAliases(m_itemdef);
	std::string texture_path = g_settings->get("texture_path");
	if (texture_path != "" && fs::IsDir(texture_path))
		m_nodedef->applyTextureOverrides(texture_path + DIR_DELIM + "override.txt");
	m_nodedef->setNodeRegistrationStatus(true);
	m_nodedef->runNodeResolveCallbacks();
	delete[] text;

	// Update node textures and assign shaders to each tile
	infostream<<"- Updating node textures"<<std::endl;
	TextureUpdateArgs tu_args;
	tu_args.device = device;
	tu_args.guienv = guienv;
	tu_args.last_time_ms = getTimeMs();
	tu_args.last_percent = 0;
	tu_args.text_base =  wgettext("Initializing nodes");
	m_nodedef->updateTextures(this, texture_update_progress, &tu_args);
	delete[] tu_args.text_base;

	// Preload item textures and meshes if configured to
	if(g_settings->getBool("preload_item_visuals"))
	{
		verbosestream<<"Updating item textures and meshes"<<std::endl;
		text = wgettext("Item textures...");
		draw_load_screen(text, device, guienv, 0, 0);
		std::set<std::string> names = m_itemdef->getAll();
		size_t size = names.size();
		size_t count = 0;
		int percent = 0;
		for(std::set<std::string>::const_iterator
				i = names.begin(); i != names.end(); ++i)
		{
			// Asking for these caches the result
			m_itemdef->getInventoryTexture(*i, this);
			m_itemdef->getWieldMesh(*i, this);
			count++;
			percent = (count * 100 / size * 0.2) + 80;
			draw_load_screen(text, device, guienv, 0, percent);
		}
		delete[] text;
	}

	// Start mesh update thread after setting up content definitions
	infostream<<"- Starting mesh update thread"<<std::endl;
	m_mesh_update_thread.start();

	m_state = LC_Ready;
	sendReady();
	text = wgettext("Done!");
	draw_load_screen(text, device, guienv, 0, 100);
	infostream<<"Client::afterContentReceived() done"<<std::endl;
	delete[] text;
}
Exemplo n.º 26
0
void GUIPasswordChange::regenerateGui(v2u32 screensize)
{
	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	core::rect<s32> rect(
			screensize.X/2 - 580/2,
			screensize.Y/2 - 300/2,
			screensize.X/2 + 580/2,
			screensize.Y/2 + 300/2
	);
	
	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 size = rect.getSize();
	v2s32 topleft_client(40, 0);

	const wchar_t *text;

	/*
		Add stuff
	*/
	s32 ypos = 50;
	{
		core::rect<s32> rect(0, 0, 150, 20);
		rect += topleft_client + v2s32(25, ypos+6);
		text = wgettext("Old Password");
		Environment->addStaticText(text, rect, false, true, this, -1);
		delete[] text;
	}
	{
		core::rect<s32> rect(0, 0, 230, 30);
		rect += topleft_client + v2s32(160, ypos);
		gui::IGUIEditBox *e = 
		Environment->addEditBox(L"", rect, true, this, ID_oldPassword);
		Environment->setFocus(e);
		e->setPasswordBox(true);
	}
	ypos += 50;
	{
		core::rect<s32> rect(0, 0, 150, 20);
		rect += topleft_client + v2s32(25, ypos+6);
		text = wgettext("New Password");
		Environment->addStaticText(text, rect, false, true, this, -1);
		delete[] text;
	}
	{
		core::rect<s32> rect(0, 0, 230, 30);
		rect += topleft_client + v2s32(160, ypos);
		gui::IGUIEditBox *e = 
		Environment->addEditBox(L"", rect, true, this, ID_newPassword1);
		e->setPasswordBox(true);
	}
	ypos += 50;
	{
		core::rect<s32> rect(0, 0, 150, 20);
		rect += topleft_client + v2s32(25, ypos+6);
		text = wgettext("Confirm Password");
		Environment->addStaticText(text, rect, false, true, this, -1);
		delete[] text;
	}
	{
		core::rect<s32> rect(0, 0, 230, 30);
		rect += topleft_client + v2s32(160, ypos);
		gui::IGUIEditBox *e = 
		Environment->addEditBox(L"", rect, true, this, ID_newPassword2);
		e->setPasswordBox(true);
	}

	ypos += 50;
	{
		core::rect<s32> rect(0, 0, 140, 30);
		rect = rect + v2s32(size.X/2-140/2, ypos);
		text = wgettext("Change");
		Environment->addButton(rect, this, ID_change, text);
		delete[] text;
	}

	ypos += 50;
	{
		core::rect<s32> rect(0, 0, 300, 20);
		rect += topleft_client + v2s32(35, ypos);
		text = wgettext("Passwords do not match!");
		IGUIElement *e = 
		Environment->addStaticText(
			text,
			rect, false, true, this, ID_message);
		e->setVisible(false);
		delete[] text;
	}
}
Exemplo n.º 27
0
int main(int argc, char *argv[])
{
	int retval = 0;

	/*
		Initialization
	*/

	log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION);
	log_add_output_all_levs(&main_dstream_no_stderr_log_out);

	log_register_thread("main");
	/*
		Parse command line
	*/

	// List all allowed options
	std::map<std::string, ValueSpec> allowed_options;
	allowed_options.insert(std::make_pair("help", ValueSpec(VALUETYPE_FLAG,
			_("Show allowed options"))));
	allowed_options.insert(std::make_pair("version", ValueSpec(VALUETYPE_FLAG,
			_("Show version information"))));
	allowed_options.insert(std::make_pair("config", ValueSpec(VALUETYPE_STRING,
			_("Load configuration from specified file"))));
	allowed_options.insert(std::make_pair("port", ValueSpec(VALUETYPE_STRING,
			_("Set network port (UDP)"))));
	allowed_options.insert(std::make_pair("disable-unittests", ValueSpec(VALUETYPE_FLAG,
			_("Disable unit tests"))));
	allowed_options.insert(std::make_pair("enable-unittests", ValueSpec(VALUETYPE_FLAG,
			_("Enable unit tests"))));
	allowed_options.insert(std::make_pair("map-dir", ValueSpec(VALUETYPE_STRING,
			_("Same as --world (deprecated)"))));
	allowed_options.insert(std::make_pair("world", ValueSpec(VALUETYPE_STRING,
			_("Set world path (implies local game) ('list' lists all)"))));
	allowed_options.insert(std::make_pair("worldname", ValueSpec(VALUETYPE_STRING,
			_("Set world by name (implies local game)"))));
	allowed_options.insert(std::make_pair("info", ValueSpec(VALUETYPE_FLAG,
			_("Print more information to console"))));
	allowed_options.insert(std::make_pair("verbose",  ValueSpec(VALUETYPE_FLAG,
			_("Print even more information to console"))));
	allowed_options.insert(std::make_pair("trace", ValueSpec(VALUETYPE_FLAG,
			_("Print enormous amounts of information to log and console"))));
	allowed_options.insert(std::make_pair("logfile", ValueSpec(VALUETYPE_STRING,
			_("Set logfile path ('' = no logging)"))));
	allowed_options.insert(std::make_pair("gameid", ValueSpec(VALUETYPE_STRING,
			_("Set gameid (\"--gameid list\" prints available ones)"))));
	allowed_options.insert(std::make_pair("migrate", ValueSpec(VALUETYPE_STRING,
			_("Migrate from current map backend to another (Only works when using minetestserver or with --server)"))));
#ifndef SERVER
	allowed_options.insert(std::make_pair("videomodes", ValueSpec(VALUETYPE_FLAG,
			_("Show available video modes"))));
	allowed_options.insert(std::make_pair("speedtests", ValueSpec(VALUETYPE_FLAG,
			_("Run speed tests"))));
	allowed_options.insert(std::make_pair("address", ValueSpec(VALUETYPE_STRING,
			_("Address to connect to. ('' = local game)"))));
	allowed_options.insert(std::make_pair("random-input", ValueSpec(VALUETYPE_FLAG,
			_("Enable random user input, for testing"))));
	allowed_options.insert(std::make_pair("server", ValueSpec(VALUETYPE_FLAG,
			_("Run dedicated server"))));
	allowed_options.insert(std::make_pair("name", ValueSpec(VALUETYPE_STRING,
			_("Set player name"))));
	allowed_options.insert(std::make_pair("password", ValueSpec(VALUETYPE_STRING,
			_("Set password"))));
	allowed_options.insert(std::make_pair("go", ValueSpec(VALUETYPE_FLAG,
			_("Disable main menu"))));
#endif

	Settings cmd_args;

	bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options);

	if(ret == false || cmd_args.getFlag("help") || cmd_args.exists("nonopt1"))
	{
		dstream<<_("Allowed options:")<<std::endl;
		for(std::map<std::string, ValueSpec>::iterator
				i = allowed_options.begin();
				i != allowed_options.end(); ++i)
		{
			std::ostringstream os1(std::ios::binary);
			os1<<"  --"<<i->first;
			if(i->second.type == VALUETYPE_FLAG)
				{}
			else
				os1<<_(" <value>");
			dstream<<padStringRight(os1.str(), 24);

			if(i->second.help != NULL)
				dstream<<i->second.help;
			dstream<<std::endl;
		}

		return cmd_args.getFlag("help") ? 0 : 1;
	}

	if(cmd_args.getFlag("version"))
	{
#ifdef SERVER
		dstream<<"minetestserver "<<minetest_version_hash<<std::endl;
#else
		dstream<<"Minetest "<<minetest_version_hash<<std::endl;
		dstream<<"Using Irrlicht "<<IRRLICHT_SDK_VERSION<<std::endl;
#endif
		dstream<<"Build info: "<<minetest_build_info<<std::endl;
		return 0;
	}

	/*
		Low-level initialization
	*/

	// If trace is enabled, enable logging of certain things
	if(cmd_args.getFlag("trace")){
		dstream<<_("Enabling trace level debug output")<<std::endl;
		log_trace_level_enabled = true;
		dout_con_ptr = &verbosestream; // this is somewhat old crap
		socket_enable_debug_output = true; // socket doesn't use log.h
	}
	// In certain cases, output info level on stderr
	if(cmd_args.getFlag("info") || cmd_args.getFlag("verbose") ||
			cmd_args.getFlag("trace") || cmd_args.getFlag("speedtests"))
		log_add_output(&main_stderr_log_out, LMT_INFO);
	// In certain cases, output verbose level on stderr
	if(cmd_args.getFlag("verbose") || cmd_args.getFlag("trace"))
		log_add_output(&main_stderr_log_out, LMT_VERBOSE);

	porting::signal_handler_init();
	bool &kill = *porting::signal_handler_killstatus();

	porting::initializePaths();

	// Create user data directory
	fs::CreateDir(porting::path_user);

	infostream<<"path_share = "<<porting::path_share<<std::endl;
	infostream<<"path_user  = "******"gameid") && cmd_args.get("gameid") == "list")
	{
		std::set<std::string> gameids = getAvailableGameIds();
		for(std::set<std::string>::const_iterator i = gameids.begin();
				i != gameids.end(); i++)
			dstream<<(*i)<<std::endl;
		return 0;
	}

	// List worlds if requested
	if(cmd_args.exists("world") && cmd_args.get("world") == "list"){
		dstream<<_("Available worlds:")<<std::endl;
		std::vector<WorldSpec> worldspecs = getAvailableWorlds();
		print_worldspecs(worldspecs, dstream);
		return 0;
	}

	// Print startup message
	infostream<<PROJECT_NAME<<
			" "<<_("with")<<" SER_FMT_VER_HIGHEST_READ="<<(int)SER_FMT_VER_HIGHEST_READ
			<<", "<<minetest_build_info
			<<std::endl;

	/*
		Basic initialization
	*/

	// Initialize default settings
	set_default_settings(g_settings);

	// Initialize sockets
	sockets_init();
	atexit(sockets_cleanup);

	/*
		Read config file
	*/

	// Path of configuration file in use
	g_settings_path = "";

	if(cmd_args.exists("config"))
	{
		bool r = g_settings->readConfigFile(cmd_args.get("config").c_str());
		if(r == false)
		{
			errorstream<<"Could not read configuration from \""
					<<cmd_args.get("config")<<"\""<<std::endl;
			return 1;
		}
		g_settings_path = cmd_args.get("config");
	}
	else
	{
		std::vector<std::string> filenames;
		filenames.push_back(porting::path_user +
				DIR_DELIM + "minetest.conf");
		// Legacy configuration file location
		filenames.push_back(porting::path_user +
				DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#if RUN_IN_PLACE
		// Try also from a lower level (to aid having the same configuration
		// for many RUN_IN_PLACE installs)
		filenames.push_back(porting::path_user +
				DIR_DELIM + ".." + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#endif

		for(u32 i=0; i<filenames.size(); i++)
		{
			bool r = g_settings->readConfigFile(filenames[i].c_str());
			if(r)
			{
				g_settings_path = filenames[i];
				break;
			}
		}

		// If no path found, use the first one (menu creates the file)
		if(g_settings_path == "")
			g_settings_path = filenames[0];
	}

	// Initialize debug streams
#define DEBUGFILE "debug.txt"
#if RUN_IN_PLACE
	std::string logfile = DEBUGFILE;
#else
	std::string logfile = porting::path_user+DIR_DELIM+DEBUGFILE;
#endif
	if(cmd_args.exists("logfile"))
		logfile = cmd_args.get("logfile");

	log_remove_output(&main_dstream_no_stderr_log_out);
	int loglevel = g_settings->getS32("debug_log_level");

	if (loglevel == 0) //no logging
		logfile = "";
	else if (loglevel > 0 && loglevel <= LMT_NUM_VALUES)
		log_add_output_maxlev(&main_dstream_no_stderr_log_out, (LogMessageLevel)(loglevel - 1));

	if(logfile != "")
		debugstreams_init(false, logfile.c_str());
	else
		debugstreams_init(false, NULL);

	infostream<<"logfile    = "<<logfile<<std::endl;

	// Initialize random seed
	srand(time(0));
	mysrand(time(0));

	// Initialize HTTP fetcher
	httpfetch_init(g_settings->getS32("curl_parallel_limit"));

	/*
		Run unit tests
	*/

	if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
			|| cmd_args.getFlag("enable-unittests") == true)
	{
		run_tests();
	}
#ifdef _MSC_VER
	init_gettext((porting::path_share + DIR_DELIM + "locale").c_str(),g_settings->get("language"),argc,argv);
#else
	init_gettext((porting::path_share + DIR_DELIM + "locale").c_str(),g_settings->get("language"));
#endif

	/*
		Game parameters
	*/

	// Port
	u16 port = 30000;
	if(cmd_args.exists("port"))
		port = cmd_args.getU16("port");
	else if(g_settings->exists("port"))
		port = g_settings->getU16("port");
	if(port == 0)
		port = 30000;

	// World directory
	std::string commanded_world = "";
	if(cmd_args.exists("world"))
		commanded_world = cmd_args.get("world");
	else if(cmd_args.exists("map-dir"))
		commanded_world = cmd_args.get("map-dir");
	else if(cmd_args.exists("nonopt0")) // First nameless argument
		commanded_world = cmd_args.get("nonopt0");
	else if(g_settings->exists("map-dir"))
		commanded_world = g_settings->get("map-dir");

	// World name
	std::string commanded_worldname = "";
	if(cmd_args.exists("worldname"))
		commanded_worldname = cmd_args.get("worldname");

	// Strip world.mt from commanded_world
	{
		std::string worldmt = "world.mt";
		if(commanded_world.size() > worldmt.size() &&
				commanded_world.substr(commanded_world.size()-worldmt.size())
				== worldmt){
			dstream<<_("Supplied world.mt file - stripping it off.")<<std::endl;
			commanded_world = commanded_world.substr(
					0, commanded_world.size()-worldmt.size());
		}
	}

	// If a world name was specified, convert it to a path
	if(commanded_worldname != ""){
		// Get information about available worlds
		std::vector<WorldSpec> worldspecs = getAvailableWorlds();
		bool found = false;
		for(u32 i=0; i<worldspecs.size(); i++){
			std::string name = worldspecs[i].name;
			if(name == commanded_worldname){
				if(commanded_world != ""){
					dstream<<_("--worldname takes precedence over previously "
							"selected world.")<<std::endl;
				}
				commanded_world = worldspecs[i].path;
				found = true;
				break;
			}
		}
		if(!found){
			dstream<<_("World")<<" '"<<commanded_worldname<<_("' not "
					"available. Available worlds:")<<std::endl;
			print_worldspecs(worldspecs, dstream);
			return 1;
		}
	}

	// Gamespec
	SubgameSpec commanded_gamespec;
	if(cmd_args.exists("gameid")){
		std::string gameid = cmd_args.get("gameid");
		commanded_gamespec = findSubgame(gameid);
		if(!commanded_gamespec.isValid()){
			errorstream<<"Game \""<<gameid<<"\" not found"<<std::endl;
			return 1;
		}
	}


	/*
		Run dedicated server if asked to or no other option
	*/
#ifdef SERVER
	bool run_dedicated_server = true;
#else
	bool run_dedicated_server = cmd_args.getFlag("server");
#endif
	g_settings->set("server_dedicated", run_dedicated_server ? "true" : "false");
	if(run_dedicated_server)
	{
		DSTACK("Dedicated server branch");
		// Create time getter if built with Irrlicht
#ifndef SERVER
		g_timegetter = new SimpleTimeGetter();
#endif

		// World directory
		std::string world_path;
		verbosestream<<_("Determining world path")<<std::endl;
		bool is_legacy_world = false;
		// If a world was commanded, use it
		if(commanded_world != ""){
			world_path = commanded_world;
			infostream<<"Using commanded world path ["<<world_path<<"]"
					<<std::endl;
		}
		// No world was specified; try to select it automatically
		else
		{
			// Get information about available worlds
			std::vector<WorldSpec> worldspecs = getAvailableWorlds();
			// If a world name was specified, select it
			if(commanded_worldname != ""){
				world_path = "";
				for(u32 i=0; i<worldspecs.size(); i++){
					std::string name = worldspecs[i].name;
					if(name == commanded_worldname){
						world_path = worldspecs[i].path;
						break;
					}
				}
				if(world_path == ""){
					dstream<<_("World")<<" '"<<commanded_worldname<<"' "<<_("not "
							"available. Available worlds:")<<std::endl;
					print_worldspecs(worldspecs, dstream);
					return 1;
				}
			}
			// If there is only a single world, use it
			if(worldspecs.size() == 1){
				world_path = worldspecs[0].path;
				dstream<<_("Automatically selecting world at")<<" ["
						<<world_path<<"]"<<std::endl;
			// If there are multiple worlds, list them
			} else if(worldspecs.size() > 1){
				dstream<<_("Multiple worlds are available.")<<std::endl;
				dstream<<_("Please select one using --worldname <name>"
						" or --world <path>")<<std::endl;
				print_worldspecs(worldspecs, dstream);
				return 1;
			// If there are no worlds, automatically create a new one
			} else {
				// This is the ultimate default world path
				world_path = porting::path_user + DIR_DELIM + "worlds" +
						DIR_DELIM + "world";
				infostream<<"Creating default world at ["
						<<world_path<<"]"<<std::endl;
			}
		}

		if(world_path == ""){
			errorstream<<"No world path specified or found."<<std::endl;
			return 1;
		}
		verbosestream<<_("Using world path")<<" ["<<world_path<<"]"<<std::endl;

		// We need a gamespec.
		SubgameSpec gamespec;
		verbosestream<<_("Determining gameid/gamespec")<<std::endl;
		// If world doesn't exist
		if(!getWorldExists(world_path))
		{
			// Try to take gamespec from command line
			if(commanded_gamespec.isValid()){
				gamespec = commanded_gamespec;
				infostream<<"Using commanded gameid ["<<gamespec.id<<"]"<<std::endl;
			}
			// Otherwise we will be using "minetest"
			else{
				gamespec = findSubgame(g_settings->get("default_game"));
				infostream<<"Using default gameid ["<<gamespec.id<<"]"<<std::endl;
			}
		}
		// World exists
		else
		{
			std::string world_gameid = getWorldGameId(world_path, is_legacy_world);
			// If commanded to use a gameid, do so
			if(commanded_gamespec.isValid()){
				gamespec = commanded_gamespec;
				if(commanded_gamespec.id != world_gameid){
					errorstream<<"WARNING: Using commanded gameid ["
							<<gamespec.id<<"]"<<" instead of world gameid ["
							<<world_gameid<<"]"<<std::endl;
				}
			} else{
				// If world contains an embedded game, use it;
				// Otherwise find world from local system.
				gamespec = findWorldSubgame(world_path);
				infostream<<"Using world gameid ["<<gamespec.id<<"]"<<std::endl;
			}
		}
		if(!gamespec.isValid()){
			errorstream<<"Subgame ["<<gamespec.id<<"] could not be found."
					<<std::endl;
			return 1;
		}
		verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl;

		// Bind address
		std::string bind_str = g_settings->get("bind_address");
		Address bind_addr(0,0,0,0, port);

		if (g_settings->getBool("ipv6_server")) {
			bind_addr.setAddress((IPv6AddressBytes*) NULL);
		}
		try {
			bind_addr.Resolve(bind_str.c_str());
		} catch (ResolveError &e) {
			infostream << "Resolving bind address \"" << bind_str
			           << "\" failed: " << e.what()
		        	   << " -- Listening on all addresses." << std::endl;
		}
		if(bind_addr.isIPv6() && !g_settings->getBool("enable_ipv6")) {
			errorstream << "Unable to listen on "
			            << bind_addr.serializeString()
				    << L" because IPv6 is disabled" << std::endl;
			return 1;
		}

		// Create server
		Server server(world_path, gamespec, false, bind_addr.isIPv6());

		// Database migration
		if (cmd_args.exists("migrate")) {
			std::string migrate_to = cmd_args.get("migrate");
			Settings world_mt;
			bool success = world_mt.readConfigFile((world_path + DIR_DELIM + "world.mt").c_str());
			if (!success) {
				errorstream << "Cannot read world.mt" << std::endl;
				return 1;
			}
			if (!world_mt.exists("backend")) {
				errorstream << "Please specify your current backend in world.mt file:"
					<< std::endl << "	backend = {sqlite3|leveldb|redis|dummy}" << std::endl;
				return 1;
			}
			std::string backend = world_mt.get("backend");
			Database *new_db;
			if (backend == migrate_to) {
				errorstream << "Cannot migrate: new backend is same as the old one" << std::endl;
				return 1;
			}
			if (migrate_to == "sqlite3")
				new_db = new Database_SQLite3(&(ServerMap&)server.getMap(), world_path);
			#if USE_LEVELDB
			else if (migrate_to == "leveldb")
				new_db = new Database_LevelDB(&(ServerMap&)server.getMap(), world_path);
			#endif
			#if USE_REDIS
			else if (migrate_to == "redis")
				new_db = new Database_Redis(&(ServerMap&)server.getMap(), world_path);
			#endif
			else {
				errorstream << "Migration to " << migrate_to << " is not supported" << std::endl;
				return 1;
			}

			std::list<v3s16> blocks;
			ServerMap &old_map = ((ServerMap&)server.getMap());
			old_map.listAllLoadableBlocks(blocks);
			int count = 0;
			new_db->beginSave();
			for (std::list<v3s16>::iterator i = blocks.begin(); i != blocks.end(); ++i) {
				MapBlock *block = old_map.loadBlock(*i);
				new_db->saveBlock(block);
				MapSector *sector = old_map.getSectorNoGenerate(v2s16(i->X, i->Z));
				sector->deleteBlock(block);
				++count;
				if (count % 500 == 0)
					actionstream << "Migrated " << count << " blocks "
						<< (100.0 * count / blocks.size()) << "% completed" << std::endl;
			}
			new_db->endSave();
			delete new_db;

			actionstream << "Successfully migrated " << count << " blocks" << std::endl;
			world_mt.set("backend", migrate_to);
			if(!world_mt.updateConfigFile((world_path + DIR_DELIM + "world.mt").c_str()))
				errorstream<<"Failed to update world.mt!"<<std::endl;
			else
				actionstream<<"world.mt updated"<<std::endl;

			return 0;
		}

		server.start(bind_addr);

		// Run server
		dedicated_server_loop(server, kill);

		return 0;
	}

#ifndef SERVER // Exclude from dedicated server build

	/*
		More parameters
	*/

	std::string address = g_settings->get("address");
	if(commanded_world != "")
		address = "";
	else if(cmd_args.exists("address"))
		address = cmd_args.get("address");

	std::string playername = g_settings->get("name");
	if(cmd_args.exists("name"))
		playername = cmd_args.get("name");

	bool skip_main_menu = cmd_args.getFlag("go");

	/*
		Device initialization
	*/

	// Resolution selection

	bool fullscreen = g_settings->getBool("fullscreen");
	u16 screenW = g_settings->getU16("screenW");
	u16 screenH = g_settings->getU16("screenH");

	// bpp, fsaa, vsync

	bool vsync = g_settings->getBool("vsync");
	u16 bits = g_settings->getU16("fullscreen_bpp");
	u16 fsaa = g_settings->getU16("fsaa");

	// Determine driver

	video::E_DRIVER_TYPE driverType;

	std::string driverstring = g_settings->get("video_driver");

	if(driverstring == "null")
		driverType = video::EDT_NULL;
	else if(driverstring == "software")
		driverType = video::EDT_SOFTWARE;
	else if(driverstring == "burningsvideo")
		driverType = video::EDT_BURNINGSVIDEO;
	else if(driverstring == "direct3d8")
		driverType = video::EDT_DIRECT3D8;
	else if(driverstring == "direct3d9")
		driverType = video::EDT_DIRECT3D9;
	else if(driverstring == "opengl")
		driverType = video::EDT_OPENGL;
#ifdef _IRR_COMPILE_WITH_OGLES1_
	else if(driverstring == "ogles1")
		driverType = video::EDT_OGLES1;
#endif
#ifdef _IRR_COMPILE_WITH_OGLES2_
	else if(driverstring == "ogles2")
		driverType = video::EDT_OGLES2;
#endif
	else
	{
		errorstream<<"WARNING: Invalid video_driver specified; defaulting "
				"to opengl"<<std::endl;
		driverType = video::EDT_OPENGL;
	}

	/*
		List video modes if requested
	*/

	MyEventReceiver receiver;

	if(cmd_args.getFlag("videomodes")){
		IrrlichtDevice *nulldevice;

		SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
		params.DriverType    = video::EDT_NULL;
		params.WindowSize    = core::dimension2d<u32>(640, 480);
		params.Bits          = 24;
		params.AntiAlias     = fsaa;
		params.Fullscreen    = false;
		params.Stencilbuffer = false;
		params.Vsync         = vsync;
		params.EventReceiver = &receiver;
		params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu");

		nulldevice = createDeviceEx(params);

		if(nulldevice == 0)
			return 1;

		dstream<<_("Available video modes (WxHxD):")<<std::endl;

		video::IVideoModeList *videomode_list =
				nulldevice->getVideoModeList();

		if(videomode_list == 0){
			nulldevice->drop();
			return 1;
		}

		s32 videomode_count = videomode_list->getVideoModeCount();
		core::dimension2d<u32> videomode_res;
		s32 videomode_depth;
		for (s32 i = 0; i < videomode_count; ++i){
			videomode_res = videomode_list->getVideoModeResolution(i);
			videomode_depth = videomode_list->getVideoModeDepth(i);
			dstream<<videomode_res.Width<<"x"<<videomode_res.Height
					<<"x"<<videomode_depth<<std::endl;
		}

		dstream<<_("Active video mode (WxHxD):")<<std::endl;
		videomode_res = videomode_list->getDesktopResolution();
		videomode_depth = videomode_list->getDesktopDepth();
		dstream<<videomode_res.Width<<"x"<<videomode_res.Height
				<<"x"<<videomode_depth<<std::endl;

		nulldevice->drop();

		return 0;
	}

	/*
		Create device and exit if creation failed
	*/

	IrrlichtDevice *device;

	SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
	params.DriverType    = driverType;
	params.WindowSize    = core::dimension2d<u32>(screenW, screenH);
	params.Bits          = bits;
	params.AntiAlias     = fsaa;
	params.Fullscreen    = fullscreen;
	params.Stencilbuffer = false;
	params.Vsync         = vsync;
	params.EventReceiver = &receiver;
	params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu");

	device = createDeviceEx(params);

	if (device == 0)
		return 1; // could not create selected driver.

	/*
		Continue initialization
	*/

	video::IVideoDriver* driver = device->getVideoDriver();

	/*
		This changes the minimum allowed number of vertices in a VBO.
		Default is 500.
	*/
	//driver->setMinHardwareBufferVertexCount(50);

	// Create time getter
	g_timegetter = new IrrlichtTimeGetter(device);

	// Create game callback for menus
	g_gamecallback = new MainGameCallback(device);

	/*
		Speed tests (done after irrlicht is loaded to get timer)
	*/
	if(cmd_args.getFlag("speedtests"))
	{
		dstream<<"Running speed tests"<<std::endl;
		SpeedTests();
		device->drop();
		return 0;
	}

	device->setResizable(true);

	bool random_input = g_settings->getBool("random_input")
			|| cmd_args.getFlag("random-input");
	InputHandler *input = NULL;
	if(random_input) {
		input = new RandomInputHandler();
	} else {
		input = new RealInputHandler(device, &receiver);
	}

	scene::ISceneManager* smgr = device->getSceneManager();

	guienv = device->getGUIEnvironment();
	gui::IGUISkin* skin = guienv->getSkin();
	std::string font_path = g_settings->get("font_path");
	gui::IGUIFont *font;
	#if USE_FREETYPE
	bool use_freetype = g_settings->getBool("freetype");
	if (use_freetype) {
		std::string fallback;
		if (is_yes(gettext("needs_fallback_font")))
			fallback = "fallback_";
		u16 font_size = g_settings->getU16(fallback + "font_size");
		font_path = g_settings->get(fallback + "font_path");
		u32 font_shadow = g_settings->getU16(fallback + "font_shadow");
		u32 font_shadow_alpha = g_settings->getU16(fallback + "font_shadow_alpha");
		font = gui::CGUITTFont::createTTFont(guienv, font_path.c_str(), font_size, true, true, font_shadow, font_shadow_alpha);
	} else {
		font = guienv->getFont(font_path.c_str());
	}
	#else
	font = guienv->getFont(font_path.c_str());
	#endif
	if(font)
		skin->setFont(font);
	else
		errorstream<<"WARNING: Font file was not found."
				" Using default font."<<std::endl;
	// If font was not found, this will get us one
	font = skin->getFont();
	assert(font);

	u32 text_height = font->getDimension(L"Hello, world!").Height;
	infostream<<"text_height="<<text_height<<std::endl;

	//skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,0,0,0));
	skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255));
	//skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(0,0,0,0));
	//skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(0,0,0,0));
	skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255,0,0,0));
	skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255,0,0,0));
	skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255,70,100,50));
	skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255,255,255,255));

#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
	// Irrlicht 1.8 input colours
	skin->setColor(gui::EGDC_EDITABLE, video::SColor(255,128,128,128));
	skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255,96,134,49));
#endif


	// Create the menu clouds
	if (!g_menucloudsmgr)
		g_menucloudsmgr = smgr->createNewSceneManager();
	if (!g_menuclouds)
		g_menuclouds = new Clouds(g_menucloudsmgr->getRootSceneNode(),
			g_menucloudsmgr, -1, rand(), 100);
	g_menuclouds->update(v2f(0, 0), video::SColor(255,200,200,255));
	scene::ICameraSceneNode* camera;
	camera = g_menucloudsmgr->addCameraSceneNode(0,
				v3f(0,0,0), v3f(0, 60, 100));
	camera->setFarValue(10000);

	/*
		GUI stuff
	*/

	ChatBackend chat_backend;

	/*
		If an error occurs, this is set to something and the
		menu-game loop is restarted. It is then displayed before
		the menu.
	*/
	std::wstring error_message = L"";

	// The password entered during the menu screen,
	std::string password;

	bool first_loop = true;

	/*
		Menu-game loop
	*/
	while(device->run() && kill == false)
	{
		// Set the window caption
		wchar_t* text = wgettext("Main Menu");
		device->setWindowCaption((std::wstring(L"Minetest [")+text+L"]").c_str());
		delete[] text;

		// This is used for catching disconnects
		try
		{

			/*
				Clear everything from the GUIEnvironment
			*/
			guienv->clear();

			/*
				We need some kind of a root node to be able to add
				custom gui elements directly on the screen.
				Otherwise they won't be automatically drawn.
			*/
			guiroot = guienv->addStaticText(L"",
					core::rect<s32>(0, 0, 10000, 10000));

			SubgameSpec gamespec;
			WorldSpec worldspec;
			bool simple_singleplayer_mode = false;

			// These are set up based on the menu and other things
			std::string current_playername = "inv£lid";
			std::string current_password = "";
			std::string current_address = "does-not-exist";
			int current_port = 0;

			/*
				Out-of-game menu loop.

				Loop quits when menu returns proper parameters.
			*/
			while(kill == false)
			{
				// If skip_main_menu, only go through here once
				if(skip_main_menu && !first_loop){
					kill = true;
					break;
				}
				first_loop = false;

				// Cursor can be non-visible when coming from the game
				device->getCursorControl()->setVisible(true);
				// Some stuff are left to scene manager when coming from the game
				// (map at least?)
				smgr->clear();

				// Initialize menu data
				MainMenuData menudata;
				menudata.address = address;
				menudata.name = playername;
				menudata.port = itos(port);
				menudata.errormessage = wide_to_narrow(error_message);
				error_message = L"";
				if(cmd_args.exists("password"))
					menudata.password = cmd_args.get("password");

				driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));

				menudata.enable_public = g_settings->getBool("server_announce");

				std::vector<WorldSpec> worldspecs = getAvailableWorlds();

				// If a world was commanded, append and select it
				if(commanded_world != ""){

					std::string gameid = getWorldGameId(commanded_world, true);
					std::string name = _("[--world parameter]");
					if(gameid == ""){
						gameid = g_settings->get("default_game");
						name += " [new]";
					}
					//TODO find within worldspecs and set config
				}

				if(skip_main_menu == false)
				{
					video::IVideoDriver* driver = device->getVideoDriver();

					infostream<<"Waiting for other menus"<<std::endl;
					while(device->run() && kill == false)
					{
						if(noMenuActive())
							break;
						driver->beginScene(true, true,
								video::SColor(255,128,128,128));
						guienv->drawAll();
						driver->endScene();
						// On some computers framerate doesn't seem to be
						// automatically limited
						sleep_ms(25);
					}
					infostream<<"Waited for other menus"<<std::endl;

					GUIEngine* temp = new GUIEngine(device, guiroot, &g_menumgr,smgr,&menudata,kill);

					delete temp;
					//once finished you'll never end up here
					smgr->clear();
				}

				if(menudata.errormessage != ""){
					error_message = narrow_to_wide(menudata.errormessage);
					continue;
				}

				//update worldspecs (necessary as new world may have been created)
				worldspecs = getAvailableWorlds();

				if (menudata.name == "")
					menudata.name = std::string("Guest") + itos(myrand_range(1000,9999));
				else
					playername = menudata.name;

				password = translatePassword(playername, narrow_to_wide(menudata.password));
				//infostream<<"Main: password hash: '"<<password<<"'"<<std::endl;

				address = menudata.address;
				int newport = stoi(menudata.port);
				if(newport != 0)
					port = newport;

				simple_singleplayer_mode = menudata.simple_singleplayer_mode;

				// Save settings
				g_settings->set("name", playername);

				if((menudata.selected_world >= 0) &&
						(menudata.selected_world < (int)worldspecs.size()))
					g_settings->set("selected_world_path",
							worldspecs[menudata.selected_world].path);

				// Break out of menu-game loop to shut down cleanly
				if(device->run() == false || kill == true)
					break;

				current_playername = playername;
				current_password = password;
				current_address = address;
				current_port = port;

				// If using simple singleplayer mode, override
				if(simple_singleplayer_mode){
					current_playername = "singleplayer";
					current_password = "";
					current_address = "";
					current_port = myrand_range(49152, 65535);
				}
				else if (address != "")
				{
					ServerListSpec server;
					server["name"] = menudata.servername;
					server["address"] = menudata.address;
					server["port"] = menudata.port;
					server["description"] = menudata.serverdescription;
					ServerList::insert(server);
				}

				// Set world path to selected one
				if ((menudata.selected_world >= 0) &&
					(menudata.selected_world < (int)worldspecs.size())) {
					worldspec = worldspecs[menudata.selected_world];
					infostream<<"Selected world: "<<worldspec.name
							<<" ["<<worldspec.path<<"]"<<std::endl;
				}

				// If local game
				if(current_address == "")
				{
					if(menudata.selected_world == -1){
						error_message = wgettext("No world selected and no address "
								"provided. Nothing to do.");
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					// Load gamespec for required game
					gamespec = findWorldSubgame(worldspec.path);
					if(!gamespec.isValid() && !commanded_gamespec.isValid()){
						error_message = wgettext("Could not find or load game \"")
								+ narrow_to_wide(worldspec.gameid) + L"\"";
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					if(commanded_gamespec.isValid() &&
							commanded_gamespec.id != worldspec.gameid){
						errorstream<<"WARNING: Overriding gamespec from \""
								<<worldspec.gameid<<"\" to \""
								<<commanded_gamespec.id<<"\""<<std::endl;
						gamespec = commanded_gamespec;
					}

					if(!gamespec.isValid()){
						error_message = wgettext("Invalid gamespec.");
						error_message += L" (world_gameid="
								+narrow_to_wide(worldspec.gameid)+L")";
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
				}

				// Continue to game
				break;
			}

			// Break out of menu-game loop to shut down cleanly
			if(device->run() == false || kill == true) {
				if(g_settings_path != "") {
					g_settings->updateConfigFile(
						g_settings_path.c_str());
				}
				break;
			}

			/*
				Run game
			*/
			the_game(
				kill,
				random_input,
				input,
				device,
				font,
				worldspec.path,
				current_playername,
				current_password,
				current_address,
				current_port,
				error_message,
				chat_backend,
				gamespec,
				simple_singleplayer_mode
			);
			smgr->clear();

		} //try
		catch(con::PeerNotFoundException &e)
		{
			error_message = wgettext("Connection error (timed out?)");
			errorstream<<wide_to_narrow(error_message)<<std::endl;
		}
#ifdef NDEBUG
		catch(std::exception &e)
		{
			std::string narrow_message = "Some exception: \"";
			narrow_message += e.what();
			narrow_message += "\"";
			errorstream<<narrow_message<<std::endl;
			error_message = narrow_to_wide(narrow_message);
		}
#endif

		// If no main menu, show error and exit
		if(skip_main_menu)
		{
			if(error_message != L""){
				verbosestream<<"error_message = "
						<<wide_to_narrow(error_message)<<std::endl;
				retval = 1;
			}
			break;
		}
	} // Menu-game loop


	g_menuclouds->drop();
	g_menucloudsmgr->drop();

	delete input;

	/*
		In the end, delete the Irrlicht device.
	*/
	device->drop();

#if USE_FREETYPE
	if (use_freetype)
		font->drop();
#endif

#endif // !SERVER

	// Update configuration file
	if(g_settings_path != "")
		g_settings->updateConfigFile(g_settings_path.c_str());

	// Print modified quicktune values
	{
		bool header_printed = false;
		std::vector<std::string> names = getQuicktuneNames();
		for(u32 i=0; i<names.size(); i++){
			QuicktuneValue val = getQuicktuneValue(names[i]);
			if(!val.modified)
				continue;
			if(!header_printed){
				dstream<<"Modified quicktune values:"<<std::endl;
				header_printed = true;
			}
			dstream<<names[i]<<" = "<<val.getString()<<std::endl;
		}
	}

	// Stop httpfetch thread (if started)
	httpfetch_cleanup();

	END_DEBUG_EXCEPTION_HANDLER(errorstream)

	debugstreams_deinit();

	return retval;
}
Exemplo n.º 28
0
int main(int argc, char *argv[])
{
	int retval = 0;

	/*
		Initialization
	*/

	log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION);
	log_add_output_all_levs(&main_dstream_no_stderr_log_out);

	log_register_thread("main");

	// Set locale. This is for forcing '.' as the decimal point.
	std::locale::global(std::locale("C"));
	// This enables printing all characters in bitmap font
	setlocale(LC_CTYPE, "en_US");

	/*
		Parse command line
	*/
	
	// List all allowed options
	core::map<std::string, ValueSpec> allowed_options;
	allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG,
			_("Show allowed options")));
	allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,
			_("Load configuration from specified file")));
	allowed_options.insert("port", ValueSpec(VALUETYPE_STRING,
			_("Set network port (UDP)")));
	allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG,
			_("Disable unit tests")));
	allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG,
			_("Enable unit tests")));
	allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING,
			_("Same as --world (deprecated)")));
	allowed_options.insert("world", ValueSpec(VALUETYPE_STRING,
			_("Set world path (implies local game) ('list' lists all)")));
	allowed_options.insert("worldname", ValueSpec(VALUETYPE_STRING,
			_("Set world by name (implies local game)")));
	allowed_options.insert("info", ValueSpec(VALUETYPE_FLAG,
			_("Print more information to console")));
	allowed_options.insert("verbose", ValueSpec(VALUETYPE_FLAG,
			_("Print even more information to console")));
	allowed_options.insert("trace", ValueSpec(VALUETYPE_FLAG,
			_("Print enormous amounts of information to log and console")));
	allowed_options.insert("logfile", ValueSpec(VALUETYPE_STRING,
			_("Set logfile path ('' = no logging)")));
	allowed_options.insert("gameid", ValueSpec(VALUETYPE_STRING,
			_("Set gameid (\"--gameid list\" prints available ones)")));
#ifndef SERVER
	allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG,
			_("Run speed tests")));
	allowed_options.insert("address", ValueSpec(VALUETYPE_STRING,
			_("Address to connect to. ('' = local game)")));
	allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG,
			_("Enable random user input, for testing")));
	allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,
			_("Run dedicated server")));
	allowed_options.insert("name", ValueSpec(VALUETYPE_STRING,
			_("Set player name")));
	allowed_options.insert("password", ValueSpec(VALUETYPE_STRING,
			_("Set password")));
	allowed_options.insert("go", ValueSpec(VALUETYPE_FLAG,
			_("Disable main menu")));
#endif

	Settings cmd_args;
	
	bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options);

	if(ret == false || cmd_args.getFlag("help") || cmd_args.exists("nonopt1"))
	{
		dstream<<_("Allowed options:")<<std::endl;
		for(core::map<std::string, ValueSpec>::Iterator
				i = allowed_options.getIterator();
				i.atEnd() == false; i++)
		{
			std::ostringstream os1(std::ios::binary);
			os1<<"  --"<<i.getNode()->getKey();
			if(i.getNode()->getValue().type == VALUETYPE_FLAG)
				{}
			else
				os1<<_(" <value>");
			dstream<<padStringRight(os1.str(), 24);

			if(i.getNode()->getValue().help != NULL)
				dstream<<i.getNode()->getValue().help;
			dstream<<std::endl;
		}

		return cmd_args.getFlag("help") ? 0 : 1;
	}
	
	/*
		Low-level initialization
	*/
	
	// If trace is enabled, enable logging of certain things
	if(cmd_args.getFlag("trace")){
		dstream<<_("Enabling trace level debug output")<<std::endl;
		log_trace_level_enabled = true;
		dout_con_ptr = &verbosestream; // this is somewhat old crap
		socket_enable_debug_output = true; // socket doesn't use log.h
	}
	// In certain cases, output info level on stderr
	if(cmd_args.getFlag("info") || cmd_args.getFlag("verbose") ||
			cmd_args.getFlag("trace") || cmd_args.getFlag("speedtests"))
		log_add_output(&main_stderr_log_out, LMT_INFO);
	// In certain cases, output verbose level on stderr
	if(cmd_args.getFlag("verbose") || cmd_args.getFlag("trace"))
		log_add_output(&main_stderr_log_out, LMT_VERBOSE);

	porting::signal_handler_init();
	bool &kill = *porting::signal_handler_killstatus();
	
	porting::initializePaths();

	// Create user data directory
	fs::CreateDir(porting::path_user);

	init_gettext((porting::path_share+DIR_DELIM+".."+DIR_DELIM+"locale").c_str());
	
	// Initialize debug streams
#define DEBUGFILE "debug.txt"
#if RUN_IN_PLACE
	std::string logfile = DEBUGFILE;
#else
	std::string logfile = porting::path_user+DIR_DELIM+DEBUGFILE;
#endif
	if(cmd_args.exists("logfile"))
		logfile = cmd_args.get("logfile");
	if(logfile != "")
		debugstreams_init(false, logfile.c_str());
	else
		debugstreams_init(false, NULL);

	infostream<<"logfile    = "<<logfile<<std::endl;
	infostream<<"path_share = "<<porting::path_share<<std::endl;
	infostream<<"path_user  = "******"gameid") && cmd_args.get("gameid") == "list")
	{
		std::set<std::string> gameids = getAvailableGameIds();
		for(std::set<std::string>::const_iterator i = gameids.begin();
				i != gameids.end(); i++)
			dstream<<(*i)<<std::endl;
		return 0;
	}
	
	// List worlds if requested
	if(cmd_args.exists("world") && cmd_args.get("world") == "list"){
		dstream<<_("Available worlds:")<<std::endl;
		std::vector<WorldSpec> worldspecs = getAvailableWorlds();
		print_worldspecs(worldspecs, dstream);
		return 0;
	}
	
	// Print startup message
	infostream<<PROJECT_NAME<<
			" "<<_("with")<<" SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
			<<", "<<BUILD_INFO
			<<std::endl;
	
	/*
		Basic initialization
	*/

	// Initialize default settings
	set_default_settings(g_settings);
	
	// Initialize sockets
	sockets_init();
	atexit(sockets_cleanup);
	
	/*
		Read config file
	*/
	
	// Path of configuration file in use
	std::string configpath = "";
	
	if(cmd_args.exists("config"))
	{
		bool r = g_settings->readConfigFile(cmd_args.get("config").c_str());
		if(r == false)
		{
			errorstream<<"Could not read configuration from \""
					<<cmd_args.get("config")<<"\""<<std::endl;
			return 1;
		}
		configpath = cmd_args.get("config");
	}
	else
	{
		core::array<std::string> filenames;
		filenames.push_back(porting::path_user +
				DIR_DELIM + "minetest.conf");
		// Legacy configuration file location
		filenames.push_back(porting::path_user +
				DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#if RUN_IN_PLACE
		// Try also from a lower level (to aid having the same configuration
		// for many RUN_IN_PLACE installs)
		filenames.push_back(porting::path_user +
				DIR_DELIM + ".." + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#endif

		for(u32 i=0; i<filenames.size(); i++)
		{
			bool r = g_settings->readConfigFile(filenames[i].c_str());
			if(r)
			{
				configpath = filenames[i];
				break;
			}
		}
		
		// If no path found, use the first one (menu creates the file)
		if(configpath == "")
			configpath = filenames[0];
	}

	// Initialize random seed
	srand(time(0));
	mysrand(time(0));

	/*
		Run unit tests
	*/

	if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
			|| cmd_args.getFlag("enable-unittests") == true)
	{
		run_tests();
	}
	
	/*
		Game parameters
	*/

	// Port
	u16 port = 30000;
	if(cmd_args.exists("port"))
		port = cmd_args.getU16("port");
	else if(g_settings->exists("port"))
		port = g_settings->getU16("port");
	if(port == 0)
		port = 30000;
	
	// World directory
	std::string commanded_world = "";
	if(cmd_args.exists("world"))
		commanded_world = cmd_args.get("world");
	else if(cmd_args.exists("map-dir"))
		commanded_world = cmd_args.get("map-dir");
	else if(cmd_args.exists("nonopt0")) // First nameless argument
		commanded_world = cmd_args.get("nonopt0");
	else if(g_settings->exists("map-dir"))
		commanded_world = g_settings->get("map-dir");
	
	// World name
	std::string commanded_worldname = "";
	if(cmd_args.exists("worldname"))
		commanded_worldname = cmd_args.get("worldname");
	
	// Strip world.mt from commanded_world
	{
		std::string worldmt = "world.mt";
		if(commanded_world.size() > worldmt.size() &&
				commanded_world.substr(commanded_world.size()-worldmt.size())
				== worldmt){
			dstream<<_("Supplied world.mt file - stripping it off.")<<std::endl;
			commanded_world = commanded_world.substr(
					0, commanded_world.size()-worldmt.size());
		}
	}
	
	// If a world name was specified, convert it to a path
	if(commanded_worldname != ""){
		// Get information about available worlds
		std::vector<WorldSpec> worldspecs = getAvailableWorlds();
		bool found = false;
		for(u32 i=0; i<worldspecs.size(); i++){
			std::string name = worldspecs[i].name;
			if(name == commanded_worldname){
				if(commanded_world != ""){
					dstream<<_("--worldname takes precedence over previously "
							"selected world.")<<std::endl;
				}
				commanded_world = worldspecs[i].path;
				found = true;
				break;
			}
		}
		if(!found){
			dstream<<_("World")<<" '"<<commanded_worldname<<_("' not "
					"available. Available worlds:")<<std::endl;
			print_worldspecs(worldspecs, dstream);
			return 1;
		}
	}

	// Gamespec
	SubgameSpec commanded_gamespec;
	if(cmd_args.exists("gameid")){
		std::string gameid = cmd_args.get("gameid");
		commanded_gamespec = findSubgame(gameid);
		if(!commanded_gamespec.isValid()){
			errorstream<<"Game \""<<gameid<<"\" not found"<<std::endl;
			return 1;
		}
	}

	/*
		Run dedicated server if asked to or no other option
	*/
#ifdef SERVER
	bool run_dedicated_server = true;
#else
	bool run_dedicated_server = cmd_args.getFlag("server");
#endif
	if(run_dedicated_server)
	{
		DSTACK("Dedicated server branch");
		// Create time getter if built with Irrlicht
#ifndef SERVER
		g_timegetter = new SimpleTimeGetter();
#endif

		// World directory
		std::string world_path;
		verbosestream<<_("Determining world path")<<std::endl;
		bool is_legacy_world = false;
		// If a world was commanded, use it
		if(commanded_world != ""){
			world_path = commanded_world;
			infostream<<"Using commanded world path ["<<world_path<<"]"
					<<std::endl;
		}
		// No world was specified; try to select it automatically
		else
		{
			// Get information about available worlds
			std::vector<WorldSpec> worldspecs = getAvailableWorlds();
			// If a world name was specified, select it
			if(commanded_worldname != ""){
				world_path = "";
				for(u32 i=0; i<worldspecs.size(); i++){
					std::string name = worldspecs[i].name;
					if(name == commanded_worldname){
						world_path = worldspecs[i].path;
						break;
					}
				}
				if(world_path == ""){
					dstream<<_("World")<<" '"<<commanded_worldname<<"' "<<_("not "
							"available. Available worlds:")<<std::endl;
					print_worldspecs(worldspecs, dstream);
					return 1;
				}
			}
			// If there is only a single world, use it
			if(worldspecs.size() == 1){
				world_path = worldspecs[0].path;
				dstream<<_("Automatically selecting world at")<<" ["
						<<world_path<<"]"<<std::endl;
			// If there are multiple worlds, list them
			} else if(worldspecs.size() > 1){
				dstream<<_("Multiple worlds are available.")<<std::endl;
				dstream<<_("Please select one using --worldname <name>"
						" or --world <path>")<<std::endl;
				print_worldspecs(worldspecs, dstream);
				return 1;
			// If there are no worlds, automatically create a new one
			} else {
				// This is the ultimate default world path
				world_path = porting::path_user + DIR_DELIM + "worlds" +
						DIR_DELIM + "world";
				infostream<<"Creating default world at ["
						<<world_path<<"]"<<std::endl;
			}
		}

		if(world_path == ""){
			errorstream<<"No world path specified or found."<<std::endl;
			return 1;
		}
		verbosestream<<_("Using world path")<<" ["<<world_path<<"]"<<std::endl;

		// We need a gamespec.
		SubgameSpec gamespec;
		verbosestream<<_("Determining gameid/gamespec")<<std::endl;
		// If world doesn't exist
		if(!getWorldExists(world_path))
		{
			// Try to take gamespec from command line
			if(commanded_gamespec.isValid()){
				gamespec = commanded_gamespec;
				infostream<<"Using commanded gameid ["<<gamespec.id<<"]"<<std::endl;
			}
			// Otherwise we will be using "minetest"
			else{
				gamespec = findSubgame(g_settings->get("default_game"));
				infostream<<"Using default gameid ["<<gamespec.id<<"]"<<std::endl;
			}
		}
		// World exists
		else
		{
			std::string world_gameid = getWorldGameId(world_path, is_legacy_world);
			// If commanded to use a gameid, do so
			if(commanded_gamespec.isValid()){
				gamespec = commanded_gamespec;
				if(commanded_gamespec.id != world_gameid){
					errorstream<<"WARNING: Using commanded gameid ["
							<<gamespec.id<<"]"<<" instead of world gameid ["
							<<world_gameid<<"]"<<std::endl;
				}
			} else{
				// If world contains an embedded game, use it;
				// Otherwise find world from local system.
				gamespec = findWorldSubgame(world_path);
				infostream<<"Using world gameid ["<<gamespec.id<<"]"<<std::endl;
			}
		}
		if(!gamespec.isValid()){
			errorstream<<"Subgame ["<<gamespec.id<<"] could not be found."
					<<std::endl;
			return 1;
		}
		verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl;

		// Create server
		Server server(world_path, configpath, gamespec, false);
		server.start(port);
		
		// Run server
		dedicated_server_loop(server, kill);

		return 0;
	}

#ifndef SERVER // Exclude from dedicated server build

	/*
		More parameters
	*/
	
	std::string address = g_settings->get("address");
	if(commanded_world != "")
		address = "";
	else if(cmd_args.exists("address"))
		address = cmd_args.get("address");
	
	std::string playername = g_settings->get("name");
	if(cmd_args.exists("name"))
		playername = cmd_args.get("name");
	
	bool skip_main_menu = cmd_args.getFlag("go");

	/*
		Device initialization
	*/

	// Resolution selection
	
	bool fullscreen = g_settings->getBool("fullscreen");
	u16 screenW = g_settings->getU16("screenW");
	u16 screenH = g_settings->getU16("screenH");

	// bpp, fsaa, vsync

	bool vsync = g_settings->getBool("vsync");
	u16 bits = g_settings->getU16("fullscreen_bpp");
	u16 fsaa = g_settings->getU16("fsaa");

	// Determine driver

	video::E_DRIVER_TYPE driverType;
	
	std::string driverstring = g_settings->get("video_driver");

	if(driverstring == "null")
		driverType = video::EDT_NULL;
	else if(driverstring == "software")
		driverType = video::EDT_SOFTWARE;
	else if(driverstring == "burningsvideo")
		driverType = video::EDT_BURNINGSVIDEO;
	else if(driverstring == "direct3d8")
		driverType = video::EDT_DIRECT3D8;
	else if(driverstring == "direct3d9")
		driverType = video::EDT_DIRECT3D9;
	else if(driverstring == "opengl")
		driverType = video::EDT_OPENGL;
	else
	{
		errorstream<<"WARNING: Invalid video_driver specified; defaulting "
				"to opengl"<<std::endl;
		driverType = video::EDT_OPENGL;
	}

	/*
		Create device and exit if creation failed
	*/

	MyEventReceiver receiver;

	IrrlichtDevice *device;

	SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
	params.DriverType    = driverType;
	params.WindowSize    = core::dimension2d<u32>(screenW, screenH);
	params.Bits          = bits;
	params.AntiAlias     = fsaa;
	params.Fullscreen    = fullscreen;
	params.Stencilbuffer = false;
	params.Vsync         = vsync;
	params.EventReceiver = &receiver;

	device = createDeviceEx(params);

	if (device == 0)
		return 1; // could not create selected driver.
	
	/*
		Continue initialization
	*/

	video::IVideoDriver* driver = device->getVideoDriver();

	/*
		This changes the minimum allowed number of vertices in a VBO.
		Default is 500.
	*/
	//driver->setMinHardwareBufferVertexCount(50);

	// Create time getter
	g_timegetter = new IrrlichtTimeGetter(device);
	
	// Create game callback for menus
	g_gamecallback = new MainGameCallback(device);
	
	/*
		Speed tests (done after irrlicht is loaded to get timer)
	*/
	if(cmd_args.getFlag("speedtests"))
	{
		dstream<<"Running speed tests"<<std::endl;
		SpeedTests();
		return 0;
	}
	
	device->setResizable(true);

	bool random_input = g_settings->getBool("random_input")
			|| cmd_args.getFlag("random-input");
	InputHandler *input = NULL;
	if(random_input)
		input = new RandomInputHandler();
	else
		input = new RealInputHandler(device, &receiver);
	
	scene::ISceneManager* smgr = device->getSceneManager();

	guienv = device->getGUIEnvironment();
	gui::IGUISkin* skin = guienv->getSkin();
	gui::IGUIFont* font = guienv->getFont(getTexturePath("fontlucida.png").c_str());
	if(font)
		skin->setFont(font);
	else
		errorstream<<"WARNING: Font file was not found."
				" Using default font."<<std::endl;
	// If font was not found, this will get us one
	font = skin->getFont();
	assert(font);
	
	u32 text_height = font->getDimension(L"Hello, world!").Height;
	infostream<<"text_height="<<text_height<<std::endl;

	//skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,0,0,0));
	skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255));
	//skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(0,0,0,0));
	//skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(0,0,0,0));
	skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255,0,0,0));
	skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255,0,0,0));
	skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255,70,100,50));
	skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255,255,255,255));

#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
	// Irrlicht 1.8 input colours
	skin->setColor(gui::EGDC_EDITABLE, video::SColor(255,128,128,128));
	skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255,96,134,49));
#endif

	/*
		GUI stuff
	*/

	ChatBackend chat_backend;

	/*
		If an error occurs, this is set to something and the
		menu-game loop is restarted. It is then displayed before
		the menu.
	*/
	std::wstring error_message = L"";

	// The password entered during the menu screen,
	std::string password;

	bool first_loop = true;

	/*
		Menu-game loop
	*/
	while(device->run() && kill == false)
	{
		// Set the window caption
		device->setWindowCaption((std::wstring(L"Minetest [")+wgettext("Main Menu")+L"]").c_str());

		// This is used for catching disconnects
		try
		{

			/*
				Clear everything from the GUIEnvironment
			*/
			guienv->clear();
			
			/*
				We need some kind of a root node to be able to add
				custom gui elements directly on the screen.
				Otherwise they won't be automatically drawn.
			*/
			guiroot = guienv->addStaticText(L"",
					core::rect<s32>(0, 0, 10000, 10000));
			
			SubgameSpec gamespec;
			WorldSpec worldspec;
			bool simple_singleplayer_mode = false;

			// These are set up based on the menu and other things
			std::string current_playername = "inv£lid";
			std::string current_password = "";
			std::string current_address = "does-not-exist";
			int current_port = 0;

			/*
				Out-of-game menu loop.

				Loop quits when menu returns proper parameters.
			*/
			while(kill == false)
			{
				// If skip_main_menu, only go through here once
				if(skip_main_menu && !first_loop){
					kill = true;
					break;
				}
				first_loop = false;
				
				// Cursor can be non-visible when coming from the game
				device->getCursorControl()->setVisible(true);
				// Some stuff are left to scene manager when coming from the game
				// (map at least?)
				smgr->clear();
				
				// Initialize menu data
				MainMenuData menudata;
				if(g_settings->exists("selected_mainmenu_tab"))
					menudata.selected_tab = g_settings->getS32("selected_mainmenu_tab");
				menudata.address = narrow_to_wide(address);
				menudata.name = narrow_to_wide(playername);
				menudata.port = narrow_to_wide(itos(port));
				if(cmd_args.exists("password"))
					menudata.password = narrow_to_wide(cmd_args.get("password"));
				menudata.fancy_trees = g_settings->getBool("new_style_leaves");
				menudata.smooth_lighting = g_settings->getBool("smooth_lighting");
				menudata.clouds_3d = g_settings->getBool("enable_3d_clouds");
				menudata.opaque_water = g_settings->getBool("opaque_water");
				menudata.mip_map = g_settings->getBool("mip_map");
				menudata.anisotropic_filter = g_settings->getBool("anisotropic_filter");
				menudata.bilinear_filter = g_settings->getBool("bilinear_filter");
				menudata.trilinear_filter = g_settings->getBool("trilinear_filter");
				menudata.enable_shaders = g_settings->getS32("enable_shaders");
				menudata.preload_item_visuals = g_settings->getBool("preload_item_visuals");
				driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, menudata.mip_map);
				menudata.creative_mode = g_settings->getBool("creative_mode");
				menudata.enable_damage = g_settings->getBool("enable_damage");
				// Default to selecting nothing
				menudata.selected_world = -1;
				// Get world listing for the menu
				std::vector<WorldSpec> worldspecs = getAvailableWorlds();
				// If there is only one world, select it
				if(worldspecs.size() == 1){
					menudata.selected_world = 0;
				}
				// Otherwise try to select according to selected_world_path
				else if(g_settings->exists("selected_world_path")){
					std::string trypath = g_settings->get("selected_world_path");
					for(u32 i=0; i<worldspecs.size(); i++){
						if(worldspecs[i].path == trypath){
							menudata.selected_world = i;
							break;
						}
					}
				}
				// If a world was commanded, append and select it
				if(commanded_world != ""){
					std::string gameid = getWorldGameId(commanded_world, true);
					std::string name = _("[--world parameter]");
					if(gameid == ""){
						gameid = g_settings->get("default_game");
						name += " [new]";
					}
					WorldSpec spec(commanded_world, name, gameid);
					worldspecs.push_back(spec);
					menudata.selected_world = worldspecs.size()-1;
				}
				// Copy worldspecs to menu
				menudata.worlds = worldspecs;

				if(skip_main_menu == false)
				{
					video::IVideoDriver* driver = device->getVideoDriver();
					
					infostream<<"Waiting for other menus"<<std::endl;
					while(device->run() && kill == false)
					{
						if(noMenuActive())
							break;
						driver->beginScene(true, true,
								video::SColor(255,128,128,128));
						drawMenuBackground(driver);
						guienv->drawAll();
						driver->endScene();
						// On some computers framerate doesn't seem to be
						// automatically limited
						sleep_ms(25);
					}
					infostream<<"Waited for other menus"<<std::endl;

					GUIMainMenu *menu =
							new GUIMainMenu(guienv, guiroot, -1, 
								&g_menumgr, &menudata, g_gamecallback);
					menu->allowFocusRemoval(true);

					if(error_message != L"")
					{
						verbosestream<<"error_message = "
								<<wide_to_narrow(error_message)<<std::endl;

						GUIMessageMenu *menu2 =
								new GUIMessageMenu(guienv, guiroot, -1, 
									&g_menumgr, error_message.c_str());
						menu2->drop();
						error_message = L"";
					}

					infostream<<"Created main menu"<<std::endl;

					while(device->run() && kill == false)
					{
						if(menu->getStatus() == true)
							break;

						//driver->beginScene(true, true, video::SColor(255,0,0,0));
						driver->beginScene(true, true, video::SColor(255,128,128,128));

						drawMenuBackground(driver);

						guienv->drawAll();
						
						driver->endScene();
						
						// On some computers framerate doesn't seem to be
						// automatically limited
						sleep_ms(25);
					}
					
					infostream<<"Dropping main menu"<<std::endl;

					menu->drop();
				}

				playername = wide_to_narrow(menudata.name);
				password = translatePassword(playername, menudata.password);
				//infostream<<"Main: password hash: '"<<password<<"'"<<std::endl;

				address = wide_to_narrow(menudata.address);
				int newport = stoi(wide_to_narrow(menudata.port));
				if(newport != 0)
					port = newport;
				simple_singleplayer_mode = menudata.simple_singleplayer_mode;
				// Save settings
				g_settings->setS32("selected_mainmenu_tab", menudata.selected_tab);
				g_settings->set("new_style_leaves", itos(menudata.fancy_trees));
				g_settings->set("smooth_lighting", itos(menudata.smooth_lighting));
				g_settings->set("enable_3d_clouds", itos(menudata.clouds_3d));
				g_settings->set("opaque_water", itos(menudata.opaque_water));

				g_settings->set("mip_map", itos(menudata.mip_map));
				g_settings->set("anisotropic_filter", itos(menudata.anisotropic_filter));
				g_settings->set("bilinear_filter", itos(menudata.bilinear_filter));
				g_settings->set("trilinear_filter", itos(menudata.trilinear_filter));

				g_settings->setS32("enable_shaders", menudata.enable_shaders);
				g_settings->set("preload_item_visuals", itos(menudata.preload_item_visuals));

				g_settings->set("creative_mode", itos(menudata.creative_mode));
				g_settings->set("enable_damage", itos(menudata.enable_damage));
				g_settings->set("name", playername);
				g_settings->set("address", address);
				g_settings->set("port", itos(port));
				if(menudata.selected_world != -1)
					g_settings->set("selected_world_path",
							worldspecs[menudata.selected_world].path);
				
				// Break out of menu-game loop to shut down cleanly
				if(device->run() == false || kill == true)
					break;
				
				current_playername = playername;
				current_password = password;
				current_address = address;
				current_port = port;

				// If using simple singleplayer mode, override
				if(simple_singleplayer_mode){
					current_playername = "singleplayer";
					current_password = "";
					current_address = "";
					current_port = 30011;
				}
				
				// Set world path to selected one
				if(menudata.selected_world != -1){
					worldspec = worldspecs[menudata.selected_world];
					infostream<<"Selected world: "<<worldspec.name
							<<" ["<<worldspec.path<<"]"<<std::endl;
				}

				// Only refresh if so requested
				if(menudata.only_refresh){
					infostream<<"Refreshing menu"<<std::endl;
					continue;
				}
				
				// Create new world if requested
				if(menudata.create_world_name != L"")
				{
					std::string path = porting::path_user + DIR_DELIM
							"worlds" + DIR_DELIM
							+ wide_to_narrow(menudata.create_world_name);
					// Create world if it doesn't exist
					if(!initializeWorld(path, menudata.create_world_gameid)){
						error_message = wgettext("Failed to initialize world");
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					g_settings->set("selected_world_path", path);
					continue;
				}

				// If local game
				if(current_address == "")
				{
					if(menudata.selected_world == -1){
						error_message = wgettext("No world selected and no address "
								"provided. Nothing to do.");
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					// Load gamespec for required game
					gamespec = findWorldSubgame(worldspec.path);
					if(!gamespec.isValid() && !commanded_gamespec.isValid()){
						error_message = wgettext("Could not find or load game \"")
								+ narrow_to_wide(worldspec.gameid) + L"\"";
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					if(commanded_gamespec.isValid() &&
							commanded_gamespec.id != worldspec.gameid){
						errorstream<<"WARNING: Overriding gamespec from \""
								<<worldspec.gameid<<"\" to \""
								<<commanded_gamespec.id<<"\""<<std::endl;
						gamespec = commanded_gamespec;
					}

					if(!gamespec.isValid()){
						error_message = wgettext("Invalid gamespec.");
						error_message += L" (world_gameid="
								+narrow_to_wide(worldspec.gameid)+L")";
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
				}

				// Continue to game
				break;
			}
			
			// Break out of menu-game loop to shut down cleanly
			if(device->run() == false || kill == true)
				break;

			/*
				Run game
			*/
			the_game(
				kill,
				random_input,
				input,
				device,
				font,
				worldspec.path,
				current_playername,
				current_password,
				current_address,
				current_port,
				error_message,
				configpath,
				chat_backend,
				gamespec,
				simple_singleplayer_mode
			);

		} //try
		catch(con::PeerNotFoundException &e)
		{
			error_message = wgettext("Connection error (timed out?)");
			errorstream<<wide_to_narrow(error_message)<<std::endl;
		}
		catch(ServerError &e)
		{
			error_message = narrow_to_wide(e.what());
			errorstream<<wide_to_narrow(error_message)<<std::endl;
		}
		catch(ModError &e)
		{
			errorstream<<e.what()<<std::endl;
			error_message = narrow_to_wide(e.what()) + wgettext("\nCheck debug.txt for details.");
		}
#ifdef NDEBUG
		catch(std::exception &e)
		{
			std::string narrow_message = "Some exception: \"";
			narrow_message += e.what();
			narrow_message += "\"";
			errorstream<<narrow_message<<std::endl;
			error_message = narrow_to_wide(narrow_message);
		}
#endif

		// If no main menu, show error and exit
		if(skip_main_menu)
		{
			if(error_message != L""){
				verbosestream<<"error_message = "
						<<wide_to_narrow(error_message)<<std::endl;
				retval = 1;
			}
			break;
		}
	} // Menu-game loop
	
	delete input;

	/*
		In the end, delete the Irrlicht device.
	*/
	device->drop();

#endif // !SERVER
	
	// Update configuration file
	if(configpath != "")
		g_settings->updateConfigFile(configpath.c_str());
	
	// Print modified quicktune values
	{
		bool header_printed = false;
		std::vector<std::string> names = getQuicktuneNames();
		for(u32 i=0; i<names.size(); i++){
			QuicktuneValue val = getQuicktuneValue(names[i]);
			if(!val.modified)
				continue;
			if(!header_printed){
				dstream<<"Modified quicktune values:"<<std::endl;
				header_printed = true;
			}
			dstream<<names[i]<<" = "<<val.getString()<<std::endl;
		}
	}

	END_DEBUG_EXCEPTION_HANDLER(errorstream)
	
	debugstreams_deinit();
	
	return retval;
}
Exemplo n.º 29
0
void GUIConfirmRegistration::regenerateGui(v2u32 screensize)
{
	acceptInput();
	removeChildren();

	/*
		Calculate new sizes and positions
	*/
	core::rect<s32> rect(screensize.X / 2 - 600 / 2, screensize.Y / 2 - 360 / 2,
			screensize.X / 2 + 600 / 2, screensize.Y / 2 + 360 / 2);

	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 size = rect.getSize();
	v2s32 topleft_client(0, 0);

	const wchar_t *text;

	/*
		Add stuff
	*/
	s32 ypos = 30;
	{
		std::string address = m_address;
		if (address.empty())
			address = "localhost";
		core::rect<s32> rect2(0, 0, 540, 180);
		rect2 += topleft_client + v2s32(30, ypos);
		static const std::string info_text_template = strgettext(
				"You are about to join the server at %1$s with the "
				"name \"%2$s\" for the first time. If you proceed, a "
				"new account using your credentials will be created "
				"on this server.\n"
				"Please retype your password and click Register and "
				"Join to confirm account creation or click Cancel to "
				"abort.");
		char info_text_buf[1024];
		porting::mt_snprintf(info_text_buf, sizeof(info_text_buf),
				info_text_template.c_str(), address.c_str(),
				m_playername.c_str());

		wchar_t *info_text_buf_wide = utf8_to_wide_c(info_text_buf);
		gui::IGUIEditBox *e = new gui::intlGUIEditBox(info_text_buf_wide, true,
				Environment, this, ID_message, rect2, false, true);
		delete[] info_text_buf_wide;
		e->drop();
		e->setMultiLine(true);
		e->setWordWrap(true);
		e->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_CENTER);
	}

	ypos += 210;
	{
		core::rect<s32> rect2(0, 0, 540, 30);
		rect2 += topleft_client + v2s32(30, ypos);
		gui::IGUIEditBox *e = Environment->addEditBox(m_pass_confirm.c_str(),
				rect2, true, this, ID_confirmPassword);
		e->setPasswordBox(true);
	}

	ypos += 60;
	{
		core::rect<s32> rect2(0, 0, 230, 35);
		rect2 = rect2 + v2s32(size.X / 2 - 220, ypos);
		text = wgettext("Register and Join");
		Environment->addButton(rect2, this, ID_confirm, text);
		delete[] text;
	}
	{
		core::rect<s32> rect2(0, 0, 120, 35);
		rect2 = rect2 + v2s32(size.X / 2 + 70, ypos);
		text = wgettext("Cancel");
		Environment->addButton(rect2, this, ID_cancel, text);
		delete[] text;
	}
	{
		core::rect<s32> rect2(0, 0, 200, 20);
		rect2 += topleft_client + v2s32(30, ypos - 40);
		text = wgettext("Passwords do not match!");
		IGUIElement *e = Environment->addStaticText(
				text, rect2, false, true, this, ID_message);
		e->setVisible(false);
		delete[] text;
	}
}
Exemplo n.º 30
0
void GUISettingsMenu::regenerateGui(v2u32 screensize)
{
	bool fancy_trees;
	bool smooth_lighting;
	bool clouds_3d;
	bool opaque_water;
	bool fullscreen;
	bool particles;
	bool mipmap;
	bool bilinear;
	bool trilinear;
	bool anisotropic;
	bool hotbar;
	bool wield_index;
	f32 volume;

	m_screensize = screensize;

	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_FANCYTREE_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			fancy_trees = ((gui::IGUICheckBox*)e)->isChecked();
		else
			fancy_trees = m_data.fancy_trees;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_SMOOTH_LIGHTING_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			smooth_lighting = ((gui::IGUICheckBox*)e)->isChecked();
		else
			smooth_lighting = m_data.smooth_lighting;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_3D_CLOUDS_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			clouds_3d = ((gui::IGUICheckBox*)e)->isChecked();
		else
			clouds_3d = m_data.clouds_3d;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_OPAQUE_WATER_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			opaque_water = ((gui::IGUICheckBox*)e)->isChecked();
		else
			opaque_water = m_data.opaque_water;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_FULLSCREEN_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			fullscreen = ((gui::IGUICheckBox*)e)->isChecked();
		else
			fullscreen = m_data.fullscreen;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_PARTICLES_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			particles = ((gui::IGUICheckBox*)e)->isChecked();
		else
			particles = m_data.particles;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_MIPMAP_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			mipmap = ((gui::IGUICheckBox*)e)->isChecked();
		else
			mipmap = m_data.mip_map;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_BILINEAR_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			bilinear = ((gui::IGUICheckBox*)e)->isChecked();
		else
			bilinear = m_data.bilinear_filter;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_TRILINEAR_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			trilinear = ((gui::IGUICheckBox*)e)->isChecked();
		else
			trilinear = m_data.trilinear_filter;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_ANISOTROPIC_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			anisotropic = ((gui::IGUICheckBox*)e)->isChecked();
		else
			anisotropic = m_data.anisotropic_filter;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_HOTBAR_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			hotbar = ((gui::IGUICheckBox*)e)->isChecked();
		else
			hotbar = m_data.hotbar;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_WIELDINDEX_CB);
		if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
			wield_index = ((gui::IGUICheckBox*)e)->isChecked();
		else
			wield_index = m_data.wield_index;
	}
	{
		gui::IGUIElement *e = getElementFromId(GUI_ID_VOLUME_SB);
		if(e != NULL && e->getType() == gui::EGUIET_SCROLL_BAR)
			volume = (float)((gui::IGUIScrollBar*)e)->getPos();
		else
			volume = m_data.volume;
	}
	/*
	 Remove stuff
	 */
	removeChildren();

	/*
	 Calculate new sizes and positions
	 */

	v2s32 size(800, 500);

	core::rect<s32> rect(
			screensize.X/2 - size.X/2,
			screensize.Y/2 - size.Y/2,
			screensize.X/2 + size.X/2,
			screensize.Y/2 + size.Y/2
	);

	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	// Main Menu button
	{
		core::rect<s32> rect(0, 0, 200, 40);
		rect += v2s32(25, 200);
		Environment->addButton(rect, this, GUI_ID_TAB_MAINMENU, wgettext("Main Menu"));
	}

	// Controls Settings button
	{
		core::rect<s32> rect(0, 0, 180, 40);
		rect += v2s32(35, 260);
		Environment->addButton(rect, this, GUI_ID_TAB_SETTINGS_CONTROLS, wgettext("Controls"));
	}
	// Graphics Settings button
	{
		core::rect<s32> rect(0, 0, 180, 40);
		rect += v2s32(35, 305);
		Environment->addButton(rect, this, GUI_ID_TAB_SETTINGS_GRAPHICS, wgettext("Graphics"));
	}
	// Video Settings button
	{
		core::rect<s32> rect(0, 0, 180, 40);
		rect += v2s32(35, 350);
		Environment->addButton(rect, this, GUI_ID_TAB_SETTINGS_VIDEO, wgettext("Video"));
	}
	// Sound Settings button
	{
		core::rect<s32> rect(0, 0, 180, 40);
		rect += v2s32(35, 395);
		Environment->addButton(rect, this, GUI_ID_TAB_SETTINGS_SOUND, wgettext("Sound"));
	}

	v2s32 topleft_content(250, 0);

	if (m_data.selected_tab == TAB_SETTINGS_CONTROLS) {
		{
			core::rect<s32> rect(0, 0, 550, 20);
			rect += topleft_content + v2s32(0, 20);
			gui::IGUIStaticText *t = Environment->addStaticText(wgettext("Controls"), rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
		}

		v2s32 offset(0, 40);

		for (int i=0; i<VLKC_MAX; i++) {
			if (keynames[i] == NULL)
				continue;
			{
				core::rect < s32 > rect(0, 0, 150, 20);
				rect += topleft_content + offset;
				gui::IGUIStaticText *t = Environment->addStaticText(keynames[i], rect, false, true, this, -1);
				t->setTextAlignment(gui::EGUIA_LOWERRIGHT, gui::EGUIA_UPPERLEFT);
			}

			{
				core::rect < s32 > rect(0, 0, 110, 30);
				rect += topleft_content + offset + v2s32(155, -5);
				Environment->addButton(rect, this, GUI_ID_KEYSETTINGS_BASE+i, keys[i].guiName().c_str());
			}
			offset += v2s32(0, 33);
			if (offset.Y > 450) {
				offset.Y = 40;
				offset.X = 275;
			}
		}
	}else if (m_data.selected_tab == TAB_SETTINGS_GRAPHICS) {
		{
			core::rect<s32> rect(0, 0, 550, 20);
			rect += topleft_content + v2s32(0, 20);
			gui::IGUIStaticText *t = Environment->addStaticText(wgettext("Graphics"), rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(80, 60);
			Environment->addCheckBox(fancy_trees, rect, this, GUI_ID_FANCYTREE_CB, wgettext("Fancy trees"));
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(80, 90);
			Environment->addCheckBox(smooth_lighting, rect, this, GUI_ID_SMOOTH_LIGHTING_CB, wgettext("Smooth Lighting"));
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(80, 120);
			Environment->addCheckBox(clouds_3d, rect, this, GUI_ID_3D_CLOUDS_CB, wgettext("3D Clouds"));
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(80, 150);
			Environment->addCheckBox(opaque_water, rect, this, GUI_ID_OPAQUE_WATER_CB, wgettext("Opaque water"));
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(290, 60);
			Environment->addCheckBox(hotbar, rect, this, GUI_ID_HOTBAR_CB, wgettext("Classic HUD"));
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(290, 90);
			gui::IGUICheckBox *c = Environment->addCheckBox(wield_index, rect, this, GUI_ID_WIELDINDEX_CB, wgettext("Wieldring Index"));
			c->setEnabled(!hotbar);
		}
		if (m_is_ingame) {
			core::rect<s32> rect(0, 0, 550, 20);
			rect += topleft_content + v2s32(0, 200);
			gui::IGUIStaticText *t = Environment->addStaticText(wgettext("Some settings cannot be changed in-game."), rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
		}
	}else if (m_data.selected_tab == TAB_SETTINGS_VIDEO) {
		{
			core::rect<s32> rect(0, 0, 550, 20);
			rect += topleft_content + v2s32(0, 20);
			gui::IGUIStaticText *t = Environment->addStaticText(wgettext("Video"), rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(80, 60);
			Environment->addCheckBox(fullscreen, rect, this, GUI_ID_FULLSCREEN_CB, wgettext("Fullscreen"));
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(80, 90);
			Environment->addCheckBox(particles, rect, this, GUI_ID_PARTICLES_CB, wgettext("Particles"));
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(80, 120);
			Environment->addCheckBox(mipmap, rect, this, GUI_ID_MIPMAP_CB, wgettext("Mip-Mapping"));
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(80, 150);
			Environment->addCheckBox(bilinear, rect, this, GUI_ID_BILINEAR_CB, wgettext("Bi-Linear Filtering"));
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(80, 180);
			Environment->addCheckBox(trilinear, rect, this, GUI_ID_TRILINEAR_CB, wgettext("Tri-Linear Filtering"));
		}
		{
			core::rect<s32> rect(0, 0, 200, 30);
			rect += topleft_content + v2s32(80, 210);
			Environment->addCheckBox(anisotropic, rect, this, GUI_ID_ANISOTROPIC_CB, wgettext("Anisotropic Filtering"));
		}
		if (m_is_ingame) {
			core::rect<s32> rect(0, 0, 550, 20);
			rect += topleft_content + v2s32(0, 250);
			gui::IGUIStaticText *t = Environment->addStaticText(wgettext("Some settings cannot be changed in-game."), rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
		}
	}else if (m_data.selected_tab == TAB_SETTINGS_SOUND) {
		{
			core::rect<s32> rect(0, 0, 550, 20);
			rect += topleft_content + v2s32(0, 20);
			gui::IGUIStaticText *t = Environment->addStaticText(wgettext("Sound"), rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
		}
		{
			core::rect<s32> rect(0, 0, 200, 15);
			rect += topleft_content + v2s32(80, 60);
			Environment->addStaticText(wgettext("Volume:"), rect, false, false, this, -1);
		}
		{
			core::rect<s32> rect(0, 0, 200, 15);
			rect += topleft_content + v2s32(290, 60);
			gui::IGUIScrollBar *sb = Environment->addScrollBar(true, rect, this, GUI_ID_VOLUME_SB);
			sb->setMin(0);
			sb->setMax(100);
			sb->setPos(volume);
		}
	}
}