long computer_check_neutral_places(struct Computer2 *comp, struct ComputerCheck * check) { SYNCDBG(8,"Starting"); //return _DK_computer_check_neutral_places(comp, check); struct Comp2_UnkStr1 *rel; rel = &comp->unkarr_A10[game.neutral_player_num]; struct Room *near_room; struct Coord3d *near_pos; int near_dist; near_room = INVALID_ROOM; near_dist = 2147483647; near_pos = &rel->pos_A[0]; int i; for (i=0; i < 64; i++) { struct Coord3d *place; place = &rel->pos_A[i]; if ((place->x.val == 0) || (place->y.val == 0)) { continue; } struct Room *room; room = INVALID_ROOM; if (computer_finds_nearest_room_to_pos(comp, &room, place)) { MapSubtlDelta dx,dy; dx = abs((int)room->central_stl_x - (MapSubtlDelta)place->x.stl.num); dy = abs((int)room->central_stl_y - (MapSubtlDelta)place->y.stl.num); if (near_dist > dx+dy) { near_room = room; near_pos = place; near_dist = dx+dy; } } } if (room_is_invalid(near_room)) { return 4; } struct Coord3d endpos; struct Coord3d startpos; endpos.x.val = near_pos->x.val; endpos.y.val = near_pos->y.val; endpos.z.val = near_pos->z.val; startpos.x.val = subtile_coord_center(stl_slab_center_subtile(near_room->central_stl_x)); startpos.y.val = subtile_coord_center(stl_slab_center_subtile(near_room->central_stl_y)); startpos.z.val = subtile_coord(1,0); if (!create_task_dig_to_neutral(comp, startpos, endpos)) { return 4; } near_pos->x.val = 0; near_pos->y.val = 0; near_pos->z.val = 0; return 1; }
void init_dungeon_essential_position(struct Dungeon *dungeon) { struct Room *room; room = room_get(dungeon->room_kind[RoK_DUNGHEART]); RoomKind rkind; for (rkind = 1; rkind < ROOM_TYPES_COUNT; rkind++) { if (!room_is_invalid(room)) break; room = room_get(dungeon->room_kind[rkind]); } if (room_is_invalid(room)) { dungeon->essential_pos.x.val = subtile_coord_center(map_subtiles_x/2); dungeon->essential_pos.y.val = subtile_coord_center(map_subtiles_y/2); dungeon->essential_pos.z.val = subtile_coord(0,1); return; } dungeon->essential_pos.x.val = subtile_coord_center(room->central_stl_x); dungeon->essential_pos.y.val = subtile_coord_center(room->central_stl_y); dungeon->essential_pos.z.val = subtile_coord(0,1); }
TbBool tag_cursor_blocks_place_trap(PlayerNumber plyr_idx, MapSubtlCoord stl_x, MapSubtlCoord stl_y) { SYNCDBG(7,"Starting"); int floor_height; TbBool can_place; MapSlabCoord slb_x, slb_y; slb_x = subtile_slab_fast(stl_x); slb_y = subtile_slab_fast(stl_y); can_place = can_place_trap_on(plyr_idx, stl_x, stl_y); floor_height = floor_height_for_volume_box(plyr_idx, slb_x, slb_y); if (is_my_player_number(plyr_idx)) { if (!game_is_busy_doing_gui() && (game.small_map_state != 2)) { // Move to first subtile on a slab stl_x = slab_subtile(slb_x,0); stl_y = slab_subtile(slb_y,0); draw_map_volume_box(subtile_coord(stl_x,0), subtile_coord(stl_y,0), subtile_coord(stl_x+STL_PER_SLB,0), subtile_coord(stl_y+STL_PER_SLB,0), floor_height, can_place); } } return can_place; }
void find_nearest_rooms_for_ambient_sound(void) { struct PlayerInfo *player; struct Room *room; struct MapOffset *sstep; struct Coord3d pos; long slb_x,slb_y; MapSubtlCoord stl_x,stl_y; long i,k; SYNCDBG(8,"Starting"); if ((SoundDisabled) || (GetCurrentSoundMasterVolume() <= 0)) return; player = get_my_player(); struct Camera *cam; cam = player->acamera; if (cam == NULL) { ERRORLOG("No active camera"); set_room_playing_ambient_sound(NULL, 0); return; } slb_x = subtile_slab(cam->mappos.x.stl.num); slb_y = subtile_slab(cam->mappos.y.stl.num); for (i = 0; i < 11*11; i++) { sstep = &spiral_step[i]; stl_x = slab_subtile_center(slb_x + sstep->h); stl_y = slab_subtile_center(slb_y + sstep->v); if (subtile_is_player_room(player->id_number,stl_x,stl_y)) { room = subtile_room_get(stl_x, stl_y); if (room_is_invalid(room)) continue; struct RoomConfigStats *roomst; roomst = &slab_conf.room_cfgstats[room->kind]; k = roomst->ambient_snd_smp_id; if (k > 0) { SYNCDBG(8,"Playing ambient for %s at (%d,%d)",room_code_name(room->kind),(int)stl_x,(int)stl_y); pos.x.val = subtile_coord_center(stl_x); pos.y.val = subtile_coord_center(stl_y); pos.z.val = subtile_coord(1,0); set_room_playing_ambient_sound(&pos, k); return; } } } set_room_playing_ambient_sound(NULL, 0); }
void draw_god_lightning(struct Thing *shotng) { //_DK_draw_god_lightning(shotng); return; struct PlayerInfo *player; player = get_player(shotng->owner); const struct Camera *cam; cam = player->acamera; if (cam == NULL) { return; } int i; for (i = LbFPMath_PI/4; i < 2*LbFPMath_PI; i += LbFPMath_PI/2) { struct Coord3d locpos; locpos.x.val = shotng->mappos.x.val; locpos.y.val = shotng->mappos.y.val; locpos.z.val = shotng->mappos.z.val; locpos.x.val += (LbSinL(i + cam->orient_a) >> (LbFPMath_TrigmBits - 10)); locpos.y.val += -(LbCosL(i + cam->orient_a) >> (LbFPMath_TrigmBits - 10)); locpos.z.val = subtile_coord(12,0); draw_lightning(&locpos, &shotng->mappos, 256, 60); } }
/** * Quick attack is just putting CTA spell on enemy room. * @param comp * @param check */ long computer_check_for_quick_attack(struct Computer2 *comp, struct ComputerCheck * check) { struct Dungeon *dungeon; SYNCDBG(8,"Starting"); //return _DK_computer_check_for_quick_attack(comp, check); dungeon = comp->dungeon; int creatrs_num; creatrs_num = check->param1 * dungeon->num_active_creatrs / 100; if (check->param3 >= creatrs_num) { return 4; } if (computer_able_to_use_magic(comp, PwrK_CALL2ARMS, 1, 3) != 1) { return 4; } if ((check_call_to_arms(comp) != 1) || is_there_an_attack_task(comp)) { return 4; } struct Room *room; room = get_hated_room_for_quick_attack(comp, check->param3); if (room_is_invalid(room)) { return 4; } struct Coord3d pos; // TODO COMPUTER_PLAYER We should make sure the place of cast is accessible for creatures pos.x.val = subtile_coord_center(room->central_stl_x); pos.y.val = subtile_coord_center(room->central_stl_y); pos.z.val = subtile_coord(1,0); if (check->param3 >= count_creatures_availiable_for_fight(comp, &pos)) { return 4; } if (!create_task_magic_support_call_to_arms(comp, &pos, check->param2, 0, creatrs_num)) { return 4; } output_message(SMsg_EnemyHarassments+ACTION_RANDOM(8), 500, 1); return 1; }
TbBool sibling_line_of_sight_3d_including_lava_check_ignoring_own_door(const struct Coord3d *prevpos, const struct Coord3d *nextpos, PlayerNumber plyr_idx) { // Check for door at central subtile if (subtile_is_door(stl_slab_center_subtile(nextpos->x.stl.num), stl_slab_center_subtile(nextpos->y.stl.num))) { return false; } // If only one dimensions changed, allow the pass // (in that case the outcome has been decided before this call) if ((nextpos->x.stl.num == prevpos->x.stl.num) || (nextpos->y.stl.num == prevpos->y.stl.num)) { // change is (x,0) or (0,x) return true; } struct Coord3d posmvy; struct Coord3d posmvx; int subdelta_x, subdelta_y; subdelta_x = (nextpos->x.stl.num - (MapSubtlDelta)prevpos->x.stl.num); subdelta_y = (nextpos->y.stl.num - (MapSubtlDelta)prevpos->y.stl.num); switch (subdelta_x + 2 * subdelta_y) { case -3: // change is (-1,-1) posmvx.x.val = prevpos->x.val - subtile_coord(1,0); posmvx.y.val = prevpos->y.val; posmvx.z.val = prevpos->z.val; posmvy.x.val = prevpos->x.val; posmvy.y.val = prevpos->y.val - subtile_coord(1,0); posmvy.z.val = prevpos->z.val; if (get_point_in_map_solid_flags_ignoring_own_door(&posmvy, plyr_idx) & 0x01) { return false; } if (get_point_in_map_solid_flags_ignoring_own_door(&posmvx, plyr_idx) & 0x01) { return false; } break; case -1: // change is (1,-1) as (-1,0) was eliminated earlier posmvx.x.val = prevpos->x.val + subtile_coord(1,0); posmvx.y.val = prevpos->y.val; posmvx.z.val = prevpos->z.val; posmvy.x.val = prevpos->x.val; posmvy.y.val = prevpos->y.val - subtile_coord(1,0); posmvy.z.val = prevpos->z.val; if (get_point_in_map_solid_flags_ignoring_own_door(&posmvy, plyr_idx) & 0x01) { return false; } if (get_point_in_map_solid_flags_ignoring_own_door(&posmvx, plyr_idx) & 0x01) { return false; } break; case 1: // change is (-1,1) as (1,0) was eliminated earlier posmvx.x.val = prevpos->x.val - subtile_coord(1,0); posmvx.y.val = prevpos->y.val; posmvx.z.val = prevpos->z.val; posmvy.x.val = prevpos->x.val; posmvy.y.val = prevpos->y.val + subtile_coord(1,0); posmvy.z.val = prevpos->z.val; if (get_point_in_map_solid_flags_ignoring_own_door(&posmvy, plyr_idx) & 0x01) { return false; } if (get_point_in_map_solid_flags_ignoring_own_door(&posmvx, plyr_idx) & 0x01) { return false; } break; case 3: // change is (1,1) posmvx.x.val = prevpos->x.val + subtile_coord(1,0); posmvx.y.val = prevpos->y.val; posmvx.z.val = prevpos->z.val; posmvy.x.val = prevpos->x.val; posmvy.y.val = prevpos->y.val + subtile_coord(1,0); posmvy.z.val = prevpos->z.val; if (get_point_in_map_solid_flags_ignoring_own_door(&posmvy, plyr_idx) & 0x01) { return false; } if (get_point_in_map_solid_flags_ignoring_own_door(&posmvx, plyr_idx) & 0x01) { return false; } break; default: ERRORDBG(8,"Invalid use of sibling function, delta (%d,%d)",(int)subdelta_x,(int)subdelta_y); break; } return true; }
void god_lightning_choose_next_creature(struct Thing *shotng) { SYNCDBG(16,"Starting for %s index %d owner %d",thing_model_name(shotng),(int)shotng->index,(int)shotng->owner); //_DK_god_lightning_choose_next_creature(shotng); return; long best_dist; struct Thing *best_thing; best_dist = LONG_MAX; best_thing = INVALID_THING; unsigned long k; int i; const struct StructureList *slist; slist = get_list_for_thing_class(TCls_Creature); k = 0; i = slist->index; while (i != 0) { struct Thing *thing; thing = thing_get(i); if (thing_is_invalid(thing)) { ERRORLOG("Jump to invalid thing detected"); break; } i = thing->next_of_class; // Per-thing code //TODO use hit_type instead of hard coded conditions if ((shotng->owner != thing->owner) && !thing_is_picked_up(thing) && !creature_is_being_unconscious(thing) && !creature_is_dying(thing)) { long dist; dist = get_2d_distance(&shotng->mappos, &thing->mappos); if (dist < best_dist) { const struct MagicStats *pwrdynst; pwrdynst = get_power_dynamic_stats(PwrK_LIGHTNING); int spell_lev; spell_lev = shotng->shot.byte_19; if (spell_lev > SPELL_MAX_LEVEL) spell_lev = SPELL_MAX_LEVEL; if (subtile_coord(pwrdynst->strength[spell_lev],0) > dist) { if (line_of_sight_2d(&shotng->mappos, &thing->mappos)) { best_dist = dist; best_thing = thing; } } } } // Per-thing code ends k++; if (k > slist->count) { ERRORLOG("Infinite loop detected when sweeping things list"); erstat_inc(ESE_InfChainTngPerClass); break; } } SYNCDBG(8,"The best target for %s index %d owner %d is %s index %d owner %d", thing_model_name(shotng),(int)shotng->index,(int)shotng->owner, thing_model_name(best_thing),(int)best_thing->index,(int)best_thing->owner); if (!thing_is_invalid(best_thing)) { shotng->shot.target_idx = best_thing->index; } else { shotng->shot.target_idx = 0; } }
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; }
long computer_check_enemy_entrances(struct Computer2 *comp, struct ComputerCheck * check) { SYNCDBG(8,"Starting"); //return _DK_computer_check_enemy_entrances(comp, check); long result; result = 4; PlayerNumber plyr_idx; for (plyr_idx=0; plyr_idx < PLAYERS_COUNT; plyr_idx++) { if (comp->dungeon->owner == plyr_idx) { continue; } if (players_are_mutual_allies(comp->dungeon->owner, plyr_idx)) { continue; } struct PlayerInfo *player; struct Dungeon *dungeon; player = get_player(plyr_idx); dungeon = get_players_dungeon(player); long i; unsigned long k; i = dungeon->room_kind[RoK_ENTRANCE]; k = 0; while (i != 0) { struct Room *room; room = room_get(i); if (room_is_invalid(room)) { ERRORLOG("Jump to invalid room detected"); break; } i = room->next_of_owner; // Per-room code struct Comp2_UnkStr1 *unkptr; unkptr = &comp->unkarr_A10[(int)plyr_idx]; long n; for (n = 0; n < 64; n++) { struct Coord3d *pos; pos = &unkptr->pos_A[n]; if ((pos->x.val == subtile_coord(room->central_stl_x,0)) && (pos->y.val == subtile_coord(room->central_stl_y,0))) { break; } } if (n == 64) { struct Coord3d *pos; n = unkptr->field_4; unkptr->field_4 = (n + 1) % 64; unkptr->field_0 = game.play_gameturn; pos = &unkptr->pos_A[n]; pos->x.val = subtile_coord(room->central_stl_x,0); pos->y.val = subtile_coord(room->central_stl_y,0); pos->z.val = subtile_coord(1,0); result = 2; } // Per-room code ends k++; if (k > ROOMS_COUNT) { ERRORLOG("Infinite loop detected when sweeping rooms list"); break; } } } return result; }
long computer_check_neutral_places(struct Computer2 *comp, struct ComputerCheck * check) { if (is_newdig_enabled(comp)) return 4; SYNCDBG(8,"Starting"); struct Dungeon *dungeon; dungeon = comp->dungeon; if (dungeon_invalid(dungeon) || !player_has_heart(dungeon->owner)) { SYNCDBG(7,"Computer players %d dungeon in invalid or has no heart",(int)dungeon->owner); return CTaskRet_Unk4; } struct OpponentRelation *oprel; oprel = &comp->opponent_relations[game.neutral_player_num]; struct Room *near_room; struct Coord3d *near_pos; int near_dist; near_room = INVALID_ROOM; near_dist = LONG_MAX; near_pos = &oprel->pos_A[0]; int i; for (i=0; i < COMPUTER_SPARK_POSITIONS_COUNT; i++) { struct Coord3d *place; place = &oprel->pos_A[i]; if ((place->x.val == 0) || (place->y.val == 0)) { continue; } struct Room *room; room = INVALID_ROOM; if (computer_finds_nearest_room_to_pos(comp, &room, place)) { MapSubtlDelta dx,dy; dx = abs((int)room->central_stl_x - (MapSubtlDelta)place->x.stl.num); dy = abs((int)room->central_stl_y - (MapSubtlDelta)place->y.stl.num); if (near_dist > dx+dy) { near_room = room; near_pos = place; near_dist = dx+dy; } } } if (room_is_invalid(near_room)) { return CTaskRet_Unk4; } struct Coord3d endpos; struct Coord3d startpos; endpos.x.val = near_pos->x.val; endpos.y.val = near_pos->y.val; endpos.z.val = near_pos->z.val; startpos.x.val = subtile_coord_center(stl_slab_center_subtile(near_room->central_stl_x)); startpos.y.val = subtile_coord_center(stl_slab_center_subtile(near_room->central_stl_y)); startpos.z.val = subtile_coord(1,0); if (!create_task_dig_to_neutral(comp, startpos, endpos)) { return CTaskRet_Unk4; } near_pos->x.val = 0; near_pos->y.val = 0; near_pos->z.val = 0; return CTaskRet_Unk1; }