Revamped Level One: North & Level One: Central to be as close to PnP as possible. Added Level One: Latrene 3 area. Added efreeti appearance from CEP3. Revamped efreeti bottle to be like PnP (no wishes, yet)
353 lines
12 KiB
Plaintext
353 lines
12 KiB
Plaintext
// 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 "nw_i0_generic"
|
|
#include "x2_inc_switches"
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// This first part is standard and generic.
|
|
// There should be no need to edit it; just skip down to the next part.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
int RA_DEBUG = 0;
|
|
|
|
// 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(GetSpellCastItem(), GetSpellTargetObject(), OBJECT_SELF);
|
|
break;
|
|
|
|
// A PC (or certain NPCs) cast a spell at the item.
|
|
case X2_ITEM_EVENT_SPELLCAST_AT:
|
|
if ( OnSpellCast(GetSpellTargetObject(), GetSpellId(), 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)
|
|
{
|
|
//:: Declare major variables
|
|
object oPC = oActTarget;
|
|
object oItem = GetItemActivated();
|
|
object oSpawn;
|
|
|
|
effect eEffect;
|
|
effect eVFX;
|
|
|
|
int nRandom = d100(1);
|
|
|
|
if (RA_DEBUG)
|
|
{
|
|
SendMessageToPC(oPC, "Efreeti Bottle Tag Based Script is running");
|
|
SendMessageToPC(oPC, "Rolled a "+ IntToString(nRandom) +".");
|
|
}
|
|
|
|
|
|
//:: Have the item activator check if the player has already summoned an efreeti.
|
|
object oExistingEfreeti = GetNearestObjectByTag("SUM_EFREETI001");
|
|
|
|
eEffect = GetFirstEffect(oPC);
|
|
|
|
while(GetIsEffectValid(eEffect))
|
|
{
|
|
if(GetEffectTag(eEffect) == GetName(oPC)+"SummonedEfreeti")
|
|
RemoveEffect(oPC, eEffect);
|
|
eEffect = GetNextEffect(oPC);
|
|
}
|
|
|
|
if (GetIsObjectValid(oExistingEfreeti))
|
|
{
|
|
SendMessageToPC(oPC, "You can only summon one Efreeti per day.");
|
|
return;
|
|
}
|
|
|
|
//:: If success on a 10% chance.
|
|
if ( nRandom <= 10 )
|
|
{
|
|
//:: Spawn Hostile Efreeti.
|
|
eVFX = EffectVisualEffect(VFX_FNF_GAS_EXPLOSION_FIRE);
|
|
oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "sum_efreeti001", GetLocation(oActivator));
|
|
AssignCommand(oSpawn, DetermineCombatRound(oPC));
|
|
DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oSpawn));
|
|
|
|
// Set the player's "SummonedEfreeti" variable to 1 to mark that an efreeti has been summoned.
|
|
SetLocalInt(oPC, GetName(oPC)+"SummonedEfreeti", 1);
|
|
SendMessageToPC(oPC, "The efreeti is insane and attacks immediately!");
|
|
|
|
//:: Create the non-magical bottle
|
|
object oDeadBottle = CreateItemOnObject("ITM_DEADBOTTLE", oPC, 1);
|
|
|
|
//:: Destroy the original magical bottle
|
|
DestroyObject(oItem);
|
|
}
|
|
//:: Else if, the next 20%.
|
|
/* else if ( nRandom < 21 && nRandom > 10 )
|
|
{
|
|
Remarked out until I get the Wish spell figured out.
|
|
//:: Spawn Friendly Efreeti.
|
|
eVFX = EffectVisualEffect(VFX_FNF_GAS_EXPLOSION_FIRE);
|
|
oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "sum_efreeti001", GetLocation(oActivator));
|
|
AssignCommand(oSpawn, ActionStartConversation(oPC));
|
|
DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oSpawn));
|
|
SetIsTemporaryFriend(oPC, oSpawn, FALSE);
|
|
SendMessageToPC(oPC, "The efreeti is friendly & wants to speak!");
|
|
|
|
// Set the player's "SummonedEfreeti" variable to 1 to mark that an efreeti has been summoned.
|
|
SetLocalInt(oPC, GetName(oPC)+"SummonedEfreeti", 1);
|
|
|
|
//:: Create the non-magical bottle
|
|
object oDeadBottle = CreateItemOnObject("ITM_DEADBOTTLE", oPC, 1);
|
|
|
|
//:: Destroy the original magical bottle
|
|
DestroyObject(oItem);
|
|
} */
|
|
//:: Else, the remainder.
|
|
else
|
|
{
|
|
//:: Have the item activator check if the player has already summoned an efreeti.
|
|
object oExistingEfreeti = GetObjectByTag(GetName(oPC)+"SummonedEfreeti");
|
|
|
|
int nSummoned = GetLocalInt(oPC, GetName(oPC)+"SummonedEfreeti");
|
|
|
|
if (!GetIsObjectValid(oExistingEfreeti) && nSummoned == 0)
|
|
{
|
|
// No Efreeti exists and the player hasn't summoned one yet, so we can summon a new one.
|
|
eEffect = EffectSummonCreature("efreeti001", VFX_FNF_GAS_EXPLOSION_FIRE, 1.0);
|
|
|
|
eEffect = MagicalEffect(eEffect);
|
|
|
|
eEffect = TagEffect(eEffect, GetName(oPC)+"SummonedEfreeti");
|
|
|
|
DelayCommand(0.5f, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, oActivator, 600.0f));
|
|
DelayCommand(600.0f, DeleteLocalInt(oPC, GetName(oPC)+"SummonedEfreeti"));
|
|
SendMessageToPC(oPC, "The efreeti grudgingly serves you for a time.");
|
|
|
|
// Set the player's "SummonedEfreeti" variable to 1 to mark that an efreeti has been summoned.
|
|
SetLocalInt(oPC, GetName(oPC)+"SummonedEfreeti", 1);
|
|
}
|
|
else
|
|
{
|
|
// An Efreeti is already present or has been summoned by the player; inform the player.
|
|
SendMessageToPC(oPC, "You can only summon one Efreeti per day.");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// 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.
|
|
}
|
|
|
|
|
|
//:: void main (){}
|
|
|
|
|
|
/* // Declare constants for the chances of the efreeti's behavior
|
|
const int CHANCE_INSANE = 10;
|
|
const int CHANCE_GRANT_WISHES = 10;
|
|
|
|
// Declare constants for the efreeti's actions
|
|
const int ACTION_INSANE = 1;
|
|
const int ACTION_GRANT_WISHES = 2;
|
|
const int ACTION_SERVE_CHARACTER = 3;
|
|
|
|
#include "nw_i0_generic"
|
|
|
|
void main()
|
|
{
|
|
//:: Declare major variables
|
|
object oPC = GetItemActivator();
|
|
object oItem = GetItemActivated();
|
|
object oSpawn;
|
|
|
|
effect eVFX;
|
|
|
|
//:: Roll a d% to determine the efreeti's behavior
|
|
int nRoll = d100(1);
|
|
|
|
//:: Determine the efreeti's action based on the roll
|
|
int nEfreetiAction;
|
|
|
|
if (nRoll <= CHANCE_INSANE)
|
|
{
|
|
nEfreetiAction = ACTION_INSANE;
|
|
}
|
|
else if (nRoll <= CHANCE_INSANE + CHANCE_GRANT_WISHES)
|
|
{
|
|
nEfreetiAction = ACTION_GRANT_WISHES;
|
|
}
|
|
else
|
|
{
|
|
nEfreetiAction = ACTION_SERVE_CHARACTER;
|
|
}
|
|
|
|
//:: Handle the efreeti's action
|
|
switch (nEfreetiAction)
|
|
{
|
|
case ACTION_INSANE:
|
|
SendMessageToPC(oPC, "The efreeti is insane and attacks immediately!");
|
|
//:: Spawn hostile Efreeti.
|
|
eVFX = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3);
|
|
oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "efreeti001", GetLocation(oPC));
|
|
AssignCommand(oSpawn, DetermineCombatRound(oPC));
|
|
DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oSpawn));
|
|
|
|
break;
|
|
|
|
case ACTION_GRANT_WISHES:
|
|
SendMessageToPC(oPC, "The efreeti is friendly & wants to speak!");
|
|
//:: Spawn friendly Efreeti.
|
|
// Insert code here to handle the granting of wishes
|
|
break;
|
|
|
|
case ACTION_SERVE_CHARACTER:
|
|
SendMessageToPC(oPC, "The efreeti loyally serves you for a time.");
|
|
effect eSummon = EffectSummonCreature("efreeti001", VFX_NONE);
|
|
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eSummon, GetLocation(oPC), TurnsToSeconds(10));
|
|
|
|
/* //:: Summon Efreeti.
|
|
effect eSummon = EffectSummonCreature("efreeti001", VFX_FNF_SUMMON_MONSTER_3);
|
|
DelayCommand(0.5f, ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eSummon, GetLocation(oPC), TurnsToSeconds(10)));
|
|
break;
|
|
}
|
|
|
|
/* // If the efreeti is insane or grants wishes, swap out the bottle with "ITM_DEADBOTTLE"
|
|
if (nEfreetiAction == ACTION_INSANE || nEfreetiAction == ACTION_GRANT_WISHES)
|
|
{
|
|
// Create the non-magical bottle
|
|
object oDeadBottle = CreateObject(OBJECT_TYPE_ITEM, "ITM_DEADBOTTLE", GetLocation(oItem));
|
|
|
|
// Destroy the original magical bottle
|
|
DestroyObject(oItem);
|
|
}
|
|
} */ |