Skip to content

Could Use Help

Hello everyone! I created some modules back in 2002-2004 that ran online in that time period. I had a lot of fun back then and want to create something new in NWN:EE. It's been a long time since I've been in the toolset, but have slowly found my way back around and started creating my next project. I'm getting close to getting something that will be playable, but could use a little help. There are a few scripts I've pulled from my past work that I know were unorganized and probably redundant. I was and still am very novice at this, so would love to find someone that can look over the scripts and help clean them up. I also have a few new ideas, that I could use help getting to work. Is there anyone out there that wouldn't mind me picking their brain and helping out?
Atrophiederic
«1

Comments

  • squattingmonksquattingmonk Member Posts: 59
    Post some of your scripts, either here or on the Neverwinter Vault Forums. There's plenty of people willing to help.
    JFK
  • IronActualIronActual Member Posts: 24
    edited February 2018
    Thanks! I'll try here first. I don't want to spam the forum, so I'll just post everything I'm working on in this thread.

    My first set of scripts go into the Module Properties "OnActivateItem"

    void main()
    {
    object oItem = GetItemActivated();
    object oPC = GetItemActivator();
    object oTarget = GetItemActivatedTarget();
    string sTag = GetTag(oItem);
    int oObject = GetObjectType(oTarget);
    if (sTag == "gem")
    {
    if (!GetIsPC(oPC)) return;
    location lTarget = GetItemActivatedTargetLocation();
    AssignCommand(oPC, ClearAllActions());
    effect eVis = EffectVisualEffect(VFX_IMP_HEALING_X, FALSE);
    effect eEffect = EffectAbilityIncrease(ABILITY_CONSTITUTION,1);
    int iConstitution = GetAbilityScore(oPC,ABILITY_CONSTITUTION);
    ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eVis, lTarget, 6.0);
    CreateObject(OBJECT_TYPE_PLACEABLE,"townportal",lTarget,TRUE);
    DeleteLocalLocation(oPC, "Portal"+GetName(oPC));
    SetLocalLocation(oPC, "Portal"+GetName(oPC), GetItemActivatedTargetLocation());
    }
    if (sTag == "destroyer")
    {
    if (oObject==OBJECT_TYPE_ITEM)
    {
    if(GetTag(oTarget)=="destroyer")
    {
    }
    if(GetTag(oTarget)=="gem")
    {
    }
    if(GetStringLeft(GetTag(oTarget),3)=="off")
    {
    }
    if(GetStringLeft(GetTag(oTarget),2)=="NW")
    {
    DestroyObject(oTarget);
    }
    if(GetStringLeft(GetTag(oTarget),3)=="sta")
    {
    DestroyObject(oTarget);
    }
    if(GetStringLeft(GetTag(oTarget),3)=="blu")
    {
    GiveGoldToCreature(oPC,10);
    DestroyObject(oTarget);
    }
    if(GetStringLeft(GetTag(oTarget),3)=="pur")
    {
    GiveGoldToCreature(oPC,25);
    DestroyObject(oTarget);
    }
    if(GetStringLeft(GetTag(oTarget),3)=="yel")
    {
    GiveGoldToCreature(oPC,100);
    DestroyObject(oTarget);
    }
    if(GetStringLeft(GetTag(oTarget),3)=="red")
    {
    GiveGoldToCreature(oPC,250);
    DestroyObject(oTarget);
    }
    }
    }
    }


    The first part "if (sTag == "gem")" spawns a portal for players to use to return to town and then from town there's another portal that teleports players back to this portal.


    The script that goes into the portal that spawns:

    void main()
    {
    object oPC = GetLastUsedBy();
    location lLoc = GetLocation(GetWaypointByTag("return"));
    {
    if(GetIsPC(oPC) == 1)
    {
    object oTarget = oPC;
    effect eVis = EffectVisualEffect(VFX_IMP_DISPEL, FALSE);
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget, 6.0);
    AssignCommand(oPC, ActionJumpToLocation(lLoc));
    DeleteLocalLocation(oPC, "Portal"+GetName(oPC));
    SetLocalLocation(oPC, "Portal"+GetName(oPC), GetLocation(OBJECT_SELF));
    DestroyObject(OBJECT_SELF,30.0);
    }
    }
    }


    The script in the Town Portal to return players:

    void main()
    {
    object oPC = GetLastUsedBy();
    location lLoc = GetLocalLocation(oPC, "Portal"+GetName(oPC));
    if(GetIsPC(oPC) == 1)
    {
    object oTarget = oPC;
    effect eVis = EffectVisualEffect(VFX_IMP_DISPEL, FALSE);
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget, 6.0);
    AssignCommand(oPC, ActionJumpToLocation(lLoc));
    DeleteLocalLocation(oPC, "Portal"+GetName(oPC));
    }
    }


    The second part in the OnActivateItem script "if (sTag == "destroyer")" is used by players to delete items in their inventory. There's a few items I don't want deleted (the destroyer item itself and the portal gem) and a few that give gold in return. This acts like a mobile merchant.

    I know these are a little messy, so hopefully someone can help clean them up!
    squattingmonk
  • IronActualIronActual Member Posts: 24
    A couple of things I'd like to add to the "OnActivateItem" gem script is to have the portal delete itself after 30 seconds, instead of it deleting when the player uses it. Also, I don't want players spawning the portal in any area that starts with "dun".
  • TerrorbleTerrorble Member Posts: 169
    Comments are in the code.




    void main()
    {
    object oItem = GetItemActivated();
    object oPC = GetItemActivator();
    object oTarget = GetItemActivatedTarget();
    string sTag = GetTag(oItem);
    int oObject = GetObjectType(oTarget);
    if (sTag == "gem")
    {
    if (!GetIsPC(oPC)) return;

    //Look at the left 3 characters of the Tag of the Area the PC is in.
    if( GetStringLeft(GetTag(GetArea(oPC)),3) == "dun" )
    {
    SendMessageToPC(oPC,"You are unable to create a portal in this area.");
    return;
    }


    location lTarget = GetItemActivatedTargetLocation();

    //I don't know if this line is necessary. If everything is working, leave it.
    AssignCommand(oPC, ClearAllActions());


    effect eVis = EffectVisualEffect(VFX_IMP_HEALING_X, FALSE);
    effect eEffect = EffectAbilityIncrease(ABILITY_CONSTITUTION,1);
    int iConstitution = GetAbilityScore(oPC,ABILITY_CONSTITUTION);

    //Are you seeing the VFX_IMP_HEALING_X visual applied at the location?
    //If not, consider using DURATION_TYPE_INSTANT (it isn't a visual that requires a duration.)
    ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eVis, lTarget, 6.0);


    //CreateObject returns the object it created, so you can store that in a variable.
    //Then, you can tell it to destroy what it created.
    object oPortal = CreateObject(OBJECT_TYPE_PLACEABLE,"townportal",lTarget,TRUE);
    DestroyObject(oPortal,30.0);
    DeleteLocalLocation(oPC, "Portal"+GetName(oPC));

    //lTarget is already the location you want so use it instead of calling GetItemActivatedTargetLocation() again. It'll work either way.
    SetLocalLocation(oPC, "Portal"+GetName(oPC), GetItemActivatedTargetLocation());
    }
    if (sTag == "destroyer")
    {
    if (oObject==OBJECT_TYPE_ITEM)
    {
    if(GetTag(oTarget)=="destroyer")
    {
    }
    if(GetTag(oTarget)=="gem")
    {
    }
    if(GetStringLeft(GetTag(oTarget),3)=="off")
    {
    }
    if(GetStringLeft(GetTag(oTarget),2)=="NW")
    {
    DestroyObject(oTarget);
    }
    if(GetStringLeft(GetTag(oTarget),3)=="sta")
    {
    DestroyObject(oTarget);
    }
    if(GetStringLeft(GetTag(oTarget),3)=="blu")
    {
    GiveGoldToCreature(oPC,10);
    DestroyObject(oTarget);
    }
    if(GetStringLeft(GetTag(oTarget),3)=="pur")
    {
    GiveGoldToCreature(oPC,25);
    DestroyObject(oTarget);
    }
    if(GetStringLeft(GetTag(oTarget),3)=="yel")
    {
    GiveGoldToCreature(oPC,100);
    DestroyObject(oTarget);
    }
    if(GetStringLeft(GetTag(oTarget),3)=="red")
    {
    GiveGoldToCreature(oPC,250);
    DestroyObject(oTarget);
    }
    }
    }
    }




    The script that goes into the portal that spawns:

    void main()
    {
    object oPC = GetLastUsedBy();
    location lLoc = GetLocation(GetWaypointByTag("return"));
    {
    if(GetIsPC(oPC) == 1)
    {
    object oTarget = oPC;
    effect eVis = EffectVisualEffect(VFX_IMP_DISPEL, FALSE);

    //Again, if the visual isn't working use DURATION_TYPE_INSTANT
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget, 6.0);
    AssignCommand(oPC, ActionJumpToLocation(lLoc));

    //You already set the location of the portal on the player when you made it.
    //DeleteLocalLocation(oPC, "Portal"+GetName(oPC));
    //SetLocalLocation(oPC, "Portal"+GetName(oPC), GetLocation(OBJECT_SELF));

    //We set the portal to be destroyed in the script that created it, so we don't need it here.
    //DestroyObject(OBJECT_SELF,30.0);
    }
    }
    }


    The script in the Town Portal to return players:

    void main()
    {
    object oPC = GetLastUsedBy();
    location lLoc = GetLocalLocation(oPC, "Portal"+GetName(oPC));
    if(GetIsPC(oPC) == 1)
    {

    //Not needed
    //object oTarget = oPC;
    effect eVis = EffectVisualEffect(VFX_IMP_DISPEL, FALSE);
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oPC, 6.0);
    AssignCommand(oPC, ActionJumpToLocation(lLoc));
    DeleteLocalLocation(oPC, "Portal"+GetName(oPC));
    }
    }


    squattingmonkIronActual
  • squattingmonksquattingmonk Member Posts: 59
    edited February 2018
    Something that helps when posting scripts in the forum is nesting it between <code></code> tags. This maintains your indentation and makes the script easier to read.

    The best way to clean up this script is to replace it with tag-based scripts. This is a technique which allows you to make one script that will work for each activated item. This will help you keep scripts for the "gem" item and "destroyer" item separate. It will also make it simpler to add new scripted items in the future.

    To do this, set the following module scripts:
    OnActivateItem x2_mod_def_act.nss
    OnAcquireItem x2_mod_def_aqu.nss
    OnPlayerEquipItem x2_mod_def_equ.nss
    OnPlayerUnEquipItem x2_mod_def_unequ.nss
    OnUnAcquireItem x2_mod_def_unacqu.nss
    Next, save the following scripts, setting the file name where noted:

    // destroyer.nss // Destroys the targeted item. May give gold depending on the item. #include "x2_inc_switches" void main() { // Only function OnActivateItem int nEvent = GetUserDefinedItemEventNumber(); if (nEvent != X2_ITEM_EVENT_ACTIVATE) return; // Only function if used by a PC object oPC = GetItemActivator(); if (!GetIsPC(oPC)) return; // Only destroy items. object oTarget = GetItemActivatedTarget(); if (GetObjectType(oTarget) != OBJECT_TYPE_ITEM) { SendMessageToPC(oPC, "You can only use this on an item."); return; } // Do not allow these items to be destroyed. // Note: a better way to do this might be to check for the plot flag. string sTarget = GetTag(oTarget); string sPrefix = GetStringLeft(sTarget, 3); if (sTarget == "destroyer" || sTarget == "gem" || sPrefix == "off") { SendMessageToPC(oPC, "This item cannot be destroyed."); return; } // Some items give gold when destroyed int nGold; if (sPrefix == "blu") nGold = 10; else if (sPrefix == "pur") nGold = 25; else if (sPrefix == "yel") nGold = 100; else if (sPrefix == "red") nGold = 250; GiveGoldToCreature(oPC, nGold); DestroyObject(oTarget); }

    // gem.nss // Creates a portal to town at the location the PC targets. The portal will // despawn after 30 seconds. This item will not do anything in areas with tags // beginning with "dun". #include "x2_inc_switches" void main() { // Only function OnActivateItem int nEvent = GetUserDefinedItemEventNumber(); if (nEvent != X2_ITEM_EVENT_ACTIVATE) return; // Only function if used by a PC object oPC = GetItemActivator(); if (!GetIsPC(oPC)) return; // Do not function in areas with tags beginning with "dun" string sArea = GetTag(GetArea(oPC)); if (GetStringLeft(sArea, 3) == "dun") { SendMessageToPC(oPC, "You cannot use this item in this area."); return; } // Create the portal to town location lPortal = GetItemActivatedTargetLocation(); object oPortal = CreateObject(OBJECT_TYPE_PLACEABLE, "townportal", lPortal, TRUE); // Apply a nifty VFX at the location effect eVis = EffectVisualEffect(VFX_IMP_HEALING_X); ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPortal); // Set the portal to self-destruct in 30 seconds DestroyObject(oPortal, 30.0); }

    // Town Portal OnUsed script: // Jumps the PC that uses the portal into town. void main() { // Only function if used by a PC object oPC = GetLastUsedBy(); if (!GetIsPC(oPC)) return; // Apply a nifty VFX to the PC effect eVis = EffectVisualEffect(VFX_IMP_DISPEL); ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC); // Save the portal location on the PC SetLocalLocation(oPC, "Portal", GetLocation(OBJECT_SELF)); // Jump to the town waypoint object oWaypoint = GetWaypointByTag("return"); AssignCommand(oPC, ActionJumpToObject(oWaypoint)); }

    // Return portal OnUsed script: // Jumps the PC that uses the portal back to his last townportal spawn location. void main() { // Only function if used by a PC object oPC = GetLastUsedBy(); if (!GetIsPC(oPC)) return; // Make sure the PC has a valid return location location lPortal = GetLocalLocation(oPC, "Portal"); if (!GetIsObjectValid(GetAreaFromLocation(lPortal))) { SendMessageToPC(oPC, "You cannot use this object."); return; } // Apply a nifty VFX to the PC effect eVis = EffectVisualEffect(VFX_IMP_DISPEL); ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC); // Jump to the return location AssignCommand(oPC, ActionJumpToLocation(lPortal)); }
    Sylvus_MoonbowthirdmouseIronActual
  • IronActualIronActual Member Posts: 24
    edited February 2018
    This is great! Everything is working as intended now, thank you both!

    So here is my next script I'm trying to figure out.

    First, I'll need a script that will spawn 1 of 3 things on a creature's OnSpawn.
    60% chance that 10 gold will spawn on the creature. 35% chance that 1 item from a list of 20 items (will probably grow to more items in the future) will spawn on the creature. 5% chance that 1 item from a different list of 20 items (will probably grow to more items in the future) will spawn on the creature.
    Then, if 1 of those items spawn on the creature, I'd like random properties to be added.

    In the past, I had these properties added to the items from the module's OnAcquireItem for when the player's looted them. But, I'd like these properties added when they spawn on the creature instead. I think it will be more interesting to see the creatures using these random items against the players!

    Here's what I used in the past as an example of the random properties being added to items. So, the items gets 2 properties added. 1 being an Enhancement bonus, and the 2nd being a Elemental Damage. The list of properties will be much larger, but this is small example to give an idea.
    itemproperty en1 = ItemPropertyEnhancementBonus(1); itemproperty en2 = ItemPropertyEnhancementBonus(2); itemproperty en3 = ItemPropertyEnhancementBonus(3); switch (Random(3) + 1) { case 1: IPSafeAddItemProperty(oItem, en1, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); break; case 2: IPSafeAddItemProperty(oItem, en2, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); break; case 3: IPSafeAddItemProperty(oItem, en3, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); break; } itemproperty acid1 = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ACID,IP_CONST_DAMAGEBONUS_1); itemproperty acid2 = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ACID,IP_CONST_DAMAGEBONUS_2); itemproperty acid3 = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ACID,IP_CONST_DAMAGEBONUS_3); switch (Random(3) + 1) { case 1: IPSafeAddItemProperty(oItem, acid1, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); break; case 2: IPSafeAddItemProperty(oItem, acid2, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); break; case 3: IPSafeAddItemProperty(oItem, acid3, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); break; }
  • squattingmonksquattingmonk Member Posts: 59
    Here's a very basic example that shows the bare minimum of what you're asking for. It may be worth doing a search of the Vault to see how some of the treasure systems there work.

    // Place this in the OnSpawn of a creature. It will generate treasure: // - 60% chance that 10 gold will spawn on the creature. // - 35% chance that 1 item from a list of 20 items (will probably grow to more // items in the future) will spawn on the creature. // - 5% chance that 1 item from a different list of 20 items (will probably grow // to more items in the future) will spawn on the creature. // Any spawned items will also receive a random enhancement bonus and a random // acid damage bonus. #include "x2_inc_itemprop" void main() { string sResRef; int nRoll = d100(); if (nRoll <= 60) GiveGoldToCreature(OBJECT_SELF, 10); else if (nRoll <= 95) { // Choose a random resref switch (Random(20)) { case 0: sResRef = "my_item_1"; break; case 1: sResRef = "my_item_2"; break; case 2: sResRef = "my_item_3"; break; // ... case 19: sResRef = "my_item_20"; break; } } else { // Choose a random resref switch (Random(20)) { case 0: sResRef = "my_other_item_1"; break; case 1: sResRef = "my_other_item_2"; break; case 2: sResRef = "my_other_item_3"; break; // ... case 19: sResRef = "my_other_item_20"; break; } } // Give the creature an item if we ought to. object oItem = CreateItemOnObject(sResRef); // If the creature was given an item, add a random item property to it. if (GetIsObjectValid(oItem)) { itemproperty ipBonus = ItemPropertyEnhancementBonus(d3()); itemproperty ipAcid = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ACID, d3()); IPSafeAddItemProperty(oItem, ipBonus); IPSafeAddItemProperty(oItem, ipAcid); } }
    IronActual
  • IronActualIronActual Member Posts: 24
    Nice! I’ll look around there, but I should be able to make this work and add things as needed. Thank you again... I’ve got work to do now!
    squattingmonk
  • IronActualIronActual Member Posts: 24
    edited February 2018
    Just realized something with this part.
    // If the creature was given an item, add a random item property to it. if (GetIsObjectValid(oItem)) { itemproperty ipBonus = ItemPropertyEnhancementBonus(d3()); itemproperty ipAcid = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ACID, d3()); IPSafeAddItemProperty(oItem, ipBonus); IPSafeAddItemProperty(oItem, ipAcid); }
    Some of the items will be armor and ranged weapons. Items blue001 - blue034 are all melee weapons, so the above will work for those. But, blue035 - blue039 are ranged and blue040 - blue043 are armors. Not to mention adding shields, boots, cloaks, etc to the mix. I'll need to add an extra "if" for each item type. Something like this?
    if (sResRef == "blue001" || sResRef == "blue002" || sResRef == "blue003" etc...) { if (GetIsObjectValid(oItem)) { itemproperty ipBonus = ItemPropertyEnhancementBonus(d3()); itemproperty ipAcid = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ACID, d3()); IPSafeAddItemProperty(oItem, ipBonus); IPSafeAddItemProperty(oItem, ipAcid); } } if (sResRef == "blue035" || sResRef == "blue036" || sResRef == "blue037" etc...) { if (GetIsObjectValid(oItem)) { itemproperty ipAttack = ItemPropertyAttackBonus(d3()); IPSafeAddItemProperty(oItem, ipAttack); } }
  • squattingmonksquattingmonk Member Posts: 59
    Just check oItem's base type in your if statement. This makes it so you don't have to keep up with all your resrefs and add new ones to the list every time you want to award a new item.

    IronActual
  • TerrorbleTerrorble Member Posts: 169
    This treasure system has a simple learning curve and will do EXACTLY what you are asking for.

    https://neverwintervault.org/project/nwn1/script/siliconscouts-treasure-spawn-system-18a

    I do not, however, know what's available for adding random enchantments.
    IronActualTheAmethystDragon
  • IronActualIronActual Member Posts: 24
    I have everything working great now! However, I added something to the end of the creature's onspawn script and it doesn't always work.
    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_BREACH), OBJECT_SELF) I even tried adding a delay to the effect, but I only notice the effect working half the time.
  • ProlericProleric Member Posts: 1,268
    Is the delay long enough? I find that, in general, visual effects work reliably on spawn if delayed by 1 second (applied as a SupernaturalEffect if necessary).
    IronActualsquattingmonk
  • IronActualIronActual Member Posts: 24
    That was it, my delay was too short!
  • HimmelweissHimmelweiss Member Posts: 72
    Terrorble said:

    This treasure system has a simple learning curve and will do EXACTLY what you are asking for.

    https://neverwintervault.org/project/nwn1/script/siliconscouts-treasure-spawn-system-18a

    I do not, however, know what's available for adding random enchantments.

    Yup, clearly one of the best treasure systems for NWN1.
    It is not worth it imo to script your own system.
    You can modify the treasure system easily for whatever custom stuff you want.

    This, combined with NESS spawn system is just really everything you need.
    The integrated loot system in NESS isn't really that great, so i replaced it with siliconscouts treasure system.
    IronActual
  • IronActualIronActual Member Posts: 24
    edited March 2018
    Another question. In this part of the script that gives the creatures items to drop as loot, how can I add a stack to some of the items (darts, throwing axes, etc)?
    // Give the creature an item if we ought to. object oItem = CreateItemOnObject(sResRef);
    Would it be easier to add an "if" this item "then" create stack?
    Or would it be easier to just set the max stack size for all items, since regular melee weapons can't stack anyway?
  • squattingmonksquattingmonk Member Posts: 59
    The third parameter of CreateItemOnObject() is the size of the stack to create. So you would do:
    object oItem = CreateItemOnObject(sResRef, OBJECT_SELF, nStackSize);
    It looks like it'd be easier to just set the max stack size. Only one of non-stackable items should be created.
    IronActual
  • IronActualIronActual Member Posts: 24
    Used this and it worked perfect!
    object oItem = CreateItemOnObject(sResRef); SetItemStackSize(oItem, 50); if (GetIsObjectValid(oItem))
  • IronActualIronActual Member Posts: 24
    I'm close to getting ready to host online, thanks to all the help here! I have one more onactivateitem script I'd like to include.

    potion.nss That when used by the player (once a day) gives the player 25% of their total HP back.

    Thank you again!
  • squattingmonksquattingmonk Member Posts: 59
    edited March 2018
    // potion.nss // Heals the PC who drinks it for 25% of his total HP. #include "x2_inc_switches" void main() { // Only function OnActivateItem int nEvent = GetUserDefinedItemEventNumber(); if (nEvent != X2_ITEM_EVENT_ACTIVATE) return; object oPC = GetItemActivator(); int nHeal = GetMaxHitPoints(oPC) / 4; effect eVis = EffectVisualEffect(VFX_IMP_HEALING_G); effect eHeal = EffectHeal(nHeal); eHeal = EffectLinkEffects(eVis, eHeal); ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC); }
    As far as making it once per day, you just control that with the item property.
    IronActual
  • IronActualIronActual Member Posts: 24
    Ran into a problem with one of my areas. I need to delete all creatures when all players exit the area. There is also a portal that needs to be deleted when all players exit. The creatures spawn from a script, so they aren't encounters. So the following doesn't work on them.
    void main() { if(!GetIsPC(GetExitingObject())) { return; } object oPC = GetExitingObject(); if (!GetIsPC(oPC)) return; oPC = GetFirstPC(); while (oPC != OBJECT_INVALID) { if (OBJECT_SELF == GetArea(oPC)) return; else oPC = GetNextPC(); } object oObject = GetFirstObjectInArea(OBJECT_SELF); while (oObject != OBJECT_INVALID) { if (GetIsEncounterCreature(oObject)) DestroyObject(oObject); oObject = GetNextObjectInArea(OBJECT_SELF); } }

    All creatures in the area have tags that start with "mummy" (mummy001, mummy002, etc.) And the portal's tag is "cryptportal".
  • FinalStandFinalStand Member Posts: 87
    There are quite a few area clean up scripts on the vault.


    Some hints though:

    When a PC leaves, mark an area to be cleaned.

    Use a delaycommand to schedule the clean, in say 60 to 90 seconds.

    if a PC enters the area cancel the mark

    if clean finds PC in area, cancel it.


    So basically, PC leaves, you mark it to be cleaned up in 90 seconds. If they come back in, cancel it.

    In your loop:

    Destroy objects at random interval so you don't get a bit lag spike!

    float fDelay = Random(10) * 1.0;
    DelayCommand(fDelay, DestroyObjectAndInventory(oObject));


    Use a DestroyObjectAndInventory type of function. If you are cleaning up BodyBags (default loop drops) you can't just delete them, you need to delete inventory first.


    To check for Creature, do this and !GetIsPC()

    if (GetObjectType(oObject) == OBJECT_TYPE_CREATURE) {

    to clean up Portal by tag:

    if (GetObjectType(oObject) == OBJECT_TYPE_PLACEABLE && GetTag(oObject) == "PortalTag") {


    squattingmonkIronActual
  • IronActualIronActual Member Posts: 24

    if (GetObjectType(oObject) == OBJECT_TYPE_CREATURE) {

    This seemed to work, thanks!
    void main() { if(!GetIsPC(GetExitingObject())) { return; } object oPC = GetExitingObject(); if (!GetIsPC(oPC)) return; oPC = GetFirstPC(); while (oPC != OBJECT_INVALID) { if (OBJECT_SELF == GetArea(oPC)) return; else oPC = GetNextPC(); } object oObject = GetFirstObjectInArea(OBJECT_SELF); while (oObject != OBJECT_INVALID) { if (GetObjectType(oObject) == OBJECT_TYPE_CREATURE) DestroyObject(oObject); oObject = GetNextObjectInArea(OBJECT_SELF); } DestroyObject(GetObjectByTag("cryptportal")); }
  • FinalStandFinalStand Member Posts: 87

    if (GetObjectType(oObject) == OBJECT_TYPE_CREATURE) {

    If there are NPCs in the area, you might want to check for that. The way I do it is by comparing fractions. Delete all hostile creatures, but skip any NPCs that are friendly with a known friendly NPC.


    Otherwise you might end up deleting a merchant or quest giver!
    IronActual
  • IronActualIronActual Member Posts: 24
    Going through everything and putting the finishing touches. Trying to be live for Tuesday's Steam release! For the above destroyer.nss scrypt, I'm thinking of adding a sound the player hears when an item is destroyed and the player receives gold in return. What's the best way to do that and is there a list of all sounds? Also, will this sound only be heard by the player or everyone in the area?
  • squattingmonksquattingmonk Member Posts: 59
    The Lexicon has a list of sounds in the game. You can play one of these sounds using PlaySound(). All nearby players will hear the sound.
    IronActual
  • IronActualIronActual Member Posts: 24
    I'm back with another set of scripts I need help with!

    I have an area that when players enter, a creature spawns (boss001). If another player enters the area and the creature (boss001) already exists, do nothing.

    When all players have left the area, only that creature (boss001) is deleted (not the others in the area).
  • ProlericProleric Member Posts: 1,268
    You can do that with the area OnEnter and OnExit scripts. If the entering/exiting object is a PC, increment/decrement a local int on the area. When the int reaches one, create the boss. When it reaches zero, destroy them.
    squattingmonkIronActual
  • BalkothBalkoth Member Posts: 157
    Do you want the boss to always respawn?

    For example, if I'm the only player in the area and I kill the boss, can I then leave the area and return to immediately respawn the boss with no delay?
    IronActual
  • IronActualIronActual Member Posts: 24
    edited April 2018
    Yes, each time a player or group of players enter the area, I'd like the boss to spawn again.

    Here's what I'm working on and could use help making it work correctly. Thanks for the direction Proleric!


    This is for the onenter of my area.
    void main() { object oTarget; object oSpawn; object oPC = GetEnteringObject(); int iBoss = 1; while (iBoss > 0) { eVFX = EffectVisualEffect(VFX_IMP_HARM); oTarget = GetWaypointByTag("boss001waypoint"); oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "boss001", GetLocation(oTarget)); iBoss--; } }
Sign In or Register to comment.