Area Script centered on PC

Post » Fri Feb 18, 2011 10:47 pm

I've been wondering about something for awhile now.

I wanted to make a script that causes a damaging effect on any creature that is within a certain distance of an NPC. I can't figure out how to make an area script move with something. I can only make it happen to creatures within a certain area, but I can't make the area move.

Say I wanted an NPC, who moves around to different locations over time, to have a script attached to it that causes 5 Fire Damage/second to any creature too close to them. If the creature moves far enough away, they stop taking damage. Is this possible? If so, how do I do it?
User avatar
Robyn Lena
 
Posts: 3338
Joined: Mon Jan 01, 2007 6:17 am

Post » Sat Feb 19, 2011 7:14 am

The easiest way is to use an X-Marker, and use a Script to keep moving it to the target, and casting every so often; you can use this to distinguish your area, and then to trigger another spell that does the damage via Script Effect-- sort of like.


Spell One Targets NPC
NPC Is Hit by Spell
Spell Produces Wider Effect
Wider Effect Hits Other NPC
Spell Triggers Spell Two to fire on NPC

I use something like this in some of my Mods.

ScriptName Spell01Ref Target1Ref Target2Begin ScriptEffectStart   Set Target1 to GetSelf   Set Target2 to Player  If ( Target1 != Target2 )      If ( Target2 != Target1 )           CastMarker.MoveTo Target1           CastMarker.Cast SPell02 Target1      EndIf   EndIfEnd

User avatar
Cartoon
 
Posts: 3350
Joined: Mon Jun 25, 2007 4:31 pm

Post » Sat Feb 19, 2011 7:26 am

