void setup_training_move_near(struct Thing *creatng, SubtlCodedCoords stl_num) { SubtlCodedCoords near_stl_num; MapSubtlDelta dist_x,dist_y; long stl_x,stl_y; stl_x = stl_num_decode_x(stl_num); stl_y = stl_num_decode_y(stl_num); // Select a subtile closer to current position dist_x = stl_x - (MapSubtlDelta)creatng->mappos.x.stl.num; dist_y = stl_y - (MapSubtlDelta)creatng->mappos.y.stl.num; if (abs(dist_x) > abs(dist_y)) { if (dist_x > 0) { stl_x -= 1; } else { stl_x += 1; } } else { if (dist_y > 0) { stl_y -= 1; } else { stl_y += 1; } } near_stl_num = get_subtile_number(stl_x,stl_y); setup_training_move(creatng, near_stl_num); }
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; }
long computer_check_for_pretty(struct Computer2 *comp, struct ComputerCheck * check) { struct Dungeon *dungeon; SYNCDBG(8,"Starting"); dungeon = comp->dungeon; MapSubtlCoord stl_x, stl_y; if (computer_able_to_use_magic(comp, PwrK_HAND, 1, 1) != CTaskRet_Unk1) { return CTaskRet_Unk4; } { long stack_len; stack_len = dungeon->digger_stack_length; if (stack_len <= check->param1 * dungeon->total_area / 100) { return CTaskRet_Unk4; } long n; n = find_in_imp_stack_starting_at(DigTsk_ImproveDungeon, ACTION_RANDOM(stack_len), dungeon); if (n < 0) { return CTaskRet_Unk4; } const struct DiggerStack *dstack; dstack = &dungeon->digger_stack[n]; stl_x = stl_num_decode_x(dstack->stl_num); stl_y = stl_num_decode_y(dstack->stl_num); } struct Thing * creatng; creatng = find_imp_for_pickup(comp, stl_x, stl_y); if (thing_is_invalid(creatng)) { return CTaskRet_Unk4; } if (!create_task_move_creature_to_subtile(comp, creatng, stl_x, stl_y, CrSt_ImpImprovesDungeon)) { return CTaskRet_Unk4; } return CTaskRet_Unk1; }
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; } }
void setup_training_move(struct Thing *creatng, SubtlCodedCoords stl_num) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); cctrl->moveto_pos.x.val = subtile_coord_center(stl_num_decode_x(stl_num)); cctrl->moveto_pos.y.val = subtile_coord_center(stl_num_decode_y(stl_num)); cctrl->moveto_pos.z.val = get_thing_height_at(creatng, &cctrl->moveto_pos); if (thing_in_wall_at(creatng, &cctrl->moveto_pos)) { ERRORLOG("Illegal setup to wall at (%d,%d)", (int)cctrl->moveto_pos.x.stl.num, (int)cctrl->moveto_pos.y.stl.num); set_start_state(creatng); } SYNCDBG(18,"The %s is moving to (%d,%d)", thing_model_name(creatng), (int)cctrl->moveto_pos.x.stl.num, (int)cctrl->moveto_pos.y.stl.num); }
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; }
TbBool setup_workshop_move(struct Thing *thing, SubtlCodedCoords stl_num) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(thing); cctrl->moveto_pos.x.stl.num = stl_num_decode_x(stl_num); cctrl->moveto_pos.x.stl.pos = 128; cctrl->moveto_pos.y.stl.num = stl_num_decode_y(stl_num); cctrl->moveto_pos.y.stl.pos = 128; cctrl->moveto_pos.z.val = get_thing_height_at(thing, &cctrl->moveto_pos); if (thing_in_wall_at(thing, &cctrl->moveto_pos)) { ERRORLOG("Illegal setup to subtile (%d,%d)", (int)cctrl->moveto_pos.x.stl.num, (int)cctrl->moveto_pos.y.stl.num); set_start_state(thing); return false; } return true; }
void setup_workshop_search_for_post(struct Thing *creatng) { struct Room *room; struct Thing *postng; postng = INVALID_THING; room = get_room_thing_is_on(creatng); // Find a random slab in the room to be used as our starting point long i; unsigned long n; i = ACTION_RANDOM(room->slabs_count); n = room->slabs_list; while (i > 0) { n = get_next_slab_number_in_room(n); i--; } i = room->slabs_count; while (i > 0) { // Loop the slabs list if (n <= 0) { n = room->slabs_list; } MapSlabCoord slb_x, slb_y; slb_x = subtile_slab_fast(stl_num_decode_x(n)); slb_y = subtile_slab_fast(stl_num_decode_y(n)); struct Thing *objtng; objtng = get_workshop_equipment_to_work_with_on_subtile(creatng->owner, slab_subtile_center(slb_x), slab_subtile_center(slb_y)); if (!thing_is_invalid(objtng)) { postng = objtng; } n = get_next_slab_number_in_room(n); i--; } if (thing_is_invalid(postng)) { SYNCDBG(9,"Work in %s, the %s moves to new pos",room_code_name(room->kind),thing_model_name(creatng)); setup_move_to_new_workshop_position(creatng, room, 1); } else { SYNCDBG(9,"Work in %s, the %s found a post",room_code_name(room->kind),thing_model_name(creatng)); setup_workshop_move(creatng, get_subtile_number(postng->mappos.x.stl.num, postng->mappos.y.stl.num)); } }
short good_back_at_start(struct Thing *thing) { // Debug code to find incorrect states if (!is_hero_thing(thing)) { ERRORLOG("Non hero thing %ld, %s, owner %ld - reset",(long)thing->index,thing_model_name(thing),(long)thing->owner); set_start_state(thing); return false; } //return _DK_good_back_at_start(thing); if (thing->creature.gold_carried <= 0) { set_start_state(thing); return 1; } SubtlCodedCoords stl_num; long m,n; stl_num = get_subtile_number(thing->mappos.x.stl.num,thing->mappos.y.stl.num); m = ACTION_RANDOM(AROUND_MAP_LENGTH); for (n=0; n < AROUND_MAP_LENGTH; n++) { struct Map *mapblk; mapblk = get_map_block_at_pos(stl_num+around_map[m]); // Per-block code if ((mapblk->flags & MapFlg_IsTall) == 0) { MapSubtlCoord stl_x, stl_y; stl_x = stl_num_decode_x(stl_num+around_map[m]); stl_y = stl_num_decode_y(stl_num+around_map[m]); if (setup_person_move_to_position(thing, stl_x, stl_y, NavRtF_Default)) { thing->continue_state = CrSt_GoodDropsGold; return 1; } } // Per-block code ends m = (m + 1) % AROUND_MAP_LENGTH; } set_start_state(thing); return 1; }
long instf_tunnel(struct Thing *creatng, long *param) { struct CreatureControl *cctrl; struct SlabMap *slb; SYNCDBG(16,"Starting"); TRACE_THING(creatng); cctrl = creature_control_get_from_thing(creatng); MapSubtlCoord stl_x,stl_y; stl_x = stl_num_decode_x(cctrl->navi.field_15); stl_y = stl_num_decode_y(cctrl->navi.field_15); slb = get_slabmap_for_subtile(stl_x, stl_y); if (slabmap_block_invalid(slb)) { return 0; } thing_play_sample(creatng, 69+UNSYNC_RANDOM(3), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); if (slb->health > 1) { slb->health--; } else { dig_out_block(stl_x, stl_y, creatng->owner); } return 1; }
long instf_dig(struct Thing *creatng, long *param) { struct CreatureControl *cctrl; struct Dungeon *dungeon; struct SlabMap *slb; long stl_x,stl_y; long task_idx,taskkind; long dig_damage,gold; SYNCDBG(16,"Starting"); TRACE_THING(creatng); //return _DK_instf_dig(thing, param); cctrl = creature_control_get_from_thing(creatng); dungeon = get_dungeon(creatng->owner); task_idx = cctrl->word_91; { struct MapTask *task; task = get_dungeon_task_list_entry(dungeon,task_idx); taskkind = task->kind; if (task->coords != cctrl->word_8F) { return 0; } stl_x = stl_num_decode_x(cctrl->word_8F); stl_y = stl_num_decode_y(cctrl->word_8F); } slb = get_slabmap_for_subtile(stl_x, stl_y); if (slabmap_block_invalid(slb)) { return 0; } dig_damage = calculate_damage_did_to_slab_with_single_hit(creatng, slb); if (slb->health > dig_damage) { if (!slab_kind_is_indestructible(slb->kind)) slb->health -= dig_damage; thing_play_sample(creatng, 63 + UNSYNC_RANDOM(6), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); create_effect(&creatng->mappos, TngEff_Unknown25, creatng->owner); if (taskkind == SDDigTask_MineGold) { gold = calculate_gold_digged_out_of_slab_with_single_hit(dig_damage, creatng->owner, cctrl->explevel, slb); creatng->creature.gold_carried += gold; dungeon->lvstats.gold_mined += gold; } return 0; } // slb->health <= dig_damage - we're going to destroy the slab remove_from_task_list(creatng->owner, task_idx); if (taskkind == SDDigTask_MineGold) { gold = calculate_gold_digged_out_of_slab_with_single_hit(slb->health, creatng->owner, cctrl->explevel, slb); creatng->creature.gold_carried += gold; dungeon->lvstats.gold_mined += gold; mine_out_block(stl_x, stl_y, creatng->owner); if (dig_has_revealed_area(stl_x, stl_y, creatng->owner)) { EventIndex evidx; evidx = event_create_event_or_update_nearby_existing_event( subtile_coord_center(stl_x), subtile_coord_center(stl_y), EvKind_AreaDiscovered, creatng->owner, 0); if ((evidx > 0) && is_my_player_number(creatng->owner)) output_message(SMsg_DugIntoNewArea, 0, true); } } else if (taskkind == SDDigTask_DigEarth) { dig_out_block(stl_x, stl_y, creatng->owner); if (dig_has_revealed_area(stl_x, stl_y, creatng->owner)) { EventIndex evidx; evidx = event_create_event_or_update_nearby_existing_event( subtile_coord_center(stl_x), subtile_coord_center(stl_y), EvKind_AreaDiscovered, creatng->owner, 0); if ((evidx > 0) && is_my_player_number(creatng->owner)) output_message(SMsg_DugIntoNewArea, 0, true); } } check_map_explored(creatng, stl_x, stl_y); thing_play_sample(creatng, 72 + UNSYNC_RANDOM(3), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); return 1; }
long process_creature_in_workshop(struct Thing *creatng, struct Room *room) { //return _DK_process_creature_in_workshop(creatng, room); struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); struct Dungeon *dungeon; dungeon = get_dungeon(creatng->owner); if ((game.play_gameturn - dungeon->field_118B < 50) && ((game.play_gameturn + creatng->index) & 3) == 0) { if (cctrl->instance_id == CrInst_NULL) { set_creature_instance(creatng, CrInst_CELEBRATE_SHORT, 1, 0, 0); } return 1; } if (cctrl->instance_id != CrInst_NULL) { return 1; } long mvret; MapSlabCoord slb_x, slb_y; SYNCDBG(19,"Work in %s, the %s in state %d",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A); switch (cctrl->byte_9A) { case 1: cctrl->byte_9E--; if (cctrl->byte_9E <= 0) { setup_workshop_search_for_post(creatng); cctrl->byte_9E = 100; break; } mvret = creature_move_to(creatng, &cctrl->moveto_pos, get_creature_speed(creatng), 0, 0); if (mvret != 1) { if (mvret == -1) { SYNCDBG(9,"Room %s move problem, the %s goes from %d to start state",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A); set_start_state(creatng); } break; } slb_x = subtile_slab_fast(creatng->mappos.x.stl.num); slb_y = subtile_slab_fast(creatng->mappos.y.stl.num); struct Thing *objtng; objtng = get_workshop_equipment_to_work_with_on_subtile(creatng->owner, slab_subtile_center(slb_x),slab_subtile_center(slb_y)); if (!thing_is_invalid(objtng)) { SYNCDBG(19,"Got %s post, the %s goes from %d to 2",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A); cctrl->byte_9A = 2; cctrl->byte_9E = 100; break; } SYNCDBG(19,"No %s post at current pos, the %s goes from %d to search position",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A); setup_move_to_new_workshop_position(creatng, room, 0); break; case 2: { SubtlCodedCoords stl_num; stl_num = find_unused_adjacent_position_in_workshop(&creatng->mappos, creatng->owner); if (stl_num != 0) { slb_x = subtile_slab_fast(stl_num_decode_x(stl_num)); slb_y = subtile_slab_fast(stl_num_decode_y(stl_num)); cctrl->byte_9C = slab_subtile_center(slb_x); cctrl->byte_9D = slab_subtile_center(slb_y); setup_workshop_move(creatng, stl_num); cctrl->byte_9A = 3; break; } SYNCDBG(9,"No free adjacent %s post, the %s goes from %d to search position",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A); setup_move_to_new_workshop_position(creatng, room, 1); break; } case 3: { mvret = creature_move_to(creatng, &cctrl->moveto_pos, get_creature_speed(creatng), 0, 0); if (mvret != 1) { if (mvret == -1) { SYNCDBG(9,"Room %s move problem, the %s goes from %d to start state",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A); set_start_state(creatng); } break; } struct Thing *mnfc_creatng; mnfc_creatng = get_other_creature_manufacturing_on_subtile(creatng->owner, creatng->mappos.x.stl.num, creatng->mappos.y.stl.num, creatng); if (thing_is_invalid(mnfc_creatng)) { cctrl->byte_9A = 4; break; } // Position used by another manufacturer SYNCDBG(9,"The %s post already in use, the %s goes from %d to search position",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A); setup_move_to_new_workshop_position(creatng, room, 1); break; } case 4: { struct Coord3d pos; pos.x.val = subtile_coord_center(cctrl->byte_9C); pos.y.val = subtile_coord_center(cctrl->byte_9D); if (creature_turn_to_face(creatng, &pos) < 56) { cctrl->byte_9A = 5; cctrl->byte_9B = 75; } break; } case 5: default: cctrl->byte_9B--; if (cctrl->byte_9B <= 0) { SYNCDBG(9,"Room %s move counter %d, the %s keeps moving in state %d",room_code_name(room->kind),(int)cctrl->byte_9B,thing_model_name(creatng),(int)cctrl->byte_9A); setup_move_to_new_workshop_position(creatng, room, 1); } else if ((cctrl->byte_9B % 8) == 0) { set_creature_instance(creatng, CrInst_SWING_WEAPON_SWORD, 1, 0, 0); } break; } return 1; }