void init_dungeons(void) { int i,k; struct Dungeon *dungeon; for (i=0; i < DUNGEONS_COUNT; i++) { dungeon = get_dungeon(game.hero_player_num); dungeon->hates_player[i] = game.fight_max_hate; dungeon = get_dungeon(i); dungeon->hates_player[game.hero_player_num%DUNGEONS_COUNT] = game.fight_max_hate; dungeon->num_active_diggers = 0; dungeon->num_active_creatrs = 0; dungeon->creatr_list_start = 0; dungeon->digger_list_start = 0; dungeon->owner = i; dungeon->max_creatures_attracted = game.default_max_crtrs_gen_entrance; dungeon->dead_creatures_count = 0; dungeon->dead_creature_idx = 0; for (k=0; k < DUNGEONS_COUNT; k++) { if (k == i) dungeon->hates_player[k] = game.fight_max_love; else dungeon->hates_player[k] = game.fight_max_hate; } LbMemorySet(dungeon->creature_models_joined, 0, CREATURE_TYPES_COUNT); } }
long instf_destroy(struct Thing *creatng, long *param) { struct Dungeon *dungeon; struct Room *room; struct SlabMap *slb; MapSlabCoord slb_x,slb_y; long prev_owner; TRACE_THING(creatng); slb_x = subtile_slab_fast(creatng->mappos.x.stl.num); slb_y = subtile_slab_fast(creatng->mappos.y.stl.num); dungeon = get_dungeon(creatng->owner); slb = get_slabmap_block(slb_x, slb_y); room = room_get(slb->room_index); prev_owner = slabmap_owner(slb); if ( !room_is_invalid(room) && (prev_owner != creatng->owner) ) { if (room->health > 1) { room->health--; return 0; } clear_dig_on_room_slabs(room, creatng->owner); if (room->owner == game.neutral_player_num) { claim_room(room, creatng); } else { MapCoord ccor_x,ccor_y; ccor_x = subtile_coord_center(room->central_stl_x); ccor_y = subtile_coord_center(room->central_stl_y); event_create_event_or_update_nearby_existing_event(ccor_x, ccor_y, EvKind_RoomLost, room->owner, 0); claim_enemy_room(room, creatng); } thing_play_sample(creatng, 76, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); create_effects_on_room_slabs(room, imp_spangle_effects[creatng->owner], 0, creatng->owner); return 0; } if (slb->health > 1) { slb->health--; return 0; } if (prev_owner != game.neutral_player_num) { struct Dungeon *prev_dungeon; prev_dungeon = get_dungeon(prev_owner); prev_dungeon->lvstats.territory_lost++; } decrease_dungeon_area(prev_owner, 1); neutralise_enemy_block(creatng->mappos.x.stl.num, creatng->mappos.y.stl.num, creatng->owner); remove_traps_around_subtile(slab_subtile_center(slb_x), slab_subtile_center(slb_y), NULL); switch_owned_objects_on_destoyed_slab_to_neutral(slb_x, slb_y, prev_owner); dungeon->lvstats.territory_destroyed++; return 1; }
CrCheckRet process_scavenge_function(struct Thing *calltng) { SYNCDBG(18,"Starting for %s owner %d",thing_model_name(calltng),(int)calltng->owner); //return _DK_process_scavenge_function(thing); struct CreatureControl *callctrl; callctrl = creature_control_get_from_thing(calltng); struct Dungeon *calldngn; struct Room *room; calldngn = get_dungeon(calltng->owner); room = get_room_creature_works_in(calltng); if ( !room_still_valid_as_type_for_thing(room, RoK_SCAVENGER, calltng) ) { WARNLOG("Room %s owned by player %d is bad work place for %s owned by played %d",room_code_name(room->kind),(int)room->owner,thing_model_name(calltng),(int)calltng->owner); set_start_state(calltng); return CrCkRet_Continue; } struct CreatureStats *crstat; crstat = creature_stats_get_from_thing(calltng); if (!player_can_afford_to_scavenge_creature(calltng)) { if (is_my_player_number(calltng->owner)) output_message(SMsg_NoGoldToScavenge, 500, 1); set_start_state(calltng); return CrCkRet_Continue; } if (calldngn->scavenge_counters_turn != game.play_gameturn) { reset_scavenge_counts(calldngn); } long work_value; work_value = compute_creature_work_value(crstat->scavenge_value*256, room->efficiency, callctrl->explevel); work_value = process_work_speed_on_work_value(calltng, work_value); SYNCDBG(9,"The %s index %d owner %d produced %d scavenge points",thing_model_name(calltng),(int)calltng->index,(int)calltng->owner,(int)work_value); struct Thing *scavtng; scavtng = get_scavenger_target(calltng); if (!thing_is_invalid(scavtng)) { process_scavenge_creature_from_level(scavtng, calltng, work_value); } else if (can_scavenge_creature_from_pool(calldngn, calltng->model)) { process_scavenge_creature_from_pool(calltng, work_value); } else { if (crstat->entrance_force) { calldngn->field_1485++; } return 0; } callctrl->field_82++; if (callctrl->field_82 > game.scavenge_cost_frequency) { callctrl->field_82 -= game.scavenge_cost_frequency; if (take_money_from_dungeon(calltng->owner, crstat->scavenger_cost, 1) < 0) { ERRORLOG("Cannot take %d gold from dungeon %d",(int)crstat->scavenger_cost,(int)calltng->owner); } create_price_effect(&calltng->mappos, calltng->owner, crstat->scavenger_cost); } return 0; }
short at_scavenger_room(struct Thing *thing) { struct CreatureControl *cctrl; struct CreatureStats *crstat; struct Dungeon *dungeon; struct Room *room; //return _DK_at_scavenger_room(thing); room = get_room_thing_is_on(thing); if (!room_initially_valid_as_type_for_thing(room, RoK_SCAVENGER, 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; } cctrl = creature_control_get_from_thing(thing); crstat = creature_stats_get_from_thing(thing); dungeon = get_dungeon(thing->owner); if (crstat->scavenger_cost >= dungeon->total_money_owned) { if (is_my_player_number(thing->owner)) output_message(SMsg_NoGoldToScavenge, MESSAGE_DELAY_TREASURY, true); set_start_state(thing); return 0; } if (!add_creature_to_work_room(thing, room)) { set_start_state(thing); return 0; } internal_set_thing_state(thing, CrSt_Scavengering); cctrl->field_82 = 0; return 1; }
TbBool prison_convert_creature_to_skeleton(struct Room *room, struct Thing *thing) { struct Dungeon *dungeon; struct CreatureControl *cctrl; struct Thing *crthing; long crmodel; cctrl = creature_control_get_from_thing(thing); crmodel = get_room_create_creature_model(room->kind); // That normally returns skeleton breed crthing = create_creature(&thing->mappos, crmodel, room->owner); if (thing_is_invalid(crthing)) { ERRORLOG("Couldn't create creature %s in prison", creature_code_name(crmodel)); return false; } init_creature_level(crthing, cctrl->explevel); set_start_state(crthing); if (creature_model_bleeds(thing->model)) create_effect_around_thing(thing, TngEff_Unknown10); kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects); dungeon = get_dungeon(room->owner); if (!dungeon_invalid(dungeon)) { dungeon->lvstats.skeletons_raised++; } return true; }
struct Room * find_nearest_navigable_room_for_thing_with_capacity_and_closer_than(struct Thing *thing, PlayerNumber owner, RoomKind rkind, unsigned char nav_flags, long used, long *neardistance) { struct Dungeon *dungeon; struct Room *nearoom; long distance; int i; SYNCDBG(18,"Searching for %s navigable by %s index %d",room_code_name(rkind),thing_model_name(thing),(int)thing->index); dungeon = get_dungeon(owner); nearoom = INVALID_ROOM; distance = *neardistance; i = dungeon->room_kind[rkind]; while (i != 0) { struct Room *room; room = find_next_navigable_room_for_thing_with_capacity_and_closer_than(thing, i, nav_flags, used, &distance); if (room_is_invalid(room)) { break; } // Found closer room i = room->next_of_owner; nearoom = room; } *neardistance = distance; return nearoom; }
long instf_attack_room_slab(struct Thing *creatng, long *param) { TRACE_THING(creatng); //return _DK_instf_attack_room_slab(creatng, param); struct Room *room; room = get_room_thing_is_on(creatng); if (room_is_invalid(room)) { ERRORLOG("The %s is not on room",thing_model_name(creatng)); return 0; } struct SlabMap *slb; slb = get_slabmap_thing_is_on(creatng); if (slb->health > 2) { //TODO CONFIG damage made to room slabs is constant - doesn't look good slb->health -= 2; thing_play_sample(creatng, 128 + UNSYNC_RANDOM(3), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); return 1; } if (room->owner != game.neutral_player_num) { struct Dungeon *dungeon; dungeon = get_dungeon(room->owner); dungeon->rooms_destroyed++; } if (!delete_room_slab(coord_slab(creatng->mappos.x.val), coord_slab(creatng->mappos.y.val), 1)) { ERRORLOG("Cannot delete %s room tile destroyed by %s",room_code_name(room->kind),thing_model_name(creatng)); return 0; } create_effect(&creatng->mappos, 3, creatng->owner); thing_play_sample(creatng, 47, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); return 1; }
struct Thing *create_and_control_creature_as_controller(struct PlayerInfo *player, long breed, struct Coord3d *pos) { struct CreatureStats *crstat; struct CreatureControl *cctrl; struct Dungeon *dungeon; struct Thing *thing; struct Camera *cam; struct InitLight ilght; SYNCDBG(6,"Request for model %ld at (%d,%d,%d)",breed,(int)pos->x.val,(int)pos->y.val,(int)pos->z.val); //return _DK_create_and_control_creature_as_controller(player, a2, pos); thing = create_creature(pos, breed, player->id_number); if (thing_is_invalid(thing)) return INVALID_THING; dungeon = get_dungeon(thing->owner); dungeon->num_active_creatrs--; dungeon->owned_creatures_of_model[thing->model]--; if (is_my_player(player)) { toggle_status_menu(0); turn_off_roaming_menus(); } cam = player->acamera; player->controlled_thing_idx = thing->index; player->field_31 = thing->creation_turn; player->field_4B5 = cam->field_6; thing->alloc_flags |= TAlF_IsControlled; thing->field_4F |= 0x01; cctrl = creature_control_get_from_thing(thing); cctrl->flgfield_2 |= 0x02; cctrl->max_speed = calculate_correct_creature_maxspeed(thing); set_player_mode(player, PVT_CreatureContrl); set_start_state(thing); // Preparing light object LbMemorySet(&ilght, 0, sizeof(struct InitLight)); ilght.mappos.x.val = thing->mappos.x.val; ilght.mappos.y.val = thing->mappos.y.val; ilght.mappos.z.val = thing->mappos.z.val; ilght.field_2 = 36; ilght.field_3 = 1; ilght.is_dynamic = 1; ilght.field_0 = 2560; thing->light_id = light_create_light(&ilght); if (thing->light_id != 0) { light_set_light_never_cache(thing->light_id); } else { ERRORLOG("Cannot allocate light to new hero"); } if (is_my_player_number(thing->owner)) { if (thing->class_id == TCls_Creature) { crstat = creature_stats_get_from_thing(thing); setup_eye_lens(crstat->eye_effect); } } return thing; }
/** * Returns if a player to whom the creature belongs can afford the creature to go scavenging. * @param creatng * @return */ TbBool player_can_afford_to_scavenge_creature(const struct Thing *creatng) { struct Dungeon *dungeon; dungeon = get_dungeon(creatng->owner); struct CreatureStats *crstat; crstat = creature_stats_get_from_thing(creatng); return (crstat->scavenger_cost < dungeon->total_money_owned); }
void increase_dungeon_area(PlayerNumber plyr_idx, long value) { struct Dungeon *dungeon; if (plyr_idx == game.neutral_player_num) return; dungeon = get_dungeon(plyr_idx); dungeon->total_area += value; }
struct ResearchVal *get_players_current_research_val(PlayerNumber plyr_idx) { struct Dungeon *dungeon; dungeon = get_dungeon(plyr_idx); if ((dungeon->current_research_idx < 0) || (dungeon->current_research_idx >= DUNGEON_RESEARCH_COUNT)) return NULL; return &dungeon->research[dungeon->current_research_idx]; }
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; }
void increase_level(struct PlayerInfo *player) { struct Dungeon *dungeon; struct CreatureControl *cctrl; struct Thing *thing; unsigned long k; int i; dungeon = get_dungeon(player->id_number); // Increase level of normal creatures k = 0; i = dungeon->creatr_list_start; while (i != 0) { thing = thing_get(i); cctrl = creature_control_get_from_thing(thing); if (thing_is_invalid(thing) || creature_control_invalid(cctrl)) { ERRORLOG("Jump to invalid creature detected"); break; } i = cctrl->players_next_creature_idx; // Thing list loop body creature_increase_level(thing); // Thing list loop body ends k++; if (k > CREATURES_COUNT) { ERRORLOG("Infinite loop detected when sweeping creatures list"); erstat_inc(ESE_InfChainTngPerOwner); break; } } // Increase level of special workers k = 0; i = dungeon->digger_list_start; while (i != 0) { thing = thing_get(i); cctrl = creature_control_get_from_thing(thing); if (thing_is_invalid(thing) || creature_control_invalid(cctrl)) { ERRORLOG("Jump to invalid creature detected"); break; } i = cctrl->players_next_creature_idx; // Thing list loop body creature_increase_level(thing); // Thing list loop body ends k++; if (k > CREATURES_COUNT) { ERRORLOG("Infinite loop detected when sweeping creatures list"); erstat_inc(ESE_InfChainTngPerOwner); break; } } }
TbBool player_can_afford_to_train_creature(const struct Thing *thing) { struct Dungeon *dungeon; struct CreatureStats *crstat; //return _DK_player_can_afford_to_train_creature(thing); dungeon = get_dungeon(thing->owner); crstat = creature_stats_get_from_thing(thing); return (dungeon->total_money_owned >= crstat->training_cost); }
void init_dungeons_essential_position(void) { int i; for (i=0; i < DUNGEONS_COUNT; i++) { struct Dungeon *dungeon; dungeon = get_dungeon(i); init_dungeon_essential_position(dungeon); } }
TbBool creature_can_do_research(const struct Thing *creatng) { if (is_neutral_thing(creatng)) { return false; } struct CreatureStats *crstat; struct Dungeon *dungeon; crstat = creature_stats_get_from_thing(creatng); dungeon = get_dungeon(creatng->owner); return (crstat->research_value > 0) && (dungeon->current_research_idx >= 0); }
TbBool creature_free_for_anger_job(struct Thing *creatng) { struct CreatureControl *cctrl; struct Dungeon *dungeon; cctrl = creature_control_get_from_thing(creatng); dungeon = get_dungeon(creatng->owner); return ((cctrl->spell_flags & CSAfF_Unkn0800) == 0) && (dungeon->must_obey_turn == 0) && ((cctrl->spell_flags & CSAfF_Chicken) == 0) && !thing_is_picked_up(creatng) && !is_thing_passenger_controlled(creatng); }
void decrease_dungeon_area(PlayerNumber plyr_idx, long value) { struct Dungeon *dungeon; if (plyr_idx == game.neutral_player_num) return; dungeon = get_dungeon(plyr_idx); if (dungeon->total_area < value) dungeon->total_area = 0; else dungeon->total_area -= value; }
void process_armageddon(void) { struct PlayerInfo *player; struct Dungeon *dungeon; struct Thing *heartng; long i; SYNCDBG(6,"Starting"); //_DK_process_armageddon(); return; if (game.armageddon_cast_turn == 0) return; if (game.armageddon.count_down+game.armageddon_cast_turn > game.play_gameturn) { if (player_cannot_win(game.armageddon_caster_idx)) { // Stop the armageddon if its originator is just losing game.armageddon_cast_turn = 0; } } else if (game.armageddon.count_down+game.armageddon_cast_turn == game.play_gameturn) { for (i=0; i < PLAYERS_COUNT; i++) { player = get_player(i); if (player_exists(player)) { if (player->field_2C == 1) reveal_whole_map(player); } } } else if (game.armageddon.count_down+game.armageddon_cast_turn < game.play_gameturn) { for (i=0; i < PLAYERS_COUNT; i++) { player = get_player(i); if ( (player_exists(player)) && (player->field_2C == 1) ) { dungeon = get_dungeon(player->id_number); if ((player->victory_state == VicS_Undecided) && (dungeon->num_active_creatrs == 0)) { event_kill_all_players_events(i); set_player_as_lost_level(player); if (is_my_player_number(i)) LbPaletteSet(engine_palette); heartng = get_player_soul_container(player->id_number); if (thing_exists(heartng)) { heartng->health = -1; } } } } } }
/** * Returns any room of given kind and owner to which the thing can navigate. * * @param thing The thing to navigate into room. * @param owner Owner of the rooms to be checked. * @param rkind Room kind to be returned. * @param nav_flags Navigation flags, for checking if creature can reach the room. * @return Nearest room of given kind and owner, or invalid room if none found. */ struct Room *find_any_navigable_room_for_thing_closer_than(struct Thing *thing, PlayerNumber owner, RoomKind rkind, unsigned char nav_flags, long max_distance) { struct Dungeon *dungeon; dungeon = get_dungeon(owner); SYNCDBG(18,"Searching for %s navigable by %s index %d",room_code_name(rkind),thing_model_name(thing),(int)thing->index); long neardistance; struct Room *nearoom; neardistance = max_distance; nearoom = INVALID_ROOM; nearoom = find_next_navigable_room_for_thing_with_capacity_and_closer_than(thing, dungeon->room_kind[rkind], nav_flags, 0, &neardistance); return nearoom; }
/** * Wander the given creature to a random digger belonging to given player. * Originally was good_setup_wander_to_imp. * @param wanderer * @param dngn_id * @return */ TbBool good_setup_wander_to_spdigger(struct Thing *wanderer, long dngn_id) { struct Dungeon *dungeon; SYNCDBG(7,"Starting"); dungeon = get_dungeon(dngn_id); if ( setup_wanderer_move_to_random_creature_from_list(dungeon->digger_list_start,wanderer) ) { wanderer->continue_state = CrSt_GoodDoingNothing; return true; } SYNCDBG(4,"Cannot wander to player %d creatures",(int)dngn_id); return false; }
struct Room * find_nearest_navigable_room_for_thing_with_capacity_and_closer_than(struct Thing *thing, PlayerNumber owner, RoomKind rkind, unsigned char nav_flags, long used, long *neardistance) { struct Dungeon *dungeon; struct Room *nearoom; long distance; struct Coord3d pos; struct Room *room; unsigned long k; int i; SYNCDBG(18,"Searching for %s navigable by %s index %d",room_code_name(rkind),thing_model_name(thing),(int)thing->index); dungeon = get_dungeon(owner); nearoom = INVALID_ROOM; k = 0; i = dungeon->room_kind[rkind]; while (i != 0) { room = room_get(i); if (room_is_invalid(room)) { ERRORLOG("Jump to invalid room detected"); break; } i = room->next_of_owner; // Per-room code // Compute simplified distance - without use of mul or div distance = abs(thing->mappos.x.stl.num - (int)room->central_stl_x) + abs(thing->mappos.y.stl.num - (int)room->central_stl_y); if ((*neardistance > distance) && (room->used_capacity >= used)) { if (find_first_valid_position_for_thing_anywhere_in_room(thing, room, &pos)) { if ((thing->class_id != TCls_Creature) || creature_can_navigate_to(thing, &pos, nav_flags)) { *neardistance = distance; nearoom = room; } } } // Per-room code ends k++; if (k > ROOMS_COUNT) { ERRORLOG("Infinite loop detected when sweeping rooms list"); break; } } return nearoom; }
short tunneller_doing_nothing(struct Thing *creatng) { //return _DK_tunneller_doing_nothing(creatng); struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); // Wait for some time if (game.play_gameturn - cctrl->last_mood_sound_turn <= 1) { return 1; } /* Sometimes we may have no target dungeon. In that case, destination dungeon * index is negative. */ if (cctrl->party.target_plyr_idx == -1) { script_support_send_tunneller_to_appropriate_dungeon(creatng); return 0; } if (!player_cannot_win(cctrl->party.target_plyr_idx)) { if (good_can_move_to_dungeon_heart(creatng, cctrl->party.target_plyr_idx)) { internal_set_thing_state(creatng, CrSt_GoodDoingNothing); return 1; } } cctrl->party.target_plyr_idx = good_find_enemy_dungeon(creatng); if (cctrl->party.target_plyr_idx != -1) { internal_set_thing_state(creatng, CrSt_GoodDoingNothing); return 1; } int plyr_idx; plyr_idx = get_best_dungeon_to_tunnel_to(creatng); if (plyr_idx == -1) { return 1; } struct Dungeon *dungeon; dungeon = get_dungeon(plyr_idx); if ( dungeon->num_active_creatrs || dungeon->num_active_diggers ) { struct Coord3d pos; get_random_position_in_dungeon_for_creature(plyr_idx, 1, creatng, &pos); send_tunneller_to_point_in_dungeon(creatng, plyr_idx, &pos); } else { good_setup_wander_to_dungeon_heart(creatng, plyr_idx); } return 1; }
short creature_scavenged_disappear(struct Thing *thing) { struct CreatureControl *cctrl; struct Dungeon *dungeon; struct Room *room; struct Coord3d pos; long stl_x, stl_y; long i; //return _DK_creature_scavenged_disappear(thing); cctrl = creature_control_get_from_thing(thing); cctrl->byte_9A--; if (cctrl->byte_9A > 0) { if ((cctrl->byte_9A == 7) && (cctrl->byte_9B < PLAYERS_COUNT)) { create_effect(&thing->mappos, get_scavenge_effect_element(cctrl->byte_9B), thing->owner); } return 0; } // We don't really have to convert coordinates into numbers and back to XY. i = get_subtile_number(cctrl->scavenge.stl_9D_x, cctrl->scavenge.stl_9D_y); stl_x = stl_num_decode_x(i); stl_y = stl_num_decode_y(i); room = subtile_room_get(stl_x, stl_y); if (room_is_invalid(room) || (room->kind != RoK_SCAVENGER)) { ERRORLOG("Room %s at (%d,%d) disappeared.",room_code_name(RoK_SCAVENGER),(int)stl_x,(int)stl_y); kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects); return -1; } if (find_random_valid_position_for_thing_in_room(thing, room, &pos)) { move_thing_in_map(thing, &pos); anger_set_creature_anger_all_types(thing, 0); dungeon = get_dungeon(cctrl->byte_9B); dungeon->creatures_scavenge_gain++; if (is_my_player_number(thing->owner)) output_message(SMsg_MinionScanvenged, 0, true); cctrl->byte_9C = thing->owner; change_creature_owner(thing, cctrl->byte_9B); internal_set_thing_state(thing, CrSt_CreatureScavengedReappear); return 0; } else { ERRORLOG("No valid position inside %s room for %s.",room_code_name(room->kind),thing_model_name(thing)); kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects); return -1; } }
TbBool set_script_flag(PlayerNumber plyr_idx, long flag_id, long value) { struct Dungeon *dungeon; if ( (flag_id < 0) || (flag_id >= SCRIPT_FLAGS_COUNT) ) { ERRORLOG("Can't set flag; invalid flag id %d.",(int)flag_id); return false; } dungeon = get_dungeon(plyr_idx); if (dungeon_invalid(dungeon)) { ERRORLOG("Can't set flag; player %d has no dungeon",(int)plyr_idx); return false; } dungeon->script_flags[flag_id] = value; return true; }
void start_transfer_creature(struct PlayerInfo *player, struct Thing *thing) { struct Dungeon *dungeon; dungeon = get_dungeon(player->id_number); if (dungeon->num_active_creatrs != 0) { if (is_my_player(player)) { dungeon_special_selected = thing->index; transfer_creature_scroll_offset = 0; turn_off_menu(GMnu_DUNGEON_SPECIAL); turn_on_menu(GMnu_TRANSFER_CREATURE); } } }
void start_resurrect_creature(struct PlayerInfo *player, struct Thing *thing) { struct Dungeon *dungeon; dungeon = get_dungeon(player->id_number); if (dungeon->dead_creatures_count != 0) { if (is_my_player(player)) { dungeon_special_selected = thing->index; resurrect_creature_scroll_offset = 0; turn_off_menu(GMnu_DUNGEON_SPECIAL); turn_on_menu(GMnu_RESURRECT_CREATURE); } } }
TbBool process_scavenge_creature_from_pool(struct Thing *calltng, long work_value) { struct Dungeon *calldngn; calldngn = get_dungeon(calltng->owner); calldngn->scavenge_turn_points[calltng->model] += work_value; long scavpts; scavpts = calculate_correct_creature_scavenge_required(calltng, calltng->owner); if ((scavpts << 8) < calldngn->scavenge_turn_points[calltng->model]) { creature_scavenge_from_creature_pool(calltng); calldngn->scavenge_turn_points[calltng->model] -= scavpts; return true; } return false; }
TbBool creature_can_gain_experience(const struct Thing *thing) { struct Dungeon *dungeon; struct CreatureStats *crstat; struct CreatureControl *cctrl; dungeon = get_dungeon(thing->owner); cctrl = creature_control_get_from_thing(thing); // Creatures which reached players max level can't be trained if (cctrl->explevel >= dungeon->creature_max_level[thing->model]) return false; // Creatures which reached absolute max level and have no grow up creature crstat = creature_stats_get_from_thing(thing); if ((cctrl->explevel >= (CREATURE_MAX_LEVEL-1)) && (crstat->grow_up == 0)) return false; return true; }
TbBool restart_script_timer(PlayerNumber plyr_idx, long timer_id) { struct Dungeon *dungeon; if ( (timer_id < 0) || (timer_id >= TURN_TIMERS_COUNT) ) { ERRORLOG("Can't restart timer; invalid timer id %d.",(int)timer_id); return false; } dungeon = get_dungeon(plyr_idx); if (dungeon_invalid(dungeon)) { ERRORLOG("Can't restart timer; player %d has no dungeon.",(int)plyr_idx); return false; } dungeon->turn_timers[timer_id].state = 1; dungeon->turn_timers[timer_id].count = game.play_gameturn; return true; }