SlabKind choose_rock_type(PlayerNumber plyr_idx, MapSlabCoord slb_x, MapSlabCoord slb_y) { unsigned char flags; flags = 0; if ((slb_x % 5) == 0) { struct SlabMap *pvslb; struct SlabMap *nxslb; pvslb = get_slabmap_block(slb_x, slb_y-1); nxslb = get_slabmap_block(slb_x, slb_y+1); if ((pvslb->kind == SlbT_CLAIMED) || (nxslb->kind == SlbT_CLAIMED)) { flags |= 0x01; } } if ((slb_y % 5) == 0) { struct SlabMap *pvslb; struct SlabMap *nxslb; pvslb = get_slabmap_block(slb_x-1, slb_y); nxslb = get_slabmap_block(slb_x+1, slb_y); if ((pvslb->kind == SlbT_CLAIMED) || (nxslb->kind == SlbT_CLAIMED)) { flags |= 0x02; } } if (flags < 1) return SlbT_EARTH; else return SlbT_TORCHDIRT; }
TbBool initialise_map_wlb_auto(void) { struct SlabMap *slb; struct SlabAttr *slbattr; unsigned long x,y; unsigned long n,nbridge; nbridge = 0; for (y=0; y < map_tiles_y; y++) for (x=0; x < map_tiles_x; x++) { slb = get_slabmap_block(x,y); if (slb->kind == SlbT_BRIDGE) { if (slabs_count_near(x,y,1,SlbT_LAVA) > slabs_count_near(x,y,1,SlbT_WATER)) n = SlbT_LAVA; else n = SlbT_WATER; nbridge++; } else { n = slb->kind; } slbattr = get_slab_kind_attrs(n); n = (slbattr->wlb_type << 3); slb->field_5 ^= (slb->field_5 ^ n) & (0x10|0x08); } SYNCMSG("Regenerated WLB flags, unsure for %d bridge blocks.",(int)nbridge); return true; }
TbBool can_place_trap_on(PlayerNumber plyr_idx, MapSubtlCoord stl_x, MapSubtlCoord stl_y) { MapSlabCoord slb_x, slb_y; slb_x = subtile_slab_fast(stl_x); slb_y = subtile_slab_fast(stl_y); struct SlabMap *slb; slb = get_slabmap_block(slb_x, slb_y); struct SlabAttr *slbattr; slbattr = get_slab_attrs(slb); if (!subtile_revealed(stl_x, stl_y, plyr_idx)) { return false; } if (((slbattr->block_flags & (SlbAtFlg_Filled|SlbAtFlg_Digable|SlbAtFlg_Valuable)) != 0)) { return false; } if (slab_kind_is_liquid(slb->kind)) { return false; } if ((slabmap_owner(slb) == plyr_idx) && (slb->kind == SlbT_CLAIMED)) { if (!slab_has_trap_on(slb_x, slb_y) && !subtile_has_door_thing_on(stl_x, stl_y)) { return true; } } return false; }
/** * Counts amount of tiles owned by given player around given slab. * @param plyr_idx Owning player to be checked. * @param slb_x Target slab to check around, X coord. * @param slb_y Target slab to check around, Y coord. * @return Amount 0-4 of owned slabs, or just 4 if there is any owned ground or room slab. */ int count_owned_ground_around(PlayerNumber plyr_idx, MapSlabCoord slb_x, MapSlabCoord slb_y) { int i, num_owned; num_owned = 0; for (i=0; i < SMALL_AROUND_SLAB_LENGTH; i++) { MapSlabCoord sslb_x, sslb_y; sslb_x = slb_x + small_around[i].delta_x; sslb_y = slb_y + small_around[i].delta_y; struct SlabMap *slb; slb = get_slabmap_block(sslb_x, sslb_y); if (slabmap_owner(slb) == plyr_idx) { struct SlabAttr *slbattr; slbattr = get_slab_attrs(slb); if ((slbattr->category == SlbAtCtg_FortifiedGround) || (slbattr->category == SlbAtCtg_RoomInterior)) { num_owned = 4; break; } else { num_owned++; } } } return num_owned; }
/** * Removes reinforces walls from tiles around given slab, except given owner. * @param keep_plyr_idx The owning player whose walls are not to be affected. * @param slb_x Central slab for the unprettying effect, X coord. * @param slb_y Central slab for the unprettying effect, Y coord. */ void do_unprettying(PlayerNumber keep_plyr_idx, MapSlabCoord slb_x, MapSlabCoord slb_y) { long n; for (n=0; n < SMALL_AROUND_SLAB_LENGTH; n++) { long sslb_x,sslb_y; struct SlabMap *slb; sslb_x = slb_x + (long)small_around[n].delta_x; sslb_y = slb_y + (long)small_around[n].delta_y; slb = get_slabmap_block(sslb_x, sslb_y); struct SlabAttr *slbattr; slbattr = get_slab_attrs(slb); if ((slbattr->category == SlbAtCtg_FortifiedWall) && (slabmap_owner(slb) != keep_plyr_idx)) { if (!slab_by_players_land(slabmap_owner(slb), sslb_x, sslb_y)) { SlabKind newslab; newslab = choose_rock_type(keep_plyr_idx, sslb_x, sslb_y); place_slab_type_on_map(newslab, slab_subtile_center(sslb_x), slab_subtile_center(sslb_y), game.neutral_player_num, 0); unfill_reinforced_corners(keep_plyr_idx, sslb_x, sslb_y); do_slab_efficiency_alteration(sslb_x, sslb_y); } } } }
SlabKind find_core_slab_type(MapSlabCoord slb_x, MapSlabCoord slb_y) { struct SlabMap *slb; slb = get_slabmap_block(slb_x, slb_y); struct SlabAttr *slbattr; slbattr = get_slab_attrs(slb); SlabKind corekind; switch (slbattr->category) { case SlbAtCtg_FriableDirt: corekind = SlbT_EARTH; break; case SlbAtCtg_FortifiedWall: corekind = SlbT_WALLDRAPE; break; case SlbAtCtg_Obstacle: // originally, 99 was returned by this case, without further conditions if ((slbattr->block_flags & SlbAtFlg_IsRoom) != 0) corekind = SlbT_BRIDGE; else corekind = SlbT_DOORWOOD1; break; default: corekind = slb->kind; break; } return corekind; }
void unfill_reinforced_corners(PlayerNumber keep_plyr_idx, MapSlabCoord base_slb_x, MapSlabCoord base_slb_y) { //_DK_unfill_reinforced_corners(plyr_idx, base_slb_x, base_slb_y); return; int i; for (i = 0; i < SMALL_AROUND_SLAB_LENGTH; i++) { MapSlabCoord slb_x, slb_y; slb_x = base_slb_x + small_around[i].delta_x; slb_y = base_slb_y + small_around[i].delta_y; struct SlabMap *slb; slb = get_slabmap_block(slb_x, slb_y); struct SlabAttr *slbattr; slbattr = get_slab_attrs(slb); if ((slbattr->category == SlbAtCtg_FortifiedWall) && (slabmap_owner(slb) != keep_plyr_idx)) { int num_owned_around; num_owned_around = count_owned_ground_around(slabmap_owner(slb), slb_x, slb_y); if (num_owned_around < 2) { SlabKind slbkind; slbkind = alter_rock_style(SlbT_EARTH, slb_x, slb_y, game.neutral_player_num); place_slab_type_on_map(slbkind, slab_subtile_center(slb_x), slab_subtile_center(slb_y), game.neutral_player_num, 0); do_slab_efficiency_alteration(slb_x, slb_y); } } } }
TbBool can_build_room_at_slab(PlayerNumber plyr_idx, RoomKind rkind, MapSlabCoord slb_x, MapSlabCoord slb_y) { if (!subtile_revealed(slab_subtile_center(slb_x), slab_subtile_center(slb_y), plyr_idx)) { SYNCDBG(7,"Cannot place %s owner %d as slab (%d,%d) is not revealed",room_code_name(rkind),(int)plyr_idx,(int)slb_x,(int)slb_y); return false; } struct SlabMap *slb; slb = get_slabmap_block(slb_x, slb_y); if (slb->room_index > 0) { SYNCDBG(7,"Cannot place %s owner %d as slab (%d,%d) has room index %d",room_code_name(rkind),(int)plyr_idx,(int)slb_x,(int)slb_y,(int)slb->room_index); return false; } if (slab_has_trap_on(slb_x, slb_y) || slab_has_door_thing_on(slb_x, slb_y)) { SYNCDBG(7,"Cannot place %s owner %d as slab (%d,%d) has blocking thing on it",room_code_name(rkind),(int)plyr_idx,(int)slb_x,(int)slb_y); return false; } if (rkind == RoK_BRIDGE) { return slab_kind_is_liquid(slb->kind) && slab_by_players_land(plyr_idx, slb_x, slb_y); } if (slabmap_owner(slb) != plyr_idx) { return false; } return (slb->kind == SlbT_CLAIMED); }
/** * Finds a safe and unused, adjacent position in room for a creature. * * @param pos Position of the creature to be moved. * @param owner Room owner to keep. * @return Coded subtiles of the new position, or 0 on failure. * @see person_get_somewhere_adjacent_in_room() */ SubtlCodedCoords find_unused_adjacent_position_in_workshop(const struct Coord3d *pos, long owner) { static const struct Around corners[] = { {1,2}, {0,1}, {1,0}, {2,1} }; long i; for (i=0; i < SMALL_AROUND_LENGTH; i++) { MapSlabCoord slb_x, slb_y; slb_x = subtile_slab_fast(pos->x.stl.num) + (long)small_around[i].delta_x; slb_y = subtile_slab_fast(pos->y.stl.num) + (long)small_around[i].delta_y; struct SlabMap *slb; slb = get_slabmap_block(slb_x, slb_y); if ((slb->kind == SlbT_WORKSHOP) && (slabmap_owner(slb) == owner)) { struct Thing *mnfc_creatng; MapSubtlCoord stl_x, stl_y; stl_x = slab_subtile(slb_x, corners[i].delta_x); stl_y = slab_subtile(slb_y, corners[i].delta_y); mnfc_creatng = get_other_creature_manufacturing_on_subtile(owner, stl_x, stl_y, INVALID_THING); if (!thing_is_invalid(mnfc_creatng)) { // Position used by another manufacturer continue; } struct Thing *objtng; objtng = get_workshop_equipment_to_work_with_on_subtile(owner, slab_subtile_center(slb_x), slab_subtile_center(slb_y)); if (thing_is_invalid(objtng)) { // Position has no work equipment nearby continue; } // Found an acceptable position return get_subtile_number(stl_x, stl_y); } } return 0; }
short load_map_slab_file(unsigned long lv_num) { SYNCDBG(7,"Starting"); struct SlabMap *slb; unsigned long x,y; unsigned char *buf; unsigned long i; unsigned long n; long fsize; fsize = 2*map_tiles_y*map_tiles_x; buf = load_single_map_file_to_buffer(lv_num,"slb",&fsize,LMFF_None); if (buf == NULL) return false; i = 0; for (y=0; y < map_tiles_y; y++) for (x=0; x < map_tiles_x; x++) { slb = get_slabmap_block(x,y); n = lword(&buf[i]); if (n > SLAB_TYPES_COUNT) { WARNMSG("Slab Type %d exceeds limit of %d",(int)n,SLAB_TYPES_COUNT); n = SlbT_ROCK; } slb->kind = n; i += 2; } LbMemoryFree(buf); initialise_map_collides(); initialise_map_health(); initialise_extra_slab_info(lv_num); return true; }
long instf_destroy(struct Thing *creatng, long *param) { struct Dungeon *dungeon; struct Room *room; struct SlabMap *slb; MapSlabCoord slb_x,slb_y; long prev_owner; TRACE_THING(creatng); slb_x = subtile_slab_fast(creatng->mappos.x.stl.num); slb_y = subtile_slab_fast(creatng->mappos.y.stl.num); dungeon = get_dungeon(creatng->owner); slb = get_slabmap_block(slb_x, slb_y); room = room_get(slb->room_index); prev_owner = slabmap_owner(slb); if ( !room_is_invalid(room) && (prev_owner != creatng->owner) ) { if (room->health > 1) { room->health--; return 0; } clear_dig_on_room_slabs(room, creatng->owner); if (room->owner == game.neutral_player_num) { claim_room(room, creatng); } else { MapCoord ccor_x,ccor_y; ccor_x = subtile_coord_center(room->central_stl_x); ccor_y = subtile_coord_center(room->central_stl_y); event_create_event_or_update_nearby_existing_event(ccor_x, ccor_y, EvKind_RoomLost, room->owner, 0); claim_enemy_room(room, creatng); } thing_play_sample(creatng, 76, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); create_effects_on_room_slabs(room, imp_spangle_effects[creatng->owner], 0, creatng->owner); return 0; } if (slb->health > 1) { slb->health--; return 0; } if (prev_owner != game.neutral_player_num) { struct Dungeon *prev_dungeon; prev_dungeon = get_dungeon(prev_owner); prev_dungeon->lvstats.territory_lost++; } decrease_dungeon_area(prev_owner, 1); neutralise_enemy_block(creatng->mappos.x.stl.num, creatng->mappos.y.stl.num, creatng->owner); remove_traps_around_subtile(slab_subtile_center(slb_x), slab_subtile_center(slb_y), NULL); switch_owned_objects_on_destoyed_slab_to_neutral(slb_x, slb_y, prev_owner); dungeon->lvstats.territory_destroyed++; return 1; }
TbBool slab_is_safe_land(PlayerNumber plyr_idx, MapSlabCoord slb_x, MapSlabCoord slb_y) { struct SlabMap *slb; struct SlabAttr *slbattr; int slb_owner; slb = get_slabmap_block(slb_x, slb_y); slbattr = get_slab_attrs(slb); slb_owner = slabmap_owner(slb); if ((slb_owner == plyr_idx) || (slb_owner == game.neutral_player_num)) { return slbattr->is_safe_land; } return false; }
int floor_height_for_volume_box(PlayerNumber plyr_idx, MapSlabCoord slb_x, MapSlabCoord slb_y) { struct SlabMap *slb; slb = get_slabmap_block(slb_x, slb_y); struct SlabAttr *slbattr; slbattr = get_slab_attrs(slb); if (!subtile_revealed(slab_subtile_center(slb_x), slab_subtile_center(slb_y), plyr_idx) || ((slbattr->block_flags & (SlbAtFlg_Filled|SlbAtFlg_Digable|SlbAtFlg_Valuable)) != 0)) { return temp_cluedo_mode < 1u ? 5 : 2; } if (slab_kind_is_liquid(slb->kind)) { return 0; } return 1; }
/** * Counts amount of slabs around given slab which have given kind and owner. * @param slb_x Target slab position, X coordinate. * @param slb_y Target slab position, Y coordinate. * @param slbkind Kind of the slabs to count. * @param owner Owner of the slabs to count. * @return Amount of matched slabs around given coordinates, 0..8. */ int count_slabs_around_of_kind(MapSlabCoord slb_x, MapSlabCoord slb_y, SlabKind slbkind, PlayerNumber owner) { unsigned long n; int matched_slabs; matched_slabs = 0; for (n = 1; n < MID_AROUND_LENGTH; n++) { MapSlabCoord arslb_x, arslb_y; arslb_x = slb_x + mid_around[n].delta_x; arslb_y = slb_y + mid_around[n].delta_y; struct SlabMap *slb; slb = get_slabmap_block(arslb_x, arslb_y); if ((slb->kind == slbkind) && (slabmap_owner(slb) == owner)) { matched_slabs++; } } return matched_slabs; }
TbBool load_map_wlb_file(unsigned long lv_num) { struct SlabMap *slb; unsigned long x,y; unsigned char *buf; unsigned long i; unsigned long n; unsigned long nfixes; long fsize; SYNCDBG(7,"Starting"); nfixes = 0; fsize = map_tiles_y*map_tiles_x; buf = load_single_map_file_to_buffer(lv_num,"wlb",&fsize,LMFF_Optional); if (buf == NULL) return false; i = 0; for (y=0; y < map_tiles_y; y++) for (x=0; x < map_tiles_x; x++) { slb = get_slabmap_block(x,y); n = (buf[i] << 3); n = slb->field_5 ^ ((slb->field_5 ^ n) & 0x18); slb->field_5 = n; n &= (0x08|0x10); if ((n != 0x10) || (slb->kind != SlbT_WATER)) if ((n != 0x08) || (slb->kind != SlbT_LAVA)) if (((n == 0x10) || (n == 0x08)) && (slb->kind != SlbT_BRIDGE)) { nfixes++; slb->field_5 &= ~(0x08|0x10); } i++; } LbMemoryFree(buf); if (nfixes > 0) { ERRORLOG("WLB file is muddled - Fixed values for %lu tiles",nfixes); } return true; }
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); } } }
void update_horizonal_explored_flags_for_power_sight(struct PlayerInfo *player, struct Coord3d *soe_pos) { struct Dungeon *dungeon; long stl_x,stl_y; long soe_x,soe_y; long boundstl_y; long slb_x,slb_y; long delta; long i; dungeon = get_players_dungeon(player); stl_x = (long)soe_pos->x.stl.num - MAX_SOE_RADIUS; for (soe_x=0; soe_x < 2*MAX_SOE_RADIUS; soe_x++,stl_x++) { if ( (stl_x >= 0) && (stl_x <= 255) ) { stl_y = (long)soe_pos->y.stl.num - MAX_SOE_RADIUS; for (soe_y=0; soe_y <= MAX_SOE_RADIUS; soe_y++,stl_y++) { if (dungeon->soe_explored_flags[soe_y][soe_x]) { soe_y++; // Find max value for delta delta = 0; for (i=1; soe_y < 2*MAX_SOE_RADIUS; soe_y++,i++) { if (dungeon->soe_explored_flags[soe_y][soe_x]) delta = i; } boundstl_y = stl_y + delta; if (boundstl_y < 0) { boundstl_y = 0; } else if (boundstl_y > map_subtiles_y-1) { boundstl_y = map_subtiles_y-1; } if (stl_y < 0) { stl_y = 0; } else if (stl_y > map_subtiles_y-1) { stl_y = map_subtiles_y-1; } if (stl_y <= boundstl_y) { delta = boundstl_y - stl_y + 1; slb_x = subtile_slab_fast(stl_x); for (i=0; i < delta; i++) { struct Map *mapblk; slb_y = subtile_slab_fast(stl_y+i); mapblk = get_map_block_at(stl_x, stl_y+i); reveal_map_block(mapblk, player->id_number); struct SlabMap *slb; struct SlabAttr *slbattr; slb = get_slabmap_block(slb_x, slb_y); slbattr = get_slab_attrs(slb); if ( !slbattr->is_unknflg14 ) mapblk->flags &= ~(MapFlg_Unkn80|MapFlg_Unkn04); } stl_y += delta; } } } } } }
TbBool slab_is_liquid(MapSlabCoord slb_x, MapSlabCoord slb_y) { struct SlabMap *slb; slb = get_slabmap_block(slb_x, slb_y); return slab_kind_is_liquid(slb->kind); }
void process_creature_in_training_room(struct Thing *thing, struct Room *room) { static const struct Around corners[] = { {1, 2}, {0, 1}, {1, 0}, {2, 1}, }; struct CreatureControl *cctrl; struct CreatureStats *crstat; struct Thing *traintng; struct Thing *crtng; struct CreatureControl *cctrl2; struct Coord3d pos; long speed,dist; long i; cctrl = creature_control_get_from_thing(thing); SYNCDBG(8,"Starting %s mode %d",thing_model_name(thing),(int)cctrl->training.mode); //_DK_process_creature_in_training_room(thing, room); return; cctrl->field_4A = 0; switch (cctrl->training.mode) { case CrTrMd_SearchForTrainPost: // While we're in an instance, just wait if (cctrl->instance_id != CrInst_NULL) break; // On timeout, search for nearby training posts to start training ASAP if (cctrl->training.search_timeout < 1) { SYNCDBG(6,"Search timeout - selecting post nearest to (%d,%d)",(int)thing->mappos.x.stl.num, (int)thing->mappos.y.stl.num); setup_training_search_for_post(thing); cctrl->training.search_timeout = 100; break; } // Do a moving step cctrl->training.search_timeout--; speed = get_creature_speed(thing); i = creature_move_to(thing, &cctrl->moveto_pos, speed, 0, 0); if (i == 1) { // Move target is reached - find a training post which is supposed to be around here traintng = find_training_post_just_next_to_creature(thing); if (thing_is_invalid(traintng)) { SYNCDBG(6,"Reached (%d,%d) but there's no training post there",(int)thing->mappos.x.stl.num, (int)thing->mappos.y.stl.num); setup_move_to_new_training_position(thing, room, false); break; } // Found - go to next mode cctrl->training.mode = CrTrMd_SelectPositionNearTrainPost; cctrl->training.search_timeout = 50; } else if (i == -1) { ERRORLOG("Cannot get to (%d,%d) in the training room",(int)cctrl->moveto_pos.x.stl.num,(int)cctrl->moveto_pos.y.stl.num); set_start_state(thing); } break; case CrTrMd_SelectPositionNearTrainPost: for (i=0; i < 4; i++) { long slb_x,slb_y; long stl_x,stl_y; struct SlabMap *slb; slb_x = subtile_slab_fast(thing->mappos.x.stl.num) + (long)small_around[i].delta_x; slb_y = subtile_slab_fast(thing->mappos.y.stl.num) + (long)small_around[i].delta_y; slb = get_slabmap_block(slb_x,slb_y); if ((slb->kind != SlbT_TRAINING) || (slabmap_owner(slb) != thing->owner)) continue; stl_x = slab_subtile(slb_x,corners[i].delta_x); stl_y = slab_subtile(slb_y,corners[i].delta_y); traintng = INVALID_THING; // Check if any other creature is using that post; allow only unused posts crtng = get_creature_of_model_training_at_subtile_and_owned_by(stl_x, stl_y, -1, thing->owner, thing->index); if (thing_is_invalid(crtng)) { traintng = get_object_at_subtile_of_model_and_owned_by(slab_subtile_center(slb_x), slab_subtile_center(slb_y), 31, thing->owner); } if (!thing_is_invalid(traintng)) { cctrl->training.pole_stl_x = slab_subtile_center(subtile_slab_fast(thing->mappos.x.stl.num)); cctrl->training.pole_stl_y = slab_subtile_center(subtile_slab_fast(thing->mappos.y.stl.num)); cctrl->moveto_pos.x.stl.num = stl_x; cctrl->moveto_pos.y.stl.num = stl_y; cctrl->moveto_pos.x.stl.pos = 128; cctrl->moveto_pos.y.stl.pos = 128; cctrl->moveto_pos.z.val = get_thing_height_at(thing, &cctrl->moveto_pos); if (thing_in_wall_at(thing, &cctrl->moveto_pos)) { ERRORLOG("Illegal setup to (%d,%d)", (int)cctrl->moveto_pos.x.stl.num, (int)cctrl->moveto_pos.y.stl.num); break; } cctrl->training.mode = CrTrMd_MoveToTrainPost; break; } } if (cctrl->training.mode == CrTrMd_SelectPositionNearTrainPost) setup_move_to_new_training_position(thing, room, 1); break; case CrTrMd_MoveToTrainPost: speed = get_creature_speed(thing); i = creature_move_to(thing, &cctrl->moveto_pos, speed, 0, 0); if (i == 1) { // If there's already someone training at that position, go somewhere else crtng = get_creature_of_model_training_at_subtile_and_owned_by(thing->mappos.x.stl.num, thing->mappos.y.stl.num, -1, thing->owner, thing->index); if (!thing_is_invalid(crtng)) { setup_move_to_new_training_position(thing, room, 1); break; } // Otherwise, train at this position cctrl->training.mode = CrTrMd_TurnToTrainPost; } else if (i == -1) { ERRORLOG("Cannot get where we're going in the training room."); set_start_state(thing); } break; case CrTrMd_TurnToTrainPost: pos.x.val = subtile_coord_center(cctrl->training.pole_stl_x); pos.y.val = subtile_coord_center(cctrl->training.pole_stl_y); if (creature_turn_to_face(thing, &pos) < 56) { cctrl->training.mode = CrTrMd_DoTrainWithTrainPost; cctrl->training.train_timeout = 75; } break; case CrTrMd_PartnerTraining: if (cctrl->training.partner_idx == 0) { setup_move_to_new_training_position(thing, room, false); return; } crtng = thing_get(cctrl->training.partner_idx); TRACE_THING(crtng); if (!thing_exists(crtng) || (get_creature_state_besides_move(crtng) != CrSt_Training) || (crtng->creation_turn != cctrl->training.partner_creation)) { SYNCDBG(8,"The %s cannot start partner training - creature to train with is gone.",thing_model_name(thing)); setup_move_to_new_training_position(thing, room, false); return; } cctrl2 = creature_control_get_from_thing(crtng); if (cctrl2->training.partner_idx != thing->index) { SYNCDBG(6,"The %s cannot start partner training - %s changed the partner.",thing_model_name(thing),thing_model_name(crtng)); cctrl->training.partner_idx = 0; setup_move_to_new_training_position(thing, room, false); break; } if (get_room_thing_is_on(crtng) != room) { SYNCDBG(8,"The %s cannot start partner training - partner has left the room.",thing_model_name(thing)); cctrl->training.partner_idx = 0; cctrl2->training.partner_idx = 0; setup_move_to_new_training_position(thing, room, false); break; } crstat = creature_stats_get_from_thing(thing); dist = get_combat_distance(thing, crtng); if (dist > 284) { if (creature_move_to(thing, &crtng->mappos, get_creature_speed(thing), 0, 0) == -1) { WARNLOG("The %s cannot navigate to training partner",thing_model_name(thing)); setup_move_to_new_training_position(thing, room, false); cctrl->training.partner_idx = 0; } } else if (dist >= 156) { if (creature_turn_to_face(thing, &crtng->mappos) < 56) { cctrl->training.train_timeout--; if (cctrl->training.train_timeout > 0) { if ((cctrl->instance_id == CrInst_NULL) && ((cctrl->training.train_timeout % 8) == 0)) { set_creature_instance(thing, CrInst_SWING_WEAPON_SWORD, 1, 0, 0); } } else { if (cctrl->instance_id == CrInst_NULL) { setup_move_to_new_training_position(thing, room, false); cctrl->training.partner_idx = 0; } else { cctrl->training.train_timeout = 1; } cctrl->exp_points += (room->efficiency * crstat->training_value); } } } else { creature_retreat_from_combat(thing, crtng, 33, 0); } break; case CrTrMd_DoTrainWithTrainPost: if (cctrl->training.train_timeout > 0) { // While training timeout is positive, continue initiating the train instances cctrl->training.train_timeout--; if ((cctrl->instance_id == CrInst_NULL) && ((cctrl->training.train_timeout % 8) == 0)) { set_creature_instance(thing, CrInst_SWING_WEAPON_SWORD, 1, 0, 0); } } else { // Wait for the instance to end, then select new move position if (cctrl->instance_id != CrInst_NULL) { cctrl->training.train_timeout = 0; } else { cctrl->training.train_timeout = 0; setup_move_to_new_training_position(thing, room, true); } } break; default: WARNLOG("Invalid %s training mode %d; reset",thing_model_name(thing),(int)cctrl->training.mode); cctrl->training.mode = CrTrMd_SearchForTrainPost; cctrl->training.search_timeout = 0; break; } SYNCDBG(18,"End"); }
TbBool find_place_to_put_door_around_room(const struct Room *room, struct Coord3d *pos) { long m,n; m = ACTION_RANDOM(SMALL_AROUND_SLAB_LENGTH); for (n = 0; n < SMALL_AROUND_SLAB_LENGTH; n++) { // Get position containing room center MapSlabCoord slb_x,slb_y; slb_x = subtile_slab_fast(room->central_stl_x); slb_y = subtile_slab_fast(room->central_stl_y); // Move the position to edge of the room struct Room *sibroom; sibroom = slab_room_get(slb_x, slb_y); while (!room_is_invalid(sibroom) && (sibroom->index == room->index)) { slb_x += small_around[m].delta_x; slb_y += small_around[m].delta_y; sibroom = slab_room_get(slb_x, slb_y); } // Move the position a few tiles further in that direction searching for a place to put door //TODO COMPUTER_PLAYER Why we can only have doors if corridor is at center of the room? This should be fixed to allow doors everywhere around room. int i; for (i = 4; i > 0; i--) { struct SlabMap *slb; slb = get_slabmap_block(slb_x, slb_y); if ((slabmap_owner(slb) != room->owner) || (slb->kind != SlbT_CLAIMED)) { i = 0; break; } if (tag_cursor_blocks_place_door(room->owner, slab_subtile_center(slb_x), slab_subtile_center(slb_y))) { break; } if (!subtile_has_door_thing_on(slab_subtile_center(slb_x), slab_subtile_center(slb_y))) { // No door - the position looks ok break; } slb_x += small_around[m].delta_x; slb_y += small_around[m].delta_y; } // Now if we were able to move, then the position seem ok. One last check - make sure the corridor is not dead end and doesn't already have a door if (i > 0) { MapSlabCoord nxslb_x,nxslb_y; nxslb_x = slb_x + small_around[m].delta_x; nxslb_y = slb_y + small_around[m].delta_y; struct SlabMap *nxslb; nxslb = get_slabmap_block(nxslb_x, nxslb_y); if ((slabmap_owner(nxslb) == room->owner) && (nxslb->kind == SlbT_CLAIMED)) { if (!subtile_has_door_thing_on(slab_subtile_center(nxslb_x), slab_subtile_center(nxslb_y))) { pos->x.val = subtile_coord_center(slab_subtile_center(slb_x)); pos->y.val = subtile_coord_center(slab_subtile_center(slb_y)); pos->z.val = subtile_coord(1,0); return true; } } } m = (m + 1) % SMALL_AROUND_SLAB_LENGTH; } return false; }