View Full Version : Scripting Help - Hidden Holes


Rotku
Sun, 10th Jul '05, 12:06pm
Okay. I've been working on a script (NB: I'm terrible at scripting! NWVault and script generators keep me alive, so making my own scripts is something new!) which well...

This script is designed for multiple purposes:
First of all, it gives Ranges and Druids and other PCs who
Would not live inside, a way of safely having a Persistant
Storage outdoors, without having every single passerby
stealing from it. It can also work in houses, for loose
floor boards and the likes
The Second reason is that it allows builders to add
'surprises' to places. Imagin walking along and suddenly
you notice a patch of mushrooms in the forest, or a loose
floorboard where the owner of the house has hidden something.

To quickly sum up what the scripts do...
(a) it checks first of all to see if the PC has found the hole before.
If they have, it spawns the hole in place
(b) If they have not, it will roll a Spot check (currently with a DC15)
If that passes, then they find the hole, and it is spawned in.
(c) When they leave the area, the OnExit script waits 10 seconds before
removing the hole!

HOW TO USE:
-> Step 1: Create a WayPoint where you want the hole to spawn.
I called this 'WP_hole1' although what you call it doesn't
matter so long as you change the script below.
-> Step 2: Create the Placeable you wish to spawn, and make sure its
resref matches the ones below. I called mine '006_hole1'
-> Step 3: Create a trigger in the area you wish for the PCs to be
able to see the hole from. Place the following scripts on
the trigger: OnEnter - rtk_hole_onenter
OnExit - rtk_hole_onexitA Persistant Storage script is used along with the Placeable hole, to allow PCs to store items.

That's atleast what it's meant to do. It works as far as despawning the hole. When the hole is despawned, all the items are thrown out of the hole and left upon the ground, like if you smash a chest or something like that.

What I need, if anyone knows how, is a way to either: (1) Port the hole to a DM Area, and port it back, instead of spawning and destroying it. Or, (2) Have another pChest in a DM Area where the items are saved to once the hole is closed, then the items are removed from the hole until it is opened. This way when it is destoried there'll be no inventory.
Anyhelp would be greatly appriciated!


Below are the scripts that I am using with this system.

Trigger Scripts

OnEnter:
void main()
{

object oPC = GetEnteringObject();

if (!GetIsPC(oPC)) return;

// This is what you want the DC to be,
// just replace the 15 with what ever you want as the DC
int nDC = 15;

// get the skill bonus and assign it to nSkill
int nSkill = GetSkillRank(SKILL_SPOT, oPC);

// Checks if the PC has already found the hole before.
if (GetLocalInt(oPC, "006_holefound1a")== 1) //Change this to the tage of the hole, with an 'a' at the end
{
//Get the Waypoint where the hole will spawn
oTarget = GetWaypointByTag("WP_hole1");//This is the WP where the hole will spawn. Change as needed.

lTarget = GetLocation(oTarget);
//Spawn the Hole at the WP
CreateObject(OBJECT_TYPE_PLACEABLE, "006_hole1", lTarget); //This is the resref of the hole
}


//If they haven't, preform a skill check to see if they find the hole.
//If the skill check is successful, follow the same as above, apart from where otherwise noted.
else if((d20() + nSkill) >= nDC)
{
//Set a local variable so in future you don't have to search for the hole to find it.
SetLocalInt(oPC, "006_holefound1a", 1); //Change this to the tag of the hole Placeable, with an 'a' at the end

oTarget = GetWaypointByTag("WP_hole1"); //This is the WP Tag, change it to the WP where you want the hole to spawn

lTarget = GetLocation(oTarget);

CreateObject(OBJECT_TYPE_PLACEABLE, "006_hole1", lTarget);
//this it the hole Tag. Change it to represent the placeable you want to spawn

}
}OnExit
void main()
{

object oPC = GetExitingObject();

if (!GetIsPC(oPC)) return;

object oTarget;
oTarget = GetObjectByTag("006_hole1");

DestroyObject(oTarget, 0.0);

}Persistant Storage Scripts

ngps_inc
// This script "ngps_inc" contains all of the storage handling logic.

// void main(){}

void ngpsInit(object oBox)
{
if (GetLocalInt(oBox, "ngps_loaded") < 1)
{
SetLocalInt(oBox, "ngps_loaded", 1);
string sFile = "ngps_" + GetTag(GetArea(oBox)) + "_" + GetTag(oBox);
int iSize = GetCampaignInt(sFile, "size");
SetLocalInt(oBox, "ngps_size", iSize);
location lLoc = GetLocation(oBox);
int iIndex = 1;
while (iIndex <= iSize)
{
RetrieveCampaignObject(sFile, "item" + IntToString(iIndex), lLoc, oBox);
iIndex++;
}
object oItem = GetFirstItemInInventory(oBox);
while (oItem != OBJECT_INVALID)
{
SetItemStackSize(oItem, GetLocalInt(oItem, "ngps_stack"));
DeleteLocalInt(oItem, "ngps_stack");
oItem = GetNextItemInInventory(oBox);
}
int iGold = GetCampaignInt(sFile, "gold");
while (iGold > 50000)
{
CreateItemOnObject("nw_it_gold001", oBox, 50000);
iGold -= 50000;
}
CreateItemOnObject("nw_it_gold001", oBox, iGold);
}
}

