RipperV Posted July 26, 2009 Share Posted July 26, 2009 What I want to do is create a hand-to-hand weapon (knuckles) that when drawn adds an imagespace modifier, slows time, increases player speed (inverse to time speed), increases the healing rate, and adds unarmed damage. IE player draws fists, and the screen goes red and time slows, but the player's speed stays the same (inverse of time speed), and the player is stronger and has an increased healing rate. I'd also like to add a jumping height multiplier, but I can't find the function for that (SetActorValue JumpMult X?) What I have so far is this (Please note, it's my first script. I know limited VB, which has been a little help): scn RageVisualFX Float fltTimeSpeedEffect = 0.5 ; multiplyer for timespeed. Player speed should remain the same (inverse)Short srtExtraMeleeDmg = 20 ; Extra hand-to-hand damage ammountFloat rfltBaseHealRate ; Initial player heal rate. Tripled on activate.Float fltHealRateMult = 3 ; Rate to multiply healing by Begin OnStartCombat ; When player enters combat (hopefully when weapon is drawn) imod 01000EA7 ; Add VisualFX sgtm fltTimeSpeedEffect ; Slow time Float TimeSpeedInverse = (1 / fltTimeSpeedEffect) Player.SetActorValue SpeedMult TimeSpeedInverse ; Set Speed to inverse of fltTimeSpeedEffect Player.SetActorValue UnarmedDamage srtExtraMeleeDmg ; Add bonus hand-to-hand damage Set rfltBaseHealRate To Player.GetActorValue HealRate ; Save the players heal rate. If rfltBaseHealRate == 0 ; No heal rate to begin with Player.SetActorValue HealRate fltHealRateMult ; Set rate to multiplyer Else Float HealMultiplyer = (rfltBaseHealRate * fltHealRateMult) Player.SetActorValue HealRate HealMultiplyer ; Else multiply heal rate EndIf End Begin OnCombatEnd ; When player exits combat (hopefully when weapon is sheathed) rimod 01000EA7 ; Remove VisualFX sgtm 1 ; Reset Time to normal Player.SetActorValue SpeedMult 1 ; Set Speed to normal Player.SetActorValue UnarmedDamage 0 ; Remove bonus hand-to-hand damage Player.SetActorValue HealRate rfltBaseHealRate ; Reset heal rate End In game, it does nothing :| Edit: I also tried a version that used ShowMessage when combat starts/ends, but that also didn't do anything :| Link to comment Share on other sites More sharing options...
cmal Posted July 26, 2009 Share Posted July 26, 2009 First and foremost, Fallout's scripting language does not assign values to variables like conventional programming languages. You can't set a variable when you declare it, for one. You have to use a separate line using the command Set (ie: Set fltfltTimeSpeedEffect to 0.5). That should take care of most of your problems. Next, you should store all of your original actor values in a variable. If you use, for example, Player.SetActorValue UnarmedDamage 0, it will set your unarmed damage to 0 even if it was non-zero before your script ran. If you happened to have the Iron Fist Perk, you just erased its effect. Thirdly, how is this script running? Is it attached to a weapon (Object), running in the background (Quest), or something like a Perk or ability (Effect)? OnStartCombat and OnCombatEnd will only trigger when the game enters/leaves combat mode. Whether your weapon is drawn or not is irrelevant. Use IsWeaponOut in an if structure in your blocks to check if your weapon is out when you're in combat. I don't think its necessary to check once you are out of combat. And you should add a switch variable so that the code in the game blocks only run the first time and then reset when the effect ends. Scripts in Fallout are basically run every frame, so its like a giant while loop. That's all I can think of for now. Try these out and post your results. I also suggest you look at the GECK Wiki and read Cipcis' excellent scripting tutorial. Link to comment Share on other sites More sharing options...
gsmanners Posted July 26, 2009 Share Posted July 26, 2009 Changing "speedmult" will not affect the player until you change their equipment (and you can't reasonably do that in a script without FOSE). It's also highly problematic to slow down the time base since that throws off spell durations and who knows what other scripts and mods you just made fail to function properly because they rely on that timer? Using an ISFX is a good idea, but you can use it by name in a script. You don't have to use the hex code. Link to comment Share on other sites More sharing options...
RipperV Posted July 26, 2009 Author Share Posted July 26, 2009 Ok, new version, but untested... I've removed trying to play with health regeneration rate, too much work for something I won't need. Also used OnEquip instead, will add for player only later. Also have a boolean check to see if it's already active. Does the GECK have an If __ and __ statement? Nested If statements are fugly :| Edit:Tested. still doesnt work all the way, but I think I got player speed to move. Also have MeleeDamage changed to UnarmedDamage. cmal: As a weapon. When the knuckles are drawn, the effect starts. gsmanners: Theres a bullet time mod that slows time quite nicely :) Thats pretty much what I want to copy. Also added EditorID naming for the imod, dunno why the GECK told me that didn't work earlier. I also believe I read somewhere that there's a console command to change speedmult, so I'd expect that to work as well. scn RageVisualFX Float TimeSpeedMultFloat MeleeDmgMult Float BaseMeleeDmgFloat BaseSpeedMult Int Active ;Boolean, is effect active? 0 No, 1 Yes Begin OnEquip Set TimeSpeedMult To 0.25 ;1/4 speed time Set MeleeDmgMult To 5 ;MeleeDmg * 5 If Player.IsWeaponOut == 1 If Active == 0 ; If Drawn and Effect Inactive, ;Declare a new float to use for math Float Math Set Active To 1 ;Gather base data Set BaseMeleeDmg To Player.GetActorValue MeleeDamage Set BaseSpeedMult To Player.GetActorValue SpeedMult ;Do Some Maths and Set New Values sgtm TimeSpeedMult ;Slow time Set Math To (BaseSpeedMult / TimeSpeedMult) ;Calculate new playerspeed Player.SetActorValue SpeedMult Math ;Set new speed (Inverse of slowdown) Set Math To (MeleeDmgMult + (BaseMeleeDmg * MeleeDmgMult)) ;Example dmg 0 -> 5, dmg 1 -> 10, dmg 2 -> 15 Player.SetActorValue MeleeDamage Math ;Set new melee damage ;Add IMOD imod RIPRageFX EndIf ElseIf Player.IsWeaponOut == 0 If Active == 1 ;If Sheathed and Effect is Active, sgtm 1 ; Reset Time to whatever it was Player.SetActorValue SpeedMult BaseSpeedMult ;Reset old multiplier Player.SetActorValue MeleeDamage BaseMeleeDmg ;Reset old melee dmg ;Remove IMOD rimod RIPRageFX Set Active To 0 EndIf EndIfEnd Link to comment Share on other sites More sharing options...
Cipscis Posted July 26, 2009 Share Posted July 26, 2009 Please use "code" or "codebox" tags when posting scripts, as this conserves indentation and causes them to be shown in a fixed-width font. Since you say you have some experience with VB I'm sure you know how to indent your scripts, but just in case you're not entirely sure here is a utility that can do it for you, as well as check for several structural errors - Script Validator. Changing "speedmult" will not affect the player until you change their equipment (and you can't reasonably do that in a script without FOSE).While it's true that changing "SpeedMult" is more problematic than making changes to other AVs, it is still feasible without FOSE. As far as I know, these are the events that will cause an actor's speed to be recalculated:Drawing or holstering a weaponToggling sneak modeAny changes to one of the two mobility AVs: "LeftMobilityCondition" and "RightMobilityCondition"Given that drawing or holstering a weapon can cause a recalculation of an actor's speed, and that AV should be changed whenever this event occurs, extra code may not be required. Does the GECK have an If __ and __ statement? Nested If statements are fugly :|You can use a logical AND for this via the "&&" operator. However, whenever possible it is best to use nested conditions in Fallout 3 script for efficiency reasons. Conditions in Fallout 3 scripts are not very well optimised, so if the first part in a condition utilising a logical AND evaluates to false, the rest of the condition will still be evaluated. Because of this, nested conditional statements are more efficient. However, when using more complicated blocks of conditional statements (i.e. those utilising "else"/"elseif" statements) use of the "&&" operator may be unavoidable. At the moment, because you're using a OnEquip block, your script will only run once whenever the weapon is equipped by an actor. Instead, you'll want to use three blocks:An OnEquip block to set the value of a variable that stores information on whether or not the weapon is equippedAn OnUnequip block to reset the value of the same variableA GameMode block to run code that depends on conditions such as whether or not the weapon is drawn In Fallout 3 scripts, variables should be declared at the the top of the script, outside of any Begin/End blocks, so you'll want to move your declaration of the "Math" variable on line 18 to the top of the script with your other variable declarations. It's also worth noting that, when checking boolean values such as the return value of IsWeaponOut, the "== 1" is unnecessary and actually makes the script less efficient. It is also more efficient to use the following structure in the place of "== 0":if <condition> else; if <condition> == 0It's also worth noting that when dealing with exactly opposite conditions, "else" statements should be used instead of "elseif" statements. For example, the second example below is more efficient than the first:if <condition> elseif <condition> == 0if <condition> elseI'm not sure if you can ensure that there will only ever be one instance of this weapon, and that only the player will ever be able to equip it, then you don't need to worry about this, but otherwise there are a few changes that you should make. Basically, you should generalise most of the script by using a "ref" variable to store the return value of GetContainer so that the functions that you call will be applied to the actor that has equipped the weapon. If you do this, then you'll obviously want to make a few changes so that the same code doesn't run on the player as on NPCs. Basically you'll want to change the speed handling so that the speed of the game only changes when the player equips the weapon, and the ImageSpace Modifier will only be applied if the player equips the weapon. Sorry if I've made any typos or if this post is difficult to follow. I've been watching a movie while I wrote it so there might be a few instances of qwertial aphasia mixed in there. Cipscis Link to comment Share on other sites More sharing options...
RipperV Posted July 26, 2009 Author Share Posted July 26, 2009 Oooh, thanks, I'll get back to work :) Edit: I <3 you Got it to work mostly :) Problem is, speed is set when holstered, but time and imod are set when drawn (like they should be). Speed is set in the wrong end. Edit2: Oh, and are there functions? I'd like to make a sub for turning off the effects, since the same code is called twice... scn RageVisualFX Float TimeSpeedMult;Ammount to decrease speed Float MeleeDmgMult;Ammount to increase damage Float BaseMeleeDmg;initial Damage multiplier Float BaseSpeedMult;initial Speed multiplier Float Math;Used for calculations Int Active;Boolean, is effect active? 0 No, 1 Yes Begin OnEquip;Declare initial values If GetContainer == Player;If it's the player, start declarations Set TimeSpeedMult To 0.25;1/4 speed time Set MeleeDmgMult To 20;MeleeDmg + 20 If Player.IsWeaponOut;Player has already drawn weapon (equipped while drawn) Set Active To 1 Else;Player has equipped while holstered Set Active To 0 EndIf Else Set Active To 2;NPC EndIf End Begin GameMode If Active != 2;If it's not an NPC equipping it, If Player.IsWeaponOut If Active == 0; If Drawn and Effect Inactive, Set Active To 1 ;Gather base data Set BaseMeleeDmg To Player.GetActorValue UnarmedDamage Set BaseSpeedMult To Player.GetActorValue SpeedMult ;Do Some Maths and Set New Values sgtm TimeSpeedMult;Slow time Set Math To (BaseSpeedMult / TimeSpeedMult);Calculate new playerspeed Player.SetActorValue SpeedMult Math;Set new speed (Inverse of slowdown) V EDIT V Player.ModActorValue UnarmedDamage MeleeDmgMult;Add melee damage ;Add IMOD imod RIPRageFX EndIf Else If Active == 1;If Sheathed and Effect is Active, sgtm 1; Reset Time to whatever it was Player.SetActorValue SpeedMult BaseSpeedMult;Reset old multiplier Set Math To (-1 * (Player.GetActorValue UnarmedDamage - MeleeDmgMult));Remove extra damage Player.ModActorValue UnarmedDamage Math;Reset old melee dmg ;Remove IMOD rimod RIPRageFX Set Active To 0 EndIf EndIf EndIf End Begin OnUnequip;Qué? I guess I just clear out old data? sgtm 1; Reset Time to whatever it was Player.SetActorValue SpeedMult BaseSpeedMult;Reset old multiplier Set Math To (-1 * (Player.GetActorValue UnarmedDamage - MeleeDmgMult));Remove extra damage Player.ModActorValue UnarmedDamage Math;Reset old melee dmg ;Remove IMOD rimod RIPRageFX Set Active To 0 ;Clear stored data Set BaseMeleeDmg To 0 Set BaseSpeedMult To 0 Set Math To 0 End Link to comment Share on other sites More sharing options...
gsmanners Posted July 26, 2009 Share Posted July 26, 2009 Thanks for clarification, Cipscis. Aren't all those SetActorValues still going to be problematic? For temporary changes like that, you really should use ModActorValue. Link to comment Share on other sites More sharing options...
RipperV Posted July 26, 2009 Author Share Posted July 26, 2009 Nope, ModAV only adds on an amount, right? SetActorValue should set a definite amount, which should let me multiply the stat, like speed x 4 instead of speed + 4. For melee damage on the other hand, I'll use it; just add 20 pts and be done with it. Thanks :) Edit: Ok, I added ModActorValue for the MeleeDamage. I think I'll keep SetActorValue for SpeedMult, since it's not effected by any specific perks, and I want to multiply it. Link to comment Share on other sites More sharing options...
cmal Posted July 26, 2009 Share Posted July 26, 2009 Now that Cipcis is here, you won't be needing my help anymore with scripting. SpeedMult and Unarmed Damage (the amount of damage you'll do Unarmed as opposed to the Unarmed Skill) both have Base Effect entries in the GECK. Since you're using constants, you could try creating an enchant that is added/removed on the player with AddSpell. That way, you won't have to do all that math and fudging with ActorValues every time your script runs. Not sure how the SpeedMult works with enchants since I always do that in scripts, but it might be worth a try. When you decide to put HP regen back in, you can make a scripted effect and just add that to your enchant -- that's sort of how the Solar Powered Perk works and I did something similar for one of my mods. Link to comment Share on other sites More sharing options...
RipperV Posted July 26, 2009 Author Share Posted July 26, 2009 K, thanks for the help :) Figured out that I need to change the SpeedMult before I draw/holster, as opposed to when I draw/holster. Then I just need to find out how to make falling faster... Link to comment Share on other sites More sharing options...
Recommended Posts