Protomag(s) added.

This commit is contained in:
Marisa the Magician 2019-09-13 00:57:43 +02:00
commit 6950bb48a1
8 changed files with 944 additions and 8 deletions

View file

@ -219,16 +219,16 @@ A very rare prototype handgun. Due to the difficulty of its manufacture, it was
quickly discontinued and not many of these exist. You would have to be pretty
lucky to come across one.
Both of its fire modes work exactly like the Automag, although due to
internal differences, it fires much slower, but bullets come out at a much
higher velocity, resulting in increased damage.
The special trait of this weapon comes into play when you realize that there's
no need to reload. An experimental entanglement unit inside the gun's internal
mag locates spare ammunition carried by the user and automatically loads it.
Since there's no need to reload, pressing the reload button makes use of the
gun's weight to beat the crap out of your enemies up close.
Both of its fire modes work exactly like the Automag, although due to
internal differences, it's a bit weaker in terms of speed and damage. The fact
that it never needs to reload at least compensates for this.
Pressing the reload button makes use of the gun's weight to beat the crap out
of your enemies up close.
As an added bonus, you can press the zoom button to spin the gun. This doesn't
serve any purpose other than looking cool.

View file

@ -30,6 +30,8 @@ Doom Tournament (currently the devel branch is required).
- Restored flashlight
- Minigun (slot 0) (replaces chaingun)
- SMP 7243 (slot 0) (replaces bfg9000)
- Protomag (slot 2) (replaces pistol)
- Dual Protomags
- Quadshot (slot 3) (replaces shotguns)
- Backpack (replaces backpack, identical to Doom Tournament version)
- Unreal 1 HUD
@ -65,8 +67,6 @@ Doom Tournament (currently the devel branch is required).
- Razorclaw (slot 1) (replaces chainsaw)
- Teleport Capsules (slot 1)
- Protomag (slot 2) (replaces pistol)
- Dual Protomags
- Stunner (slot 4) (replaces chainsaw)
- Fireblaster (slot 5) (replaces rocket launcher)
- Flamethrower (slot 6) (replaces plasma rifle)

View file

