#include "xstp_inc_jump"
//#include "jump_include"

int TargetHasRequiredRing(object oTarget)
{
    object oLeftRing = GetItemInSlot(INVENTORY_SLOT_LEFTRING, oTarget);
    object oRightRing = GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oTarget);

    if (GetTag(oLeftRing) == "I_CAS_SLUTSNATCHER" || GetTag(oRightRing) == "I_CAS_SLUTSNATCHER")
    {
        return TRUE;
    }
    return FALSE;
}


int CheckValidErf(string sPrefix)
{
    if (sPrefix == "cac" ||
    sPrefix == "hvh" || 
    sPrefix == "mds" || 
    sPrefix == "poe" ||
    sPrefix == "scd" ||
    sPrefix == "ggd" ||
    sPrefix == "bhm")
    return FALSE;
    
    else return TRUE;
}

// Custom function to calculate the difference between two vectors
void JumpTargetTowardsUser(object oTarget, object oUser)
{
    float fFraction = 0.25; // Quarter of the distance for each jump

    // Get the current locations of the target and the user
    location lTarget = GetLocation(oTarget);
    location lUser = GetLocation(oUser);

    // Extract positions from locations
    vector vTarget = GetPositionFromLocation(lTarget);
    vector vUser = GetPositionFromLocation(lUser);

    // Calculate the potential new position for the target
    vector vNewPos = Vector(
        vTarget.x + fFraction * (vUser.x - vTarget.x),
        vTarget.y + fFraction * (vUser.y - vTarget.y),
        vTarget.z // Keeping Z constant
    );

    // Create a new location object at the calculated position
    location lNewLocation = Location(GetArea(oTarget), vNewPos, GetFacingFromLocation(lTarget));

    // Jump the target to this location
    AssignCommand(oTarget, ActionJumpToLocation(lNewLocation));
}







void ExecuteJumps(object oTarget, object oUser, int nRemainingJumps)
{
    if (nRemainingJumps <= 0) {
        // Remove the immobilization effect after the last jump
        effect eRemoveImmobilize = EffectCutsceneImmobilize();
        DelayCommand(24.0, RemoveEffect(oTarget, eRemoveImmobilize));
        return;
    }

    // Execute the jump
    DelayCommand(6.0 * (4 - nRemainingJumps), JumpTargetTowardsUser(oTarget, oUser));

    // Schedule the next jump
    DelayCommand(6.0, ExecuteJumps(oTarget, oUser, nRemainingJumps - 1));
}




void main()
{
    object oItem = GetEventParamObject(0);
    object oTarget = GetEventParamObject(1);
    object oUser = GetEventParamObject(2);
    
    // Retrieve the area object where the user is located
    object oArea = GetArea(oUser);

    // Check if XS_NO_JUMP_TOOL is set in this area
    int nNoJumpTool = GetLocalInt(oArea, "XS_NO_JUMP_TOOL");
    if (nNoJumpTool == 1)
    {
        SendMessageToPC(oUser, "The jump tool cannot be used in this area.");
        return;
    }
    
    // Check if the area is from a valid ERF
    string sPrefix = GetResRefErfPrefix(GetResRef(oArea));
    if (!CheckValidErf(sPrefix))
    {
        SendMessageToPC(oUser, "Jumpers can't be used in epic dungeons!");
        return;
    }

    // Check if the target has the required ring
    if (!TargetHasRequiredRing(oTarget))
    {
        SendMessageToPC(oUser, "Target does not have the required item equipped in either ring slot.");
        return;
    }

    // Check distance between user and target
    if(GetDistanceBetween(oUser, oTarget) > 20.0)
    {
        SendMessageToPC(oUser, "The target is too far away.");
        return;
    }

    // Apply visual effects
    effect eBeam = EffectBeam(VFX_BEAM_CHAIN, oUser, BODY_NODE_CHEST);
    effect eEntangleVFX = EffectVisualEffect(VFX_DUR_ENTANGLE);
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oTarget, 24.0);
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEntangleVFX, oTarget, 24.0);

    // Immobilize the target
    effect eImmobilize = EffectCutsceneImmobilize();
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eImmobilize, oTarget, 24.0);

    // Command the target to speak
    AssignCommand(oTarget, ActionSpeakString("[The target is wrapped in rope and being dragged towards the Slut Snatcher's user!]"));

    ExecuteJumps(oTarget, oUser, 4);
}