TheManWithoutAPlan Posted January 4, 2018 Share Posted January 4, 2018 Hi all, I'm new at modding in general (though I have a background with computers). I have been trying to make a modded spell that turns whatever it hits into a sheep. After reading through some documentation on the wiki, I figured the best way to do this was as follows - make the spell call 'target.PlaceAtMe <Sheep Code>', since the documentation on PlaceAtMe says that it can be used on any actor. After doing this, I could disable the target (to get the 'turned into a sheep' effect). I've been experiencing some troubles with this, though. The code compiles, but it seems to stop executing at this line (any code that comes before that line of the script is still executed). I'm guessing that it is blowing up because I'm doing something wrong and that's why the rest of the script is not getting executed. Although the documentation seemed to suggest that you could use PlaceAtMe with any actor, I have not seen anyone use it outside of using 'Player.PlaceAtMe'. If someone could help me out with this, I would really appreciate it! If you guys have more ideas on how to get my sheep spell to work, I would love that too! For reference, here is the code that I currently have for my spell script: scn SheepsRUsScript ref target begin ScriptEffectStart set target to getself if( target != player ) && ( target.IsActorEvil ) ;This isn't the issue, I made another spell with this setup and that one has no problems. target.PlaceAtMe 000151DD target.Disable endif end Link to comment Share on other sites More sharing options...
TheManWithoutAPlan Posted January 4, 2018 Author Share Posted January 4, 2018 I figured out the issue! You can use PlaceAtMe on other actors! The issue was in the if statement. I commented out everything after 'if( target != player)' and it worked! Yay for sheep! I would still like to know if there is a way to tell if an actor is an enemy or not, though. This would help, because then friendlies could not get hit by this. Thanks everyone! Link to comment Share on other sites More sharing options...
Surilindur Posted January 4, 2018 Share Posted January 4, 2018 (edited) Unfortunately I cannot comment on the PlaceAtMe aspect because it has been the subject of some debate as a function (it has been argued that overusing PlateAtMe might cause 'bloat' in the long term). Hopefully someone else can give you some more ideas on how to maybe avoid that. :blush: It is possible to use the editor ID of an object in a script. If the sheep has a form ID of 000151DD (the one in your script) and an editor ID of "Sheep" (I have no idea what it really is, you should check it before typing anything), then just using the editor ID "Sheep" in the script would be enough. The object (Sheep) can be renamed after the script has been compiled, but it will not effect the already compiled script, so I suspect the name is converted to the form ID when compiling the script. But when writing the script, it makes the script more readable to use the editor ID and not form ID. For example to add a weapon to a character, one could use: SomeActorRef.AddItem WeapIronDagger 1As for the script, magic effect scripts are run on the target actor: casting a spell with a custom script effect on an NPC will have the script run on that NPC, just like an object script would. It is therefore possible to just use a function that needs to be run on a reference without typing the reference, because the game will consider the current NPC (that the script/effect runs on) as that reference, when the reference part is omitted in the script! Handy, some might argue. :smile: The IsActorEvil function returns true for actors that are only in evil factions and not in a single non-evil faction, so that might explain why the condition check never returned true. Maybe something like a vampire or a bandit would qualify as an evil actor, but guards or other civilians would probably not. Also, the wiki page says no creatures are considered evil, so that might also explain something. I have never had to quickly identify an enemy of the player and the allies of the player, but maybe something like the GetCombatTarget function, combined with GetAllies and an ar_Find would work? Below is a small untested idea, for the spell effect script. I have no idea if it compiles, although I think it should, but to give an idea of what to maybe try. Again, the PlaceAtMe part would need someone else to present some thoughts, I cannot comment on it, I have left it there because you had it in your script. scriptname SheepStaffScript array_var PlayerAllies ref CombatTarget begin _ScriptEffectStart ; this assumes the PLAYER is using the staff and not any other ; actor like a follower or somesuch if eval ( ( GetIsReference PlayerRef ) || !( PlayerRef.IsInCombat ) || ( IsEssential ) ) ; feel free to add any extra conditions here return endif let PlayerAllies := PlayerRef.GetAllies let CombatTarget := GetCombarTarget if eval ( ( ar_Find CombatTarget PlayerAllies ) != ar_BadNumericIndex ) PlaceAtMe Sheep 1 ; Disable --> are there any other options ??? endif ; OBSE should automatically destroy unreferenced arrays, ; (unlike string_vars), but it does not hurt to manually ; set PlayerAllies to ar_Null before the script terminates endThe example assumes you have run the CS with OBSE through "obse_loader.exe -editor" or that you use the Construction Set Extender by shademe. If you do not use the CSE, it might be worth taking a look at it! OBSE allows for the use of function return values directly in various places (like an array index): let ValFromSomeIndex := SomeArray[(SomeFuncThatReturnsNumber SomeArg SomeArg2)]So it might be possible to write the condition check in the example idea like this, too: scriptname SheepStaffScript begin _ScriptEffectStart ; this assumes the PLAYER is using the staff and not any other ; actor like a follower or somesuch if eval ( ( GetIsReference PlayerRef ) || !( PlayerRef.IsInCombat ) || ( IsEssential ) ) ; feel free to add any extra conditions here return endif if eval ( ( ar_Find ( GetCombarTarget ) ( PlayerRef.GetAllies ) ) != ar_BadNumericIndex ) PlaceAtMe Sheep 1 ; Disable --> are there any other options ??? endif endHopefully that helps a bit. :thumbsup: And hopefully someone else has a better idea of whether using PlaceAtMe is smart in this specific case. Maybe restricting the number of sheeps and affected NPCs to one, and allowing only one NPC to be turned into a sheep at a time, for the duration of the spell only, would help both prevent accidentally disabling NPCs relevant to a quest and to help avoid PlaceAtMe completely. The requirement for player to be the one to use the staff/spell/something is also interesting, but I cannot remember any quick way to dynamically get the actor who has cast a spell. In Skyrim, it is passed as an argument to the script effect start event, but in Oblivion, I do not think there is a way to check the caster in an easy way... or maybe there is something I cannot remember... ? Would not be the first time. :tongue: Also, have you looked at the Wabbajack script in the game? That might also be handy, I think it was implemented as a script in the game. Edited January 4, 2018 by Contrathetix Link to comment Share on other sites More sharing options...
lubronbrons Posted January 4, 2018 Share Posted January 4, 2018 (edited) in my experience to check player's foe is a bit complicated...this script below can check hostility towards pc but not that effective, nice NPC will always return negative values if target.GetShouldAttack PlayerRef printc "%n may atk pc" target endif in combat, the best way to check whether npc is hostile to player or not, use this if eval(ar_Find PlayerRef target.GetTargets) > -1 printc "%n is pc foe" target endif but when the npc is NOT in combat, you can check them like this. AFAIK actors that have confidence less than 36 will run from combat if target.GetDisposition PlayerRef <= target.GetAV Aggression - 5 && target.GetAV Aggression > 5 && target.GetAV Confidence > 35 printc "%n is hostile towards pc" target endif as for your sheep caseI think this script below should be enough if target.GetDisposition PlayerRef <= target.GetAV Aggression - 5 && target.GetAV Aggression > 5 || eval(ar_Find PlayerRef target.GetTargets) > -1 printc "%n is hostile towards pc" target endif don't worry about PlaceAtMe on actor, because when the cell reset routine kick in the reference will be gone for goodPlaceAtMe only become harm on savegame when used on objectsbut the problem in your mod is ... I think the turned NPC can't go back to original. is that intentional ? Edited January 5, 2018 by lubronbrons Link to comment Share on other sites More sharing options...
Surilindur Posted January 5, 2018 Share Posted January 5, 2018 (edited) <snip> Thank you! Using PlayerRef with GetTargets on the spell target saves a function call in the condition check! Also, I had no idea disposition and aggression were connected like that. Every day one learns something new. :happy: Also, now that I remember it, the thread by QQuix about his research on PlaceAtMe a while ago is here, if it helps: Cell Reset Edited January 5, 2018 by Contrathetix Link to comment Share on other sites More sharing options...
lubronbrons Posted January 5, 2018 Share Posted January 5, 2018 Thank you! Using PlayerRef with GetTargets on the spell target saves a function call in the condition check! Also, I had no idea disposition and aggression were connected like that. Every day one learns something new. :happy:Also, now that I remember it, the thread by QQuix about his research on PlaceAtMe a while ago is here, if it helps: Cell Reset your welcome Contra :) it is great to see you still doing Oblivion troubleshooting here~yeah...aggression, disposition, and confidence is variable that affecting hostility towards pc Link to comment Share on other sites More sharing options...
Surilindur Posted January 5, 2018 Share Posted January 5, 2018 (edited) Thank you! Yes, I am still here and I am not going to go anywhere anytime soon, either. :smile: The plan is to remain here for the foreseeable future and to continue my mod projects for Oblivion when I find the time (a bit busy at the moment, I have not had the time for modding). There is something about Oblivion that Skyrim or other titles do not have, but I cannot quite point out what it is. Also, if you do not mind, just to quote this part again from your previous post, which is extremely relevant to the whole sheep transform spell thingy: --but the problem in your mod is ... I think the turned NPC can't go back to original. is that intentional ? Which means that, for example:If the NPC or creature is a questgiver or otherwise needed for a quest alive (such as for dialogue), then the NPC or creature will no longer be available if it is just left disabled. Probably not an issue for hostile NPCs, but one can never know (for example, if using a mod that allows one to join an evil faction that can give quests, with the faction being hostile at first, it would be possible to disable the quest givers in that faction when they are hostile, for example before the player joins the faction).If the NPC or creature has to be killed for some reason (to advance a quest, for example), then killing them is not possible anymore when/if the actor is disabled and replaced with a sheep (which would be sort of funny, but then again, it would leave the quest stuck). Killing the sheep would still leave the original NPC disabled but alive, unless some sort of workaround would be implemented to kill the NPC if the sheep is killed.Essential NPCs (if there are any essential NPCs hostile towards the player somehow???) probably should not be turned into sheep that can be killed by the player, because it would defeat the purpose of marking the NPCs as essential, when the player could remove them from the gameworld forever by using the staff on them.If the NPC or creature has an item in their inventory that the player would need to fetch, then the item would be become unavailable when the original actor is disabled, unless the inventory of the actor (including leveled lists) is transferred to the sheep (or the sheep is turned into a sort of scripted proxy activator for accessing the original NPC's inventory, but I do not know if it is possible to activate a disabled NPC - if not then the inventory would need to be moved to the sheep somehow).Maybe something else, too, that I cannot think of at the moment.Just to clarify the issue to TheManWithoutAPlan. :smile: Also a happy new year to you, L! May it be better than the previous one. Edited January 5, 2018 by Contrathetix Link to comment Share on other sites More sharing options...
lubronbrons Posted January 5, 2018 Share Posted January 5, 2018 (edited) Happy new year to you too Contra and best of luck to all of us and around you too !!! that's rightit will trouble some NPCs quest related, it will make the game unstable in many waysI think the script need to turn back the NPC to originalalso make sure your spell have time effect something like 30 seconds or whatever second you want scriptname SheepStaffScript ref theSheep begin ScriptEffectStart if GetIsReference PlayerRef ;this line same as -> target != player, but more faster ;prevent player from getting turned into sheep Dispel SheepStaffSpell return elseif PlayerRef.IsInCombat ;prevent sheep spell when player is in combat Dispel SheepStaffSpell return endif if GetDisposition PlayerRef <= GetAV Aggression - 5 && GetAV Aggression > 5 ;only hostile actors that get turned into sheep Let theSheep := PlaceAtMe Sheep 1 Disable else Dispel SheepStaffSpell return endif end begin ScriptEffectFinish ;if you set script time effect 30 secs, then at the end of spell effect the actor will turn back to original if theSheep theSheep.Disable Enable endif end Edited January 5, 2018 by lubronbrons Link to comment Share on other sites More sharing options...
Recommended Posts