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;
}
示例#2
0
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;
    }
}
示例#3
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;
}
示例#5
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;
}