Jump to content
ℹ️ Intermittent Download History issues ×

xWilburCobbx

Members
  • Posts

    92
  • Joined

  • Last visited

Posts posted by xWilburCobbx

  1. Scriptname AAAnewscript001 extends activemagiceffect

     

    Spell Property AAAdummyspell001 Auto

     

     

    Event OnEffectStart(Actor akTarget, Actor akCaster)

    Game.GetPlayer().AddSpell(AAAdummyspell001)

    EndEvent

     

     

    This is what I tried after the akCaster didn't work. I set the dummymagiceffect to constant,self, and set the dummyspell to ability, but still in the game when I cast the fireblast no magic effect occurs.. no dummymagiceffects, no dummyspells,

     

    The script saved fine, but I don't understand why the magic effect doesn't occur. The script is made in the magic effect of fireblast, and it's correct right?

    I am probably gonna need some more information. An ability still needs a duration, or you need to disable it's duration in the magic effect settings, that's all I can think of off the top of my head. Also, put down some traces and perform multiple tests. Using trace messages in your script will print them in the papyrus logs, this way you can see if the effect actually starts or ends, or whatever you need to check.

  2. Spell Property AAAdummyspell001 Auto

     

     

    Event OnEffectStart(Actor akTarget, Actor akCaster)

     

    AAAdummyspell001.cast(akCaster)

     

    EndEvent

     

     

    This is what I tried. AAAdummyspell001 is self delivery spell I made for my aimed spell. The script saved fine, but didn't do anything ingame. Anyone see the problem.?

    I think this is because cast() only works for aimed spells. Or perhaps you need to specify a target, so the spell wont just cast in a random direction. AAAdummyspell001.cast(akTarget, akCaster)

     

    If this magic effect you want to apply to the player is set to constant, self delivery, and it's assigned to a spell that's an ability. Use this:

     

     

    Scriptname WC_AddSpell extends activemagiceffect
    {Adds the spell to who ever casts this one.}
    
    Spell Property SpellToAdd Auto
    {The spell to add.}
     
    Event OnEffectStart(Actor akTarget, Actor akCaster)
    	akCaster.AddSpell(SpellToAdd) ;If the spell is an ability, it will instantly begin. Otherwise it will just add it to their list of spells.
    EndEvent
    

     

     

     

    If for some reason this still isn't working, then replace akCaster with Game.GetPlayer(). Just remember to not let other NPCs use it, for it will only act on the player.

  3. I think I'm going to have to try and create my own workbench that the other script doesn't effect.

    I did try one but the other script still found it so I must have missed something...

    Well perhaps you could get with the mod author, the first step is to at least find out what the other mod's script searches for. Figure out how it identifies a work bench. Like I said, it could be a formlist, a keyword, .. etc. You probably wont know till you look at his script.

     

    Perhaps find programs that can decompile mods... I do a lot of that my self. There is nothing wrong with taking a peak to see how something works, as long as you don't steal anything out of it.

  4. You know what you could do, instead of making the work benches portable, make a spell the can access a magical work bench at anytime. Just make pieces of furniture that use the correct work bench type. You can make it a kneel marker or something that spawns at the player, then forces him to activate the furniture piece/magic workbench. To prevent save bloat, you could use this code I made for a mod I am currently making on:

     

     

    Scriptname WC_FurnitureCleanup extends ObjectReference
    {Constantly makes sure the furniture is in use before deleting itself. Written by Wilbur Cobb / smashballsx88}
    
    Actor property PlayerRef auto
    {Assign this to (any) cell, PlayerRef. This is faster then Game.GetPlayer(), it will be good for looping scripts.}
    
    Event OnInit()
    	RegisterForSingleUpdate(4)	;It will begin the check loop in 4 seconds, this makes sure the player finishes entering the furniture before checking.
    EndEvent
    
    Event OnUpdate()
    	if PlayerRef.GetSitState() != 3	;Checks if the player is still using the furniture. (3 = Sitting)
    		self.delete()
    	else
    		RegisterForSingleUpdate(4)	;Runs the loop every 4 seconds, you can increase this as you see fit.
    	endif
    endEvent
    

     

     

     

    Place it on the custom workbench, set it's property, and enjoy. The reason why I made this a loop, is so this way it will delete it self encase there is a bug that prevents you from using it.

     

    You can manipulate it or do whatever you want with it, I just thought I throw the idea out there encase you wish to use an alternative.

  5. As far as I am aware, when you have 2 scripts that do a simular thing and aren't compatable, the only way to work around it is to change how the system works...

     

    If they use menus, then use spells instead... Or use a custom form that won't have the attached scripts. Perhaps the other mod uses a specific formlist, a keyword, a global, something you can use to separate your mod from theirs.

  6.  

    598LA4P.jpg

     

    This is my very first mod I am actually going to release.

     

    It is a Dark Souls-esque mod that adds a new soul sucking mechanic to the game, and I am bringing in Dark Souls inspired game play mechanics. It's not really a combat overhaul, but it's coming with various ways to interact with the new souls mechanic, including souls based enchanted weapons, and items.

     

    As long as some living thing is in the same general area as you, you will absorb its soul when it dies. A soul is the sum of the target's health, stamina, and magica. You can also convert money, dragon souls, and soul gems into souls.

     

    You can use the souls to level up any skill you choose. The required souls per upgrade starts at a low amount to give you a starter boost, but it will scale up to a cap after each upgrade. You will also be able to transpose unique gear using souls.

     

    Right now I have 5 enchanted weapons and one incomplete set of enchanted armor. Some of the unique enchanted weapons include:

     

    A mace that can completely break NPC's guard items, and consume it for souls.

    A hammer that scales damage based on your carried souls.

    A cuirass that will suck the stamina and souls out of any nearby target.

    A pair of boots that will stagger all nearby enemies everytime you jump or fall.

     

     

    I may also include a covenant system that grants you unique souls based perks.

     

    The mod will come with a unique sound track made by Alex Row aka RoeTaKa. Which I was granted full official permission to use.

     

    This mod should be very easy on the game's memory. It does use a repeating spell system which may not work in conjunction with too many repeating script based mods. It also shouldn't save bloat, I take very good care to ensure my scripts are at least clean if nothing else. I also took care to try and include as many safety features as possible to ensure you can't break quest and such.

  7. Unless it involves real money, it doesn't count as gambling in any legal since, at least not here in the States. I don't see why this would be an issue at all ...

     

    EDIT - Even then, somehow actual money bought loot boxes pass under the gambling radar, so the laws seem pretty lenient when it comes to games.

  8. Good deal, what might help, is making sure all of your locations don't parent to your exterior world. I don't know if that will have any affect for the script, so do your own testing, but this might have unintended side effects, so read up on Locations and do a bit of research before you decide. Otherwise, if you can think of a good script revision, always go for that instead.

  9. Well, this script doesn't work too well, since a lot of interior cells are technically in the TamrielLocation, but since I made it, you might as well have it.

     

     

    Scriptname MyScriptName extends ReferenceAlias 
    {Pauses time when not in the specified locations. Written by Wilbur Cobb / smashballsx88}
    
    Location property LTam auto
    {Set this to TamrielLocation, you can also define more exterior spaces.}
    ;Location property nLoc2 auto
    ;Location property nLoc3 auto
    
    GlobalVariable property Hr auto
    {Set this to GameHour.}
    
    bool pInter
    
    float pTime
    
    Event OnLocationChange(Location akOldLoc, Location akNewLoc)
    	if akNewLoc == LTam			;Makes sure the player is in Tameriel. You can define more exterior locations, do (Ltam || nLoc2 || nLoc3) ... ect
    		UnregisterForUpdate()	;Terminates any registered updates.
    		pInter = false			;Sets a bool to track rather the player is or isnt in tameriel, false if tameriel, true if anywhere else.
    		debug.trace("The player is in " + akNewLoc)
    	else
    		pTime = Hr.GetValue()	;Sets the hour that it curretly is, when the player inters the new location, to a float that wont change till he does it again.
    		pInter = true
    		RegisterForSingleUpdate(10)	;In 10 real-time seconds, it will begin the pause time cycle.
    		debug.trace("The player is NOT in exterior")
    	endIf
    endEvent
    
    Event OnUpdate()	;Starts the loop, and fires everytime an Update happens.
    	if pInter == true
    		Hr.SetValue(pTime)	;Every 10 seconds it will reset the time to the hour the player left tameriel in.
    		RegisterForSingleUpdate(10)
    		debug.trace("Time was reset to " + pTime + " hour(s)")
    	endif
    endEvent
    

     

     

     

    Perhaps you can work with it though, this script attaches to a reference alias through a quest. Just make the specific reference a player, and add it to the Papyrus box.

     

    Read more about how OnLocationChange() works here, perhaps you can find a better solution.

     

    This also won't account for days, so if the player waits over a day it will just revert it to the hour. To avoid this, it's really simple, just do what I did with the Hr global, to another global assigned to GameDay.

     

    Also, watch out for making the script too big, cheers.

  10. Seriously... You make 3 post about this in a row, insulting the author just for not giving you permission. Now you want to say you've been ignored?

     

    With that attitude, you will be... If you can't play it on your Xbox then just play it on PC, and deal with it... That is your final answer.

  11. Since items can't reference or call functions on themselves when they are in an inventory, you have to use a magic effect instead to make use of something like OnUpdateGameTime().

     

    So stick this script on a magic effect, with it's properties at least set to Script > Constant Effect > Self.

     

     

    Scriptname MyMagicScriptName extends activemagiceffect  
    
    Event OnEffectStart(Actor akTarget, Actor akCaster)
    	RegisterForSingleUpdateGameTime(24) ;Measured by in-game hours. Fires the update event after the first day.
    endEvent
    
    Event OnUpdateGameTime()	
    	;Do stuff.
    	RegisterForSingleUpdateGameTime(24)	;Loop it. Should automatically UnregisterForUpdateGameTime, and stop listening for updates when the spell dispels.
    endEvent
    

     

     

    Make sure to read the wiki about how OnUpdateGameTime() works, and such. Make sure you don't loop these updates endlessly, bogging down the Papyrus engine.

     

    Also create a new Spell set to Ability then add your magic effect to it.

     

    Then attach this script to your item, if you want it to run if its in the player inventory instead.

     

     

    Scriptname MyItemScriptName extends ObjectReference 
    
    Actor property PlayerRef auto	;Make sure to assign this to the player ref in (any) cell. If we only needed to get the player once, use Game.GetPlayer() instead.
    
    Spell property aSpell auto	;Assign this to your ability spell.
    
    Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
    	if akNewContainer == PlayerRef	;Only add the spell if its in the players inventory.
    		PlayerRef.AddSpell(aSpell, false)
    	else    ;Removes the spell if the item ends up anywhere but the players inventory.
    		PlayerRef.RemoveSpell(aSpell)
    	endif
    endEvent
    

     

     

     

    Otherwise this will run if you have it equipped or unequipped.

     

     

    Scriptname MyItemScriptName extends ObjectReference 
    {Add spell on equipped. Written by Wilbur Cobb / smashballsx88}
    
    Actor property PlayerRef auto	;Make sure to assign this to the player ref in (any) cell. We want this since we need to get the player more then once, otherwise use Game.GetPlayer()
    
    Spell property aSpell auto	;Assign this to your ability spell.
    
    ;Form, Weapon, Armor ... ect, as long as it extends Form. property MyItemProperty auto
    
    Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
            CheckIfEqByPlayer()    ;OnEquipped() wont fire if equipped right out of a container. This will make sure to still add the spell.
    endEvent
    
    Event OnEquipped(Actor akActor)
            CheckIfEqByPlayer()
    endEvent
    
    Event OnUnequipped(Actor akActor)
        if akActor == PlayerRef
            PlayerRef.RemoveSpell(aSpell)
        endif
    endEvent
    
    Function CheckIfEqByPlayer()    ;This function will make sure the player has the item equipped.
        if PlayerRef.IsEquipped(MyItemProperty)    ;Set this to a property, which points to the form of your item. You cant use self when its in the inventory.
            PlayerRef.AddSpell(aSpell, false)
        endif
    endFunction
    

     

     

    This Script Objects map should help you see what all extends Form.

     

    Make sure to use this wiki page to read notes on all the functions present in these scripts. Cheers.

  12. You asked: "My only real question here, is how does return work exactly? Does return stop the current function where it is at, and move on to the next?"

    "return" does the same as "endevent" or "endfunction", but within the event or function body.

    Exception is a function with return value, you need "return" here followed by number or variable or False/TRUE (depends on type of function return)

     

    basic, which do nothing

    Thanks for clearing that up! Seems I ended up figuring that out, which is why I came to my final version of the AAAxWCxWeapCorruptingDoomScript.

     

    about your last version of AAAxWCxWeapCorruptingDoomEnchApply

     

    - try to avoid PlayerRef it does not make sense to store this as property, use Game.GetPlayer() instead

    - the "Weapon property CorDoom auto" is surely the same as self, you don't need this property here

    - the "Spell property DoomSpell auto" is unused by script, can be removed here

    - I use a player ref property when the player is referred to more than once. According to my research, Game.GetPlayer() takes process time, and if used multiple times it will have to reprocess it each time. Assigning PlayerRef should cut down latency.

     

    - Technically yes, but self is an object reference. When an item is in an inventory/container, it no longer exist, so not even self will work. You have to check if it matches a Form instead.

     

    - That was just left in error, it was omitted in the actual final script.

     

     

    about your last version of AAAxWCxWeapCorruptingDoomScript

    Using IF with a return shrinks stack size during run time? From what I have seen when an IF doesn't check out it already ignores whats in the stack entirely. It shouldn't have any of it's contents in the thread, this why I organized it the way I did, because it ignores the code block as soon the condition isn't met. So when akSource != CorDoom it should already return without even acknowledging whats in the code block.

     

    I can see how your revision of my IF chain though would be easier on the memory. Since that way if its one version or another, the most it could run is 1 IF check.

     

    Also, just as a side note, (akSource == CorDoom as Form) I don't see a reason to cast a Weapon to a form, since all these base objects are already extensions of Forms. (akSource as Weapon == CorDoom), this specifies a Form as a Weapon. There is no need for this either, since any function that runs on Forms won't care what the form extension might be during compile time. I might see using casting akSource as a Weapon if it reduces memory usage in some way, but I have no current reason to believe that.

     

    Example from a new script I just wrote today.

    Armor eqShield = mySelf.GetEquippedShield() ;This can only run on Armor forms
    Weapon rWeap = mySelf.GetEquippedWeapon()   ;This can only run on Weapon forms
    
    ;You can also do this
    
    Form eqShield = mySelf.GetEquippedShield()
    Form rWeap = mySelf.GetEquippedWeapon()
    
    ;Both are still Forms, so there is no need to specify what extension eqShield or rWeap is, as long as eqShield is assigned to an Armor form, and rWeap to a Weapon form
    
    ;If you are still concerned that it wont get the right form, then think about this, casting a Weapon as an Armor form will still return errors anyways.
    
    ;In my script I just used the first example, either way it doesnt matter.
    
    ;----Another Example----
    Form eqShield = myActor.GetEquippedShield()
    
    eqShield.GetWarmthRating() ;Can only run on Armor forms
    
    

    You can always refer to this awesome Script Objects map to see what extends what.

     

    If you have more to add, or wish to explain somethings, please do. Your info is most helpful, thanks a bunch!

     

    Hopefully, I helped you too, it's always good to question each others knowledge to get the best possible understanding.

  13. Thank you very much for your help! I appreciate it greatly!

    Its no problem, I've got to work on my own mod for now, since I haven't even uploaded my first one yet! Hopefully though using the notes and stuff you at least have a general idea on what to do. The Papyrus wiki will always be your absolute best friend.

     

    Once you really start to grasp the concept of Papyrus, I would double down on these 4 topics that will pave the way of making you a competent script writer. They are actually gravely important, I wouldn't ship a mod until you begin to implement and practice these concepts.

     

    Threading Notes

     

    Persistence

     

    Using Functions

     

    A map of all the Script Objects and their extensions/relationships

  14. This is actually pretty impressive ... I can't hold on to developing mods for very long, much less make a comprehensible road map! Creation kit was such a big learning curve for me, I quit a long time ago, ain't even till recently I rose from the ashes to finally start producing my first official mod.

     

    I am not THAT good yet, but my scripting skills are improving rapidly, as I spend most of my development time on the wiki studying Papyrus and various scripting/computer science topics. I know a good amount of process threading and script optimization, and actually a decent amount about how the game engine handles certain forms. I just need to keep putting it into practice, I think am to the point of building pretty competent scripts.

     

    Perhaps when I finish my mod, and prove my self a competent modder. I will give something like this a try, wouldn't hurt to see what I could do.

  15. I am also a beginner, so for learning purposes, I will give this one a shot.

     

    EDIT - The script has one major flaw, apparently its completely impossible to make inventory items persistent, even forcefully. So OnUpdate() never calls, I am not sure how to work around that without using while loops, and I am not sure if that's even ok to do, for threading reasons.

     

     

     

    Scriptname MyScriptName extends ObjectReference  
    {Spawns inventory items, in inventory, at random intervals. Written by Wilbur Cobb / smashballsx88}
    
    Keyword property ActorKW auto	;Set this to ActorTypeNPC to filter for NPCs.
    
    FormList property MyItems auto	;Create a form list of all the items you want spawned.
    
    ObjectReference addRef	;The container to add the items to.
    
    int flSize	;Int to assign the form list size to.
    
    bool inInv	;Ensures termination on inventory removal, all bool values check true by default.
    
    Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
    	if akNewContainer.HasKeyword(ActorKW)	;Checks if the container matches the key word.
    		addRef = akNewContainer	;Assigns the current container, to the container reference.
    		inInv = true
    		gotoState("Looping")	;Goes into the looping state to start item spawning.
    	else	;If the container is anything that doesnt match the keyword, terminate.
    		inInv = false
    		UnregisterForUpdateGameTime()
    		gotoState("")
    	endif
    endEvent
    
    state Looping	;This state will only fire once until the state changes. This is to prevent update stacking for this script.
    	Event OnBeginState()
    		flSize = MyItems.GetSize()	;Assigns form list size to an int
    		RegisterForSingleUpdateGameTime(1)	;This starts the update loop in 1 in-game hour.
    	endEvent
    	
    	Event OnUpdateGameTime()
    		if inInv	;Prevents the update from running. True to run, false to terminate.
    			if flSize >= 0	;Stops once the form list has been gone through
    				Form pEnt = MyItems.GetAt(flSize)	;Gets the paper entry, based on flSize for the chosen index.
    				addRef.AddItem(pEnt)
    				flSize -= 1	;Subtracts 1 from total list size to track what was already spawned.
    				int ranHr = Utility.RandomInt(1, 24)	;You can set these 2 values to what ever you like, think of it as dice.
    				RegisterForSingleUpdateGameTime(ranHr)	;Sets the random in-game hour to spawn an item again.
    			else
    				gotoState("")	;Makes sure to terminate once all the items are spawned.
    			endif
    		endif
    	endEvent
    endState
    

     

     

     

    If anyone wants to make it better, and explain somethings, please do. I am in this too.

     

    This basically spawns a certain number of items in order, starting from the highest index number. It will do it at random intervals, for each container (NPC) it is placed it. This also means the cycle starts over every time its in the players inventory. If you want to make it a finite number, just use a global variable.

  16. After working on this weapon for a considerable amount of time, I think I got it exactly how I want it. If there is anyone who can think of an idea to make the player responsible, still go for it.

     

    This is how everything looks so far. I added comments regarding the reason why I omitted a lot of things, and wrote my own versions of each correction.

     

    I also scrapped an enchantment that once made the weapon apply force to everyone it hit, once the weapon got strong enough. So the weapon has no official enchantments.

     

    This is the function that adds a cloak ability. The cloak ability applies an adder spell to all nearby NPCs.

     

     

    Scriptname AAAxWCxWeapCorruptingDoomEnchApply extends ObjectReference 
    
    Spell property CloakSpell auto
    Spell property DoomSpell auto
    
    Actor property PlayerRef auto
    
    Weapon property CorDoom auto
    
    Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer) ;OnEquipped will not fire if equipped right out of a container, it needs 2 checks.
    		CheckIfEqByPlayer()                                                      ;SideNote You dont have to cast Actors as an ObjectReference
    endEvent                                                                                 ;they are already an extension of an ObjRef
    
    Event OnEquipped(Actor akActor) ;This checks if equipped normally
    		CheckIfEqByPlayer()
    endEvent
    
    Event OnUnequipped(Actor akActor)
    	if akActor == PlayerRef
    		PlayerRef.RemoveSpell(CloakSpell)
    	endif
    endEvent
    
    Function CheckIfEqByPlayer()
    	if PlayerRef.IsEquipped(CorDoom)
    		PlayerRef.AddSpell(CloakSpell, false)
    	endif
    endFunction 
    

     

     

     

    I didn't see a point in setting a state if it had to be checked twice anyways. This will fire every time its move from a container, but I don't see this causing issues since its not possible for the player to do it in rapid succession. If another mod does that, then it probably could also cause issues with item gathering type side quests anyways.

     

    The adder spell attached to the cloak ability uses a universal script that adds the doom weapon's ability to the NPCs.

     

     

    Scriptname AAAxWCxSoulSuckScriptADD extends activemagiceffect
    
    Spell Property SpellToAdd Auto
     
    Event OnEffectStart(Actor akTarget, Actor akCaster)
    	akTarget.AddSpell(SpellToAdd)
    EndEvent
    

     

     

     

    The doom ability runs this script on all the NPCs it attaches to.

     

     

    Scriptname AAAxWCxWeapCorruptingDoomScript extends activemagiceffect  
    
    GlobalVariable property SoulsGlobal auto
    
    Actor property PlayerRef auto
    
    Weapon property CorDoom auto
    
    Actor target
    
    Sound property Exp auto
    
    Event OnEffectStart(Actor akTarget, Actor akCaster) ;I dont see a reason to need more then this, since the target is a local value, and should clear once the ability dispels
    	target = akTarget ;Assigns the NPC the ability runs on, to an Actor reference that is used in the script
    endEvent
    
    Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool pA, bool sA, bool abBashAttack, bool hB)
    
    	if (akSource) == CorDoom ;No need to have returns, since it already stops as soon as one of the IF conditions is met
    		if (pA || sA) && !hB ;I wanted this to be conditional to recreate a sort of normalish combat calculation system
    			TheResult(0.02) ;Max is 2000 damage if its a sneak or power attack
    		elseif hB && !pA
    			TheResult(0.005) ;Max is 500 damage if its a blocked regular hit
    		elseif !hB || (hB && pA)
    			TheResult(0.01) ;Max is 1000 if its a regular hit or a blocked power attack
    		endif
    	endif
    	
    endEvent
    
    Function TheResult(float aMod) ;This starts the calculation with the passed in hit result
    	float s = SoulsGlobal.GetValue() ;It gets the total value of my global count
    	
    	if s < 100000 ;This is a cap to make sure the weapon cant get infinitely powerful
    		s *= aMod ;2%, 1%, or 0.5% of any soul amount between 0 and a 100,000
    	else
    		s = 100000 * aMod ;Enforces a hard cap, to prevent over calculating
    	endif
    	
    	target.DamageActorValue("Health", s) ;I dont actually need to store my new value as a global, since the global is apart of another system, that this weapon is the beneficiary of
    endFunction
    

     

     

     

    Now the reason why the actual doom ability is distributed in this system, is to have it on actors in advance. This prevents form every first hit being a dud hit, and with a 5 min timer, it cleans it self up.

     

    So, does it all look good? I put in a lot of hours of research today, so I think this is the best way to set everything up.

  17. I really appreciate all the help!

     

    I see what you did with my AAAxWCxWeapCorruptingDoomEnchApply . According to my understanding of the wiki, a state doesn't change, regardless of how many instances run. So if its in that "waiting" state, it will check for the equipped and unequipped states. Until it is removed from the player's inventory.

     

     

     

    
    EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, Bool b1, Bool b2, Bool b3, Bool b4)
    ; b1 = abPowerAttack
    ; b2 = abSneakAttack
    ; b3 = abBashAttack
    ; b4 = abHitBlocked
    
    IF ( akProjectile )
        RETURN    ; - STOP - /0    hit by arrow (almost)
    ENDIF
    ;---------------------
    IF (akSource == CorDoom as Form)
    ELSE
        RETURN    ; - STOP - /1    actor which wears this ability, was not hit by the special weapon
    ENDIF
    ;---------------------
    IF ( b4 )
        RETURN    ; - STOP - /2    weapon hit was blocked
    ENDIF
    ;---------------------
    IF ( b1 )
        myF_Hit(4.0)
        RETURN    ; - STOP - /3    power attack strength
    ENDIF
    ;---------------------
    IF ( b2 )
        myF_Hit(2.0)
        RETURN    ; - STOP - /4    sneak attack strength
    ENDIF
    ;---------------------
        myF_Hit(1.0)    ; normal attack
    ENDEVENT
    
    
    ; -- FUNCTION --
    
    ;------------------------------
    FUNCTION myF_Hit(Float fAttack)
    ;------------------------------
        float f = SoulsGlobal.GetValue()        ; f = DamageMult
    
    ; This just makes sure the actual applied weapon enchantment has enough time to apply force
        Utility.Wait(0.3)               ; !?
    
        IF (f < 100000.0)
            f = f * (0.01 * fAttack)    ; 0.02, 0.01, 0.005
        ELSE
            f = 1000.0 * fAttack        ; 2000, 1000, 500
        ENDIF
    
        SoulsGlobal.SetValue(f)                    ; make sure to store the value of our new multiplier
        target.DamageActorValue("Health", f)
    ENDFUNCTION
    

     

     

     

    My only real question here, is how does return work exactly? Does return stop the current function where it is at, and move on to the next?

  18. WHAT!? I have been doing research on Papyrus all this time ... And never once have I even glanced at creating functions! :facepalm:

     

    For practice I did this:

    (This script is the one that runs on the weapon itself, its the one that adds that nifty little cloak spell)

    Old

     

     

    Scriptname AAAxWCxWeapCorruptingDoomEnchApply extends ObjectReference  
    
    Spell property CloakSpell auto
    
    Actor property PlayerRef auto
    
    Weapon property CorDoom auto
    
    Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
    	if PlayerRef.IsEquipped(CorDoom)
    		PlayerRef.AddSpell(CloakSpell, false)
    		self.SetActorCause(PlayerRef)
    	endif
    endEvent
    
    Event OnEquipped(Actor akActor)
    	if akActor == PlayerRef
    		PlayerRef.AddSpell(CloakSpell, false)
    		self.SetActorCause(PlayerRef)
    	endif
    endEvent
    
    Event OnUnequipped(Actor akActor)
    	PlayerRef.RemoveSpell(CloakSpell)
    	self.SetActorCause(none)
    endEvent
    

     

     

     

    NEW

     

     

    Scriptname AAAxWCxWeapCorruptingDoomEnchApply extends ObjectReference  
    
    Spell property CloakSpell auto
    
    Actor property PlayerRef auto
    
    Weapon property CorDoom auto
    
    Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
    	CheckIfEqByPlayer()
    endEvent
    
    Event OnEquipped(Actor akActor)
    	CheckIfEqByPlayer()
    endEvent
    
    Event OnUnequipped(Actor akActor)
    	debug.notification("Player removed the weapon")
    	PlayerRef.RemoveSpell(CloakSpell)
    	self.SetActorCause(none)
    endEvent
    
    Function CheckIfEqByPlayer()
    	if PlayerRef.IsEquipped(CorDoom)
    		debug.notification("Player equipped the weapon")
    		PlayerRef.AddSpell(CloakSpell, false)
    		self.SetActorCause(PlayerRef)
    	endif
    endFunction 
    

     

     

     

    Oh well, time to get busy on doing some optimizations! Luckily I choose a smaller project to release as my very first mod, lol. Only 3 scripts need this thankfully.

     

    This is why I always ask for ANY advice that could possibly be given to me, great contribution ReDragon2013! You have my deepest gratitude!

  19. Thanks, this is all great!

     

    So with your redesign of my script, I have never thought of using my own functions before. You inspired me to further research and I came across this wiki page. I would like to gather as much knowledge as I can, so if you know anything about custom functions, let me know. I have a menu script that repeats this segment 18 times!:

     

     

    -----Snippet----- 
    
    if aiButton == 0 ;Archery
    	while abMenu3
    		aiButton = SubMenu.Show()
    			if aiButton == 0
    				if ReqSouls <= CarriedSouls && PlayerRef.GetActorValue("Marksman") < 100
    					if ReqSouls < SoulCap
    						ReqSouls *= AmntToEncrRqSouls
    					endif
    					CarriedSouls -= ReqSouls
    					ReqSoulsGlobal.SetValue(ReqSouls)
    					CarriedSoulsGlobal.SetValue(CarriedSouls)
    					UpdateSoulTxt.UpdateCurrentInstanceGlobal(ReqSoulsGlobal)
    					UpdateSoulTxt.UpdateCurrentInstanceGlobal(CarriedSoulsGlobal)
    					Game.IncrementSkill("Marksman")
    				else
    					FailSFX.play(PlayerRef)
    					if ReqSouls > CarriedSouls
    						Debug.Notification(Lacking)
    					else
    						Debug.Notification(Maxed)
    					endif
    				endif
    				
    			elseif aiButton == 1
    				abMenu3 = false
    				abMenu2 = true
    			endif
    	endwhile
    	
    -----Snippet----- 
    

     

     

    Could probably use an optimization, hehehe.

     

    Anyways, self.SetActorCause(akActor) this is pointless to put on the weapon itself, since Actors are already inherently responsible for all their equipped weapons, fired spells, and all that stuff. Not to say I didn't at least give it a go, but I can confirm this is ineffective.

     

    I probably didn't specify very well, but what really happens, is the Cloak spell, has an Adding spell as its Assoc. Item 1 (This is because you can't associate abilities type spells). The Adding spell has a script that fires this akTarget.AddSpell(SpellToAdd) , which adds the AAAxWCxWeapCorruptingDoomScript ... and this is why the game won't make the connection between the kills and the player.

     

    Hopefully this clears it up a bit more, I greatly appreciate all the help!

  20. I appreciate the response.

    I feared as much, but I never thought to dissect summons and followers, I will give that a try a little later. Here is what I have found though.

    ObjectThatThePlayerIsResponsibleFor.SetActorCause(PlayerRef)

    I thought this one was interesting, but as far as I know, you can't cast ActiveMagicEffects as ObjectReferences. Not according this nifty little map anyways Script Objects Map. So I had no way to apply it, if only this worked backwards and could be used with ActiveMagicEffects!

    So the next thing I have in mind is this code I found:

     

     

    Actor Property PlayerRef auto
    Int Property Bounty auto
    
    
    Event OnEffectStart(Actor aktarget, Actor akCaster)
    
    	If akTarget.HasLOS(PlayerRef) ; if the target can see the player while he commited the crime
    	
    		SentencePlayer(PlayerRef, Bounty) ;increase the player's bounty
    	
    	EndIf
    
    EndEvent
    

     

     

     

    This will probably my general solution, I would have to figure out how to properly set the LOS and then put my bounty. This wouldn't account for crime severity, nor would it utilize the witness system. I would have to create a whole custom scripted crime system for the ONE Frickin weapon that could use it! So either there is another way, or I am gonna just deal. It's not the end of the world, plus its an OP weapon, maybe leaving the kills under the radar isn't such a bad idea, hehehe. That might cause quest problems though, particularly if there is any such quest that requires, you alone, kill the target.

     

    So ... Anyone else want to give it a go?

  21. I like learning experiences! But to be honest, I don't see the problem ...

     

    function cleanUpBody()
    ;     debug.trace("WIDeadBodyCleanupScript" + self + "cleanUpBody() moving to WIDeadBodyCleanupCellMarker in WIDeadBodyCleanupCell and Calling RemoveAllItems() to DeathContainer, and enabling it:" + DeathContainer)
        
        Disable()
        ;*** It has been decided it's safer to move them to a holding cell, for quests that might be filling allowing for dead actors but not allowing checking for disabled actors
        
        MoveTo(WI.WIDeadBodyCleanupCellMarker)
            
        DeathContainer.SetActorOwner(GetActorBase())
        DeathContainer.Enable()
        RemoveAllItems(DeathContainer)
        
    EndFunction

     



    (I am assuming you are editing some vanilla NPCs?) Just removing that mark in front of Disable() will stop the actor's items form being preserved, but for the aforementioned reason I don't see why you would ever want to. This would cause a host of vanilla quest alias errors and potential game crashes. Same goes for making literally EVERY NPC kill able ... If you ask me this just isn't a good modding choice. I would stick to only doing this with custom Actors where you can easily manipulate your own quest, and stay out of vanilla content. This way your mod is easily compatible with other mods.

    I mean .. deathcontainer is the container the items get moved into, if you aren't gonna use it then there really is no point in setting it. WIFunctionsScript Property WI Auto I have never seen anything like this before, but from my understanding its probably a custom property that can be set to literally anything ... Apparently its for some kind of quest that is apart of the whole system.

    The script kind of already mentions this stuff, I am guessing the script author left instructions or more scripts? If not, then I don't think anyone can help you but him.

    Also, if all that is bothering you is setting the properties each time, then all I can say is "patients" I guess ... I spend most my hours trouble shooting and correcting, in fact, all I did today with my mod is re modify some script systems, thats it. ... Make sure everything functions with one actor, then take the time to do it with all of your actors, then just be done with it ..

×
×
  • Create New...