short good_attack_room(struct Thing *thing) { // Debug code to find incorrect states if (!is_hero_thing(thing)) { ERRORLOG("Non hero %s index %d owner %d - reset",thing_model_name(thing),(int)thing->index,(int)thing->owner); set_start_state(thing); return 0; } //return _DK_good_attack_room(thing); MapSlabCoord base_slb_x,base_slb_y; base_slb_x = subtile_slab_fast(thing->mappos.x.stl.num); base_slb_y = subtile_slab_fast(thing->mappos.y.stl.num); struct Room *room; room = slab_room_get(base_slb_x, base_slb_y); // If the current tile can be destroyed if (room_exists(room) && (room->owner != thing->owner) && !room_cannot_vandalise(room->kind)) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(thing); if (cctrl->instance_id == CrInst_NULL) { set_creature_instance(thing, CrInst_ATTACK_ROOM_SLAB, 1, 0, 0); MapCoord ev_coord_x,ev_coord_y; ev_coord_x = subtile_coord_center(room->central_stl_x); ev_coord_y = subtile_coord_center(room->central_stl_y); event_create_event_or_update_nearby_existing_event(ev_coord_x, ev_coord_y, EvKind_RoomUnderAttack, room->owner, 0); if (is_my_player_number(room->owner)) output_message(SMsg_EnemyDestroyRooms, MESSAGE_DELAY_FIGHT, true); } return 1; } // Otherwise, search around for a tile to destroy long m,n; m = ACTION_RANDOM(SMALL_AROUND_SLAB_LENGTH); for (n=0; n < SMALL_AROUND_SLAB_LENGTH; n++) { MapSlabCoord slb_x,slb_y; slb_x = base_slb_x + (long)small_around[m].delta_x; slb_y = base_slb_y + (long)small_around[m].delta_y; room = slab_room_get(slb_x, slb_y); if (room_exists(room) && (room->owner != thing->owner)) { if (setup_person_move_to_position(thing, slb_x, slb_y, NavRtF_Default)) { thing->continue_state = CrSt_GoodAttackRoom1; return 1; } } m = (m+1) % SMALL_AROUND_SLAB_LENGTH; } set_start_state(thing); return 0; }
TbBool remove_workshop_object_from_player(PlayerNumber owner, ThingModel objmodel) { struct Thing *cratetng; struct Room *room; cratetng = get_workshop_box_thing(owner, objmodel); if (thing_is_invalid(cratetng)) { WARNLOG("Crate %s could not be found",object_code_name(objmodel)); return false; } room = get_room_thing_is_on(cratetng); if (room_exists(room)) { remove_workshop_object_from_workshop(room,cratetng); } else { WARNLOG("Crate thing index %d isn't placed existing room; removing anyway",(int)cratetng->index); } create_effect(&cratetng->mappos, imp_spangle_effects[cratetng->owner], cratetng->owner); destroy_object(cratetng); return true; }
short good_arrived_at_attack_room(struct Thing *thing) { struct Room *room; room = get_room_thing_is_on(thing); // If the current tile can be destroyed if (room_exists(room) && (room->owner != thing->owner) && !room_cannot_vandalise(room->kind)) { internal_set_thing_state(thing, CrSt_GoodAttackRoom1); MapCoord ev_coord_x,ev_coord_y; ev_coord_x = subtile_coord_center(room->central_stl_x); ev_coord_y = subtile_coord_center(room->central_stl_y); event_create_event_or_update_nearby_existing_event(ev_coord_x, ev_coord_y, EvKind_RoomUnderAttack, room->owner, 0); if (is_my_player_number(room->owner)) output_message(SMsg_EnemyDestroyRooms, MESSAGE_DELAY_FIGHT, true); return 1; } set_start_state(thing); return 0; }
struct Room *get_opponent_room(struct Computer2 *comp, PlayerNumber plyr_idx) { static const RoomKind opponent_room_kinds[] = {RoK_DUNGHEART, RoK_PRISON, RoK_LIBRARY, RoK_TREASURE}; struct Dungeon *dungeon; struct Room *room; dungeon = get_players_num_dungeon(plyr_idx); if (dungeon_invalid(dungeon) || (slab_conf.room_types_count < 1)) { return INVALID_ROOM; } int i,n; n = opponent_room_kinds[ACTION_RANDOM(sizeof(opponent_room_kinds)/sizeof(opponent_room_kinds[0]))]; for (i=0; i < slab_conf.room_types_count; i++) { room = room_get(dungeon->room_kind[n]); if (room_exists(room)) { return room; } n = (n + 1) % slab_conf.room_types_count; } return INVALID_ROOM; }
void room_manager::read_rooms() { if (!filename_.empty() && file_exists(filename_)) { LOG_LOBBY << "Reading rooms from " << filename_ << "\n"; config cfg; scoped_istream file = istream_file(filename_); if (compress_stored_rooms_) { read_gz(cfg, *file); } else { detect_format_and_read(cfg, *file); } foreach (const config &c, cfg.child_range("room")) { room* r(new room(c)); if (room_exists(r->name())) { ERR_LOBBY << "Duplicate room ignored in stored rooms: " << r->name() << "\n"; delete r; } else { rooms_by_name_.insert(std::make_pair(r->name(), r)); } } }
struct Thing *find_prisoner_for_thing(struct Thing *creatng) { struct CreatureControl *cctrl; struct Thing *thing; unsigned long k; long i; TRACE_THING(creatng); struct Room *room; room = INVALID_ROOM; if (!is_neutral_thing(creatng)) { room = find_nearest_room_for_thing_with_used_capacity(creatng, creatng->owner, RoK_PRISON, NavRtF_Default, 1); } if (room_exists(room)) { i = room->creatures_list; } else { i = 0; } struct Thing *out_creatng; long out_delay; out_creatng = INVALID_THING; out_delay = LONG_MAX; k = 0; while (i != 0) { thing = thing_get(i); TRACE_THING(thing); cctrl = creature_control_get_from_thing(thing); if (!creature_control_exists(cctrl)) { ERRORLOG("Jump to invalid creature %ld detected",i); break; } i = cctrl->next_in_room; // Per creature code long dist, durt; dist = get_2d_box_distance(&creatng->mappos, &thing->mappos); if (out_delay < 0) { // If we have a victim which isn't frozen, accept only other unfrozen creatures if ((dist <= LONG_MAX) && !creature_affected_by_spell(thing, SplK_Freeze)) { out_creatng = thing; out_delay = -1; } } else if (creature_affected_by_spell(thing, SplK_Freeze)) { // If the victim is frozen, select one which will unfreeze sooner durt = get_spell_duration_left_on_thing(thing, SplK_Freeze); if ((durt > 0) && (out_delay > durt)) { out_creatng = thing; out_delay = durt; } } else { // Found first unfrozen victim - change out_delay to mark thet we no longer want frozen ones out_creatng = thing; out_delay = -1; } // Per creature code ends k++; if (k > THINGS_COUNT) { ERRORLOG("Infinite loop detected when sweeping creatures list"); break; } } return out_creatng; }