short creature_freeze_prisonors(struct Thing *creatng) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); if (cctrl->instance_id != CrInst_NULL) { return 1; } if (!creature_instance_has_reset(creatng, CrInst_FREEZE)) { if (creature_choose_random_destination_on_valid_adjacent_slab(creatng)) { creatng->continue_state = CrSt_CreatureFreezePrisoners; } return 1; } struct Thing *victng; victng = find_prisoner_for_thing(creatng); if (thing_is_invalid(victng)) { set_start_state(creatng); return 0; } long dist; dist = get_combat_distance(creatng, victng); if (dist < 156) { creature_retreat_from_combat(creatng, victng, CrSt_CreatureFreezePrisoners, 0); } else if ((dist <= 2048) && (creature_can_see_combat_path(creatng, victng, dist) > AttckT_Unset)) { set_creature_instance(creatng, CrInst_FREEZE, 1, victng->index, 0); } else { creature_move_to(creatng, &victng->mappos, cctrl->max_speed, 0, 0); } return 1; }
short good_doing_nothing(struct Thing *creatng) { struct CreatureControl *cctrl; struct PlayerInfo *player; long nturns; PlayerNumber target_plyr_idx; //return _DK_good_doing_nothing(creatng); SYNCDBG(18,"Starting"); TRACE_THING(creatng); // Debug code to find incorrect states if (!is_hero_thing(creatng)) { ERRORLOG("Non hero %s index %d owned by player %d - reset", thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); set_start_state(creatng); return 0; } cctrl = creature_control_get_from_thing(creatng); if (creature_control_invalid(cctrl)) { ERRORLOG("Invalid creature control; no action"); return 0; } // Respect the idle time - just wander around some time nturns = game.play_gameturn - cctrl->idle.start_gameturn; if (nturns <= 1) { return 1; } // Do some wandering also if can't find any task to do if (cctrl->field_5 > (long)game.play_gameturn) { if (creature_choose_random_destination_on_valid_adjacent_slab(creatng)) { creatng->continue_state = CrSt_GoodDoingNothing; } return 1; } // Done wandering - find a target player target_plyr_idx = cctrl->party.target_plyr_idx; if (target_plyr_idx != -1) { player = get_player(target_plyr_idx); if (player_invalid(player)) { ERRORLOG("Invalid target player in %s index %d owned by player %d - reset", thing_model_name(creatng),(int)creatng->index,(int)creatng->owner); cctrl->party.target_plyr_idx = -1; return 0; } if (player->victory_state != VicS_LostLevel) { nturns = game.play_gameturn - cctrl->long_91; if (nturns > 400) { // Go to the previously chosen dungeon if (!creature_can_get_to_dungeon(creatng,target_plyr_idx)) { // Cannot get to the originally selected dungeon - reset it cctrl->party.target_plyr_idx = -1; } } else if (nturns >= 0) { // Waiting - move around a bit if (creature_choose_random_destination_on_valid_adjacent_slab(creatng)) { creatng->continue_state = CrSt_GoodDoingNothing; return 0; } } else { // Value lower than 0 would mean it is invalid WARNLOG("Invalid wait time detected for %s, value %ld",thing_model_name(creatng),(long)cctrl->long_91); cctrl->long_91 = 0; } } else { // The player we've chosen has lost - we'll have to find other target cctrl->party.target_plyr_idx = -1; } } target_plyr_idx = cctrl->party.target_plyr_idx; if (target_plyr_idx == -1) { nturns = game.play_gameturn - cctrl->long_91; if (nturns > 400) { cctrl->long_91 = game.play_gameturn; cctrl->byte_8C = 1; } nturns = game.play_gameturn - cctrl->long_8D; if (nturns > 64) { cctrl->long_8D = game.play_gameturn; cctrl->party.target_plyr_idx = good_find_enemy_dungeon(creatng); } target_plyr_idx = cctrl->party.target_plyr_idx; if (target_plyr_idx == -1) { SYNCDBG(4,"No enemy dungeon to perform %s index %d task", thing_model_name(creatng),(int)creatng->index); if (creature_choose_random_destination_on_valid_adjacent_slab(creatng)) { creatng->continue_state = CrSt_GoodDoingNothing; return 1; } cctrl->field_5 = game.play_gameturn + 16; } return 1; } if (good_creature_setup_task_in_dungeon(creatng, target_plyr_idx)) { return 1; } // If there are problems with the task, do a break before re-trying cctrl->field_5 = game.play_gameturn + 200; return 0; }