// Frame event handling void ActionBar::draw(GameState* gs) const { perf_timer_begin(FUNCNAME); PlayerInst* player = gs->local_player(); draw_player_weapon_actionbar(gs, player, bbox.x1, bbox.y1); draw_player_spell_actionbar(gs, player, BBox(bbox.x1 + EQUIP_SLOT_WIDTH, bbox.y1, bbox.x2, bbox.y2)); perf_timer_end(FUNCNAME); }
/* General gl_print function for others to delegate to */ static Dim gl_print_impl(const font_data& font, const Colour& c, Pos p, int max_width, bool center_x, bool center_y, bool actually_print, const char* fmt, va_list ap) { perf_timer_begin(FUNCNAME); char text[512]; vsnprintf(text, 512, fmt, ap); va_end(ap); Dim offset(0, 0); std::vector<int> line_splits; int measured_width = process_string(font, text, max_width, line_splits); if (center_x) { p.x -= measured_width / 2; } if (center_y) { p.y -= font.h * line_splits.size() / 2; } glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, font.font_img.texture); glColor4ub(c.r, c.g, c.b, c.a); glBegin(GL_QUADS); for (int linenum = 0, i = 0; linenum < line_splits.size(); linenum++) { int len = 0; int eol = line_splits[linenum]; offset.h += font.h; for (; i < eol; i++) { unsigned char chr = text[i]; if (chr == '\n') { continue; //skip newline char } const char_data& cdata = font.data[chr]; len += cdata.advance; if (actually_print) { gl_draw_glyph(font, chr, p.x + len - (cdata.advance - cdata.left), p.y + offset.h - cdata.move_up, c); } } offset.w = std::max(len, offset.w); offset.h += 1; } glEnd(); glDisable(GL_TEXTURE_2D); perf_timer_end(FUNCNAME); return offset; }
void PlayerInst::perform_queued_actions(GameState* gs) { perf_timer_begin(FUNCNAME); GameSettings& settings = gs->game_settings(); if (settings.saving_to_action_file()) { save_actions(gs, queued_actions); } for (int i = 0; i < queued_actions.size(); i++) { perform_action(gs, queued_actions[i]); } queued_actions.clear(); actions_set_for_turn = false; perf_timer_end(FUNCNAME); }
void GameHud::draw(GameState* gs) { perf_timer_begin(FUNCNAME); gl_set_drawing_area(0, 0, sidebar_box.x2, sidebar_box.y2); gl_draw_rectangle(sidebar_box.x1, sidebar_box.y1, width(), height(), bg_colour); PlayerInst* player_inst = gs->local_player(); if (!player_inst) return; action_bar.draw(gs); sidebar.draw(gs); // Must draw console after other components have chance to draw content there console.draw(gs); perf_timer_end(FUNCNAME); }
int GameNetConnection::poll_messages(int timeout) { if (_connection) { for (int i = 0; i < _delayed_messages.size(); i++) { QueuedMessage& qm = _delayed_messages[i]; if (_handle_message(qm.sender, *qm.message)) { delete qm.message; _delayed_messages.erase(_delayed_messages.begin() + i); i--; } } perf_timer_begin("*** NETWORK POLLING ***"); int polln = _connection->poll(gamenetconnection_consume_message, (void*) this, timeout); perf_timer_end("*** NETWORK POLLING ***"); return polln; } return 0; }
void GameChat::draw_player_chat(GameState* gs) const { perf_timer_begin(FUNCNAME); const ldraw::Font& font = gs->font(); const int padding = 5; int line_sep = font.height() + 2; Size vsize(gs->view().size()); Size chat_size(vsize.w, 100); Pos chat_pos(0, 0); Pos text_pos(chat_pos.x + padding, chat_pos.y + padding); ldraw::draw_rectangle(COL_CONSOLE_BOX.alpha(50 * fade_out), BBox(chat_pos, chat_size)); bool draw_typed_message = is_typing || !typing_field.empty(); int start_msg = 0; int message_space = chat_size.h - padding * 2 - (draw_typed_message ? line_sep : 0); int msgs_in_screen = message_space / line_sep; if (messages.size() > msgs_in_screen) { start_msg = messages.size() - msgs_in_screen; } for (int i = start_msg; i < messages.size(); i++) { messages[i].draw(font, fade_out, text_pos); text_pos.y += line_sep; } if (draw_typed_message) { int type_y = chat_pos.y + chat_size.h - padding - line_sep; ldraw::draw_line(Colour(200, 200, 200, fade_out * 180), Pos(chat_pos.x, type_y), Pos(chat_pos.x + chat_size.w, type_y)); ChatMessage typed_message = get_field_as_chat_message(gs, false); typed_message.draw(font, fade_out, Pos(text_pos.x, type_y + padding - 1)); } perf_timer_end(FUNCNAME); }
void GameChat::draw_player_chat(GameState* gs) const { perf_timer_begin(FUNCNAME); const font_data& font = gs->primary_font(); const int padding = 5; int line_sep = font.h + 2; int view_w = gs->view().width, view_h = gs->view().height; int chat_w = view_w, chat_h = 100; int chat_x = 0, chat_y = 0; //h - chat_h - TILE_SIZE; int text_x = chat_x + padding, text_y = chat_y + padding; gl_draw_rectangle(chat_x, chat_y, chat_w, chat_h, COL_CONSOLE_BOX.with_alpha(50 * fade_out)); bool draw_typed_message = is_typing || !typed_message.empty(); int start_msg = 0; int message_space = chat_h - padding * 2 - (draw_typed_message ? line_sep : 0); int msgs_in_screen = message_space / line_sep; if (messages.size() > msgs_in_screen) { start_msg = messages.size() - msgs_in_screen; } for (int i = start_msg; i < messages.size(); i++) { messages[i].draw(font, fade_out, text_x, text_y); text_y += line_sep; } if (draw_typed_message) { int type_y = chat_y + chat_h - padding - line_sep; gl_draw_line(chat_x, type_y, chat_x + chat_w, type_y, Colour(200, 200, 200, fade_out * 180)); typed_message.draw(font, fade_out, text_x, type_y + padding - 1); } perf_timer_end(FUNCNAME); }
void MonsterController::pre_step(GameState* gs) { perf_timer_begin(FUNCNAME); CollisionAvoidance& coll_avoid = gs->collision_avoidance(); PlayerInst* local_player = gs->local_player(); std::vector<EnemyOfInterest> eois; players = gs->players_in_level(); //Update 'mids' to only hold live objects std::vector<obj_id> mids2; mids2.reserve(mids.size()); mids.swap(mids2); for (int i = 0; i < mids2.size(); i++) { EnemyInst* e = (EnemyInst*)gs->get_instance(mids2[i]); if (e == NULL) continue; EnemyBehaviour& eb = e->behaviour(); eb.step(); //Add live instances back to monster id list mids.push_back(mids2[i]); int closest_player_index = find_player_to_target(gs, e); if (eb.current_action == EnemyBehaviour::INACTIVE && e->cooldowns().is_hurting()) { eb.current_action = EnemyBehaviour::CHASING_PLAYER; } if (closest_player_index == -1 && eb.current_action == EnemyBehaviour::CHASING_PLAYER) { eb.current_action = EnemyBehaviour::INACTIVE; e->target() = NONE; } if (eb.current_action == EnemyBehaviour::CHASING_PLAYER) eois.push_back( EnemyOfInterest(e, closest_player_index, inst_distance(e, players[closest_player_index]))); else if (eb.current_action == EnemyBehaviour::INACTIVE) monster_wandering(gs, e); else //if (eb.current_action == EnemyBehaviour::FOLLOWING_PATH) monster_follow_path(gs, e); } set_monster_headings(gs, eois); //Update player positions for collision avoidance simulator for (int i = 0; i < players.size(); i++) { PlayerInst* p = players[i]; coll_avoid.set_position(p->collision_simulation_id(), p->x, p->y); } for (int i = 0; i < mids.size(); i++) { EnemyInst* e = (EnemyInst*)gs->get_instance(mids[i]); lua_State* L = gs->luastate(); lua_gameinst_callback(L, e->etype().step_event.get(L), e); update_velocity(gs, e); simul_id simid = e->collision_simulation_id(); coll_avoid.set_position(simid, e->rx, e->ry); coll_avoid.set_preferred_velocity(simid, e->vx, e->vy); } coll_avoid.step(); for (int i = 0; i < mids.size(); i++) { EnemyInst* e = (EnemyInst*)gs->get_instance(mids[i]); update_position(gs, e); } perf_timer_end(FUNCNAME); }