Dual wield for weapons

The best and quickest support by a group of top-notch editing specialists, guaranteed!

Moderator: Forum Guards

Dual wield for weapons

Postby clyzm » Tue Apr 03, 07 12:20 pm

Sup, so I came across this issue earlier. One of my friends successfully made this, and I have the source somewhere here in my DeusEx folder. Anyways, I remembered what he did was:

He used a dual weapon base, and two of each class, Wap9 and DWap9. They used the same mesh source except DWap9 was mirrored to work on lefthand, and it was moved so it was viewable on the left side of the screen.

He made both of the guns fire successfully but one at a time, since they were semiautomatics. There were some bugs, like muzzle flashes, but I don't know much else.

I just need to know how to make dual wield weapons so I don't have to custom model both guns into one mesh file, but rather separately. If you want, I could show you some of the source code my friend used for his dualweapons.

I've also seen Hejhujka's done this, but I'm not sure how.
Image
User avatar
clyzm
Forum Master God
 
Posts: 16023
Joined: Sun Nov 28, 04 2:48 am
Location: Chiraq

Postby Allan » Tue Apr 03, 07 12:46 pm

I'll try having a look at the source, even if it may blow me out of the water... :P
User avatar
Allan
Alpha
 
Posts: 4545
Joined: Wed Dec 21, 05 1:41 pm
Location: Northamptonshire, England.

Postby clyzm » Tue Apr 03, 07 1:20 pm

Contents of DoubleWeapBase.uc:

Code: Select all
//=============================================================================
// DoubleWeapBase.
// Created on 11th June 2001 @ 11:23:01
//
// <Version> 0.4a
// <RenZo aka Simon Webster>
// <MAILTO://Duejopor@ic24.net>
// <Double Weapons For DeusEx Still needs testing with assaultgun firing>
// <and single shotweapons>
// <also there is still a lot of usless code from earlyer versions>
// if u use this class or any part of it in any of yourmods or maps
// please give me and the Dx Community credit for the parts you use
// also let us know what the mod is so we can download it and play it
// <Created using: VUC++ http://www.midnightinteractive.com>
//=============================================================================
class DoubleWeapBase expands DeusExWeapon;

/*Var(DualWeapons) bool bReplaceCrossHair;*/
Var Bool bDual,bSlave;
var byte WeapUsed;
var DoubleWeapBase SlaveWeap;
var(DeusExWeapon) String SecondPickupMsg;

replication
{
   reliable if(ROLE==Role_Authority)
      bDual,bSlave,SlaveWeap,WeapUsed/*,setCrossHairVis*/;
}

Simulated Function PreBeginPlay()
{
   Super.prebeginplay();
   
   // please in the Child classes include the multiplayer
   // info here
}

/*Simulated Function SetCrossHairVis(bool HideShow)
{
    DeusExRootWindow(DeusExPlayer(owner).rootWindow).hud.Cross.setCrosshair(HideShow);
}*/

function setHand(float Hand)
{
    local rotator newRot;

    if ( Hand == 2 )
    {
        bHideWeapon = true;
        Super.SetHand(Hand);
        return;
    }

    if ( SlaveWeap != None )
    {
        //*if ( Hand == 0 )//*Took this out. Removing it seems to make pick up work instantly instead of hiding both meshes
            Hand = -4;    //until repull out
        SlaveWeap.SetHand(2);   //(-1 * Hand);
          Mesh = mesh'DWap9';//Mesh = mesh'DWap9'; <<have to figure out how to replace this so i can use the same class for all dual wielding weapons
    }
    bHideWeapon = false;
    Super.SetHand(Hand);
    if ( Hand == 2 )
        Mesh = mesh;// Wap9 mesh
    //else
        //Mesh = mesh'DWap9';
}
     
