TbBool creature_move_to_using_teleport(struct Thing *thing, struct Coord3d *pos, long walk_speed) { struct CreatureControl *cctrl; short destination_valid; cctrl = creature_control_get_from_thing(thing); if (creature_instance_is_available(thing, CrInst_TELEPORT) && creature_instance_has_reset(thing, CrInst_TELEPORT) && (cctrl->instance_id == CrInst_NULL)) { // Creature can only be teleported to a revealed location destination_valid = true; if (!is_hero_thing(thing) && !is_neutral_thing(thing)) { destination_valid = subtile_revealed(pos->x.stl.num, pos->y.stl.num, thing->owner); } if (destination_valid) { // Use teleport only over large enough distances if (get_2d_box_distance(&thing->mappos, pos) > COORD_PER_STL*game.min_distance_for_teleport) { set_creature_instance(thing, CrInst_TELEPORT, 1, 0, pos); return true; } } } return false; }
long creature_move_direct_line_backwards(struct Thing *thing, struct Coord3d *nextpos, MoveSpeed speed) { if (creature_turn_to_face_backwards(thing, nextpos) > 0) { // Creature is turning - don't let it move creature_set_speed(thing, 0); return 2; } struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(thing); creature_set_speed(thing, -speed); cctrl->flgfield_2 |= TF2_Unkn01; if (get_2d_box_distance(&thing->mappos, nextpos) > -2*cctrl->move_speed) { ERRORDBG(3,"The %s index %d tried to reach (%d,%d) from (%d,%d) with excessive backward speed", thing_model_name(thing),(int)thing->index,(int)nextpos->x.stl.num,(int)nextpos->y.stl.num, (int)thing->mappos.x.stl.num,(int)thing->mappos.y.stl.num); cctrl->moveaccel.x.val = distance_with_angle_to_coord_x(cctrl->move_speed, thing->move_angle_xy); cctrl->moveaccel.y.val = distance_with_angle_to_coord_y(cctrl->move_speed, thing->move_angle_xy); cctrl->moveaccel.z.val = 0; return 1; } else { cctrl->moveaccel.x.val = nextpos->x.val - (MapCoordDelta)thing->mappos.x.val; cctrl->moveaccel.y.val = nextpos->y.val - (MapCoordDelta)thing->mappos.y.val; cctrl->moveaccel.z.val = 0; return 0; } }
void lightning_modify_palette(struct Thing *thing) { struct PlayerInfo *myplyr; // _DK_lightning_modify_palette(thing); myplyr = get_my_player(); if (thing->health == 0) { PaletteSetPlayerPalette(myplyr, engine_palette); myplyr->field_3 &= ~0x08; return; } if (myplyr->acamera == NULL) { ERRORLOG("No active camera"); return; } if (((thing->health % 8) != 7) && (thing->health != 1) && (ACTION_RANDOM(4) != 0)) { if ((myplyr->field_3 & 0x08) != 0) { if (get_2d_box_distance(&myplyr->acamera->mappos, &thing->mappos) < 11520) { PaletteSetPlayerPalette(myplyr, engine_palette); myplyr->field_3 &= ~0x08; } } return; } if ((myplyr->view_mode != PVM_ParchFadeIn) && (myplyr->view_mode != PVM_ParchFadeOut) && (myplyr->view_mode != PVM_ParchmentView)) { if ((myplyr->field_3 & 0x08) == 0) { if (get_2d_box_distance(&myplyr->acamera->mappos, &thing->mappos) < 11520) { PaletteSetPlayerPalette(myplyr, lightning_palette); myplyr->field_3 |= 0x08; } } } }
long creature_move_to_using_gates(struct Thing *thing, struct Coord3d *pos, MoveSpeed speed, long a4, NaviRouteFlags flags, TbBool backward) { struct Coord3d nextpos; AriadneReturn follow_result; long i; SYNCDBG(18,"Starting to move %s index %d from (%d,%d) to (%d,%d) with speed %d",thing_model_name(thing), (int)thing->index,(int)thing->mappos.x.stl.num,(int)thing->mappos.y.stl.num,(int)pos->x.stl.num,(int)pos->y.stl.num,(int)speed); TRACE_THING(thing); if ( backward ) { // Rotate the creature 180 degrees to trace route with forward move i = (thing->move_angle_xy + LbFPMath_PI); thing->move_angle_xy = i & LbFPMath_AngleMask; } follow_result = creature_follow_route_to_using_gates(thing, pos, &nextpos, speed, flags); SYNCDBG(18,"The %s index %d route result: %d, next pos (%d,%d)",thing_model_name(thing),(int)thing->index,(int)follow_result,(int)nextpos.x.stl.num,(int)nextpos.y.stl.num); if ( backward ) { // Rotate the creature back i = (thing->move_angle_xy + LbFPMath_PI); thing->move_angle_xy = i & LbFPMath_AngleMask; } if ((follow_result == AridRet_PartOK) || (follow_result == AridRet_Val2)) { creature_set_speed(thing, 0); return -1; } if (follow_result == AridRet_FinalOK) { return 1; } struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(thing); if ( backward ) { if (creature_turn_to_face_backwards(thing, &nextpos) > 0) { // Creature is turning - don't let it move creature_set_speed(thing, 0); } else { creature_set_speed(thing, -speed); cctrl->flgfield_2 |= TF2_Unkn01; if (get_2d_box_distance(&thing->mappos, &nextpos) > -2*cctrl->move_speed) { ERRORDBG(3,"The %s index %d tried to reach (%d,%d) from (%d,%d) with excessive backward speed", thing_model_name(thing),(int)thing->index,(int)nextpos.x.stl.num,(int)nextpos.y.stl.num, (int)thing->mappos.x.stl.num,(int)thing->mappos.y.stl.num); cctrl->moveaccel.x.val = distance_with_angle_to_coord_x(cctrl->move_speed, thing->move_angle_xy); cctrl->moveaccel.y.val = distance_with_angle_to_coord_y(cctrl->move_speed, thing->move_angle_xy); cctrl->moveaccel.z.val = 0; } else { cctrl->moveaccel.x.val = nextpos.x.val - (MapCoordDelta)thing->mappos.x.val; cctrl->moveaccel.y.val = nextpos.y.val - (MapCoordDelta)thing->mappos.y.val; cctrl->moveaccel.z.val = 0; } } SYNCDBG(18,"Backward target set, speed %d, accel (%d,%d)",(int)cctrl->move_speed,(int)cctrl->moveaccel.x.val,(int)cctrl->moveaccel.y.val); } else { if (creature_turn_to_face(thing, &nextpos) > 0) { // Creature is turning - don't let it move creature_set_speed(thing, 0); } else { creature_set_speed(thing, speed); cctrl->flgfield_2 |= TF2_Unkn01; if (get_2d_box_distance(&thing->mappos, &nextpos) > 2*cctrl->move_speed) { ERRORDBG(3,"The %s index %d tried to reach (%d,%d) from (%d,%d) with excessive forward speed", thing_model_name(thing),(int)thing->index,(int)nextpos.x.stl.num,(int)nextpos.y.stl.num, (int)thing->mappos.x.stl.num,(int)thing->mappos.y.stl.num); cctrl->moveaccel.x.val = distance_with_angle_to_coord_x(cctrl->move_speed, thing->move_angle_xy); cctrl->moveaccel.y.val = distance_with_angle_to_coord_y(cctrl->move_speed, thing->move_angle_xy); cctrl->moveaccel.z.val = 0; } else { cctrl->moveaccel.x.val = nextpos.x.val - (MapCoordDelta)thing->mappos.x.val; cctrl->moveaccel.y.val = nextpos.y.val - (MapCoordDelta)thing->mappos.y.val; cctrl->moveaccel.z.val = 0; } } SYNCDBG(18,"Forward target set, speed %d, accel (%d,%d)",(int)cctrl->move_speed,(int)cctrl->moveaccel.x.val,(int)cctrl->moveaccel.y.val); } return 0; }
struct Thing *find_prisoner_for_thing(struct Thing *creatng) { struct CreatureControl *cctrl; struct Thing *thing; unsigned long k; long i; TRACE_THING(creatng); struct Room *room; room = INVALID_ROOM; if (!is_neutral_thing(creatng)) { room = find_nearest_room_for_thing_with_used_capacity(creatng, creatng->owner, RoK_PRISON, NavRtF_Default, 1); } if (room_exists(room)) { i = room->creatures_list; } else { i = 0; } struct Thing *out_creatng; long out_delay; out_creatng = INVALID_THING; out_delay = LONG_MAX; 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 %ld detected",i); break; } i = cctrl->next_in_room; // Per creature code long dist, durt; dist = get_2d_box_distance(&creatng->mappos, &thing->mappos); if (out_delay < 0) { // If we have a victim which isn't frozen, accept only other unfrozen creatures if ((dist <= LONG_MAX) && !creature_affected_by_spell(thing, SplK_Freeze)) { out_creatng = thing; out_delay = -1; } } else if (creature_affected_by_spell(thing, SplK_Freeze)) { // If the victim is frozen, select one which will unfreeze sooner durt = get_spell_duration_left_on_thing(thing, SplK_Freeze); if ((durt > 0) && (out_delay > durt)) { out_creatng = thing; out_delay = durt; } } else { // Found first unfrozen victim - change out_delay to mark thet we no longer want frozen ones out_creatng = thing; out_delay = -1; } // Per creature code ends k++; if (k > THINGS_COUNT) { ERRORLOG("Infinite loop detected when sweeping creatures list"); break; } } return out_creatng; }
long creature_tunnel_to(struct Thing *creatng, struct Coord3d *pos, short speed) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); SYNCDBG(6,"Move %s from (%d,%d) to (%d,%d) with speed %d",thing_model_name(creatng),(int)creatng->mappos.x.stl.num,(int)creatng->mappos.y.stl.num,(int)pos->x.stl.num,(int)pos->y.stl.num,(int)speed); //return _DK_creature_tunnel_to(creatng, pos, a3); long i; cctrl->navi.field_19[0] = 0; if (get_2d_box_distance(&creatng->mappos, pos) <= 32) { // We've reached the destination creature_set_speed(creatng, 0); return 1; } i = cctrl->party.long_8B; if ((i > 0) && (i < LONG_MAX)) { cctrl->party.long_8B++; } if ((pos->x.val != cctrl->navi.pos_final.x.val) || (pos->y.val != cctrl->navi.pos_final.y.val) || (pos->z.val != cctrl->navi.pos_final.z.val)) { pos->z.val = get_thing_height_at(creatng, pos); initialise_wallhugging_path_from_to(&cctrl->navi, &creatng->mappos, pos); } long tnlret; tnlret = get_next_position_and_angle_required_to_tunnel_creature_to(creatng, pos, cctrl->party.byte_8F); if (tnlret == 2) { i = cctrl->navi.field_15; if (cctrl->navi.field_17 != i) { cctrl->navi.field_17 = i; } else if (cctrl->instance_id == CrInst_NULL) { set_creature_instance(creatng, CrInst_TUNNEL, 0, 0, 0); } } MapCoordDelta dist; dist = get_2d_distance(&creatng->mappos, &cctrl->navi.pos_next); if (dist <= 16) { creature_turn_to_face_angle(creatng, cctrl->navi.field_D); creature_set_speed(creatng, 0); return 0; } if (dist > 768) { ERRORLOG("Move %s index %d to (%d,%d) reset - wallhug distance %d too large",thing_model_name(creatng),(int)creatng->index,(int)pos->x.stl.num,(int)pos->y.stl.num,(int)dist); clear_wallhugging_path(&cctrl->navi); creature_set_speed(creatng, speed); return 0; } if (creature_turn_to_face(creatng, &cctrl->navi.pos_next)) { creature_set_speed(creatng, 0); return 0; } cctrl->moveaccel.x.val = cctrl->navi.pos_next.x.val - (MapCoordDelta)creatng->mappos.x.val; cctrl->moveaccel.y.val = cctrl->navi.pos_next.y.val - (MapCoordDelta)creatng->mappos.y.val; cctrl->moveaccel.z.val = 0; cctrl->flgfield_2 |= 0x01; creature_set_speed(creatng, min(speed,dist)); return 0; }