EnaiSiaion Posted April 16, 2013 Share Posted April 16, 2013 Let's dedicate this thread to sharing those little tips that might be of use to other people! I'll start: Did you know...<Global=NameOfYourGlobal> is valid text substitution. It also works in spell descriptions! Events for entering/leaving combat, sneak, reaching a health threshold etc.Putting a condition directly into an ability causes the ability to turn itself on or off when the condition is met or no longer met (unsure whether this also works if you put the condition into the magiceffect instead), triggering OnEffectStart() and OnEffectFinish() events in any scripts attached to its magic effects. For instance, if you want an event that runs on an actor when the actor enters combat, what you should do is give the actor an ability with condition GetCombatState != 0 and a script with Event OnEffectStart(). Conditions that compare two variablesTo implement a condition that compares two variables (eg your health < opponent health), find a way (magic effect or quest script) to put one variable into a global, then compare the other variable to the global. My spell is cast on Self and is supposed to affect an area around the caster, but it randomly misses targets!Turn on "Area Effect Ignores LOS" [Line of Sight] in the spell properties (and optionally also in the explosion properties). Line of sight is not only blocked by obstacles but also by the caster himself, causing the spell to fail against targets behind the caster if this is not checked. Also, open the spell and close it again; when you add or modify the effects of a spell and Ok out, their area field is set to 0 unless Auto Calculate is off. This will cause the spell to fail, unless you open it and close it again without touching the effects. If it's an offensive spell and you forget to do this, it will hit the caster instead. Fixing the magnitude description of a cloakThe thing about cloaks is that their magnitude is the radius of the cloak. The magnitude of the subspell it casts on targets is handled by the subspell and not by the cloak itself. If you want the magnitude to display correctly in the description of the cloak, add a dummy magiceffect with target Self to your cloak that does nothing, has the same duration as the cloak and the same keywords and magnitude as the subspell. Then put the whole description into that magiceffect and set "Hide in UI" to true for the actual cloak magiceffect so all the player sees in their active abilities list is a fake. A working FindXActorFromRef()Calling FindClosestActorFromRef() from an actor will return the actor itself, calling FindRandomActorFromRef() from an actor may return the actor itself. To fix this, instead add a new quest with an alias of type "unique actor" = Player and an alias of type "find [closest] actor in loaded area" with a condition GetDistance to Alias:YourPlayerAlias < your desired distance. It needs at least one stage but it doesn't matter what you put in that stage. Aliases are only populated when the quest is started (using YourQuest.Start()) and cleared when it is stopped (using YourQuest.Stop()), so all you have to do is call Start() on it when you want to find an actor. To actually retrieve the actor in the alias, a quick and dirty solution is to add a spell to the alias that is an ability with a magic effect with a script that goes off on Event OnEffectStart(Actor akTarget, Actor akCaster). The akTarget of this event is the actor in the alias. Define global variables that aren't floats, longs or shortsCreate a quest that runs on game start and has a script attached to it. Define your variable in this script and add functions to read and write the variable: Actor YourVariable = NONE Actor Function ReadYourVariable() Return YourVariableHere EndFunction Function WriteYourVariable(Actor NewContent) YourVariableHere = NewContent EndFunctionTo access the variable in another script, do: NameOfYourQuestScript Property NameOfYourQuest Auto [example uses] actorhealth = NameOfYourQuest.ReadYourVariable().GetActorValue("Health") NameOfYourQuest.WriteYourVariable(akTarget)It is more limited than regular globals in that you can't use them in conditions, but at least it's something. You have X number of things and you want to randomly draw from them using a script, but without drawing the same thing twiceMake an empty formlist in the CK. Then do this: Formlist Property EmptyFormlist Auto Spell[] Property AllSpellCards Auto ;assuming the things are spells in an array variable, adapt the script if needed Spell FirstSpell Spell SecondSpell Spell ThirdSpell Spell Function DrawACard() Int randomrow = (Utility.RandomInt(1,EmptyFormList.GetSize()) - 1) Spell drawnspell = EmptyFormList.GetAt(randomrow) as Spell EmptyFormList.RemoveAddedForm(drawnspell) Return drawnspell EndFunction Event OnSomethingCoolHappensAndIWantToDrawCards() Int i = 0 While i < AllSpellCards.Length EmptyFormlist.AddForm(AllSpellCards[i]) i += 1 EndWhile Spell FirstSpell = DrawACard() Spell SecondSpell = DrawACard() Spell ThirdSpell = DrawACard() EmptyFormList.RemoveAddedForms() ;resets the formlist to empty EndEventThe reason why you don't just want to throw your things directly into the empty formlist in the CK is because you can't remove forms that weren't added by a script. Link to comment Share on other sites More sharing options...
scrivener07 Posted April 16, 2013 Share Posted April 16, 2013 Very nice Siaion :)Maybe not a forum sticky imo but maybe this can evolve into a ck wiki article or two. Theres so much you can do in papyrus with condition functions. Modifying private variables with public get/set style functions. None of the things in your op are very well known at all. I hope others pitch in too. Link to comment Share on other sites More sharing options...
Recommended Posts