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; }
short load_map_ownership_file(LevelNumber lv_num) { struct SlabMap *slb; unsigned long x,y; unsigned char *buf; unsigned long i; long fsize; fsize = (map_subtiles_y+1)*(map_subtiles_x+1); buf = load_single_map_file_to_buffer(lv_num,"own",&fsize,LMFF_None); if (buf == NULL) return false; i = 0; for (y=0; y < (map_subtiles_y+1); y++) for (x=0; x < (map_subtiles_x+1); x++) { slb = get_slabmap_for_subtile(x,y); if ((x < map_subtiles_x) && (y < map_subtiles_y)) slabmap_set_owner(slb,buf[i]); else slabmap_set_owner(slb,NEUTRAL_PLAYER); i++; } LbMemoryFree(buf); return true; }
PlayerNumber get_slab_owner_thing_is_on(const struct Thing *thing) { if (thing_is_invalid(thing)) return game.neutral_player_num; struct SlabMap *slb; slb = get_slabmap_for_subtile(thing->mappos.x.stl.num, thing->mappos.y.stl.num); return slabmap_owner(slb); }
/** * Sets owner of a slab on given position. */ void set_whole_slab_owner(MapSlabCoord slb_x, MapSlabCoord slb_y, PlayerNumber owner) { struct SlabMap *slb; MapSubtlCoord stl_x,stl_y; long i,k; stl_x = STL_PER_SLB * slb_x; stl_y = STL_PER_SLB * slb_y; for (i = 0; i < STL_PER_SLB; i++) { for (k = 0; k < STL_PER_SLB; k++) { slb = get_slabmap_for_subtile(stl_x + k, stl_y + i); slabmap_set_owner(slb, owner); } } }
short tunnelling(struct Thing *creatng) { struct SlabMap *slb; long speed; SYNCDBG(7,"Move %s from (%d,%d)",thing_model_name(creatng),(int)creatng->mappos.x.stl.num,(int)creatng->mappos.y.stl.num); //return _DK_tunnelling(creatng); speed = get_creature_speed(creatng); slb = get_slabmap_for_subtile(creatng->mappos.x.stl.num,creatng->mappos.y.stl.num); struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); struct Coord3d *pos; pos = &cctrl->moveto_pos; if (slabmap_owner(slb) == cctrl->party.target_plyr_idx) { internal_set_thing_state(creatng, CrSt_GoodDoingNothing); return 1; } long move_result; move_result = creature_tunnel_to(creatng, pos, speed); if (move_result == 1) { internal_set_thing_state(creatng, CrSt_TunnellerDoingNothing); return 1; } if (move_result == -1) { ERRORLOG("Bad place to tunnel to!"); set_start_state(creatng); creatng->continue_state = CrSt_Unused; return 0; } // Once per 128 turns, check if we've done digging and can now walk to the place if (((game.play_gameturn + creatng->index) & 0x7F) == 0) { if (creature_can_navigate_to(creatng, pos, NavRtF_Default)) { SYNCDBG(7,"The %s can now walk to (%d,%d), no need to tunnel",thing_model_name(creatng),(int)pos->x.stl.num,(int)pos->y.stl.num); return 1; } } SYNCDBG(7,"The %s cannot reach (%d,%d) by walk",thing_model_name(creatng),(int)pos->x.stl.num,(int)pos->y.stl.num); return 0; }
TbBool is_correct_position_to_perform_job(const struct Thing *creatng, MapSubtlCoord stl_x, MapSubtlCoord stl_y, CreatureJob new_job) { const struct SlabMap *slb; slb = get_slabmap_for_subtile(stl_x, stl_y); const struct Room *room; room = subtile_room_get(stl_x, stl_y); RoomKind job_rkind; job_rkind = get_room_for_job(new_job); if (job_rkind != RoK_NONE) { if (room_is_invalid(room)) { return false; } if (room->kind != job_rkind) { return false; } } if (!is_correct_owner_to_perform_job(creatng, slabmap_owner(slb), new_job)) { return false; } return true; }
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; }
/** * Gives SlabMap struct for slab on which given thing is placed. * @param thing The thing which coordinates are used to retrieve SlabMap. */ struct SlabMap *get_slabmap_thing_is_on(const struct Thing *thing) { if (thing_is_invalid(thing)) return INVALID_SLABMAP_BLOCK; return get_slabmap_for_subtile(thing->mappos.x.stl.num, thing->mappos.y.stl.num); }
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; }