short creature_sleep(struct Thing *thing)
{
    //return _DK_creature_sleep(thing);
    struct CreatureControl *cctrl;
    cctrl = creature_control_get_from_thing(thing);
    if ((cctrl->slap_turns > 0) || !creature_will_sleep(thing)) {
        set_start_state(thing);
        return 0;
    }
    struct Room *room;
    room = get_room_thing_is_on(thing);
    if (room_is_invalid(room) || (room->kind != RoK_LAIR)
        || (cctrl->lair_room_id != room->index) || (room->owner != thing->owner)) {
        set_start_state(thing);
        return 0;
    }
    thing->movement_flags &= ~0x0020;
    struct CreatureStats *crstat;
    crstat = creature_stats_get_from_thing(thing);
    if (((game.play_gameturn + thing->index) % game.recovery_frequency) == 0)
    {
        HitPoints recover;
        recover = compute_creature_max_health(crstat->sleep_recovery, cctrl->explevel);
        apply_health_to_thing_and_display_health(thing, recover);
    }
    anger_set_creature_anger(thing, 0, AngR_NoLair);
    anger_apply_anger_to_creature(thing, crstat->annoy_sleeping, AngR_Other, 1);
    if (cctrl->field_82 > 0) {
        cctrl->field_82--;
    }
    if (((game.play_gameturn + thing->index) & 0x3F) == 0)
    {
        if (ACTION_RANDOM(100) < 5) {
            struct Dungeon *dungeon;
            dungeon = get_dungeon(thing->owner);
            dungeon->lvstats.backs_stabbed++;
        }
    }
    if (crstat->sleep_exp_slab != SlbT_ROCK)
    {
        if (creature_can_gain_experience(thing) && room_has_slab_adjacent(room, crstat->sleep_exp_slab))
        {
            cctrl->exp_points += crstat->sleep_experience;
            check_experience_upgrade(thing);
        }
    }
    {
        HitPoints health_max;
        health_max = compute_creature_max_health(crstat->health, cctrl->explevel);
        if ((crstat->heal_threshold * health_max / 256 <= thing->health) && (!cctrl->field_82))
        {
            set_start_state(thing);
            return 1;
        }
    }
    process_lair_enemy(thing, room);
    return 0;
}
Example #2
0
CrStateRet training(struct Thing *thing)
{
    struct CreatureControl *cctrl;
    TRACE_THING(thing);
    SYNCDBG(18,"Starting");
    //return _DK_training(thing);
    cctrl = creature_control_get_from_thing(thing);
    // Check if we should finish training
    if (!creature_can_be_trained(thing))
    {
        SYNCDBG(9,"Ending training of %s level %d; creature is not trainable",thing_model_name(thing),(int)cctrl->explevel);
        remove_creature_from_work_room(thing);
        set_start_state(thing);
        return CrStRet_ResetOk;
    }
    if (!player_can_afford_to_train_creature(thing))
    {
        SYNCDBG(19,"Ending training %s index %d; cannot afford",thing_model_name(thing),(int)thing->index);
        if (is_my_player_number(thing->owner))
            output_message(SMsg_NoGoldToTrain, MESSAGE_DELAY_TREASURY, true);
        remove_creature_from_work_room(thing);
        set_start_state(thing);
        return CrStRet_ResetFail;
    }
    // Check if we're in correct room
    struct Room *room;
    room = get_room_thing_is_on(thing);
    if (creature_work_in_room_no_longer_possible(room, RoK_TRAINING, thing))
    {
        remove_creature_from_work_room(thing);
        set_start_state(thing);
        return CrStRet_ResetFail;
    }
    struct Dungeon *dungeon;
    struct CreatureStats *crstat;
    dungeon = get_dungeon(thing->owner);
    crstat = creature_stats_get_from_thing(thing);
    // Pay for the training
    cctrl->field_82++;
    if (cctrl->field_82 >= game.train_cost_frequency)
    {
        cctrl->field_82 -= game.train_cost_frequency;
        if (take_money_from_dungeon(thing->owner, crstat->training_cost, 1) < 0) {
            ERRORLOG("Cannot take %d gold from dungeon %d",(int)crstat->training_cost,(int)thing->owner);
        }
        create_price_effect(&thing->mappos, thing->owner, crstat->training_cost);
    }
    if ((cctrl->instance_id != CrInst_NULL) || !check_experience_upgrade(thing))
    {
        long work_value;
        // Training speed does not grow with experience - otherwise it would be too fast
        work_value = compute_creature_work_value(crstat->training_value*256, room->efficiency, 0);
        work_value = process_work_speed_on_work_value(thing, work_value);
        SYNCDBG(19,"The %s index %d produced %d training points",thing_model_name(thing),(int)thing->index,(int)work_value);
        cctrl->exp_points += work_value;
        dungeon->total_experience_creatures_gained += work_value;
        process_creature_in_training_room(thing, room);
    } else
    {
        if (external_set_thing_state(thing, CrSt_CreatureBeHappy)) {
            cctrl->field_282 = 50;
        }
        dungeon->lvstats.creatures_trained++;
    }
    return CrStRet_Modified;
}