/*
-Minetest-c55
-Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include <IMaterialRendererServices.h>
+#include "IMeshCache.h"
#include "client.h"
#include "server.h"
#include "guiPauseMenu.h"
#include "subgame.h"
#include "quicktune_shortcutter.h"
#include "clientmap.h"
+#include "hud.h"
#include "sky.h"
#include "sound.h"
#if USE_SOUND
std::string m_formspec;
FormspecFormSource** m_game_formspec;
};
-/*
- Hotbar draw routine
-*/
-void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font,
- IGameDef *gamedef,
- v2s32 centerlowerpos, s32 imgsize, s32 itemcount,
- Inventory *inventory, s32 halfheartcount, u16 playeritem)
-{
- InventoryList *mainlist = inventory->getList("main");
- if(mainlist == NULL)
- {
- errorstream<<"draw_hotbar(): mainlist == NULL"<<std::endl;
- return;
- }
-
- s32 padding = imgsize/12;
- //s32 height = imgsize + padding*2;
- s32 width = itemcount*(imgsize+padding*2);
-
- // Position of upper left corner of bar
- v2s32 pos = centerlowerpos - v2s32(width/2, imgsize+padding*2);
-
- // Draw background color
- /*core::rect<s32> barrect(0,0,width,height);
- barrect += pos;
- video::SColor bgcolor(255,128,128,128);
- driver->draw2DRectangle(bgcolor, barrect, NULL);*/
-
- core::rect<s32> imgrect(0,0,imgsize,imgsize);
-
- for(s32 i=0; i<itemcount; i++)
- {
- const ItemStack &item = mainlist->getItem(i);
-
- core::rect<s32> rect = imgrect + pos
- + v2s32(padding+i*(imgsize+padding*2), padding);
-
- if(playeritem == i)
- {
- video::SColor c_outside(255,255,0,0);
- //video::SColor c_outside(255,0,0,0);
- //video::SColor c_inside(255,192,192,192);
- s32 x1 = rect.UpperLeftCorner.X;
- s32 y1 = rect.UpperLeftCorner.Y;
- s32 x2 = rect.LowerRightCorner.X;
- s32 y2 = rect.LowerRightCorner.Y;
- // Black base borders
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x1 - padding, y1 - padding),
- v2s32(x2 + padding, y1)
- ), NULL);
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x1 - padding, y2),
- v2s32(x2 + padding, y2 + padding)
- ), NULL);
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x1 - padding, y1),
- v2s32(x1, y2)
- ), NULL);
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x2, y1),
- v2s32(x2 + padding, y2)
- ), NULL);
- /*// Light inside borders
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x1 - padding/2, y1 - padding/2),
- v2s32(x2 + padding/2, y1)
- ), NULL);
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x1 - padding/2, y2),
- v2s32(x2 + padding/2, y2 + padding/2)
- ), NULL);
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x1 - padding/2, y1),
- v2s32(x1, y2)
- ), NULL);
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x2, y1),
- v2s32(x2 + padding/2, y2)
- ), NULL);
- */
- }
-
- video::SColor bgcolor2(128,0,0,0);
- driver->draw2DRectangle(bgcolor2, rect, NULL);
- drawItemStack(driver, font, item, rect, NULL, gamedef);
- }
-
- /*
- Draw hearts
- */
- video::ITexture *heart_texture =
- gamedef->getTextureSource()->getTextureRaw("heart.png");
- if(heart_texture)
- {
- v2s32 p = pos + v2s32(0, -20);
- for(s32 i=0; i<halfheartcount/2; i++)
- {
- const video::SColor color(255,255,255,255);
- const video::SColor colors[] = {color,color,color,color};
- core::rect<s32> rect(0,0,16,16);
- rect += p;
- driver->draw2DImage(heart_texture, rect,
- core::rect<s32>(core::position2d<s32>(0,0),
- core::dimension2di(heart_texture->getOriginalSize())),
- NULL, colors, true);
- p += v2s32(16,0);
- }
- if(halfheartcount % 2 == 1)
- {
- const video::SColor color(255,255,255,255);
- const video::SColor colors[] = {color,color,color,color};
- core::rect<s32> rect(0,0,16/2,16);
- rect += p;
- core::dimension2di srcd(heart_texture->getOriginalSize());
- srcd.Width /= 2;
- driver->draw2DImage(heart_texture, rect,
- core::rect<s32>(core::position2d<s32>(0,0), srcd),
- NULL, colors, true);
- p += v2s32(16,0);
- }
- }
-}
/*
Check if a node is pointable
// Calculate text height using the font
u32 text_height = font->getDimension(L"Random test string").Height;
- v2u32 screensize(0,0);
v2u32 last_screensize(0,0);
- screensize = driver->getScreenSize();
-
- const s32 hotbar_itemcount = 8;
- //const s32 hotbar_imagesize = 36;
- //const s32 hotbar_imagesize = 64;
- s32 hotbar_imagesize = 48;
+ v2u32 screensize = driver->getScreenSize();
/*
Draw "Loading" screen
sound_is_dummy = true;
}
+ Server *server = NULL;
+
+ try{
// Event manager
EventManager eventmgr;
/*
Create server.
- SharedPtr will delete it when it goes out of scope.
*/
- SharedPtr<Server> server;
+
if(address == ""){
draw_load_screen(L"Creating server...", driver, font);
infostream<<"Creating server"<<std::endl;
server->start(port);
}
- try{
do{ // Client scope (breakable do-while(0))
/*
LocalPlayer* player = client.getEnv().getLocalPlayer();
player->hurt_tilt_timer = 0;
player->hurt_tilt_strength = 0;
+
+ /*
+ HUD object
+ */
+ Hud hud(driver, guienv, font, text_height,
+ gamedef, player, &local_inventory);
for(;;)
{
v2s32 displaycenter(screensize.X/2,screensize.Y/2);
//bool screensize_changed = screensize != last_screensize;
- // Resize hotbar
- if(screensize.Y <= 800)
- hotbar_imagesize = 32;
- else if(screensize.Y <= 1280)
- hotbar_imagesize = 48;
- else
- hotbar_imagesize = 64;
+
+ // Update HUD values
+ hud.screensize = screensize;
+ hud.displaycenter = displaycenter;
+ hud.resizeHotbar();
// Hilight boxes collected during the loop and displayed
std::vector<aabb3f> hilightboxes;
{
s32 wheel = input->getMouseWheel();
u16 max_item = MYMIN(PLAYER_INVENTORY_SIZE-1,
- hotbar_itemcount-1);
+ hud.hotbar_itemcount-1);
if(wheel < 0)
{
const KeyPress *kp = NumberKey + (i + 1) % 10;
if(input->wasKeyDown(*kp))
{
- if(i < PLAYER_INVENTORY_SIZE && i < hotbar_itemcount)
+ if(i < PLAYER_INVENTORY_SIZE && i < hud.hotbar_itemcount)
{
new_playeritem = i;
{
update_wielded_item_trigger = true;
}
+ else if(event.type == CE_SPAWN_PARTICLE)
+ {
+ LocalPlayer* player = client.getEnv().getLocalPlayer();
+ AtlasPointer ap =
+ gamedef->tsrc()->getTexture(*(event.spawn_particle.texture));
+
+ new Particle(gamedef, smgr, player, client.getEnv(),
+ *event.spawn_particle.pos,
+ *event.spawn_particle.vel,
+ *event.spawn_particle.acc,
+ event.spawn_particle.expirationtime,
+ event.spawn_particle.size,
+ event.spawn_particle.collisiondetection, ap);
+ }
+ else if(event.type == CE_ADD_PARTICLESPAWNER)
+ {
+ LocalPlayer* player = client.getEnv().getLocalPlayer();
+ AtlasPointer ap =
+ gamedef->tsrc()->getTexture(*(event.add_particlespawner.texture));
+
+ new ParticleSpawner(gamedef, smgr, player,
+ event.add_particlespawner.amount,
+ event.add_particlespawner.spawntime,
+ *event.add_particlespawner.minpos,
+ *event.add_particlespawner.maxpos,
+ *event.add_particlespawner.minvel,
+ *event.add_particlespawner.maxvel,
+ *event.add_particlespawner.minacc,
+ *event.add_particlespawner.maxacc,
+ event.add_particlespawner.minexptime,
+ event.add_particlespawner.maxexptime,
+ event.add_particlespawner.minsize,
+ event.add_particlespawner.maxsize,
+ event.add_particlespawner.collisiondetection,
+ ap,
+ event.add_particlespawner.id);
+ }
+ else if(event.type == CE_DELETE_PARTICLESPAWNER)
+ {
+ delete_particlespawner (event.delete_particlespawner.id);
+ }
+ else if (event.type == CE_HUDADD)
+ {
+ u32 id = event.hudadd.id;
+ size_t nhudelem = player->hud.size();
+ if (id > nhudelem || (id < nhudelem && player->hud[id])) {
+ delete event.hudadd.pos;
+ delete event.hudadd.name;
+ delete event.hudadd.scale;
+ delete event.hudadd.text;
+ delete event.hudadd.align;
+ delete event.hudadd.offset;
+ continue;
+ }
+
+ HudElement *e = new HudElement;
+ e->type = (HudElementType)event.hudadd.type;
+ e->pos = *event.hudadd.pos;
+ e->name = *event.hudadd.name;
+ e->scale = *event.hudadd.scale;
+ e->text = *event.hudadd.text;
+ e->number = event.hudadd.number;
+ e->item = event.hudadd.item;
+ e->dir = event.hudadd.dir;
+ e->align = *event.hudadd.align;
+ e->offset = *event.hudadd.offset;
+
+ if (id == nhudelem)
+ player->hud.push_back(e);
+ else
+ player->hud[id] = e;
+
+ delete event.hudadd.pos;
+ delete event.hudadd.name;
+ delete event.hudadd.scale;
+ delete event.hudadd.text;
+ delete event.hudadd.align;
+ delete event.hudadd.offset;
+ }
+ else if (event.type == CE_HUDRM)
+ {
+ u32 id = event.hudrm.id;
+ if (id < player->hud.size() && player->hud[id]) {
+ delete player->hud[id];
+ player->hud[id] = NULL;
+ }
+ }
+ else if (event.type == CE_HUDCHANGE)
+ {
+ u32 id = event.hudchange.id;
+ if (id >= player->hud.size() || !player->hud[id]) {
+ delete event.hudchange.v2fdata;
+ delete event.hudchange.sdata;
+ continue;
+ }
+
+ HudElement* e = player->hud[id];
+ switch (event.hudchange.stat) {
+ case HUD_STAT_POS:
+ e->pos = *event.hudchange.v2fdata;
+ break;
+ case HUD_STAT_NAME:
+ e->name = *event.hudchange.sdata;
+ break;
+ case HUD_STAT_SCALE:
+ e->scale = *event.hudchange.v2fdata;
+ break;
+ case HUD_STAT_TEXT:
+ e->text = *event.hudchange.sdata;
+ break;
+ case HUD_STAT_NUMBER:
+ e->number = event.hudchange.data;
+ break;
+ case HUD_STAT_ITEM:
+ e->item = event.hudchange.data;
+ break;
+ case HUD_STAT_DIR:
+ e->dir = event.hudchange.data;
+ break;
+ case HUD_STAT_ALIGN:
+ e->align = *event.hudchange.v2fdata;
+ break;
+ case HUD_STAT_OFFSET:
+ e->offset = *event.hudchange.v2fdata;
+ break;
+ }
+
+ delete event.hudchange.v2fdata;
+ delete event.hudchange.sdata;
+ }
}
}
infotext = narrow_to_wide(meta->getString("infotext"));
} else {
MapNode n = map.getNode(nodepos);
- if(nodedef->get(n).tiledef[0].name == "unknown_block.png"){
+ if(nodedef->get(n).tiledef[0].name == "unknown_node.png"){
infotext = L"Unknown node: ";
infotext += narrow_to_wide(nodedef->get(n).name);
}
}
- // We can't actually know, but assume the sound of right-clicking
- // to be the sound of placing a node
- soundmaker.m_player_rightpunch_sound.gain = 0.5;
- soundmaker.m_player_rightpunch_sound.name = "default_place_node";
-
/*
Handle digging
*/
const ContentFeatures &features =
client.getNodeDefManager()->get(n);
addPunchingParticles
- (gamedef, smgr, player, nodepos, features.tiles);
+ (gamedef, smgr, player, client.getEnv(),
+ nodepos, features.tiles);
}
}
const ContentFeatures &features =
client.getNodeDefManager()->get(wasnode);
addDiggingParticles
- (gamedef, smgr, player, nodepos, features.tiles);
+ (gamedef, smgr, player, client.getEnv(),
+ nodepos, features.tiles);
}
dig_time = 0;
<<") - Position not loaded"<<std::endl;
}
}while(0);
+
+ // Read the sound
+ soundmaker.m_player_rightpunch_sound = def.sound_place;
}
}
}
*/
allparticles_step(dtime, client.getEnv());
+ allparticlespawners_step(dtime, client.getEnv());
/*
Fog
char temptext[300];
snprintf(temptext, 300,
"(% .1f, % .1f, % .1f)"
- " (yaw = %.1f) (seed = %lli)",
+ " (yaw = %.1f) (seed = %llu)",
player_position.X/BS,
player_position.Y/BS,
player_position.Z/BS,
wrapDegrees_0_360(camera_yaw),
- client.getMapSeed());
+ (unsigned long long)client.getMapSeed());
guitext2->setText(narrow_to_wide(temptext).c_str());
guitext2->setVisible(true);
*/
TimeTaker tt_draw("mainloop: draw");
-
{
TimeTaker timer("beginScene");
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
- if(show_hud)
- {
- v3f selectionbox_color = g_settings->getV3F("selectionbox_color");
- u32 selectionbox_color_r = rangelim(myround(selectionbox_color.X), 0, 255);
- u32 selectionbox_color_g = rangelim(myround(selectionbox_color.Y), 0, 255);
- u32 selectionbox_color_b = rangelim(myround(selectionbox_color.Z), 0, 255);
-
- for(std::vector<aabb3f>::const_iterator
- i = hilightboxes.begin();
- i != hilightboxes.end(); i++)
- {
- /*infostream<<"hilightbox min="
- <<"("<<i->MinEdge.X<<","<<i->MinEdge.Y<<","<<i->MinEdge.Z<<")"
- <<" max="
- <<"("<<i->MaxEdge.X<<","<<i->MaxEdge.Y<<","<<i->MaxEdge.Z<<")"
- <<std::endl;*/
- driver->draw3DBox(*i, video::SColor(255,selectionbox_color_r,selectionbox_color_g,selectionbox_color_b));
- }
- }
-
+ if (show_hud)
+ hud.drawSelectionBoxes(hilightboxes);
/*
Wielded tool
*/
- if(show_hud)
+ if(show_hud && (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE))
{
// Warning: This clears the Z buffer.
camera.drawWieldedTool();
/*
Draw crosshair
*/
- if(show_hud)
- {
- v3f crosshair_color = g_settings->getV3F("crosshair_color");
- u32 crosshair_color_r = rangelim(myround(crosshair_color.X), 0, 255);
- u32 crosshair_color_g = rangelim(myround(crosshair_color.Y), 0, 255);
- u32 crosshair_color_b = rangelim(myround(crosshair_color.Z), 0, 255);
- u32 crosshair_alpha = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255);
-
- driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),
- displaycenter + core::vector2d<s32>(10,0),
- video::SColor(crosshair_alpha,crosshair_color_r,crosshair_color_g,crosshair_color_b));
- driver->draw2DLine(displaycenter - core::vector2d<s32>(0,10),
- displaycenter + core::vector2d<s32>(0,10),
- video::SColor(crosshair_alpha,crosshair_color_r,crosshair_color_g,crosshair_color_b));
- }
-
+ if (show_hud)
+ hud.drawCrosshair();
+
} // timer
//timer10.stop();
/*
Draw hotbar
*/
- if(show_hud)
+ if (show_hud)
{
- draw_hotbar(driver, font, gamedef,
- v2s32(displaycenter.X, screensize.Y),
- hotbar_imagesize, hotbar_itemcount, &local_inventory,
+ hud.drawHotbar(v2s32(displaycenter.X, screensize.Y),
client.getHP(), client.getPlayerItem());
}
player->hurt_tilt_strength = 0;
}
+ /*
+ Draw lua hud items
+ */
+ if (show_hud)
+ hud.drawLuaElements();
+
/*
Draw gui
*/
/*
Drop stuff
*/
- if(clouds)
+ if (clouds)
clouds->drop();
- if(gui_chat_console)
+ if (gui_chat_console)
gui_chat_console->drop();
+ clear_particles();
/*
Draw a "shutting down" screen, which will be shown while the map
L" running a different version of Minetest.";
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.");
+ }
+
+
if(!sound_is_dummy)
delete sound;
+ //has to be deleted first to stop all server threads
+ delete server;
+
delete tsrc;
delete shsrc;
delete nodedef;
delete itemdef;
+
+ //extended resource accounting
+ infostream << "Irrlicht resources after cleanup:" << std::endl;
+ infostream << "\tRemaining meshes : "
+ << device->getSceneManager()->getMeshCache()->getMeshCount() << std::endl;
+ infostream << "\tRemaining textures : "
+ << driver->getTextureCount() << std::endl;
+ for (unsigned int i = 0; i < driver->getTextureCount(); i++ ) {
+ irr::video::ITexture* texture = driver->getTextureByIndex(i);
+ infostream << "\t\t" << i << ":" << texture->getName().getPath().c_str()
+ << std::endl;
+ }
+ infostream << "\tRemaining materials: "
+ << driver-> getMaterialRendererCount ()
+ << " (note: irrlicht doesn't support removing renderers)"<< std::endl;
}