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; }
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; }