Cock and ball torture (CBT), penis torture or dick torture is a sexual activity involving application of pain or constriction to the penis or testicles.

This commit is contained in:
Mari the Deer 2020-05-29 18:52:30 +02:00
commit 827aeed6c6
30 changed files with 774 additions and 11 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

View file

@ -1,2 +1,2 @@
[default]
SWWM_MODVER="\cxSWWM GZ\c- r274 (Fri 29 May 18:48:46 CEST 2020)";
SWWM_MODVER="\cxSWWM GZ\c- r275 (Fri 29 May 18:52:30 CEST 2020)";

View file

@ -11,3 +11,447 @@ Model "Wallbuster"
FrameIndex XZW1 A 0 0
}
Model "Wallbuster"
{
// muzzle flashes
Path "models/extra"
Model 3 "Flat_d.3d"
PitchOffset 90
// Buckshot XZWW
Scale 0.13 0.13 0.13
Skin 3 "ShotgMuz.png"
Offset 16 -60 -16
FrameIndex XZWW A 3 0
FrameIndex XZWW B 3 0
FrameIndex XZWW C 3 0
FrameIndex XZWW D 3 0
FrameIndex XZWW E 3 0
FrameIndex XZWW F 3 0
FrameIndex XZWW G 3 0
FrameIndex XZWW H 3 0
FrameIndex XZWW I 3 0
FrameIndex XZWW J 3 0
FrameIndex XZWW K 3 0
FrameIndex XZWW L 3 0
FrameIndex XZWW M 3 0
FrameIndex XZWW N 3 0
FrameIndex XZWW O 3 0
FrameIndex XZWW P 3 0
FrameIndex XZWW Q 3 0
FrameIndex XZWW R 3 0
FrameIndex XZWW S 3 0
FrameIndex XZWW T 3 0
FrameIndex XZWW U 3 0
FrameIndex XZWW V 3 0
FrameIndex XZWW W 3 0
FrameIndex XZWW X 3 0
FrameIndex XZWW Y 3 0
// Slug XZWX
Scale 0.08 0.08 0.08
Skin 3 "ShotgMuz.png"
// Kinylum XZWY
Scale 0.13 0.13 0.13
Skin 2 "ShotgMuzSalt.png"
// Ball XZWZ
Scale 0.06 0.06 0.06
Skin 2 "ShotgMuz.png"
}
Model "Wallbuster"
{
// shells
Path "models"
Model 2 "Wallbuster1st_d.3d"
AngleOffset -93
Offset 0 2 0
Scale -0.005 0.0025 0.005
//// Shell0
SurfaceSkin 2 5 "Shell_Normal.png"
// Detach
FrameIndex XZWA E 2 91
FrameIndex XZWA F 2 92
FrameIndex XZWA G 2 93
FrameIndex XZWA H 2 94
FrameIndex XZWA I 2 95
FrameIndex XZWA J 2 96
FrameIndex XZWA K 2 97
FrameIndex XZWA L 2 98
FrameIndex XZWA M 2 99
FrameIndex XZWA N 2 100
// Attach
FrameIndex XZWA O 2 116
FrameIndex XZWA P 2 117
FrameIndex XZWA Q 2 118
FrameIndex XZWA R 2 119
FrameIndex XZWA S 2 120
FrameIndex XZWA T 2 121
FrameIndex XZWA U 2 122
FrameIndex XZWA V 2 123
FrameIndex XZWA W 2 124
FrameIndex XZWA X 2 125
FrameIndex XZWA Y 2 126
FrameIndex XZWA Z 2 127
FrameIndex XZWB A 2 128
FrameIndex XZWB B 2 129
//// Shell1
SurfaceSkin 2 5 ""
SurfaceSkin 2 6 "Shell_Normal.png"
// Detach
FrameIndex XZWB C 2 91
FrameIndex XZWB D 2 92
FrameIndex XZWB E 2 93
FrameIndex XZWB F 2 94
FrameIndex XZWB G 2 95
FrameIndex XZWB H 2 96
FrameIndex XZWB I 2 97
FrameIndex XZWB J 2 98
FrameIndex XZWB K 2 99
FrameIndex XZWB L 2 100
// Attach
FrameIndex XZWB M 2 116
FrameIndex XZWB N 2 117
FrameIndex XZWB O 2 118
FrameIndex XZWB P 2 119
FrameIndex XZWB Q 2 120
FrameIndex XZWB R 2 121
FrameIndex XZWB S 2 122
FrameIndex XZWB T 2 123
FrameIndex XZWB U 2 124
FrameIndex XZWB V 2 125
FrameIndex XZWB W 2 126
FrameIndex XZWB X 2 127
FrameIndex XZWB Y 2 128
FrameIndex XZWB Z 2 129
//// Shell2
SurfaceSkin 2 6 ""
SurfaceSkin 2 7 "Shell_Normal.png"
// Detach
FrameIndex XZWC A 2 91
FrameIndex XZWC B 2 92
FrameIndex XZWC C 2 93
FrameIndex XZWC D 2 94
FrameIndex XZWC E 2 95
FrameIndex XZWC F 2 96
FrameIndex XZWC G 2 97
FrameIndex XZWC H 2 98
FrameIndex XZWC I 2 99
FrameIndex XZWC J 2 100
// Attach
FrameIndex XZWC K 2 116
FrameIndex XZWC L 2 117
FrameIndex XZWC M 2 118
FrameIndex XZWC N 2 119
FrameIndex XZWC O 2 120
FrameIndex XZWC P 2 121
FrameIndex XZWC Q 2 122
FrameIndex XZWC R 2 123
FrameIndex XZWC S 2 124
FrameIndex XZWC T 2 125
FrameIndex XZWC U 2 126
FrameIndex XZWC V 2 127
FrameIndex XZWC W 2 128
FrameIndex XZWC X 2 129
//// Shell3
SurfaceSkin 2 7 ""
SurfaceSkin 2 8 "Shell_Normal.png"
// Detach
FrameIndex XZWC Y 2 91
FrameIndex XZWC Z 2 92
FrameIndex XZWD A 2 93
FrameIndex XZWD B 2 94
FrameIndex XZWD C 2 95
FrameIndex XZWD D 2 96
FrameIndex XZWD E 2 97
FrameIndex XZWD F 2 98
FrameIndex XZWD G 2 99
FrameIndex XZWD H 2 100
// Attach
FrameIndex XZWD I 2 116
FrameIndex XZWD J 2 117
FrameIndex XZWD K 2 118
FrameIndex XZWD L 2 119
FrameIndex XZWD M 2 120
FrameIndex XZWD N 2 121
FrameIndex XZWD O 2 122
FrameIndex XZWD P 2 123
FrameIndex XZWD Q 2 124
FrameIndex XZWD R 2 125
FrameIndex XZWD S 2 126
FrameIndex XZWD T 2 127
FrameIndex XZWD U 2 128
FrameIndex XZWD V 2 129
//// Shell4
SurfaceSkin 2 8 ""
SurfaceSkin 2 9 "Shell_Normal.png"
// Detach
FrameIndex XZWD W 2 91
FrameIndex XZWD X 2 92
FrameIndex XZWD Y 2 93
FrameIndex XZWD Z 2 94
FrameIndex XZWE A 2 95
FrameIndex XZWE B 2 96
FrameIndex XZWE C 2 97
FrameIndex XZWE D 2 98
FrameIndex XZWE E 2 99
FrameIndex XZWE F 2 100
// Attach
FrameIndex XZWE G 2 116
FrameIndex XZWE H 2 117
FrameIndex XZWE I 2 118
FrameIndex XZWE J 2 119
FrameIndex XZWE K 2 120
FrameIndex XZWE L 2 121
FrameIndex XZWE M 2 122
FrameIndex XZWE N 2 123
FrameIndex XZWE O 2 124
FrameIndex XZWE P 2 125
FrameIndex XZWE Q 2 126
FrameIndex XZWE R 2 127
FrameIndex XZWE S 2 128
FrameIndex XZWE T 2 129
}
Model "Wallbuster"
{
// main
Path "models"
Model 1 "Wallbuster1st_d.3d"
SurfaceSkin 1 0 "DemoTags.png"
SurfaceSkin 1 1 "DemoArms.png"
SurfaceSkin 1 2 "DemoSoft.png"
SurfaceSkin 1 3 "Wallbuster.png"
AngleOffset -93
Offset 0 2 0
Scale -0.005 0.0025 0.005
// Still/Deselect
FrameIndex XZW2 A 1 0
FrameIndex XZW2 B 1 1
FrameIndex XZW2 C 1 2
FrameIndex XZW2 D 1 3
FrameIndex XZW2 E 1 4
FrameIndex XZW2 F 1 5
FrameIndex XZW2 G 1 6 // Select
FrameIndex XZW2 H 1 7
FrameIndex XZW2 I 1 8
FrameIndex XZW2 J 1 9
FrameIndex XZW2 K 1 10
FrameIndex XZW2 L 1 11
FrameIndex XZW2 M 1 12
FrameIndex XZW2 N 1 13
FrameIndex XZW2 O 1 14
FrameIndex XZW2 P 1 15
// Fire One
FrameIndex XZW2 Q 1 17
FrameIndex XZW2 R 1 18
FrameIndex XZW2 S 1 19
FrameIndex XZW2 T 1 20
FrameIndex XZW2 U 1 21
FrameIndex XZW2 V 1 22
FrameIndex XZW2 W 1 23
FrameIndex XZW2 X 1 24
// Spin One
FrameIndex XZW2 Y 1 26
FrameIndex XZW2 Z 1 27
FrameIndex XZW3 A 1 28
FrameIndex XZW3 B 1 29
// Fire Five
FrameIndex XZW3 C 1 31
FrameIndex XZW3 D 1 32
FrameIndex XZW3 E 1 33
FrameIndex XZW3 F 1 34
FrameIndex XZW3 G 1 35
FrameIndex XZW3 H 1 36
FrameIndex XZW3 I 1 37
FrameIndex XZW3 J 1 38
FrameIndex XZW3 K 1 39
// Spin Five
FrameIndex XZW3 L 1 41
FrameIndex XZW3 M 1 42
FrameIndex XZW3 N 1 43
FrameIndex XZW3 O 1 44
FrameIndex XZW3 P 1 45
FrameIndex XZW3 Q 1 46
FrameIndex XZW3 R 1 47
// Fire Twenty-Five
FrameIndex XZW3 S 1 49
FrameIndex XZW3 T 1 50
FrameIndex XZW3 U 1 51
FrameIndex XZW3 V 1 52
FrameIndex XZW3 W 1 53
FrameIndex XZW3 X 1 54
FrameIndex XZW3 Y 1 55
FrameIndex XZW3 Z 1 56
FrameIndex XZW4 A 1 57
FrameIndex XZW4 B 1 58
FrameIndex XZW4 C 1 59
// Unlock
FrameIndex XZW4 D 1 61
FrameIndex XZW4 E 1 62
FrameIndex XZW4 F 1 63
FrameIndex XZW4 G 1 64
FrameIndex XZW4 H 1 65
FrameIndex XZW4 I 1 66
FrameIndex XZW4 J 1 67
FrameIndex XZW4 K 1 68
FrameIndex XZW4 L 1 69 // LeverSnd
FrameIndex XZW4 M 1 70
FrameIndex XZW4 N 1 71
FrameIndex XZW4 O 1 72
FrameIndex XZW4 P 1 73
FrameIndex XZW4 Q 1 74
FrameIndex XZW4 R 1 75
FrameIndex XZW4 S 1 76
FrameIndex XZW4 T 1 77
FrameIndex XZW4 U 1 78
FrameIndex XZW4 V 1 79
FrameIndex XZW4 W 1 80 // StillFrm
// Detach
FrameIndex XZW4 X 1 81
FrameIndex XZW4 Y 1 82
FrameIndex XZW4 Z 1 83
FrameIndex XZW5 A 1 84
FrameIndex XZW5 B 1 85
FrameIndex XZW5 C 1 86
FrameIndex XZW5 D 1 87
FrameIndex XZW5 E 1 88
FrameIndex XZW5 F 1 89
FrameIndex XZW5 G 1 90 // DetachSnd
FrameIndex XZW5 H 1 91 // StartDetachOverlays
FrameIndex XZW5 I 1 92
FrameIndex XZW5 J 1 93
FrameIndex XZW5 K 1 94
FrameIndex XZW5 L 1 95
FrameIndex XZW5 M 1 96
FrameIndex XZW5 N 1 97
FrameIndex XZW5 O 1 98
FrameIndex XZW5 P 1 99
FrameIndex XZW5 Q 1 100
FrameIndex XZW5 R 1 101 // DropShells
FrameIndex XZW5 S 1 102
FrameIndex XZW5 T 1 103
FrameIndex XZW5 U 1 104
FrameIndex XZW5 V 1 105 // LoadShell
FrameIndex XZW5 W 1 106
FrameIndex XZW5 X 1 107 // LoadShell
// Attach
FrameIndex XZW5 Y 1 108
FrameIndex XZW5 Z 1 109 // LoadShell
FrameIndex XZW6 A 1 110
FrameIndex XZW6 B 1 111 // LoadShell
FrameIndex XZW6 C 1 112
FrameIndex XZW6 D 1 113 // LoadShell
FrameIndex XZW6 E 1 114
FrameIndex XZW6 F 1 115
FrameIndex XZW6 G 1 116 // StartAttachOverlays
FrameIndex XZW6 H 1 117
FrameIndex XZW6 I 1 118
FrameIndex XZW6 J 1 119
FrameIndex XZW6 K 1 120
FrameIndex XZW6 L 1 121
FrameIndex XZW6 M 1 122
FrameIndex XZW6 N 1 123
FrameIndex XZW6 O 1 124
FrameIndex XZW6 P 1 125
FrameIndex XZW6 Q 1 126 // AttachSnd
FrameIndex XZW6 R 1 127
FrameIndex XZW6 S 1 128
FrameIndex XZW6 T 1 129
FrameIndex XZW6 U 1 130
FrameIndex XZW6 V 1 131
FrameIndex XZW6 W 1 132
FrameIndex XZW6 X 1 133
FrameIndex XZW6 Y 1 134
FrameIndex XZW6 Z 1 135
FrameIndex XZW7 A 1 136
FrameIndex XZW7 B 1 137
FrameIndex XZW7 C 1 138
// Attach + Spin
FrameIndex XZW7 D 1 139
FrameIndex XZW7 E 1 140 // LoadShell
FrameIndex XZW7 F 1 141
FrameIndex XZW7 G 1 142 // LoadShell
FrameIndex XZW7 H 1 143
FrameIndex XZW7 I 1 144 // LoadShell
FrameIndex XZW7 J 1 145
FrameIndex XZW7 K 1 146
FrameIndex XZW7 L 1 147 // StartAttachOverlays
FrameIndex XZW7 M 1 148
FrameIndex XZW7 N 1 149
FrameIndex XZW7 O 1 150
FrameIndex XZW7 P 1 151
FrameIndex XZW7 Q 1 152
FrameIndex XZW7 R 1 153
FrameIndex XZW7 S 1 154
FrameIndex XZW7 T 1 155
FrameIndex XZW7 U 1 156
FrameIndex XZW7 V 1 157
FrameIndex XZW7 W 1 158 // AttachSnd
FrameIndex XZW7 X 1 159
FrameIndex XZW7 Y 1 160
FrameIndex XZW7 Z 1 161
FrameIndex XZW8 A 1 162
FrameIndex XZW8 B 1 163
FrameIndex XZW8 C 1 164
FrameIndex XZW8 D 1 165 // Speen
FrameIndex XZW8 E 1 166
FrameIndex XZW8 F 1 167
FrameIndex XZW8 G 1 168
FrameIndex XZW8 H 1 169
FrameIndex XZW8 I 1 170
FrameIndex XZW8 J 1 171
FrameIndex XZW8 K 1 172
FrameIndex XZW8 L 1 173
// Lock
FrameIndex XZW8 M 1 174 // StillFrm
FrameIndex XZW8 N 1 175
FrameIndex XZW8 O 1 176
FrameIndex XZW8 P 1 177
FrameIndex XZW8 Q 1 178
FrameIndex XZW8 R 1 179
FrameIndex XZW8 S 1 180
FrameIndex XZW8 T 1 181 // LeverSnd
FrameIndex XZW8 U 1 182
FrameIndex XZW8 V 1 183
FrameIndex XZW8 W 1 184
FrameIndex XZW8 X 1 185
FrameIndex XZW8 Y 1 186
FrameIndex XZW8 Z 1 187
FrameIndex XZW9 A 1 188
FrameIndex XZW9 B 1 189
FrameIndex XZW9 C 1 190
FrameIndex XZW9 D 1 191
FrameIndex XZW9 E 1 192
FrameIndex XZW9 F 1 193
// Melee
FrameIndex XZW9 G 1 195
FrameIndex XZW9 H 1 196
FrameIndex XZW9 I 1 197
FrameIndex XZW9 J 1 198
FrameIndex XZW9 K 1 199
FrameIndex XZW9 L 1 200
FrameIndex XZW9 M 1 201
FrameIndex XZW9 N 1 202
FrameIndex XZW9 O 1 203 // Impact
FrameIndex XZW9 P 1 204
FrameIndex XZW9 Q 1 205
FrameIndex XZW9 R 1 206
FrameIndex XZW9 S 1 207
FrameIndex XZW9 T 1 208
FrameIndex XZW9 U 1 209
FrameIndex XZW9 V 1 210
FrameIndex XZW9 W 1 211
FrameIndex XZW9 X 1 212
FrameIndex XZW9 Y 1 213
FrameIndex XZW9 Z 1 214
FrameIndex XZWA A 1 215
FrameIndex XZWA B 1 216
FrameIndex XZWA C 1 217
FrameIndex XZWA D 1 218
}

