diff --git a/Readme.md b/Readme.md index 2da6e66..dd06fda 100644 --- a/Readme.md +++ b/Readme.md @@ -31,6 +31,7 @@ Doom Tournament (currently the devel branch is required). - Minigun (slot 0) (replaces chaingun) - SMP 7243 (slot 0) (replaces bfg9000) - Teleport Capsules (slot 1) + - Razorclaw (slot 1) (replaces chainsaw) - Protomag (slot 2) (replaces pistol) - Dual Protomags - Quadshot (slot 3) (replaces shotguns) @@ -69,7 +70,6 @@ Doom Tournament (currently the devel branch is required). ## In progress - - Razorclaw (slot 1) (replaces chainsaw) - Stunner (slot 4) (replaces chainsaw) - Fireblaster (slot 5) (replaces rocket launcher) - Flamethrower (slot 6) (replaces plasma rifle) diff --git a/language.txt b/language.txt index 21a9c3a..d916bb7 100644 --- a/language.txt +++ b/language.txt @@ -25,6 +25,8 @@ O_MINIGUN = "%k's Minigun turned %o into a leaky piece of meat."; O_STUNNER = "%o couldn't stand the force from %k's Stunner."; O_RAZORCLAW1 = "%k took a bite off %o with the Razorclaw."; O_RAZORCLAW2 = "%o was shredded into mincemeat by %k's Razorclaw."; +O_RAZORCLAWDECAP1 = "%k tore %o's head off with the Razorclaw."; +O_RAZORCLAWDECAP2 = "%o got %p head sliced off by %k's Razorclaw."; O_PROTOMAG = "%k put a couple extra holes into %o with the Protomag."; O_PROTOMAG2 = "%k put a couple extra holes into %o with the Dual Protomags."; O_QUADSHOT = "%o ate a mouthful of buckshot from %k's Quadshot."; @@ -278,6 +280,8 @@ O_RAZORJACK = "%k arrancó un trozo ensangrentado de %o con el Razorjack."; O_STUNNER = "%o no pudo soportar la fuerza del Aturdidor de %k."; O_RAZORCLAW1 = "%k mordisqueó a %o con la Garra Cortadora."; O_RAZORCLAW2 = "%o fue hech@[ao_esp] picadillo por la Garra Cortadora de %k."; +O_RAZORCLAWDECAP1 = "%k le arrancó la cabeza a %o con la Garra Cortadora."; +O_RAZORCLAWDECAP2 = "%o fue decapitad@[ao_esp] por la Garra Cortadora de %k."; O_PROTOMAG = "%k le hizo unos cuantos agujeros extra a %o con la Protoarma."; O_PROTOMAG2 = "%k le hizo unos cuantos agujeros extra a %o con las Dos Protoarmas."; O_QUADSHOT = "%o tragó un bocado de perdigones del Quadshot de %k."; diff --git a/modeldef.bonesaw b/modeldef.bonesaw index 4f8a313..350152d 100644 --- a/modeldef.bonesaw +++ b/modeldef.bonesaw @@ -13,3 +13,137 @@ Model "Bonesaw" ROTATING FrameIndex CSWP A 1 0 } + +Model "Bonesaw" +{ + Path "models" + Model 0 "Bonesaw_d.3d" + Skin 0 "JBoneSw1.png" + Scale -0.1 -0.08 0.1 + Offset 10 -20 -10 + + // Down + FrameIndex CSWD A 0 1 + FrameIndex CSWD B 0 2 + FrameIndex CSWD C 0 3 + FrameIndex CSWD D 0 4 + FrameIndex CSWD E 0 5 + FrameIndex CSWD F 0 6 + FrameIndex CSWD G 0 7 + FrameIndex CSWD H 0 8 + FrameIndex CSWD I 0 9 + // Select + FrameIndex CSWS A 0 9 + FrameIndex CSWS B 0 10 + FrameIndex CSWS C 0 11 + FrameIndex CSWS D 0 12 + FrameIndex CSWS E 0 13 + FrameIndex CSWS F 0 14 + FrameIndex CSWS G 0 15 + FrameIndex CSWS H 0 16 + FrameIndex CSWS I 0 17 + // Idle + FrameIndex CSWI A 0 18 + FrameIndex CSWI B 0 19 + FrameIndex CSWI C 0 20 + FrameIndex CSWI D 0 21 + FrameIndex CSWI E 0 22 + // Twiddle + FrameIndex CSWT A 0 23 + FrameIndex CSWT B 0 24 + FrameIndex CSWT C 0 25 + FrameIndex CSWT D 0 26 + FrameIndex CSWT E 0 27 + FrameIndex CSWT F 0 28 + FrameIndex CSWT G 0 29 + FrameIndex CSWT H 0 30 + FrameIndex CSWT I 0 31 + FrameIndex CSWT J 0 32 + FrameIndex CSWT K 0 33 + FrameIndex CSWT L 0 34 + FrameIndex CSWT M 0 35 + // AltFire + FrameIndex CSWA A 0 36 + FrameIndex CSWA B 0 37 + FrameIndex CSWA C 0 38 + FrameIndex CSWA D 0 39 + FrameIndex CSWA E 0 40 + FrameIndex CSWA F 0 41 + FrameIndex CSWA G 0 42 + FrameIndex CSWA H 0 43 + FrameIndex CSWA I 0 44 + FrameIndex CSWA J 0 45 + FrameIndex CSWA K 0 46 + FrameIndex CSWA L 0 47 + FrameIndex CSWA M 0 48 + FrameIndex CSWA N 0 49 + // Fire + FrameIndex CSWF A 0 50 + FrameIndex CSWF B 0 51 + FrameIndex CSWF C 0 52 + FrameIndex CSWF D 0 53 + FrameIndex CSWF E 0 54 + FrameIndex CSWF F 0 55 + FrameIndex CSWF G 0 56 + FrameIndex CSWF H 0 57 + FrameIndex CSWF I 0 58 + FrameIndex CSWF J 0 59 + FrameIndex CSWF K 0 60 + FrameIndex CSWF L 0 61 + FrameIndex CSWF M 0 62 + FrameIndex CSWF N 0 63 + FrameIndex CSWF O 0 64 + FrameIndex CSWF P 0 65 + FrameIndex CSWF Q 0 66 + FrameIndex CSWF R 0 67 + FrameIndex CSWF S 0 68 + FrameIndex CSWF T 0 69 + FrameIndex CSWF U 0 70 + FrameIndex CSWF V 0 71 + FrameIndex CSWF W 0 72 + FrameIndex CSWF X 0 73 + // Hold + FrameIndex CSWH A 0 74 + FrameIndex CSWH B 0 75 + FrameIndex CSWH C 0 76 + FrameIndex CSWH D 0 77 + FrameIndex CSWH E 0 78 + FrameIndex CSWH F 0 79 + FrameIndex CSWH G 0 80 + FrameIndex CSWH H 0 81 + FrameIndex CSWH I 0 82 + FrameIndex CSWH J 0 83 + FrameIndex CSWH K 0 84 + FrameIndex CSWH L 0 85 + FrameIndex CSWH M 0 86 + FrameIndex CSWH N 0 87 + FrameIndex CSWH O 0 88 + FrameIndex CSWH P 0 89 + FrameIndex CSWH Q 0 90 + FrameIndex CSWH R 0 91 + // Release + FrameIndex CSWR A 0 92 + FrameIndex CSWR B 0 93 + FrameIndex CSWR C 0 94 + FrameIndex CSWR D 0 95 + FrameIndex CSWR E 0 96 + FrameIndex CSWR F 0 97 + FrameIndex CSWR G 0 98 + FrameIndex CSWR H 0 99 + FrameIndex CSWR I 0 100 + FrameIndex CSWR J 0 101 + FrameIndex CSWR K 0 102 + FrameIndex CSWR L 0 103 + FrameIndex CSWR M 0 104 + FrameIndex CSWR N 0 105 + FrameIndex CSWR O 0 106 + FrameIndex CSWR P 0 107 + FrameIndex CSWR Q 0 108 + FrameIndex CSWR R 0 109 + FrameIndex CSWR S 0 110 + FrameIndex CSWR T 0 111 + FrameIndex CSWR U 0 112 + FrameIndex CSWR V 0 113 + FrameIndex CSWR W 0 114 + FrameIndex CSWR X 0 115 +} \ No newline at end of file diff --git a/models/Bonesaw.blend b/models/Bonesaw.blend index 0c2d246..e11cf5d 100644 Binary files a/models/Bonesaw.blend and b/models/Bonesaw.blend differ diff --git a/models/Bonesaw_a.3d b/models/Bonesaw_a.3d index ddca2bb..b308080 100644 Binary files a/models/Bonesaw_a.3d and b/models/Bonesaw_a.3d differ diff --git a/sndinfo.txt b/sndinfo.txt index 5cc6845..9399a02 100644 --- a/sndinfo.txt +++ b/sndinfo.txt @@ -298,6 +298,11 @@ smini/altfire sminialt smini/endfire sminiend smini/explode sminiexp +bonesaw/select bsawsel +bonesaw/claw bsawstab +bonesaw/spin bsawloop +bonesaw/spinend bsawend + translator/event transa3 detector/start detact diff --git a/sounds/BSawEnd.ogg b/sounds/BSawEnd.ogg index e68ab1f..9fe88d1 100644 Binary files a/sounds/BSawEnd.ogg and b/sounds/BSawEnd.ogg differ diff --git a/zscript/bonesaw.zsc b/zscript/bonesaw.zsc index b8726ac..afa0efd 100644 --- a/zscript/bonesaw.zsc +++ b/zscript/bonesaw.zsc @@ -41,10 +41,71 @@ Class Bonesaw : UnrealWeapon Destroy(); } } + override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack ) + { + if ( !bAltFire ) + return StringTable.Localize((mod=='Decapitated')?"$O_RAZORCLAWDECAP2":"$O_RAZORCLAW2"); + return StringTable.Localize((mod=='Decapitated')?"$O_RAZORCLAWDECAP1":"$O_RAZORCLAW1"); + } + private action bool TryHit( double angle, int dmg ) + { + FTranslatedLineTarget t; + double slope = AimLineAttack(angle,DEFMELEERANGE,t,0.,ALF_CHECK3D); + FLineTraceData d; + Vector3 x, y, z, origin; + [x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll); + origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),y*4-z*4); + LineTrace(angle,DEFMELEERANGE,slope,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d); + if ( d.HitType != TRACE_HitNone ) + { + if ( d.HitType == TRACE_HitActor ) + { + if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.8) ) + dmg = d.HitActor.DamageMobj(invoker,self,dmg*2,'Decapitated',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x)); + else dmg = d.HitActor.DamageMobj(invoker,self,dmg,'slashed',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x)); + UTMainHandler.DoKnockback(d.HitActor,d.HitDir,-7000); + UTMainHandler.DoKnockback(self,-d.HitDir,-2000); + if ( d.HitActor.player ) d.HitActor.A_QuakeEx(2,2,2,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25); + if ( !d.HitActor.bNOBLOOD ) + { + d.HitActor.TraceBleed(dmg,invoker); + d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg); + } + } + else if ( d.HitType == TRACE_HitWall ) + d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation-d.HitDir*4); + A_QuakeEx(1,1,1,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.12); + if ( !d.HitActor || d.HitActor.bNOBLOOD ) + { + A_PlaySound("ripper/hit",CHAN_6); + let p = Spawn("SawImpact",d.HitLocation-d.HitDir*4); + p.angle = atan2(d.HitDir.y,d.HitDir.x); + p.pitch = asin(-d.HitDir.z); + } + else A_PlaySound("ripper/flesh",CHAN_6); + A_AlertMonsters(); + if ( invoker.bAltFire ) A_QuakeEx(3,3,3,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.13); + else A_QuakeEx(1,1,1,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.06); + return true; + } + return false; + } + action void A_Slice() + { + UTMainHandler.DoSwing(self,(FRandom[Bonesaw](-1,1),FRandom[Bonesaw](-1,1)),0.3,-0.2,2,SWING_Spring,0,2); + invoker.special1++; + if ( invoker.special1 < 5 ) return; + invoker.special1 = 0; + for ( int i=0; i<8; i++ ) if ( TryHit(angle+i*(45./16),5) || TryHit(angle-i*(45./16),5) ) return; + } + action void A_Clamp() + { + for ( int i=0; i<8; i++ ) if ( TryHit(angle+i*(45./16),20) || TryHit(angle-i*(45./16),20) ) return; + } Default { - Tag "$T_BONESAW"; - Inventory.PickupMessage "$I_BONESAW"; + Tag "$T_RAZORCLAW"; + Inventory.PickupMessage "$I_RAZORCLAW"; Weapon.UpSound "bonesaw/select"; Weapon.SlotNumber 1; Weapon.SelectionOrder 9; @@ -60,5 +121,88 @@ Class Bonesaw : UnrealWeapon Stop; CSWP B -1; Stop; + Select: + CSWS A 1 A_Raise(int.max); + Wait; + Ready: + CSWS ABCDEFGHI 2 A_WeaponReady(WRF_NOFIRE); + Goto Idle; + Dummy: + TNT1 A 1 A_WeaponReady(); + Wait; + Idle: + #### # 2 A_Overlay(-9999,"Dummy"); + CSWI ABCDE 15 A_Jump(32,"Twiddle"); + Goto Idle+1; + Twiddle: + #### # 2; + CSWT ABCDEFGHIJKLM 3; + CSWI A 3; + Goto Idle; + Fire: + #### # 2 + { + A_Overlay(-9999,"Null"); + A_PlaySound("bonesaw/spin",CHAN_WEAPON,Dampener.Active(self)?.1:1.,true); + invoker.special2 = 0; + } + CSWF ABCDEFGHIJKLMNO 1 + { + invoker.special2++; + A_WeaponOffset(0+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,32+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,WOF_INTERPOLATE); + } + CSWF PQRSTUVWX 1 + { + invoker.special2++; + A_WeaponOffset(0+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,32+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,WOF_INTERPOLATE); + A_Slice(); + } + Goto Hold; + Hold: + CSWH A 0 A_SoundVolume(CHAN_WEAPON,Dampener.Active(self)?.1:1.); + CSWH ABCDEFGHIJKLMNOPQR 1 + { + A_WeaponOffset(0+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,32+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,WOF_INTERPOLATE); + A_Slice(); + } + CSWH A 0 A_Refire("Hold"); + Goto Release; + Release: + CSWR A 0 A_PlaySound("bonesaw/spinend",CHAN_WEAPON,Dampener.Active(self)?.1:1.); + CSWR ABCDEFGHI 1 + { + A_WeaponOffset(0+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,32+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,WOF_INTERPOLATE); + invoker.special2--; + A_Slice(); + } + CSWR JKLMNOPQRSTUVWX 1 + { + A_WeaponOffset(0+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,32+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,WOF_INTERPOLATE); + invoker.special2--; + } + Goto Idle; + AltFire: + #### # 1 + { + A_Overlay(-9999,"Null"); + A_PlaySound("bonesaw/claw",CHAN_WEAPON,Dampener.Active(self)?.1:1.); + UTMainHandler.DoSwing(self,(FRandom[Bonesaw](-0.1,0.1),FRandom[Bonesaw](-0.2,-0.3)),4,0,8,SWING_Spring,5,0.7); + } + CSWA ABC 2; + CSWA D 0 + { + UTMainHandler.DoSwing(self,(FRandom[Bonesaw](-0.1,0.1),FRandom[Bonesaw](0.8,0.5)),2,0,8,SWING_Spring,2,1.2); + } + CSWA DEF 1; + CSWA G 0 A_Clamp(); + CSWA GH 1; + CSWA IJLMN 3; + CSWI A 3; + Goto Idle; + Deselect: + CSWD A 1 A_Overlay(-9999,"Null"); + CSWD ABCDEFGHI 1; + CSWD I 1 A_Lower(int.max); + Wait; } } diff --git a/zscript/gatling.zsc b/zscript/gatling.zsc index 0259a5b..fa3c965 100644 --- a/zscript/gatling.zsc +++ b/zscript/gatling.zsc @@ -35,7 +35,7 @@ Class SMiniShell : FastProjectile { Default { - Obituary "$O_EIGHTBALL"; + Obituary "$O_SMINI"; DamageType 'Shot'; DamageFunction 150; Radius 4;