[BETA] Oblivion Script Extender (OBSE) v0020

Post » Fri Sep 03, 2010 8:20 pm

I seem to be having a problem with OBSE 20. When I open my Imperial Furniture Reno mod, I get a ton of script errors. Basically it lists one script after the other as not being compiled.

Nevermind!! Turns out it's only one script that has this error. The other errors are normal and are a result of the nature of the IFR scripts. The one that has an error is because when I tried to add an instance of the object to the render window, the CS would crash. That was happening because the object had a zero size. For some reason, the CS won't compute the size for me anymore - it just crashes. I've noticed this is a problem under Win 7. Anyway I fixed that by deleting the version that had zero size and created a new one by taking an object that did have a size and giving it a new id. Of course, this invalidated the scripts and I forgot to recompile them :blush:

Sorry for the false alarm. :D
User avatar
Yvonne Gruening
 
Posts: 3503
Joined: Mon Apr 23, 2007 7:31 pm

Post » Fri Sep 03, 2010 5:48 pm

Out of morbid curiosity, with ar_CustomSort, is it safe for the supplied comparison function to call ar_CustomSort? I would assume it isn't, but I could see someone writing a custom sort function that sorts a multi-dimensional array by calling ar_CustomSort on the top level array and then having the comparison function custom sort the rhs & lhs arrays before testing equality.
User avatar
Marie Maillos
 
Posts: 3403
Joined: Wed Mar 21, 2007 4:39 pm

Post » Fri Sep 03, 2010 12:05 pm

Some compiler funkiness. Full script behind spoiler, excerpts below.
Spoiler
ScN zzDecayOnSkillUpint skillint countref classint specLowint specHighint indexint offsetfloat valuebegin _Function {skill count}	let class := player.GetClass	if eval ((GetName class) != " -")		let specLow := (player.GetClassSpecialization * 7) + 12		let specHigh := specLow + 6	endif	while (count > 0)		let count -= 1		let index := 33		while (index > 12)			let index -= 1			if (index == skill)				CONTINUE			endif			let offset := 5 + (player.GetRaceSkillBonus index)			if (index >= specLow) && (index <= specHigh)				let offset += 5			endif			if (player.IsClassSkill index)				let offset += 25			endif			let value := (player.GetBaseAV index) - offset			if (value <= 0)				CONTINUE			endif			let value *= (GetRequiredSkillExp index)			let value *= -0.0005			ModPlayerSkillExp index value		Loop	Loopend

