void set_sprite_view_isometric(void) { //_DK_set_sprite_view_isometric(); long i; for (i=1; i < THINGS_COUNT; i++) { struct Thing *thing; thing = thing_get(i); if (thing_exists(thing)) { if (thing_is_creature(thing) || ((thing->field_4F & 0x01) == 0)) { int n; n = straight_td_iso(thing->field_44); if (n >= 0) { thing->field_44 = n; long nframes; nframes = keepersprite_frames(thing->field_44); if (nframes != thing->field_49) { ERRORLOG("No frames different between views C%d, M%d, A%d, B%d",thing->class_id,thing->model,thing->field_49,nframes); thing->field_49 = nframes; n = thing->field_49 - 1; if (n > thing->field_48) { n = thing->field_48; } thing->field_48 = n; thing->field_40 = n << 8; } } } } } }
void set_sprite_view_3d(void) { long i; for (i=1; i < THINGS_COUNT; i++) { struct Thing *thing; thing = thing_get(i); if (thing_exists(thing)) { if (thing_is_creature(thing) || ((thing->field_4F & TF4F_DoNotDraw) == 0)) { int n; n = straight_iso_td(thing->anim_sprite); if (n >= 0) { thing->anim_sprite = n; long nframes; nframes = keepersprite_frames(thing->anim_sprite); if (nframes != thing->field_49) { ERRORLOG("No frames different between views C%d, M%d, A%d, B%d",thing->class_id,thing->model,thing->field_49,nframes); thing->field_49 = nframes; n = thing->field_49 - 1; if (n > thing->field_48) { n = thing->field_48; } thing->field_48 = n; thing->field_40 = n << 8; } } } } } }
TbBool can_thing_be_possessed(const struct Thing *thing, PlayerNumber plyr_idx) { //return _DK_can_thing_be_possessed(thing, plyr_idx); if (thing->owner != plyr_idx) return false; if (thing_is_creature(thing)) { if (thing_is_picked_up(thing)) { return false; } if ((thing->active_state == CrSt_CreatureUnconscious) || creature_affected_by_spell(thing, SplK_Teleport)) { return false; } if (creature_is_being_sacrificed(thing) || creature_is_being_summoned(thing)) { return false; } if (creature_is_kept_in_custody_by_enemy(thing)) { return false; } return true; } if (thing_is_object(thing)) { if (object_is_mature_food(thing)) { return true; } return false; } return false; }
void transfer_creature(struct Thing *boxtng, struct Thing *transftng, unsigned char plyr_idx) { SYNCDBG(7,"Starting"); struct CreatureControl *cctrl; if (!thing_exists(boxtng) || (box_thing_to_special(boxtng) != SpcKind_TrnsfrCrtr) ) { ERRORMSG("Invalid transfer box object!"); return; } // Check if 'things' are correct if (!thing_exists(transftng) || !thing_is_creature(transftng) || (transftng->owner != plyr_idx)) { ERRORMSG("Invalid transfer creature thing!"); return; } cctrl = creature_control_get_from_thing(transftng); set_transfered_creature(plyr_idx, transftng->model, cctrl->explevel); remove_thing_from_power_hand_list(transftng, plyr_idx); kill_creature(transftng, INVALID_THING, -1, CrDed_NoEffects|CrDed_NotReallyDying); create_special_used_effect(&boxtng->mappos, plyr_idx); remove_events_thing_is_attached_to(boxtng); force_any_creature_dragging_owned_thing_to_drop_it(boxtng); delete_thing_structure(boxtng, 0); if (is_my_player_number(plyr_idx)) output_message(SMsg_CommonAcknowledge, 0, true); }
void process_disease(struct Thing *creatng) { SYNCDBG(18,"Starting"); //_DK_process_disease(thing); struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); if (!creature_affected_by_spell(creatng, SplK_Disease)) { return; } if (ACTION_RANDOM(100) < game.disease_transfer_percentage) { SubtlCodedCoords stl_num; long n; stl_num = get_subtile_number(creatng->mappos.x.stl.num,creatng->mappos.y.stl.num); for (n=0; n < AROUND_MAP_LENGTH; n++) { struct Thing *thing; struct Map *mapblk; unsigned long k; long i; mapblk = get_map_block_at_pos(stl_num+around_map[n]); k = 0; i = get_mapwho_thing_index(mapblk); while (i != 0) { thing = thing_get(i); if (thing_is_invalid(thing)) { WARNLOG("Jump out of things array"); break; } i = thing->next_on_mapblk; // Per thing code if (thing_is_creature(thing) && ((get_creature_model_flags(thing) & CMF_IsSpecDigger) == 0) && (thing->owner != cctrl->disease_caster_plyridx) && !creature_affected_by_spell(thing, SplK_Disease)) { struct CreatureControl *tngcctrl; tngcctrl = creature_control_get_from_thing(thing); apply_spell_effect_to_thing(thing, SplK_Disease, cctrl->explevel); tngcctrl->disease_caster_plyridx = cctrl->disease_caster_plyridx; } // Per thing code ends k++; if (k > THINGS_COUNT) { ERRORLOG("Infinite loop detected when sweeping things list"); erstat_inc(ESE_InfChainTngPerMapWho); break_mapwho_infinite_chain(mapblk); break; } } } } if (((game.play_gameturn - cctrl->disease_start_turn) % game.disease_lose_health_time) == 0) { apply_damage_to_thing_and_display_health(creatng, game.disease_lose_percentage_health * cctrl->max_health / 100, DmgT_Biological, cctrl->disease_caster_plyridx); } }
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; }
TbBool find_pressure_trigger_trap_target_passing_by_subtile(const struct Thing *traptng, MapSubtlCoord stl_x, MapSubtlCoord stl_y, struct Thing **found_thing) { 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_is_creature(thing) && (thing->owner != traptng->owner)) { if (!creature_is_being_unconscious(thing) && !thing_is_dragged_or_pulled(thing) && !creature_is_kept_in_custody_by_enemy(thing) && !creature_is_dying(thing) && ((get_creature_model_flags(thing) & CMF_IsSpectator) == 0)) { if (!is_neutral_thing(thing) && !players_are_mutual_allies(traptng->owner,thing->owner)) { *found_thing = thing; return true; } } } // Per thing code end k++; if (k > THINGS_COUNT) { ERRORLOG("Infinite loop detected when sweeping things list"); break; } } return false; }
TbBool update_trap_trigger_line_of_sight_90_on_subtile(struct Thing *traptng, 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_is_creature(thing) && (thing->owner != traptng->owner)) { // Trigger for enemy player, or any player for neutral traps (otherwise neutral traps would be useless) if (players_are_enemies(traptng->owner,thing->owner) || is_neutral_thing(traptng)) { if (!creature_is_being_unconscious(thing) && !thing_is_dragged_or_pulled(thing) && !creature_is_kept_in_custody_by_enemy(thing) && !creature_is_dying(thing) && ((get_creature_model_flags(thing) & CMF_IsSpectator) == 0)) { activate_trap(traptng, thing); return true; } } } // Per thing code end k++; if (k > THINGS_COUNT) { ERRORLOG("Infinite loop detected when sweeping things list"); break; } } return false; }
TbBool thing_is_valid_scavenge_target(const struct Thing *calltng, const struct Thing *scavtng) { if (!thing_is_creature(scavtng) || (scavtng->model != calltng->model)) { return false; } if (!is_neutral_thing(scavtng)) { if (!players_are_enemies(calltng->owner, scavtng->owner)) { return false; } } if (thing_is_picked_up(scavtng)) { return false; } if (is_thing_passenger_controlled(scavtng) || creature_is_kept_in_custody(scavtng)) { return false; } if (is_hero_thing(scavtng) && (!gameadd.scavenge_good_allowed)) { return false; } if (is_neutral_thing(scavtng) && (!gameadd.scavenge_neutral_allowed)) { return false; } struct PlayerInfo *scavplyr; scavplyr = INVALID_PLAYER; if (!is_neutral_thing(scavtng)) { scavplyr = get_player(scavtng->owner); } if (scavplyr->controlled_thing_idx != scavtng->index) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(scavtng); if (game.play_gameturn - cctrl->temple_cure_gameturn > game.temple_scavenge_protection_turns) { return true; } } return false; }
/** * Returns a creature manufacturing on a subtile other than given creature. * @param plyr_idx * @param stl_x * @param stl_y * @param othertng * @return */ struct Thing *get_other_creature_manufacturing_on_subtile(PlayerNumber plyr_idx, MapSubtlCoord stl_x, MapSubtlCoord stl_y, struct Thing *othertng) { struct Thing *thing; long i; unsigned long k; struct Map *mapblk; 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->active_state == CrSt_Manufacturing) && (thing->index != othertng->index)) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(thing); if ((cctrl->byte_9A > 1) && (thing->owner == plyr_idx)) { return thing; } } // Per thing code end k++; if (k > THINGS_COUNT) { ERRORLOG("Infinite loop detected when sweeping things list"); break; } } return INVALID_THING; }
TbBool process_scavenge_creature_from_level(struct Thing *scavtng, struct Thing *calltng, long work_value) { struct Dungeon *calldngn; long num_prayers; calldngn = get_dungeon(calltng->owner); if (dungeon_invalid(calldngn)) { ERRORLOG("The %s owner %d can't do scavenging - has no dungeon",thing_model_name(calltng),(int)calltng->owner); return false; } // Compute amount of creatures praying against the scavenge if (!is_neutral_thing(scavtng)) { struct Dungeon *scavdngn; scavdngn = get_dungeon(scavtng->owner); num_prayers = scavdngn->creatures_praying[scavtng->model]; } else { num_prayers = 0; } // Increase scavenging counter, used to break the prayers counter calldngn->creatures_scavenging[scavtng->model]++; // If scavenge is blocked by prayers, return if (calldngn->creatures_scavenging[calltng->model] < 2 * num_prayers) { SYNCDBG(8, "Player %d prayers (%d) are blocking player %d scavenging (%d) of %s", (int)scavtng->owner, (int)num_prayers, (int)calltng->owner, (int)calldngn->creatures_scavenging[calltng->model], thing_model_name(calltng)); return false; } SYNCDBG(18,"The %s index %d scavenges %s index %d",thing_model_name(calltng),(int)calltng->index,thing_model_name(scavtng),(int)scavtng->index); // If we're starting to scavenge a new creature, do the switch if (calldngn->scavenge_targets[calltng->model] != scavtng->index) { calldngn->scavenge_turn_points[calltng->model] = work_value; if (calldngn->scavenge_targets[calltng->model] > 0) { // Stop scavenging old creature struct Thing *thing; thing = thing_get(calldngn->scavenge_targets[calltng->model]); if (thing_is_creature(thing) && (thing->model == calltng->model)) { if (creature_is_being_scavenged(thing)) { set_start_state(thing); } } } // Start the new scavenging calldngn->scavenge_targets[calltng->model] = scavtng->index; if (is_my_player_number(scavtng->owner)) { output_message(SMsg_CreatureScanvenged, 500, 1); } event_create_event(scavtng->mappos.x.val, scavtng->mappos.y.val, EvKind_CreatrScavenged, scavtng->owner, scavtng->index); } else { calldngn->scavenge_turn_points[calltng->model] += work_value; } // Make sure the scavenged creature is in correct state if (!creature_is_being_scavenged(scavtng)) { if (!is_neutral_thing(scavtng)) { external_set_thing_state(scavtng, CrSt_CreatureBeingScavenged); } } long scavpts; scavpts = calculate_correct_creature_scavenge_required(scavtng, calltng->owner); if ((scavpts << 8) < calldngn->scavenge_turn_points[calltng->model]) { SYNCDBG(8,"The %s index %d owner %d accumulated enough points to turn to scavenger",thing_model_name(scavtng),(int)scavtng->index,(int)scavtng->owner); turn_creature_to_scavenger(scavtng, calltng); calldngn->scavenge_turn_points[calltng->model] -= (scavpts << 8); return true; } return false; }
TbBool steal_hero(struct PlayerInfo *player, struct Coord3d *pos) { //TODO CONFIG creature models dependency; put them in config files static ThingModel skip_steal_models[] = {6, 7}; static ThingModel prefer_steal_models[] = {3, 12}; struct Thing *herotng; herotng = INVALID_THING; int heronum; struct Dungeon *herodngn; struct CreatureControl *cctrl; unsigned long k; int i; SYNCDBG(8,"Starting"); herodngn = get_players_num_dungeon(game.hero_player_num); k = 0; if (herodngn->num_active_creatrs > 0) { heronum = ACTION_RANDOM(herodngn->num_active_creatrs); i = herodngn->creatr_list_start; SYNCDBG(4,"Selecting random creature %d out of %d heroes",(int)heronum,(int)herodngn->num_active_creatrs); } else { heronum = 0; i = 0; SYNCDBG(4,"No heroes on map, skipping selection"); } while (i != 0) { struct Thing *thing; thing = thing_get(i); TRACE_THING(thing); 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 TbBool heroallow; heroallow = true; ThingModel skipidx; for (skipidx=0; skipidx < sizeof(skip_steal_models)/sizeof(skip_steal_models[0]); skipidx++) { if (thing->model == skip_steal_models[skipidx]) { heroallow = false; } } if (heroallow) { herotng = thing; } // If we've reached requested hero number, return either current hero on previously selected one if ((heronum <= 0) && thing_is_creature(herotng)) { break; } heronum--; if (i == 0) { i = herodngn->creatr_list_start; } // Thing list loop body ends k++; if (k > CREATURES_COUNT) { ERRORLOG("Infinite loop detected when sweeping creatures list"); erstat_inc(ESE_InfChainTngPerOwner); break; } } if (!thing_is_invalid(herotng)) { move_thing_in_map(herotng, pos); change_creature_owner(herotng, player->id_number); SYNCDBG(3,"Converted %s to owner %d",thing_model_name(herotng),(int)player->id_number); } else { i = ACTION_RANDOM(sizeof(prefer_steal_models)/sizeof(prefer_steal_models[0])); struct Thing *creatng; creatng = create_creature(pos, prefer_steal_models[i], player->id_number); if (thing_is_invalid(creatng)) return false; SYNCDBG(3,"Created %s owner %d",thing_model_name(creatng),(int)player->id_number); } return true; }