How to Make a C.A.N.S. Patch or Mod
So, and bear with me here, I'm assuming you've already heard of C.A.N.S. and what it does if you're here. Additionally, I'm going to assume you're here to figure out how to make a mod or patch reliant on it because the implementation on the OP is pretty half-assed.
Luckily I've slapped this together to (hopefully) contain anything you would want to know about implementing C.A.N.S. in a papyrus script.
Prologue: How C.A.N.S. works
C.A.N.S. is effectively two parts, with a few minor additions that are no worry to you. I figured I'd explain in more detail here how it all worked so you could understand it a bit better and get a feeling for what this code does and limitations it will face.
Major parts: The CANS Quest and CANSframework magic effect.
These two work in tandem, and if you dig into the source code you'll notice a lot of the functions (at least, based on name and argument) seem to mimic each other. The quest is effectively the real framework here, as it is the middle man between your mod (or patch) and the magic effects (which do all the real work). The quest holds just enough code to keep track of actors being montiored or managed by CANS and point the way to the correct instance of the magic effect to call code on. The magic effect handles all of the math and storage of requested node sizes.
Minor Parts: MCM, two-dozen or so global variables, and the spell
The MCM is fairly straightforward and the global variables are all internal housekeeping for the code, mostly corresponding directly to an option in the MCM. The spell (CANSapplication) is a very simple and straightforward ability, that merely applies the CANSframework magic effect to an actor.
On to the actual code:
Step 0: Applying CANS
CANS_Framework Property CANS Auto;The code you'll be referencing and calling, in the quest.;If using more than one code, add this property to any that wish to interact with CANSMagicEffect Property CANSframework Auto;The magic effect that handles everything, beyond applying this, do not touch this in code. It will remove itself when it is no longer needed.Spell Property CANSapplication Auto;The spell that applied the framework effect.
Event OnEffectStart(Actor akTarget, Actor akCaster) ;For a magic effectEvent OnInit() ;For a quest;Assuming you use a magic effect, akTarget will work fine;if you use a quest, use whatever alias the actor you're monitoring has been cast to.;for demonstration I will use zTarget;You want to check to see if the target already has the effect applied, for instance, followers or certain npc's may already be managed by other modsif !(zTarget.HasMagicEfect(CANSframework)) ;the target does not have the effect. if (zTarget.HasSpell(CANSapplication)) ;The target has the spell but not the effect, something was called incorrectly and the effect was dispelled but not the spell zTarget.RemoveSpell(CANSapplication) endif ;Now the target has neither the effect nor the spell zTarget.AddSpell(CANSapplication, false) ;Adds the spell, does not notify if it is added to the player CANSapplication.Cast(zTarget, zTarget) ;Activates the spell and applies the frameworkendif;Registration script can go here for simplificationEndEvent;Note: Even if you are targeting the player, run this code, as the effect will clean itself up when it is no longer in use, which could potentially lead to; it being removed from the player.
Step 1: Registering
CANS.RegisterMyMod(zTarget, ModName, Category);zTarget is the actor you are modifying as an Actor.;ModName is the unique string you will use throughout CANS to call functions. It is incredibly important to keep this consistent.;Category is a string that groups your mod into one of several categories, check the spoiler below for more information.;Note: Calling the registration function when already registered will result in no change within CANS, it will ;detect the mod as already registered and assume no change is necessary
Step 2: Updating Nodes
CANS.Belly(zTarget, ModName, NodeSize)CANS.Breast(zTarget, ModName, NodeSize)CANS.Butt(zTarget, ModName, NodeSize);zTarget and ModName are the same as before, and will remain constant throughout.;NodeSize is the requested scale as a Float variable.
Step 2b: Retrieving values
CANS.ReturnBelly(zTarget, ModName)CANS.ReturnBreast(zTaret, ModName)CANS.ReturnButt(zTarget, ModName);All of these functions return the float value sent as NodeSize previously.
Step 3: Uninstalling
Event OnEffectFinish(Actor akTarget);Or in the last stage of the quest I supposeCANS.UninstallMyMod(zTarget, ModName);Very straightforward, zTarget and Modname are used exaclty the same as before.EndEvent
And there you have it folks, the bare skeleton for a CANS mod or patch. If you have any questions or need any help, do not hesitate to contact me here at LL.

Bonus: Tips and Tricks from Feliks
1: There is a ReturnTotalXXX() function in the framework. DO NOT USE THIS. IT IS FAR TOO UNRELIABLE TO BASE YOUR CALCULATIONS ON THIS, THAT's ONE OF THE ISSUES CANS WAS CREATED TO SOLVE
2: The ModName arguments are by no means tied to your mod, if you know what string another mod is using your mod or patch can retrieve (or even modify, but please don't unless you know what you're doing) their values.
2b: Better yet, why should your mod be tied to a single "ModName"? If you have more than one thing affecting nodes, by all means, register them as separate mods in CANS, just be sure that the name is fairly easy to understand.
3: In the source files you may notice some "Override" functions. These were nearly abandoned but will be reintroduced in a future update.
4: You shouldn't need to do any modification to scripts made now between now and the 2.0 release (quite some ways off) as any modifications from here on will not touch the way you call functions, only how it handles those functions.
5: It is possible to glean some information on the workings of the framework by retrieving values from the globals. Please do not modify them.
6: Almost everything in CANS has an ID beginning with "CANS_" with the exception of the magic effect and spell. I'll probably make them conform in a future release as well. If you attach the data in the CK this won't break your script, if you just leave it as auto and let it figure it out you may need to add a few underscores to fix your script.
2 Comments
Recommended Comments