long room_has_slab_adjacent(const struct Room *room, long slbkind) { long i; unsigned long k; k = 0; i = room->slabs_list; while (i > 0) { // Per room tile code long n; for (n=0; n < AROUND_SLAB_LENGTH; n++) { long slab_num; slab_num = i + around_slab[n]; struct SlabMap *slb; slb = get_slabmap_direct(slab_num); if (!slabmap_block_invalid(slb)) { if (slb->kind == slbkind) { return true; } } } // Per room tile code ends i = get_next_slab_number_in_room(i); k++; if (k > room->slabs_count) { ERRORLOG("Room slabs list length exceeded when sweeping"); break; } } return 0; }
TbBool jailbreak_possible(struct Room *room, long plyr_idx) { unsigned long i; unsigned long k; struct SlabMap *slb; if (room->owner == plyr_idx) { return false; } k = 0; i = room->slabs_list; while (i > 0) { slb = get_slabmap_direct(i); if (slabmap_block_invalid(slb)) { ERRORLOG("Jump to invalid room slab detected"); break; } if (slab_by_players_land(plyr_idx, slb_num_decode_x(i), slb_num_decode_y(i))) return true; i = get_next_slab_number_in_room(i); k++; if (k > map_tiles_x * map_tiles_y) { ERRORLOG("Infinite loop detected when sweeping room slabs"); break; } } return false; }
long instf_tunnel(struct Thing *creatng, long *param) { struct CreatureControl *cctrl; struct SlabMap *slb; SYNCDBG(16,"Starting"); TRACE_THING(creatng); cctrl = creature_control_get_from_thing(creatng); MapSubtlCoord stl_x,stl_y; stl_x = stl_num_decode_x(cctrl->navi.field_15); stl_y = stl_num_decode_y(cctrl->navi.field_15); slb = get_slabmap_for_subtile(stl_x, stl_y); if (slabmap_block_invalid(slb)) { return 0; } thing_play_sample(creatng, 69+UNSYNC_RANDOM(3), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); if (slb->health > 1) { slb->health--; } else { dig_out_block(stl_x, stl_y, creatng->owner); } return 1; }
void do_slab_efficiency_alteration(MapSlabCoord slb_x, MapSlabCoord slb_y) { long n; for (n=0; n < SMALL_AROUND_SLAB_LENGTH; n++) { MapSlabCoord sslb_x, sslb_y; sslb_x = slb_x + small_around[n].delta_x; sslb_y = slb_y + small_around[n].delta_y; struct SlabMap *slb; struct SlabAttr *slbattr; slb = get_slabmap_block(sslb_x, sslb_y); if (slabmap_block_invalid(slb)) { continue; } slbattr = get_slab_attrs(slb); if (slbattr->category == SlbAtCtg_RoomInterior) { struct Room *room; room = slab_room_get(sslb_x, sslb_y); set_room_efficiency(room); set_room_capacity(room, true); } } }
long calculate_effeciency_score_for_room_slab(SlabCodedCoords slab_num, PlayerNumber plyr_idx) { //return _DK_calculate_effeciency_score_for_room_slab(slab_num, plyr_idx); long eff_score; TbBool is_room_inside; is_room_inside = true; eff_score = 0; struct SlabMap *slb; slb = get_slabmap_direct(slab_num); long n; for (n=1; n < AROUND_SLAB_LENGTH; n+=2) { long round_slab_num; round_slab_num = slab_num + around_slab[n]; struct SlabMap *round_slb; round_slb = get_slabmap_direct(round_slab_num); if (!slabmap_block_invalid(round_slb)) { MapSlabCoord slb_x,slb_y; slb_x = slb_num_decode_x(round_slab_num); slb_y = slb_num_decode_y(round_slab_num); // Per slab code if ((slabmap_owner(round_slb) == slabmap_owner(slb)) && (round_slb->kind == slb->kind)) { eff_score += 2; } else { is_room_inside = false; switch (find_core_slab_type(slb_x, slb_y)) { case SlbT_ROCK: case SlbT_GOLD: case SlbT_EARTH: case SlbT_GEMS: eff_score++; break; case SlbT_WALLDRAPE: if (slabmap_owner(round_slb) == slabmap_owner(slb)) eff_score += 2; break; case SlbT_DOORWOOD1: if (slabmap_owner(round_slb) == slabmap_owner(slb)) eff_score += 2; break; default: break; } } // Per slab code ends } } // If we already know this is not an inside - finish if (!is_room_inside) { return eff_score; } // Make sure this is room inside by checking corners for (n=0; n < AROUND_SLAB_LENGTH; n+=2) { long round_slab_num; round_slab_num = slab_num + around_slab[n]; struct SlabMap *round_slb; round_slb = get_slabmap_direct(round_slab_num); if (!slabmap_block_invalid(round_slb)) { // Per slab code if ((slabmap_owner(round_slb) != slabmap_owner(slb)) || (round_slb->kind != slb->kind)) { is_room_inside = 0; break; } // Per slab code ends } } if (is_room_inside) { eff_score += 2; } return eff_score; }
/** * Sets Water-Lava under Bridge flags for given SlabMap. */ void slabmap_set_wlb(struct SlabMap *slb, unsigned long wlbflag) { if (slabmap_block_invalid(slb)) return; slb->field_5 ^= (slb->field_5 ^ (wlbflag << 3)) & 0x18; }
/** * Returns Water-Lava under Bridge flags for given SlabMap. */ unsigned long slabmap_wlb(struct SlabMap *slb) { if (slabmap_block_invalid(slb)) return 0; return (slb->field_5 >> 3) & 0x03; }
/** * Sets owner of given SlabMap. */ void slabmap_set_owner(struct SlabMap *slb, PlayerNumber owner) { if (slabmap_block_invalid(slb)) return; slb->field_5 ^= (slb->field_5 ^ owner) & 0x07; }
/** * Returns owner index of given SlabMap. */ long slabmap_owner(const struct SlabMap *slb) { if (slabmap_block_invalid(slb)) return 5; return slb->field_5 & 0x07; }
long instf_dig(struct Thing *creatng, long *param) { struct CreatureControl *cctrl; struct Dungeon *dungeon; struct SlabMap *slb; long stl_x,stl_y; long task_idx,taskkind; long dig_damage,gold; SYNCDBG(16,"Starting"); TRACE_THING(creatng); //return _DK_instf_dig(thing, param); cctrl = creature_control_get_from_thing(creatng); dungeon = get_dungeon(creatng->owner); task_idx = cctrl->word_91; { struct MapTask *task; task = get_dungeon_task_list_entry(dungeon,task_idx); taskkind = task->kind; if (task->coords != cctrl->word_8F) { return 0; } stl_x = stl_num_decode_x(cctrl->word_8F); stl_y = stl_num_decode_y(cctrl->word_8F); } slb = get_slabmap_for_subtile(stl_x, stl_y); if (slabmap_block_invalid(slb)) { return 0; } dig_damage = calculate_damage_did_to_slab_with_single_hit(creatng, slb); if (slb->health > dig_damage) { if (!slab_kind_is_indestructible(slb->kind)) slb->health -= dig_damage; thing_play_sample(creatng, 63 + UNSYNC_RANDOM(6), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); create_effect(&creatng->mappos, TngEff_Unknown25, creatng->owner); if (taskkind == SDDigTask_MineGold) { gold = calculate_gold_digged_out_of_slab_with_single_hit(dig_damage, creatng->owner, cctrl->explevel, slb); creatng->creature.gold_carried += gold; dungeon->lvstats.gold_mined += gold; } return 0; } // slb->health <= dig_damage - we're going to destroy the slab remove_from_task_list(creatng->owner, task_idx); if (taskkind == SDDigTask_MineGold) { gold = calculate_gold_digged_out_of_slab_with_single_hit(slb->health, creatng->owner, cctrl->explevel, slb); creatng->creature.gold_carried += gold; dungeon->lvstats.gold_mined += gold; mine_out_block(stl_x, stl_y, creatng->owner); if (dig_has_revealed_area(stl_x, stl_y, creatng->owner)) { EventIndex evidx; evidx = event_create_event_or_update_nearby_existing_event( subtile_coord_center(stl_x), subtile_coord_center(stl_y), EvKind_AreaDiscovered, creatng->owner, 0); if ((evidx > 0) && is_my_player_number(creatng->owner)) output_message(SMsg_DugIntoNewArea, 0, true); } } else if (taskkind == SDDigTask_DigEarth) { dig_out_block(stl_x, stl_y, creatng->owner); if (dig_has_revealed_area(stl_x, stl_y, creatng->owner)) { EventIndex evidx; evidx = event_create_event_or_update_nearby_existing_event( subtile_coord_center(stl_x), subtile_coord_center(stl_y), EvKind_AreaDiscovered, creatng->owner, 0); if ((evidx > 0) && is_my_player_number(creatng->owner)) output_message(SMsg_DugIntoNewArea, 0, true); } } check_map_explored(creatng, stl_x, stl_y); thing_play_sample(creatng, 72 + UNSYNC_RANDOM(3), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); return 1; }