// OverRide Function for fire offsets
simulated function Vector ComputeProjectileStart(Vector X, Vector Y, Vector Z)
{
   local Vector Start;

   // if we are instant-hit, non-projectile, then don't offset our starting point by PlayerViewOffset
   if (bInstantHit)
      Start = Owner.Location + Pawn(Owner).BaseEyeHeight * vect(0,0,1);// - Vector(Pawn(Owner).ViewRotation)*(0.9*Pawn(Owner).CollisionRadius);
   else{
      if(WeapUsed == 0 || SlaveWeap == none) {
      Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z;
      } Else {
      Start = Owner.Location + SlaveWeap.CalcDrawOffset() + SlaveWeap.FireOffset.X * X + SlaveWeap.FireOffset.Y * Y + SlaveWeap.FireOffset.Z * Z;
       }
   }
   return Start;
}

function Tick(float DeltaTime)
{
   // the stuff in here isnt Very Delta Time Friendly
   // but it needs to be changed on Frame
   //This is just a quick fix at the moment
   Super.tick(deltaTime);
   
   if(owner == none) {
      SlaveWeap.ReloadCount=class.Default.ReloadCount;
      SlaveWeap.ShotTime = class.Default.shotTime;
      ReloadCount = Class.Default.ReloadCount;
      ShotTime = class.Default.shotTime;
   }
   //added this because i maybe Changing the CrossHair Later on
   /*SetCrossHairVis(bReplaceCrossHair);*/
   
   if(slaveWeap != none && SlaveWeap.bHasMuzzleFlash)
         SlaveWeap.EraseMuzzleFlashTexture();
}

function fire(float value)
{

   if(bSlave) return;
   Super.Fire(value);


}

simulated function PlaySelectiveFiring()
{
   local Pawn aPawn;
   local float rnd;
   local Name anim;

   anim = 'Shoot';

   if (bHandToHand)
   {
      rnd = FRand();
      if (rnd < 0.33)
         anim = 'Attack';
      else if (rnd < 0.66)
         anim = 'Attack2';
      else
         anim = 'Attack3';
   }
   if(WeapUSed==0 || SlaveWeap==None){
   if (( Level.NetMode == NM_Standalone ) || ( DeusExPlayer(Owner) == DeusExPlayer(GetPlayerPawn())) )
   {
      if (bAutomatic)
         LoopAnim(anim,, 0.1);
      else
         PlayAnim(anim,,0.1);
   }
   else if ( Role == ROLE_Authority )
   {
      for ( aPawn = Level.PawnList; aPawn != None; aPawn = aPawn.nextPawn )
      {
         if ( aPawn.IsA('DeusExPlayer') && ( DeusExPlayer(Owner) != DeusExPlayer(aPawn) ) )
         {
            // If they can't see the weapon, don't bother
            if ( DeusExPlayer(aPawn).FastTrace( DeusExPlayer(aPawn).Location, Location ))
               DeusExPlayer(aPawn).ClientPlayAnimation( Self, anim, 0.1, bAutomatic );
         }
      }
   }
  }
  Else {
        if (( Level.NetMode == NM_Standalone ) || ( DeusExPlayer(Owner) == DeusExPlayer(GetPlayerPawn())) )
   {
      if (bAutomatic)
         SlaveWeap.LoopAnim(anim,, 0.1);
      else
         SlaveWeap.PlayAnim(anim,,0.1);
   }
   else if ( Role == ROLE_Authority )
   {
      for ( aPawn = Level.PawnList; aPawn != None; aPawn = aPawn.nextPawn )
      {
         if ( aPawn.IsA('DeusExPlayer') && ( DeusExPlayer(Owner) != DeusExPlayer(aPawn) ) )
         {
            // If they can't see the weapon, don't bother
            if ( DeusExPlayer(aPawn).FastTrace( DeusExPlayer(aPawn).Location, Location ))
               DeusExPlayer(aPawn).ClientPlayAnimation( Self, anim, 0.1, bAutomatic );
         }
      }
   }
  }
        if(WeapUsed==1)
         WeapUsed=0;
      else
         WeapUsed=1;
}

Function TweenDown()
{
   Super.TweenDown();
   /*bReplaceCrossHair = False;*/
   if(SlaveWeap != none)
      SlaveWeap.TweenDown();
}

function PlaySelect()
{
   PlayAnim('Select',1.0,0.0);
   if(SlaveWeap!=None)
      SlaveWeap.PlayAnim('Select',1.0,0.0);
   Owner.PlaySound(SelectSound, SLOT_Misc, Pawn(Owner).SoundDampening);   
}

