/ GUNRPG.Core / WeaponFactory.cs
WeaponFactory.cs
  1  using GUNRPG.Core.Weapons;
  2  
  3  namespace GUNRPG.Core;
  4  
  5  /// <summary>
  6  /// Factory for creating pre-configured weapons.
  7  /// All stats based on real weapon data.
  8  /// </summary>
  9  public static class WeaponFactory
 10  {
 11      /// <summary>
 12      /// Creates a SOKOL 545 light machine gun.
 13      /// Stats based on the provided in-game attachment screen.
 14      /// </summary>
 15      public static Weapon CreateSokol545()
 16      {
 17          return new Weapon("SOKOL 545")
 18          {
 19              // Firepower
 20              RoundsPerMinute = 583,
 21              BulletVelocityMetersPerSecond = 740.0f,
 22  
 23              // Magazine / handling
 24              MagazineSize = 102,
 25              ReloadTimeMs = 7333,
 26  
 27              // Damage ranges
 28              BaseDamage = 32f,
 29              HeadshotMultiplier = 1.2f,
 30  
 31              // Accuracy
 32              HipfireSpreadDegrees = 9.50f,
 33              JumpHipfireSpreadDegrees = 14.50f,
 34              SlideHipfireSpreadDegrees = 16.50f,
 35              DiveHipfireSpreadDegrees = 16.50f,
 36              ADSSpreadDegrees = 1.0f,
 37  
 38              // Recoil
 39              VerticalRecoil = 0.5627f,
 40              HorizontalRecoil = 0.1292f,
 41              RecoilRecoveryTimeMs = 680f,
 42  
 43              // Advanced recoil / handling
 44              FirstShotRecoilScale = 1.08f,
 45              RecoilGunKickDegreesPerSecond = 24.92f,
 46              HorizontalRecoilControlDegreesPerSecond = 12.92f,
 47              VerticalRecoilControlDegreesPerSecond = 56.27f,
 48              KickResetSpeedMs = 680,
 49              AimingIdleSwayDegreesPerSecond = 8.53f,
 50              AimingIdleSwayDelayMs = 2200,
 51              FlinchResistance = 0.10f,
 52  
 53              // ADS / mobility
 54              ADSTimeMs = 420,
 55              JumpADSTimeMs = 552,
 56  
 57              MovementSpeedMetersPerSecond = 4.5f,
 58              CrouchMovementSpeedMetersPerSecond = 2.0f,
 59              SprintingMovementSpeedMetersPerSecond = 6.6f,
 60              ADSMovementSpeedMetersPerSecond = 2.5f,
 61  
 62              // Movement penalties
 63              SprintToFireTimeMs = 235f,
 64              SlideToFireTimeMs = 470f,
 65              DiveToFireTimeMs = 550f,
 66              JumpSprintToFireTimeMs = 329f,
 67  
 68              // Commitment
 69              BulletsPerCommitmentUnit = 3,
 70  
 71              // Suppression - LMGs are highly suppressive
 72              SuppressionFactor = 1.5f
 73          }.WithSokol545DamageModel();
 74      }
 75  
 76      private static Weapon WithSokol545DamageModel(this Weapon weapon)
 77      {
 78          weapon.DamageRanges.Clear();
 79          weapon.DamageRanges.Add(new DamageRange(0f, 51f, 32f)
 80          {
 81              BodyPartDamageOverrides = new Dictionary<BodyPart, float>
 82              {
 83                  [BodyPart.Head] = 38f, // 38(x1.2) shown in image
 84                  [BodyPart.Neck] = 32f,
 85                  [BodyPart.UpperTorso] = 32f,
 86                  [BodyPart.LowerTorso] = 32f,
 87                  [BodyPart.UpperArm] = 32f,
 88                  [BodyPart.LowerArm] = 32f,
 89                  [BodyPart.UpperLeg] = 32f,
 90                  [BodyPart.LowerLeg] = 32f,
 91              }
 92          });
 93          weapon.DamageRanges.Add(new DamageRange(51f, 71f, 31f)
 94          {
 95              BodyPartDamageOverrides = new Dictionary<BodyPart, float>
 96              {
 97                  [BodyPart.Head] = 37f, // Approximate based on 1.2x multiplier
 98                  [BodyPart.Neck] = 31f,
 99                  [BodyPart.UpperTorso] = 31f,
100                  [BodyPart.LowerTorso] = 31f,
101                  [BodyPart.UpperArm] = 31f,
102                  [BodyPart.LowerArm] = 31f,
103                  [BodyPart.UpperLeg] = 31f,
104                  [BodyPart.LowerLeg] = 31f,
105              }
106          });
107          weapon.DamageRanges.Add(new DamageRange(71f, float.PositiveInfinity, 24f)
108          {
109              BodyPartDamageOverrides = new Dictionary<BodyPart, float>
110              {
111                  [BodyPart.Head] = 29f, // Approximate based on 1.2x multiplier
112                  [BodyPart.Neck] = 24f,
113                  [BodyPart.UpperTorso] = 24f,
114                  [BodyPart.LowerTorso] = 24f,
115                  [BodyPart.UpperArm] = 24f,
116                  [BodyPart.LowerArm] = 24f,
117                  [BodyPart.UpperLeg] = 24f,
118                  [BodyPart.LowerLeg] = 24f,
119              }
120          });
121  
122          return weapon;
123      }
124  
125      /// <summary>
126      /// Creates a STURMWOLF 45 submachine gun.
127      /// Stats based on the provided in-game attachment screen.
128      /// </summary>
129      public static Weapon CreateSturmwolf45()
130      {
131          return new Weapon("STURMWOLF 45")
132          {
133              // Firepower
134              RoundsPerMinute = 667,
135              BulletVelocityMetersPerSecond = 540.0f,
136  
137              // Magazine / handling
138              MagazineSize = 32,
139              ReloadTimeMs = 2730,
140  
141              // Damage ranges
142              BaseDamage = 30f,
143              HeadshotMultiplier = 1.2f,
144  
145              // Accuracy
146              HipfireSpreadDegrees = 7.25f,
147              JumpHipfireSpreadDegrees = 12.00f,
148              SlideHipfireSpreadDegrees = 15.00f,
149              DiveHipfireSpreadDegrees = 15.00f,
150              ADSSpreadDegrees = 1.0f,
151  
152              // Recoil
153              VerticalRecoil = 0.4596f,
154              HorizontalRecoil = 0.1311f,
155              RecoilRecoveryTimeMs = 600f,
156  
157              // Advanced recoil / handling
158              FirstShotRecoilScale = 1.00f,
159              RecoilGunKickDegreesPerSecond = 44.86f,
160              HorizontalRecoilControlDegreesPerSecond = 13.11f,
161              VerticalRecoilControlDegreesPerSecond = 45.96f,
162              KickResetSpeedMs = 600,
163              AimingIdleSwayDegreesPerSecond = 0.39f,
164              AimingIdleSwayDelayMs = 2200,
165              FlinchResistance = 0.12f,
166  
167              // ADS / mobility
168              ADSTimeMs = 220,
169              JumpADSTimeMs = 291,
170  
171              MovementSpeedMetersPerSecond = 4.8f,
172              CrouchMovementSpeedMetersPerSecond = 2.7f,
173              SprintingMovementSpeedMetersPerSecond = 7.1f,
174              ADSMovementSpeedMetersPerSecond = 3.4f,
175  
176              // Movement penalties
177              SprintToFireTimeMs = 150f,
178              SlideToFireTimeMs = 340f,
179              DiveToFireTimeMs = 420f,
180              JumpSprintToFireTimeMs = 210f,
181  
182              // Commitment
183              BulletsPerCommitmentUnit = 4,
184  
185              // Suppression - SMGs are less suppressive
186              SuppressionFactor = 0.8f
187          }.WithSturmwolf45DamageModel();
188      }
189  
190      private static Weapon WithSturmwolf45DamageModel(this Weapon weapon)
191      {
192          weapon.DamageRanges.Clear();
193          weapon.DamageRanges.Add(new DamageRange(0f, 11f, 30f)
194          {
195              BodyPartDamageOverrides = new Dictionary<BodyPart, float>
196              {
197                  [BodyPart.Head] = 37f, // 37(x1.2) shown in image
198                  [BodyPart.Neck] = 30f,
199                  [BodyPart.UpperTorso] = 30f,
200                  [BodyPart.LowerTorso] = 30f,
201                  [BodyPart.UpperArm] = 30f,
202                  [BodyPart.LowerArm] = 30f,
203                  [BodyPart.UpperLeg] = 30f,
204                  [BodyPart.LowerLeg] = 30f,
205              }
206          });
207          weapon.DamageRanges.Add(new DamageRange(11f, 18f, 23f)
208          {
209              BodyPartDamageOverrides = new Dictionary<BodyPart, float>
210              {
211                  [BodyPart.Head] = 28f, // Approximate based on 1.2x multiplier
212                  [BodyPart.Neck] = 23f,
213                  [BodyPart.UpperTorso] = 23f,
214                  [BodyPart.LowerTorso] = 23f,
215                  [BodyPart.UpperArm] = 23f,
216                  [BodyPart.LowerArm] = 23f,
217                  [BodyPart.UpperLeg] = 23f,
218                  [BodyPart.LowerLeg] = 23f,
219              }
220          });
221          weapon.DamageRanges.Add(new DamageRange(18f, 26f, 19f)
222          {
223              BodyPartDamageOverrides = new Dictionary<BodyPart, float>
224              {
225                  [BodyPart.Head] = 23f, // Approximate based on 1.2x multiplier
226                  [BodyPart.Neck] = 19f,
227                  [BodyPart.UpperTorso] = 19f,
228                  [BodyPart.LowerTorso] = 19f,
229                  [BodyPart.UpperArm] = 19f,
230                  [BodyPart.LowerArm] = 19f,
231                  [BodyPart.UpperLeg] = 19f,
232                  [BodyPart.LowerLeg] = 19f,
233              }
234          });
235          weapon.DamageRanges.Add(new DamageRange(26f, float.PositiveInfinity, 16f)
236          {
237              BodyPartDamageOverrides = new Dictionary<BodyPart, float>
238              {
239                  [BodyPart.Head] = 19f, // Approximate based on 1.2x multiplier
240                  [BodyPart.Neck] = 16f,
241                  [BodyPart.UpperTorso] = 16f,
242                  [BodyPart.LowerTorso] = 16f,
243                  [BodyPart.UpperArm] = 16f,
244                  [BodyPart.LowerArm] = 16f,
245                  [BodyPart.UpperLeg] = 16f,
246                  [BodyPart.LowerLeg] = 16f,
247              }
248          });
249  
250          return weapon;
251      }
252  
253      /// <summary>
254      /// Creates a M15 MOD 0 assault rifle.
255      /// Stats based on the provided in-game attachment screen.
256      /// </summary>
257      public static Weapon CreateM15Mod0()
258      {
259          return new Weapon("M15 MOD 0")
260          {
261              // Firepower
262              RoundsPerMinute = 769,
263              BulletVelocityMetersPerSecond = 730.0f,
264  
265              // Magazine / handling
266              MagazineSize = 30,
267              ReloadTimeMs = 3000,
268  
269              // Damage ranges
270              BaseDamage = 21f,
271              HeadshotMultiplier = 1.3f,
272  
273              // Accuracy
274              HipfireSpreadDegrees = 7.95f,
275              JumpHipfireSpreadDegrees = 11.95f,
276              SlideHipfireSpreadDegrees = 14.95f,
277              DiveHipfireSpreadDegrees = 14.95f,
278              ADSSpreadDegrees = 1.0f,
279  
280              // Recoil
281              VerticalRecoil = 0.4667f,
282              HorizontalRecoil = 0.1111f,
283              RecoilRecoveryTimeMs = 600f,
284  
285              // Advanced recoil / handling
286              FirstShotRecoilScale = 1.00f,
287              RecoilGunKickDegreesPerSecond = 15.50f,
288              HorizontalRecoilControlDegreesPerSecond = 11.11f,
289              VerticalRecoilControlDegreesPerSecond = 46.67f,
290              KickResetSpeedMs = 600,
291              AimingIdleSwayDegreesPerSecond = 0.42f,
292              AimingIdleSwayDelayMs = 2200,
293              FlinchResistance = 0.10f,
294  
295              // ADS / mobility
296              ADSTimeMs = 250,
297              JumpADSTimeMs = 333,
298  
299              MovementSpeedMetersPerSecond = 4.7f,
300              CrouchMovementSpeedMetersPerSecond = 2.6f,
301              SprintingMovementSpeedMetersPerSecond = 6.8f,
302              ADSMovementSpeedMetersPerSecond = 2.9f,
303  
304              // Movement penalties
305              SprintToFireTimeMs = 210f,
306              SlideToFireTimeMs = 430f,
307              DiveToFireTimeMs = 400f,
308              JumpSprintToFireTimeMs = 385f,
309  
310              // Commitment
311              BulletsPerCommitmentUnit = 3,
312  
313              // Suppression - ARs have standard suppression
314              SuppressionFactor = 1.0f
315          }.WithM15Mod0DamageModel();
316      }
317  
318      private static Weapon WithM15Mod0DamageModel(this Weapon weapon)
319      {
320          weapon.DamageRanges.Clear();
321          weapon.DamageRanges.Add(new DamageRange(0f, 30.5f, 21f)
322          {
323              BodyPartDamageOverrides = new Dictionary<BodyPart, float>
324              {
325                  [BodyPart.Head] = 27f,
326                  [BodyPart.Neck] = 21f,
327                  [BodyPart.UpperTorso] = 21f,
328                  [BodyPart.LowerTorso] = 21f,
329                  [BodyPart.UpperArm] = 21f,
330                  [BodyPart.LowerArm] = 21f,
331                  [BodyPart.UpperLeg] = 21f,
332                  [BodyPart.LowerLeg] = 21f,
333              }
334          });
335          weapon.DamageRanges.Add(new DamageRange(30.5f, 46.4f, 18f)
336          {
337              BodyPartDamageOverrides = new Dictionary<BodyPart, float>
338              {
339                  [BodyPart.Head] = 23f,
340                  [BodyPart.Neck] = 18f,
341                  [BodyPart.UpperTorso] = 18f,
342                  [BodyPart.LowerTorso] = 18f,
343                  [BodyPart.UpperArm] = 18f,
344                  [BodyPart.LowerArm] = 18f,
345                  [BodyPart.UpperLeg] = 18f,
346                  [BodyPart.LowerLeg] = 18f,
347              }
348          });
349          weapon.DamageRanges.Add(new DamageRange(46.4f, float.PositiveInfinity, 17f)
350          {
351              BodyPartDamageOverrides = new Dictionary<BodyPart, float>
352              {
353                  [BodyPart.Head] = 22f,
354                  [BodyPart.Neck] = 17f,
355                  [BodyPart.UpperTorso] = 17f,
356                  [BodyPart.LowerTorso] = 17f,
357                  [BodyPart.UpperArm] = 17f,
358                  [BodyPart.LowerArm] = 17f,
359                  [BodyPart.UpperLeg] = 17f,
360                  [BodyPart.LowerLeg] = 17f,
361              }
362          });
363  
364          return weapon;
365      }
366  }