void GameStatePlay::checkCutscene() { if (!mapr->cutscene) return; GameStateCutscene *cutscene = new GameStateCutscene(NULL); if (!cutscene->load(mapr->cutscene_file)) { delete cutscene; mapr->cutscene = false; return; } // handle respawn point and set game play game_slot cutscene->game_slot = save_load->getGameSlot(); if (mapr->teleportation) { if (mapr->teleport_mapname != "") mapr->respawn_map = mapr->teleport_mapname; mapr->respawn_point = mapr->teleport_destination; } else { mapr->respawn_point = FPointToPoint(pc->stats.pos); } if (SAVE_ONLOAD) save_load->saveGame(); delete requestedGameState; requestedGameState = cutscene; }
void GameStatePlay::checkSaveEvent() { if (mapr->save_game) { mapr->respawn_point = FPointToPoint(pc->stats.pos); save_load->saveGame(); mapr->save_game = false; } }
void GameStateLoad::render() { Rect src; Rect dest; // portrait if (selected_slot >= 0 && portrait != NULL && portrait_border != NULL) { render_device->render(portrait); dest.x = int(portrait->getDest().x); dest.y = int(portrait->getDest().y); portrait_border->setDest(dest); render_device->render(portrait_border); } Point label; std::stringstream ss; if (loading_requested || loading || loaded) { label.x = loading_pos.x + (VIEW_W - FRAME_W)/2; label.y = loading_pos.y + (VIEW_H - FRAME_H)/2; if ( loaded) { label_loading->set(msg->get("Entering game world...")); } else { label_loading->set(msg->get("Loading saved game...")); } label_loading->set(label.x, label.y, loading_pos.justify, loading_pos.valign, label_loading->get(), color_normal, loading_pos.font_style); label_loading->render(); } Color color_permadeath_enabled = font->getColor("hardcore_color_name"); // display text for (int slot=0; slot<visible_slots; slot++) { int off_slot = slot+scroll_offset; // slot background if (background) { src.x = 0; src.y = (off_slot % 4) * gameslot_pos.h; dest.w = dest.h = 0; src.w = gameslot_pos.w; src.h = gameslot_pos.h; dest.x = slot_pos[slot].x; dest.y = slot_pos[slot].y; background->setClip(src); background->setDest(dest); render_device->render(background); } Point slot_dest = FPointToPoint(background->getDest()); Color color_used = game_slots[off_slot]->stats.permadeath ? color_permadeath_enabled : color_normal; // name label.x = slot_pos[slot].x + name_pos.x; label.y = slot_pos[slot].y + name_pos.y; game_slots[off_slot]->label_name.set(label.x, label.y, name_pos.justify, name_pos.valign, game_slots[off_slot]->stats.name, color_used, name_pos.font_style); if (text_trim_boundary > 0 && game_slots[off_slot]->label_name.bounds.x + game_slots[off_slot]->label_name.bounds.w >= text_trim_boundary + slot_dest.x) game_slots[off_slot]->label_name.setMaxWidth(text_trim_boundary - (game_slots[off_slot]->label_name.bounds.x - slot_dest.x)); game_slots[off_slot]->label_name.render(); // level ss.str(""); label.x = slot_pos[slot].x + level_pos.x; label.y = slot_pos[slot].y + level_pos.y; ss << msg->get("Level %d", game_slots[off_slot]->stats.level); if (game_slots[off_slot]->stats.permadeath) ss << ", " + msg->get("Permadeath"); game_slots[off_slot]->label_level.set(label.x, label.y, level_pos.justify, level_pos.valign, ss.str(), color_normal, level_pos.font_style); if (text_trim_boundary > 0 && game_slots[off_slot]->label_level.bounds.x + game_slots[off_slot]->label_level.bounds.w >= text_trim_boundary + slot_dest.x) game_slots[off_slot]->label_level.setMaxWidth(text_trim_boundary - (game_slots[off_slot]->label_level.bounds.x - slot_dest.x)); game_slots[off_slot]->label_level.render(); // class label.x = slot_pos[slot].x + class_pos.x; label.y = slot_pos[slot].y + class_pos.y; game_slots[off_slot]->label_class.set(label.x, label.y, class_pos.justify, class_pos.valign, game_slots[off_slot]->stats.getLongClass(), color_normal, class_pos.font_style); if (text_trim_boundary > 0 && game_slots[off_slot]->label_class.bounds.x + game_slots[off_slot]->label_class.bounds.w >= text_trim_boundary + slot_dest.x) game_slots[off_slot]->label_class.setMaxWidth(text_trim_boundary - (game_slots[off_slot]->label_class.bounds.x - slot_dest.x)); game_slots[off_slot]->label_class.render(); // map label.x = slot_pos[slot].x + map_pos.x; label.y = slot_pos[slot].y + map_pos.y; game_slots[off_slot]->label_map.set(label.x, label.y, map_pos.justify, map_pos.valign, game_slots[off_slot]->current_map, color_normal, map_pos.font_style); if (text_trim_boundary > 0 && game_slots[off_slot]->label_map.bounds.x + game_slots[off_slot]->label_map.bounds.w >= text_trim_boundary + slot_dest.x) game_slots[off_slot]->label_map.setMaxWidth(text_trim_boundary - (game_slots[off_slot]->label_map.bounds.x - slot_dest.x)); game_slots[off_slot]->label_map.render(); // render character preview dest.x = slot_pos[slot].x + sprites_pos.x; dest.y = slot_pos[slot].y + sprites_pos.y; game_slots[off_slot]->preview.setPos(Point(dest.x, dest.y)); game_slots[off_slot]->preview.render(); // slot number std::stringstream off_slot_str; off_slot_str << "#" << off_slot + 1; label.x = slot_pos[slot].x + slot_number_pos.x; label.y = slot_pos[slot].y + slot_number_pos.y; game_slots[off_slot]->label_slot_number.set(label.x, label.y, slot_number_pos.justify, slot_number_pos.valign, off_slot_str.str(), color_normal, slot_number_pos.font_style); if (text_trim_boundary > 0 && game_slots[off_slot]->label_slot_number.bounds.x + game_slots[off_slot]->label_slot_number.bounds.w >= text_trim_boundary + slot_dest.x) game_slots[off_slot]->label_slot_number.setMaxWidth(text_trim_boundary - (game_slots[off_slot]->label_slot_number.bounds.x - slot_dest.x)); game_slots[off_slot]->label_slot_number.render(); } // display selection if (selected_slot >= scroll_offset && selected_slot < visible_slots+scroll_offset && selection != NULL) { selection->setDest(slot_pos[selected_slot-scroll_offset]); render_device->render(selection); } if (has_scroll_bar) scrollbar->render(); // display warnings if (confirm->visible) confirm->render(); // display buttons button_exit->render(); button_new->render(); button_load->render(); button_delete->render(); }
void LootManager::checkLoot(std::vector<Event_Component> &loot_table, FPoint *pos, std::vector<ItemStack> *itemstack_vec) { if (hero == NULL) { logError("LootManager: checkLoot() failed, no hero."); return; } FPoint p; Event_Component *ec; ItemStack new_loot; std::vector<Event_Component*> possible_ids; int chance = rand() % 100; // first drop any 'fixed' (0% chance) items for (size_t i = loot_table.size(); i > 0; i--) { ec = &loot_table[i-1]; if (ec->z == 0) { Point src; if (pos) { src = FPointToPoint(*pos); } else { src.x = ec->x; src.y = ec->y; } p.x = static_cast<float>(src.x) + 0.5f; p.y = static_cast<float>(src.y) + 0.5f; if (!mapr->collider.is_valid_position(p.x, p.y, MOVEMENT_NORMAL, false)) { p = mapr->collider.get_random_neighbor(src, drop_radius); if (!mapr->collider.is_valid_position(p.x, p.y, MOVEMENT_NORMAL, false)) { p = hero->pos; } else { if (src.x == static_cast<int>(p.x) && src.y == static_cast<int>(p.y)) p = hero->pos; mapr->collider.block(p.x, p.y, false); tiles_to_unblock.push_back(FPointToPoint(p)); } } new_loot.quantity = randBetween(ec->a,ec->b); // an item id of 0 means we should drop currency instead if (ec->c == 0 || ec->c == CURRENCY_ID) { new_loot.item = CURRENCY_ID; new_loot.quantity = new_loot.quantity * (100 + hero->get(STAT_CURRENCY_FIND)) / 100; } else { new_loot.item = ec->c; } if (itemstack_vec) itemstack_vec->push_back(new_loot); else addLoot(new_loot, p); loot_table.erase(loot_table.begin()+i-1); } } // now pick up to 1 random item to drop int threshold = hero->get(STAT_ITEM_FIND) + 100; for (unsigned i = 0; i < loot_table.size(); i++) { ec = &loot_table[i]; int real_chance = ec->z; if (ec->c != 0 && ec->c != CURRENCY_ID) { real_chance = static_cast<int>(static_cast<float>(ec->z) * static_cast<float>(hero->get(STAT_ITEM_FIND) + 100) / 100.f); } if (real_chance >= chance) { if (real_chance <= threshold) { if (real_chance != threshold) { possible_ids.clear(); } threshold = real_chance; } if (chance <= threshold) { possible_ids.push_back(ec); } } } if (!possible_ids.empty()) { // if there was more than one item with the same chance, randomly pick one of them size_t chosen_loot = static_cast<size_t>(rand()) % possible_ids.size(); ec = possible_ids[chosen_loot]; Point src; if (pos) { src = FPointToPoint(*pos); } else { src.x = ec->x; src.y = ec->y; } p.x = static_cast<float>(src.x) + 0.5f; p.y = static_cast<float>(src.y) + 0.5f; if (!mapr->collider.is_valid_position(p.x, p.y, MOVEMENT_NORMAL, false)) { p = mapr->collider.get_random_neighbor(src, drop_radius); if (!mapr->collider.is_valid_position(p.x, p.y, MOVEMENT_NORMAL, false)) { p = hero->pos; } else { if (src.x == static_cast<int>(p.x) && src.y == static_cast<int>(p.y)) p = hero->pos; mapr->collider.block(p.x, p.y, false); tiles_to_unblock.push_back(FPointToPoint(p)); } } new_loot.quantity = randBetween(ec->a,ec->b); // an item id of 0 means we should drop currency instead if (ec->c == 0 || ec->c == CURRENCY_ID) { new_loot.item = CURRENCY_ID; new_loot.quantity = new_loot.quantity * (100 + hero->get(STAT_CURRENCY_FIND)) / 100; } else { new_loot.item = ec->c; } if (itemstack_vec) itemstack_vec->push_back(new_loot); else addLoot(new_loot, p); } }
void GameStatePlay::checkTeleport() { bool on_load_teleport = false; // both map events and player powers can cause teleportation if (mapr->teleportation || pc->stats.teleportation) { mapr->collider.unblock(pc->stats.pos.x, pc->stats.pos.y); if (mapr->teleportation) { mapr->cam.x = pc->stats.pos.x = mapr->teleport_destination.x; mapr->cam.y = pc->stats.pos.y = mapr->teleport_destination.y; } else { mapr->cam.x = pc->stats.pos.x = pc->stats.teleport_destination.x; mapr->cam.y = pc->stats.pos.y = pc->stats.teleport_destination.y; } // if we're not changing map, move allies to a the player's new position // when changing maps, enemies->handleNewMap() does something similar to this if (mapr->teleport_mapname.empty()) { FPoint spawn_pos = mapr->collider.get_random_neighbor(FPointToPoint(pc->stats.pos), 1, false); for (unsigned int i=0; i < enemies->enemies.size(); i++) { if(enemies->enemies[i]->stats.hero_ally && enemies->enemies[i]->stats.alive) { mapr->collider.unblock(enemies->enemies[i]->stats.pos.x, enemies->enemies[i]->stats.pos.y); enemies->enemies[i]->stats.pos = spawn_pos; mapr->collider.block(enemies->enemies[i]->stats.pos.x, enemies->enemies[i]->stats.pos.y, true); } } } // process intermap teleport if (mapr->teleportation && !mapr->teleport_mapname.empty()) { std::string teleport_mapname = mapr->teleport_mapname; mapr->teleport_mapname = ""; inpt->lock_all = (teleport_mapname == "maps/spawn.txt"); mapr->executeOnMapExitEvents(); showLoading(); mapr->load(teleport_mapname); setLoadingFrame(); enemies->handleNewMap(); hazards->handleNewMap(); loot->handleNewMap(); powers->handleNewMap(&mapr->collider); menu->enemy->handleNewMap(); npcs->handleNewMap(); resetNPC(); menu->stash->visible = false; menu->mini->prerender(&mapr->collider, mapr->w, mapr->h); npc_id = nearest_npc = -1; // use the default hero spawn position for this map if (mapr->teleport_destination.x == -1 && mapr->teleport_destination.y == -1) { mapr->cam.x = pc->stats.pos.x = mapr->hero_pos.x; mapr->cam.y = pc->stats.pos.y = mapr->hero_pos.y; } // store this as the new respawn point (provided the tile is open) if (mapr->collider.is_valid_position(pc->stats.pos.x, pc->stats.pos.y, MOVEMENT_NORMAL, true)) { mapr->respawn_map = teleport_mapname; mapr->respawn_point = pc->stats.pos; } else { logError("GameStatePlay: Spawn position (%d, %d) is blocked.", static_cast<int>(pc->stats.pos.x), static_cast<int>(pc->stats.pos.y)); } // return to title (permadeath) OR auto-save if (pc->stats.permadeath && pc->stats.corpse) { removeSaveDir(save_load->getGameSlot()); snd->stopMusic(); delete requestedGameState; requestedGameState = new GameStateTitle(); } else if (SAVE_ONLOAD) { save_load->saveGame(); } // switch off teleport flag so we can check if an on_load event has teleportation mapr->teleportation = false; mapr->executeOnLoadEvents(); if (mapr->teleportation) on_load_teleport = true; } mapr->collider.block(pc->stats.pos.x, pc->stats.pos.y, false); pc->stats.teleportation = false; } if (!on_load_teleport && mapr->teleport_mapname.empty()) mapr->teleportation = false; }