If I remove the underscore, use *C commands where relevant and comment out the line with GetRequiredSkillExp (because there's no *C version), this compiles. But when I convert it to _Function, a couple of apparent parsing errors crop up.

Line 15 fails with invalid operands for * --
		let specLow := (player.GetClassSpecialization * 7) + 12
This is fixed by putting another set of parentheses around player.GetClassSpecialization.

Line 30 fails with mismatched braces --
			if (player.IsClassSkill index)
Removing the parentheses fixes it.

Edit: Similar issue in another script, let me know if you need the full context. This gives me "Invalid expression for parameter 2. Expected variable." --
			printc "Skill Decay settings loaded from %z" filename
"filename" is a string_var. Compiles fine in a non-underscore block.

...okay, after encountering another such quirk, it looks like most of these are fixed by adding parentheses which I'm generally fine with. The if statement that was broken by parentheses disturbs me, tho.
User avatar
Sun of Sammy
 
Posts: 3442
Joined: Mon Oct 22, 2007 3:38 pm

Post » Fri Sep 03, 2010 10:59 am

. . . Edit: Similar issue in another script, let me know if you need the full context. This gives me "Invalid expression for parameter 2. Expected variable." --
			printc "Skill Decay settings loaded from %z" filename
"filename" is a string_var. Compiles fine in a non-underscore block.

Probably the same reason it breaks sv_construct, as scruggsy mentioned in http://www.gamesas.com/index.php?/topic/1153305-beta-oblivion-script-extender-obse-v0020/page__view__findpost__p__16882678
User avatar
N Only WhiTe girl
 
Posts: 3353
Joined: Mon Oct 30, 2006 2:30 pm

Post » Fri Sep 03, 2010 1:57 pm

Have I missed something, or is there currently no direct command to get a FormID as an integer?
User avatar
Kelsey Anna Farley
 
Posts: 3433
Joined: Fri Jun 30, 2006 10:33 pm

Post » Fri Sep 03, 2010 12:19 pm

Some compiler funkiness. Full script behind spoiler, excerpts below.
[snip]
...okay, after encountering another such quirk, it looks like most of these are fixed by adding parentheses which I'm generally fine with. The if statement that was broken by parentheses disturbs me, tho.

Yeah, both of the class functions take an optional 'class' argument which is why the parens are needed. Hmm, that's mildly annoying. I think I can get the compiler to recognize and respond to those sorts of expressions.
Out of morbid curiosity, with ar_CustomSort, is it safe for the supplied comparison function to call ar_CustomSort? I would assume it isn't, but I could see someone writing a custom sort function that sorts a multi-dimensional array by calling ar_CustomSort on the top level array and then having the comparison function custom sort the rhs & lhs arrays before testing equality.

Yes, it's safe. You just have to make sure you're not doing anything hugely recursive; remember that there's a limit of 30 nested function calls.
Have I missed something, or is there currently no direct command to get a FormID as an integer?

It's actually not possible due to precision issues - FormIDs can range up to 0xFFFFFFFF but script variables are handled variously as single- or double-precision floats, so dynamic refIDs won't reliably fit.
User avatar
Russell Davies
 
Posts: 3429
Joined: Wed Nov 07, 2007 5:01 am

Post » Fri Sep 03, 2010 10:04 pm

Edit: Never mind, somehow the script editor is giving me explicit open/close quotes instead of neutral ". Of course that doesn't work, but it's not your problem. :P

May as well use this post slot for something: a fun side-effect of the OnScriptedSkillUp trigger is that when you test it with ModPCS at the console, you learn all sorts of things about which commands generate console output! As a long-term idea, what are the chances of a SuppressConsoleOutput command? Ideally, when called it would affect the calling script for one frame; it would propagate down (but not up) through function calls; and commands like printc and dbg_echo would be exempt.
User avatar
Farrah Lee
 
Posts: 3488
Joined: Fri Aug 17, 2007 10:32 pm

Post » Fri Sep 03, 2010 5:46 pm

I have a question about SetEventHandler. I want to have an OnHit event handler where I know who the attacker is, but not who the target will be. The docs say all filter arguments are optional, but I don't know how to make the target filter optional. The compiler complains no matter what I try since it's not the last argument.

scn FISTFIDGScriptref selfbegin ScriptEffectStart	set self to GetSelf	SetEventHandler "OnHit" OnFireFistHit ref:: ref::self	print "FISTFIDGScript added to " + $selfendbegin ScriptEffectFinish	RemoveEventHandler "OnHit" OnFireFistHit ref:: ref::self	print "FISTFIDGScript removed from " + $selfend

User avatar
..xX Vin Xx..
 
Posts: 3531
Joined: Sun Jun 18, 2006 6:33 pm

Post » Fri Sep 03, 2010 3:31 pm

I have a question about SetEventHandler. I want to have an OnHit event handler where I know who the attacker is, but not who the target will be. The docs say all filter arguments are optional, but I don't know how to make the target filter optional. The compiler complains no matter what I try since it's not the last argument.


Since the "attacker" is listed as second argument in the docs, it's referred to as object::.
The "target" listed as first argument would be reffered to as ref::. Since it doesn't matter who is the target, you just don't specify anything about it.



i.e. your script should look like this:
scn FISTFIDGScriptref selfbegin ScriptEffectStart        set self to GetSelf        SetEventHandler "OnHit" OnFireFistHit object::self        print "FISTFIDGScript added to " + $selfendbegin ScriptEffectFinish        RemoveEventHandler "OnHit" OnFireFistHit object::self        print "FISTFIDGScript removed from " + $selfend

User avatar
Kim Kay
 
Posts: 3427
Joined: Fri Oct 13, 2006 10:45 am

Post » Fri Sep 03, 2010 11:07 pm

Thanks that works, I see what I did wrong. Still I think the docs could use a little more clarification on this, since the way these arguments are specified is different from (almost?) all other functions. At least it wasn't obvious to me.
User avatar
Nancy RIP
 
Posts: 3519
Joined: Mon Jan 29, 2007 5:42 am

Post » Fri Sep 03, 2010 11:16 pm

Gee... Can the CS Wiki get updated too?

Looks like it hasn't been updated since 15
User avatar
Charles Weber
 
Posts: 3447
Joined: Wed Aug 08, 2007 5:14 pm

Post » Fri Sep 03, 2010 11:54 pm

19, but who's counting.

Actually, some parts of it are older than that.

Anyway, you want to update it? You do it. It is, after all, freely editable. I'll probably try to get around to doing it myself at some point, but ya know, all-in-all I'm rather tired of complaints about the Wiki.
User avatar
Rude_Bitch_420
 
Posts: 3429
Joined: Wed Aug 08, 2007 2:26 pm

Post » Sat Sep 04, 2010 12:31 am

Not sure if this is a wish list forum, but I'm going to ask anyways and see what everyone thinks:

GetCurrentAnimFrame/GetCurrentAnimTime
These would give the current animation's Frame / Time (based on how far the animation has played). Obviously, the animation can have string commands built in, but with all of the animations playing at once, those string functions can't talk directly to the actor playing them (that I've seen). Since an animation can't directly talk to a script running on an actor, retrieving the frame or time from the animation playing, one could easily "sync" an action there (like for example, upward thrust curve derived by the flap of a wing).

DisableFallDamage/EnableFallDamage/HasFallDamage
This would be actor based and would disable/enable actors from receiving or taking fall damage. (ResetFallTimerDamage only works for Player.)

SetActorVelocity/GetActorVelocity
This would allow an actor's velocity to be set/gotten (x,y,z): Actor.SetActorVelocity 0,0,0 would stop the actor from moving. This would also stop the actor from falling (due to gravity).
Actor.GetActorVelocity xFloatVar yFloatVar zFloatVar would place the values into 3 float variables.

SetActorRace/ResetActorRace
Actor.SetActorRace RaceRef (DATA) would set the actor to that race, it would ignore the "playable" flag, allowing for hidden races to be used. The (DATA) would hold all the information of the race config, which needs to be savegame persistent.
Actor.ResetActorRace (DATA) would set the actor back to it's original race (and settings). This would also require valid (DATA) to be present. These would finally allow Oblivion to have the magic a magic world should have (the ability to turn NPC's into creatures and use them as such and then turn them back later, or for the player to have that happen to them and get out of it).
(DATA): My thought would be the first is a ref to the original Race, then a series of longs where the information on how the character's settings were altered (in the character creation), in longs for each setting change. Since most of the time longs are persistent in savegames, it'd make a safe storage for the data. Another thing is using these two together, you could alter the character's normal settings during game-play.

OverrideAnim
This would let you override an existing animation for an actor with a replacement. This wouldn't be game save persistent, so you'd need to re-apply it after each load.
Actor.OverrideAnim Forward walkforward.kf Characters/Egyptian/WalklLkeAnEgyptian.kf

MustFleeFrom
Much like the in-game flee, this would let you: Deer.MustFleeFrom Horse, making the Deer run away from that Horse. This would be a non-combat flee, like deers do when you get near them. MustFleeFrom would not "stop fleeing" until far enough away from Horse, this would make situations where the Deer wouldn't normally flee with Forceflee, to flee anyways. Would be useful in scenes where a big weapon comes through an Oblivion gate and starts blasting at anything that moves, people should turn and run, but ForceFlee will ignore it as it's not a threat.

I look forward to hopefully seeing some of these, hopefully I have the right thread.

GuruSR.
User avatar
Milagros Osorio
 
Posts: 3426
Joined: Fri Aug 25, 2006 4:33 pm

Post » Fri Sep 03, 2010 4:12 pm

GetNthEnemy
Lets you go through the list of enemies.

GetIsAttacking
if Actor.GetIsAttacking Player == 0
Actor.StartCombat Player ; GRR, hate player.
endif

OnDisposition

OnDisposition block would let the script decide if two ref's "like" each other, would offer the option of controlling what happens next.
If they'd start combat instantly, one or the other would both flee, they'd ignore each other, or they like each other.

GuruSR.
User avatar
vanuza
 
Posts: 3522
Joined: Fri Sep 22, 2006 11:14 pm

Post » Fri Sep 03, 2010 3:08 pm

Request: Get/SetSkillGoverningSpecialization

The vanilla skill AVs are all in nice contiguous blocks, but this can be modded even with the vanilla CS, and with AddActorValues all bets are off...
User avatar
Joanne
 
Posts: 3357
Joined: Fri Oct 27, 2006 1:25 pm

Post » Fri Sep 03, 2010 12:29 pm

I talked about this before, but this limitation still greatly annoys me, so I'll mention it again:

Could something be implemented to allow you to let a certain block be run on an external target? I need to let a Begin OnTrigger block run on many/all horses. This type of block doesn't work when it is in a Magic Ability script, it needs to be attached directly to the object through an Object script. I did this for all vanilla horses, but it means that for every mod that adds a horse to the game, a compatibility patch needs to be created.

Either an Event Handler for OnTrigger would be nice, or an expansion of ref.Call that allows you to run an Object script with vanilla begin/end blocks on the reference in that frame. With the latter solution, I could just Call for that script every frame in a Magic Ability script.

Thanks for reading!
User avatar
lucy chadwick
 
Posts: 3412
Joined: Mon Jul 10, 2006 2:43 am

Post » Sat Sep 04, 2010 12:24 am

DisableFallDamage/EnableFallDamage/HasFallDamage
This would be actor based and would disable/enable actors from receiving or taking fall damage. (ResetFallTimerDamage only works for Player.)


You could also use IsInAir and GetFallTimer to detect when an actor is falling, and temporarily toggle the god mode on for that actor. Then when it lands (IsOnGround or FallTimer of 0) you toggle the godmode off. You could even use GetTerrainHeight to only toggle the godmode on for a split second, just before they hit the ground.

SetActorVelocity/GetActorVelocity
This would allow an actor's velocity to be set/gotten (x,y,z): Actor.SetActorVelocity 0,0,0 would stop the actor from moving. This would also stop the actor from falling (due to gravity).
Actor.GetActorVelocity xFloatVar yFloatVar zFloatVar would place the values into 3 float variables.


It requires some math, but the GetPos function could allow you to calculate the current velocity of an actor. Just record the positions on two intervals, and record the difference between them. Not sure how to set the velocity though, but you could alternately place a small invisible plane model with collision under the actor to make them stop mid-air. Most flying mount mods use that technique to create the flying.

OverrideAnim
This would let you override an existing animation for an actor with a replacement. This wouldn't be game save persistent, so you'd need to re-apply it after each load.
Actor.OverrideAnim Forward walkforward.kf Characters/Egyptian/WalklLkeAnEgyptian.kf


It's not perfect, but you can override an animation by calling a SpecialIdle animation with higher priorities than the current one playing. Higher than 65 is probably always enough. You can do this by copying a vanilla anim to the IdleAnims folder, opening it in NifSkope, select the root node, and then in the Block Details window, expand the Extra Data List. For each bone, there is a priority number under it.

MustFleeFrom
Much like the in-game flee, this would let you: Deer.MustFleeFrom Horse, making the Deer run away from that Horse. This would be a non-combat flee, like deers do when you get near them. MustFleeFrom would not "stop fleeing" until far enough away from Horse, this would make situations where the Deer wouldn't normally flee with Forceflee, to flee anyways. Would be useful in scenes where a big weapon comes through an Oblivion gate and starts blasting at anything that moves, people should turn and run, but ForceFlee will ignore it as it's not a threat.


IIRC any actor/creature with a Confidence value of 0 will flee at the sight of an enemy. A workaround could be to place a restrained invisible (not the spell, just the alpha value) Creature near that big weapon with a faction that is an enemy to those you want to make run away.


GetNthEnemy
Lets you go through the list of enemies.


You can use GetTargets for that:

GetTargets - for an actor in combat, returns an Array of actors which the game considers potential targets of the calling actor at that particular moment.
(targets:Array) reference.GetTargets

GetIsAttacking
if Actor.GetIsAttacking Player == 0
Actor.StartCombat Player ; GRR, hate player.
endif


if Actor.GetCombatTarget != Player
if Actor.GetShouldAttack Player == 0
if Actor.GetDisposition Player > Actor.GetActorValue Aggression

are all working options.

OnDisposition

OnDisposition block would let the script decide if two ref's "like" each other, would offer the option of controlling what happens next.
If they'd start combat instantly, one or the other would both flee, they'd ignore each other, or they like each other.


Just using GetDisposition allows you to do exactly what you want.


Hope that helps!

(EDIT: Woops, sorry for double post! :( )
User avatar
George PUluse
 
Posts: 3486
Joined: Fri Sep 28, 2007 11:20 pm

Post » Sat Sep 04, 2010 1:19 am

There's not much documentation for OBSE's slice notation, and I haven't used it much. I assume it's supposed to imitate Python's implementation, in which case this is inconsistent:
aString[-x] yields null.
aString[-x:-x] works fine.
User avatar
Danielle Brown
 
Posts: 3380
Joined: Wed Sep 27, 2006 6:03 am

Post » Fri Sep 03, 2010 2:46 pm

OverrideAnim
This would let you override an existing animation for an actor with a replacement. This wouldn't be game save persistent, so you'd need to re-apply it after each load.
Actor.OverrideAnim Forward walkforward.kf Characters/Egyptian/WalklLkeAnEgyptian.kf

It's not perfect, but you can override an animation by calling a SpecialIdle animation with higher priorities than the current one playing. Higher than 65 is probably always enough. You can do this by copying a vanilla anim to the IdleAnims folder, opening it in NifSkope, select the root node, and then in the Block Details window, expand the Extra Data List. For each bone, there is a priority number under it.


To: GuruSR, Maegfear

As for Walk, Run, Idle, etc., OBSE already has functions which makes same behavior.
Actor.toggleSpecialAnim "Characters/Egyptian/WalklLkeAnEgyptian.kf" 1Actor.update3d


As for Attack, Recoil, and Stagger, I also have the almost same wish.
User avatar
electro_fantics
 
Posts: 3448
Joined: Fri Mar 30, 2007 11:50 pm

Post » Fri Sep 03, 2010 5:12 pm

Ah, I didn't know that Update3D worked for updating them. :)

I have another question. Would it (theoretically) be possible to create functions that store changes ingame in a .esp file rather than in the savegame? For example, I place a Static object somewhere in the gameworld, and then I use a script that stores this placement in a new esp, or in the esp of the script (either is fine). Is data stored in esp files very different from data stored in savegames? If not, only the dynamic reference pre-fix FF needs to be changed to the index of the esp to which you are writing, and then the location/rotation data of the object stored in the .esp.

It would need to be used with utmost care, but it would open up really fun possibilities...
User avatar
Charleigh Anderson
 
Posts: 3398
Joined: Fri Feb 02, 2007 5:17 am

Post » Fri Sep 03, 2010 3:25 pm

You could also use IsInAir and GetFallTimer to detect when an actor is falling, and temporarily toggle the god mode on for that actor. Then when it lands (IsOnGround or FallTimer of 0) you toggle the godmode off. You could even use GetTerrainHeight to only toggle the godmode on for a split second, just before they hit the ground.

Problem with this it's still player based (GodMode is), need something Actor based. I don't want to actually see if the actor is falling, I want to prevent damage in certain situations. Currently ResetFallDamageTimer is player only and you can't tell it's active, reading it with GetFallTimer is fine, but again, there's no way to do this on any other actor, disabling the damage would be better since the actor wouldn't be inflicted with damage on landing and would probably be easier to accomplish than resetting an actor's damage timer (since the player is probably the only one with one).

It requires some math, but the GetPos function could allow you to calculate the current velocity of an actor. Just record the positions on two intervals, and record the difference between them. Not sure how to set the velocity though, but you could alternately place a small invisible plane model with collision under the actor to make them stop mid-air. Most flying mount mods use that technique to create the flying.

Well, the thing is, it'd be nice to actually control the velocity, being able to move an actor or slow it down. There just is no control over velocity at all. I can figure the velocity out with GetPOS, thats a piece of cake, but again, knowing and not being able to change it, is frustrating. Each actor that moves has a velocity, using a push away, that actor goes flying through the air, a velocity is applied, that would be nice to get at. Another nice idea with getting access to velocity would be wind, being able to make wind push people/things around, that'd be fun, we could have tornadoes.

It's not perfect, but you can override an animation by calling a SpecialIdle animation with higher priorities than the current one playing. Higher than 65 is probably always enough. You can do this by copying a vanilla anim to the IdleAnims folder, opening it in NifSkope, select the root node, and then in the Block Details window, expand the Extra Data List. For each bone, there is a priority number under it.
The thing is, overriding a specific animation would be very useful for those making weapons and such that would only alter the animations necessary to make the weapon look better when in use. The togglespecialanim is not 100% encompassing, you can't do it with every animation group in the list.


IIRC any actor/creature with a Confidence value of 0 will flee at the sight of an enemy. A workaround could be to place a restrained invisible (not the spell, just the alpha value) Creature near that big weapon with a faction that is an enemy to those you want to make run away.

Actually, that doesn't work, ForceFlee looks for threats nearby and a confidence of 0 is rare in-game (Deer are not at 0) and having a negative disposition to something doesn't class it as a threat. I've tested this with Deers, set their disposition to the actor to a negative 100 by faction and the Deer just sits stands there like it's stuffed. ForceFlee repeatedly does nothing, nor will it make the Deer flee. You have to Actor.StartCombat Deer then Deer.ForceFlee for it to work (because Actor is the threat). That sort of situation will later make the Deer come back and attack the Actor (not something wanted), plus it'll also throw both actors into battle. ForceFlee also has no "threat" input (meaning "fake this as a threat ref"), if it did, I'd not ask for this.


You can use GetTargets for that:

GetTargets - for an actor in combat, returns an Array of actors which the game considers potential targets of the calling actor at that particular moment.
(targets:Array) reference.GetTargets

Actually, GetNthEnemy is not what you're listing, those are "possible" targets, I'm talking about current Enemies of the actor, those in combat with the actor. There currently is no 100% guaranteed way to tell if all the actors nearby are fighting an actor, plus, no way to tell who's fighting an actor if they're nowhere to be found (as in an enemy who's stuck in the woods and you're still in battle). You could GetNthEnemy like GetNthFollower only for the actor's current enemies.

if Actor.GetCombatTarget != Player
if Actor.GetShouldAttack Player == 0
if Actor.GetDisposition Player > Actor.GetActorValue Aggression

are all working options.

And all don't work... GetIsAttacking basically says "Is Actor A is being attacked by Actor B?" not the Current Combat Target. GetShouldAttack is also not going to tell me if Actor B is currently fighting Actor A. GetNthEnemy here could be used to test for this if needed. But basically it would look down the list of enemies to see if these two are in combat with each other whether they're one on one or they're in a group combat situation and have each other on their "to kill list".

Just using GetDisposition allows you to do exactly what you want.

Umm, no. OnDisposition basically alters how the disposition of actor to actor happens. Perfect example: An Ogre comes to town, someone SEEs the Ogre, the OnDisposition block is run with the Ogre and the Actor listed along with the two dispositions (for both ways). The code then determines that the Ogre is present and the other isn't an Ogre, well, the Ogre hasn't saved the princess, has never been in town before, so then checks the gender of the other actor, if female, flees, if male, grabs a weapon and starts a fight, both dispositions are set at -100 on the way out.

Currently, there is no inner AI injection method, to alter/change the behavior of any actor to actor situation. Each time an actor sees another, they test at least Disposition (there are hundreds of other factors here, but disposition is the easiest), but currently, all we can do is add factions to alter disposition, but it won't alter behavior on that disposition. You can't make anyone with -100 Disposition fight you without help (a script on the actor that causes a startcombat and we don't want to do that to every actor on the game). The OnDisposition block would make it so you'd be an enemy or friend based on your code. Another example would be Playable Creatures, you could have a flag to say "Live as one", meaning the OnDisposition would make humans attack you like you were the real thing. The creature's enemies and friends would be yours as well.

Disposition plays a minor roll in the decision on how an actor reacts at that moment, if not in Disposition, another block to control reactions would be fine. The AI in the engine is so bottled up, it's annoying and there still isn't anything globally we have access to that'd let us alter the behavior of the masses without resorting to massive token deposits (which adds bloat and performance loss).

To: GuruSR, Maegfear

As for Walk, Run, Idle, etc., OBSE already has functions which makes same behavior.
Actor.toggleSpecialAnim "Characters/Egyptian/WalklLkeAnEgyptian.kf" 1Actor.update3d


As for Attack, Recoil, and Stagger, I also have the almost same wish.

Why I was asking for an OverrideAnim, makes sense to override an existing anim with one you want.

GuruSR.
User avatar
Jessica Lloyd
 
Posts: 3481
Joined: Fri Aug 25, 2006 2:11 pm

Post » Fri Sep 03, 2010 5:16 pm

Ah, I didn't know that Update3D worked for updating them. :)

I have another question. Would it (theoretically) be possible to create functions that store changes ingame in a .esp file rather than in the savegame? For example, I place a Static object somewhere in the gameworld, and then I use a script that stores this placement in a new esp, or in the esp of the script (either is fine). Is data stored in esp files very different from data stored in savegames? If not, only the dynamic reference pre-fix FF needs to be changed to the index of the esp to which you are writing, and then the location/rotation data of the object stored in the .esp.

It would need to be used with utmost care, but it would open up really fun possibilities...

You might want to look at the OBSE documentation:

GetNumericINISetting - returns the specified ini setting
(setting:float) GetNumericINISetting iniSettingName:string

SetNumericINISetting - sets the specified ini setting to the following variable or direct value
(nothing) SetNumericINISetting iniSettingName:string value:float

GetStringINISetting - returns the value of a string ini setting
(setting:string_var) GetStringINISetting settingName:formatString

SetStringINISetting - sets the ini setting to the specified string. Pass both arguments as a single string of the format "settingName|newValue". If called from the console, use the "@" character in place of the pipe character.
(nothing) SetStringINISetting settingNameAndValue:formatString


That would do the trick.

GuruSR.
User avatar
Andrea P
 
Posts: 3400
Joined: Mon Feb 12, 2007 7:45 am

Post » Fri Sep 03, 2010 10:11 pm

Oooooh, I love what you've added in this version. A lot of those functions are going to make my modding life much easier, thank you! :wub:

If you are still taking requests, I would love SetIsPlayersLastRiddenHorse and/or SetPlayersLastRiddenHorse and/or SetPlayerHasLastRiddenHorse, so I could change (or nullify) the active horse without the player having to actually mount another horse.
User avatar
Sara Johanna Scenariste
 
Posts: 3381
Joined: Tue Mar 13, 2007 8:24 pm

Post » Fri Sep 03, 2010 9:21 pm

Uuhm no, that doesn't do what I want at all, changing INI settings is something completely different from saving the data of dynamically placed references in a .esp file.




Actually, GetNthEnemy is not what you're listing, those are "possible" targets, I'm talking about current Enemies of the actor, those in combat with the actor. There currently is no 100% guaranteed way to tell if all the actors nearby are fighting an actor, plus, no way to tell who's fighting an actor if they're nowhere to be found (as in an enemy who's stuck in the woods and you're still in battle). You could GetNthEnemy like GetNthFollower only for the actor's current enemies.



Why not walk through all the potential targets in the target list, and do a GetCombatTarget check to the actor? Then you have everyone who is attacking the actor. You could alternately iterate over all the actors/creatures in the surrounding cells with GetFirstRef and GetNextRef, just in case the actor hasn't detected everyone that is attacking him yet.

And all don't work... GetIsAttacking basically says "Is Actor A is being attacked by Actor B?" not the Current Combat Target. GetShouldAttack is also not going to tell me if Actor B is currently fighting Actor A. GetNthEnemy here could be used to test for this if needed. But basically it would look down the list of enemies to see if these two are in combat with each other whether they're one on one or they're in a group combat situation and have each other on their "to kill list".



I either misunderstand you, or you have an incorrect interpretation of GetCombatTarget. "If ActorB.GetCombatTarget == ActorA" does tell you if ActorA is currently being attacked by ActorB.
User avatar
flora
 
Posts: 3479
Joined: Fri Jun 23, 2006 1:48 am

Post » Fri Sep 03, 2010 2:15 pm

Uuhm no, that doesn't do what I want at all, changing INI settings is something completely different from saving the data of dynamically placed references in a .esp file.

I don't know if it's possible with OBSE proper (don't know if the game executable has support for writing mods, and if it doesn't, I don't imagine the OBSE team wants to write such support from scratch), but it's definitely possible if an OBSE plugin is written based off of CBash. Most of the work would be to expose the current API as function commands...you'd have support for reading/writing any field of any mod. It's been on the back of my mind to do once CBash reaches 1.0, but anyone is welcome to take a stab at it.
User avatar
Laura Elizabeth
 
Posts: 3454
Joined: Wed Oct 11, 2006 7:34 pm

PreviousNext

Return to IV - Oblivion

cron