long computer_check_move_creatures_to_best_room(struct Computer2 *comp, struct ComputerCheck * check) { struct Dungeon *dungeon; dungeon = comp->dungeon; SYNCDBG(8,"Starting"); //return _DK_computer_check_move_creatures_to_best_room(comp, check); //TODO check if should be changed to computer_able_to_use_magic() if (!is_power_available(dungeon->owner, PwrK_HAND)) { return 4; } int num_to_move; num_to_move = check->param1 * dungeon->num_active_creatrs / 100; if (num_to_move <= 0) { SYNCDBG(8,"No creatures to move, active %d percentage %d", (int)dungeon->num_active_creatrs, (int)check->param1); return 4; } if (is_task_in_progress(comp, CTT_MoveCreatureToRoom)) { return 4; } if (!create_task_move_creatures_to_room(comp, 0, num_to_move)) { return 4; } SYNCDBG(8,"Added task to move %d creatures to best room", (int)num_to_move); return 1; }
long computer_check_for_expand_room(struct Computer2 *comp, struct ComputerCheck * check) { SYNCDBG(8,"Starting"); //return _DK_computer_check_for_expand_room(comp, check); struct Dungeon *dungeon; dungeon = comp->dungeon; if (dungeon_invalid(dungeon)) { ERRORLOG("Invalid computer players dungeon"); return 0; } long around_start; around_start = ACTION_RANDOM(119); // Don't work when placing rooms; we could place in an area for room by mistake if (is_task_in_progress(comp, CTT_PlaceRoom) || is_task_in_progress(comp, CTT_CheckRoomDug)) { SYNCDBG(8,"No rooms expansion - colliding task already in progress"); return 0; } if (4 * dungeon->creatures_total_pay / 3 >= dungeon->total_money_owned) { SYNCDBG(8,"No rooms expansion - we don't even have money for payday"); return 0; } const struct ExpandRooms *expndroom; for (expndroom = &expand_rooms[0]; expndroom->rkind != RoK_NONE; expndroom++) { if (computer_check_for_expand_room_kind(comp, check, expndroom->rkind, expndroom->max_slabs, around_start)) { return 1; } } SYNCDBG(8,"No rooms found for expansion"); return 0; }
short move_to_position(struct Thing *creatng) { CreatureStateCheck callback; struct CreatureControl *cctrl; struct StateInfo *stati; long move_result; CrCheckRet state_check; long speed; TRACE_THING(creatng); cctrl = creature_control_get_from_thing(creatng); speed = get_creature_speed(creatng); SYNCDBG(18,"Starting to move %s index %d into (%d,%d)",thing_model_name(creatng),(int)creatng->index,(int)cctrl->moveto_pos.x.stl.num,(int)cctrl->moveto_pos.y.stl.num); // Try teleporting the creature if (creature_move_to_using_teleport(creatng, &cctrl->moveto_pos, speed)) { SYNCDBG(8,"Teleporting %s index %d owner %d into (%d,%d) for %s",thing_model_name(creatng),(int)creatng->index,(int)creatng->owner, (int)cctrl->moveto_pos.x.stl.num,(int)cctrl->moveto_pos.y.stl.num,creature_state_code_name(creatng->continue_state)); return 1; } move_result = creature_move_to(creatng, &cctrl->moveto_pos, speed, cctrl->move_flags, 0); state_check = CrCkRet_Available; stati = get_thing_continue_state_info(creatng); if (!state_info_invalid(stati)) { callback = stati->move_check; if (callback != NULL) { SYNCDBG(18,"Doing move check callback for continue state %s",creature_state_code_name(creatng->continue_state)); state_check = callback(creatng); } } if (state_check == CrCkRet_Available) { // If moving was successful if (move_result == 1) { // Back to "main state" internal_set_thing_state(creatng, creatng->continue_state); return CrStRet_Modified; } // If moving failed, do a reset if (move_result == -1) { CrtrStateId cntstat; cntstat = creatng->continue_state; internal_set_thing_state(creatng, cntstat); set_start_state(creatng); SYNCDBG(8,"Couldn't move %s to place required for state %s; reset to state %s",thing_model_name(creatng),creature_state_code_name(cntstat),creatrtng_actstate_name(creatng)); return CrStRet_ResetOk; } // If continuing the job, check for job stress process_job_stress_and_going_postal(creatng); } switch (state_check) { case CrCkRet_Deleted: return CrStRet_Deleted; case CrCkRet_Available: return CrStRet_Modified; default: return CrStRet_ResetOk; } }
long computer_check_move_creatures_to_best_room(struct Computer2 *comp, struct ComputerCheck * check) { struct Dungeon *dungeon; dungeon = comp->dungeon; SYNCDBG(8,"Starting for player %d",(int)dungeon->owner); int num_to_move; num_to_move = check->param1 * dungeon->num_active_creatrs / 100; if (num_to_move <= 0) { SYNCDBG(8,"No player %d creatures to move, active %d percentage %d", (int)dungeon->owner,(int)dungeon->num_active_creatrs,(int)check->param1); return CTaskRet_Unk4; } if (computer_able_to_use_magic(comp, PwrK_HAND, 1, num_to_move) != 1) { return CTaskRet_Unk4; } // If there's already task in progress which uses hand, then don't add more // content of the hand could be used by wrong task by mistake if (is_task_in_progress_using_hand(comp)) { return CTaskRet_Unk4; } if (!create_task_move_creatures_to_room(comp, 0, num_to_move)) { return CTaskRet_Unk4; } SYNCDBG(8,"Added player %d task to move %d creatures to best room",(int)dungeon->owner,(int)num_to_move); return CTaskRet_Unk1; }
long computer_check_for_accelerate(struct Computer2 *comp, struct ComputerCheck * check) { static RoomKind workers_in_rooms[] = {RoK_LIBRARY,RoK_LIBRARY,RoK_WORKSHOP,RoK_TRAINING,RoK_SCAVENGER}; struct Thing *thing; long i,n; SYNCDBG(8,"Starting"); //return _DK_computer_check_for_accelerate(comp, check); if (computer_able_to_use_magic(comp, PwrK_SPEEDCRTR, 8, 3) != 1) { return 4; } n = check->param1 % (sizeof(workers_in_rooms)/sizeof(workers_in_rooms[0])); if (n <= 0) n = ACTION_RANDOM(sizeof(workers_in_rooms)/sizeof(workers_in_rooms[0])); for (i=0; i < sizeof(workers_in_rooms)/sizeof(workers_in_rooms[0]); i++) { thing = computer_check_creatures_in_dungeon_rooms_of_kind_for_accelerate(comp, workers_in_rooms[n]); if (!thing_is_invalid(thing)) { SYNCDBG(8,"Cast on thing %d",(int)thing->index); return 1; } n = (n+1) % (sizeof(workers_in_rooms)/sizeof(workers_in_rooms[0])); } return 4; }
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); }
/** * Allocates graphics heap. */ TbBool setup_heap_memory(void) { long i; SYNCDBG(8,"Starting"); if (heap != NULL) { SYNCDBG(0,"Freeing old Graphics heap"); LbMemoryFree(heap); heap = NULL; } i = mem_size; heap_size = get_best_sound_heap_size(i); while ( 1 ) { heap = LbMemoryAlloc(heap_size); if (heap != NULL) break; i = get_smaller_memory_amount(i); if (i > 8) { heap_size = get_best_sound_heap_size(i); } else { if (heap_size < 524288) { ERRORLOG("Unable to allocate Graphic Heap"); heap_size = 0; return false; } heap_size -= 16384; } } SYNCMSG("GraphicsHeap Size %d", heap_size); return true; }
TbBool setup_person_move_to_position_f(struct Thing *thing, MapSubtlCoord stl_x, MapSubtlCoord stl_y, NaviRouteFlags flags, const char *func_name) { struct CreatureControl *cctrl; struct Coord3d locpos; SYNCDBG(18,"%s: Moving %s index %d to (%d,%d)",func_name,thing_model_name(thing),(int)thing->index,(int)stl_x,(int)stl_y); TRACE_THING(thing); locpos.x.val = subtile_coord_center(stl_x); locpos.y.val = subtile_coord_center(stl_y); locpos.z.val = thing->mappos.z.val; locpos.z.val = get_thing_height_at(thing, &locpos); cctrl = creature_control_get_from_thing(thing); if (creature_control_invalid(cctrl)) { WARNLOG("%s: Tried to move invalid creature to (%d,%d)",func_name,(int)stl_x,(int)stl_y); return false; } if (thing_in_wall_at(thing, &locpos)) { SYNCDBG(16,"%s: The %s would be trapped in wall at (%d,%d)",func_name,thing_model_name(thing),(int)stl_x,(int)stl_y); return false; } if (!creature_can_navigate_to_with_storage_f(thing, &locpos, flags, func_name)) { SYNCDBG(19,"%s: The %s cannot reach subtile (%d,%d)",func_name,thing_model_name(thing),(int)stl_x,(int)stl_y); return false; } cctrl->move_flags = flags; internal_set_thing_state(thing, CrSt_MoveToPosition); cctrl->moveto_pos.x.val = locpos.x.val; cctrl->moveto_pos.y.val = locpos.y.val; cctrl->moveto_pos.z.val = locpos.z.val; SYNCDBG(19,"%s: Done",func_name); return true; }
TbBool setup_person_move_close_to_position(struct Thing *thing, MapSubtlCoord stl_x, MapSubtlCoord stl_y, NaviRouteFlags flags) { struct CreatureControl *cctrl; struct Coord3d trgpos; struct Coord3d navpos; SYNCDBG(18,"Moving %s index %d to (%d,%d)",thing_model_name(thing),(int)thing->index,(int)stl_x,(int)stl_y); trgpos.x.val = subtile_coord_center(stl_x); trgpos.y.val = subtile_coord_center(stl_y); trgpos.z.val = thing->mappos.z.val; cctrl = creature_control_get_from_thing(thing); if (creature_control_invalid(cctrl)) { WARNLOG("Tried to move invalid creature to (%d,%d)",(int)stl_x,(int)stl_y); return false; } get_nearest_navigable_point_for_thing(thing, &trgpos, &navpos, flags); if (!creature_can_navigate_to_with_storage(thing, &navpos, flags)) { SYNCDBG(19,"The %s cannot reach subtile (%d,%d)",thing_model_name(thing),(int)stl_x,(int)stl_y); return false; } cctrl->move_flags = flags; internal_set_thing_state(thing, CrSt_MoveToPosition); cctrl->moveto_pos.x.val = navpos.x.val; cctrl->moveto_pos.y.val = navpos.y.val; cctrl->moveto_pos.z.val = navpos.z.val; return true; }
/** * Draws the crucial warning messages on screen. * Requires the screen to be locked before. */ TbBool draw_onscreen_direct_messages(void) { unsigned int msg_pos; SYNCDBG(5,"Starting"); // Display in-game message for debug purposes if ((onscreen_msg_turns > 0) || erstat_check()) { if ( LbScreenIsLocked() ) LbTextDraw(260*units_per_pixel/16, 0*units_per_pixel/16, onscreen_msg_text); onscreen_msg_turns--; } msg_pos = 200; if ((game.system_flags & GSF_NetGameNoSync) != 0) { ERRORLOG("OUT OF SYNC (GameTurn %7d)", game.play_gameturn); if ( LbScreenIsLocked() ) LbTextDraw(260*units_per_pixel/16, msg_pos*units_per_pixel/16, "OUT OF SYNC"); msg_pos += 20; } if ((game.system_flags & GSF_NetSeedNoSync) != 0) { ERRORLOG("SEED OUT OF SYNC (GameTurn %7d)", game.play_gameturn); if ( LbScreenIsLocked() ) LbTextDraw(260*units_per_pixel/16, msg_pos*units_per_pixel/16, "SEED OUT OF SYNC"); msg_pos += 20; } SYNCDBG(18,"Finished"); return true; }
void turn_off_menu(MenuID mnu_idx) { struct GuiMenu *gmnu; long menu_num; SYNCDBG(8,"Menu ID %d",(int)mnu_idx); if ((mnu_idx == GMnu_VIDEO) || (mnu_idx == GMnu_SOUND)) save_settings(); menu_num = menu_id_to_number(mnu_idx); SYNCDBG(8,"Menu number %d",(int)menu_num); if (menu_num >= 0) { if (game_is_busy_doing_gui_string_input()) { if (input_button->gmenu_idx == menu_num) kill_button_area_input(); } gmnu = get_active_menu(menu_num); gmnu->visible = 3; if (update_menu_fade_level(gmnu) == -1) { kill_menu(gmnu); remove_from_menu_stack(gmnu->ident); } } }
/** * Loads the language-specific strings data for the current campaign. */ TbBool setup_campaign_strings_data(struct GameCampaign *campgn) { char *strings_data_end; char *fname; short result; long filelen; SYNCDBG(18,"Starting"); fname = prepare_file_path(FGrp_Main,campgn->strings_fname); filelen = LbFileLengthRnc(fname); if (filelen <= 0) { ERRORLOG("Campaign Strings file does not exist or can't be opened"); return false; } campgn->strings_data = (char *)LbMemoryAlloc(filelen + 256); if (campgn->strings_data == NULL) { ERRORLOG("Can't allocate memory for Campaign Strings data"); return false; } strings_data_end = campgn->strings_data+filelen+255; long loaded_size; loaded_size = LbFileLoadAt(fname, campgn->strings_data); if (loaded_size < 16) { ERRORLOG("Campaign Strings file couldn't be loaded or is too small"); return false; } // Resetting all values to empty strings reset_strings(campgn->strings); // Analyzing strings data and filling correct values result = create_strings_list(campgn->strings, campgn->strings_data, strings_data_end); SYNCDBG(19,"Finished"); return result; }
TbBool good_setup_loot_research_room(struct Thing *thing, long dngn_id) { struct CreatureControl *cctrl; struct Room *room; room = find_random_room_creature_can_navigate_to(thing, dngn_id, RoK_LIBRARY, NavRtF_Default); if (room_is_invalid(room)) { SYNCDBG(6,"No accessible player %d library found",(int)dngn_id); return false; } struct Coord3d pos; if (!find_random_valid_position_for_thing_in_room(thing, room, &pos)) { SYNCDBG(6,"No position for %s index %d in %s owned by player %d", thing_model_name(thing),(int)thing->index,room_code_name(room->kind),(int)room->owner); return false; } if (!setup_person_move_to_coord(thing, &pos, NavRtF_Default)) { SYNCDBG(6,"Cannot setup move %s index %d to %s owned by player %d", thing_model_name(thing),(int)thing->index,room_code_name(room->kind),(int)room->owner); return false; } cctrl = creature_control_get_from_thing(thing); thing->continue_state = CrSt_CreatureSearchForSpellToStealInRoom; cctrl->target_room_id = room->index; return true; }
CrCheckRet process_scavenge_function(struct Thing *calltng) { SYNCDBG(18,"Starting for %s owner %d",thing_model_name(calltng),(int)calltng->owner); //return _DK_process_scavenge_function(thing); struct CreatureControl *callctrl; callctrl = creature_control_get_from_thing(calltng); struct Dungeon *calldngn; struct Room *room; calldngn = get_dungeon(calltng->owner); room = get_room_creature_works_in(calltng); if ( !room_still_valid_as_type_for_thing(room, RoK_SCAVENGER, calltng) ) { WARNLOG("Room %s owned by player %d is bad work place for %s owned by played %d",room_code_name(room->kind),(int)room->owner,thing_model_name(calltng),(int)calltng->owner); set_start_state(calltng); return CrCkRet_Continue; } struct CreatureStats *crstat; crstat = creature_stats_get_from_thing(calltng); if (!player_can_afford_to_scavenge_creature(calltng)) { if (is_my_player_number(calltng->owner)) output_message(SMsg_NoGoldToScavenge, 500, 1); set_start_state(calltng); return CrCkRet_Continue; } if (calldngn->scavenge_counters_turn != game.play_gameturn) { reset_scavenge_counts(calldngn); } long work_value; work_value = compute_creature_work_value(crstat->scavenge_value*256, room->efficiency, callctrl->explevel); work_value = process_work_speed_on_work_value(calltng, work_value); SYNCDBG(9,"The %s index %d owner %d produced %d scavenge points",thing_model_name(calltng),(int)calltng->index,(int)calltng->owner,(int)work_value); struct Thing *scavtng; scavtng = get_scavenger_target(calltng); if (!thing_is_invalid(scavtng)) { process_scavenge_creature_from_level(scavtng, calltng, work_value); } else if (can_scavenge_creature_from_pool(calldngn, calltng->model)) { process_scavenge_creature_from_pool(calltng, work_value); } else { if (crstat->entrance_force) { calldngn->field_1485++; } return 0; } callctrl->field_82++; if (callctrl->field_82 > game.scavenge_cost_frequency) { callctrl->field_82 -= game.scavenge_cost_frequency; if (take_money_from_dungeon(calltng->owner, crstat->scavenger_cost, 1) < 0) { ERRORLOG("Cannot take %d gold from dungeon %d",(int)crstat->scavenger_cost,(int)calltng->owner); } create_price_effect(&calltng->mappos, calltng->owner, crstat->scavenger_cost); } return 0; }
void process_creature_instance(struct Thing *thing) { struct CreatureControl *cctrl; struct InstanceInfo *inst_inf; SYNCDBG(19,"Starting for %s index %d instance %d",thing_model_name(thing),(int)thing->index,(int)cctrl->instance_id); TRACE_THING(thing); cctrl = creature_control_get_from_thing(thing); if (cctrl->instance_id != CrInst_NULL) { cctrl->inst_turn++; if (cctrl->inst_turn == cctrl->inst_action_turns) { inst_inf = creature_instance_info_get(cctrl->instance_id); if (inst_inf->func_cb != NULL) { SYNCDBG(18,"Executing instance %d for %s index %d.",(int)cctrl->instance_id,thing_model_name(thing),(int)thing->index); inst_inf->func_cb(thing, inst_inf->func_params); } } if (cctrl->inst_turn >= cctrl->inst_total_turns) { if (cctrl->inst_repeat) { cctrl->inst_turn--; cctrl->inst_repeat = 0; return; } cctrl->instance_use_turn[cctrl->instance_id] = game.play_gameturn; cctrl->instance_id = CrInst_NULL; } cctrl->inst_repeat = 0; } }
/** * Removes item from the amount of crates stored in workshops. * @param owner * @param tngclass * @param tngmodel * @return Gives WrkCrtS_None if no crate was found, WrkCrtS_Offmap if offmap crate was used, WrkCrtS_Stored if crate from workshop was used. * @note was named remove_workshop_item() */ int remove_workshop_item_from_amount_stored_f(PlayerNumber plyr_idx, ThingClass tngclass, ThingModel tngmodel, unsigned short flags, const char *func_name) { SYNCDBG(18,"%s: Starting",func_name); struct Dungeon *dungeon; dungeon = get_players_num_dungeon_f(plyr_idx,func_name); if (dungeon_invalid(dungeon)) { ERRORLOG("%s: Can't remove item; player %d has no dungeon.",func_name,(int)plyr_idx); return WrkCrtS_None; } long amount; amount = 0; switch (tngclass) { case TCls_Trap: if ((flags & WrkCrtF_NoStored) == 0) { amount = dungeon->trap_amount_stored[tngmodel]; } if (amount > 0) { SYNCDBG(8,"%s: Removing stored trap %s",func_name,trap_code_name(tngmodel)); dungeon->trap_amount_stored[tngmodel] = amount - 1; return WrkCrtS_Stored; } if ((flags & WrkCrtF_NoOffmap) == 0) { amount = dungeon->trap_amount_offmap[tngmodel]; } if (amount > 0) { SYNCDBG(8,"%s: Removing offmap trap %s",func_name,trap_code_name(tngmodel)); dungeon->trap_amount_offmap[tngmodel] = amount - 1; return WrkCrtS_Offmap; } ERRORLOG("%s: Trap %s not available",func_name,trap_code_name(tngmodel)); break; case TCls_Door: if ((flags & WrkCrtF_NoStored) == 0) { amount = dungeon->door_amount_stored[tngmodel]; } if (amount > 0) { SYNCDBG(8,"%s: Removing stored door %s",func_name,door_code_name(tngmodel)); dungeon->door_amount_stored[tngmodel] = amount - 1; return WrkCrtS_Stored; } if ((flags & WrkCrtF_NoOffmap) == 0) { amount = dungeon->door_amount_offmap[tngmodel]; } if (amount > 0) { SYNCDBG(8,"%s: Removing offmap door %s",func_name,door_code_name(tngmodel)); dungeon->door_amount_offmap[tngmodel] = amount - 1; return WrkCrtS_Offmap; } ERRORLOG("%s: Door %s not available",func_name,door_code_name(tngmodel)); break; default: ERRORLOG("%s: Can't remove item; illegal item class %d",func_name,(int)tngclass); break; } return WrkCrtS_None; }
struct Thing *select_scavenger_target(const struct Thing *calltng) { long weakpts; struct Thing *weaktng; weaktng = INVALID_THING; weakpts = LONG_MAX; struct Thing *thing; unsigned long k; int i; SYNCDBG(18,"Starting"); const struct StructureList *slist; slist = get_list_for_thing_class(TCls_Creature); k = 0; i = slist->index; while (i != 0) { thing = thing_get(i); if (thing_is_invalid(thing)) { ERRORLOG("Jump to invalid thing detected"); break; } i = thing->next_of_class; // Per-thing code if (thing_is_valid_scavenge_target(calltng, thing)) { SYNCDBG(18,"The %s index %d owner %d is valid target for %s index %d owner %d", thing_model_name(thing),(int)thing->index,(int)thing->owner, thing_model_name(calltng),(int)calltng->index,(int)calltng->owner); struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(thing); if (game.play_gameturn - cctrl->temple_cure_gameturn > game.temple_scavenge_protection_turns) { long thingpts; thingpts = calculate_correct_creature_scavenge_required(thing, calltng->owner); if (weakpts > thingpts) { weakpts = thingpts; weaktng = thing; } } } // Per-thing code ends k++; if (k > slist->count) { ERRORLOG("Infinite loop detected when sweeping things list"); break; } } SYNCDBG(18,"The weakest valid target for %s index %d owner %d is %s index %d owner %d", thing_model_name(calltng),(int)calltng->index,(int)calltng->owner, thing_model_name(weaktng),(int)weaktng->index,(int)weaktng->owner); return weaktng; }
TbBool load_trapdoor_config_file(const char *textname, const char *fname, unsigned short flags) { char *buf; long len; TbBool result; SYNCDBG(0,"%s %s file \"%s\".",((flags & CnfLd_ListOnly) == 0)?"Reading":"Parsing",textname,fname); len = LbFileLengthRnc(fname); if (len < MIN_CONFIG_FILE_SIZE) { if ((flags & CnfLd_IgnoreErrors) == 0) WARNMSG("The %s file \"%s\" doesn't exist or is too small.",textname,fname); return false; } if (len > MAX_CONFIG_FILE_SIZE) { if ((flags & CnfLd_IgnoreErrors) == 0) WARNMSG("The %s file \"%s\" is too large.",textname,fname); return false; } buf = (char *)LbMemoryAlloc(len+256); if (buf == NULL) return false; // Loading file data len = LbFileLoadAt(fname, buf); result = (len > 0); // Parse blocks of the config file if (result) { result = parse_trapdoor_common_blocks(buf, len, textname, flags); if ((flags & CnfLd_AcceptPartial) != 0) result = true; if (!result) WARNMSG("Parsing %s file \"%s\" common blocks failed.",textname,fname); } if (result) { result = parse_trapdoor_trap_blocks(buf, len, textname, flags); if ((flags & CnfLd_AcceptPartial) != 0) result = true; if (!result) WARNMSG("Parsing %s file \"%s\" trap blocks failed.",textname,fname); } if (result) { result = parse_trapdoor_door_blocks(buf, len, textname, flags); if ((flags & CnfLd_AcceptPartial) != 0) result = true; if (!result) WARNMSG("Parsing %s file \"%s\" door blocks failed.",textname,fname); } //Freeing and exiting LbMemoryFree(buf); SYNCDBG(19,"Done"); return result; }
long computer_check_move_creatures_to_room(struct Computer2 *comp, struct ComputerCheck * check) { struct Dungeon *dungeon; struct Room *room; dungeon = comp->dungeon; SYNCDBG(8,"Checking player %d for move to %s", (int)dungeon->owner, room_code_name(check->param2)); int num_to_move; num_to_move = check->param1 * dungeon->num_active_creatrs / 100; if (num_to_move <= 0) { SYNCDBG(8,"No creatures to move, active %d percentage %d", (int)dungeon->num_active_creatrs, (int)check->param1); return CTaskRet_Unk4; } if (computer_able_to_use_magic(comp, PwrK_HAND, 1, num_to_move) != 1) { return CTaskRet_Unk4; } // If there's already task in progress which uses hand, then don't add more // content of the hand could be used by wrong task by mistake if (is_task_in_progress_using_hand(comp)) { return CTaskRet_Unk4; } unsigned long k; long i; k = 0; i = dungeon->room_kind[check->param2]; while (i != 0) { room = room_get(i); if (room_is_invalid(room)) { ERRORLOG("Jump to invalid room detected"); break; } i = room->next_of_owner; // Per-room code if (room->total_capacity > room->used_capacity) { int num_to_move_fit; num_to_move_fit = min(num_to_move, room->total_capacity - room->used_capacity); if (create_task_move_creatures_to_room(comp, room->index, num_to_move_fit)) { SYNCDBG(8,"Added task to move %d creatures to %s index %d", (int)num_to_move_fit,room_code_name(room->kind),(int)room->index); return CTaskRet_Unk1; } } // Per-room code ends k++; if (k > ROOMS_COUNT) { ERRORLOG("Infinite loop detected when sweeping rooms list"); break; } } return CTaskRet_Unk4; }
/** * Wander the given creature to a random digger belonging to given player. * Originally was good_setup_wander_to_imp. * @param wanderer * @param dngn_id * @return */ TbBool good_setup_wander_to_spdigger(struct Thing *wanderer, long dngn_id) { struct Dungeon *dungeon; SYNCDBG(7,"Starting"); dungeon = get_dungeon(dngn_id); if ( setup_wanderer_move_to_random_creature_from_list(dungeon->digger_list_start,wanderer) ) { wanderer->continue_state = CrSt_GoodDoingNothing; return true; } SYNCDBG(4,"Cannot wander to player %d creatures",(int)dngn_id); return false; }
long computer_check_move_creatures_to_room(struct Computer2 *comp, struct ComputerCheck * check) { struct Dungeon *dungeon; struct Room *room; dungeon = comp->dungeon; SYNCDBG(8,"Checking player %d for move to %s", (int)dungeon->owner, room_code_name(check->param2)); //return _DK_computer_check_move_creatures_to_room(comp, check); //TODO check if should be changed to computer_able_to_use_magic() if (!is_power_available(dungeon->owner, PwrK_HAND)) { return 4; } int num_to_move; num_to_move = check->param1 * dungeon->num_active_creatrs / 100; if (num_to_move <= 0) { SYNCDBG(8,"No creatures to move, active %d percentage %d", (int)dungeon->num_active_creatrs, (int)check->param1); return 4; } if (is_task_in_progress(comp, CTT_MoveCreatureToRoom)) { return 4; } unsigned long k; long i; k = 0; i = dungeon->room_kind[check->param2]; while (i != 0) { room = room_get(i); if (room_is_invalid(room)) { ERRORLOG("Jump to invalid room detected"); break; } i = room->next_of_owner; // Per-room code if (room->total_capacity > room->used_capacity) { if (create_task_move_creatures_to_room(comp, room->index, num_to_move)) { SYNCDBG(8,"Added task to move %d creatures to %s index %d", (int)num_to_move,room_code_name(room->kind),(int)room->index); return 1; } } // Per-room code ends k++; if (k > ROOMS_COUNT) { ERRORLOG("Infinite loop detected when sweeping rooms list"); break; } } return 4; }
long load_texture_anim_file(void) { SYNCDBG(8,"Starting"); //return _DK_load_anim_file(); char *fname; static const char textname[] = "animated tmap"; fname = prepare_file_path(FGrp_StdData,"tmapanim.dat"); SYNCDBG(0,"Reading %s file \"%s\".",textname,fname); if (LbFileLoadAt(fname, game.texture_animation) != sizeof(game.texture_animation)) { return false; } return true; }
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 setup_move_to_new_training_position(struct Thing *thing, struct Room *room, unsigned long restart) { struct CreatureControl *cctrl; struct CreatureStats *crstat; struct Thing *prtng; struct CreatureControl *prctrl; struct Coord3d pos; long i; SYNCDBG(8,"Starting for %s",thing_model_name(thing)); //_DK_setup_move_to_new_training_position(thing, room, a3); cctrl = creature_control_get_from_thing(thing); crstat = creature_stats_get_from_thing(thing); if ( restart ) cctrl->training.search_timeout = 50; // Try partner training if ((crstat->partner_training > 0) && (ACTION_RANDOM(100) < crstat->partner_training)) { prtng = get_creature_in_training_room_which_could_accept_partner(room, thing); if (!thing_is_invalid(prtng)) { SYNCDBG(7,"The %s found %s as training partner.",thing_model_name(thing),thing_model_name(prtng)); prctrl = creature_control_get_from_thing(prtng); prctrl->training.mode = CrTrMd_PartnerTraining; prctrl->training.train_timeout = 75; prctrl->training.partner_idx = thing->index; prctrl->training.partner_creation = thing->creation_turn; cctrl->training.mode = CrTrMd_PartnerTraining; cctrl->training.train_timeout = 75; cctrl->training.partner_idx = prtng->index; cctrl->training.partner_creation = prtng->creation_turn; return; } } // No partner - train at some random position cctrl->training.mode = CrTrMd_SearchForTrainPost; if (find_random_valid_position_for_thing_in_room(thing, room, &pos)) { SYNCDBG(8,"Going to train at (%d,%d)",(int)pos.x.stl.num,(int)pos.y.stl.num); i = get_subtile_number(pos.x.stl.num,pos.y.stl.num); setup_training_move(thing, i); } else { SYNCDBG(8,"No new position found, staying at (%d,%d)",(int)cctrl->moveto_pos.x.stl.num,(int)cctrl->moveto_pos.x.stl.num); } if (cctrl->instance_id == CrInst_NULL) { set_creature_instance(thing, CrInst_SWING_WEAPON_SWORD, 1, 0, 0); } }
void process_3d_sounds(void) { SYNCDBG(9,"Starting"); increment_sample_times(); process_sound_samples(); process_sound_emitters(); }
TbBool attempt_job_sleep_in_lair_near_pos(struct Thing *creatng, MapSubtlCoord stl_x, MapSubtlCoord stl_y, CreatureJob new_job) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); SYNCDBG(16,"Starting for %s (owner %d) and job %s",thing_model_name(creatng),(int)creatng->owner,creature_job_code_name(new_job)); struct Room *room; room = subtile_room_get(stl_x, stl_y); if (get_arrive_at_state_for_job(new_job) == CrSt_Unused) { ERRORLOG("No arrive at state for job %s in %s room",creature_job_code_name(new_job),room_code_name(room->kind)); return false; } cctrl->slap_turns = 0; cctrl->max_speed = calculate_correct_creature_maxspeed(creatng); if (creature_has_lair_room(creatng) && (room->index == cctrl->lair_room_id)) { if (creature_move_to_home_lair(creatng)) { creatng->continue_state = CrSt_CreatureGoingHomeToSleep; return 1; } } struct Coord3d pos; if (find_first_valid_position_for_thing_in_room(creatng, room, &pos) && setup_person_move_to_coord(creatng, &pos, NavRtF_Default)) { creatng->continue_state = CrSt_CreatureChangeLair; cctrl->target_room_id = room->index; return 1; } return 0; }
TbBool attempt_job_work_in_room_for_player(struct Thing *creatng, PlayerNumber plyr_idx, CreatureJob new_job) { struct Coord3d pos; struct Room *room; RoomKind rkind; rkind = get_room_for_job(new_job); SYNCDBG(6,"Starting for %s (owner %d) and job %s in %s room",thing_model_name(creatng),(int)creatng->owner,creature_job_code_name(new_job),room_code_name(rkind)); if ((get_flags_for_job(new_job) & JoKF_NeedsCapacity) != 0) { room = find_nearest_room_for_thing_with_spare_capacity(creatng, creatng->owner, rkind, NavRtF_Default, 1); } else { room = find_nearest_room_for_thing(creatng, creatng->owner, rkind, NavRtF_Default); } if (room_is_invalid(room)) { return false; } if (!find_random_valid_position_for_thing_in_room(creatng, room, &pos)) { return false; } if (get_arrive_at_state_for_job(new_job) == CrSt_Unused) { ERRORLOG("No arrive at state for job %s in %s room",creature_job_code_name(new_job),room_code_name(room->kind)); return false; } if (!setup_person_move_to_coord(creatng, &pos, NavRtF_Default)) { return false; } struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); creatng->continue_state = get_arrive_at_state_for_job(new_job); cctrl->target_room_id = room->index; return true; }
TbBool send_creature_to_job_near_position(struct Thing *creatng, MapSubtlCoord stl_x, MapSubtlCoord stl_y, CreatureJob new_job) { SYNCDBG(6,"Starting for %s (owner %d) and job %s",thing_model_name(creatng),(int)creatng->owner,creature_job_code_name(new_job)); struct CreatureJobConfig *jobcfg; jobcfg = get_config_for_job(new_job); if (jobcfg->func_cord_assign != NULL) { if (jobcfg->func_cord_assign(creatng, stl_x, stl_y, new_job)) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); // Set computer control accordingly to job flags if ((get_flags_for_job(new_job) & JoKF_NoSelfControl) != 0) { cctrl->flgfield_1 |= CCFlg_NoCompControl; } else { cctrl->flgfield_1 &= ~CCFlg_NoCompControl; } // If a new task isn't a work-in-group thing, remove the creature from group if ((get_flags_for_job(new_job) & JoKF_NoGroups) != 0) { if (creature_is_group_member(creatng)) { remove_creature_from_group(creatng); } } return true; } } else { ERRORLOG("Cannot start %s for %s (owner %d); job has no coord-based assign",creature_job_code_name(new_job),thing_model_name(creatng),(int)creatng->owner); } return false; }
/** * Tries to assign one of creature's preferred jobs to it. * Starts at random job, to make sure all the jobs have equal chance of being selected. * @param creatng The creature to assign a job to. * @param jobpref Job preference flags. */ TbBool attempt_job_preference(struct Thing *creatng, long jobpref) { //return _DK_attempt_job_preference(creatng, jobpref); long i,n; // Start checking at random job if (crtr_conf.jobs_count < 1) { return false; } n = ACTION_RANDOM(crtr_conf.jobs_count); for (i=0; i < crtr_conf.jobs_count; i++, n = (n+1)%crtr_conf.jobs_count) { if (n == 0) continue; CreatureJob new_job; new_job = 1 << (n-1); if ((jobpref & new_job) != 0) { SYNCDBG(19,"Check job %s",creature_job_code_name(new_job)); if (creature_can_do_job_for_player(creatng, creatng->owner, new_job, JobChk_None)) { if (send_creature_to_job_for_player(creatng, creatng->owner, new_job)) { return true; } } } } return false; }
void setup_exchange_player_number(void) { struct PlayerInfo *player; struct Packet *pckt; int i,k; SYNCDBG(6,"Starting"); clear_packets(); player = get_my_player(); pckt = get_packet_direct(my_player_number); set_packet_action(pckt, PckA_InitPlayerNum, player->field_2C, settings.video_rotate_mode, 0, 0); if (LbNetwork_Exchange(pckt)) ERRORLOG("Network Exchange failed"); k = 0; for (i=0; i<NET_PLAYERS_COUNT; i++) { pckt = get_packet_direct(i); if ((net_player_info[i].active) && (pckt->action == PckA_InitPlayerNum)) { player = get_player(k); player->id_number = k; player->field_0 |= 0x01; if (pckt->field_8 < 1) player->field_4B5 = 2; else player->field_4B5 = 5; player->field_2C = pckt->field_6; init_player(player, 0); strncpy(player->field_15,net_player[i].name,sizeof(struct TbNetworkPlayerName)); k++; } } }