void draw_town_boat(location center) { location where_draw; rectangle source_rect; short i; sf::Texture& vehicle_gworld = *ResMgr::get<ImageRsrc>("vehicle"); for(i = 0; i < univ.party.boats.size(); i++) if((univ.party.boats[i].which_town == univ.town.num) && ((point_onscreen(center, univ.party.boats[i].loc)) && (can_see_light(center, univ.party.boats[i].loc,sight_obscurity) < 5) && (univ.party.in_boat != i) && (pt_in_light(center,univ.party.boats[i].loc)))) { where_draw.x = univ.party.boats[i].loc.x - center.x + 4; where_draw.y = univ.party.boats[i].loc.y - center.y + 4; Draw_Some_Item(vehicle_gworld, calc_rect(1,0), terrain_screen_gworld, where_draw, 1, 0); } for(i = 0; i < univ.party.horses.size(); i++) if((univ.party.horses[i].which_town == univ.town.num) && ((point_onscreen(center, univ.party.horses[i].loc)) && (can_see_light(center, univ.party.horses[i].loc,sight_obscurity) < 5) && (univ.party.in_horse != i) && (pt_in_light(center,univ.party.horses[i].loc)))) { where_draw.x = univ.party.horses[i].loc.x - center.x + 4; where_draw.y = univ.party.horses[i].loc.y - center.y + 4; Draw_Some_Item(vehicle_gworld, calc_rect(1,1), terrain_screen_gworld, where_draw, 1, 0); } }
// Returns 6 if can't see, O.W. returns the # of a PC that can see short party_can_see(location where) { short i; if(is_out()) { if((point_onscreen(univ.party.p_loc,where)) && (can_see_light(univ.party.p_loc,where,sight_obscurity) < 5)) return 1; else return 6; } if(fog_lifted) return point_onscreen(univ.town.p_loc,where) ? 1 : 6; if(is_town()) { if( ((point_onscreen(univ.town.p_loc,where)) || (overall_mode == MODE_LOOK_TOWN)) && (pt_in_light(univ.town.p_loc,where) ) && (can_see_light(univ.town.p_loc,where,sight_obscurity) < 5)) return 1; else return 6; } // Now for combat checks. Doing separately for efficiency. Check first for light. If // dark, give up. if((which_combat_type != 0) && !combat_pt_in_light(where)) return 6; for(i = 0; i < 6; i++) if(univ.party[i].main_status == eMainStatus::ALIVE) { if(can_see_light(univ.party[i].combat_pos,where,sight_obscurity) < 5) return i; } return 6; }
bool combat_move_monster(short which,location destination) { if (monst_can_be_there(destination,which) == false) return false; else if (monst_check_special_terrain(destination,2,which) == false) return false; else { univ.town.monst[which].direction = set_direction(univ.town.monst[which].cur_loc, destination); univ.town.monst[which].cur_loc = destination; monst_inflict_fields(which); if (point_onscreen(destination,center) == true) { if (is_combat()) move_sound(combat_terrain[destination.x][destination.y], (short) univ.town.monst[which].ap); else move_sound(univ.town->terrain(destination.x,destination.y), (short) univ.town.monst[which].ap); } return true; } return false; }
void draw_fields(location where){ if(!point_onscreen(center,where)) return; if(party_can_see(where) >= 6) return; location where_draw(4 + where.x - center.x, 4 + where.y - center.y); sf::Texture& fields_gworld = *ResMgr::get<ImageRsrc>("fields"); if(is_out()){ if(univ.out.is_spot(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(4,0),terrain_screen_gworld,where_draw,1,0); return; } if(univ.town.is_force_wall(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(0,1),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_fire_wall(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(1,1),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_antimagic(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(2,1),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_scloud(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(3,1),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_ice_wall(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(4,1),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_blade_wall(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(5,1),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_sleep_cloud(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(6,1),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_block(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(3,0),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_spot(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(4,0),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_web(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(5,0),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_crate(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(6,0),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_barrel(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(7,0),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_fire_barr(where.x,where.y) || univ.town.is_force_barr(where.x,where.y)) Draw_Some_Item(*ResMgr::get<ImageRsrc>("teranim"),calc_rect(8+(anim_ticks%4),4),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_quickfire(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(7,1),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_sm_blood(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(0,3),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_med_blood(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(1,3),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_lg_blood(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(2,3),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_sm_slime(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(3,3),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_lg_slime(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(4,3),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_ash(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(5,3),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_bones(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(6,3),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_rubble(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(7,3),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_force_cage(where.x,where.y)) { Draw_Some_Item(fields_gworld,calc_rect(1,0),terrain_screen_gworld,where_draw,1,0); forcecage_locs.push_back(where_draw); } }
void create_wand_monst() { short r1,r2,r3,i = 0,num_tries = 0; location p_loc; r1 = get_ran(1,0,3); if (overall_mode == MODE_OUTDOORS) if (!univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].wandering[r1].isNull()) { r2 = get_ran(1,0,3); while ((point_onscreen(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].wandering_locs[r2], global_to_local(univ.party.p_loc))) && (num_tries++ < 100)) r2 = get_ran(1,0,3); if (!is_blocked(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].wandering_locs[r2])) place_outd_wand_monst(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].wandering_locs[r2], univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].wandering[r1],0); } else // won't place wandering is more than 50 monsters if ((!univ.town->wandering[r1].isNull()) && (univ.town.countMonsters() <= 50) && (univ.party.m_killed[univ.town.num] < univ.town->max_num_monst)) { r2 = get_ran(1,0,3); while (point_onscreen(univ.town->wandering_locs[r2],univ.town.p_loc) && !loc_off_act_area(univ.town->wandering_locs[r2]) && (num_tries++ < 100)) r2 = get_ran(1,0,3); for (i = 0; i < 4; i++) { if (univ.town->wandering[r1].monst[i] != 0) { // place a monster p_loc = univ.town->wandering_locs[r2]; p_loc.x += get_ran(1,0,4) - 2; p_loc.y += get_ran(1,0,4) - 2; if (!is_blocked(p_loc)) place_monster(univ.town->wandering[r1].monst[i],p_loc); } p_loc = univ.town->wandering_locs[r2]; p_loc.x += get_ran(1,0,4) - 2; p_loc.y += get_ran(1,0,4) - 2; r3 = get_ran(1,0,3); if ((r3 >= 2) && (!is_blocked(p_loc))) // place extra monsters? place_monster(univ.town->wandering[r1].monst[3],p_loc); } } }
void draw_items(location where){ if(!point_onscreen(center,where)) return; location where_draw(4 + where.x - center.x, 4 + where.y - center.y); rectangle from_rect, to_rect; if(supressing_some_spaces && (where != ok_space[0]) && (where != ok_space[1]) && (where != ok_space[2]) && (where != ok_space[3])) return; for(int i = 0; i < univ.town.items.size(); i++) { if(univ.town.items[i].variety != eItemType::NO_ITEM && univ.town.items[i].item_loc == where) { if(univ.town.items[i].contained) continue; if(party_can_see(where) >= 6) continue; sf::Texture* src_gw; to_rect = coord_to_rect(where_draw.x,where_draw.y); if(univ.town.items[i].graphic_num >= 10000){ graf_pos_ref(src_gw, from_rect) = spec_scen_g.find_graphic(univ.town.items[i].graphic_num - 10000, true); }else if(univ.town.items[i].graphic_num >= 1000){ graf_pos_ref(src_gw, from_rect) = spec_scen_g.find_graphic(univ.town.items[i].graphic_num - 1000); }else{ graf_pos_ref(src_gw, from_rect) = calc_item_rect(univ.town.items[i].graphic_num, to_rect); } rect_draw_some_item(*src_gw, from_rect, terrain_screen_gworld, to_rect, sf::BlendAlpha); } } }
bool monst_check_special_terrain(location where_check,short mode,short which_monst) //mode; // 1 - town 2 - combat { ter_num_t ter = 0; short r1,i,guts = 0; bool can_enter = true,mage = false; location from_loc,to_loc; bool do_look = false; // If becomes true, terrain changed, so need to update what party sees cCreature *which_m; short ter_abil; unsigned short ter_flag; from_loc = univ.town.monst[which_monst].cur_loc; switch (mode) { case 1: ter = univ.town->terrain(where_check.x,where_check.y); break; case 2: ter = combat_terrain[where_check.x][where_check.y]; break; } //// which_m = &univ.town.monst[which_monst]; ter_abil = scenario.ter_types[ter].special; ter_flag = scenario.ter_types[ter].flag3.u; if ((mode > 0) && (ter_abil == TER_SPEC_CONVEYOR)) { if ( ((ter_flag == DIR_N) && (where_check.y > from_loc.y)) || ((ter_flag == DIR_E) && (where_check.x < from_loc.x)) || ((ter_flag == DIR_S) && (where_check.y < from_loc.y)) || ((ter_flag == DIR_W) && (where_check.x > from_loc.x)) ) { return false; } } // begin determining guts, which determines how enthused the monst is about entering // nasty barriers if ((which_m->mu > 0) || (which_m->cl > 0)) mage = true; if (which_m->spec_skill == 13) guts = 20; else guts = get_ran(1,1,(which_m->level / 2)); guts += which_m->health / 20; if (mage == true) guts = guts / 2; if (which_m->attitude == 0) guts = guts / 2; if ((univ.town.is_antimagic(where_check.x,where_check.y)) && (mage == true)) return false; if ((univ.town.is_fire_wall(where_check.x,where_check.y)) && (which_m->spec_skill != 22)) { if (guts < 3) return false; } if (univ.town.is_force_wall(where_check.x,where_check.y)) { if (guts < 4) return false; } if ((univ.town.is_ice_wall(where_check.x,where_check.y)) && (which_m->spec_skill != 23)) { if (guts < 5) return false; } if (univ.town.is_sleep_cloud(where_check.x,where_check.y)) { if (guts < 8) return false; } if (univ.town.is_blade_wall(where_check.x,where_check.y)) { if (guts < 8) return false; } if (univ.town.is_quickfire(where_check.x,where_check.y)) { if (guts < 8) return false; } if (univ.town.is_scloud(where_check.x,where_check.y)) { if (guts < 4) return false; } if ((univ.town.is_web(where_check.x,where_check.y)) && (which_m->m_type != 12)) { if (guts < 3) return false; } if (univ.town.is_fire_barr(where_check.x,where_check.y)) { if ((which_m->attitude % 2 == 1) && (get_ran(1,1,100) < (which_m->mu * 10 + which_m->cl * 4))) { play_sound(60); add_string_to_buf("Monster breaks barrier."); univ.town.set_fire_barr(where_check.x,where_check.y,false); } else { if (guts < 6) return false; r1 = get_ran(1,0,10); if ((r1 < 8) || (monster_placid(which_monst))) can_enter = false; } } if (univ.town.is_force_barr(where_check.x,where_check.y)) { /// Not in big towns if ((which_m->attitude % 2 == 1) && (get_ran(1,1,100) < (which_m->mu * 10 + which_m->cl * 4)) && (!univ.town->strong_barriers)) { play_sound(60); add_string_to_buf("Monster breaks barrier."); univ.town.set_force_barr(where_check.x,where_check.y,false); } else can_enter = false; } if (univ.town.is_crate(where_check.x,where_check.y)) { if (monster_placid(which_monst)) can_enter = false; else { to_loc = push_loc(from_loc,where_check); univ.town.set_crate((short) where_check.x,(short) where_check.y,false); if (to_loc.x > 0) univ.town.set_crate((short) to_loc.x,(short) to_loc.y, true); for (i = 0; i < NUM_TOWN_ITEMS; i++) if ((univ.town.items[i].variety > 0) && (univ.town.items[i].item_loc == where_check) && (univ.town.items[i].contained)) univ.town.items[i].item_loc = to_loc; } } if (univ.town.is_barrel(where_check.x,where_check.y)) { if (monster_placid(which_monst)) can_enter = false; else { to_loc = push_loc(from_loc,where_check); univ.town.set_barrel((short) where_check.x,(short) where_check.y,false); if (to_loc.x > 0) univ.town.set_barrel((short) to_loc.x,(short) to_loc.y,true); for (i = 0; i < NUM_TOWN_ITEMS; i++) if ((univ.town.items[i].variety > 0) && (univ.town.items[i].item_loc == where_check) && (univ.town.items[i].contained)) univ.town.items[i].item_loc = to_loc; } } if (monster_placid(which_monst) && // monsters don't hop into bed when things are calm (scenario.ter_types[ter].special == TER_SPEC_BED)) can_enter = false; if (mode == 1 && univ.town.is_spot(where_check.x, where_check.y)) can_enter = false; if (ter == 90) { if ((is_combat()) && (which_combat_type == 0)) { univ.town.monst[which_monst].active = 0; add_string_to_buf("Monster escaped! "); } return false; } switch (ter_abil) { // changing ter case TER_SPEC_CHANGE_WHEN_STEP_ON: can_enter = false; if (!(monster_placid(which_monst))) { univ.town->terrain(where_check.x,where_check.y) = scenario.ter_types[ter].flag1.u; combat_terrain[where_check.x][where_check.y] = scenario.ter_types[ter].flag1.u; do_look = true; if (point_onscreen(center,where_check)) play_sound(scenario.ter_types[ter].flag2.u); } break; case TER_SPEC_BLOCKED_TO_MONSTERS: case TER_SPEC_TOWN_ENTRANCE: case TER_SPEC_WATERFALL: can_enter = false; break; case TER_SPEC_DAMAGING: // TODO: Update this to check other cases if (ter_flag == DAMAGE_FIRE && univ.town.monst[which_monst].immunities & 8) return true; else return false; break; } // Action may change terrain, so update what's been seen if (do_look == true) { if (is_town()) update_explored(univ.town.p_loc); if (is_combat()) for (i = 0; i < 6; i++) if (univ.party[i].main_status == 1) update_explored(pc_pos[i]); } return can_enter; }
//short mode; // 0 - put pcs in gworld 1 - only rectangle around active pc void draw_pcs(location center,short mode) { rectangle source_rect,active_pc_rect; location where_draw; if(!univ.party.is_alive()) return; if(!can_draw_pcs) return; // Draw current pc on top int pcs[6] = {0,1,2,3,4,5}; if(current_pc < 6) std::swap(pcs[5], pcs[current_pc]); for(int j = 0; j < 6; j++) { int i = pcs[j]; if(univ.party[i].main_status == eMainStatus::ALIVE) if(point_onscreen(center, univ.party[i].combat_pos) && (cartoon_happening || party_can_see(univ.party[i].combat_pos) < 6)){ where_draw.x = univ.party[i].combat_pos.x - center.x + 4; where_draw.y = univ.party[i].combat_pos.y - center.y + 4; sf::Texture* from_gw; pic_num_t pic = univ.party[i].which_graphic; if(pic >= 1000) { bool isParty = pic >= 10000; pic_num_t need_pic = pic % 1000; if(univ.party[i].direction >= 4) need_pic++; if(combat_posing_monster == i) need_pic += 2; graf_pos_ref(from_gw, source_rect) = spec_scen_g.find_graphic(need_pic, isParty); } else if(pic >= 100) { // Note that we assume it's a 1x1 graphic. // PCs can't be larger than that, but we leave it to the scenario designer to avoid assigning larger graphics. pic_num_t need_pic = pic - 100; int mode = 0; if(univ.party[current_pc].direction >= 4) mode++; if(combat_posing_monster == i) mode += 10; source_rect = get_monster_template_rect(need_pic, mode, 0); int which_sheet = m_pic_index[need_pic].i / 20; from_gw = ResMgr::get<ImageRsrc>("monst" + std::to_string(1 + which_sheet)).get(); } else { source_rect = calc_rect(2 * (pic / 8), pic % 8); if(univ.party[i].direction >= 4) source_rect.offset(28,0); if(combat_posing_monster == i) source_rect.offset(0,288); from_gw = ResMgr::get<ImageRsrc>("pcs").get(); } if(mode == 0) { Draw_Some_Item(*from_gw, source_rect, terrain_screen_gworld, where_draw, 1, 0); } if((current_pc == i) && (mode == 1) && !monsters_going) { active_pc_rect.top = 18 + where_draw.y * 36; active_pc_rect.left = 18 + where_draw.x * 28; active_pc_rect.bottom = 54 + where_draw.y * 36; active_pc_rect.right = 46 + where_draw.x * 28; active_pc_rect.offset(ul); frame_roundrect(mainPtr, active_pc_rect, 8, sf::Color::Magenta); } } } }
void draw_monsters() { short i,j = 0,k; short width,height; rectangle source_rect,to_rect; location where_draw,store_loc; ter_num_t ter; rectangle monst_rects[4][4] = { {{0,0,36,28}}, {{0,7,18,21},{18,7,36,21}}, {{9,0,27,14},{9,14,27,28}}, {{0,0,18,14},{0,14,18,28},{18,0,36,14},{18,14,36,28}} }; if(is_out()) for(i = 0; i < 10; i++) if(univ.party.out_c[i].exists) { if((point_onscreen(univ.party.p_loc, univ.party.out_c[i].m_loc)) && (can_see_light(univ.party.p_loc, univ.party.out_c[i].m_loc,sight_obscurity) < 5)) { where_draw.x = univ.party.out_c[i].m_loc.x - univ.party.p_loc.x + 4; where_draw.y = univ.party.out_c[i].m_loc.y - univ.party.p_loc.y + 4; for(j = 0; univ.party.out_c[i].what_monst.monst[j] == 0 && j < 7; j++); short picture_wanted; if(j == 7) univ.party.out_c[i].exists = false; // begin watch out else { picture_wanted = get_monst_picnum(univ.party.out_c[i].what_monst.monst[j]); } // end watch out if(univ.party.out_c[i].exists) { get_monst_dims(univ.party.out_c[i].what_monst.monst[j],&width,&height); if(picture_wanted >= 1000) { for(k = 0; k < width * height; k++) { sf::Texture* src_gw; graf_pos_ref(src_gw, source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000 + ((univ.party.out_c[i].direction < 4) ? 0 : (width * height)) + k); to_rect = monst_rects[(width - 1) * 2 + height - 1][k]; to_rect.offset(13 + 28 * where_draw.x,13 + 36 * where_draw.y); rect_draw_some_item(*src_gw, source_rect, terrain_screen_gworld,to_rect, sf::BlendAlpha); } } if(picture_wanted < 1000) { for(k = 0; k < width * height; k++) { source_rect = get_monster_template_rect(picture_wanted,(univ.party.out_c[i].direction < 4) ? 0 : 1,k); to_rect = monst_rects[(width - 1) * 2 + height - 1][k]; to_rect.offset(13 + 28 * where_draw.x,13 + 36 * where_draw.y); int which_sheet = m_pic_index[picture_wanted].i / 20; sf::Texture& monst_gworld = *ResMgr::get<ImageRsrc>("monst" + std::to_string(1 + which_sheet)); rect_draw_some_item(monst_gworld, source_rect, terrain_screen_gworld,to_rect, sf::BlendAlpha); } } } } } if(is_town() || is_combat()) { for(i = 0; i < univ.town.monst.size(); i++) if(univ.town.monst[i].active != 0 && !univ.town.monst[i].invisible && univ.town.monst[i].status[eStatus::INVISIBLE] <= 0) if(point_onscreen(center,univ.town.monst[i].cur_loc) && party_can_see_monst(i)) { where_draw.x = univ.town.monst[i].cur_loc.x - center.x + 4; where_draw.y = univ.town.monst[i].cur_loc.y - center.y + 4; get_monst_dims(univ.town.monst[i].number,&width,&height); for(k = 0; k < width * height; k++) { store_loc = where_draw; store_loc.x += k % width; store_loc.y += k / width; ter = univ.town->terrain(univ.town.monst[i].cur_loc.x,univ.town.monst[i].cur_loc.y); // in bed? if(store_loc.x >= 0 && store_loc.x < 9 && store_loc.y >= 0 && store_loc.y < 9 && (univ.scenario.ter_types[ter].special == eTerSpec::BED) && isHumanoid(univ.town.monst[i].m_type) && (univ.town.monst[i].active == 1 || univ.town.monst[i].target == 6) && width == 1 && height == 1) draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1); else if(univ.town.monst[i].picture_num >= 1000) { bool isParty = univ.town.monst[i].picture_num >= 10000; sf::Texture* src_gw; pic_num_t need_pic = (univ.town.monst[i].picture_num % 1000) + k; if(univ.town.monst[i].direction >= 4) need_pic += width * height; if(combat_posing_monster == i + 100) need_pic += (2 * width * height); graf_pos_ref(src_gw, source_rect) = spec_scen_g.find_graphic(need_pic, isParty); Draw_Some_Item(*src_gw, source_rect, terrain_screen_gworld, store_loc, 1, 0); } else { pic_num_t this_monst = univ.town.monst[i].picture_num; int pic_mode = (univ.town.monst[i].direction) < 4 ? 0 : 1; pic_mode += (combat_posing_monster == i + 100) ? 10 : 0; source_rect = get_monster_template_rect(this_monst, pic_mode, k); int which_sheet = m_pic_index[this_monst].i / 20; sf::Texture& monst_gworld = *ResMgr::get<ImageRsrc>("monst" + std::to_string(1 + which_sheet)); Draw_Some_Item(monst_gworld, source_rect, terrain_screen_gworld, store_loc, 1, 0); } } } } }