TbBool output_message_room_related_from_computer_or_player_action(PlayerNumber plyr_idx, RoomKind rkind, OutputMessageKind msg_kind) { if (!is_my_player_number(plyr_idx)) { return false; } const struct RoomConfigStats *roomst; roomst = get_room_kind_stats(rkind); long delay, msg_idx; switch (msg_kind) { case OMsg_RoomNeeded: msg_idx = roomst->msg_needed; delay = MESSAGE_DELAY_ROOM_NEED; break; case OMsg_RoomTooSmall: msg_idx = roomst->msg_too_small; delay = MESSAGE_DELAY_ROOM_SMALL; break; case OMsg_RoomNoRoute: msg_idx = roomst->msg_no_route; delay = MESSAGE_DELAY_ROOM_NEED; break; default: msg_idx = 0; delay = 0; break; } if (msg_idx < 1) { return false; } return output_message(msg_idx, delay, true); }
void set_chosen_room(RoomKind rkind, TextStringId tip_stridx) { struct RoomConfigStats *roomst; roomst = get_room_kind_stats(rkind); game.my.chosen_room_kind = rkind; game.my.chosen_room_spridx = roomst->bigsym_sprite_idx; if (tip_stridx != 0) { game.my.chosen_room_tooltip = tip_stridx; } else { game.my.chosen_room_tooltip = roomst->tooltip_stridx; } }
/** 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; }
/** Returns if a creature can do specific job for the player. * * @param creatng The creature which is planned for the job. * @param plyr_idx Player for whom the job is to be done. * @param new_job Job selection with single job flag set. * @param flags Function behavior adjustment flags. * @return True if the creature can do the job specified, false otherwise. * @note this should be used instead of person_will_do_job_for_room() * @note this function will never change state of the input thing, even if appropriate flags are set * @see creature_can_do_job_near_position() similar function for use when target position is known */ TbBool creature_can_do_job_for_player(const struct Thing *creatng, PlayerNumber plyr_idx, CreatureJob new_job, unsigned long flags) { SYNCDBG(16,"Starting for %s (owner %d) and job %s",thing_model_name(creatng),(int)creatng->owner,creature_job_code_name(new_job)); if (creature_will_reject_job(creatng, new_job)) { SYNCDBG(13,"Cannot assign %s for %s index %d owner %d; in not do jobs list",creature_job_code_name(new_job),thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); return false; } if (!is_correct_owner_to_perform_job(creatng, plyr_idx, new_job)) { SYNCDBG(13,"Cannot assign %s for %s index %d owner %d; not correct owner for job",creature_job_code_name(new_job),thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); 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(13,"Cannot assign %s for %s index %d owner %d; under chicken spell",creature_job_code_name(new_job),thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); return false; } // Check if the job is related to correct player struct CreatureJobConfig *jobcfg; jobcfg = get_config_for_job(new_job); if (jobcfg->func_plyr_check == NULL) { return false; } if (!jobcfg->func_plyr_check(creatng, plyr_idx, new_job)) { return false; } RoomKind job_rkind; job_rkind = get_room_for_job(new_job); if (job_rkind != RoK_NONE) { if (!player_has_room(plyr_idx, job_rkind)) { SYNCDBG(3,"Cannot assign %s in player %d room for %s index %d owner %d; no required room built",creature_job_code_name(new_job),(int)plyr_idx,thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); if ((flags & JobChk_PlayMsgOnFail) != 0) { const struct RoomConfigStats *roomst; roomst = get_room_kind_stats(get_room_for_job(new_job)); if (is_my_player_number(plyr_idx) && (roomst->msg_needed > 0)) { output_message_room_related_from_computer_or_player_action(roomst->msg_needed); } } return false; } if ((get_flags_for_job(new_job) & JoKF_NeedsCapacity) != 0) { struct Room *room; room = find_room_with_spare_capacity(plyr_idx, job_rkind, 1); if (room_is_invalid(room)) { SYNCDBG(3,"Cannot assign %s in player %d room for %s index %d owner %d; not enough room capacity",creature_job_code_name(new_job),(int)plyr_idx,thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); if ((flags & JobChk_PlayMsgOnFail) != 0) { const struct RoomConfigStats *roomst; roomst = get_room_kind_stats(get_room_for_job(new_job)); if (is_my_player_number(plyr_idx) && (roomst->msg_too_small > 0)) { output_message_room_related_from_computer_or_player_action(roomst->msg_too_small); } } return false; } } } return true; }