|
Post by zunath on May 4, 2008 19:40:46 GMT
Hey there Funky. I don't know if you check this section of the boards any more but I've been wondering if you'd be able to help me with something I'm working on.
I want to use the includes in the HGLL system, but not the system itself. In short, I just need the functions.
These are the scripts I pulled from the included module:
hgll_spells_inc hgll_leto_inc hgll_classft_inc hgll_client_exit hgll_cliententer hgll_const_inc hgll_featlist_01 (through 11) hgll_featreq_inc hgll_struct_stat pg_lists_i
To test and see if it worked I made this script:
Now this didn't work, so it seems I did something wrong. Can you provide any help with this? I would really appreciate it.
Thanks!
|
|
|
Post by FunkySwerve on May 4, 2008 21:59:57 GMT
You'll also need the hgll module oncliententer and exit scripts to be merged into yours. Leto works like this:
Instead of editing the character in server memory, it edits the file, which is much simpler in some ways. Because of this, the player cannot be online at the time; if they were, when they logged out, their character in memory would overwrite the character saved on disk, and any changes to the disk version would be lost. So, the edits are stored in a local string on the character, and checked on clientexit - which fires AFTER the character has left the server, and memory written to disk. If there is a Letoscript local string set at that point, it is read to determine 1) what changes to make and 2) which character to make them to, via the filepath stored in that info. If such a local is found, it sends the info to the Letoscript plugin, which makes the edits. When the character logs back in the edits will have taken effect. On that relog, the Letoscript local is deleted so that it isn't found and re-executed on the next logout. The only reason it isn't deleted sooner is that you cannot delete it onclientexit.
Also, you need to be sure that you are getting the right filepath set on the character. Leto checks the filepath using FindNewestBic, a letoscript command that doesn't edit the character, but simply returns information. Because no edits take place, there's no need for booting, and the return is essentially instantaneous. It checks the timestamps on the file for the last edited (the last time the character was saved, essentially). Here enters one of the tricky parts of letoscript editing. Almost every nwn command blocks - meaning that it fniishing executing before the next command starts. Export commands do NOT block, at least not in the sense relevant to what we are doing. Because there is some delay in writing to disk, an Export command followed immediately by a letoscript inquiry to FindNewestBic will often find the last character saved BEFORE the one currently being saved, since the save has not yet completed and the timestamp is not yet updated. Because of this, you need a substsantial delay between Export and FindNewestBic to be safe. On HG we use a 6 second delay with a verification by character name oncliententer, if you don't verify name you should make it longer than 6 seconds, and prevent them from transitioning until the delay fires (you can't Export during a transition, or during OnClientEnter).
The HGLL scripts deal with it differently. Instead of checking the filepath onenter the first area, it checks it when the altar is clicked, ensuring that the character export is complete before FindNewestBic is fired. If you are doing your own edits, you'll probably want to just check the bicfilepath once, onareaenter, and then set it on the character as a local. This system ensures accuracy and efficiency. Here's our way of doing this (sorry, this BBS loses indents):
string LetoScript (string sScript) { SetLocalString(GetModule(), "NWNX!LETO!SCRIPT", sScript); return GetLocalString(GetModule(), "NWNX!LETO!SCRIPT"); }
string GetBicFilePath (object oPC) { string sVaultPath =YOUR_NWN_VAULT_PATH; // string sVaultPath = "C:/NeverwinterNights/NWN/servervault/";//windows sample string sBicPath = sVaultPath + GetPCPlayerName(oPC) + "/";
return LetoScript("print q<" + sBicPath + "> + " + "FindNewestBic q<" + sBicPath + ">;"); }
string VerifyBicFileName (object oPC) { string sChar, sBicFile; string sName = GetStringLowerCase(GetName(oPC)); int i, nLen = GetStringLength(sName);
for (i = 0; i < nLen; i++) { sChar = GetSubString(sName, i, 1);
if (TestStringAgainstPattern("(*a|*n|*w|'|-|_)", sChar)) { if (sChar != " ") sBicFile += sChar; } }
return GetStringLeft(sBicFile, 15); }
void SetBicPathLocal (object oPC) { string sPath = GetLocalString(oPC, "BicFilePath");
if (sPath == "") { sPath = GetBicFilePath(oPC);
/* gets the left 15 characters (of 16) or less, using the old method */ string sVerify = VerifyBicFileName(oPC);
if (TestStringAgainstPattern("**" + sVerify + "**", sPath)) { SetLocalString(oPC, "BicFilePath", sPath);
if (!GetCommandable(oPC)) SetCommandable(TRUE, oPC); } else { ExportSingleCharacter(oPC); FloatingTextStringOnCreature("File System Error! Attempting to fix, please wait. " + "If you get this message more than 3 times in a row, please contact a DM.", oPC, FALSE);
if (GetCommandable(oPC)) SetCommandable(FALSE, oPC); DelayCommand(5.0f, FloatingTextStringOnCreature("Accents or other unusual symbols in character names " + "prevent the server from locating your character for subrace and other edits.", oPC, FALSE));
/* if the bic hasn't updated yet, try again at an extended delay */ DelayCommand(10.0f, SetBicPathLocal(oPC)); return; } } }
void main() { object oPC = GetEnteringObject();
if (!GetIsPC(oPC)) return;
object oArea = GetArea(oPC);
if (!GetIsDM(oPC)) { ExportSingleCharacter(oPC); DelayCommand(6.0f, SetBicPathLocal(oPC)); } }
You would then check the local when setting edits on a character.
Funky
|
|
|
Post by zunath on May 5, 2008 0:00:21 GMT
Alright, thanks so much for all that. I can script fairly well but when it comes to understanding how stuff like this works, it takes me a bit of time. Sorry for that hehe I think I should go into more detail into what I want to accomplish. For our module, we want to allow PCs to make changes to their stats, feats, etc through a conversation. For this wouldn't I just Export their character, boot them and fire the ApplyLetoScriptToPC function 6 seconds after? Or is there something else I'm not getting that's causing this to not work right? Thank you again for all the help, I really appreciate it.
|
|
|
Post by FunkySwerve on May 5, 2008 0:22:03 GMT
Yes. Again, you need to Export 6 seconds before you check the filepath. After that you can do what you like. Do you have the necessary scripts in oncliententer and onclientexit?
Funky
|
|
|
Post by zunath on May 5, 2008 0:30:53 GMT
EDIT2: Sorry, wow, I totally forgot about the functions you posted. My bad, let me try those. Sorry, I'm not sure how to check the filepath. I noticed the ApplyLetoScriptToPC function had something about getting the bic file - is that what you mean? I made some minor modifications to the small test script. Am I way off track? Thanks for being so patient with me EDIT: And yep, I do have those scripts on enter and on exit of the module.
|
|
|
Post by zunath on May 5, 2008 1:45:12 GMT
Okay, got those functions you posted in your include file but I'm still not sure what to do with them. If you're not too busy, would you mind explaining for me?
Thanks a ton.
|
|
|
Post by FunkySwerve on May 5, 2008 2:52:13 GMT
You put the script (it's a void main with all the needed functions above it) in the area enter of the first area of the module, unless you are immediately porting characters elsewhere. The area in which you put it must be 1) one in which all characters pass through every time they first enter the module after a reset, 2) one in which they are guaranteed to be in long enough for the delaycommanded SetBicPathLocal to fire (6 seconds minimum - you could even put checks for the local on the transitions out of the area so that pcs cannot exit until they have their bicpaths set; and 3) in a place before they need to have any leto edits applied - this function needs to run to set the filepath local on the pc BEFORE you do any letoing. Once you have that in place, you no longer need to worry about a delay for letoing. Then, if you wanted to leto a character, you could simply do something like this, from a placeable used script, or an item activate, or what have you : void ApplyLetoScriptToPC(string Script, object oPC) { //object M = GetModule();
string Player = GetPCPlayerName(oPC); string BicFile = GetLocalString(oPC, "BicFilePath");
Script = "$RealFile = q<" + BicFile + ">;" + "$EditFile = $RealFile + '.utc';" + "FileRename $RealFile, $EditFile;" + "%bic = $EditFile or die;" + Script + "%bic = '>';" + "close %bic;" + "FileRename $EditFile, $RealFile;";
SetLocalString(oPC, "LetoScript", Script); //Ask player to relog rather than booting them since they could crash server if they log out after boot delaycommanded but before executed //alternatively you can boot with a validity check RepeatFloatingTextStringOnCreature(oPC, "Please relog for feat addition.");
}
void SetPCName(object oPC, string sFirstName, string sLastName) { //below string should contain all the changes you want to make - in this case, just first and last name string Script = "/FirstName = q~" + sFirstName +"~';/LastName = q~" + sLastName + "~;"; ApplyLetoScriptToPC(Script, oPC); }
void main() { object oPC = GetLastUsedBy();//or whatever function you need to get the pc, depending on what event you put this in SetPCName(oPC, "Fred", "Astaire"); } LMK if you have any questions. Funky
|
|
|
Post by zunath on May 5, 2008 9:53:17 GMT
Great. I understand now. But instead of storing the bic path on the PC itself, couldn't you store it on an item in their inventory so that they don't have to wait 6 seconds each restart?
I used what you posted and now the bic setting works like it should, but then I used the script above to change their name and that didn't seem to work. I have the placeable set in another area and I know the bic is setting before they enter another area. But on relog, no changes are made. The name stays the same.
EDIT: Actually, I got the stat adding to work. I still need to test and see if feats and the like will work.
Thanks so much for the help!
|
|
|
Post by FunkySwerve on May 5, 2008 10:00:57 GMT
Sure, you could do that, but it serves an important function. If for some reason your computer is not finding the bic, or is having difficulty talking to the leto plugin, then this system will fire off the file warning, and players won't be able to play until the issue is fixed. This comes in very handy on HG, because of rare fileserver blips.
As for your problem, you'll have to post your leto log for the attempted edit before I can be of any help.
Funky
|
|
|
Post by zunath on May 5, 2008 22:48:34 GMT
Looks great. Got everything working thanks to you This is on an unrelated note but do you know if Virusman ever ported GetConvoNodeSelected, GetConvoNodeText, and SetConvoNodeText over to windows users? Trying to cut down on the number of scripts for my conversations but there's not much out there besides ZZ-Dialog which is kind of difficult to use from what I can tell.
|
|
|
Post by FunkySwerve on May 6, 2008 0:03:49 GMT
No, he didn't. Apparently it'd be a great deal of work. I've been lobbying acaos to do it though, so I can release a single versoin of simtools instead of two.
Funky
|
|