Simmilarly (I've never tried it but I think) you can have an effect box (like the collision-box or kill-box) continuously resetting its position to the NPCs position, using set commands. If you gave that box an effect anything in that area would be effected by it.
User avatar
Kristina Campbell
 
Posts: 3512
Joined: Sun Oct 15, 2006 7:08 am

Post » Sat Feb 19, 2011 9:17 am

I'm using an invisible activator which is always following a certain actor via "setPos"-calls and regularly casts an AOE Scripted Effect Spell (those "target" spells with an area effect setting) to spam the actor's surrounding and apply said spell script to any actor in range it hits. That's one script moving the invisible activator and one script for the spell effect applied to the actors hit. This way I get a script running on every actor in range to do interesting things.

In the case you described it'd be far easier even, because you only need the script which is updating the caster's position and calls "cast XXX YYY" to make it cast the spell XXX on the governing actor YYY (which always is "in the center of explosion", if you like), say a Quest Script to run every second as you said, and the actual spell XXX (effect fire damage 5 in your example) can be a Vanilla one or a custom and doesn't even need to be scripted at all.

If it helps any, here's the snippet of my code part for this task:
set source to DrakeDragonRaceScanner;move into new cell with player and reset count so spell is cast immediatelyif(source.getInSameCell player != 1)  source.moveTo player  set timer to 0endifif(timer <= 0)  set playerX to player.getPos X  source.setPos X playerX  set playerY to player.getPos Y  source.setPos Y playerY  set playerZ to player.getPos Z  source.setPos Z playerZ  source.cast DrakeDragonRaceScannerAura player  set timer to 1else  set timer to (timer - getSecondsPassed)endif

The upper part makes sure the invisible activator, my caster, is in the same cell as the player and the lower part updates its position and makes it cast the spell.
There's a little timer, conveniently it's even set to 1 second already, DrakeDragonRaceScannerAura is my custom spell (just ignore it and create your own or use an existing one), and DrakeDragonRaceScanner is the "persistent reference" ID of my invisible activator, neatly put away into a holding cell at game start so it doesn't mess with any existing cells.
The most important parts come in the setup of the actual spell, as you need to make it an area spell with a defined range and such. Unfortunately I have no access to the CS at the moment so I can't take a look which options those were.
User avatar
Kahli St Dennis
 
Posts: 3517
Joined: Tue Jun 13, 2006 1:57 am

Post » Fri Feb 18, 2011 9:43 pm

There is a perfectly good tutorial on how to do http://cs.elderscrolls.com/constwiki/index.php/Casting_Spells_From_An_Activator on the CS Wiki. However, another often simpler way is to use OBSE's http://obse.silverlock.org/obse_command_doc.html#Ref_Walking_Functions to iterate through all surrounding actors and use getDistance to figure out which actors are close enough. It looks like this;

	; Do something to surrounding actors within 4000 units of the player	let actor := getFirstRef 69 1	while actor	 	if actor.getDead == 0 && actor.getDistance player < 4000			; Call aaMyFunction OBSE function on actor.			actor.call aaMyFunction		endif		let actor := getNextRef	loop

User avatar
Motionsharp
 
Posts: 3437
Joined: Sun Aug 06, 2006 1:33 am

Post » Fri Feb 18, 2011 11:15 pm

Thanks for the quick replies guys. CS says that "Script Command Let Not Found". I have OBSE so I don't know what's wrong. Is "Let" something that only came out recently? Perhaps a new version came out that I don't know about. Preventing the Activator from shooting at me or actors not attacking me is the easy part. I set the target to the PC so I could see if it worked first. I decided to use Drake's idea. The script looks fine to me, but for some reason it won't run. There are no errors, it just doesn't do anything.

Here is what I have:

ScriptName TestFlameAuraref sourceshort posplayerXshort posplayerYshort posplayerZfloat timerBegin gamemodeset source to ICastFlameAura;move into new cell with player and reset count so spell is cast immediatelyif (source.getInSameCell player != 1)  source.moveTo player  set timer to 0endifif(timer <= 0)  set posplayerX to player.getPos X  source.setPos X posplayerX  set posplayerY to player.getPos Y  source.setPos Y posplayerY  set posplayerZ to player.getPos Z  source.setPos Z posplayerZ  source.cast 000FlameAuraOuch player  set timer to 1else  set timer to (timer - getSecondsPassed)endifEnd


The script should cast a Fire Spell with a radius of 25 on the PC every second. Nothing happens at all. What should I do?
User avatar
Blackdrak
 
Posts: 3451
Joined: Thu May 17, 2007 11:40 pm

Post » Fri Feb 18, 2011 10:48 pm

What do you have this Script Attached to?

Usually, if it is attached to an Object, Scripts will not run unless the Object is in the same cell as the Player (I am not sure, off the top of my head, whether this is true for Quest Item -marked objects-- I recall reading something about them, but...); if it is attached to a Quest Script, is the Quest set to run, and what is it's priority? If it is a Quest Script, you can use an Quest Delay Variable to make it run faster:

Float fQuestDelayTimeSet fQuestDelayTime to 1 ;- Makes it run every second

User avatar
Tom Flanagan
 
Posts: 3522
Joined: Sat Jul 21, 2007 1:51 am

Post » Sat Feb 19, 2011 6:15 am

The script is attached to an Activator "object". The script is an object script. I thought that I set the script up to make the object follow me. Did I mess up?
User avatar
Jade Muggeridge
 
Posts: 3439
Joined: Mon Nov 20, 2006 6:51 pm

Post » Sat Feb 19, 2011 6:31 am

The object script will only run if the cell is loaded, so you must go with the PC near the object in order to trigger its script and, then, it will start following you.

But, as ABO found out some time ago, this approach is flawed because in systems with low memory, when the player leaves a cell, the cell is immediately unloaded and the object script will not run and the object is left behind.

Maybe the best solution is moving the object with a quest script instead.
User avatar
Jonathan Montero
 
Posts: 3487
Joined: Tue Aug 14, 2007 3:22 am

Post » Sat Feb 19, 2011 9:29 am

The object script will only run if the cell is loaded, so you must go with the PC near the object in order to trigger its script and, then, it will start following you.

But, as ABO found out some time ago, this approach is flawed because in systems with low memory, when the player leaves a cell, the cell is immediately unloaded and the object script will not run and the object is left behind.

Maybe the best solution is moving the object with a quest script instead.

My tests on objects only hit these problems when the objects were not persistent... if your activator is a persistent object as per the CS wiki tutorial you should be OK. My tests were moving existing non-persistent game objects (sacks) to the player, and this cannot be done reliably. You can only reliably move persistent objects.

However, my tests were not relying on scripts on the object working... they were only moving the object to the player before attempting to use on-activate type scripts on the objects. I don't know if scripts will still work on persistent objects that are in cells that are unloaded. If they don't, you can always use some other (quest?) script to move the object to the player before activating them.

The "let" command has been in OBSE for some time... since the 0017 release. It is syntactic sugar for "set to " that also supports extra OBSE operators. If it's not working for you, then probably OBSE is not working for you... Note that you need to start the CS with OBSE too for the OBSE scripting commands to compile in the CS.
User avatar
SWagg KId
 
Posts: 3488
Joined: Sat Nov 17, 2007 8:26 am

Post » Sat Feb 19, 2011 12:03 am

I have OBSE 0018, though I don't know how to run it along with the construction set, which would probably be the problem. I just know that it runs along with Oblivion and it makes stuff like Supreme Magicka work since it has advanced coding. I changed the script to "quest". Still nothing. It is a begin gamemode type so it should start up when I play.
User avatar
Samantha hulme
 
Posts: 3373
Joined: Wed Jun 21, 2006 4:22 pm

Post » Sat Feb 19, 2011 4:47 am

My tests were moving existing non-persistent game objects (sacks) to the player, and this cannot be done reliably. You can only reliably move persistent objects.


Yes, I remember now.


Object scripts, even on persistent objects, stop running when the cell is unloaded, so the object would not move itself to the player in that low memory system.

On the other hand, the script modifies its own vars, so it may keep running due to http://cs.elderscrolls.com/constwiki/index.php/Script_Processing

Hard to get to a conclusion without testing it in a low memory system.



FiddleSticks96,
Load the CS thru the OBSE loader as you do to run the game.
Just add -editor at the end and the loader will load the editor

A shortcut target should look something like: "C:\Program Files\Oblivion\obse_loader.exe" -editor
User avatar
Rachel Cafferty
 
Posts: 3442
Joined: Thu Jun 22, 2006 1:48 am

Post » Sat Feb 19, 2011 8:34 am

Just adding...

Only changing the script type to "quest" will NOT make it start automatically when the game runs. Quest-scripts always need to be assigned to actual quests, which then need to have "start-game enabled" checked to start up on their own.

And for reference, I was using my code posted above in a quest-script as well, as there's only 1 activator I move around and due to the limitations to object-scripts' execution as mentioned by the others.
User avatar
Danielle Brown
 
Posts: 3380
Joined: Wed Sep 27, 2006 6:03 am


Return to IV - Oblivion