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 good_attack_room(struct Thing *thing) { // Debug code to find incorrect states if (!is_hero_thing(thing)) { ERRORLOG("Non hero %s index %d owner %d - reset",thing_model_name(thing),(int)thing->index,(int)thing->owner); set_start_state(thing); return 0; } //return _DK_good_attack_room(thing); MapSlabCoord base_slb_x,base_slb_y; base_slb_x = subtile_slab_fast(thing->mappos.x.stl.num); base_slb_y = subtile_slab_fast(thing->mappos.y.stl.num); struct Room *room; room = slab_room_get(base_slb_x, base_slb_y); // If the current tile can be destroyed if (room_exists(room) && (room->owner != thing->owner) && !room_cannot_vandalise(room->kind)) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(thing); if (cctrl->instance_id == CrInst_NULL) { set_creature_instance(thing, CrInst_ATTACK_ROOM_SLAB, 1, 0, 0); MapCoord ev_coord_x,ev_coord_y; ev_coord_x = subtile_coord_center(room->central_stl_x); ev_coord_y = subtile_coord_center(room->central_stl_y); event_create_event_or_update_nearby_existing_event(ev_coord_x, ev_coord_y, EvKind_RoomUnderAttack, room->owner, 0); if (is_my_player_number(room->owner)) output_message(SMsg_EnemyDestroyRooms, MESSAGE_DELAY_FIGHT, true); } return 1; } // Otherwise, search around for a tile to destroy long m,n; m = ACTION_RANDOM(SMALL_AROUND_SLAB_LENGTH); for (n=0; n < SMALL_AROUND_SLAB_LENGTH; n++) { MapSlabCoord slb_x,slb_y; slb_x = base_slb_x + (long)small_around[m].delta_x; slb_y = base_slb_y + (long)small_around[m].delta_y; room = slab_room_get(slb_x, slb_y); if (room_exists(room) && (room->owner != thing->owner)) { if (setup_person_move_to_position(thing, slb_x, slb_y, NavRtF_Default)) { thing->continue_state = CrSt_GoodAttackRoom1; return 1; } } m = (m+1) % SMALL_AROUND_SLAB_LENGTH; } set_start_state(thing); return 0; }
short good_arrived_at_attack_room(struct Thing *thing) { struct Room *room; room = get_room_thing_is_on(thing); // If the current tile can be destroyed if (room_exists(room) && (room->owner != thing->owner) && !room_cannot_vandalise(room->kind)) { internal_set_thing_state(thing, CrSt_GoodAttackRoom1); MapCoord ev_coord_x,ev_coord_y; ev_coord_x = subtile_coord_center(room->central_stl_x); ev_coord_y = subtile_coord_center(room->central_stl_y); event_create_event_or_update_nearby_existing_event(ev_coord_x, ev_coord_y, EvKind_RoomUnderAttack, room->owner, 0); if (is_my_player_number(room->owner)) output_message(SMsg_EnemyDestroyRooms, MESSAGE_DELAY_FIGHT, true); return 1; } set_start_state(thing); return 0; }
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; }