示例#1
0
CrStateRet creature_in_prison(struct Thing *thing)
{
    struct Room *room;
    TRACE_THING(thing);
    room = get_room_thing_is_on(thing);
    if (creature_work_in_room_no_longer_possible(room, RoK_PRISON, thing))
    {
        remove_creature_from_work_room(thing);
        set_start_state(thing);
        return CrStRet_ResetFail;
    }
    if (room->used_capacity > room->total_capacity)
    {
        output_message_room_related_from_computer_or_player_action(room->owner, room->kind, OMsg_RoomTooSmall);
        set_start_state(thing);
        return CrStRet_ResetOk;
    }
    switch (process_prison_function(thing))
    {
    case CrCkRet_Deleted:
        return CrStRet_Deleted;
    case CrCkRet_Available:
        process_prison_visuals(thing, room);
        return CrStRet_Modified;
    default:
        return CrStRet_ResetOk;
    }
}
示例#2
0
short creature_arrived_at_prison(struct Thing *creatng)
{
    struct CreatureControl *cctrl;
    struct Room *room;
    TRACE_THING(creatng);
    cctrl = creature_control_get_from_thing(creatng);
    cctrl->target_room_id = 0;
    room = get_room_thing_is_on(creatng);
    if (!room_initially_valid_as_type_for_thing(room, RoK_PRISON, creatng))
    {
        WARNLOG("Room %s owned by player %d is invalid for %s index %d",room_code_name(room->kind),(int)room->owner,thing_model_name(creatng),(int)creatng->index);
        set_start_state(creatng);
        return 0;
    }
    if (!add_creature_to_work_room(creatng, room))
    {
        output_message_room_related_from_computer_or_player_action(room->owner, room->kind, OMsg_RoomTooSmall);
        cctrl->flgfield_1 &= ~CCFlg_NoCompControl;
        set_start_state(creatng);
        return 0;
    }
    cctrl->field_82 = game.play_gameturn;
    cctrl->flgfield_1 |= CCFlg_NoCompControl;
    internal_set_thing_state(creatng, CrSt_CreatureInPrison);
    if (creature_affected_by_spell(creatng, SplK_Speed)) {
        terminate_thing_spell_effect(creatng, SplK_Speed);
    }
    if (creature_affected_by_spell(creatng, SplK_Invisibility)) {
        terminate_thing_spell_effect(creatng, SplK_Invisibility);
    }
    if (creatng->light_id != 0) {
        light_delete_light(creatng->light_id);
        creatng->light_id = 0;
    }
    return 1;

}
示例#3
0
/** 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;
}
示例#4
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;
}
示例#5
0
short researching(struct Thing *thing)
{
    struct Dungeon *dungeon;
    long i;
    TRACE_THING(thing);
    dungeon = get_dungeon(thing->owner);
    if (is_neutral_thing(thing))
    {
        ERRORLOG("Neutral %s index %d cannot do research",thing_model_name(thing),(int)thing->index);
        remove_creature_from_work_room(thing);
        set_start_state(thing);
        return CrStRet_Unchanged;
    }
    if (!creature_can_do_research(thing))
    {
        if (!is_neutral_thing(thing) && (dungeon->current_research_idx < 0))
        {
            if (is_my_player_number(dungeon->owner))
                output_message(SMsg_NoMoreReseach, 500, true);
        }
        remove_creature_from_work_room(thing);
        set_start_state(thing);
        return CrStRet_Unchanged;
    }
    // Get and verify working room
    struct Room *room;
    room = get_room_thing_is_on(thing);
    if (creature_work_in_room_no_longer_possible(room, RoK_LIBRARY, thing))
    {
        remove_creature_from_work_room(thing);
        set_start_state(thing);
        return CrStRet_ResetFail;
    }

    if (room->used_capacity > room->total_capacity)
    {
        output_message_room_related_from_computer_or_player_action(room->owner, room->kind, OMsg_RoomTooSmall);
        remove_creature_from_work_room(thing);
        set_start_state(thing);
        return CrStRet_ResetOk;
    }
    process_research_function(thing);
    struct CreatureControl *cctrl;
    cctrl = creature_control_get_from_thing(thing);
    if ( (game.play_gameturn - dungeon->field_AE5 < 50)
      && ((game.play_gameturn + thing->index) & 0x03) == 0)
    {
        external_set_thing_state(thing, CrSt_CreatureBeHappy);
        cctrl->countdown_282 = 50;
        cctrl->long_9A = 0;
        return CrStRet_Modified;
    }
    if (cctrl->instance_id != CrInst_NULL)
      return 1;
    cctrl->field_82++;
    // Shall we do some "Standing and thinking"
    if (cctrl->field_82 <= 128)
    {
      if (cctrl->byte_9A == 3)
      {
          // Do some random thinking
          if ((cctrl->field_82 % 16) == 0)
          {
              i = ACTION_RANDOM(LbFPMath_PI) - LbFPMath_PI/2;
              cctrl->long_9B = ((long)thing->move_angle_xy + i) & LbFPMath_AngleMask;
              cctrl->byte_9A = 4;
          }
      } else
      {
          // Look at different direction while thinking
          if (creature_turn_to_face_angle(thing, cctrl->long_9B) < LbFPMath_PI/18)
          {
              cctrl->byte_9A = 3;
          }
      }
      return 1;
    }
    // Finished "Standing and thinking" - make "new idea" effect and go to next position
    if (!setup_random_head_for_room(thing, room, NavRtF_Default))
    {
        ERRORLOG("Cannot move %s index %d in %s room", thing_model_name(thing),(int)thing->index,room_code_name(room->kind));
        set_start_state(thing);
        return 1;
    }
    thing->continue_state = CrSt_Researching;
    cctrl->field_82 = 0;
    cctrl->byte_9A = 3;
    if (cctrl->explevel < 3)
    {
        create_effect(&thing->mappos, TngEff_Unknown54, thing->owner);
    } else
    if (cctrl->explevel < 6)
    {
        create_effect(&thing->mappos, TngEff_Unknown55, thing->owner);
    } else
    {
        create_effect(&thing->mappos, TngEff_Unknown56, thing->owner);
    }
    return 1;
}