TbBool good_setup_wander_to_dungeon_heart(struct Thing *creatng, PlayerNumber plyr_idx) { struct PlayerInfo *player; SYNCDBG(18,"Starting"); TRACE_THING(creatng); if (creatng->owner == plyr_idx) { ERRORLOG("The %s tried to wander to own (%d) heart", thing_model_name(creatng), (int)plyr_idx); return false; } player = get_player(plyr_idx); if (!player_exists(player)) { WARNLOG("The %s tried to wander to inactive player (%d) heart", thing_model_name(creatng), (int)plyr_idx); return false; } struct Thing *heartng; heartng = get_player_soul_container(plyr_idx); TRACE_THING(heartng); if (thing_is_invalid(heartng)) { WARNLOG("The %s tried to wander to player %d which has no heart", thing_model_name(creatng), (int)plyr_idx); return false; } set_creature_object_combat(creatng, heartng); return true; }
long creature_will_sleep(struct Thing *thing) { struct CreatureControl *cctrl; struct Thing *lairtng; long dist_x,dist_y; TRACE_THING(thing); cctrl = creature_control_get_from_thing(thing); lairtng = thing_get(cctrl->lairtng_idx); TRACE_THING(lairtng); if (thing_is_invalid(lairtng)) return false; dist_x = (long)thing->mappos.x.stl.num - (long)lairtng->mappos.x.stl.num; dist_y = (long)thing->mappos.y.stl.num - (long)lairtng->mappos.y.stl.num; return (abs(dist_x) < 1) && (abs(dist_y) < 1); }
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; }
void process_creature_instance(struct Thing *thing) { struct CreatureControl *cctrl; struct InstanceInfo *inst_inf; SYNCDBG(19,"Starting for %s index %d instance %d",thing_model_name(thing),(int)thing->index,(int)cctrl->instance_id); TRACE_THING(thing); cctrl = creature_control_get_from_thing(thing); if (cctrl->instance_id != CrInst_NULL) { cctrl->inst_turn++; if (cctrl->inst_turn == cctrl->inst_action_turns) { inst_inf = creature_instance_info_get(cctrl->instance_id); if (inst_inf->func_cb != NULL) { SYNCDBG(18,"Executing instance %d for %s index %d.",(int)cctrl->instance_id,thing_model_name(thing),(int)thing->index); inst_inf->func_cb(thing, inst_inf->func_params); } } if (cctrl->inst_turn >= cctrl->inst_total_turns) { if (cctrl->inst_repeat) { cctrl->inst_turn--; cctrl->inst_repeat = 0; return; } cctrl->instance_use_turn[cctrl->instance_id] = game.play_gameturn; cctrl->instance_id = CrInst_NULL; } cctrl->inst_repeat = 0; } }
long instf_damage_wall(struct Thing *creatng, long *param) { SYNCDBG(16,"Starting"); TRACE_THING(creatng); //return _DK_instf_damage_wall(creatng, param); MapSubtlCoord stl_x, stl_y; { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); stl_x = stl_num_decode_x(cctrl->field_284); stl_y = stl_num_decode_y(cctrl->field_284); } struct SlabMap *slb; slb = get_slabmap_for_subtile(stl_x, stl_y); if (slb->health > 2) { slb->health -= 2; } else { place_slab_type_on_map(2, stl_x, stl_y, creatng->owner, 0); do_slab_efficiency_alteration(subtile_slab_fast(stl_x), subtile_slab_fast(stl_y)); } thing_play_sample(creatng, 63+UNSYNC_RANDOM(6), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); return 1; }
CrStateRet guarding(struct Thing *thing) { struct Room *room; TRACE_THING(thing); room = get_room_thing_is_on(thing); if (creature_job_in_room_no_longer_possible(room, Job_GUARD, thing)) { remove_creature_from_work_room(thing); set_start_state(thing); return CrStRet_ResetFail; } struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(thing); if (creature_move_to(thing, &cctrl->moveto_pos, cctrl->max_speed, 0, 0) == 0) { return CrStRet_Unchanged; } if (!person_get_somewhere_adjacent_in_room(thing, room, &cctrl->moveto_pos)) { cctrl->moveto_pos.x.val = thing->mappos.x.val; cctrl->moveto_pos.y.val = thing->mappos.y.val; cctrl->moveto_pos.z.val = thing->mappos.z.val; } return CrStRet_Modified; }
TbBool setup_person_move_to_position_f(struct Thing *thing, MapSubtlCoord stl_x, MapSubtlCoord stl_y, NaviRouteFlags flags, const char *func_name) { struct CreatureControl *cctrl; struct Coord3d locpos; SYNCDBG(18,"%s: Moving %s index %d to (%d,%d)",func_name,thing_model_name(thing),(int)thing->index,(int)stl_x,(int)stl_y); TRACE_THING(thing); locpos.x.val = subtile_coord_center(stl_x); locpos.y.val = subtile_coord_center(stl_y); locpos.z.val = thing->mappos.z.val; locpos.z.val = get_thing_height_at(thing, &locpos); cctrl = creature_control_get_from_thing(thing); if (creature_control_invalid(cctrl)) { WARNLOG("%s: Tried to move invalid creature to (%d,%d)",func_name,(int)stl_x,(int)stl_y); return false; } if (thing_in_wall_at(thing, &locpos)) { SYNCDBG(16,"%s: The %s would be trapped in wall at (%d,%d)",func_name,thing_model_name(thing),(int)stl_x,(int)stl_y); return false; } if (!creature_can_navigate_to_with_storage_f(thing, &locpos, flags, func_name)) { SYNCDBG(19,"%s: The %s cannot reach subtile (%d,%d)",func_name,thing_model_name(thing),(int)stl_x,(int)stl_y); return false; } cctrl->move_flags = flags; internal_set_thing_state(thing, CrSt_MoveToPosition); cctrl->moveto_pos.x.val = locpos.x.val; cctrl->moveto_pos.y.val = locpos.y.val; cctrl->moveto_pos.z.val = locpos.z.val; SYNCDBG(19,"%s: Done",func_name); return true; }
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; } }
void update_explored_flags_for_power_sight(struct PlayerInfo *player) { struct Dungeon *dungeon; struct Thing *thing; SYNCDBG(9,"Starting"); //_DK_update_explored_flags_for_power_sight(player); dungeon = get_players_dungeon(player); LbMemorySet(backup_explored, 0, sizeof(backup_explored)); if (dungeon->sight_casted_thing_idx == 0) { return; } thing = thing_get(dungeon->sight_casted_thing_idx); if (!thing_is_object(thing)) { ERRORLOG("Sight thing index %d invalid", (int)dungeon->sight_casted_thing_idx); turn_off_sight_of_evil(player->id_number); dungeon->sight_casted_thing_idx = 0; return; } TRACE_THING(thing); // Fill the backup_explored array store_backup_explored_flags_for_power_sight(player, &thing->mappos); update_vertical_explored_flags_for_power_sight(player, &thing->mappos); update_horizonal_explored_flags_for_power_sight(player, &thing->mappos); }
struct Thing *get_trap_for_position(MapSubtlCoord stl_x, MapSubtlCoord stl_y) { struct Thing *thing; struct Map *mapblk; long i; unsigned long k; mapblk = get_map_block_at(stl_x,stl_y); k = 0; i = get_mapwho_thing_index(mapblk); while (i != 0) { thing = thing_get(i); TRACE_THING(thing); if (thing_is_invalid(thing)) { ERRORLOG("Jump to invalid thing detected"); break; } i = thing->next_on_mapblk; // Per thing code start if (thing->class_id == TCls_Trap) { return thing; } // Per thing code end k++; if (k > THINGS_COUNT) { ERRORLOG("Infinite loop detected when sweeping things list"); break; } } return INVALID_THING; }
void redraw_creature_view(void) { SYNCDBG(6,"Starting"); TbGraphicsWindow ewnd; struct PlayerInfo *player; struct Thing *thing; //_DK_redraw_creature_view(); return; player = get_my_player(); if (player->field_45F != 2) player->field_45F = 2; update_explored_flags_for_power_sight(player); thing = thing_get(player->controlled_thing_idx); TRACE_THING(thing); if (!thing_is_invalid(thing)) draw_creature_view(thing); if (smooth_on) { store_engine_window(&ewnd,pixel_size); smooth_screen_area(lbDisplay.WScreen, ewnd.x, ewnd.y, ewnd.width, ewnd.height, lbDisplay.GraphicsScreenWidth); } remove_explored_flags_for_power_sight(player); draw_swipe_graphic(); if ((game.numfield_C & 0x20) != 0) { draw_whole_status_panel(); } draw_gui(); if ((game.numfield_C & 0x20) != 0) { draw_overlay_compass(player->minimap_pos_x, player->minimap_pos_y); } message_draw(); gui_draw_all_boxes(); draw_tooltip(); }
short creature_hero_entering(struct Thing *thing) { struct CreatureControl *cctrl; TRACE_THING(thing); //return _DK_creature_hero_entering(thing); cctrl = creature_control_get_from_thing(thing); if (cctrl->field_282 > 0) { cctrl->field_282--; return CrStRet_Unchanged; } if (cctrl->field_282 == 0) { thing->mappos.z.val = get_ceiling_height(&thing->mappos) - (long)thing->field_58 - 1; cctrl->field_282--; return CrStRet_Modified; } if ( thing_touching_floor(thing) || (((thing->movement_flags & TMvF_Flying) != 0) && thing_touching_flight_altitude(thing))) { set_start_state(thing); return CrStRet_ResetOk; } if (cctrl->field_282 < -500) { set_start_state(thing); return CrStRet_ResetFail; } cctrl->field_282--; return CrStRet_Modified; }
CrStateRet creature_at_changed_lair(struct Thing *creatng) { struct Room *room; TRACE_THING(creatng); //return _DK_creature_at_changed_lair(thing); if (!thing_is_on_own_room_tile(creatng)) { set_start_state(creatng); return CrStRet_ResetFail; } room = get_room_thing_is_on(creatng); if (!room_initially_valid_as_type_for_thing(room, RoK_LAIR, creatng)) { WARNLOG("Room %s owned by player %d is invalid for %s",room_code_name(room->kind),(int)room->owner,thing_model_name(creatng)); set_start_state(creatng); return CrStRet_ResetFail; } if (!creature_add_lair_to_room(creatng, room)) { internal_set_thing_state(creatng, CrSt_CreatureChooseRoomForLairSite); return CrStRet_Modified; } // All done - finish the state set_start_state(creatng); return CrStRet_ResetOk; }
short move_to_position(struct Thing *creatng) { CreatureStateCheck callback; struct CreatureControl *cctrl; struct StateInfo *stati; long move_result; CrCheckRet state_check; long speed; TRACE_THING(creatng); cctrl = creature_control_get_from_thing(creatng); speed = get_creature_speed(creatng); SYNCDBG(18,"Starting to move %s index %d into (%d,%d)",thing_model_name(creatng),(int)creatng->index,(int)cctrl->moveto_pos.x.stl.num,(int)cctrl->moveto_pos.y.stl.num); // Try teleporting the creature if (creature_move_to_using_teleport(creatng, &cctrl->moveto_pos, speed)) { SYNCDBG(8,"Teleporting %s index %d owner %d into (%d,%d) for %s",thing_model_name(creatng),(int)creatng->index,(int)creatng->owner, (int)cctrl->moveto_pos.x.stl.num,(int)cctrl->moveto_pos.y.stl.num,creature_state_code_name(creatng->continue_state)); return 1; } move_result = creature_move_to(creatng, &cctrl->moveto_pos, speed, cctrl->move_flags, 0); state_check = CrCkRet_Available; stati = get_thing_continue_state_info(creatng); if (!state_info_invalid(stati)) { callback = stati->move_check; if (callback != NULL) { SYNCDBG(18,"Doing move check callback for continue state %s",creature_state_code_name(creatng->continue_state)); state_check = callback(creatng); } } if (state_check == CrCkRet_Available) { // If moving was successful if (move_result == 1) { // Back to "main state" internal_set_thing_state(creatng, creatng->continue_state); return CrStRet_Modified; } // If moving failed, do a reset if (move_result == -1) { CrtrStateId cntstat; cntstat = creatng->continue_state; internal_set_thing_state(creatng, cntstat); set_start_state(creatng); SYNCDBG(8,"Couldn't move %s to place required for state %s; reset to state %s",thing_model_name(creatng),creature_state_code_name(cntstat),creatrtng_actstate_name(creatng)); return CrStRet_ResetOk; } // If continuing the job, check for job stress process_job_stress_and_going_postal(creatng); } switch (state_check) { case CrCkRet_Deleted: return CrStRet_Deleted; case CrCkRet_Available: return CrStRet_Modified; default: return CrStRet_ResetOk; } }
TbBool attempt_anger_job_join_enemy(struct Thing *creatng) { struct Thing *heartng; int i, n; n = ACTION_RANDOM(PLAYERS_COUNT); for (i=0; i < PLAYERS_COUNT; i++, n=(n+1)%PLAYERS_COUNT) { if ((n == game.neutral_player_num) || (n == creatng->owner)) continue; struct PlayerInfo *player; player = get_player(n); if (!player_exists(player) || (player->field_2C != 1)) continue; heartng = get_player_soul_container(n); if (thing_exists(heartng) && (heartng->active_state != 3)) { TRACE_THING(heartng); if (creature_can_navigate_to(creatng, &heartng->mappos, NavRtF_Default)) { change_creature_owner(creatng, n); anger_set_creature_anger_all_types(creatng, 0); } } } return false; }
long instf_creature_fire_shot(struct Thing *creatng, long *param) { struct CreatureControl *cctrl; struct Thing *target; int i; TRACE_THING(creatng); cctrl = creature_control_get_from_thing(creatng); if (cctrl->targtng_idx <= 0) { if ((creatng->alloc_flags & TAlF_IsControlled) == 0) i = 4; else i = 1; } else if ((creatng->alloc_flags & TAlF_IsControlled) != 0) { target = thing_get(cctrl->targtng_idx); TRACE_THING(target); if (target->class_id == TCls_Object) i = 1; else i = 2; } else { target = thing_get(cctrl->targtng_idx); TRACE_THING(target); if (target->class_id == TCls_Object) i = 1; else if (target->owner == creatng->owner) i = 2; else i = 4; } if (cctrl->targtng_idx > 0) { target = thing_get(cctrl->targtng_idx); SYNCDBG(8,"The %s index %d fires %s at %s index %d",thing_model_name(creatng),(int)creatng->index,shot_code_name(*param),thing_model_name(target),(int)target->index); TRACE_THING(target); } else { target = NULL; SYNCDBG(8,"The %s index %d fires %s",thing_model_name(creatng),(int)creatng->index,shot_code_name(*param)); } creature_fire_shot(creatng, target, *param, 1, i); return 0; }
long instf_creature_fire_shot(struct Thing *creatng, long *param) { struct CreatureControl *cctrl; struct Thing *target; int i; TRACE_THING(creatng); cctrl = creature_control_get_from_thing(creatng); if (cctrl->targtng_idx <= 0) { if ((creatng->alloc_flags & TAlF_IsControlled) == 0) i = 4; else i = 1; } else if ((creatng->alloc_flags & TAlF_IsControlled) != 0) { target = thing_get(cctrl->targtng_idx); TRACE_THING(target); if (target->class_id == TCls_Object) i = 1; else i = 2; } else { target = thing_get(cctrl->targtng_idx); TRACE_THING(target); if (target->class_id == TCls_Object) i = 1; else if (target->owner == creatng->owner) i = 2; else i = 4; } if (cctrl->targtng_idx > 0) { target = thing_get(cctrl->targtng_idx); TRACE_THING(target); } else { target = NULL; } creature_fire_shot(creatng, target, *param, 1, i); return 0; }
TbBool creature_instance_is_available(const struct Thing *thing, CrInstance inst_id) { struct CreatureControl *cctrl; TRACE_THING(thing); cctrl = creature_control_get_from_thing(thing); if (creature_control_invalid(cctrl)) return false; return cctrl->instance_available[inst_id]; }
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; }
short at_lair_to_sleep(struct Thing *thing) { struct CreatureControl *cctrl; struct Thing *lairtng; struct Room *room; TRACE_THING(thing); //return _DK_at_lair_to_sleep(thing); cctrl = creature_control_get_from_thing(thing); lairtng = thing_get(cctrl->lairtng_idx); TRACE_THING(lairtng); cctrl->target_room_id = 0; if (thing_is_invalid(lairtng) || (cctrl->slap_turns != 0)) { set_start_state(thing); return 0; } if (!creature_will_sleep(thing)) { set_start_state(thing); return 0; } room = get_room_thing_is_on(thing); if (!room_initially_valid_as_type_for_thing(room, RoK_LAIR, thing)) { WARNLOG("Room %s owned by player %d is invalid for %s",room_code_name(room->kind),(int)room->owner,thing_model_name(thing)); set_start_state(thing); return 0; } if ((cctrl->lair_room_id != room->index)) { set_start_state(thing); return 0; } if ( !creature_turn_to_face_angle(thing, lairtng->field_52) ) { internal_set_thing_state(thing, CrSt_CreatureSleep); cctrl->field_82 = 200; thing->movement_flags &= ~TMvF_Flying; } process_lair_enemy(thing, room); return 1; }
struct Thing *get_creature_in_training_room_which_could_accept_partner(struct Room *room, struct Thing *partnertng) { struct CreatureControl *cctrl; struct Thing *thing; unsigned long k; long i; TRACE_THING(partnertng); i = room->creatures_list; k = 0; while (i != 0) { thing = thing_get(i); TRACE_THING(thing); cctrl = creature_control_get_from_thing(thing); if (!creature_control_exists(cctrl)) { ERRORLOG("Jump to invalid creature %d detected",(int)i); break; } i = cctrl->next_in_room; // Per creature code if (thing != partnertng) { if ( (get_creature_state_besides_move(thing) == CrSt_Training) && (cctrl->training.partner_idx == 0) ) { if (get_room_thing_is_on(thing) == room) { return thing; } else { WARNLOG("The %s pretends to be in room but it's not.",thing_model_name(thing)); } } } // Per creature code ends k++; if (k > THINGS_COUNT) { ERRORLOG("Infinite loop detected when sweeping creatures list"); break; } } return INVALID_THING; }
long instf_fart(struct Thing *creatng, long *param) { TRACE_THING(creatng); //return _DK_instf_fart(creatng, param); struct Thing *efftng; efftng = create_effect(&creatng->mappos, 13, creatng->owner); if (!thing_is_invalid(efftng)) efftng->byte_16 = 4; thing_play_sample(creatng,94+UNSYNC_RANDOM(6), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); return 1; }
TbBool good_can_move_to_dungeon_heart(struct Thing *creatng, PlayerNumber plyr_idx) { struct PlayerInfo *player; SYNCDBG(18,"Starting"); TRACE_THING(creatng); player = get_player(plyr_idx); if (!player_exists(player)) { SYNCDBG(3,"The %s cannot move to inactive player %d heart", thing_model_name(creatng), (int)plyr_idx); return false; } struct Thing *heartng; heartng = get_player_soul_container(plyr_idx); TRACE_THING(heartng); if (thing_is_invalid(heartng)) { SYNCDBG(3,"The %s cannot move to player %d which has no heart", thing_model_name(creatng), (int)plyr_idx); return false; } return creature_can_navigate_to(creatng, &heartng->mappos, NavRtF_Default); }
TbBool attempt_anger_job_mad_psycho(struct Thing *creatng) { TRACE_THING(creatng); if (!external_set_thing_state(creatng, CrSt_MadKillingPsycho)) { return false; } struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); cctrl->spell_flags |= CSAfF_MadKilling; cctrl->byte_9A = 0; return true; }
TbBool find_combat_target_passing_by_subtile_but_having_unrelated_job(const struct Thing *creatng, CreatureJob job_kind, MapSubtlCoord stl_x, MapSubtlCoord stl_y, unsigned long *found_dist, struct Thing **found_thing) { struct Thing *thing; struct Map *mapblk; long i; unsigned long k; long dist; mapblk = get_map_block_at(stl_x,stl_y); k = 0; i = get_mapwho_thing_index(mapblk); while (i != 0) { thing = thing_get(i); TRACE_THING(thing); if (thing_is_invalid(thing)) { ERRORLOG("Jump to invalid thing detected"); break; } i = thing->next_on_mapblk; // Per thing code start if (thing_is_creature(thing) && (thing->index != creatng->index) && !creature_has_job(thing, job_kind) && !creature_is_kept_in_custody(thing) && !creature_is_being_unconscious(thing) && !creature_is_dying(thing) && !creature_is_doing_anger_job(thing)) { if (!creature_is_invisible(thing) || creature_can_see_invisible(creatng)) { dist = get_combat_distance(creatng, thing); // If we have combat sight - we want that target, don't search anymore if (creature_can_see_combat_path(creatng, thing, dist) > AttckT_Unset) { *found_dist = dist; *found_thing = thing; return true; } // No combat sight - but maybe it's at least closer than previous one if ( *found_dist > dist ) { *found_dist = dist; *found_thing = thing; } } } // Per thing code end k++; if (k > THINGS_COUNT) { ERRORLOG("Infinite loop detected when sweeping things list"); break; } } return false; }
long instf_eat(struct Thing *creatng, long *param) { TRACE_THING(creatng); //return _DK_instf_eat(creatng, param); struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); if (cctrl->hunger_amount > 0) cctrl->hunger_amount--; apply_health_to_thing_and_display_health(creatng, game.food_health_gain); cctrl->hunger_level = 0; return 1; }
struct Thing *allocate_free_thing_structure_f(unsigned char allocflags, const char *func_name) { struct Thing *thing; long i; // Get a thing from "free things list" i = game.free_things_start_index; // If there is no free thing, try to free an effect if (i >= THINGS_COUNT-1) { if ((allocflags & FTAF_FreeEffectIfNoSlots) != 0) { thing = thing_get(game.thing_lists[TngList_EffectElems].index); if (!thing_is_invalid(thing)) { delete_thing_structure(thing, 0); } else { #if (BFDEBUG_LEVEL > 0) ERRORMSG("%s: Cannot free up effect element to allocate new thing!",func_name); #endif } } i = game.free_things_start_index; } // Now, if there is still no free thing (we couldn't free any) if (i >= THINGS_COUNT-1) { #if (BFDEBUG_LEVEL > 0) ERRORMSG("%s: Cannot allocate new thing, no free slots!",func_name); #endif return INVALID_THING; } // And if there is free one, allocate it thing = thing_get(game.free_things[i]); #if (BFDEBUG_LEVEL > 0) if (thing_exists(thing)) { ERRORMSG("%s: Found existing thing %d in free things list at pos %d!",func_name,(int)game.free_things[i],(int)i); } #endif LbMemorySet(thing, 0, sizeof(struct Thing)); if (thing_is_invalid(thing)) { ERRORMSG("%s: Got invalid thing slot instead of free one!",func_name); return INVALID_THING; } thing->alloc_flags |= TAlF_Exists; thing->index = game.free_things[i]; game.free_things[game.free_things_start_index] = 0; game.free_things_start_index++; TRACE_THING(thing); return thing; }
TbBool set_creature_assigned_job(struct Thing *thing, CreatureJob new_job) { struct CreatureControl *cctrl; TRACE_THING(thing); cctrl = creature_control_get_from_thing(thing); if (creature_control_invalid(cctrl)) { ERRORLOG("The %s index %d has invalid control",thing_model_name(thing),(int)thing->index); return false; } cctrl->job_assigned = new_job; SYNCLOG("Assigned job %s for %s index %d owner %d",creature_job_code_name(new_job),thing_model_name(thing),(int)thing->index,(int)thing->owner); return true; }
TbBool creature_has_ranged_object_weapon(const struct Thing *creatng) { TRACE_THING(creatng); const struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); long inum; for (inum = 1; inum < CREATURE_INSTANCES_COUNT; inum++) { if (cctrl->instance_available[inum]) { if (instance_is_ranged_weapon_vs_objects(inum)) return true; } } return false; }
long instf_reinforce(struct Thing *creatng, long *param) { struct CreatureControl *cctrl; SYNCDBG(16,"Starting"); TRACE_THING(creatng); //return _DK_instf_reinforce(creatng, param); cctrl = creature_control_get_from_thing(creatng); MapSubtlCoord stl_x,stl_y; MapSlabCoord slb_x,slb_y; stl_x = stl_num_decode_x(cctrl->digger.working_stl); stl_y = stl_num_decode_y(cctrl->digger.working_stl); slb_x = subtile_slab_fast(stl_x); slb_y = subtile_slab_fast(stl_y); if (check_place_to_reinforce(creatng, slb_x, slb_y) <= 0) { return 0; } if (cctrl->digger.byte_93 <= 25) { cctrl->digger.byte_93++; if (!S3DEmitterIsPlayingSample(creatng->snd_emitter_id, 172, 0)) { thing_play_sample(creatng, 172, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); } return 0; } cctrl->digger.byte_93 = 0; place_and_process_pretty_wall_slab(creatng, slb_x, slb_y); struct Coord3d pos; pos.x.stl.pos = 128; pos.y.stl.pos = 128; pos.z.stl.pos = 128; long n; for (n=0; n < SMALL_AROUND_LENGTH; n++) { pos.x.stl.num = stl_x + 2 * small_around[n].delta_x; pos.y.stl.num = stl_y + 2 * small_around[n].delta_y; struct Map *mapblk; mapblk = get_map_block_at(pos.x.stl.num, pos.y.stl.num); if (map_block_revealed(mapblk, creatng->owner) && ((mapblk->flags & MapFlg_IsTall) == 0)) { pos.z.val = get_floor_height_at(&pos); create_effect(&pos, imp_spangle_effects[creatng->owner], creatng->owner); } } thing_play_sample(creatng, 41, NORMAL_PITCH, 0, 3, 0, 3, FULL_LOUDNESS); return 0; }