// Tag-based script template.
// This is intended to be a starting point for writing an item's tag-based script.
// Copy this to a script whose name is the tag of the item in question.
// Edit the event handlers (scroll down to find them) as desired.


#include "prc_x2_itemprop"
#include "x2_inc_switches"
#include "prc_inc_spells"

// -----------------------------------------------------------------------------
// This first part is standard and generic.
// There should be no need to edit it; just skip down to the next part.
// -----------------------------------------------------------------------------


// The individual event handlers.

void OnAcquire(object oEventItem, object oAcquiredBy, object oTakenFrom, int nStackSize);
void OnActivate(object oEventItem, object oActTarget, location lActTarget, object oActivator);
void OnEquip(object oEventItem, object oEquippedBy);
void OnHit(object oEventItem, object oHitTarget, object oCaster);
int  OnSpellCast(object oEventItem, int nSpell, object oCaster);
void OnUnacquire(object oEventItem, object oLostBy);
void OnUnequip(object oEventItem, object oUnequippedBy);


// The main function.
void main()
{
    int nEvent = GetUserDefinedItemEventNumber();

    // Spells might continue to their spell scripts. All other events are
    // completely handled by this script.
    if ( nEvent != X2_ITEM_EVENT_SPELLCAST_AT )
        SetExecutedScriptReturnValue();

    // Determine which event triggered this script's execution.
    switch ( nEvent )
    {
        // Item was acquired.
        case X2_ITEM_EVENT_ACQUIRE:
                OnAcquire(GetModuleItemAcquired(), GetModuleItemAcquiredBy(),
                          GetModuleItemAcquiredFrom(), GetModuleItemAcquiredStackSize());
                break;

        // Item was activated ("activate item" or "unique power").
        case X2_ITEM_EVENT_ACTIVATE:
                OnActivate(GetItemActivated(), GetItemActivatedTarget(),
                           GetItemActivatedTargetLocation(), GetItemActivator());
                break;

        // Item was equipped by a PC.
        case X2_ITEM_EVENT_EQUIP:
                OnEquip(GetPCItemLastEquipped(), GetPCItemLastEquippedBy());
                break;

        // Item is a weapon that just hit a target, or it is the armor of someone
        // who was just hit.
        case X2_ITEM_EVENT_ONHITCAST:
                OnHit(PRCGetSpellCastItem(), PRCGetSpellTargetObject(), OBJECT_SELF);
                break;

        // A PC (or certain NPCs) cast a spell at the item.
        case X2_ITEM_EVENT_SPELLCAST_AT:
                if ( OnSpellCast(PRCGetSpellTargetObject(), PRCGetSpellId(), OBJECT_SELF) )
                    SetExecutedScriptReturnValue();
                break;

        // Item was unacquired.
        case X2_ITEM_EVENT_UNACQUIRE:
                OnUnacquire(GetModuleItemLost(), GetModuleItemLostBy());
                break;

        // Item was unequipped by a PC.
        case X2_ITEM_EVENT_UNEQUIP:
                OnUnequip(GetPCItemLastUnequipped(), GetPCItemLastUnequippedBy());
                break;
    }
}


// -----------------------------------------------------------------------------
// Event handlers
// -----------------------------------------------------------------------------
// This second part is where you add your desired functionality. Each event
// has its own function with relavant information passed as parameters.
// -----------------------------------------------------------------------------


// -----------------------------------------------------------------------------
// oEventItem was acquired (by a PC or an NPC).
// Run by the module.
void OnAcquire(object oEventItem, object oAcquiredBy, object oTakenFrom, int nStackSize)
{
    // Default: do nothing.
}


