Store locations within a database
#1
Posté 08 juin 2011 - 12:41
object oPlayer = OBJECT_SELF;
location lPlayer = GetLocation(oPlayer);
string sPlayer = GetStringLeft(GetName(oPlayer), 3);
string sArea = GetStringLeft(GetTag(GetArea(oPlayer)), 3);
string sNewTag = sPlayer + sArea;
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(925), oPlayer, 0.0);
object oJewel = CreateItemOnObject("starjewel", oPlayer, 1, sNewTag + "jewel");
AssignCommand(oJewel, ActionDoCommand(SetCampaignLocation("starjewel_db", GetTag(oJewel), lPlayer, oJewel)));
SetCutsceneMode(oPlayer, TRUE);
DelayCommand(4.0, AssignCommand(oPlayer, ActionDoCommand(SetCutsceneMode(oPlayer, FALSE))));
After this Starjewel is created, the player should be able to use the Starjewel to return to the location originally marked upon it. When I use Local variables and locations, this works just fine. When I use Campaign ones, it does not, nor is any database created. Here is the Starjewel script for onuse....
#include "X0_I0_SPELLS"
void main()
{
object oCaster = GetItemActivator();
location lCaster = GetLocation(oCaster);
string sJewel = GetTag(GetItemActivated());
location lDest = GetCampaignLocation("starjewel_db", sJewel, GetItemActivated());
string sRecall = GetLocalString(oCaster, "starjewel");
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, lCaster , TRUE, OBJECT_TYPE_CREATURE);
location lTarget = GetLocation(oTarget);
while (GetIsObjectValid(oTarget))
{
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(860), lTarget);
AssignCommand(oTarget, ActionJumpToLocation(lDest));
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lCaster, TRUE, OBJECT_TYPE_CREATURE);
lTarget = GetLocation(oTarget);
}
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(860), lDest);
}
Do I have to initialize a database somewhere? Any ideas why this doesn't seem to store into a database as requested?
Thank you in advance.
#2
Posté 08 juin 2011 - 01:19
#3
Posté 08 juin 2011 - 01:43
As it is, if that part is trying to run before the jewel is created, it simply won't fire off.
#4
Posté 08 juin 2011 - 02:35
object oPlayer = OBJECT_SELF;
location lPlayer = GetLocation(oPlayer);
string sPlayer = GetStringLeft(GetName(oPlayer), 3);
string sArea = GetStringLeft(GetTag(GetArea(oPlayer)), 3);
string sNewTag = sPlayer + sArea;
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(925), oPlayer, 0.0);
object oJewel = CreateItemOnObject("starjewel", oPlayer, 1, sNewTag + "jewel");
SetCampaignLocation("starjewel_db", sNewTag + "jewel", lPlayer, oJewel);
SetCutsceneMode(oPlayer, TRUE);
DelayCommand(4.0, SetCutsceneMode(oPlayer, FALSE));
Funky
Modifié par FunkySwerve, 08 juin 2011 - 02:36 .
#5
Posté 08 juin 2011 - 02:45
#6
Posté 08 juin 2011 - 02:52
there should be no problem with useing the created item right away, they are created right away, It is the destroy item that has a delay .
The problem I see from a quic glance is that you are using 'starjewel' as the DB name you are writing to and 'starjewel_db' as the name of the db you are reading from.
of cource there is no reason to use a DB for this unless you are just useing it as a learning process.
#7
Posté 08 juin 2011 - 02:56
#8
Posté 08 juin 2011 - 03:02
FunkySwerve wrote...
You've got heaps of unnecessary functions in there. My guess is that item objects don't have action cues, and that assigning them actions has no effect, but I don't know, because I have never and would never do something like that. Here's a cleaned up version. Long story short: save Action functions for cueing up behavoir on NPCs. AssignCommand is useful for making a different object than the caller of the script run code, but there's no real reason to do that here. Lastly, the way you set the campaign location using only 3 letters from player name and area tag is...some combination of bizarre, unnecessary, or nonfunctional, but my goal for now is simply to get your script working.object oPlayer = OBJECT_SELF; location lPlayer = GetLocation(oPlayer); string sPlayer = GetStringLeft(GetName(oPlayer), 3); string sArea = GetStringLeft(GetTag(GetArea(oPlayer)), 3); string sNewTag = sPlayer + sArea; ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(925), oPlayer, 0.0); object oJewel = CreateItemOnObject("starjewel", oPlayer, 1, sNewTag + "jewel"); SetCampaignLocation("starjewel_db", sNewTag + "jewel", lPlayer, oJewel); SetCutsceneMode(oPlayer, TRUE); DelayCommand(4.0, SetCutsceneMode(oPlayer, FALSE));
Funky
Thank you for your help. After removing the "heaps" of unnecessary functions, it worked. I apologize if my code offended you. I am still learning.
As for the "bizarre and unnecessary" combination of the player and area tag in addition to the word "jewel", this seemed sensible given that there would be multiple star jewels all over the place from multiple players, and the only way to successfully call the right location to the right jewel would be to assign some sort of unique ID to it. Again, if I am wrong, I apologize. I'm trying to learn this stuff.
#9
Posté 08 juin 2011 - 03:03
The problem I see from a quic glance is that you are using 'starjewel' as the DB name you are writing to and 'starjewel_db' as the name of the db you are reading from.
That's fixed
of cource there is no reason to use a DB for this unless you are just useing it as a learning process.
If I don't use a database, I lose all the Starjewel "locations" on a server crash, no?
#10
Posté 08 juin 2011 - 03:15
If you store local variables on an item, and the item is in the character's inventory, then you do not lose those locations.Ivanovich wrote...
If I don't use a database, I lose all the Starjewel "locations" on a server crash, no?
#11
Posté 08 juin 2011 - 03:16
Ivanovich wrote...
If I don't use a database, I lose all the Starjewel "locations" on a server crash, no?
No, Just store it as a local on the item. Locals on the Item are saved with the item.
Since the locals are on the item you also will not need unique lables. The jewel just uses the data that is stored on itsself.
also if the server crashes and the item is lost there is no need to have the data stored in the DB. there is no item to use it,
Modifié par Lightfoot8, 08 juin 2011 - 03:17 .
#12
Posté 08 juin 2011 - 03:54
Offended?Ivanovich wrote...
FunkySwerve wrote...
You've got heaps of unnecessary functions in there. My guess is that item objects don't have action cues, and that assigning them actions has no effect, but I don't know, because I have never and would never do something like that. Here's a cleaned up version. Long story short: save Action functions for cueing up behavoir on NPCs. AssignCommand is useful for making a different object than the caller of the script run code, but there's no real reason to do that here. Lastly, the way you set the campaign location using only 3 letters from player name and area tag is...some combination of bizarre, unnecessary, or nonfunctional, but my goal for now is simply to get your script working.object oPlayer = OBJECT_SELF; location lPlayer = GetLocation(oPlayer); string sPlayer = GetStringLeft(GetName(oPlayer), 3); string sArea = GetStringLeft(GetTag(GetArea(oPlayer)), 3); string sNewTag = sPlayer + sArea; ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(925), oPlayer, 0.0); object oJewel = CreateItemOnObject("starjewel", oPlayer, 1, sNewTag + "jewel"); SetCampaignLocation("starjewel_db", sNewTag + "jewel", lPlayer, oJewel); SetCutsceneMode(oPlayer, TRUE); DelayCommand(4.0, SetCutsceneMode(oPlayer, FALSE));
Funky
Thank you for your help. After removing the "heaps" of unnecessary functions, it worked. I apologize if my code offended you. I am still learning.
As for the "bizarre and unnecessary" combination of the player and area tag in addition to the word "jewel", this seemed sensible given that there would be multiple star jewels all over the place from multiple players, and the only way to successfully call the right location to the right jewel would be to assign some sort of unique ID to it. Again, if I am wrong, I apologize. I'm trying to learn this stuff.
The fix is to remove it if you don't need it, or to use truly unique identifiers if you do. I would go with the area resref and a 16-character chunk of the playername (NOT character name, which is what you are using). Having not used the bioware database in the last 5 or 6 years, I can't attest to this myself, but a poster above noted a 32-character limit for the vanilla database, or I'd be suggesting full playername.
Funky
Modifié par FunkySwerve, 08 juin 2011 - 03:54 .
#13
Posté 08 juin 2011 - 04:02
#14
Posté 08 juin 2011 - 04:20
Offended?Ivanovich wrote...
Thank you for your help. After removing the "heaps" of unnecessary functions, it worked. I apologize if my code offended you. I am still learning.
As for the "bizarre and unnecessary" combination of the player and area tag in addition to the word "jewel", this seemed sensible given that there would be multiple star jewels all over the place from multiple players, and the only way to successfully call the right location to the right jewel would be to assign some sort of unique ID to it. Again, if I am wrong, I apologize. I'm trying to learn this stuff.
The fix is to remove it if you don't need it, or to use truly unique identifiers if you do. I would go with the area resref
and a 16-character chunk of the playername (NOT character name, which is what you are using). Having not used the bioware database in the last 5 or 6 years, I can't attest to this myself, but a poster above noted a
32-character limit for the vanilla database, or I'd be suggesting full playername (resrefs are 16 characters max).
So, DO you need it? As written, I'm not sure. I do know that all the information you're storing on that will be available
when the gem is used as well, if the gem is undroppable, making it unnecessary if it's written a certain way. I don't see you setting the Cursed flag on it though. Such campaign variables can be keyed to a particular player anyway, in the optional parameter, though, for some reason, you chose to specify the jewel.
My suggestion to you as someone who's learning scripting nwscript would be to experiment enough to understand how all the parameters of the functions that you're using work. I remember being confused not just by campaign variables once, but by plain old local variables. I also remember, however, disliking how much time every little thing took to get working, since there was so much to learn. If you don't want to invest the full amount of learning time up front, but go at it gradually, I get that too.
Lastly, a warning. When you add areas to your module, I believe your stored campaign locations will subject to breakage. It might be more advisable to use a string to store the data, combining the x, y, and z coordiates with the area resref (at minimum). If you're curious about how to do that, I'll be happy to explain.
Of course, most of this is moot anyway past the learning experience, since, as other posters have noted, setting the local on the item will store it on the character's bic as soon as the character is Exported, either via the Export functions or by exiting the server.
Funky
Modifié par FunkySwerve, 08 juin 2011 - 04:29 .
#15
Posté 08 juin 2011 - 04:26
I wasn't quesitoning whether they could take assigned commands, but whether they had action queues (I've AC'd items many times). That it worked when he removed the action queue-up suggests to me that they can't. That, or you just can't ActionDoCommand a SetCampaign - wouldn't surprise me either.Lightfoot8 wrote...
@funky. yes an object can take an assigned command. It is not often needed but once in awhile it is. an example would be setting the destroyable flag, it has to run on object self. of cource you use nwnx so my have other options on setting the flag.
Funky
Modifié par FunkySwerve, 08 juin 2011 - 04:31 .
#16
Posté 08 juin 2011 - 05:06
#17
Posté 08 juin 2011 - 09:10
object oPlayer = OBJECT_SELF;
location lPlayer = GetLocation(oPlayer);
string sAreaTag = GetTag(GetArea(oPlayer));
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(925), oPlayer, 0.0);
object oJewel = CreateItemOnObject("starjewel", oPlayer);
SetLocalLocation( oJewel,"JewelLoc",lPlayer);
SetLocalString ( oJewel,"JewelArea",sAreaTag);
SetCutsceneMode(oPlayer, TRUE);
DelayCommand(4.0, SetCutsceneMode(oPlayer, FALSE));
then to rebuild you location to make sure the area is correct would look something like this.
location lLoc = GetLocalLocation( oJewel,"JewelLoc");
string sAreaTag =GetLocalString ( oJewel,"JewelArea");
lLoc = Location(GetObjectByTag(sAreaTag),
GetPositionFromLocation( lLoc),
GetFacingFromLocation( lLoc)
);
Modifié par Lightfoot8, 08 juin 2011 - 09:11 .
#18
Posté 08 juin 2011 - 11:15
Lightfoot8 wrote...
then to rebuild you location to make sure the area is correct would look something like this.
location lLoc = GetLocalLocation( oJewel,"JewelLoc");
string sAreaTag =GetLocalString ( oJewel,"JewelArea");
lLoc = Location(GetObjectByTag(sAreaTag),
GetPositionFromLocation( lLoc),
GetFacingFromLocation( lLoc)
);
*Yoinks*
I'd never considered that only part of the location was becoming invalid on rebuilds. That fixes up a problem I'd been having in my little mods OnEnter script, being able to rebuild it that way. I thought I was going to have to go with floats as well, it's why I never bothered fixing it, too much of a nuisance that way.
#19
Posté 23 juin 2011 - 10:30
Modifié par GhostOfGod, 23 juin 2011 - 11:51 .





Retour en haut






