Difference between revisions of "Command an NPC/Creature to Attack"
imported>Phinix |
imported>Phinix |
||
(8 intermediate revisions by 2 users not shown) | |||
Line 2: | Line 2: | ||
[[Category:Scripting]] | [[Category:Scripting]] | ||
This tutorial will explain how to set up a script on a custom NPC/creature so that by activating it you will be able to command it to attack nearby actors (including friendlies.) | This tutorial will explain how to set up a script on a custom NPC/creature so that by activating it you will be able to command it to attack nearby actors (including friendlies.) | ||
== Create a Global variable == | == Create a Global variable == | ||
Line 31: | Line 29: | ||
begin ScriptEffectUpdate | begin ScriptEffectUpdate | ||
if | if globalvar1 == 1 | ||
SetAV Aggression 50 | SetAV Aggression 50 | ||
elseif | elseif globalvar1 == 2 | ||
SetAV Aggression 10 | SetAV Aggression 10 | ||
endif | endif | ||
Line 39: | Line 37: | ||
begin ScriptEffectFinish | begin ScriptEffectFinish | ||
SetAV Aggression 10 | |||
end | end | ||
Line 54: | Line 52: | ||
Now right-click the space on the right and select "New" to bring up the box to add a new spell effect. | Now right-click the space on the right and select "New" to bring up the box to add a new spell effect. | ||
For the effect choose "Script Effect" and give it a duration | For the effect choose "Script Effect" and give it a duration of 0, since we're adding it as an Ability which remains constant. | ||
Give it an "Effect Name," then choose any school and visual. Do not check "Effect is Hostile." | Give it an "Effect Name," then choose any school and visual. Do not check "Effect is Hostile." | ||
Line 99: | Line 97: | ||
set activestat to 0 | set activestat to 0 | ||
elseif button == 1 | elseif button == 1 | ||
set timer to 1.5 | |||
set globalvar1 to 2 | set globalvar1 to 2 | ||
set activestat to 0 | set activestat to 0 | ||
Line 105: | Line 104: | ||
endif | endif | ||
endif | endif | ||
endif | endif | ||
if globalvar1 == 2 | if globalvar1 == 2 | ||
if | if timer == 0 | ||
set | set globalvar1 to 0 | ||
elseif timer > 0 | |||
set timer to timer - getSecondsPassed | |||
StopCombatAlarmOnActor | |||
elseif timer < 0 | |||
set timer to 0 | |||
endif | endif | ||
endif | endif | ||
Line 130: | Line 118: | ||
That should do it. I set my summons to have '''aggression''' at 10 in their AI setup by default. That way they’ll fight when attacked but won’t go after friendlies unless you command them to. | That should do it. I set my summons to have '''aggression''' at 10 in their AI setup by default. That way they’ll fight when attacked but won’t go after friendlies unless you command them to. | ||
'''UPDATE:''' The reason I use the timer for setting the defensive state to 2 and then back to 0 (waiting state) is so that if multiple NPC/Creatures are watching this same global variable status to change their hostility (using the Ability script we added), we want to give the game a few frames to think about it so all of them get the message. | |||
This is something I have discovered in troubleshooting some issues with actor scripts seemingly losing the ability to effect the global through their menu. I believe this has been resolved by adding the Ability to their spell list directly in the editor rather than attempting to do so on-the-fly via additional scripting. This method eliminates some unnecessary complexity, and seems to work better. Your mileage may vary. | |||
Best of luck! | Best of luck! | ||
Latest revision as of 11:09, 26 December 2009
This tutorial will explain how to set up a script on a custom NPC/creature so that by activating it you will be able to command it to attack nearby actors (including friendlies.)
Create a Global variable[edit | edit source]
Start by clicking Gameplay on the main CS menu, and select Globals.
Right-click the list on the left and select "New."
Give your variable a name. For this guide I’ll use globalvar1 but you'll want to make certain and use something unique for any global you create.
You can see it gets set as a short variable with a value of "0" by default, which is what we want. Click OK to close the Globals window.
Create a Magic Effect script[edit | edit source]
Next you need to create a new script. Again from the main CS menu click Gameplay and then Edit Scripts.
In this windows click Script and then New. For Script Type select Object (this is the default.)
Paste the following into the script body, using whatever you want in place of MyFrenzyScript and again substituting globalvar1 with whatever you named your global variable from before:
ScriptName MyFrenzyScript begin ScriptEffectStart end begin ScriptEffectUpdate if globalvar1 == 1 SetAV Aggression 50 elseif globalvar1 == 2 SetAV Aggression 10 endif end begin ScriptEffectFinish SetAV Aggression 10 end
Click the little floppy disk icon or Script-->Save to save, and then close the script window.
Create the Frenzy spell[edit | edit source]
Next click Spell from the tree menu on the left side of the Object Window. (You might have to expand the Magic branch to see it.)
Right-click the list space on the right and select "New." Give your spell a name and an ID (for this example I’ll use myFrenzySpell for the ID; you can use anything you want as well as for the Name.) Select "Ability" from the Type dropdown and make sure "Disallow Spell Absorb/Reflect", "Script Effect Always Applies", and "Immune to Silence" are all checked.
Now right-click the space on the right and select "New" to bring up the box to add a new spell effect.
For the effect choose "Script Effect" and give it a duration of 0, since we're adding it as an Ability which remains constant.
Give it an "Effect Name," then choose any school and visual. Do not check "Effect is Hostile."
For the Script select the one you just made.
NOTE: Left this out before; it is very important you be sure to put this spell in the spell list of the NPC/Creature you want to be able to command.
Do this by first double-clicking the MPC/character in the CS to open their stats sheet. Click the SpellList tab.
Now go back to the Spell branch of the Object Window and find your Frenzy spell you just made, and drag it into the NPC/Creature's spell list.
Create the Object script for your NPC[edit | edit source]
Follow the same steps as above to create another new script, only make this one an Object type. You can replace the names of the short and float variables listed at the top to be whatever you wish. Same goes for the script name.
Once created this script will need to go on the NPC/creature you want to command:
ScriptName MyNPCScript short timerinit short activestat short button float timer begin OnActivate if IsActionRef player == 1 set activestat to 1 if activestat == 1 MessageBox "Command?", "Attack", "Defend", "Cancel" set activestat to 2 endif endif end begin GameMode if activestat == 2 set button to getbuttonpressed if button > -1 if button == 0 set globalvar1 to 1 set activestat to 0 elseif button == 1 set timer to 1.5 set globalvar1 to 2 set activestat to 0 elseif button == 2 set activestat to 0 endif endif endif if globalvar1 == 2 if timer == 0 set globalvar1 to 0 elseif timer > 0 set timer to timer - getSecondsPassed StopCombatAlarmOnActor elseif timer < 0 set timer to 0 endif endif end
That should do it. I set my summons to have aggression at 10 in their AI setup by default. That way they’ll fight when attacked but won’t go after friendlies unless you command them to.
UPDATE: The reason I use the timer for setting the defensive state to 2 and then back to 0 (waiting state) is so that if multiple NPC/Creatures are watching this same global variable status to change their hostility (using the Ability script we added), we want to give the game a few frames to think about it so all of them get the message.
This is something I have discovered in troubleshooting some issues with actor scripts seemingly losing the ability to effect the global through their menu. I believe this has been resolved by adding the Ability to their spell list directly in the editor rather than attempting to do so on-the-fly via additional scripting. This method eliminates some unnecessary complexity, and seems to work better. Your mileage may vary.
Best of luck!