so what i want to do is make an NPC spawn once when the modual loads, spawning the NPC in one of, say, 7 locations (waypoints) spread out between 3 maps. secondly, i'm looking for an OnDeath script to make the NPC continue to spawn on one of these waypoints after it dies. i have a slight idea how to do the second script, but unsure about the first.
here is what i have for the second script now....
void SpawnBoss(location loc)
{
CreateObject(OBJECT_TYPE_CREATURE, "boss", loc, FALSE);
}
void main()
{
object pc = GetLastKiller();
if (!GetIsPC(pc) )
return;
int n = Random(7);
object wp = GetObjectByTag("wp_boss", n);
location loc = GetLocation(wp);
DelayCommand(1.0, SpawnBoss(loc));
}
obviously nothing to do with any other maps, but i have the random locations down...
any help with this is appreciated.
thanks
help with onmodual load style spawn
Débuté par
zero-feeling
, oct. 20 2010 07:11
#1
Posté 20 octobre 2010 - 07:11
#2
Posté 20 octobre 2010 - 03:45
Seems like you have a good grip on what to do, but here's how my mad scientist brain would do it...
This was mostly scratched off in notepad, so there may be some minor compile errors:
//for onmoduleload
void SpawnRandomNPC(){
string sNPCResRef = "yournpcresref";
string sWPTag = "YourWPTag";
//count the waypoints
int iWPCount = 0;
while(GetIsObjectValid(GetObjectByTag(sWPTag, iWPCount))){
iWPCount++;
}
//Grab one at random
int iRandomWP = Random(iWPCount);
object oRandomWP = GetObjectByTag(sWPTag, iRandomWP);
//Spawn the NPC there
object oSpawnedNPC = CreateObject(OBJECT_TYPE_CREATURE,sNPCResRef,GetLocation(oRandomWP));
//Cache WP Tag/Count/Spawn Point
Object oCacheOn = GetModule();
SetLocalString(oCacheOn,"randmob_wp_tag",sWPTag);
SetLocalInt(oCacheOn,"randmob_wp_count",iWPCount);
SetLocalInt(oCacheOn,"randmob_spawned_at",iRandomWP);
}
//for ondeath
void RespawnSelf(string sResRef, location lSpawnPoint){
object oSpawnedNPC = CreateObject(OBJECT_TYPE_CREATURE,sResRef,lSpawnPoint);
}
void main(){
float fRespawnDelay = 30.0;
if (!GetIsPC(GetLastKiller())) return;
object oCachedOn = GetModule();
string sWPTag = GetLocalString(oCachedOn,"randmob_wp_tag");
int iWPCount = GetLocalInt(oCachedOn,"randmob_wp_count");
int iLastWP = GetLocalInt(oCachedOn,""randmob_spawned_at");
//pick a new one at random, but not the current one
int iRandomWP = iLastWP;
while(iRandomWP == iLastWP){
iRandomWP = Random(iWPCount);
}
object oRandomWP = GetObjectByTag(sWPTag, iRandomWP);
//Spawn the NPC there in X.0 seconds
DelayCommand(fRespawnDelay,RespawnSelf(GetResRef(OBJECT_SELF),GetLocation(oRandomWP));
//update cache
SetLocalInt(oCachedOn,"randmob_spawned_at",iRandomWP);
}
This was mostly scratched off in notepad, so there may be some minor compile errors:
//for onmoduleload
void SpawnRandomNPC(){
string sNPCResRef = "yournpcresref";
string sWPTag = "YourWPTag";
//count the waypoints
int iWPCount = 0;
while(GetIsObjectValid(GetObjectByTag(sWPTag, iWPCount))){
iWPCount++;
}
//Grab one at random
int iRandomWP = Random(iWPCount);
object oRandomWP = GetObjectByTag(sWPTag, iRandomWP);
//Spawn the NPC there
object oSpawnedNPC = CreateObject(OBJECT_TYPE_CREATURE,sNPCResRef,GetLocation(oRandomWP));
//Cache WP Tag/Count/Spawn Point
Object oCacheOn = GetModule();
SetLocalString(oCacheOn,"randmob_wp_tag",sWPTag);
SetLocalInt(oCacheOn,"randmob_wp_count",iWPCount);
SetLocalInt(oCacheOn,"randmob_spawned_at",iRandomWP);
}
//for ondeath
void RespawnSelf(string sResRef, location lSpawnPoint){
object oSpawnedNPC = CreateObject(OBJECT_TYPE_CREATURE,sResRef,lSpawnPoint);
}
void main(){
float fRespawnDelay = 30.0;
if (!GetIsPC(GetLastKiller())) return;
object oCachedOn = GetModule();
string sWPTag = GetLocalString(oCachedOn,"randmob_wp_tag");
int iWPCount = GetLocalInt(oCachedOn,"randmob_wp_count");
int iLastWP = GetLocalInt(oCachedOn,""randmob_spawned_at");
//pick a new one at random, but not the current one
int iRandomWP = iLastWP;
while(iRandomWP == iLastWP){
iRandomWP = Random(iWPCount);
}
object oRandomWP = GetObjectByTag(sWPTag, iRandomWP);
//Spawn the NPC there in X.0 seconds
DelayCommand(fRespawnDelay,RespawnSelf(GetResRef(OBJECT_SELF),GetLocation(oRandomWP));
//update cache
SetLocalInt(oCachedOn,"randmob_spawned_at",iRandomWP);
}
Modifié par Ne0nx3r0, 20 octobre 2010 - 05:48 .
#3
Posté 20 octobre 2010 - 05:43
well, i find two errors when compileing the scripts, both the same error...
ERROR: NO SEMICOLON AFTER EXPRESSION
in each case there is a semicolon at the end of the line, and i've tried a few things to fix this, but i can't seem to figure this out. have any ideas?
one other thing missing was a "void" before the line RespawnSelf in the OnDeath script, fixed now though.
thanks.
ERROR: NO SEMICOLON AFTER EXPRESSION
in each case there is a semicolon at the end of the line, and i've tried a few things to fix this, but i can't seem to figure this out. have any ideas?
one other thing missing was a "void" before the line RespawnSelf in the OnDeath script, fixed now though.
thanks.
#4
Posté 20 octobre 2010 - 05:47
It's almost always parenthesis (at least for me) with those errors. I've updated the code above to fix a few parenthesis issues.
BTW If you don't know this, you can double click on the compile errors to jump to the line they happened on. Makes debugging a heck of a lot easier.
BTW If you don't know this, you can double click on the compile errors to jump to the line they happened on. Makes debugging a heck of a lot easier.
Modifié par Ne0nx3r0, 20 octobre 2010 - 05:47 .
#5
Posté 20 octobre 2010 - 05:54
Just my mind pondering this... You might want to consider placing the NPC wherever in the toolset, and then change his tag manually. Then onspawn he checks to see if his tag is the changed tag, and if so he destroys himself and spawns a fresh copy of himself in a random location. Ondeath would work the same. the main advantage here is that it's unobtrusive, and more modular.
.. and you probably want to store the variables on him (or skip caching), for scaling reasons.
.. and you probably want to store the variables on him (or skip caching), for scaling reasons.
Modifié par Ne0nx3r0, 20 octobre 2010 - 05:55 .
#6
Posté 20 octobre 2010 - 06:36
i got the issues sorted, had a few extra )) in both scripts and a capital o for object in the first... compiles fine now and will be testing soon, i'll post the results when i'm done.
as for the latest post you made... i don't follow. could you explain it a little more?
thanks again.
as for the latest post you made... i don't follow. could you explain it a little more?
thanks again.
#7
Posté 20 octobre 2010 - 07:03
Well I was thinking afterwards my initial shot at it was kind of sloppy.
A more effecient way to do this would be to make him work like this:
OnSpawn: If the NPC has the original tag destroy it, and create a new version at a random WP with a changed tag (otherwise just return)
OnDeath: Respawn after 20 seconds at a different random location, still changing the tag so he wont kill himself and respawn again
Any variables would be stored on each NPC that is spawned.
Why? Well this way you could drop the NPC from the toolset, or from the DM client. If you put down ten of them in game for example, they would all destroy themselves and appear at 10 random locations from your list. It's just a cleaner and more expandable way to accomplish what you're after.
A more effecient way to do this would be to make him work like this:
OnSpawn: If the NPC has the original tag destroy it, and create a new version at a random WP with a changed tag (otherwise just return)
OnDeath: Respawn after 20 seconds at a different random location, still changing the tag so he wont kill himself and respawn again
Any variables would be stored on each NPC that is spawned.
Why? Well this way you could drop the NPC from the toolset, or from the DM client. If you put down ten of them in game for example, they would all destroy themselves and appear at 10 random locations from your list. It's just a cleaner and more expandable way to accomplish what you're after.
Modifié par Ne0nx3r0, 20 octobre 2010 - 07:03 .
#8
Posté 20 octobre 2010 - 08:51
hmm... thats definetly got my attention. unfortunately your previous assumption was incorect, i'm more of a builder (story, ideas, all other toolset work) than a scripter. the script i posted was one i had from another scripter (whos no longer working on my server with me)
looking for work?
if you wouldn't mind conjuring up a script that would work in this way, it would be appreciated greatly... otherwise, i will try and tweek the current script **points up** to make it work. (currently does not work).
thanks
looking for work?
if you wouldn't mind conjuring up a script that would work in this way, it would be appreciated greatly... otherwise, i will try and tweek the current script **points up** to make it work. (currently does not work).
thanks
#9
Posté 20 octobre 2010 - 09:01
Your original death script looks fine, save that you should AssignCommand the DelayCommand to GetArea(OBJECT_SELF). That's almost certainly why it isn't working - the creature running the delaycommand isn't around to run it (being dead and all). Just swap out the last line:
DelayCommand(1.0, SpawnBoss(loc));
with this:
AssignCommand(GetArea(pc), DelayCommand(1.0, SpawnBoss(loc)));
Funky
DelayCommand(1.0, SpawnBoss(loc));
with this:
AssignCommand(GetArea(pc), DelayCommand(1.0, SpawnBoss(loc)));
Funky
Modifié par FunkySwerve, 20 octobre 2010 - 09:02 .
#10
Posté 20 octobre 2010 - 09:35
thanks for the help with that funky (will work for another similar script) , but i think you missed something from the OP i made, namely the use of thee maps to have this NPC spawn from. the problem i'm having now is the script Ne0nx3r0 provided dosn't spawn the first NPC. i added the script into my current OnModualLoad script as an ExecuteScript line, with a 2 second delay.... which might be the problem....
so after this post i will try to remove that and see what happens....
other than that, all toolset related things (resrefs, waypoints, ect) are set accordingly.
so after this post i will try to remove that and see what happens....
other than that, all toolset related things (resrefs, waypoints, ect) are set accordingly.
#11
Posté 20 octobre 2010 - 09:38
No, I didn't miss it, I was just pointing out the bug in your death script, which Ne0nx3r0's code also suffers from. I didn't examine his code closely, but it looks like he's giving you what you asked for, no?
Funky
Funky
#12
Posté 20 octobre 2010 - 09:52
well, i thank you for the fix then.
as for if it's what i asked for, i can only assume so. to be honest, i'm not very good at scripting (can do most of the basics and cut and paste some...) and his style is a bit different than others i've worked with. i did however manage to find the small errors in the script to make it compile, something 3 months ago i prolly couldn't do.
you say Ne0nx3r0's script suffers from the same problem? would you mind pointing me to it as well, maybe any other issues you might find?
thanks
as for if it's what i asked for, i can only assume so. to be honest, i'm not very good at scripting (can do most of the basics and cut and paste some...) and his style is a bit different than others i've worked with. i did however manage to find the small errors in the script to make it compile, something 3 months ago i prolly couldn't do.
you say Ne0nx3r0's script suffers from the same problem? would you mind pointing me to it as well, maybe any other issues you might find?
thanks
#13
Posté 20 octobre 2010 - 11:06
The problem line in his code is this one:
//Spawn the NPC there in X.0 seconds
DelayCommand(fRespawnDelay,RespawnSelf(GetResRef(OBJECT_SELF),GetLocation(oRandomWP));
Note that when you assigncommand that to the area, you must have already passed the resref of the creature, because AssignCommand changes the 'self' that OBJECT_SELF refers to from the creature to the area.
So, replace that line with these, and it should in theory work:
string sCritterRes = GetResRef(OBJECT_SELF);
location lCritterLoc = GetLocation(oRandomWP);
AssignCommand(GetArea(OBJECT_SELF), DelayCommand(fRespawnDelay,RespawnSelf(sCritterRes,lCritterLoc)));
Funky
//Spawn the NPC there in X.0 seconds
DelayCommand(fRespawnDelay,RespawnSelf(GetResRef(OBJECT_SELF),GetLocation(oRandomWP));
Note that when you assigncommand that to the area, you must have already passed the resref of the creature, because AssignCommand changes the 'self' that OBJECT_SELF refers to from the creature to the area.
So, replace that line with these, and it should in theory work:
string sCritterRes = GetResRef(OBJECT_SELF);
location lCritterLoc = GetLocation(oRandomWP);
AssignCommand(GetArea(OBJECT_SELF), DelayCommand(fRespawnDelay,RespawnSelf(sCritterRes,lCritterLoc)));
Funky
Modifié par FunkySwerve, 20 octobre 2010 - 11:07 .
#14
Posté 21 octobre 2010 - 12:12
ok, so the OnDeath script seems to be working ok from what i can see, but the OnModualLoad script dosn't...
any idea why this is? could it be that it's in an Execute script off the main script or would that matter?
Edit: getting error for the OnDeath script i didn't notice before, OID: 8000008f; TOO MANY INSTRUCTIONS
what does this mean?
thanks
any idea why this is? could it be that it's in an Execute script off the main script or would that matter?
Edit: getting error for the OnDeath script i didn't notice before, OID: 8000008f; TOO MANY INSTRUCTIONS
what does this mean?
thanks
Modifié par zero-feeling, 21 octobre 2010 - 12:17 .
#15
Posté 21 octobre 2010 - 12:18
Oh that's a good point... I guess I assumed it would figure out the location/resref before delaying the command and pass the direct values onward... (or something)
Is there some trick to posting code and keeping the formatting here? It drives me crazy what this forum does to code... Anyway here's what I was talking about with the onspawn/ondeath scripts:
//
//onSpawn for a given creature
//
void main(){
string sWPTag = "YourWPTag";
string sPrefix = "~Respawn";//can be whatever
string sTag = GetTag(OBJECT_SELF);
if(GetStringLeft(sTag,GetStringLength(sPrefix)) == sPrefix){
//count the waypoints
int iWPCount = 0;
while(GetIsObjectValid(GetObjectByTag(sWPTag, iWPCount))){
iWPCount++;
}
//Spawn the NPC there
object oSpawnedNPC = CreateObject(
OBJECT_TYPE_CREATURE,
GetResRef(OBJECT_SELF),
GetLocation(GetObjectByTag(sWPTag, Random(iWPCount))),
TRUE,
sPrefix+sTag
);
DestroyObject(OBJECT_SELF);
}
}
//
//OnDeath for that same creature
//
void SpawnNewMe(string sResRef,string sTag){
string sWPTag = "YourWPTag";
//count the waypoints
int iWPCount = 0;
while(GetIsObjectValid(GetObjectByTag(sWPTag, iWPCount))){
iWPCount++;
}
//Spawn the NPC there
object oSpawnedNPC = CreateObject(
OBJECT_TYPE_CREATURE,
GetResRef(OBJECT_SELF),
GetLocation(GetObjectByTag(sWPTag, Random(iWPCount))),
TRUE,
sTag
);
}
void main(){
if(GetIsPC(GetLastKiller())){
float fRespawnTime = 20.0;
string sResRef = GetResRef(OBJECT_SELF);
string sTag = GetTag(OBJECT_SELF);//note this should have the ~Respawn Prefix in it
DelayCommand(fRespawnTime,SpawnNewMe(sResRef,sTag));
}
}
Haven't had a chance to test them yet, but if you have any issues I'll do what I can.. I suppose I did get you into this mess to begin with!
Is there some trick to posting code and keeping the formatting here? It drives me crazy what this forum does to code... Anyway here's what I was talking about with the onspawn/ondeath scripts:
//
//onSpawn for a given creature
//
void main(){
string sWPTag = "YourWPTag";
string sPrefix = "~Respawn";//can be whatever
string sTag = GetTag(OBJECT_SELF);
if(GetStringLeft(sTag,GetStringLength(sPrefix)) == sPrefix){
//count the waypoints
int iWPCount = 0;
while(GetIsObjectValid(GetObjectByTag(sWPTag, iWPCount))){
iWPCount++;
}
//Spawn the NPC there
object oSpawnedNPC = CreateObject(
OBJECT_TYPE_CREATURE,
GetResRef(OBJECT_SELF),
GetLocation(GetObjectByTag(sWPTag, Random(iWPCount))),
TRUE,
sPrefix+sTag
);
DestroyObject(OBJECT_SELF);
}
}
//
//OnDeath for that same creature
//
void SpawnNewMe(string sResRef,string sTag){
string sWPTag = "YourWPTag";
//count the waypoints
int iWPCount = 0;
while(GetIsObjectValid(GetObjectByTag(sWPTag, iWPCount))){
iWPCount++;
}
//Spawn the NPC there
object oSpawnedNPC = CreateObject(
OBJECT_TYPE_CREATURE,
GetResRef(OBJECT_SELF),
GetLocation(GetObjectByTag(sWPTag, Random(iWPCount))),
TRUE,
sTag
);
}
void main(){
if(GetIsPC(GetLastKiller())){
float fRespawnTime = 20.0;
string sResRef = GetResRef(OBJECT_SELF);
string sTag = GetTag(OBJECT_SELF);//note this should have the ~Respawn Prefix in it
DelayCommand(fRespawnTime,SpawnNewMe(sResRef,sTag));
}
}
Haven't had a chance to test them yet, but if you have any issues I'll do what I can.. I suppose I did get you into this mess to begin with!
#16
Posté 21 octobre 2010 - 12:35
Ne0nx3r0 wrote...
Is there some trick to posting code and keeping the formatting here?
I just use the standard form to reply rather than the quick one and just copy/paste. Works fine for me so far. I am using firefox. Not sure if that makes a difference.
#17
Posté 21 octobre 2010 - 01:01
i do have a question. where you have string sPrefix = "~Respawn";//can be whatever.... not familiar with this type of thing, so would that go something like
TAG of NPC = greg
sPrefix = dude
all together = gregdude or dudegreg
or am i missing something?
thanks
TAG of NPC = greg
sPrefix = dude
all together = gregdude or dudegreg
or am i missing something?
thanks
#18
Posté 21 octobre 2010 - 02:02
As far as spawning the creature at a random location when the module loads...why not just place the monster in the toolset(it's going to be there on load anyway) maybe in an inaccessible part of your mod, and then when it (the monster) loads/spawns you just jump him to one of your locations. You would give the monster an OnSpawn script with something like so:
//OnSpawn
void main()
{
int iInt = Random(7) + 1;
object oWP = GetWaypointByTag("wp_boss" + IntToString(iInt);
ActionJumpToObject(oWP);
}
This assumes that your waypoints are numbered 1to 7 (no 0) and no space between "boss" and the number.
And then when you create/spawn him from the delay in the death script, you don't need to jump him to a location, as it will do it again with it's OnSpawn script.
Good luck.
P.S. Could use something like so for the OnDeath:
//OnDeath
void RespawnMe(string sResRef, location lLocation, string sNewTag)
{
CreateObject(OBJECT_TYPE_CREATURE, sResRef, lLocation, FALSE, sNewTag);
}
void main()
{
float fSeconds = 10.0;//Set respawn time in seconds
string sMyResRef = GetResRef(OBJECT_SELF);
location lMyLocation = GetLocation(OBJECT_SELF);
string sMyTag = GetTag(OBJECT_SELF);
AssignCommand(GetArea(OBJECT_SELF), DelayCommand(fSeconds , RespawnMe(sMyResRef, lMyLocation, sMyTag)));
}
//OnSpawn
void main()
{
int iInt = Random(7) + 1;
object oWP = GetWaypointByTag("wp_boss" + IntToString(iInt);
ActionJumpToObject(oWP);
}
This assumes that your waypoints are numbered 1to 7 (no 0) and no space between "boss" and the number.
And then when you create/spawn him from the delay in the death script, you don't need to jump him to a location, as it will do it again with it's OnSpawn script.
Good luck.
P.S. Could use something like so for the OnDeath:
//OnDeath
void RespawnMe(string sResRef, location lLocation, string sNewTag)
{
CreateObject(OBJECT_TYPE_CREATURE, sResRef, lLocation, FALSE, sNewTag);
}
void main()
{
float fSeconds = 10.0;//Set respawn time in seconds
string sMyResRef = GetResRef(OBJECT_SELF);
location lMyLocation = GetLocation(OBJECT_SELF);
string sMyTag = GetTag(OBJECT_SELF);
AssignCommand(GetArea(OBJECT_SELF), DelayCommand(fSeconds , RespawnMe(sMyResRef, lMyLocation, sMyTag)));
}
Modifié par GhostOfGod, 21 octobre 2010 - 04:42 .
#19
Posté 21 octobre 2010 - 02:11
Should be prefix, then the tag - this is mainly because it uses GetStringLeft to identify which monsters are a respawn.
#20
Posté 22 octobre 2010 - 05:07
sorry for the late reply, first i'd like to tell GoG that i tried his method works just fine, but since i don't want all of Ne0nx3r0's efforts to be for naught, i will use his scipt for this "need", and use yours for another "need" i have.
thanks to you all for your help.
thanks to you all for your help.





Retour en haut







