Here's the original version of the mod: https://www.nexusmods.com/morrowind/mods/45694
And my edited script:
- Spoiler: Show
- Begin CHIM_movement
float temp
float temp2
short stemp
short playerspeed
short playerspeedmaster
short offset
short initialize
float pheight
float delay
if initialize = 0
set initialize to 1
endif
set pheight to 134
if getrace "Breton"
set pheight to pheight * 0.950
elseif getrace "High Elf"
set pheight to pheight * 1.1
elseif getrace "Nord"
set pheight to pheight * 1.060
elseif getrace "Orc"
set pheight to pheight * 1.050
elseif getrace "Redguard"
set pheight to pheight * 1.020
elseif getrace "Wood Elf"
set pheight to pheight * 0.900
endif
set pheight to pheight * getscale
short jumpbonus
modsuperjump -jumpbonus
short climbspeed
modflying -climbspeed
set climbspeed to 0
short attacking
float attacktimer
set attacking to 0
if attacktimer <= 0
if getsoundplaying "weapon swish" + getsoundplaying "bowshoot" + getsoundplaying "crossbowshoot"
set attacking to 1
set attacktimer to 0.5
endif
else
set attacktimer to attacktimer - getsecondspassed
endif
float prevx
float prevy
float prevz
float deltx
float delty
float deltz
float prevdeltx
float prevdelty
set prevdeltx to deltx
set prevdelty to delty
float px
float py
float pz
float az
float ax
set px to getpos x
set py to getpos y
set pz to getpos z
set az to getangle z
set ax to getangle x
set deltx to px - prevx
set prevx to px
set delty to py - prevy
set prevy to py
set deltz to pz - prevz
set prevz to pz
float deltx2
float delty2
float deltz2
float deltxyz2
float xyspeed
set deltx2 to deltx * deltx
set delty2 to delty * delty
set deltz2 to deltz * deltz
set deltxyz2 to (deltx2 + delty2 + deltz2)
set xyspeed to getsquareroot(deltx2 + delty2)
short notmoving
if deltxyz2 < getsecondspassed
set notmoving to 1
else
set notmoving to 0
endif
short jumping
short isunderwater
short swimming
short movingtowardswall
set jumping to 0
set swimming to 0
set isunderwater to 0
set movingtowardswall to 0
; sprint when you double tap the walk/run button
short wasrunning
float stoppedrunningtimer
float wadingmult
float sprintmult
if getpcrunning
MessageBox,"We're testing the getPCrunning function, feller!"
; if you are at less than 0.65 * your regular running speed and you're running then you must be colliding, used for climbing later
; .65 is because you movement speed is 0.75 normal when strafing, and to be safe i gave it another 0.1 window
if (xyspeed / (getsecondspassed * (100 + getspeed) * 1.75)) < 0.65
set movingtowardswall to 1
endif
if stoppedrunningtimer < 0.3
set stoppedrunningtimer to 100
if sprintmult == 4
set sprintmult to 1
else
set sprintmult to 4
endif
elseif wasrunning == 0
set sprintmult to 1
endif
if wasrunning == 0
set wasrunning to 1
endif
; if you are wading through water you get slowed down significantly
set wadingmult to 1
if getwaterlevel - pheight * 0.9 < pz
if getwaterlevel - pheight * 0.15 > pz
set wadingmult to 0.2
endif
endif
else
if wasrunning
set stoppedrunningtimer to 0
set wasrunning to 0
endif
if stoppedrunningtimer < 0.3
if notmoving
set stoppedrunningtimer to 1.0
endif
set stoppedrunningtimer to stoppedrunningtimer + getsecondspassed
endif
endif
float attackingmult
if attacktimer > 0
set attackingmult to 0.2
else
set attackingmult to 1
endif
; gives you a bonus to your jump based on how long you crouch for before uncrouching
short WasSneaking
short sneakjumpbonus
float sneakjumptimer
if (GetPCSneaking)
if (WasSneaking == 0)
set sneakjumpbonus to 0
Set WasSneaking to 1
endif
else
if (WasSneaking == 1)
set sneakjumpbonus to ((getacrobatics + getstrength) / 15.0) + getsuperjump
Set SneakJumpTimer to 0.25
Set WasSneaking to 0
endif
if (sneakjumpbonus)
if getpcjumping == 0
if (SneakJumpTimer < 0)
set sneakjumpbonus to 0
else
set SneakJumpTimer to (SneakJumpTimer - getsecondspassed)
endif
endif
endif
endif
; water skipping, fall damage, and wall collision for climbing from water are all here
short wwchanged
float waterwalkingtimer
float landed
short wasjumping
if getpcjumping
; check if you're actually jumping, getpcjumping returns 1 when swimming
; this basically finds out if you're moving horizontally enough (and fast enough) to skip over water
if getwaterlevel < pz
if (deltx2 + delty2) / (1 + 0.1 * deltz2) > 17
if wwchanged == 0
set waterwalkingtimer to getacrobatics / 400.0
set wwchanged to 1
modwaterwalking 1
endif
else
if wwchanged
set wwchanged to 0
set waterwalkingtimer to 0
modwaterwalking -1
endif
endif
if wasjumping == 0
set wasjumping to 1
endif
; since the player doesnt have xy velocity during slowfall i can tell if you're colliding with a wall
if geteffect seffectslowfall
if xyspeed
if xyspeed / (getsecondspassed * (100 + getspeed)) < 0.65
;set movingtowardswall to 1
endif
endif
endif
set jumping to 1
else
; check for collision with wall when swimming
if xyspeed
if xyspeed / ((getsecondspassed * (100 + getspeed) * 1.75) * (1 + 0.01 * getswimspeed)) < 0.65
set movingtowardswall to 1
endif
set swimming to 1
endif
endif
else
if wasjumping
set wasjumping to 0
set sneakjumpbonus to 0
endif
if waterwalkingtimer > 0
set waterwalkingtimer to waterwalkingtimer - getsecondspassed
else
if wwchanged
modwaterwalking -1
set wwchanged to 0
endif
endif
endif
; attaching onto a wall to climb
short climbingstate
short weapondrawn
short sheathedthisframe
if movingtowardswall
set movingtowardswall to 0
if getweapondrawn + getspellreadied
set weapondrawn to 1
else
if weapondrawn == 1
set climbingstate to 1
endif
set weapondrawn to 0
endif
endif
; no regenerating fatigue while in air, climbing, running, being underwater, or swimming (with head above water)
if climbingstate + getpcrunning + jumping + isunderwater + swimming
modcurrentfatigue -getendurance * getsecondspassed
endif
if isunderwater + swimming == 2
modcurrentfatigue -10 * getsecondspassed
endif
if delay <= 15
set delay to ( delay + GetSecondsPassed )
elseif delay > 15
if initialize = 1
set playerspeed to ( player->getspeed )
player->setspeed 0
set initialize to 2
endif
endif
if initialize = 2
if climbingstate
;setspeed 100
elseif getpcrunning
if sprintmult > 1
SetSpeed (PlayerSpeed * sprintmult * wadingmult * attackingmult)
modcurrentfatigue - ( 5000.0 / 250 + getathletics) * getsecondspassed
else
SetSpeed (PlayerSpeed * wadingmult * attackingmult)
endif
elseif GetPCJumping
setspeed getacrobatics
else
setspeed playerspeed
endif
endif
set jumpbonus to sneakjumpbonus
modsuperjump jumpbonus
; knocks you down if you run out of fatigue
float previousfatigue
if previousfatigue > 0
If (GetFatigue <= 0)
set climbingstate to 0
If (previousfatigue > GetFatigue)
ModCurrentFatigue (-50)
EndIf
endif
EndIf
set previousfatigue to getfatigue
; climbing
float sinx
float cosx
float sinz
float cosz
float dsinz
float dcosz
float ppx
float ppy
float ppz
float error
float ferror
float frerror
float flerror
float berror
float brerror
float blerror
float rerror
float lerror
float safezonex
float safezoney
float safezonez
float speedmult
if climbingstate
if getfatigue <= 0
set climbingstate to 0
return
endif
if getweapondrawn
set climbingstate to 0
return
endif
if getpcsneaking
set climbingstate to 0
return
endif
set climbspeed to ((getagility + getacrobatics) / 2.5)
modflying climbspeed
if notmoving
return
endif
set temp to (getsecondspassed * deltxyz2 * -1000.0 / (getathletics + 500.0))
modcurrentfatigue temp
set speedmult to getsecondspassed * (getspeed + getflying) * 3
set ppx to ppx - getpos x
set ppy to ppy - getpos y
set ppz to ppz - getpos z
set temp to (ppx + cosx * cosz * speedmult) ; forward
set error to temp * temp
set temp to (ppy + cosx * sinz * speedmult)
set error to error + temp * temp
set temp to (ppz + sinx * speedmult)
set ferror to error + temp * temp
set temp to (ppx + cosx * -cosz * speedmult) ; backward
set error to temp * temp
set temp to (ppy + cosx * -sinz * speedmult)
set error to error + temp * temp
set temp to (ppz + -sinx * speedmult)
set berror to error + temp * temp
set temp to (ppx + 0.707226 * sinz * speedmult + 0.707226 * cosx * cosz * speedmult) ; forward right
set error to temp * temp
set temp to (ppy + 0.707226 * -cosz * speedmult + 0.707226 * cosx * sinz * speedmult)
set error to error + temp * temp
set temp to (ppz + sinx * 0.707226 * speedmult)
set frerror to error + temp * temp
set temp to (ppx + 0.707226 * -sinz * speedmult + 0.707226 * cosx * cosz * speedmult) ; forward left
set error to temp * temp
set temp to (ppy + 0.707226 * cosz * speedmult + 0.707226 * cosx * sinz * speedmult)
set error to error + temp * temp
set temp to (ppz + sinx * 0.707226 * speedmult)
set flerror to error + temp * temp
set temp to (ppx + 0.707226 * sinz * speedmult + 0.707226 * -cosx * cosz * speedmult) ; backward right
set error to temp * temp
set temp to (ppy + 0.707226 * -cosz * speedmult + 0.707226 * -cosx * sinz * speedmult)
set error to error + temp * temp
set temp to (ppz - sinx * 0.707226 * speedmult)
set brerror to error + temp * temp
set temp to (ppx + 0.707226 * -sinz * speedmult + 0.707226 * -cosx * cosz * speedmult) ; backward left
set error to temp * temp
set temp to (ppy + 0.707226 * cosz * speedmult + 0.707226 * -cosx * sinz * speedmult)
set error to error + temp * temp
set temp to (ppz + -sinx * 0.707226 * speedmult)
set blerror to error + temp * temp
set speedmult to speedmult * 0.75 ; horizontal movement penalty
set temp to (ppx + sinz * speedmult) ; right
set error to temp * temp
set temp to (ppy + -cosz * speedmult)
set error to error + temp * temp
set temp to (ppz)
set rerror to error + temp * temp
set temp to (ppx + -sinz * speedmult) ; left
set error to temp * temp
set temp to (ppy + cosz * speedmult)
set error to error + temp * temp
set temp to (ppz)
set lerror to error + temp * temp
set error to ferror ; find minimum error
if berror < error
set error to berror
endif
if frerror < error
set error to frerror
endif
if flerror < error
set error to flerror
endif
if brerror < error
set error to brerror
endif
if blerror < error
set error to blerror
endif
if lerror < error
set error to lerror
endif
if rerror < error
set error to rerror
endif
set ppx to getpos x
set ppy to getpos y
set ppz to getpos z
set temp to 0.25
if error < temp
if error > -temp
if climbingstate == 1
set climbingstate to 2
set safezonex to ppx
set safezoney to ppy
set safezonez to ppz
else
set climbingstate to 0
set temp to 10
if safezonex - ppx < temp
if safezoney - ppy < temp
if safezonez - ppz < temp
if safezonex - ppx > -temp
if safezoney - ppy > -temp
if safezonez - ppz > -temp
set climbingstate to 2
endif
endif
endif
endif
endif
endif
endif
else
set climbingstate to 1
endif
else
set climbingstate to 1
endif
endif
if climbingstate + sheathedthisframe == 0
return
endif
;==================================================
; Simple Sin
; By: Matt (Simpleton) Edlefsen
;==================================================
set temp to -getangle x
while ( temp > 270 )
set temp to temp - 360
endwhile
while ( temp < -90 )
set temp to temp + 360
endwhile
if ( temp > 90 )
set temp to 180 - temp
endif
set temp to temp * 3.14159265 / 180
set sinx to temp * temp
set sinx to temp * ( ( -0.16605 * sinx) + ( 0.00761 * sinx * sinx) + 1 )
;==================================================
set temp to 90 - getangle x
while ( temp > 270 )
set temp to temp - 360
endwhile
while ( temp < -90 )
set temp to temp + 360
endwhile
if ( temp > 90 )
set temp to 180 - temp
endif
set temp to temp * 3.14159265 / 180
set cosx to temp * temp
set cosx to temp * ( ( -0.16605 * cosx) + ( 0.00761 * cosx * cosx) + 1 )
;==================================================
set temp to 90 - getangle z
while ( temp > 270 )
set temp to temp - 360
endwhile
while ( temp < -90 )
set temp to temp + 360
endwhile
if ( temp > 90 )
set temp to 180 - temp
endif
set temp to temp * 3.14159265 / 180
set sinz to temp * temp
set sinz to temp * ( ( -0.16605 * sinz) + ( 0.00761 * sinz * sinz) + 1 )
;==================================================
set temp to getangle z
while ( temp > 270 )
set temp to temp - 360
endwhile
while ( temp < -90 )
set temp to temp + 360
endwhile
if ( temp > 90 )
set temp to 180 - temp
endif
set temp to temp * 3.14159265 / 180
set cosz to temp * temp
set cosz to temp * ( ( -0.16605 * cosz) + ( 0.00761 * cosz * cosz) + 1 )
;==================================================
set temp to 225 + getangle z
while ( temp > 270 )
set temp to temp - 360
endwhile
while ( temp < -90 )
set temp to temp + 360
endwhile
if ( temp > 90 )
set temp to 180 - temp
endif
set temp to temp * 3.14159265 / 180
set dsinz to temp * temp
set dsinz to temp * ( ( -0.16605 * dsinz) + ( 0.00761 * dsinz * dsinz) + 1 )
;==================================================
set temp to 135 + getangle z
while ( temp > 270 )
set temp to temp - 360
endwhile
while ( temp < -90 )
set temp to temp + 360
endwhile
if ( temp > 90 )
set temp to 180 - temp
endif
set temp to temp * 3.14159265 / 180
set dcosz to temp * temp
set dcosz to temp * ( ( -0.16605 * dcosz) + ( 0.00761 * dcosz * dcosz) + 1 )
;==================================================
End
- Spoiler: Show
- if (xyspeed / (getsecondspassed * (100 + getspeed) * 1.75)) < 0.65
1) It seems like it's not calculating speed accurately, like at all. fBaseRunMultiplier is 1.75, fMinWalkSpeed is 100, and I have completely disabled fAthleticsRunBonus and fEncumberedMoveEffect so it seems like it should be. Here is how xyspeed is generated, can anyone comment on its accuracy? I feel like I'm missing some part of the movement speed formula here.
- Spoiler: Show
- float prevx
float prevy
float prevz
float deltx
float delty
float deltz
float prevdeltx
float prevdelty
set prevdeltx to deltx
set prevdelty to delty
float px
float py
float pz
float az
float ax
set px to getpos x
set py to getpos y
set pz to getpos z
set az to getangle z
set ax to getangle x
set deltx to px - prevx
set prevx to px
set delty to py - prevy
set prevy to py
set deltz to pz - prevz
set prevz to pz
float deltx2
float delty2
float deltz2
float deltxyz2
float xyspeed
set deltx2 to deltx * deltx
set delty2 to delty * delty
set deltz2 to deltz * deltz
set deltxyz2 to (deltx2 + delty2 + deltz2)
set xyspeed to getsquareroot(deltx2 + delty2)
Thanks for any help, guys! Love OpenMW.