Jump to content

Need Help With Scripting


RipperV

Recommended Posts

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 ammount

Float 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

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

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

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 TimeSpeedMult

Float MeleeDmgMult

 

Float BaseMeleeDmg

Float 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

EndIf

End

Link to comment
Share on other sites

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 weapon
  • Toggling sneak mode
  • Any 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 equipped
  • An OnUnequip block to reset the value of the same variable
  • A 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> == 0

It'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> == 0

if <condition>
else

I'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

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

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

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...