function BringUp()
{
   if(SlaveWeap!=None)
      SlaveWeap.SetHand(1);

   Super.BringUp();
}

simulated event RenderOverlays( canvas Canvas )
{
   local rotator NewRot;

   Super.RenderOverlays(Canvas);
   if(SlaveWeap!=None) {
      NewRot=Pawn(Owner).ViewRotation;
      newRot.Roll=Default.Rotation.Roll;
      SlaveWeap.setRotation(newRot);
      SlaveWeap.SetLocation(Owner.Location+SlaveWeap.CalcDrawOffset());
      Canvas.DrawActor(SlaveWeap, false);
   }
}

function bool HandlePickupQuery( inventory Item )
{
   local int OldAmmo;
   local Pawn P;

   if (Item.Class == Class)
   {
      if ( (Weapon(item).bWeaponStay && SlaveWeap!=None) && (!Weapon(item).bHeldItem || Weapon(item).bTossedOut) )
         return true;
      P = Pawn(Owner);
      
      if ( AmmoType != None )
      {
         OldAmmo = AmmoType.AmmoAmount;
         if ( AmmoType.AddAmmo(PickupAmmoCount) && (OldAmmo == 0)
            && (P.Weapon.class != item.class) && !P.bNeverSwitchOnPickup )
               WeaponSet(P);
      }
      
      if(!bDual && SecondpickupMsg != ""){
         p.clientMessage(SecondPickupMsg);
      }

      if (SlaveWeap==None) {
         SlaveWeap=Spawn(class<DoubleWeapBase>(DynamicLoadObject(String(item.class), class'Class')));
         SlaveWeap.BecomeItem();
         SlaveWeap.SetOwner(Owner);
         SlaveWeap.bSlave=True;
         SlaveWeap.setHand(69);
         SlaveWeap.ReloadCount=class.Default.ReloadCount;
         SlaveWeap.ShotTime = class.Default.shotTime;
         ReloadCount = Class.Default.ReloadCount * 2;
         SlaveWeap.BringUp();
         bDual=True;
         SetHand(69);
      }
      
      Item.PlaySound(Item.PickupSound);
      Item.SetRespawn();   
      return true;
   }
   if ( Inventory == None )
      return false;

   return Inventory.HandlePickupQuery(Item);
}

function DropFrom(vector StartLocation)
{
   if(SLaveWeap!=None)
      SlaveWeap.DropFrom(StartLocation);
   SlaveWeap.bSlave=False;
   bDual=False;
   bSlave=False;
   SlaveWeap=None;
   Super.DropFrom(StartLocation);
}

// Finish a firing sequence (ripped off and modified from Engine\Weapon.uc)
function Finish()
{
   local Pawn PawnOwner;

   if ( bChangeWeapon )
   {
      GotoState('DownWeapon');
      return;
   }

   PawnOwner = Pawn(Owner);
   if ( PawnOwner == None )
      return;
   if ( PlayerPawn(Owner) == None )
   {
      if ( (AmmoType != None) && (AmmoType.AmmoAmount<=0) )
      {
         PawnOwner.StopFiring();
         PawnOwner.SwitchToBestWeapon();
         if ( bChangeWeapon )
            GotoState('DownWeapon');
      }
// Removed this as it would have stopped the slave from Reloading
//      else if ( (PawnOwner.bFire != 0) && (FRand() < RefireRate) )
//         Global.Fire(0);
//      else if ( (PawnOwner.bAltFire != 0) && (FRand() < AltRefireRate) )
//         Global.AltFire(0);   
//      else
//      {
//         PawnOwner.StopFiring();
//         GotoState('Idle');
//      }
      return;
   }
   if ( ((AmmoType != None) && (AmmoType.AmmoAmount<=0)) || (PawnOwner.Weapon != self) )
      GotoState('Idle');
   else if (PawnOwner.bFire!=0)
      Global.Fire(0);
   else if (PawnOwner.bAltFire!=0)
      Global.AltFire(0);
   else
      GotoState('Idle');
}

function ReloadAmmo()
{

   if(SlaveWeap!=none)
   {
         SlaveWeap.TweenAnim('Still',0.1);
//         SlaveWeap.GotoState('ReLoadAmmo');
   }
   Super.Reloadammo();
}