// -----------------------------------------------------------------------------
// oEventItem was activated ("activate item" or "unique power").
// Run by the module.
void OnActivate(object oEventItem, object oActTarget, location lActTarget, object oActivator)
{
    int nType;
    object oPC = oActivator;

    // The target must be a certain type of object.
    nType = GetBaseItemType(oActTarget);
    if ( nType != BASE_ITEM_BASTARDSWORD && nType != BASE_ITEM_BATTLEAXE && nType != BASE_ITEM_CLUB
    && nType != BASE_ITEM_DAGGER && nType != BASE_ITEM_DIREMACE && nType != BASE_ITEM_DOUBLEAXE
    && nType != BASE_ITEM_DWARVENWARAXE && nType != BASE_ITEM_GREATAXE && nType != BASE_ITEM_GREATSWORD
    && nType != BASE_ITEM_HALBERD && nType != BASE_ITEM_HANDAXE && nType != BASE_ITEM_HEAVYFLAIL
    && nType != BASE_ITEM_KAMA && nType != BASE_ITEM_KATANA && nType != BASE_ITEM_KUKRI
    && nType != BASE_ITEM_LIGHTFLAIL && nType != BASE_ITEM_LIGHTHAMMER && nType != BASE_ITEM_LONGSWORD
    && nType != BASE_ITEM_LIGHTMACE && nType != BASE_ITEM_MORNINGSTAR && nType != BASE_ITEM_RAPIER
    && nType != BASE_ITEM_QUARTERSTAFF && nType != BASE_ITEM_SCIMITAR && nType != BASE_ITEM_SCYTHE
    && nType != BASE_ITEM_SHORTSWORD && nType != BASE_ITEM_SICKLE && nType != BASE_ITEM_SHORTSPEAR
    && nType != BASE_ITEM_TRIDENT && nType != BASE_ITEM_TWOBLADEDSWORD && nType != BASE_ITEM_WARHAMMER
    && nType != BASE_ITEM_WHIP)
    {
        SendMessageToPC(oActivator, "You can only use runes on melee weapons!");
        return;
    }

    //Get all the info about the runestone
    string sResRef = GetResRef(oEventItem); //ex. "run_edivi04"
    string sRuneInfo = GetStringRight(sResRef, 7); //ex. "edivi04"
    string sDamage = GetStringRight(sRuneInfo, 2); //ex. "04"
    string sDuration = GetStringLeft(sRuneInfo, 1); //ex. "e"
    string sType = GetStringRight(GetStringLeft(sRuneInfo, 5), 4); //ex. "divi"

    //If duration is permanent and the rune is supposed to add bonus damage, check for existing properties on the item
    itemproperty iProp = GetFirstItemProperty(oActTarget);
    if (GetIsItemPropertyValid(iProp) && sDamage != "00" && sDuration == "e")
    {
        SendMessageToPC(oActivator, "You can't add permanent damage bonus to weapons with existing properties!");
        return;
    }

    //This part handles "visual" runes
    if (sDamage == "00")
    {
        int nVisual;
        if (sType == "dark") nVisual = 9;
        if (sType == "blfi") nVisual = 17;
        if (sType == "blgl") nVisual = 11;
        if (sType == "blsh") nVisual = 52;
        if (sType == "grfi") nVisual = 18;
        if (sType == "grgl") nVisual = 12;
        if (sType == "grsh") nVisual = 35;
        if (sType == "orfi") nVisual = 48;
        if (sType == "orgl") nVisual = 13;
        if (sType == "orsh") nVisual = 51;
        if (sType == "pufi") nVisual = 19;
        if (sType == "pugl") nVisual = 14;
        if (sType == "push") nVisual = 38;
        if (sType == "whfi") nVisual = 21;
        if (sType == "whgl") nVisual = 34;
        if (sType == "whsh") nVisual = 36;
        if (sType == "yefi") nVisual = 22;
        if (sType == "yegl") nVisual = 16;
        if (sType == "yesh") nVisual = 37;

        iProp = GetFirstItemProperty(oActTarget);
        while (GetIsItemPropertyValid(iProp))
        {
            if (GetItemPropertyType(iProp) == ITEM_PROPERTY_VISUALEFFECT)
            {
                SendMessageToPC(oActivator, "You can't add a visual effect to this item!");
                return;
            }
            iProp = GetNextItemProperty(oActTarget);
        }

        effect eVFX = EffectVisualEffect(VFX_FNF_DISPEL);
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oActivator);

        iProp = ItemPropertyVisualEffect(nVisual);
        IPSafeAddItemProperty(oActTarget, iProp);
        DestroyObject(oEventItem);
    }

    //Apply a visual effect.
    effect eVFX = EffectVisualEffect(VFX_FNF_DISPEL);
    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oActivator);

    int nDmgType;
    if (sType == "divi") nDmgType = IP_CONST_DAMAGETYPE_DIVINE;
    if (sType == "acid") nDmgType = IP_CONST_DAMAGETYPE_ACID;
    if (sType == "flam") nDmgType = IP_CONST_DAMAGETYPE_FIRE;
    if (sType == "fros") nDmgType = IP_CONST_DAMAGETYPE_COLD;
    if (sType == "vibr") nDmgType = IP_CONST_DAMAGETYPE_SONIC;
    if (sType == "thun") nDmgType = IP_CONST_DAMAGETYPE_ELECTRICAL;

    int nDamage;
    if (sDamage == "02") nDamage = IP_CONST_DAMAGEBONUS_2;
    if (sDamage == "04") nDamage = IP_CONST_DAMAGEBONUS_4;
    if (sDamage == "06") nDamage = IP_CONST_DAMAGEBONUS_6;
    if (sDamage == "08") nDamage = IP_CONST_DAMAGEBONUS_8;
    if (sDamage == "10") nDamage = IP_CONST_DAMAGEBONUS_10;
    if (sDuration == "t") nDamage = IP_CONST_DAMAGEBONUS_5;

    float fDuration = 0.0f;
    if (sDuration == "t") fDuration = 300.0;

    itemproperty ipAdd = ItemPropertyDamageBonus(nDmgType, nDamage);
    if (sDamage != "00")
    {
        IPSafeAddItemProperty(oActTarget, ipAdd, fDuration);
        DestroyObject(oEventItem);
    }
}


// -----------------------------------------------------------------------------
// oEventItem was equipped by a PC.
// Run by the module.
void OnEquip(object oEventItem, object oEquippedBy)
{
    // Default: do nothing.
}


// -----------------------------------------------------------------------------
// oEventItem is a weapon that just hit a target, or it is the armor of someone who
// was just hit by someone else's weapon.
// Run by the caster.
void OnHit(object oEventItem, object oHitTarget, object oCaster)
{
    // Default: do nothing.
}


// -----------------------------------------------------------------------------
// Someone cast a spell at oEventItem.
// This usually only fires if a PC cast the spell, but it also fires for
// DM-possessed NPCs and NPCs in an area with the "X2_L_WILD_MAGIC" local integer set.
//
// Return TRUE to prevent the spell script from firing.
// Return FALSE to proceed normally.
//
// This fires after the UMD check, module spellhook, item creation, and
// sequencer handlers decide they do not want to handle/interrupt this spell.
// This fires before the check to see if this is a spell that normally can
// target items (and before the spell script itself runs).
//
// Run by the caster.
int OnSpellCast(object oEventItem, int nSpell, object oCaster)
{
    // Default: just proceed normally.
    return FALSE;
}


// -----------------------------------------------------------------------------
// oEventItem was unacquired/lost (by a PC or NPC).
// Run by the module.
void OnUnacquire(object oEventItem, object oLostBy)
{
    // Default: do nothing.
}


// -----------------------------------------------------------------------------
// oEventItem was unequipped by a PC.
// Run by the module.
void OnUnequip(object oEventItem, object oUnequippedBy)
{
    // Default: do nothing.
}