Random Buried Treasure and Maps
#1
Posté 05 août 2013 - 04:43
I've an idea that requires some knowledge that I don't have: I'm looking to make Useable map items that, once used, will spawn a waypoint to a random location on a random area, and then it would tell the player on which area the waypoint is. Or better yet, if it could be made so that everytime the player uses the map, it will tell you which direction you must walk towards (North, East, South, West... ) to get to that waypoint.
Once you'd reach the waypoint, (On percieved script?) it would spawn an "X" on the waypoint (There's a nice X placeable) that would only be visible to the player who used this map. Then you could use a shovel to dig the treasure up. I have random treasure system on place already, but now I want this random buried treasure system.
Anyone got any great ideas ?
#2
Posté 05 août 2013 - 06:05
1) Use preset points, as many as you like, each marked with a waypoint (you could use coordinates with an area, but I'm going for simplicity here).
2) On use of the map, run everything else. If no spot has been picked yet, pick one and store it on the map item as a variable. Then, if the user is not in the destination area, do a floating text on the user telling them the name of the area the treasure is in. Else, if they're not within x meters of the treasure, tell them what direction it's in, with vector math (probably the trickiest bit, converting a float to a string with cardinal/ordinal direction, with a custom function). Else, spawn the treasure and destroy the map item.
Funky
#3
Posté 05 août 2013 - 07:08
Also, I'm completely dumb with scripts, I know something works but I don't know why it works...
So what I need is atleast a template script that I can modify to suit my needs.
Here's a numbered list of what I need and wish:
1. I want to make using this map spawn the waypoint at a random area, to a random walkable location in an area. Spawning it on a raised level without a slope isn't a problem, because I'll make climbing gear later. Likewise spawning it on some little islet that is technically walkable but surrounded by unwalkable water won't be a problem because I will put in ways to get there (Swim... boat..)
2. I'm looking to make different quality maps (Authentic / Unauthentic style, so you might just get a chest full of broken bottles... or a chest full of gold.) so it would be a gamble to get a map instead of gold at a dice table
3. How can I make placeables like the X only visible to the player who activated the said map, so that other players who activate a map with the same tag would not see this aswell ? Can I maybe use "Once per game" conditional, or will it also apply to other maps with it's tag?(These items will create in your inventory when you get them, from the palette. This affects plenty of things in items too, as I've noticed)
4. A template, because my scripting skill is horrible, I can modify things to a point but I can't make stuff from scratch. So I'll need a skilled superhero make me something like this
5. I do think that what you said would be best with how it would run: First it sends you a chatbox message (Name of the area it is in) and when you reach the area, it will tell you in which direction to walk to find it. However, if possible I'd love to have it check some skills like search to successfully determine where it is. I'm not a big fan of not requiring any non-combat skills to be invested in to use cool features. "Wasting power" in favor of RP character build should be heavily rewarded. Always.
#4
Posté 05 août 2013 - 07:12
#5
Posté 08 août 2013 - 04:57
Also, making the red X visible only to a particular PC is going to require NWNX. There are basic NWScript workarounds to keep others from sniping treasure from treasure hunters.
Here's a version I whipped up at work. It compiles and seems to work fine, but there may be a bug or two. I would appreciate any advice folks more experienced than me would have.
The gist is this: when a PC uses the map item, it fires a tag-based script that picks a random waypoint tagged "TreasureWP". If it's in a different area, it tells the PC the area it's in. If it's in the same area, it tells the PC the approximate distance and direction (N, NE, E, etc.) in which the treasure lies. If the PC is within five meters of the treasure waypoint, the treasure chest spawns and the map is destroyed.
Treasure is generated when the chest is opened for the first time. Whether it is junk, normal treasure, or ph4t l00t depends on a die roll. Only the PC who found the treasure may open the chest. The chest will despawn three minutes after it is first opened. Until then, more treasure will not be found at this waypoint. Any PCs unlucky enough to have randomly gotten the same treasure waypoint before the chest has despawned will be informed that someone else has already found the treasure and their map will be destroyed.
To use it:
1: Save this script in your module with its script name as "treasuremap".
2: Save this script as "treasurechest".
3: Make your treasure map item, giving it the Unique Power: Self Only item property and setting its tag to "treasuremap".
4: Make the treasure container (you could use a red X or the buried chest) and set its resref to "treasurechest". Make it usable and give it an inventory. Set its OnOpen script to "treasurechest".
5: Make a waypoint template, giving it the tag "TreasureWP". Place an instance of this waypoint anywhere in the module that you'd like treasure to be found.
6: Edit treasurechest.nss to add the item creation code as indicated by the comments.
Modifié par Squatting Monk, 08 août 2013 - 05:08 .
#6
Posté 08 août 2013 - 06:10
JerrodAmolyan wrote...
That sounds really good, but is there a way to use something like spawning a waypoint that I have now tagged as jer_randomtres_wp, so that this waypoint would be spawned in a -random area- so even I could not tell where it will be spawned ? But like you implied (I think you did...), the problem might be if it spawns into unwalkable tiles (water, cliff,) So is there a command to use to spawn it into a valid location that would be a walkable tile?
If there were, I wouldn't have suggested the approach I did. There is actually a GetIsWalkable in nwnx_functions, but there is still no way to tell if there is a way for a pc to arrive at that walkable spot. By far the simplest way to build that fairly complex determination into the system is just to place the waypoints yourself.
Funky
#7
Posté 08 août 2013 - 08:37
Monk, I'll try this out today, thanks a lot.
Though I might modify it (If I am able) to spawn an X you can talk to and pick "*dig up treasure*" and maybe I can make it perform an animation (I know there's animations like some earth worm tossing around dirt, just need to find it
#8
Posté 08 août 2013 - 08:53
#9
Posté 08 août 2013 - 09:37
#10
Posté 08 août 2013 - 12:44
#11
Posté 08 août 2013 - 03:31
string GetRandomResRef() {
string sRes;
switch (Random(9)) {
case 0: sRes = "resref001";
case 1: sRes = "resref002";
case 2: sRes = "resref003";
case 3: sRes = "resref004";
case 4: sRes = "resref005";
case 5: sRes = "resref006";
case 6: sRes = "resref007";
case 7: sRes = "resref008";
case 8: sRes = "resref009";
}
return sRes;
}
Random yeilds a random number from 0 to (x-1), where x is the number you input. So, if you have 9 item resrefs, you want cases 0-8.
Funky
#12
Posté 08 août 2013 - 03:46
#13
Posté 08 août 2013 - 08:10
I did make the map "treasuremap" and I have that script saved with the same name.
I have TreasureWP waypoint set on the map aswell. I tried to just put in the chest and it seems the chest itself works. The map just doesn't. *Shoulder shrug*
#14
Posté 08 août 2013 - 08:33
#15
Posté 08 août 2013 - 08:52
But as it happens, it seems like the map gets destroyed but the chest won't spawn.
Now I really am stumped. heh.
#16
Posté 08 août 2013 - 09:04
(Tried to make it set SourceChest string to a tag of a chest filled with junk, decent or jackpot stuff depending on the dice roll. Not sure why it doesn't work... I guess you can't set and immediately check for a variable
#17
Posté 08 août 2013 - 09:10
Modifié par Squatting Monk, 09 août 2013 - 07:40 .
#18
Posté 08 août 2013 - 09:15
#19
Posté 08 août 2013 - 09:16
const string TREASURE_PC = "TreasurePC";
// Local variable name for a flag noting the treasure has been opened.
const string TREASURE_OPENED = "TreasureOpened";
// Delay to destroy treasure container after it is first opened
// Default: 180 seconds (3 IRL minutes).
const float TREASURE_DELAY = 180.0;
void MakeTreasure(string sChest,object oChest)
{
int nCountItems;
int nRandomItem;
object oSource;
object oItem;
string sResRefItem;
oSource = GetObjectByTag(sChest);
if(!GetIsObjectValid(oSource))return;
//count item logic
oItem=GetFirstItemInInventory(oSource);
nCountItems = 0;
while(GetIsObjectValid(oItem)){
nCountItems++;
oItem=GetNextItemInInventory(oSource);
}
//now get random item
nRandomItem=Random(nCountItems)+1;
oItem=GetFirstItemInInventory(oSource);
while(nRandomItem>1){
nRandomItem--;
oItem=GetNextItemInInventory(oSource);
}
sResRefItem = GetResRef(oItem);
CreateItemOnObject(sResRefItem,oChest);
}
void main()
{
// Get the PC opening the treasure and make sure it's the one who found it.
object oPC = GetLastOpenedBy();
object oThisChest = OBJECT_SELF;
string sSourceChest; // Source of Treasure
sSourceChest = GetLocalString(oThisChest,"SourceChest");
if (GetLocalObject(OBJECT_SELF, TREASURE_PC) != oPC)
{
// It's not the same person, send them a message and abort. This is to
// prevent someone from sniping treasure from its rightful owner.
FloatingTextStringOnCreature("This treasure was found by someone else.", oPC, FALSE);
AssignCommand(oPC, ClearAllActions());
return;
}
// If it's the first time this treasure is being opened, spawn some treasure
// and then DelayCommand() the treasure's destruction.
if (!GetLocalInt(OBJECT_SELF, TREASURE_OPENED))
{
// Flag the treasure as having been opened before.
SetLocalInt(OBJECT_SELF, TREASURE_OPENED, TRUE);
// Delay the destruction of the treasure so it won't tie up this
// treasure waypoint indefinitely. We do this before creating the
// treasure in case any custom code added to the treasure generation
// code times us out.
DestroyObject(OBJECT_SELF, TREASURE_DELAY);
// Create treasure on the container. We'll roll a d20 and base the
// quality of the find on the roll.
switch (d20())
{
// On a roll of 1-5, find junk.
case 1: case 2: case 3: case 4: case 5:
{ // Set a local string.
FloatingTextStringOnCreature("Oi! This is ****!", oPC, FALSE);
// Creation code here.
MakeTreasure("jer_src_****treasure",oThisChest);
if(d2() > 1 ) MakeTreasure("jer_src_****treasure",oThisChest);
if(d3() > 1 ) MakeTreasure("jer_src_****treasure",oThisChest);
if(d2() > 1 ) MakeTreasure("jer_src_****treasure",oThisChest);
if(d2() > 1 ) MakeTreasure("jer_src_****treasure",oThisChest);
} break;
// On a roll of 6-19, find decent treasure.
case 6: case 7: case 8: case 9: case 10:
case 11: case 12: case 13: case 14: case 15:
case 16: case 17: case 18: case 19:
{
FloatingTextStringOnCreature("Aye! Not bad!", oPC, FALSE);
// Creation code here.
MakeTreasure("jer_src_decenttreasure",oThisChest);
if(d2() > 1 ) MakeTreasure("jer_src_decenttreasure",oThisChest);
if(d3() > 1 ) MakeTreasure("jer_src_decenttreasure",oThisChest);
if(d2() > 1 ) MakeTreasure("jer_src_decenttreasure",oThisChest);
if(d2() > 1 ) MakeTreasure("jer_src_decenttreasure",oThisChest);
} break;
// On a roll of 20, find ph4t l00t!
case 20:
{
FloatingTextStringOnCreature("Arr! This be a jackpot!", oPC, FALSE);
// Creation code here.
MakeTreasure("jer_src_jackpottreasure",oThisChest);
if(d2() > 1 ) MakeTreasure("jer_src_jackpottreasure",oThisChest);
if(d3() > 1 ) MakeTreasure("jer_src_jackpottreasure",oThisChest);
if(d2() > 1 ) MakeTreasure("jer_src_jackpottreasure",oThisChest);
if(d2() > 1 ) MakeTreasure("jer_src_jackpottreasure",oThisChest);
} break;
}
}
}
#20
Posté 08 août 2013 - 09:19
#21
Posté 08 août 2013 - 11:10
Sure you can. Never had an issue with that, and a ton of stuff in our mod wouldn't work without it. Lest ye doubt, here's a test function:Squatting Monk wrote...
You usually can't set and then get variables off of an object during the same script that creates it.
void main()
{
object oPC = GetLastUsedBy();
object oItem = CreateItemOnObject("nw_cloth020", oPC);
int nX, nCheck;
for (nX = 0; nX < 20; nX++) {
SetLocalInt(oItem, "Test", nX+1);
nCheck = GetLocalInt(oItem, "Test");
SpeakString(IntToString(nCheck) + " = Test var value");
}
}
Funky
#22
Posté 08 août 2013 - 11:35
#23
Posté 09 août 2013 - 10:33
#24
Posté 09 août 2013 - 11:32
Something like this would probably do it:
int nStack = GetItemStackSize(oItem);
sResRefItem = GetResRef(oItem);
CreateItemOnObject(sResRefItem,oChest, nStack);
Or collapse it a bit:
CreateItemOnObject(sResRefItem,oChest, GetItemStackSize(oItem));
#25
Posté 09 août 2013 - 12:56





Retour en haut







