PerPlayerFlags action_point_get_players_within(long apt_idx) { //return _DK_action_point_get_players_within(apt_idx); struct ActionPoint *apt; apt = action_point_get(apt_idx); PerPlayerFlags activated; activated = apt->activated; PlayerNumber plyr_idx; for (plyr_idx=0; plyr_idx < PLAYERS_COUNT; plyr_idx++) { struct PlayerInfo *player; player = get_player(plyr_idx); if (player_exists(player)) { if ((activated & (1 << plyr_idx)) == 0) { struct Dungeon *dungeon; dungeon = get_players_dungeon(player); if (dungeon_invalid(dungeon)) { continue; } SYNCDBG(16,"Checking player %d",(int)plyr_idx); if (action_point_is_creature_from_list_within(apt, dungeon->digger_list_start)) { activated |= (1 << plyr_idx); continue; } if (action_point_is_creature_from_list_within(apt, dungeon->creatr_list_start)) { activated |= (1 << plyr_idx); continue; } } } } return activated; }
void update_explored_flags_for_power_sight(struct PlayerInfo *player) { struct Dungeon *dungeon; struct Thing *thing; SYNCDBG(9,"Starting"); //_DK_update_explored_flags_for_power_sight(player); dungeon = get_players_dungeon(player); LbMemorySet(backup_explored, 0, sizeof(backup_explored)); if (dungeon->sight_casted_thing_idx == 0) { return; } thing = thing_get(dungeon->sight_casted_thing_idx); if (!thing_is_object(thing)) { ERRORLOG("Sight thing index %d invalid", (int)dungeon->sight_casted_thing_idx); turn_off_sight_of_evil(player->id_number); dungeon->sight_casted_thing_idx = 0; return; } TRACE_THING(thing); // Fill the backup_explored array store_backup_explored_flags_for_power_sight(player, &thing->mappos); update_vertical_explored_flags_for_power_sight(player, &thing->mappos); update_horizonal_explored_flags_for_power_sight(player, &thing->mappos); }
void store_backup_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; dungeon = get_players_dungeon(player); stl_y = (long)soe_pos->y.stl.num - MAX_SOE_RADIUS; for (soe_y=0; soe_y < 2*MAX_SOE_RADIUS; soe_y++,stl_y++) { 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 (dungeon->soe_explored_flags[soe_y][soe_x]) { struct Map *mapblk; mapblk = get_map_block_at(stl_x, stl_y); if (!map_block_invalid(mapblk)) { if (map_block_revealed(mapblk, player->id_number)) backup_explored[soe_y][soe_x] |= 0x01; if ((mapblk->flags & MapFlg_Unkn04) != 0) backup_explored[soe_y][soe_x] |= 0x02; if ((mapblk->flags & MapFlg_Unkn80) != 0) backup_explored[soe_y][soe_x] |= 0x04; } } } } }
void multiply_creatures(struct PlayerInfo *player) { struct Dungeon *dungeon; dungeon = get_players_dungeon(player); // Copy 'normal' creatures multiply_creatures_in_dungeon_list(dungeon, dungeon->creatr_list_start); // Copy 'special worker' creatures multiply_creatures_in_dungeon_list(dungeon, dungeon->digger_list_start); }
TbBool player_uses_power_hold_audience(PlayerNumber plyr_idx) { struct PlayerInfo *player; player = get_player(plyr_idx); if (!player_exists(player)) { return false; } struct Dungeon *dungeon; dungeon = get_players_dungeon(player); return (dungeon->hold_audience_cast_turn != 0); }
TbBool player_uses_power_obey(PlayerNumber plyr_idx) { struct PlayerInfo *player; player = get_player(plyr_idx); if (!player_exists(player)) { return false; } struct Dungeon *dungeon; dungeon = get_players_dungeon(player); return (dungeon->must_obey_turn != 0); }
TbBool player_uses_power_sight(PlayerNumber plyr_idx) { struct PlayerInfo *player; player = get_player(plyr_idx); if (!player_exists(player)) { return false; } struct Dungeon *dungeon; dungeon = get_players_dungeon(player); return (dungeon->sight_casted_thing_idx > 0); }
void turn_off_power_call_to_arms(PlayerNumber plyr_idx) { //_DK_turn_off_call_to_arms(plyr_idx); if (!player_uses_power_call_to_arms(plyr_idx)) { return; } struct PlayerInfo *player; player = get_player(plyr_idx); { struct Thing *objtng; objtng = thing_get(player->field_43C); set_call_to_arms_as_dying(objtng); struct Dungeon *dungeon; dungeon = get_players_dungeon(player); dungeon->cta_start_turn = 0; } reset_all_players_creatures_affected_by_cta(plyr_idx); }
void add_score_to_high_score_table(void) { struct Dungeon *dungeon; struct PlayerInfo *player; int idx; player = get_my_player(); dungeon = get_players_dungeon(player); idx = add_high_score_entry(dungeon->lvstats.player_score, get_loaded_level_number(), ""); if (idx >= 0) { // Preparing input in the new entry // Note that we're not clearing previous name - this way it may be easily kept unchanged high_score_entry_input_active = idx; high_score_entry_index = strlen(high_score_entry); } else { high_score_entry_input_active = -1; high_score_entry_index = 0; } }
/** * Updates gameplay score for a dungeon belonging to given player. * @return */ TbBool update_dungeon_scores_for_player(struct PlayerInfo *player) { struct Dungeon *dungeon; int i,k; dungeon = get_players_dungeon(player); unsigned long manage_efficiency,max_manage_efficiency; if (dungeon_invalid(dungeon)) { return false; } manage_efficiency = 0; max_manage_efficiency = 0; { manage_efficiency += 40 * compute_dungeon_rooms_attraction_score(dungeon->room_slabs_count[RoK_ENTRANCE], dungeon->field_949, dungeon->field_1485); max_manage_efficiency += 40 * compute_dungeon_rooms_attraction_score(LONG_MAX, LONG_MAX, LONG_MAX); } { manage_efficiency += 40 * compute_dungeon_creature_tactics_score(dungeon->battles_won, dungeon->battles_lost, dungeon->creatures_scavenge_gain, dungeon->creatures_scavenge_lost); max_manage_efficiency += 40 * compute_dungeon_creature_tactics_score(LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX); } { // Compute amount of different types of rooms built unsigned long room_types; room_types = 0; for (i=0; i < ROOM_TYPES_COUNT; i++) { if (dungeon->room_slabs_count[i] > 0) room_types++; } manage_efficiency += 40 * compute_dungeon_rooms_variety_score(room_types, dungeon->total_area); max_manage_efficiency += 40 * compute_dungeon_rooms_variety_score(ROOM_TYPES_COUNT, LONG_MAX); } { manage_efficiency += compute_dungeon_train_research_manufctr_wealth_score(dungeon->total_experience_creatures_gained, dungeon->total_research_points, dungeon->field_1181, dungeon->total_money_owned); max_manage_efficiency += compute_dungeon_train_research_manufctr_wealth_score(LONG_MAX, LONG_MAX, LONG_MAX, LONG_MAX); } unsigned long creatures_efficiency, creatures_mood; unsigned long max_creatures_efficiency, max_creatures_mood; { creatures_efficiency = compute_dungeon_creature_amount_score(dungeon->num_active_creatrs); max_creatures_efficiency = compute_dungeon_creature_amount_score(LONG_MAX); creatures_mood = compute_dungeon_creature_mood_score(dungeon->num_active_creatrs,dungeon->creatures_annoyed); max_creatures_mood = compute_dungeon_creature_mood_score(LONG_MAX,LONG_MAX); } { // Compute total score for this turn i = manage_efficiency + creatures_efficiency; k = max_manage_efficiency + max_creatures_efficiency; dungeon->field_AE9[1] = 1000 * i / k; } { // Compute managing efficiency score i = manage_efficiency - creatures_efficiency; k = max_manage_efficiency - max_creatures_efficiency; if (i < 0) i = 0; long raw_score; raw_score = 1000 * i / k; // Angry creatures may degrade the score by up to 50% raw_score = raw_score / 2 + raw_score * (max_creatures_mood - creatures_mood) / (2*max_creatures_mood); dungeon->field_AE9[0] = raw_score; } { unsigned long gameplay_score; gameplay_score = dungeon->field_AE9[1]; if (gameplay_score <= 1) { WARNLOG("Total score for turn is too low!"); gameplay_score = 1; } dungeon->field_AE9[1] = gameplay_score; } { unsigned long gameplay_score; gameplay_score = dungeon->field_AE9[0]; if (gameplay_score <= 1) { WARNLOG("Managing score for turn is too low!"); gameplay_score = 1; } dungeon->field_AE9[0] = gameplay_score; } { // Check to update max score unsigned long gameplay_score; gameplay_score = dungeon->field_AE9[1]; if (dungeon->max_gameplay_score < gameplay_score) dungeon->max_gameplay_score = gameplay_score; } return true; }
TbBool load_game(long slot_num) { TbFileHandle fh; long file_len; struct PlayerInfo *player; struct Dungeon *dungeon; struct CatalogueEntry *centry; // unsigned char buf[14]; // char cmpgn_fname[CAMPAIGN_FNAME_LEN]; SYNCDBG(6,"Starting"); reset_eye_lenses(); { // Use fname only here - it is overwritten by next use of prepare_file_fmtpath() char *fname; fname = prepare_file_fmtpath(FGrp_Save,saved_game_filename,slot_num); if (!wait_for_cd_to_be_available()) return false; fh = LbFileOpen(fname,Lb_FILE_MODE_READ_ONLY); if (fh == -1) { WARNMSG("Cannot open saved game file \"%s\".",fname); save_catalogue_slot_disable(slot_num); return false; } } file_len = LbFileLengthHandle(fh); if (is_primitive_save_version(file_len)) { //if (LbFileRead(handle, buf, sizeof(buf)) != sizeof(buf)) { LbFileClose(fh); save_catalogue_slot_disable(slot_num); return false; } /*LbFileSeek(fh, (char *)&game.campaign_fname[0] - (char *)&game, Lb_FILE_SEEK_BEGINNING); LbFileRead(fh, cmpgn_fname, CAMPAIGN_FNAME_LEN); cmpgn_fname[CAMPAIGN_FNAME_LEN-1] = '\0'; if (!change_campaign(cmpgn_fname)) { ERRORLOG("Unable to load campaign associated with saved game"); } LbFileClose(fh); WARNMSG("Saved game file \"%s\" has incompatible version; restarting level.",fname); player = get_my_player(); player->field_7 = 0; my_player_number = default_loc_player; player = get_my_player(); game.flagfield_14EA4A = 2; set_flag_byte(&game.system_flags,GSF_NetworkActive,false); player->field_2C = 1; set_selected_level_number(((struct Game *)buf)->load_restart_level); set_continue_level_number(((struct Game *)buf)->continue_level_number); startup_network_game(); return true;*/ } centry = &save_game_catalogue[slot_num]; LbFileSeek(fh, 0, Lb_FILE_SEEK_BEGINNING); // Here is the actual loading if (load_game_chunks(fh,centry) != GLoad_SavedGame) { LbFileClose(fh); WARNMSG("Couldn't correctly load saved game in slot %d.",(int)slot_num); init_lookups(); return false; } LbFileClose(fh); LbStringCopy(game.campaign_fname,campaign.fname,sizeof(game.campaign_fname)); reinit_level_after_load(); output_message(SMsg_GameLoaded, 0, true); pannel_map_update(0, 0, map_subtiles_x+1, map_subtiles_y+1); calculate_moon_phase(false,false); update_extra_levels_visibility(); player = get_my_player(); set_flag_byte(&player->field_3,0x08,false); set_flag_byte(&player->field_3,0x04,false); player->field_4C1 = 0; player->field_4C5 = 0; player->field_7 = 0; PaletteSetPlayerPalette(player, engine_palette); reinitialise_eye_lens(game.numfield_1B); // Update the lights system state light_import_system_state(&gameadd.lightst); // Victory state if (player->victory_state != VicS_Undecided) { frontstats_initialise(); dungeon = get_players_dungeon(player); dungeon->lvstats.player_score = 0; dungeon->lvstats.allow_save_score = 1; } game.loaded_swipe_idx = -1; return 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; } } } } } }
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_checks_hates(struct Computer2 *comp, struct ComputerCheck * check) { struct Dungeon *compdngn; SYNCDBG(8,"Starting"); //return _DK_computer_checks_hates(comp, check); compdngn = comp->dungeon; // Reference values for checking hate int cdngn_creatrs, cdngn_spdiggrs, cdngn_enrancs; cdngn_creatrs = count_creatures_in_dungeon(compdngn); cdngn_spdiggrs = count_diggers_in_dungeon(compdngn); cdngn_enrancs = count_entrances(comp, compdngn->owner); // Now check hate for every player int i; for (i=0; i < PLAYERS_COUNT; i++) { struct PlayerInfo *player; struct Dungeon *dungeon; struct Comp2_UnkStr1 *rel; player = get_player(i); dungeon = get_players_dungeon(player); rel = &comp->unkarr_A10[i]; if (!player_exists(player) || (player->id_number == compdngn->owner) || (player->id_number == game.neutral_player_num)) continue; if (player->field_2C != 1) continue; if (players_are_mutual_allies(compdngn->owner, i)) continue; int hdngn_creatrs, hdngn_spdiggrs, hdngn_enrancs; int hate_reasons; hate_reasons = 0; hdngn_creatrs = count_creatures_in_dungeon(dungeon); hdngn_spdiggrs = count_diggers_in_dungeon(dungeon); // Computers hate players who have more creatures than them if (hdngn_creatrs >= cdngn_creatrs) { hate_reasons++; rel->hate_amount++; } // Computers hate players who have more special diggers than them if (cdngn_spdiggrs / 6 + cdngn_spdiggrs < hdngn_spdiggrs) { hate_reasons++; rel->hate_amount++; } // Computers hate players who can build more rooms than them if (((int)compdngn->total_rooms + (int)compdngn->total_rooms / 6) < (int)dungeon->total_rooms) { hate_reasons++; rel->hate_amount++; } // Computers highly hate players who claimed more entrances than them hdngn_enrancs = count_entrances(comp, i); if (hdngn_enrancs > cdngn_enrancs) { hate_reasons++; rel->hate_amount += 5; } // If no reason to hate the player - hate him randomly for just surviving that long if ((hate_reasons <= 0) && (check->param1 < game.play_gameturn)) { if (ACTION_RANDOM(100) < 20) { rel->hate_amount++; } } } return 4; }