How to make a Static Object Summon Creatures
So here's the idea I came up with. I built a rather elaborate mage tower, and I wanted it to be totally complete. I wanted a mage tower that no mage would really want to leave, unless it was to do the quests and perhaps get money and such. A true home for a grand mage. Well, after going through all the obvious things (alchemy lab, garden for components, library, enchanting and spell making stations, royal bedchambers, etc.) I came across a need for souls. Soul gems don't just fill themselves, after all. While I could've went the cheap route and designed a machine to do it, I wanted this somewhat more "real-life". I created a war room. I have a lecturn (much like those for enchanting and spell making) that can summon creatures. I then soul trap them, kill them, and viola. Now given the fact that it took me a good long time to do this, I hope I can assume there are others out there that are looking for something similiar. Hence this post. So, now that the narrative is outta the way, let's begin.
I should point out that the item in question is not static, but is an activator. I don't see how it'd be too hard, as virtually any item can be made into an activator with NifSkope. Just select the item you want to use out of the activator menu, or unload the BSA files and create your own activator. There are many tutorials on that, and we won't get into it here. Just make sure said activator runs the script that we're about to create, and you won't have any troubles.
My initial idea was to create a station that would summon said monsters, as per the spell. There are guides out there to do this, but the scripts take quite some time to modify and add in. I also went the idea of actually having the station create said monsters using the PlaceAtMe function. That led to more frustrations than I could possibly tell you. Here's what I did in the end.
Scriptname SummoningStation ref Xivilai ref GWraith ref Lich ref Daedroth short alive short button short stage
Now to explain. The Scriptname obviously names your script, so you can return to it later. Name it whatever you please. I created several variables here. ref means a reference to something later defined. In this, I created ref's to four monsters, a Xivilai (mean little devils), a Gloom Wraith, a Lich, and a Daedroth. Now it doesn't matter what you name these references. You could call the Gloom Wraith "sissy" and it wouldn't matter, so long as you use that reference from then on. The word short refers to a short integer. A number of some specific value, always a whole number. I wanted to test to see if the creature was alive, and I wanted buttons for our menus. The stage reference is to mainly close out the menu when we're done, as you'll see later.
begin onactivate set Xivilai to SummonXivilaiWR.createfullactorcopy set GWraith to SummonGloomWraithWR.createfullactorcopy set Lich to SummonLichWR.createfullactorcopy set Daedroth to SummonDaedrothWR.createfullactorcopy
Begin OnActivate tells the program that this object should begin it's script when the player attempts to activate said object. There are many other ways to begin a script, but they are beyond the scope of this tutorial.
After that, we start to define our references made at the start, and here's where it gets a bit tricky, so you may want to re-read this a few times if you're not familiar with coding. What you want to do is create a room in the cell you are editing that the player cannot see. I simply added a room that wasn't even attached to my mage tower. Now, you need to go to the Object Window and select Actors->Creature and select the creatures you'd like to spawn. Place them in the aforementioned room. Double-click on them, and give them a name in the Reference ID space. As you can see from above, the names I gave mine were SummonXivilaiWR, SummonGWraithWR, and so on. Then, in that main window, check the "Persistant Reference" option. From that point on, you need only remember the name you gave each creature.
Here also we need to discuss the little addendum I added. CreateFullActorCopy is a function you can look up here on this wiki. It creates a full copy of the specified target and it's base, including all inventory items.
MessageBox "Which monster would you like to summon?", "Xivilai", "Gloom Wraith", "Lich", "Daedroth", "Cancel" set stage to 1 set alive to 1 end
Here is where we create our menu and what it will say. MessageBox tells the program we want a menu displayed. After the first set of quotations is where you put what you want your menu to say. Always include the comma after it, as that tells the program that you now want to define the options. Underneath all this, the program is defining values for each option. The first option you list is given a value of 0. The second is given a 1, and so forth. You can feel free to give as many options as you'd like, but limit it due to the GUI and just common sense.
We also set the two variables I mentioned earlier to a value of 1. This just tells the program to stop running the script, as you'll see later. The end signifies the end of the Begin OnActivate command.
begin gamemode set Button to getButtonPressed if stage == 1 && button == 0 Xivilai.moveto killroommarker Message "Xivilai Summoned." if alive if Xivilai.getdead set alive to 0 Xivilai.deletefullactorcopy endif endif set stage to 0 Return
The begin gamemode just tells the program that what happens here should be run in game time, not being paused.
Here we also set what the reference of Button does. GetButtonPressed is a function in the program that tells the program what the user presses. As I said earlier, each of your options is assigned a value, starting with 0 and going on. We just told the program that the term Button should have that value.
If statements just mean that if this condition exists, do the following lines of code. If the condition does not exist, the program will skip those lines and move on to the next. In this case, since stage will always be 1 as long as the program is running, that condition will always be true. && is code for saying If stage is set to 1, AND button is set to 0, this condition is true. Button being set to 0 means that the user has selected the first choice, in this case, the Xivilai.
Xivilai.moveto tells the program to go get the named Xivilai and move him somewhere. What you want to do before you save this script is go to the place you want him to appear, and go to your Objects window, then go to World Objects->Static->XMarkerHeading. Grab that and place it where you want the monster to appear and in what direction. Double-click the XMarker and give it a name. My name was killroommarker. Now, after the moveto part, tell the script the name of your XMarker. It will then make the monster appear there.
After that, I added a Message function that simply tells the user, "hey, you just summoned a Xivilai. Idiot.". You can make it say whatever you like. We then test to see if he's alive. As we have already set alive to 1, he sure enough is. We then add a clause there. if Xivilai.GetDead means if he gets himself killed, one way or another, then we have to tell the script that. We do so by setting alive to 0. Then we add Xivilai.DeleteFullActorCopy. That removes him from our sight. He's dead, and good riddance. The endif is necessary to close out our if statement. We're telling the program that that's all we need done. Add one endif for every if you have, but make sure you get it to do all you want it to do before you add the endif. After that, the program will ignore any lines of code you have. We then set the stage variable to 0 to tell the program we're done. Return sends the program back to it's start, where it sees now that alive and stage are both 0. It then tries to go back through the program, but it sees that stage is 0, so none of the if's run. It then ends.
elseif stage == 1 && button == 1 GWraith.moveto killroommarker Message "Gloom Wraith Summoned." if alive if GWraith.getdead set alive to 0 GWraith.deletefullactorcopy endif endif set stage to 0 Return
You then create a nearly exact replica of the previous code for each menu option you want to have. Remember, the first option is given a value of 0, so the second will be 1. In this case, the second option (button 1) is my Gloom Wraith. So instead of Xivilai, I substitute my names for the gloom wraith and do exactly the same thing as before. The only difference I need to point out is the insertion of elseif. This is a command that says, well, since the first if didn't work, try this one.
Skipping ahead now...
elseif stage == 1 && button == 4 set stage to 0 Return endif End
When we initiated our menu, I added an option of "Cancel", which in my case, was the fifth option, making it button #4. This gets you out of the menu with no monsters summoned. All we did in this option was set the stage variable to 0. That last endif closes out all of our previous elseif's and the original if. And of course, End tells the program that we're done completely now, and to close the script.
I do hope this helped. While this is certainly a small niche of people looking for this particular thing, I think it can be applied to a great many projects if you have the interest.
AnImbroglio 07:03, 7 March 2007 (EST)