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 creature_can_take_salary_near_pos(const struct Thing *creatng, MapSubtlCoord stl_x, MapSubtlCoord stl_y, CreatureJob new_job, unsigned long flags) { struct Room *room; room = subtile_room_get(stl_x, stl_y); if (room->used_capacity < 1) { 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); }
short creature_scavenged_disappear(struct Thing *thing) { struct CreatureControl *cctrl; struct Dungeon *dungeon; struct Room *room; struct Coord3d pos; long stl_x, stl_y; long i; //return _DK_creature_scavenged_disappear(thing); cctrl = creature_control_get_from_thing(thing); cctrl->byte_9A--; if (cctrl->byte_9A > 0) { if ((cctrl->byte_9A == 7) && (cctrl->byte_9B < PLAYERS_COUNT)) { create_effect(&thing->mappos, get_scavenge_effect_element(cctrl->byte_9B), thing->owner); } return 0; } // We don't really have to convert coordinates into numbers and back to XY. i = get_subtile_number(cctrl->scavenge.stl_9D_x, cctrl->scavenge.stl_9D_y); stl_x = stl_num_decode_x(i); stl_y = stl_num_decode_y(i); room = subtile_room_get(stl_x, stl_y); if (room_is_invalid(room) || (room->kind != RoK_SCAVENGER)) { ERRORLOG("Room %s at (%d,%d) disappeared.",room_code_name(RoK_SCAVENGER),(int)stl_x,(int)stl_y); kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects); return -1; } if (find_random_valid_position_for_thing_in_room(thing, room, &pos)) { move_thing_in_map(thing, &pos); anger_set_creature_anger_all_types(thing, 0); dungeon = get_dungeon(cctrl->byte_9B); dungeon->creatures_scavenge_gain++; if (is_my_player_number(thing->owner)) output_message(SMsg_MinionScanvenged, 0, true); cctrl->byte_9C = thing->owner; change_creature_owner(thing, cctrl->byte_9B); internal_set_thing_state(thing, CrSt_CreatureScavengedReappear); return 0; } else { ERRORLOG("No valid position inside %s room for %s.",room_code_name(room->kind),thing_model_name(thing)); kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects); return -1; } }
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; long stl_x,stl_y; long i,k; SYNCDBG(8,"Starting"); //_DK_find_nearest_rooms_for_ambient_sound(); if ((SoundDisabled) || (GetCurrentSoundMasterVolume() <= 0)) return; player = get_my_player(); if (player->acamera == NULL) { ERRORLOG("No active camera"); set_room_playing_ambient_sound(NULL, 0); return; } slb_x = subtile_slab(player->acamera->mappos.x.stl.num); slb_y = subtile_slab(player->acamera->mappos.y.stl.num); for (i = 0; i < 120; i++) { sstep = &spiral_step[i]; stl_x = 3 * (slb_x + sstep->h); stl_y = 3 * (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; k = room_info[room->kind].field_4; if (k > 0) { pos.x.val = (stl_x << 8); pos.y.val = (stl_y << 8); pos.z.val = (1 << 8); set_room_playing_ambient_sound(&pos, k); return; } } } set_room_playing_ambient_sound(NULL, 0); }
TbBool creature_can_do_research_near_pos(const struct Thing *creatng, MapSubtlCoord stl_x, MapSubtlCoord stl_y, CreatureJob new_job, unsigned long flags) { if (!creature_can_do_research(creatng)) { struct Room *room; room = subtile_room_get(stl_x, stl_y); struct Dungeon *dungeon; dungeon = get_dungeon(room->owner); if (!is_neutral_thing(creatng) && (dungeon->current_research_idx < 0)) { if (is_my_player_number(dungeon->owner) && ((flags & JobChk_PlayMsgOnFail) != 0)) { output_message(SMsg_NoMoreReseach, 500, true); } } return false; } return true; }
TbBool attempt_job_work_in_room_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; } if (!creature_move_to_place_in_room(creatng, room, new_job)) { return false; } creatng->continue_state = get_arrive_at_state_for_job(new_job); cctrl->target_room_id = room->index; if ((new_job == Job_TRAIN) && (creatng->model == get_players_special_digger_model(room->owner))) { cctrl->digger.last_did_job = SDLstJob_UseTraining4; } return true; }
TbBool is_correct_position_to_perform_job(const struct Thing *creatng, MapSubtlCoord stl_x, MapSubtlCoord stl_y, CreatureJob new_job) { const struct SlabMap *slb; slb = get_slabmap_for_subtile(stl_x, stl_y); const struct Room *room; room = subtile_room_get(stl_x, stl_y); RoomKind job_rkind; job_rkind = get_room_for_job(new_job); if (job_rkind != RoK_NONE) { if (room_is_invalid(room)) { return false; } if (room->kind != job_rkind) { return false; } } if (!is_correct_owner_to_perform_job(creatng, slabmap_owner(slb), new_job)) { return false; } return true; }
TbBool attempt_job_work_in_room_and_cure_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; } struct Coord3d pos; if (!find_first_valid_position_for_thing_in_room(creatng, room, &pos)) { return false; } if (!setup_person_move_to_position(creatng, pos.x.stl.num, pos.y.stl.num, NavRtF_Default)) { return false; } creatng->continue_state = get_arrive_at_state_for_job(new_job); cctrl->target_room_id = room->index; process_temple_cure(creatng); return true; }
/** Returns if a creature can do specific job at given map position. * * @param creatng The creature which is planned for the job. * @param stl_x Target map position, x coord. * @param stl_y Target map position, y coord. * @param new_job Job selection with single job flag set. * @return True if the creature can do the job specified, false otherwise. * @see creature_can_do_job_for_player() similar function for use when only target player is known */ TbBool creature_can_do_job_near_position(struct Thing *creatng, MapSubtlCoord stl_x, MapSubtlCoord stl_y, CreatureJob new_job, unsigned long flags) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); SYNCDBG(6,"Starting for %s (owner %d) and job %s",thing_model_name(creatng),(int)creatng->owner,creature_job_code_name(new_job)); struct CreatureStats *crstat; crstat = creature_stats_get_from_thing(creatng); if (creature_will_reject_job(creatng, new_job)) { SYNCDBG(3,"Cannot assign %s at (%d,%d) for %s index %d owner %d; in not-do-jobs list",creature_job_code_name(new_job),(int)stl_x,(int)stl_y,thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); if ((flags & JobChk_SetStateOnFail) != 0) { anger_apply_anger_to_creature(creatng, crstat->annoy_will_not_do_job, AngR_Other, 1); external_set_thing_state(creatng, CrSt_CreatureMoan); cctrl->field_282 = 50; } return false; } // Don't allow creatures changed to chickens to have any job assigned, besides those specifically marked if (creature_affected_by_spell(creatng, SplK_Chicken) && ((get_flags_for_job(new_job) & JoKF_AllowChickenized) == 0)) { SYNCDBG(3,"Cannot assign %s at (%d,%d) for %s index %d owner %d; under chicken spell",creature_job_code_name(new_job),(int)stl_x,(int)stl_y,thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); return false; } // Check if the job is related to correct map place (room,slab) if (!is_correct_position_to_perform_job(creatng, stl_x, stl_y, new_job)) { SYNCDBG(3,"Cannot assign %s at (%d,%d) for %s index %d owner %d; not correct place for job",creature_job_code_name(new_job),(int)stl_x,(int)stl_y,thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); return false; } struct CreatureJobConfig *jobcfg; jobcfg = get_config_for_job(new_job); if (jobcfg->func_cord_check == NULL) { SYNCDBG(3,"Cannot assign %s at (%d,%d) for %s index %d owner %d; job has no coord check function",creature_job_code_name(new_job),(int)stl_x,(int)stl_y,thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); return false; } if (!jobcfg->func_cord_check(creatng, stl_x, stl_y, new_job, flags)) { SYNCDBG(3,"Cannot assign %s at (%d,%d) for %s index %d owner %d; coord check not passed",creature_job_code_name(new_job),(int)stl_x,(int)stl_y,thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); return false; } // If other tests pass, check if related room (if is needed) has capacity to be used for that job if ((get_flags_for_job(new_job) & JoKF_NeedsCapacity) != 0) { struct Room *room; room = subtile_room_get(stl_x, stl_y); if (!room_has_enough_free_capacity_for_creature(room, creatng)) { SYNCDBG(3,"Cannot assign %s at (%d,%d) for %s index %d owner %d; not enough room capacity",creature_job_code_name(new_job),(int)stl_x,(int)stl_y,thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); if ((flags & JobChk_PlayMsgOnFail) != 0) { const struct RoomConfigStats *roomst; roomst = get_room_kind_stats(room->kind); if (is_my_player_number(room->owner) && (roomst->msg_too_small > 0)) { output_message_room_related_from_computer_or_player_action(roomst->msg_too_small); } } return false; } } return true; }