Įƒ*žE—@?ØS@—Q‚TL4g߇œ#+;‘?—NoneWallJumpBootsClientMessageConsoleCommandCoreEngineFlipDodgeRDodgeLDodgeBkxWallJump02 kxWallJumpInitializeKeysFindClosestWallSetFinalMeshClientPlayAnim ROLLRIGHT ROLLLEFTMesh PlayerPawnPreBeginPlayCollisionHeight SpectatorGiveToMutateMaxDesireabilityPickupMessageModifyPlayer RespawnTime AmbientGlowDoJumpIcon ItemNamebAutoActivatebActivatablebDisplayableInvPickupViewMesh PickupSoundActivateSoundBotExpireMessageBotpackRechargeRate WallJumpUT MaxJumps JumpHeightVelocityLimit JumpStyle MaxWallDistNormalBounce nofJumps WallJumpByteProperty IntPropertyBoolPropertyFloatPropertyObjectPropertyNamePropertyClassPropertyStructProperty StrPropertyUnrealIStructVectorRotator FunctionObject TextBufferHitWallPackageClassRoleTextureSoundPlayerLodMeshPawnActorLevel Viewport InventoryPlayerReplicationInfo ZoneInfo GameInfo LevelInfoMutatorRight ReturnValueYaw ScriptTextiKeyNameYZXAPhysicsJumpZ Location PointRegion ZoneGravity DifficultyOther TweenTime SequenceP HitLocation HitNormalRateMutateString VelocityHasFlagbAdmin JumpSoundGameRegionZone WallNormalOwner TimeSeconds DodgeDirNetMode RotationSender DirectionIconsAnglePickupsI_BootsBootSndNewMeshTournamentPickupjbootInventoryClass JumpType bRestrictFC nofJumpKeysLastJumpTime keyBindingDeltaVBestHitLocationBestHitNormalClosestSoFarBestA forwardness rightnessDJ_InvMyMutateStringtempMaxJumpstempJumpTypetempJumpHeight#ƒ®4=#š:Ø,–:Ø,€’’’’’’’’’’6K*ja®Xu6č„œŌXƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Y“1ŚČ“1ŚČ‡Ž”“1ŚČ“1ŚČƒ> £Yƒ> £Yƒ> £Y‡Ž”ƒ> £Y—{#Uæƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Y‡Ž”ƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Y‡Ž”‡Ž”˜©Ł«ƒ> £Y‡Ž”˜©Ł«ƒ> £Yƒ> £Y‡Ž”ƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Yƒ> £Y‡Ž”ƒ> £Y )… ,"-$Ķ̌?.$ÜB/"*$ @0$€B1$ff&?2"(]WallJumping is over!Ó"Ó#Ó]! You picked up the WallJumpBoots ]WallJumpBoots$šA$°$?%±&±Ą°$`A @ €ƒ@€ƒ@3€‰ €ƒ€†@ƒ&*@@††.€ƒ„'†¦)@+@,@-„†„†€@!@"@@$†/€†;€†1€2ŽhŒ /* WARNING! This file was auto-generated by jpp. You probably want to be editing ./WallJumpBoots.uc.jpp instead. */ //================================================================================ // WallJumpBoots. //================================================================================ // vim: ft=uc // TODO: If we have normal jump boots, our in-air doublejumps also jump with their strength. I think this is wrong - we should ideally prevent the jump boots from being used in-air, but keep their charge. // TODO: Refuse doublejump during dodge (could make it an admin option). // DONE: I think we can remove GRAPPLEGUN_JUMPOFF_FIX. The grapple jump-off is unreliable with or without DJBoots. I doubt DJBoots are intercepting the jump call, since they work by adding a keybind! // #define GRAPPLEGUN_JUMPOFF_FIX class WallJumpBoots extends TournamentPickup config(kxWallJump); var() config int MaxJumps; var() config float JumpHeight; var() config float VelocityLimit; // Defines the size of the apex var() config int JumpType; // This is the restriction on jumping var() config int JumpStyle; // This is the type of jump that the player performs var() config float RechargeRate; // This allows your boots to recharge slowly without walking if you don't use them for some time, for example, when using the grappling hook. var() config bool bRestrictFC; var() config float MaxWallDist; var() config float NormalBounce; var int nofJumps; var int nofJumpKeys; var float LastJumpTime; replication { reliable if ( Role == 4 ) ClientPlayAnim; reliable if ( Role < 4 ) WallJump; } simulated function PreBeginPlay () { local PlayerPawn P; if ( Level.NetMode == 1 ) { return; } foreach AllActors(Class'PlayerPawn',P) { if ( Viewport(P.Player) != None ) { break; } else { P = None; } } if ( P == None ) { Log("kxWallJump02.WallJumpBoots.PreBeginPlay() NO LOCAL PLAYERPAWN !!!"); return; } InitializeKeys(P); if ( nofJumpKeys == 0 ) { Log("kxWallJump02.WallJumpBoots.PreBeginPlay() Could NOT find any keys bound to JUMP/DOUBLEJUMP, WallJump will NOT work !!!"); } else { } } simulated function InitializeKeys (PlayerPawn P) { local string KeyName; local string keyBinding; local int i; nofJumpKeys = 0; for (i=0;i<256;i++) { // TODO: This looks ballbag - check and test. Why aren' we using GET INPUT? Match on Jump single-word. KeyName = P.ConsoleCommand("Keyname" @ string(i)); if ( (InStr(P.ConsoleCommand("Keybinding" @ KeyName),"Jump") != -1) && (InStr(P.ConsoleCommand("Keybinding" @ KeyName),"WallJump") == -1) ) { keyBinding = P.ConsoleCommand("Keybinding" @ KeyName); P.ConsoleCommand("SET INPUT " @ KeyName @ " WallJump|" $ keyBinding); Log("kxWallJump02.WallJumpBoots.InitializeKeys() Changed" @ KeyName @ "from" @ keyBinding @ "to WallJump|" $ keyBinding); nofJumpKeys++; } else { if ( InStr(P.ConsoleCommand("Keybinding" @ KeyName),"WallJump") != -1 ) { nofJumpKeys++; } } } } exec function WallJump () { local PlayerPawn P; local Actor HitWall; local vector HitLocation,WallNormal,DeltaV; if ( PlayerPawn(Owner) == None ) { return; } P = PlayerPawn(Owner); if (RechargeRate>0 && (Level.TimeSeconds-LastJumpTime)>=RechargeRate && nofJumps>1) { nofJumps = 1; } if (bRestrictFC && P.PlayerReplicationInfo.HasFlag != None && nofJumps VelocityLimit) { // Not at apex return; } break; case 1: // Only allow jump when going upwards, or at the apex (not falling too fast) if (P.Velocity.Z < -VelocityLimit) { // Falling fast return; } break; default: } // Repeated jump after dodge takes player too far! (Certainly if velocity is additional.) if (p.DodgeDir == DODGE_Active) { // p.ClientMessage("Disallowed WallJump because you are mid-dodge."); return; } HitWall = FindClosestWall(p,HitLocation,WallNormal); if (HitWall == None) { p.ClientMessage("You need to be near a wall to wall-jump!"); return; } // OK we will do a jump nofJumps++; LastJumpTime = Level.TimeSeconds; DeltaV = P.JumpZ * JumpHeight * NormalBounce * WallNormal; switch (JumpStyle) { case 0: // Set standard upward velocity P.Velocity.Z = P.JumpZ * JumpHeight; break; case 1: // Moderated additional //// If we are already goin up fast, give us only half a jump extra P.Velocity.Z = P.Velocity.Z + 0.5 * P.JumpZ * JumpHeight; //// If we are not going up at jump speed, make us go up at jump speed! if (P.Velocity.Z < P.JumpZ * JumpHeight) { P.Velocity.Z = P.JumpZ * JumpHeight; } break; case 2: //// Add extra jump to current upward velocity. This can take you very high if tapped quickly, so for this JumpStyle, JumpType=on-apex is recommended. P.Velocity.Z += P.JumpZ * JumpHeight; break; case 3: //// Let the player choose whether to go for height or distance on the secondary jumps: //// Add extra jump to current velocity (half up, half "with" our sideways velocity) P.Velocity.Z += P.JumpZ * JumpHeight * 0.5; P.Velocity = Normal(P.Velocity) * (VSize(P.Velocity) + P.JumpZ * JumpHeight * 0.5); break; case 4: // "Fixed" / "sticky" / "standard" // Always standard (TODO: should only be applied if greater than existing Z or horizontal velocity): P.Velocity.X = 0; P.Velocity.Y = 0; P.Velocity.Z = P.JumpZ * JumpHeight; break; default: P.Velocity.Z = P.JumpZ * JumpHeight; break; } // P.Velocity.Z = P.JumpZ * JumpHeight; // P.Velocity.X = 0; // P.Velocity.Y = 0; P.Velocity = P.Velocity + DeltaV; P.PlaySound(P.JumpSound,SLOT_Interface,1.5,True,1200.0,1.0); if ( (Level.Game != None) && (Level.Game.Difficulty > 0) ) { P.MakeNoise(0.1 * Level.Game.Difficulty); } // if ( nofJumps == MaxJumps ) { SetFinalMesh(P,DeltaV); // } } } else if (p.Physics == PHYS_Walking) { // Do a normal jump off the ground: P.DoJump(); nofJumps = 1; LastJumpTime = Level.TimeSeconds; } } function Actor FindClosestWall(PlayerPawn P, out vector BestHitLocation, out vector BestHitNormal) { local float ClosestSoFar,angle; local Actor BestA,A; local vector HitLocation,HitNormal; local vector Direction; ClosestSoFar = 1000000.00; for (angle=0;angle<2.0*PI;angle+=PI/8.0) { // Direction = vect( MaxWallDist*sin(angle), MaxWallDist*cos(angle), 0.0 ); // Direction = vector( rotator(angle,0,0) ); Direction.X = MaxWallDist*sin(angle); Direction.Y = MaxWallDist*cos(angle); Direction.Z = 0; A = Trace(HitLocation,HitNormal,P.Location+Direction,P.Location,false); if (A!=None && VSize(HitLocation-P.Location) < ClosestSoFar) { BestHitLocation = HitLocation; BestHitNormal = HitNormal; BestA = A; } } return BestA; } simulated function SetFinalMesh(PlayerPawn P, Vector DeltaV) { local name newMesh; local float forwardness,rightness; local Rotator right; newMesh = ''; forwardness = Normal(DeltaV) Dot Normal(Vector(P.Rotation)); right = P.Rotation; right.Yaw += 16384; rightness = Normal(DeltaV) Dot Normal(Vector(right)); // if ( sqrt(forwardness*forwardness+rightness*rightness)<0.2 && P.HasAnim('Flip')) { // newMesh = 'Flip'; if ( sqrt(DeltaV.X*DeltaV.X+DeltaV.Y*DeltaV.Y)<4.0) { // && P.HasAnim('Flip')) { //// Do not change mesh. // newMesh = 'Flip'; // TODO: should really *set* them on flat jump anim, since they may have started jumping sideways but then flattened to straight upward velocity. } else if ( rightness > Abs(forwardness) && P.HasAnim('ROLLRIGHT') ) { newMesh = 'ROLLRIGHT'; } else if ( rightness > Abs(forwardness) && P.HasAnim('DodgeL') ) { newMesh = 'DodgeL'; } else if ( rightness < (-Abs(forwardness)) && P.HasAnim('ROLLLEFT') ) { newMesh = 'ROLLLEFT'; } else if ( rightness < (-Abs(forwardness)) && P.HasAnim('DodgeR') ) { newMesh = 'DodgeR'; } else if ( forwardness < (-Abs(rightness)) && P.HasAnim('DodgeB') ) { newMesh = 'DodgeB'; } else if ( P.HasAnim('Flip') ) { // forwardness>Abs(rightness) newMesh = 'Flip'; } if (newMesh != '' && P.HasAnim(newMesh)) { P.PlayAnim(newMesh,1.352 * FMax(0.34999999,Region.Zone.ZoneGravity.Z / Region.Zone.Default.ZoneGravity.Z),0.06); if ( Level.NetMode != 0 ) { ClientPlayAnim(newMesh,1.352 * FMax(0.34999999,Region.Zone.ZoneGravity.Z / Region.Zone.Default.ZoneGravity.Z),0.06); } } } simulated function ClientPlayAnim (name Sequence, optional float Rate, optional float TweenTime) { Owner.PlayAnim(Sequence,Rate,TweenTime); } ”6?+’’’’’’’’’’’’’’’’’’ 5ŠŚ¦¤”=$:eƒ> £Y—{#U懎”Ž*jaƒ> £YŽ*jaƒ> £YŽ*jaƒ> £YŽ*jaƒ> £YŽ*jaƒ> £Yƒ> £YŽ*jaƒ> £YŽ*ja‰žtȉžtȉžtȉžtČ*ja*ja … EH//================================================================================ // WallJumpUT. //================================================================================ class WallJumpUT extends Mutator config (kxWallJump); // var config bool bRestrictFC; // var config int MaxJumps; // var config int JumpType; // var config float JumpHeight; // var config float RechargeRate; function ModifyPlayer (Pawn Other) { local Class InventoryClass; local WallJumpBoots DJ_Inv; Super.ModifyPlayer(Other); // 0x00000014 : 0x0000 if ( Other.IsA('Spectator') || (!Other.IsA('PlayerPawn') && !Other.IsA('Bot')) ) // 0x00000019 : 0x000B { return; // 0x0000003A : 0x0037 } // InventoryClass = Class(DynamicLoadObject("kxWallJump02.WallJumpBoots",Class'Class')); // 0x0000003C : 0x0039 // InventoryClass = Class(DynamicLoadObject(String(class'WallJumpBoots'),Class'Class')); // 0x0000003C : 0x0039 InventoryClass = class'WallJumpBoots'; DJ_Inv = Spawn(Class'WallJumpBoots',Other,,Other.Location); // 0x00000066 : 0x006E if ( DJ_Inv != None ) { DJ_Inv.RespawnTime = 0.0; // 0x00000082 : 0x009B DJ_Inv.GiveTo(Other); // 0x00000091 : 0x00AF // DJ_Inv.MaxJumps = MaxJumps; // 0x0000009C : 0x00C3 // DJ_Inv.JumpType = JumpType; // 0x000000A7 : 0x00D7 // DJ_Inv.JumpHeight = JumpHeight; // 0x000000B2 : 0x00EB // DJ_Inv.RechargeRate = RechargeRate; // 0x000000B2 : 0x00EB // TODO parts missing! } } function Mutate (string MutateString, PlayerPawn Sender) { local string MyMutateString; local int tempMaxJumps; local int tempJumpType; local float tempJumpHeight; // TODO: SaveConfig()? Nah, for that let admin do "admin set" :P if ( Sender.PlayerReplicationInfo.bAdmin || (Level.NetMode == 0) ) // 0x00000014 : 0x0000 { MyMutateString = MutateString; // 0x0000003B : 0x0034 if ( Left(MyMutateString,12) ~= "WallJumpUT" ) // 0x00000040 : 0x003F { MyMutateString = Mid(MyMutateString,13); // 0x00000059 : 0x005B if ( Left(MyMutateString,8) ~= "MaxJumps" ) // 0x00000062 : 0x006A { tempMaxJumps = int(Mid(MyMutateString,9)); // 0x00000077 : 0x0082 if ( tempMaxJumps != 0 ) // 0x00000081 : 0x0092 { class'WallJumpBoots'.default.MaxJumps = tempMaxJumps; // 0x00000089 : 0x009D Sender.ClientMessage("Maximum number of jumps is now: " $ string(class'WallJumpBoots'.default.MaxJumps)); // 0x0000008E : 0x00A8 } else { // 0x000000BA : 0x00DD Sender.ClientMessage("MaxJumps should be 1 or higher."); // 0x000000BD : 0x00E0 } } else { // 0x000000E3 : 0x010C if ( Left(MyMutateString,8) ~= "JumpType" ) // 0x000000E6 : 0x010F { tempJumpType = int(Mid(MyMutateString,9)); // 0x000000FB : 0x0127 switch (tempJumpType) // 0x00000105 : 0x0137 { case 0: // 0x00000109 : 0x013E class'WallJumpBoots'.default.JumpType = 0; // 0x0000010D : 0x0142 Sender.ClientMessage("Jumptype is now \"At apex\""); // 0x00000111 : 0x0149 break; // 0x00000131 : 0x016F case 1: // 0x00000134 : 0x0172 class'WallJumpBoots'.default.JumpType = 1; // 0x00000138 : 0x0176 Sender.ClientMessage("Jumptype is now \"Going up and apex\""); // 0x0000013C : 0x017D break; // 0x00000166 : 0x01AD case 2: // 0x00000169 : 0x01B0 class'WallJumpBoots'.default.JumpType = 2; // 0x0000016E : 0x01B5 Sender.ClientMessage("Jumptype is now \"Always\""); // 0x00000173 : 0x01BD break; // 0x00000192 : 0x01E2 default: // 0x00000195 : 0x01E5 Sender.ClientMessage("Jumptype should be 0, 1 or 2."); // 0x00000198 : 0x01E8 break; // 0x000001BC : 0x0212 } } else { // 0x000001BF : 0x0215 if ( Left(MyMutateString,10) ~= "JumpHeight" ) // 0x000001C2 : 0x0218 { tempJumpHeight = float(Mid(MyMutateString,11)); // 0x000001D9 : 0x0232 if ( tempJumpHeight >= 100 ) // 0x000001E4 : 0x0242 { class'WallJumpBoots'.default.JumpHeight = tempJumpHeight / 100; // 0x000001EF : 0x024F Sender.ClientMessage("JumpHeight is now "$ class'WallJumpBoots'.default.JumpHeight); // 0x00000198 : 0x01E8 // TODO // File ended here! } } } } } } Super.Mutate(MutateString,Sender); } ¹.³6š:¢& /a0 ƒNFw.“·*NM*10”r*ēkxWallJump02.WallJumpBoots.PreBeginPlay() NO LOCAL PLAYERPAWN !!!  4š%ēkxWallJump02.WallJumpBoots.PreBeginPlay() Could NOT find any keys bound to JUMP/DOUBLEJUMP, WallJump will NOT work !!!4 7 L Ź%%Č–  ØKeynameS‚›~ ØKeybinding Jump’’’’6š~ ØKeybinding WallJump’’’’ ØKeybinding  .pØØSET INPUT  WallJump|ēpØØØØkxWallJump02.WallJumpBoots.InitializeKeys() Changed fromto WallJump|„¾¾›~ ØKeybinding WallJump’’’’„„ 83d r.ƒ”* .ƒ”c‚‚±!?%³Æ£! —&&Ŗ‚‚-+w§½*–“&Ļš:Ŗ:$Ģ– ’%ü±ŗ6Š ˆ  * '&$°6Š ˆ©  * ’’Cš:ø:$ #-$¤r#*0You need to be near a wall to wall-jump! „£Õ««,$* %6Š ˆ« Į&6Š ˆ®6Š ˆ««?¾°6Š ˆ«6Š ˆ« ó,ø6Š ˆ« {,ø6Š ˆ««? ˆŌā ˆ®į ˆ««? Ž,6š ˆ6™ ˆ6Š ˆ« ’’6Š ˆ« ˆ× ˆ#a¼$Ą?'–D€?¼‚w *—: «%"b«ĶĢĢ=< «š:Ŗ:$&£ Ā 9Ē%$tI °«@ŪI@6š«"»6™«"¼6Ša'× › ›(ō‚w*°įŲ ›%./'&ø¬ŪI@A& %€„:ŪÓ“!Ūā ā9 © ©”6¶@Ūā ā9¤°Į®«6š 6š «6™ 6™ €@ŅŁ‚±ŗa!!Ņ‚±ŗa!!ŅE‚°©ŗa!!Ņ|‚°©ŗa!!ҳ‚°©ŗa! ! ŅŅa!!²‚’!aMa«V­?õ33³>¬6Š6ž Ÿ6Š6ž ŸĀu=²›:¢%«V­?õ33³>¬6Š6ž Ÿ6Š6ž ŸĀu= <0ūś"”a012 ¬  ³¬ Q„ a/!,‚ a/! a/!' 3 a    ›±w*ŗ   ­>(/śļŻ„§-»š:¢%(Ż|€, WallJumpUT,%|€,MaxJumpsJ, ņ›% 9pMaximum number of jumps is now: S "'MaxJumps should be 1 or higher.ŻY|€,JumpType)J, ) •% %!Jumptype is now "At apex"V ą& &+Jumptype is now "Going up and apex"V ", , Jumptype is now "Always"V ’’%Jumptype should be 0, 1 or 2.VŻŻ|€, JumpHeightL, ݳ?,d ¬?,d+pJumpHeight is now U ­( EEF’’’’F’’’’MFž’’’B>ū’’’?F’’’’T;ü’’’nF’’’’L7ś’’’]Fž’’’7Fž’’’8Fž’’’;Fž’’’F7÷’’’a8ü’’’NFž’’’5Fž’’’AF’’’’RF’’’’UE)Fž’’’<F’’’’QF’’’’S7ś’’’\7ś’’’^;ü’’’b>ü’’’c8ä’’’t;ü’’’s;ķ’’’d8ł’’’r8ü’’’v4ł’’’y7ł’’’wFž’’’9Fž’’’C>ū’’’@8÷’’’Q4ü’’’G;ü’’’z4ü’’’`4č’’’eAģ’’’Aģ’’’Fė’’’CEė’’’Kė’’’DIŃ’’’AFž’’’:Fž’’’6F’’’’OF’’’’P5Ś’’’X8ż’’’J4ü’’’xAü’’’7Ė’’’6é’’’p8ż’’’q8é’’’oE=EĀ’’’}HĮ’’’@Œ9iu#®bB$‹- d2¤<B p2Œ<i|2–?S I3Œ?{U3‘2 b3–8[ n3Œ>fz3Œ8iG4<KT4‹<P a4‹<Q m4‘, y4Œ7iE5‹:~ R5‘F ^5‘H j5–8J v5‘8Z B6:|N6Œ>R[6‹I h69Kt6Œ:iA7Œ:_N7:j[7<Vh7‘?T u7‹?V A8‹. M8‹* Y8‹0 e8Œ9Dq89u~8‹:N K9Œ:OW9:kd9–?m q9‘?U }9‘/ I:³G U:‹1 a:9jm::Lz::MG;¤=h T;‹=l `;‹=g l;²>Ex;„Y4tŒF<”+czČ„5Y4PH]Ī’¹km–’ IX›’3qa”’ERÆŒ:WW²’Wd²’,{¹’¬5Mgŗ’­5c t¼