//modifyed so that the Dual Weapons Fire Correctly   
state NormalFire
{
   function AnimEnd()
   {
      if (bAutomatic)
      {
         if ((Pawn(Owner).bFire != 0) && (AmmoType.AmmoAmount > 0))
         {
            if (PlayerPawn(Owner) != None)
               Global.Fire(0);
            else  {
               GotoState('FinishFire');
            }
         }
         else {
            GotoState('FinishFire');
         }
      }
      else
      {
         // if we are a thrown weapon and we run out of ammo, destroy the weapon
         if (bHandToHand && (ReloadCount > 0) && (AmmoType.AmmoAmount <= 0))
            Destroy();
      }
     if(SlaveWeap != none)
       if(SlaveWeap.MultiSkins[2] != None)
          SlaveWeap.MultiSkins[2] = None;
   }
Begin:
   if ((ClipCount >= ReloadCount) && (ReloadCount != 0))
   {
      if (!bAutomatic)
      {
         bFiring = False;
         FinishAnim();
      }

      if (Owner != None)
      {
         if (Owner.IsA('DeusExPlayer'))
         {
            bFiring = False;

            // should we autoreload?
            if (DeusExPlayer(Owner).bAutoReload)
            {
               // auto switch ammo if we're out of ammo and
               // we're not using the primary ammo
               if ((AmmoType.AmmoAmount == 0) && (AmmoName != AmmoNames[0])) {
                  CycleAmmo();
                  SlaveWeap.CycleAmmo();
               }
               SlaveWeap.ReloadAmmo();
               ReloadAmmo();
            }
            else
            {
               if (bHasMuzzleFlash) {
                  EraseMuzzleFlashTexture();
               }
               if(SlaveWeap.bHasMuzzleFlash) {
                  SlaveWeap.EraseMuzzleFlashTexture();
               }
               GotoState('Idle');
            }
         }
         else if (Owner.IsA('ScriptedPawn'))
         {
            bFiring = False;
            ReloadAmmo();
         }
      }
      else
      {
         if (bHasMuzzleFlash) {
               EraseMuzzleFlashTexture();
            }
         if(SlaveWeap.bHasMuzzleFlash) {
               SlaveWeap.EraseMuzzleFlashTexture();
         }
         GotoState('Idle');
      }
   }
//   if ( bAutomatic && (( Level.NetMode == NM_DedicatedServer ) || ((Level.NetMode == NM_ListenServer) && Owner.IsA('DeusExPlayer') && !DeusExPlayer(Owner).PlayerIsListenClient())))
//      GotoState('Idle');

   Sleep(GetShotTime());
   if (bAutomatic)
   {
      GenerateBullet();   // In multiplayer bullets are generated by the client which will let the server know when
      Goto('Begin');
   }
   bFiring = False;
   FinishAnim();

   // if ReloadCount is 0 and we're not hand to hand, then this is a
   // single-use weapon so destroy it after firing once
   if ((ReloadCount == 0) && !bHandToHand)
   {
      if (DeusExPlayer(Owner) != None)
         DeusExPlayer(Owner).RemoveItemFromSlot(Self);   // remove it from the inventory grid
      Destroy();
   }
   ReadyToFire();
Done:
   bFiring = False;
   Finish();
}
// modifyed reload State so that the Second Weapon looks as if it is reloading
state Reload
{
ignores Fire, AltFire;

   function float GetReloadTime()
   {
      local float val;

      val = ReloadTime;

      if (ScriptedPawn(Owner) != None)
      {
         val = ReloadTime * (ScriptedPawn(Owner).BaseAccuracy*2+1);
      }
      else if (DeusExPlayer(Owner) != None)
      {
         // check for skill use if we are the player
         val = GetWeaponSkill();
         val = ReloadTime + (val*ReloadTime);
      }

      return val;
   }

   function NotifyOwner(bool bStart)
   {
      local DeusExPlayer player;
      local ScriptedPawn pawn;

      player = DeusExPlayer(Owner);
      pawn   = ScriptedPawn(Owner);

      if (player != None)
      {
         if (bStart)
            player.Reloading(self, GetReloadTime()+(1.0/AnimRate));
         else
         {
            player.DoneReloading(self);
         }
      }
      else if (pawn != None)
      {
         if (bStart)
            pawn.Reloading(self, GetReloadTime()+(1.0/AnimRate));
         else
            pawn.DoneReloading(self);
      }
   }

Begin:
   FinishAnim();

   // only reload if we have ammo left
   if (AmmoType.AmmoAmount > 0)
   {
      if (( Level.NetMode == NM_DedicatedServer ) || ((Level.NetMode == NM_ListenServer) && Owner.IsA('DeusExPlayer') && !DeusExPlayer(Owner).PlayerIsListenClient()))
      {
         ClientReload();
         Sleep(GetReloadTime());
         ReadyClientToFire( True );
      }
      else
      {
         bWasZoomed = bZoomed;
         if (bWasZoomed)
            ScopeOff();

         Owner.PlaySound(CockingSound, SLOT_None,,, 1024);      // CockingSound is reloadbegin
         // Added to Make it look like the SlaveWeapon HasReloaded as well
         if(SlaveWeap != none) {
         PlayAnim('ReloadBegin');
         SlaveWeap.PlayAnim('ReloadBegin');
         NotifyOwner(True);
         FinishAnim();
         LoopAnim('Reload');
         SlaveWeap.PlayAnim('Reload');   //SlaveWeap.LoopAnim('Reload'); <<Replaced "Loop anim" with "PlayAnim" for obvious reasons
         Sleep(GetReloadTime());
         Owner.PlaySound(AltFireSound, SLOT_None,,, 1024);      // AltFireSound is reloadend
         PlayAnim('ReloadEnd');
         SlaveWeap.PlayAnim('ReloadEnd');
         FinishAnim();
         NotifyOwner(False);

         if (bWasZoomed)
            ScopeOn();

         ClipCount = 0;
         } Else {
         PlayAnim('ReloadBegin');
         NotifyOwner(True);
         FinishAnim();
         LoopAnim('Reload');
         Sleep(GetReloadTime());
         Owner.PlaySound(AltFireSound, SLOT_None,,, 1024);      // AltFireSound is reloadend
         PlayAnim('ReloadEnd');
         FinishAnim();
         NotifyOwner(False);

         if (bWasZoomed)
            ScopeOn();

         ClipCount = 0;
         }
      }
   }
   WeapUsed=0;
   GotoState('Idle');
}
DefaultProperties
{

   SecondPickupMsg="TIME TO CLEAN HOUSE"
}
Image
User avatar
clyzm
Forum Master God
 