View file

@ -568,6 +568,24 @@ spreadgun/goldexpl1 sounds/spreadgun/spread_goldexp1.ogg
spreadgun/goldexpl2 sounds/spreadgun/spread_goldexp2.ogg
$random spreadgun/goldexpl { spreadgun/goldexpl1 spreadgun/goldexpl2 }
wallbuster/select sounds/wallbuster/cbt_select.ogg
wallbuster/deselect sounds/wallbuster/cbt_deselect.ogg
wallbuster/dryfire sounds/wallbuster/cbt_dryfire.ogg
wallbuster/spin sounds/wallbuster/cbt_spinone.ogg
wallbuster/spinbig sounds/wallbuster/cbt_spinbig.ogg
wallbuster/unlock sounds/wallbuster/cbt_leverpull.ogg
wallbuster/lock sounds/wallbuster/cbt_leverpush.ogg
wallbuster/meleestart sounds/wallbuster/cbt_lower.ogg
wallbuster/meleeend sounds/wallbuster/cbt_raise.ogg
wallbuster/detach sounds/wallbuster/cbt_unload.ogg
wallbuster/attach sounds/wallbuster/cbt_load.ogg
wallbuster/handspin sounds/wallbuster/cbt_handspin.ogg
wallbuster/load1 sounds/wallbuster/cbt_shellin1.ogg
wallbuster/load2 sounds/wallbuster/cbt_shellin2.ogg
wallbuster/load3 sounds/wallbuster/cbt_shellin3.ogg
wallbuster/load4 sounds/wallbuster/cbt_shellin4.ogg
$random wallbuster/load { wallbuster/load1 wallbuster/load2 wallbuster/load3 wallbuster/load4 }
eviscerator/select sounds/eviscerator/visc_select.ogg
eviscerator/deselect sounds/eviscerator/visc_deselect.ogg
eviscerator/load sounds/eviscerator/visc_cycle.ogg

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -10,6 +10,110 @@ Class Wallbuster : SWWMWeapon
Class<Ammo> loaded[25];
bool fired[25];
int rotation[6];
bool initialized;
Array<int> reloadqueue;
transient bool waitreload;
int whichspin;
transient CVar cbtmuffler;
transient ui TextureID WeaponBox, AmmoIcon[4], LoadIcon[4], UsedIcon[4], EmptyIcon;
transient ui Font TewiFont;
override void DrawWeapon( double TicFrac, double bx, double by, Vector2 hs, Vector2 ss )
{
static const Class<Ammo> types[] = {"RedShell","GreenShell","BlueShell","PurpleShell"};
/*
(Layout of indices)
0
4 1
3 2
L 9
K M 8 5
O N 7 6
H D
G I C E
F J B A
*/
static const int barrelposx[] =
{
29,24,26,32,34,
10,12,18,20,15,
17,23,25,20,15,
41,43,38,33,35,
48,43,38,40,46
};
static const int barrelposy[] =
{
46,42,36,36,42,
31,25,25,31,35,
8, 8,14,18,14,
8,14,18,14, 8,
31,35,31,25,25
};
if ( !TewiFont ) TewiFont = Font.GetFont('TewiShaded');
if ( !WeaponBox )
{
WeaponBox = TexMan.CheckForTexture("graphics/HUD/WallbusterDisplay.png",TexMan.Type_Any);
AmmoIcon[0] = TexMan.CheckForTexture("graphics/HUD/RedShell.png",TexMan.Type_Any);
AmmoIcon[1] = TexMan.CheckForTexture("graphics/HUD/GreenShell.png",TexMan.Type_Any);
AmmoIcon[2] = TexMan.CheckForTexture("graphics/HUD/BlueShell.png",TexMan.Type_Any);
AmmoIcon[3] = TexMan.CheckForTexture("graphics/HUD/PurpleShell.png",TexMan.Type_Any);
LoadIcon[0] = TexMan.CheckForTexture("graphics/HUD/WallbusterRed.png",TexMan.Type_Any);
LoadIcon[1] = TexMan.CheckForTexture("graphics/HUD/WallbusterGreen.png",TexMan.Type_Any);
LoadIcon[2] = TexMan.CheckForTexture("graphics/HUD/WallbusterBlue.png",TexMan.Type_Any);
LoadIcon[3] = TexMan.CheckForTexture("graphics/HUD/WallbusterPurple.png",TexMan.Type_Any);
UsedIcon[0] = TexMan.CheckForTexture("graphics/HUD/WallbusterRedUsed.png",TexMan.Type_Any);
UsedIcon[1] = TexMan.CheckForTexture("graphics/HUD/WallbusterGreenUsed.png",TexMan.Type_Any);
UsedIcon[2] = TexMan.CheckForTexture("graphics/HUD/WallbusterBlueUsed.png",TexMan.Type_Any);
UsedIcon[3] = TexMan.CheckForTexture("graphics/HUD/WallbusterPurpleUsed.png",TexMan.Type_Any);
EmptyIcon = TexMan.CheckForTexture("graphics/HUD/WallbusterEmpty.png",TexMan.Type_Any);
}
Screen.DrawTexture(WeaponBox,false,bx-54,by-72,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
int ox = 6;
int oy = 60;
for ( int i=0; i<4; i++ )
{
Screen.DrawTexture(AmmoIcon[i],false,bx-ox,by-oy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
String astr = String.Format("%3d",Owner.CountInv(types[i]));
Screen.DrawText(TewiFont,Font.CR_FIRE,bx-ox-(TewiFont.StringWidth(astr)+1),by-oy-2,astr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
oy += 10;
if ( i == 1 )
{
oy = 60;
ox = 33;
}
}
// and here's the big clusterdick
for ( int i=0; i<25; i++ )
{
int idx = i;
int group = idx/5;
// shift based on group rotation
int gidx = i%5;
gidx = (gidx-rotation[group]);
while ( gidx < 0 ) gidx += 5;
idx = gidx+group*5;
// shift based on full rotation
idx = (idx-rotation[5]*5);
while ( idx < 0 ) idx += 25;
if ( !loaded[i] )
{
Screen.DrawTexture(EmptyIcon,false,bx-barrelposx[idx],by-barrelposy[idx],DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
continue;
}
int which = 0;
for ( int j=0; j<4; j++ )
{
if ( !(loaded[i] is types[j]) ) continue;
which = j;
break;
}
Screen.DrawTexture(fired[i]?UsedIcon[which]:LoadIcon[which],false,bx-barrelposx[idx],by-barrelposy[idx],DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
}
override bool UsesAmmo( Class<Ammo> kind )
{
@ -17,21 +121,130 @@ Class Wallbuster : SWWMWeapon
for ( int i=0; i<4; i++ ) if ( kind is types[i] ) return true;
return false;
}
// leave these while it's still unimplemented
override bool ReportHUDAmmo()
{
static const Class<Ammo> types[] = {"RedShell","GreenShell","BlueShell","PurpleShell"};
for ( int i=0; i<4; i++ ) if ( Owner.CountInv(types[i]) > 0 ) return true;
for ( int i=0; i<25; i++ ) if ( loaded[i] && !fired[i] ) return true;
return false;
}
override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount )
{
static const Class<Ammo> types[] = {"RedShell","GreenShell","BlueShell","PurpleShell"};
if ( (firemode == PrimaryFire) || (firemode == AltFire) )
{
for ( int i=0; i<4; i++ ) if ( Owner.CountInv(types[i]) > 0 ) return true;
for ( int i=0; i<25; i++ ) if ( loaded[i] && !fired[i] ) return true;
return false;
}
return Super.CheckAmmo(firemode,autoswitch,requireammo,ammocount);
}
bool CanReload()
{
static const Class<Ammo> types[] = {"RedShell","GreenShell","BlueShell","PurpleShell"};
for ( int i=0; i<4; i++ ) if ( Owner.CountInv(types[i]) > 0 ) return true;
return false;
}
override void AttachToOwner( Actor other )
{
Super.AttachToOwner(other);
if ( other.player == players[consoleplayer] )
Console.Printf("\cgWALLBUSTER NOT IMPLEMENTED\c-");
if ( !initialized )
{
// first wallbuster is fully loaded
initialized = true;
for ( int i=0; i<25; i++ )
loaded[i] = "RedShell";
for ( int i=0; i<25; i++ )
fired[i] = false;
}
}
action void A_FireShells( int num = 1 )
{
static const Class<Ammo> types[] = {"RedShell","GreenShell","BlueShell","PurpleShell"};
static const statelabel flashes[] = {"FlashRed","FlashGreen","FlashBlue","FlashPurple"};
static const String sounds[] = {"spreadgun/redfire","spreadgun/greenfire","spreadgun/bluefire","spreadgun/purplefire"};
static const Color cols[] = {Color(40,255,192,64),Color(36,255,192,80),Color(48,32,176,255),Color(24,255,224,96)};
// speen
if ( num == 1 ) invoker.whichspin = 1;
else if ( num == 5 ) invoker.whichspin = 2;
else invoker.whichspin = 0;
// first pass, count fired rounds
int howmany = 0;
for ( int i=0; i<num; i++ )
{
int idx = i;
// shift based on full rotation
idx = (idx+invoker.rotation[5]*5);
while ( idx > 24 ) idx -= 25;
int group = idx/5;
// shift based on group rotation
int gidx = i%5;
gidx = (gidx+invoker.rotation[group]);
while ( gidx > 4 ) gidx -= 5;
idx = gidx+group*5;
if ( !invoker.loaded[idx] || invoker.fired[idx] ) continue;
howmany++;
}
if ( howmany <= 0 )
{
A_StartSound("wallbuster/dryfire",CHAN_WEAPON,CHANF_OVERLAP);
player.SetPsprite(PSP_WEAPON,ResolveState("DryFire"));
return;
}
Vector3 x, y, z;
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
if ( !invoker.cbtmuffler ) invoker.cbtmuffler = CVar.GetCVar('swwm_earbuster',players[consoleplayer]);
// second pass, actually fire them
for ( int i=0; i<num; i++ )
{
int idx = i;
// shift based on full rotation
idx = (idx+invoker.rotation[5]*5);
while ( idx > 24 ) idx -= 25;
int group = idx/5;
// shift based on group rotation
int gidx = i%5;
gidx = (gidx+invoker.rotation[group]);
while ( gidx > 4 ) gidx -= 5;
idx = gidx+group*5;
if ( !invoker.loaded[idx] || invoker.fired[idx] ) continue;
int which = 0;
for ( int j=0; j<4; j++ )
{
if ( !(invoker.loaded[i] is types[j]) ) continue;
which = j;
break;
}
double rfact = invoker.cbtmuffler.GetBool()?.85:.65;
A_StartSound(sounds[which],CHAN_WEAPON,CHANF_OVERLAP,1./(howmany**rfact),.6-howmany*.004,1.-howmany*.012);
invoker.fired[idx] = true;
}
if ( howmany < 3 ) player.SetPsprite(PSP_WEAPON,ResolveState("FireOne"));
else if ( howmany < 15 ) player.SetPsprite(PSP_WEAPON,ResolveState("FireFive"));
else player.SetPsprite(PSP_WEAPON,ResolveState("FireTwentyFive"));
int qk = min(9,1+howmany/5);
int ql = min(25,6+howmany/2);
A_QuakeEx(qk,qk,qk,ql,0,8,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:qk*.15);
A_ZoomFactor(1.+qk*.04,ZOOM_INSTANT);
A_ZoomFactor(1.);
}
action void A_SpinOne()
{
A_StartSound("wallbuster/spin",CHAN_WEAPON,CHANF_OVERLAP);
invoker.rotation[invoker.rotation[5]]++;
while ( invoker.rotation[invoker.rotation[5]] > 4 ) invoker.rotation[invoker.rotation[5]] -= 5;
}
action void A_SpinBig()
{
A_StartSound("wallbuster/spinbig",CHAN_WEAPON,CHANF_OVERLAP);
invoker.rotation[5]++;
while ( invoker.rotation[5] > 4 ) invoker.rotation[5] -= 5;
}
action void A_HandSpin()
{
A_StartSound("wallbuster/handspin",CHAN_WEAPON,CHANF_OVERLAP);
invoker.rotation[5]--;
while ( invoker.rotation[5] < 0 ) invoker.rotation[5] += 5;
}
Default
@ -41,8 +254,11 @@ Class Wallbuster : SWWMWeapon
Obituary "$O_WALLBUSTER";
Weapon.SlotNumber 4;
Weapon.SelectionOrder 2200;
Weapon.UpSound "wallbuster/select";
Weapon.AmmoType1 "RedShell";
Weapon.AmmoGive1 25;
Stamina 35000;
+WEAPON.NO_AUTO_SWITCH;
+SWWMWEAPON.NOFIRSTGIVE;
}
States
{
@ -50,20 +266,105 @@ Class Wallbuster : SWWMWeapon
XZW1 A -1;
Stop;
Select:
TNT1 A 1
XZW2 G 1
{
Console.Printf("\cgWALLBUSTER NOT IMPLEMENTED\c-");
A_FullRaise();
Console.Printf("\cgWALLBUSTER NOT FULLY IMPLEMENTED\c-");
}
XZW2 HIJKLMNOP 2;
Goto Ready;
Ready:
TNT1 A 1 A_WeaponReady();
XZW2 A 1
{
int flg = WRF_ALLOWUSER1;
if ( invoker.CheckAmmo(PrimaryFire,false) ) flg |= WRF_ALLOWZOOM;
if ( invoker.CanReload() ) flg |= WRF_ALLOWRELOAD;
A_WeaponReady(flg);
if ( player.cmd.buttons&(BT_ATTACK|BT_ALTATTACK|BT_ZOOM) )
invoker.CheckAmmo(EitherFire,true);
}
Wait;
Fire:
TNT1 A 1;
XZW2 A 0 A_FireShells(1);
Goto FireOne;
AltFire:
XZW2 A 0 A_FireShells(5);
Goto FireFive;
Zoom:
XZW2 A 0 A_FireShells(25);
Goto FireTwentyFive;
FireOne:
XZW2 AQRSTUVWX 1;
XZW2 A 0
{
if ( invoker.whichspin == 2 ) return ResolveState("BigSpin");
if ( invoker.whichspin == 1 ) return ResolveState("OneSpin");
return ResolveState("Ready");
}
Goto Ready;
FireFive:
XZW2 A 2;
XZW3 CDEFGHIJK 2;
XZW2 A 0
{
if ( invoker.whichspin == 2 ) return ResolveState("BigSpin");
if ( invoker.whichspin == 1 ) return ResolveState("OneSpin");
return ResolveState("Ready");
}
Goto Ready;
FireTwentyFive:
XZW2 A 2;
XZW3 STUVWXYZ 2;
XZW4 ABC 2;
XZW2 A 0
{
if ( invoker.whichspin == 2 ) return ResolveState("BigSpin");
if ( invoker.whichspin == 1 ) return ResolveState("OneSpin");
return ResolveState("Ready");
}
Goto Ready;
DryFire:
XZW2 A 2;
XZW2 XA 4;
XZW2 A 0
{
if ( invoker.whichspin == 2 ) return ResolveState("BigSpin");
if ( invoker.whichspin == 1 ) return ResolveState("OneSpin");
return ResolveState("Ready");
}
Goto Ready;
OneSpin:
XZW2 A 1 A_SpinOne();
XZW2 YZ 2;
XZW3 A 2;
XZW3 B 0;
XZW2 A 0 A_JumpIf(invoker.rotation[invoker.rotation[5]]==0,"BigSpin");
Goto Ready;
BigSpin:
XZW2 A 1 A_SpinBig();
XZW3 LMNOPQ 2;
XZW3 R 0;
XZW2 A 0;
Goto Ready;
Reload:
XZW2 A 1;
Goto Ready;
Detach:
XZW2 A 1;
Goto Ready;
Attach:
XZW2 A 1;
Goto Ready;
EndReload:
XZW2 A 1;
Goto Ready;
User1:
XZW2 A 1;
Goto Ready;
Deselect:
TNT1 A -1 A_FullLower();
XZW2 A 2 A_StartSound("wallbuster/deselect",CHAN_WEAPON,CHANF_OVERLAP);
XZW2 BCDEFG 2;
XZW2 G -1 A_FullLower();
Stop;
}
}