示例#1
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;
}
示例#2
0
TbBool creature_can_freeze_prisoners_for_player(const struct Thing *creatng, PlayerNumber plyr_idx, CreatureJob new_job)
{
    // To freeze prisoners, our prison can't be empty
    struct Room *room;
    room = find_room_for_thing_with_used_capacity(creatng, creatng->owner, get_room_for_job(Job_FREEZE_PRISONERS), NavRtF_Default, 1);
    return creature_instance_is_available(creatng, CrInst_FREEZE) && !room_is_invalid(room);
}
short at_guard_post_room(struct Thing *thing)
{
    struct CreatureControl *cctrl;
    struct Room *room;
    cctrl = creature_control_get_from_thing(thing);
    cctrl->target_room_id = 0;
    room = get_room_thing_is_on(thing);
    if (!room_initially_valid_as_type_for_thing(room, get_room_for_job(Job_GUARD), thing))
    {
        WARNLOG("Room %s owned by player %d is invalid for %s index %d",room_code_name(room->kind),(int)room->owner,thing_model_name(thing),(int)thing->index);
        set_start_state(thing);
        return 0;
    }
    if (!add_creature_to_work_room(thing, room, Job_GUARD))
    {
        set_start_state(thing);
        return 0;
    }
    internal_set_thing_state(thing, get_continue_state_for_job(Job_GUARD));
    if (!person_get_somewhere_adjacent_in_room(thing, room, &cctrl->moveto_pos))
    {
        cctrl->moveto_pos.x.val = thing->mappos.x.val;
        cctrl->moveto_pos.y.val = thing->mappos.y.val;
        cctrl->moveto_pos.z.val = thing->mappos.z.val;
    }
    return 1;
}
示例#4
0
TbBool attempt_job_in_state_on_room_content_for_player(struct Thing *creatng, PlayerNumber plyr_idx, CreatureJob new_job)
{
    struct Room *room;
    RoomKind rkind;
    rkind = get_room_for_job(new_job);
    room = find_room_for_thing_with_used_capacity(creatng, creatng->owner, rkind, NavRtF_Default, 1);
    if (room_is_invalid(room)) {
        return false;
    }
    internal_set_thing_state(creatng, get_initial_state_for_job(new_job));
    return true;
}
示例#5
0
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;
}
示例#6
0
/** 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;
}