#include "xstp_inc_jump"
//#include "jump_include"

int CheckValidErf(string sPrefix)
{
    if (sPrefix == "cac" ||
        sPrefix == "hvh" || 
        sPrefix == "mds" || 
        sPrefix == "poe" ||
        sPrefix == "scd" ||
        sPrefix == "ggd" ||
        sPrefix == "bhm")
    {
        return FALSE;
    }
    
    return TRUE;
}

// Function to check if the user is on the hardcoded list of allowed players
int UserIsOnList(object oUser)
{
    // Get the username of the user
    string sPlayerName = GetName(oUser);

    // Hardcoded list of usernames
    if (sPlayerName == "Renzokuken" ||
        sPlayerName == "XCRs Bitch" ||
        sPlayerName == "IMP-Possible" ||
        sPlayerName == "A USerName I Hope Doesn't Exist")
    {
        return TRUE; // The user is on the list
    }

    return FALSE; // The user is not on the list
}

// Function to check if the target can be grappled (based on the `I_CAN_BE_GRAPPLED` variable)
int TargetCanBeGrappled(object oTarget)
{
    // Check if the target has the local integer `I_CAN_BE_GRAPPLED` set to 1
    if (GetLocalInt(oTarget, "I_CAN_BE_GRAPPLED") == 1)
    {
        return TRUE; // The target can be grappled
    }

    return FALSE; // The target cannot be grappled
}

// Main function for the jump functionality
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);

    // 1. Check if the person USING the item is on the hardcoded list
    if (!UserIsOnList(oUser))
    {
        SendMessageToPC(oUser, "You are not authorized to use this item.");
        return;
    }

    // 2. Check if the person USING the item has the required variable turned on
    if (GetLocalInt(oUser, "ALLOW_JUMP_TOOL") != 1)
    {
        SendMessageToPC(oUser, "You do not have permission to use this item. Please check your permissions.");
        return;
    }

    // 3. Check if the area has the "XS_NO_JUMP_TOOL" restriction
    int nNoJumpTool = GetLocalInt(oArea, "XS_NO_JUMP_TOOL");
    if (nNoJumpTool == 1)
    {
        SendMessageToPC(oUser, "The jump tool cannot be used in this area.");
        return;
    }
    
    // 4. 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;
    }

    // 5. Check if the target is on the allowed list OR has `I_CAN_BE_GRAPPLED` set
    if (!UserIsOnList(oTarget) && !TargetCanBeGrappled(oTarget))
    {
        SendMessageToPC(oUser, "The target player is not on the allowed list and cannot be grappled.");
        return;
    }

    // 6. Check distance between the user and the target
    if (GetDistanceBetween(oUser, oTarget) > 20.0)
    {
        SendMessageToPC(oUser, "The target is too far away.");
        return;
    }

    // If all checks pass, proceed with the jump functionality

    // 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 = EffectCutsceneDominated();
    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!]"));

    // Schedule the jump after the immobilization effect has ended
    ActionJumpToObject(oUser);
}