@ -13,3 +13,412 @@ Model "Betamag"
ROTATING
FrameIndex AUTP A 1 0
}
Model "BCasing"
{
Path "models"
Model 0 "OldShell_d.3d"
Skin 0 "AutoHand1.png"
Scale 0.0264 -0.022 0.022
AngleOffset 90
RollOffset 180
ZOffset 1
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
USEROTATIONCENTER
Rotation-Center 0 0 1
FrameIndex PCAS A 0 0
}
Model "BCasing2"
{
Path "models"
Model 0 "OldShell_d.3d"
Skin 0 "Autom1.png"
Scale 0.0264 -0.022 0.022
AngleOffset 90
RollOffset 180
ZOffset 1
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
USEROTATIONCENTER
Rotation-Center 0 0 1
FrameIndex PCAS A 0 0
}
Model "Betamag"
{
Path "models"
Model 3 "Flat_d.3d"
Skin 3 "OldMuz.png"
AngleOffset 90
Offset 12 -30 -2.5
Scale 0.06 0.06 0.06
PitchOffset 0
FrameIndex AMZ1 A 3 0
PitchOffset 90
FrameIndex AMZ1 B 3 0
PitchOffset 180
FrameIndex AMZ1 C 3 0
PitchOffset 270
FrameIndex AMZ1 D 3 0
Offset 6 -30 -10
PitchOffset 0
FrameIndex AMZ2 A 3 0
PitchOffset 90
FrameIndex AMZ2 B 3 0
PitchOffset 180
FrameIndex AMZ2 C 3 0
PitchOffset 270
FrameIndex AMZ2 D 3 0
Offset -12 -30 -2.5
PitchOffset 0
FrameIndex AMZ3 A 3 0
PitchOffset 90
FrameIndex AMZ3 B 3 0
PitchOffset 180
FrameIndex AMZ3 C 3 0
PitchOffset 270
FrameIndex AMZ3 D 3 0
Offset -6 -30 -10
PitchOffset 0
FrameIndex AMZ4 A 3 0
PitchOffset 90
FrameIndex AMZ4 B 3 0
PitchOffset 180
FrameIndex AMZ4 C 3 0
PitchOffset 270
FrameIndex AMZ4 D 3 0
}
Model "Betamag"
{
Path "models"
Model 0 "OldAutoMag_d.3d"
SurfaceSkin 0 0 "AutoHand1.png"
SurfaceSkin 0 1 "Automa1.png"
Scale 0.12 -0.06 0.084
Offset 10.2 -17 -8.7
AngleOffset 90
RollOffset -90
// Down
FrameIndex AUTD A 0 0
FrameIndex AUTD B 0 1
FrameIndex AUTD C 0 2
FrameIndex AUTD D 0 3
FrameIndex AUTD E 0 4
FrameIndex AUTD F 0 5
FrameIndex AUTD G 0 6
// Select
FrameIndex AUTS A 0 6
FrameIndex AUTS B 0 7
FrameIndex AUTS C 0 8
FrameIndex AUTS D 0 9
FrameIndex AUTS E 0 10
FrameIndex AUTS F 0 11
FrameIndex AUTS G 0 12
FrameIndex AUTS H 0 13
FrameIndex AUTS I 0 14
FrameIndex AUTS J 0 15
FrameIndex AUTS K 0 16
// Idle
FrameIndex AUTI A 0 17
FrameIndex AUTI B 0 18
FrameIndex AUTI C 0 19
FrameIndex AUTI D 0 20
FrameIndex AUTI E 0 21
FrameIndex AUTI F 0 22
// Twiddle
FrameIndex AUTT A 0 23
FrameIndex AUTT B 0 24
FrameIndex AUTT C 0 25
FrameIndex AUTT D 0 26
FrameIndex AUTT E 0 27
FrameIndex AUTT F 0 28
FrameIndex AUTT G 0 29
FrameIndex AUTT H 0 30
FrameIndex AUTT I 0 31
FrameIndex AUTT J 0 32
FrameIndex AUTT K 0 33
FrameIndex AUTT L 0 34
FrameIndex AUTT M 0 35
FrameIndex AUTT N 0 36
FrameIndex AUTT O 0 37
FrameIndex AUTT P 0 38
FrameIndex AUTT Q 0 39
// Fire
FrameIndex AUTF A 0 40
FrameIndex AUTF B 0 41
FrameIndex AUTF C 0 42
FrameIndex AUTF D 0 43
FrameIndex AUTF E 0 44
FrameIndex AUTF F 0 45
FrameIndex AUTF G 0 46
FrameIndex AUTF H 0 47
FrameIndex AUTF I 0 48
FrameIndex AUTF J 0 49
// T1
FrameIndex AUTA A 0 50
FrameIndex AUTA B 0 51
FrameIndex AUTA C 0 52
FrameIndex AUTA D 0 53
FrameIndex AUTA E 0 54
// AltFire
FrameIndex AUTA F 0 55
FrameIndex AUTA G 0 56
FrameIndex AUTA H 0 57
FrameIndex AUTA I 0 58
FrameIndex AUTA J 0 59
FrameIndex AUTA K 0 60
FrameIndex AUTA L 0 61
// T2
FrameIndex AUTA M 0 62
FrameIndex AUTA N 0 63
FrameIndex AUTA O 0 64
FrameIndex AUTA P 0 65
FrameIndex AUTA Q 0 66
// Twirl
FrameIndex AUTR A 0 67
FrameIndex AUTR B 0 68
FrameIndex AUTR C 0 69
FrameIndex AUTR D 0 70
FrameIndex AUTR E 0 71
FrameIndex AUTR F 0 72
FrameIndex AUTR G 0 73
FrameIndex AUTR H 0 74
FrameIndex AUTR I 0 75
FrameIndex AUTR J 0 76
FrameIndex AUTR K 0 77
FrameIndex AUTR L 0 78
FrameIndex AUTR M 0 79
FrameIndex AUTR N 0 80
// TwirlLoop
FrameIndex AUTR O 0 81
FrameIndex AUTR P 0 82
FrameIndex AUTR Q 0 83
FrameIndex AUTR R 0 84
FrameIndex AUTR S 0 85
FrameIndex AUTR T 0 86
FrameIndex AUTR U 0 87
FrameIndex AUTR V 0 88
FrameIndex AUTR W 0 89
FrameIndex AUTR X 0 90
// TwirlEnd
FrameIndex AUTR Y 0 91
FrameIndex AUTR Z 0 92
FrameIndex AUTR [ 0 93
FrameIndex AUTR \ 0 94
FrameIndex AUTR ] 0 95
FrameIndex AUR2 A 0 96
FrameIndex AUR2 B 0 97
FrameIndex AUR2 C 0 98
FrameIndex AUR2 D 0 99
FrameIndex AUR2 E 0 100
FrameIndex AUR2 F 0 101
FrameIndex AUR2 G 0 102
FrameIndex AUR2 H 0 103
FrameIndex AUR2 I 0 104
FrameIndex AUR2 J 0 105
FrameIndex AUR2 K 0 106
// Whip
FrameIndex AUTW A 0 107
FrameIndex AUTW B 0 108
FrameIndex AUTW C 0 109
FrameIndex AUTW D 0 110
FrameIndex AUTW E 0 111
FrameIndex AUTW F 0 112
FrameIndex AUTW G 0 113
FrameIndex AUTW H 0 114
FrameIndex AUTW I 0 115
FrameIndex AUTW J 0 116
FrameIndex AUTW K 0 117
FrameIndex AUTW L 0 118
FrameIndex AUTW M 0 119
FrameIndex AUTW N 0 120
FrameIndex AUTW O 0 121
FrameIndex AUTW P 0 122
FrameIndex AUTW Q 0 123
FrameIndex AUTW R 0 124
FrameIndex AUTW S 0 125
FrameIndex AUTW T 0 126
FrameIndex AUTW U 0 127
FrameIndex AUTW V 0 128
FrameIndex AUTW W 0 129
FrameIndex AUTW X 0 130
FrameIndex AUTW Y 0 131
FrameIndex AUTW Z 0 132
FrameIndex AUTW [ 0 133
FrameIndex AUTW \ 0 134
}
Model "Betamag"
{
Path "models"
Model 2 "OldAutoMag_d.3d"
SurfaceSkin 2 0 "Autom1.png"
SurfaceSkin 2 1 "Automa1.png"
Scale 0.12 0.06 0.084
Offset -10.2 -17 -8.7
AngleOffset -90
RollOffset -90
// Down
FrameIndex 2UTD A 2 0
FrameIndex 2UTD B 2 1
FrameIndex 2UTD C 2 2
FrameIndex 2UTD D 2 3
FrameIndex 2UTD E 2 4
FrameIndex 2UTD F 2 5
FrameIndex 2UTD G 2 6
// Select
FrameIndex 2UTS A 2 6
FrameIndex 2UTS B 2 7
FrameIndex 2UTS C 2 8
FrameIndex 2UTS D 2 9
FrameIndex 2UTS E 2 10
FrameIndex 2UTS F 2 11
FrameIndex 2UTS G 2 12
FrameIndex 2UTS H 2 13
FrameIndex 2UTS I 2 14
FrameIndex 2UTS J 2 15
FrameIndex 2UTS K 2 16
// Idle
FrameIndex 2UTI A 2 17
FrameIndex 2UTI B 2 18
FrameIndex 2UTI C 2 19
FrameIndex 2UTI D 2 20
FrameIndex 2UTI E 2 21
FrameIndex 2UTI F 2 22
// Twiddle
FrameIndex 2UTT A 2 23
FrameIndex 2UTT B 2 24
FrameIndex 2UTT C 2 25
FrameIndex 2UTT D 2 26
FrameIndex 2UTT E 2 27
FrameIndex 2UTT F 2 28
FrameIndex 2UTT G 2 29
FrameIndex 2UTT H 2 30
FrameIndex 2UTT I 2 31
FrameIndex 2UTT J 2 32
FrameIndex 2UTT K 2 33
FrameIndex 2UTT L 2 34
FrameIndex 2UTT M 2 35
FrameIndex 2UTT N 2 36
FrameIndex 2UTT O 2 37
FrameIndex 2UTT P 2 38
FrameIndex 2UTT Q 2 39
// Fire
FrameIndex 2UTF A 2 40
FrameIndex 2UTF B 2 41
FrameIndex 2UTF C 2 42
FrameIndex 2UTF D 2 43
FrameIndex 2UTF E 2 44
FrameIndex 2UTF F 2 45
FrameIndex 2UTF G 2 46
FrameIndex 2UTF H 2 47
FrameIndex 2UTF I 2 48
FrameIndex 2UTF J 2 49
// T1
FrameIndex 2UTA A 2 50
FrameIndex 2UTA B 2 51
FrameIndex 2UTA C 2 52
FrameIndex 2UTA D 2 53
FrameIndex 2UTA E 2 54
// AltFire
FrameIndex 2UTA F 2 55
FrameIndex 2UTA G 2 56
FrameIndex 2UTA H 2 57
FrameIndex 2UTA I 2 58
FrameIndex 2UTA J 2 59
FrameIndex 2UTA K 2 60
FrameIndex 2UTA L 2 61
// T2
FrameIndex 2UTA M 2 62
FrameIndex 2UTA N 2 63
FrameIndex 2UTA O 2 64
FrameIndex 2UTA P 2 65
FrameIndex 2UTA Q 2 66
// Twirl
FrameIndex 2UTR A 2 67
FrameIndex 2UTR B 2 68
FrameIndex 2UTR C 2 69
FrameIndex 2UTR D 2 70
FrameIndex 2UTR E 2 71
FrameIndex 2UTR F 2 72
FrameIndex 2UTR G 2 73
FrameIndex 2UTR H 2 74
FrameIndex 2UTR I 2 75
FrameIndex 2UTR J 2 76
FrameIndex 2UTR K 2 77
FrameIndex 2UTR L 2 78
FrameIndex 2UTR M 2 79
FrameIndex 2UTR N 2 80
// TwirlLoop
FrameIndex 2UTR O 2 81
FrameIndex 2UTR P 2 82
FrameIndex 2UTR Q 2 83
FrameIndex 2UTR R 2 84
FrameIndex 2UTR S 2 85
FrameIndex 2UTR T 2 86
FrameIndex 2UTR U 2 87
FrameIndex 2UTR V 2 88
FrameIndex 2UTR W 2 89
FrameIndex 2UTR X 2 90
// TwirlEnd
FrameIndex 2UTR Y 2 91
FrameIndex 2UTR Z 2 92
FrameIndex 2UTR [ 2 93
FrameIndex 2UTR \ 2 94
FrameIndex 2UTR ] 2 95
FrameIndex 2UR2 A 2 96
FrameIndex 2UR2 B 2 97
FrameIndex 2UR2 C 2 98
FrameIndex 2UR2 D 2 99
FrameIndex 2UR2 E 2 100
FrameIndex 2UR2 F 2 101
FrameIndex 2UR2 G 2 102
FrameIndex 2UR2 H 2 103
FrameIndex 2UR2 I 2 104
FrameIndex 2UR2 J 2 105
FrameIndex 2UR2 K 2 106
// Whip
FrameIndex 2UTW A 2 107
FrameIndex 2UTW B 2 108
FrameIndex 2UTW C 2 109
FrameIndex 2UTW D 2 110
FrameIndex 2UTW E 2 111
FrameIndex 2UTW F 2 112
FrameIndex 2UTW G 2 113
FrameIndex 2UTW H 2 114
FrameIndex 2UTW I 2 115
FrameIndex 2UTW J 2 116
FrameIndex 2UTW K 2 117
FrameIndex 2UTW L 2 118
FrameIndex 2UTW M 2 119
FrameIndex 2UTW N 2 120
FrameIndex 2UTW O 2 121
FrameIndex 2UTW P 2 122
FrameIndex 2UTW Q 2 123
FrameIndex 2UTW R 2 124
FrameIndex 2UTW S 2 125
FrameIndex 2UTW T 2 126
FrameIndex 2UTW U 2 127
FrameIndex 2UTW V 2 128
FrameIndex 2UTW W 2 129
FrameIndex 2UTW X 2 130
FrameIndex 2UTW Y 2 131
FrameIndex 2UTW Z 2 132
FrameIndex 2UTW [ 2 133
FrameIndex 2UTW \ 2 134
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -249,6 +249,12 @@ quadshot/shell5 qshell5
quadshot/shell6 qshell6
$random quadshot/shell { quadshot/shell1 quadshot/shell2 quadshot/shell3 quadshot/shell4 quadshot/shell5 quadshot/shell6 }
betamag/select oldasel
betamag/fire oldmag
betamag/slide oldmage
betamag/whip oldawhip
betamag/hit oldahit
translator/event transa3
detector/start detact

View file

@ -1,5 +1,271 @@
Class BCasing : UTCasing
{
}
Class BCasing2 : UTCasing
{
}
Class Betamag : UnrealWeapon
{
bool SlaveActive, SlaveDown, SlaveAltFire, SlaveWhip, SlaveSpin;
int SlaveRefire;
double AltAccuracy;
override bool HandlePickup( Inventory item )
{
if ( sting_protomags && (item.GetClass() == GetClass()) )
{
SetTag(StringTable.Localize("$T_PROTOMAG2"));
return Super.HandlePickup(item);
}
return Super.HandlePickup(item);
}
override String PickupMessage()
{
if ( Owner ) return Super.PickupMessage();
return StringTable.Localize("$I_PROTOMAG2");
}
override Inventory CreateTossable( int amt )
{
Inventory inv = Super.CreateTossable(amt);
if ( inv )
{
SetTag(StringTable.Localize("$T_PROTOMAG"));
inv.SetTag(StringTable.Localize("$T_PROTOMAG"));
if ( Owner && (Owner.player.ReadyWeapon == self) )
{
// delete the slave overlay
PSprite psp;
for ( psp = Owner.player.psprites; psp; psp = psp.next )
{
if ( (psp.Caller == self) && ((psp.id == 2) || (psp.id == -9998)) ) psp.Destroy();
slaveactive = false;
slavedown = false;
}
}
}
return inv;
}
action void A_BetamagRefire( statelabel flash = null, bool slave = false )
{
Weapon weap = Weapon(invoker);
if ( !weap || !player ) return;
if ( invoker.altaccuracy < 0.1 ) invoker.altaccuracy += 0.015;
if ( slave )
{
if ( weap.Ammo1.Amount <= 0 )
{
invoker.slaverefire = 0;
return;
}
bool pending = (player.PendingWeapon != WP_NOCHANGE) && (player.WeaponState & WF_REFIRESWITCHOK);
if ( (player.cmd.buttons&BT_ATTACK) && !invoker.slavealtfire && !pending && (player.health > 0) )
{
invoker.slaverefire++;
if ( player.ReadyWeapon.CheckAmmo(Weapon.PrimaryFire,true) )
player.setpsprite(2,flash?ResolveState(flash):ResolveState("LeftHold"));
}
else if ( (player.cmd.buttons&BT_ALTATTACK) && invoker.slavealtfire && !pending && (player.health > 0) )
{
invoker.slaverefire++;
if ( player.ReadyWeapon.CheckAmmo(Weapon.AltFire,true) )
player.setpsprite(2,flash?ResolveState(flash):ResolveState("LeftAltHold"));
}
else
{
invoker.slaverefire = 0;
player.ReadyWeapon.CheckAmmo(invoker.slavealtfire?Weapon.AltFire:Weapon.PrimaryFire,true);
}
}
else
{
if ( weap.Ammo1.Amount <= 0 )
{
A_ClearRefire();
return;
}
A_Refire(flash);
}
}
action void A_LeftWeaponReady()
{
Weapon weap = Weapon(invoker);
if ( !weap || !player ) return;
if ( weap.Ammo1.Amount <= 0 ) return;
if ( player.cmd.buttons&BT_ATTACK && !player.ReadyWeapon.bAltFire )
{
invoker.slaverefire = 0;
invoker.slavealtfire = false;
player.setpsprite(2,ResolveState("LeftFire"));
}
else if ( player.cmd.buttons&BT_ALTATTACK && player.ReadyWeapon.bAltFire )
{
invoker.slaverefire = 0;
invoker.slavealtfire = true;
player.setpsprite(2,ResolveState("LeftAltFire"));
}
}
private action bool TryWhip( double angle )
{
FTranslatedLineTarget t;
double slope = AimLineAttack(angle,DEFMELEERANGE,t,0.,ALF_CHECK3D);
FLineTraceData d;
LineTrace(angle,DEFMELEERANGE,slope,0,player.viewheight,data:d);
if ( d.HitType != TRACE_HitNone )
{
if ( d.HitType == TRACE_HitActor )
{
int dmg = Random[Betamag](1,10)<<1;
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'Melee',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,35000);
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);
A_PlaySound("betamag/hit",CHAN_WEAPON);
A_AlertMonsters();
return true;
}
return false;
}
action void A_BetamagWhip()
{
invoker.FireEffect();
for ( int i=0; i<16; i++ ) if ( TryWhip(angle+i*(45./16)) || TryWhip(angle-i*(45./16)) ) return;
}
action void A_BetamagFire( bool alt = false, bool slave = false )
{
Weapon weap = Weapon(invoker);
if ( !weap ) return;
if ( weap.Ammo1.Amount <= 0 ) return;
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
invoker.FireEffect();
UTMainHandler.DoFlash(self,Color(32,255,128,0),1);
A_PlaySound("betamag/fire",slave?CHAN_6:CHAN_WEAPON,!Dampener.Active(self)?1.:.2);
if ( !Dampener.Active(self) ) A_AlertMonsters();
A_QuakeEx(2,2,2,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.08);
if ( slave )
{
if ( alt ) A_Overlay(-3,"LeftAltMuzzleFlash");
else A_Overlay(-3,"LeftMuzzleFlash");
A_OverlayFlags(-3,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
A_OverlayRenderstyle(-3,STYLE_Add);
UTMainHandler.DoSwing(self,(FRandom[Betamag](0.5,0.2),FRandom[Betamag](-0.3,0.2)),2,0,1,SWING_Spring,0,2);
}
else
{
if ( alt ) A_Overlay(-2,"AltMuzzleFlash");
else A_Overlay(-2,"MuzzleFlash");
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
A_OverlayRenderstyle(-2,STYLE_Add);
UTMainHandler.DoSwing(self,(FRandom[Betamag](-0.2,-0.5),FRandom[Betamag](-0.3,0.2)),2,0,1,SWING_Spring,0,2);
}
Vector3 x, y, z, x2, y2, z2;
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10.0*x);
int ydir = slave?-1:1;
if ( alt ) origin = level.Vec3Offset(origin,-z*2.5+ydir*y*1.5);
else origin = level.Vec3Offset(origin,-z*1.5+ydir*y*2.0);
double a = FRandom[Betamag](0,360), s = FRandom[Betamag](0,alt?invoker.altaccuracy:0.01);
[x2, y2, z2] = dt_CoordUtil.GetAxes(BulletSlope(),angle,roll);
Vector3 dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
FLineTraceData d;
LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
if ( d.HitType == TRACE_HitActor )
{
int dmg = 10;
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
double mm = 3000;
if ( FRandom[Betamag](0,1) < 0.2 ) mm *= 5;
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,mm);
if ( d.HitActor.bNOBLOOD )
{
let p = Spawn("BulletImpact",d.HitLocation);
p.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
p.pitch = asin(d.HitDir.z);
}
else
{
d.HitActor.TraceBleed(dmg,self);
d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg);
}
}
else if ( d.HitType != TRACE_HitNone )
{
Vector3 hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
let p = Spawn("BulletImpact",d.HitLocation+hitnormal*0.01);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
}
for ( int i=0; i<3; i++ )
{
let s = Spawn("UTViewSmoke",origin);
if ( alt ) UTViewSmoke(s).ofs = (10,ydir,-3);
else UTViewSmoke(s).ofs = (10,4*ydir,-1);
s.target = self;
s.alpha *= 0.5;
}
origin = level.Vec3Offset(origin,x*5.0+ydir*y*8.0-z*2.0);
let c = Spawn(slave?"BCasing2":"BCasing",origin);
c.vel = x*FRandom[Junk](-1.5,1.5)+y*ydir*FRandom[Junk](2,4)+z*FRandom[Junk](2,3);
}
override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )
{
if ( Amount > 1 ) return StringTable.Localize("$O_PROTOMAG2");
return StringTable.Localize("$O_PROTOMAG");
}
override void Travelled()
{
Super.Travelled();
slaveactive = false;
}
override void OwnerDied()
{
Super.OwnerDied();
slaverefire = 0;
}
override void Tick()
{
Super.Tick();
if ( sting_protomags && (MaxAmount <= 1) ) MaxAmount = 2;
else if ( !sting_protomags && (MaxAmount > 1) ) MaxAmount = 1;
if ( !Owner || sting_protomags || (Amount <= 1) ) return;
// no dual wielding
if ( Owner.player.ReadyWeapon == self )
{
// delete the slave overlay
PSprite psp;
for ( psp = Owner.player.psprites; psp; psp = psp.next )
{
if ( (psp.Caller == self) && ((psp.id == 2) || (psp.id == -9998)) ) psp.Destroy();
slaveactive = false;
slavedown = false;
}
}
Amount = 1;
}
Default
{
Tag "$T_PROTOMAG";
@ -17,6 +283,8 @@ Class Betamag : UnrealWeapon
Weapon.AmmoGive 20;
Weapon.Kickback 320;
UTWeapon.DropAmmo 10;
+WEAPON.AMMO_OPTIONAL;
+WEAPON.ALT_AMMO_OPTIONAL;
}
States
{
@ -25,5 +293,258 @@ Class Betamag : UnrealWeapon
Stop;
AUTP B -1;
Stop;
Select:
AUTS A 1 A_Raise(int.max);
Ready:
AUTS A 0
{
invoker.slavedown = false;
if ( !invoker.slaveactive && (CountInv("Betamag") > 1) )
player.setpsprite(2,ResolveState("LeftReady"));
}
AUTS ABCDEFGHIJK 2 A_WeaponReady(WRF_NOFIRE);
Idle:
AUTI A 0 A_Overlay(-9999,"Dummy");
AUTI ABCDEF 20;
AUTI A 0 A_Jump(50,"Twiddle");
Goto Idle+1;
LeftReady:
2UTS A 0
{
A_PlaySound("betamag/select",CHAN_6,!Dampener.Active(self)?1.:.1);
invoker.slaveactive = true;
}
2UTS ABCDEFGHIJK 2 A_JumpIf(invoker.slavedown,"LeftDeselect");
LeftIdle:
2UTI A 0 A_Overlay(-9998,"LeftDummy");
2UTI ABCDEF 20;
2UTI A 0 A_Jump(50,"LeftTwiddle");
Goto LeftIdle+1;
Twiddle:
AUTT A 0 { invoker.special1 = Random[Betamag](2,3); }
AUTT ABCDEFGHIJKLMNOPQ 3 A_SetTics(invoker.special1);
Goto Idle+1;
LeftTwiddle:
2UTT A 0 { invoker.special2 = Random[Betamag](2,3); }
2UTT ABCDEFGHIJKLMNOPQ 3 A_SetTics(invoker.special2);
Goto LeftIdle+1;
Dummy:
TNT1 A 1
{
A_WeaponReady(WRF_ALLOWRELOAD|WRF_ALLOWZOOM);
if ( !invoker.slaveactive && (CountInv("Betamag") > 1) )
player.setpsprite(2,ResolveState("LeftReady"));
}
Wait;
LeftDummy:
TNT1 A 1
{
if ( health <= 0 )
{
invoker.slaveactive = false;
player.setpsprite(2,ResolveState("LeftDeselect"));
}
else if ( invoker.slavedown ) player.setpsprite(2,ResolveState("LeftDeselect"));
else if ( invoker.slavewhip ) player.setpsprite(2,ResolveState("LeftReload"));
else if ( invoker.slavespin ) player.setpsprite(2,ResolveState("LeftZoom"));
else A_LeftWeaponReady();
}
Wait;
Fire:
AUTF A 2
{
A_Overlay(-9999,null);
return A_JumpIfNoAmmo("Reload");
}
AUTF B 2;
Hold:
AUTF C 2 A_BetamagFire();
AUTF DE 2;
AUTF F 0 A_PlaySound("betamag/slide",CHAN_ITEM,!Dampener.Active(self)?.3:.03);
AUTF FGHI 2;
AUTF J 0 A_BetamagRefire("Hold");
AUTF J 2;
AUTI A 0;
Goto Idle;
LeftFire:
#### # 10 A_Overlay(-9998,null);
2UTI A 0 A_BetamagRefire(1,true);
Goto LeftIdle;
2UTF AB 1;
LeftHold:
2UTF C 2 A_BetamagFire(false,true);
2UTF DE 2;
2UTF F 0 A_PlaySound("betamag/slide",CHAN_7,!Dampener.Active(self)?.3:.03);
2UTF FGHI 2;
2UTF J 0 A_BetamagRefire("LeftHold",true);
2UTF J 2;
2UTI A 0;
Goto LeftIdle;
AltFire:
AUTA A 0
{
invoker.altaccuracy = 0.08;
A_Overlay(-9999,null);
return A_JumpIfNoAmmo("Reload");
}
AUTA ABCDEFG 2;
AltHold:
AUTA H 2 A_BetamagFire(true);
AUTA I 2;
AUTA J 0 A_PlaySound("betamag/slide",CHAN_ITEM,!Dampener.Active(self)?.3:.03);
AUTA JKLM 2;
AUTA N 0 A_BetamagRefire("AltHold");
AltRelease:
AUTA NOPQ 2;
AUTI A 2;
Goto Idle;
LeftAltFire:
#### # 6 A_Overlay(-9998,null);
2UTI A 0 A_BetamagRefire(1,true);
Goto LeftIdle;
2UTA ABCDEFG 2;
LeftAltHold:
2UTA H 2 A_BetamagFire(true,true);
2UTA I 2;
2UTA J 0 A_PlaySound("betamag/slide",CHAN_7,!Dampener.Active(self)?.3:.03);
2UTA JKLM 2;
2UTA N 0 A_BetamagRefire("LeftAltHold",true);
2UTA NOPQ 2;
2UTI A 2;
Goto LeftIdle;
Reload:
AUTW A 0
{
A_Overlay(-9999,null);
invoker.slavewhip = true;
UTMainHandler.DoSwing(self,(FRandom[Betamag](-0.5,-0.4),FRandom[Betamag](0.2,0.3)),4,0,8,SWING_Spring,5);
}
AUTW ABCDE 2;
AUTW F 0
{
if ( self is 'UTPlayer' ) UTPlayer(self).PlayAttacking3();
A_PlaySound("betamag/whip",CHAN_ITEM);
UTMainHandler.DoSwing(self,(FRandom[Betamag](-0.3,-0.2),FRandom[Betamag](-0.8,-0.5)),2,0,8,SWING_Spring,2,0.5);
}
AUTW FGHIJ 2;
AUTW K 0
{
UTMainHandler.DoSwing(self,(FRandom[Betamag](0.2,0.3),FRandom[Betamag](0.8,0.5)),3,0.5,6,SWING_Spring,3,3);
}
AUTW KLM 1;
AUTW N 0 A_BetamagWhip();
AUTW NOPQR 1;
AUTW STUVWXYZ[\ 2;
Goto Idle;
LeftReload:
#### # 25
{
invoker.slavewhip = false;
A_Overlay(-9998,null);
}
LeftReloadHold:
2UTI A 0
{
if ( !(player.cmd.buttons&BT_RELOAD) ) return ResolveState("LeftIdle");
invoker.slavewhip = false;
A_Overlay(-9998,null);
UTMainHandler.DoSwing(self,(FRandom[Betamag](0.4,0.5),FRandom[Betamag](0.2,0.3)),4,0,8,SWING_Spring,5);
return ResolveState(null);
}
2UTW ABCDE 2;
2UTW F 0
{
if ( self is 'UTPlayer' ) UTPlayer(self).PlayAttacking3();
A_PlaySound("betamag/whip",CHAN_7);
UTMainHandler.DoSwing(self,(FRandom[Betamag](0.2,0.3),FRandom[Betamag](-0.8,-0.5)),2,0,8,SWING_Spring,2,0.5);
}
2UTW FGHIJ 2;
2UTW K 0
{
UTMainHandler.DoSwing(self,(FRandom[Betamag](-0.3,-0.2),FRandom[Betamag](0.8,0.5)),3,0.5,6,SWING_Spring,3,3);
}
2UTW KLM 1;
2UTW N 0 A_BetamagWhip();
2UTW NOPQR 1;
2UTW STUVWXYZ[\ 2;
2UTI A 0 A_JumpIf(player.cmd.buttons&BT_RELOAD,"LeftReloadHold");
Goto LeftIdle;
Zoom:
AUTR A 1
{
A_Overlay(-9999,null);
invoker.slavespin = true;
}
AUTR BCDEFGHIJKLMN 1;
ZoomLoop:
AUTR OPQRSTUVWX 1;
AUTR Y 0 A_JumpIf(player.cmd.buttons&BT_ZOOM,"ZoomLoop");
AUTR YZ[\] 1;
AUR2 ABCDEFGHIJK 1;
Goto Idle;
LeftZoom:
2UTR A 1
{
A_Overlay(-9998,null);
invoker.slavespin = false;
}
2UTR BCDEFGHIJKLMN 1;
LeftZoomLoop:
2UTR OPQRSTUVWX 1;
2UTR Y 0 A_JumpIf(player.cmd.buttons&BT_ZOOM,"LeftZoomLoop");
2UTR YZ[\] 1;
2UR2 ABCDEFGHIJK 1;
Goto LeftIdle;
Deselect:
AUTI A 1 { invoker.slavedown = true; }
AUTD A 0 A_Overlay(-9999,null);
AUTD A 0 A_JumpIf(invoker.slaveactive,"Deselect");
AUTD ABCDEFG 1;
AUTD G 1 A_Lower(int.max);
Wait;
LeftDeselect:
2UTD A 0
{
A_Overlay(-9998,null);
invoker.slaveactive = false;
}
2UTD ABCDEFG 1;
Stop;
MuzzleFlash:
AMZ1 # 2 Bright
{
let psp = player.FindPSprite(OverlayID());
psp.frame = Random[Betamag](0,3);
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
AltMuzzleFlash:
AMZ2 # 2 Bright
{
let psp = player.FindPSprite(OverlayID());
psp.frame = Random[Betamag](0,3);
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
LeftMuzzleFlash:
AMZ3 # 2 Bright
{
let psp = player.FindPSprite(OverlayID());
psp.frame = Random[Betamag](0,3);
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
LeftAltMuzzleFlash:
AMZ4 # 2 Bright
{
let psp = player.FindPSprite(OverlayID());
psp.frame = Random[Betamag](0,3);
let l = Spawn("EnforcerLight",pos);
l.target = self;
}
Stop;
}
}