00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "object/infoblock.hpp"
00018
00019 #include "object/player.hpp"
00020 #include "sprite/sprite_manager.hpp"
00021 #include "supertux/object_factory.hpp"
00022 #include "supertux/sector.hpp"
00023 #include "supertux/info_box_line.hpp"
00024 #include "util/reader.hpp"
00025 #include "video/drawing_context.hpp"
00026 #include "sprite/sprite.hpp"
00027
00028 namespace {
00029 const float SCROLL_DELAY = 0.5;
00030 const float SCROLL_DISTANCE = 16;
00031 const float WIDTH = 400;
00032 const float HEIGHT = 200;
00033 }
00034
00035 InfoBlock::InfoBlock(const Reader& lisp) :
00036 Block(sprite_manager->create("images/objects/bonus_block/infoblock.sprite")),
00037 message(),
00038 shown_pct(0),
00039 dest_pct(0),
00040 lines(),
00041 lines_height()
00042 {
00043 Vector pos;
00044 lisp.get("x", pos.x);
00045 lisp.get("y", pos.y);
00046 bbox.set_pos(pos);
00047
00048 if(!lisp.get("message", message)) {
00049 log_warning << "No message in InfoBlock" << std::endl;
00050 }
00051
00052
00053
00054
00055
00056 lines = InfoBoxLine::split(message, 400);
00057 lines_height = 0;
00058 for(size_t i = 0; i < lines.size(); ++i) lines_height+=lines[i]->get_height();
00059 }
00060
00061 InfoBlock::~InfoBlock()
00062 {
00063 for(std::vector<InfoBoxLine*>::iterator i = lines.begin(); i != lines.end(); i++) {
00064 delete *i;
00065 }
00066 }
00067
00068 void
00069 InfoBlock::hit(Player& player)
00070 {
00071 start_bounce(&player);
00072
00073
00074
00075
00076
00077
00078 if (dest_pct != 1) {
00079
00080
00081 Sector* parent = Sector::current();
00082 if (!parent) return;
00083 for (Sector::GameObjects::iterator i = parent->gameobjects.begin(); i != parent->gameobjects.end(); i++) {
00084 InfoBlock* block = dynamic_cast<InfoBlock*>(*i);
00085 if (!block) continue;
00086 if (block != this) block->hide_message();
00087 }
00088
00089
00090 show_message();
00091
00092 } else {
00093 hide_message();
00094 }
00095 }
00096
00097 Player*
00098 InfoBlock::get_nearest_player()
00099 {
00100
00101
00102 std::vector<Player*> players = Sector::current()->get_players();
00103 for (std::vector<Player*>::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) {
00104 Player* player = *playerIter;
00105 return player;
00106 }
00107
00108 return 0;
00109 }
00110
00111 void
00112 InfoBlock::update(float delta)
00113 {
00114 Block::update(delta);
00115
00116 if (delta == 0) return;
00117
00118
00119 if (dest_pct > 0) {
00120 Player* player = get_nearest_player();
00121 if (player) {
00122 Vector p1 = this->get_pos() + (this->get_bbox().p2 - this->get_bbox().p1) / 2;
00123 Vector p2 = player->get_pos() + (player->get_bbox().p2 - player->get_bbox().p1) / 2;
00124 Vector dist = (p2 - p1);
00125 float d = dist.norm();
00126 if (d > 128 || dist.y < 0) dest_pct = 0;
00127 }
00128 }
00129
00130
00131 if (shown_pct != dest_pct) {
00132 if (dest_pct > shown_pct) shown_pct = std::min(shown_pct + 2*delta, dest_pct);
00133 if (dest_pct < shown_pct) shown_pct = std::max(shown_pct - 2*delta, dest_pct);
00134 }
00135 }
00136
00137 void
00138 InfoBlock::draw(DrawingContext& context)
00139 {
00140 Block::draw(context);
00141
00142 if (shown_pct <= 0) return;
00143
00144 context.push_transform();
00145
00146 context.set_alpha(shown_pct);
00147
00148
00149
00150 float border = 8;
00151 float width = 400;
00152 float height = lines_height;
00153 float x1 = (get_bbox().p1.x + get_bbox().p2.x)/2 - width/2;
00154 float x2 = (get_bbox().p1.x + get_bbox().p2.x)/2 + width/2;
00155 float y1 = original_y - height;
00156
00157 if(x1 < 0) {
00158 x1 = 0;
00159 x2 = width;
00160 }
00161
00162 if(x2 > Sector::current()->get_width()) {
00163 x2 = Sector::current()->get_width();
00164 x1 = x2 - width;
00165 }
00166
00167
00168 context.draw_filled_rect(Vector(x1-border, y1-border), Vector(width+2*border, height+2*border-4), Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-50);
00169
00170 float y = y1;
00171 for(size_t i = 0; i < lines.size(); ++i) {
00172 if(y >= y1 + height) {
00173
00174
00175
00176 break;
00177 }
00178
00179 lines[i]->draw(context, Rectf(x1, y, x2, y), LAYER_GUI-50+1);
00180 y += lines[i]->get_height();
00181 }
00182
00183 context.pop_transform();
00184 }
00185
00186 void
00187 InfoBlock::show_message()
00188 {
00189 dest_pct = 1;
00190 }
00191
00192 void
00193 InfoBlock::hide_message()
00194 {
00195 dest_pct = 0;
00196 }
00197
00198