void ngpsSaveGold(object oBox)
{
string sFile = "ngps_" + GetTag(GetArea(oBox)) + "_" + GetTag(oBox);
int iGold = 0;
object oItem = GetFirstItemInInventory(oBox);
while (oItem != OBJECT_INVALID)
{
if (GetResRef(oItem) == "nw_it_gold001")
iGold += GetItemStackSize(oItem);
oItem = GetNextItemInInventory(oBox);
}
if ((iGold < 1) &amp;&amp; (GetLocalInt(oBox, "ngps_size") < 1))
DestroyCampaignDatabase(sFile);
else
SetCampaignInt(sFile, "gold", iGold);
}

void ngpsUpdate(object oBox, object oItem)
{
if ((GetResRef(oItem) != "nw_it_gold001") &amp;&amp; (GetResRef(oItem) != ""))
{
string sFile = "ngps_" + GetTag(GetArea(oBox)) + "_" + GetTag(oBox);
int iIndex = GetLocalInt(oItem, "ngps_index");
SetLocalInt(oItem, "ngps_stack", GetItemStackSize(oItem));
SetItemStackSize(oItem, 999999);
StoreCampaignObject(sFile, "item" + IntToString(iIndex), oItem);
SetItemStackSize(oItem, GetLocalInt(oItem, "ngps_stack"));
DeleteLocalInt(oItem, "ngps_stack");
}
}

void ngpsAdd(object oBox, object oItem)
{
if ((GetResRef(oItem) != "nw_it_gold001") &amp;&amp; (GetResRef(oItem) != ""))
{
string sFile = "ngps_" + GetTag(GetArea(oBox)) + "_" + GetTag(oBox);
int iSize = GetLocalInt(oBox, "ngps_size");
iSize++;
SetLocalInt(oItem, "ngps_index", iSize);
ngpsUpdate(oBox, oItem);
SetLocalInt(oBox, "ngps_size", iSize);
SetCampaignInt(sFile, "size", iSize);
}
}

void ngpsDelete(object oBox, object oItem)
{
if ((GetResRef(oItem) != "nw_it_gold001") &amp;&amp; (GetResRef(oItem) != ""))
{
string sFile = "ngps_" + GetTag(GetArea(oBox)) + "_" + GetTag(oBox);
int iSize = GetLocalInt(oBox, "ngps_size");
int iIndex = GetLocalInt(oItem, "ngps_index");
// Bioware bug get-around (begin)
// The bug is that items loaded from a campaign database to
// a container lose their local variables when removed.
if (iIndex < 1)
{
while (iIndex <= iSize)
{
iIndex++;
object oLastItem = GetFirstItemInInventory(oBox);
while (oLastItem != OBJECT_INVALID)
{
if (GetLocalInt(oLastItem, "ngps_index") == iIndex)
break;
oLastItem = GetNextItemInInventory(oBox);
}
if (oLastItem == OBJECT_INVALID)
break;
}
}
// Bioware bug get-around (end)
if (iIndex < iSize)
{
object oLastItem = GetFirstItemInInventory(oBox);
while (oLastItem != OBJECT_INVALID)
{
if (GetLocalInt(oLastItem, "ngps_index") == iSize)
break;
oLastItem = GetNextItemInInventory(oBox);
}
SetLocalInt(oLastItem, "ngps_index", iIndex);
ngpsUpdate(oBox, oLastItem);
}
iSize--;
if ((iSize < 1) &amp;&amp; (GetCampaignInt(sFile, "gold") < 1))
{
SetLocalInt(oBox, "ngps_size", 0);
DestroyCampaignDatabase(sFile);
}
else
{
SetLocalInt(oBox, "ngps_size", iSize);
SetCampaignInt(sFile, "size", iSize);
}
DeleteLocalInt(oItem, "ngps_index");
}
}OnOpen
// This script "ngps_onopen" is called by a persistent container's
// onopen event. Persistent containers require a tag unique to the
// area.

#include "ngps_inc"

void main()
{
ngpsInit(OBJECT_SELF);
}OnClose
// This script "ngps_onclose" is called by a persistent container's
// onclose event. Persistent containers require a tag unique to the
// area.

#include "ngps_inc"

void main()
{
ngpsSaveGold(OBJECT_SELF);
}OnDeath
// This script "ngps_ondeath" is called by a persistent container's
// ondeath event. Persistent containers require a tag unique to the
// area.

void main()
{
string sFile = "ngps_" + GetTag(GetArea(OBJECT_SELF)) + "_" + GetTag(OBJECT_SELF);
DestroyCampaignDatabase(sFile);
}OnDisturbed
// This script "ngps_ondisturbed" is called by a persistent container's
// ondistrubed event. Persistent containers require a tag unique to the
// area.

#include "ngps_inc"

void main()
{
object oPC = GetLastDisturbed();
if (GetIsPC(oPC) || GetIsDM(oPC) || GetIsDMPossessed(oPC))
{
object oItem = GetInventoryDisturbItem();
if (GetInventoryDisturbType() == INVENTORY_DISTURB_TYPE_ADDED)
ngpsAdd(OBJECT_SELF, oItem);
else
ngpsDelete(OBJECT_SELF, oItem);
}
}

[ July 10, 2005, 18:29: Message edited by: Blackthorne TA ]

Taza
Sun, 10th Jul '05, 12:20pm
Those scripts seem invalid for the purpose.

I think the DestroyCampaignDatabase() should SERIOUSLY not be there!

I'll look more into it when I've digged up my scripting tools though.

EDIT: Now I've finished studying it, and I need to ask for what purpose this script is needed for. The script overall isn't too smart though.

[ July 10, 2005, 12:55: Message edited by: Taza ]

Rotku
Sun, 10th Jul '05, 11:58pm
Well, the latter group of scripts are just the pStorage sripts that I was planning to add to the hole. They are the most reliable persistant storage that I've found. The first two are the ones that I've described at the top of my first post.