Posts: 16023
Joined: Sun Nov 28, 04 2:48 am
Location: Chiraq

Postby Andrievskaya Veronika » Tue Apr 03, 07 3:53 pm

I seen script for doubleweapons here:

http://thesheep.deusexgaming.com/

But i'm not sure where exactly :oops: . Maybe in "Code collection" in "SP Mod" category
User avatar
Andrievskaya Veronika
Poster
 
Posts: 164
Joined: Sat Sep 02, 06 7:35 am
Location: Database read error

Postby Allan » Tue Apr 03, 07 8:08 pm

Andrievskaya Veronika wrote:I seen script for doubleweapons here:

http://thesheep.deusexgaming.com/

But i'm not sure where exactly :oops: . Maybe in "Code collection" in "SP Mod" category


Found it :D
Attachments
codecollection-100.src.zip
(68.97 KiB) Downloaded 151 times
User avatar
Allan
Alpha
 
Posts: 4545
Joined: Wed Dec 21, 05 1:41 pm
Location: Northamptonshire, England.

Postby clyzm » Wed Apr 04, 07 11:41 pm

Ok, it works good so far. Some major bugs like the muzzle flash freezes, and the gun get stuck in uncomfortable positions when it equips dual wield, but it's ok for now. I used double weap base.

Image
Image
User avatar
clyzm
Forum Master God
 
Posts: 16023
Joined: Sun Nov 28, 04 2:48 am
Location: Chiraq


Return to Editing issues

Who is online

Users browsing this forum: No registered users and 6 guests