steve40 Posted September 10, 2012 Share Posted September 10, 2012 I think you probably want to have "Run Once" checked for the quest (the quest should never stop unless you configure it to, so it should only need to run once), otherwise it all looks good. Cheers. Link to comment Share on other sites More sharing options...
ryanshowseason2 Posted September 10, 2012 Author Share Posted September 10, 2012 I should add that the script is attached to a reference alias, set to the player, on a "hidden" quest. I don't know if I create the quest correctly or not. I just started learning this stuff yesterday, so please forgive any noobish mistakes I made - but please let me know of them. - new quest- set ID and uncheck "Run Once"- save (*)- on quest aliases, add new reference alias- set name- set Fill Type to Specific Reference- click Select Forced Reference- set Cell to (any)- wait a bit- ref should set itself to PlayerRef ('Player') by default, select it if not- save (*)- add script to the reference alias (*) On my first attempt, I created the quest, alias, added the script and then clicked OK all the way out and CK crashed on me. I read that if you create the quest and save it (and your active file) before adding the script, it won't crash. I tried that and it worked. Wow, does it work as intended then? Do you have a working esp? I'd love to try it out! Link to comment Share on other sites More sharing options...
ryanshowseason2 Posted September 11, 2012 Author Share Posted September 11, 2012 I got it working myself. I don't really know a lot about the ck but I managed even if I didn't know what I was doing. It seemed to work pretty much fine. The engine seems to have a block from equipping an new shout right after using a shout, somewhere around half a second. I haven't seen any problems yet though. This should get published on the nexus though! I'm gonna see if theres anything else to be done with it. Link to comment Share on other sites More sharing options...
jshepler Posted September 11, 2012 Share Posted September 11, 2012 I've updated the script to add a "real" global cooldown of 1.5 seconds. I want to make it configurable in-game. I still need to figure out how to determine if the spell cast was from a shout or not; otherwise casting a normal spell triggers the gcd. I also want to add groupings such that a group of shouts share a cooldown. For example, grouping shouts into damage, buff, debuff, utility where each group shares a cooldown. And I want that configurable in-game. Not sure what the problem you're describing is. I haven't noticed any problems doing a shout and being able to immediately change shouts using favorites or the magic menu. I haven't tried hotkeys yet. Put a Debug.MessageBox("boo!") after the part of the code that saves shout info. It should immediately pop up when you shout (it does for me). I'd be interested in seeing anything else you do with this. Link to comment Share on other sites More sharing options...
jshepler Posted September 12, 2012 Share Posted September 12, 2012 I think I see what you're talking about now.. If I don't wait for the shout animation to finish, it doesn't let me change shouts, but I don't think that's because of this mod as the game does the same thing without it. Link to comment Share on other sites More sharing options...
ryanshowseason2 Posted September 12, 2012 Author Share Posted September 12, 2012 exactly thats what I'm talking about. What do you mean by a global cooldown? like no shout would be able to be used for that time? I think I did experience a bug the other day though. I switched to some of my shouts and found that their calculated cooldown was somewhere on the order of entire game hours for shouts like one word of whirlwind sprint. Not sure how the calculations went wrong... Link to comment Share on other sites More sharing options...
jshepler Posted September 12, 2012 Share Posted September 12, 2012 Yes, the global cooldown is how long no shout could be cast, but super short like a second or two. I thought it would represent the player having to draw in a breath before shouting again. The bug might be from saving the game. I use GetCurrentRealTime because it returns seconds, but it is the number of seconds since the game launched. So, after playing for a while, saving, quitting, launching, loading, the saved timestamps would be large but current times would be small, resulting in negative numbers when calculating the difference. The code is assuming (i.e. not validating) diff will always be positive. It would end up calling SetVoiceRecoveryTime with a large negative value which probably jacks it up. Link to comment Share on other sites More sharing options...
ryanshowseason2 Posted September 12, 2012 Author Share Posted September 12, 2012 ScriptName sgc_PlayerAliasScript Extends ReferenceAlias { detects equipping/casting shouts and manually manages the global cooldown } Actor player Shout[] shoutArray Float[] recoveryArray Float[] timestampArray int howManyStored = 0 int MAXNUMBER = 128 Event OnInit() player = GetActorReference() shoutArray = New Shout[128] ;MAXNUMBER recoveryArray = New Float[128] ;MAXNUMBER timestampArray = New Float[128] ;MAXNUMBER EndEvent ; ReferenceAlias scripts receive ObjectReference events ; shouting triggers OnSpellCast for the spell on the shout word ; record currently equipped shout and current recovery/time Event OnSpellCast(Form akSpell) Spell sp = akSpell as Spell ;TODO: determine if spell type is "Voice Power" bool isVoicePower = (sp != None) If isVoicePower Shout currentShout = player.GetEquippedShout() Float recovery = player.GetVoiceRecoveryTime() ;seconds Float timestamp = Utility.GetCurrentRealTime() ;seconds int found = shoutArray.Find(currentShout) If found == -1 If howManyStored < MAXNUMBER shoutArray[howManyStored] = currentShout recoveryArray[howManyStored] = recovery timestampArray[howManyStored] = timestamp howManyStored += 1 EndIf Else recoveryArray[found] = recovery timestampArray[found] = timestamp EndIf EndIf EndEvent ; ReferenceAlias scripts receive Actor events if pointing to an Actor ; equipping shouts triggers OnObjectEquipped, contrary to what wiki says ; check if equipped shout in array, calc/set remaining recovery Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference) Shout theShout = akBaseObject as Shout If theShout Float newRecovery = 0.0 int found = shoutArray.Find(theShout) If found >= 0 Float now = Utility.GetCurrentRealTime() ;seconds Float diff = now - timestampArray[found] If diff < recoveryArray[found] If diff > 0 newRecovery = recoveryArray[found] - diff Else timestampArray[found] = now newRecovery = recoveryArray[found] Endif EndIf EndIf player.SetVoiceRecoveryTime(newRecovery) EndIf EndEvent Perhaps an improvement or two then, diff should be greater than 0. If it is not then reset the timestamp to now and start the cooldown process for this shout over again? So you can't reload to get a 0 shout cooldown but you also won't have broken cooldowns. Link to comment Share on other sites More sharing options...
jshepler Posted September 13, 2012 Share Posted September 13, 2012 Yeah, that's fine. There are limited options to choose from, none of them perfect. There some other potential issues related to time... "Real time" is number of seconds since the game launched. Period. Meaning, it's not paused when the game is paused (e.g. in a menu). It does not advance with waiting/sleeping or anything else that affects game time. Saving games and loading games doesn't affect it. And, as we've found, it inherently resets when the game is launched. It's the absolute worst thing to use for this... ... except it's in seconds. "Game time" is completely different and is exactly what should be used, except it's not in seconds. It's in days. Granted, it's a float, so technically it can be used. If the precision is high enough, the "diff" (as a very small fraction of a day) could be multiplied by 86400.0 to get seconds to compare to the stored cooldown (or divide the cooldown by 86400.0 to get days, but divides are much slower, especially floating point divides). Time to do some tests... Link to comment Share on other sites More sharing options...
ryanshowseason2 Posted September 14, 2012 Author Share Posted September 14, 2012 An alternative then would be to make your own timer through OnUpdate calls, just tell the engine to give you an onupdate every second and do it yourself. Link to comment Share on other sites More sharing options...
Recommended Posts