• Please make sure you are familiar with the forum rules. You can find them here: https://forums.tripwireinteractive.com/index.php?threads/forum-rules.2334636/

Code Crossbow Style Scope Code

Yomommassis

Grizzled Veteran
Sep 24, 2009
705
230
Palmdale, CA USA
Im here to ask for some help, I must admit I havent spent much time on this thought, but if someone could help me figure this out it would save me some trouble

The idea is to get the crossbow style scoping system but implement it on other weapons (with scopes)

m14snipe.jpg

scarsnipe.jpg

I got this idea when I was going to put a 6x scope on a G3 but then realized I didnt know where to start with the scope, I was hoping it would have been as simple as somehow changing its iron sight type but nope the code for this was massive

scopes.gif


Crossbow.uc

Code:
class Crossbow extends KFWeapon;
Code:
[LEFT]//=============================================================================[/LEFT]
 
[LEFT]// Execs[/LEFT]
 
[LEFT]//=============================================================================

#exec OBJ LOAD FILE=..\textures\ScopeShaders.utx
[LEFT]var color ChargeColor;
var float Range;
var float LastRangingTime;
var() Material ZoomMat;
var() Sound ZoomSound;
var bool bArrowRemoved;
//=============================================================================
// Variables
//=============================================================================
var()  int   lenseMaterialID;  // used since material id's seem to change alot
var()  float  scopePortalFOVHigh;  // The FOV to zoom the scope portal by.
var()  float  scopePortalFOV;   // The FOV to zoom the scope portal by.
var()       vector      XoffsetScoped;
var()       vector      XoffsetHighDetail;
// Not sure if these pitch vars are still needed now that we use Scripted Textures. We'll keep for now in case they are. - Ramm 08/14/04
var()  int   scopePitch;    // Tweaks the pitch of the scope firing angle
var()  int   scopeYaw;    // Tweaks the yaw of the scope firing angle
var()  int   scopePitchHigh;   // Tweaks the pitch of the scope firing angle high detail scope
var()  int   scopeYawHigh;   // Tweaks the yaw of the scope firing angle high detail scope
// 3d Scope vars
var   ScriptedTexture   ScopeScriptedTexture;   // Scripted texture for 3d scopes
var   Shader      ScopeScriptedShader;    // The shader that combines the scripted texture with the sight overlay
var   Material          ScriptedTextureFallback;// The texture to render if the users system doesn't support shaders
// new scope vars
var     Combiner            ScriptedScopeCombiner;
var     texture             TexturedScopeTexture;
var     bool    bInitializedScope;  // Set to true when the scope has been initialized
var(Zooming)    float       ZoomedDisplayFOVHigh;       // What is the DisplayFOV when zoomed in
var     float               ForceZoomOutTime;
//=============================================================================
// Functions
//=============================================================================
//===========================================
// Used for debugging the weapons and scopes- Ramm
//===========================================
// Commented out for the release build
exec function pfov(int thisFOV)
{
if( !class'ROEngine.ROLevelInfo'.static.RODebugMode() )
return;
scopePortalFOV = thisFOV;
}
exec function pPitch(int num)
{
if( !class'ROEngine.ROLevelInfo'.static.RODebugMode() )
return;
scopePitch = num;
scopePitchHigh = num;
}
exec function pYaw(int num)
{
if( !class'ROEngine.ROLevelInfo'.static.RODebugMode() )
return;
scopeYaw = num;
scopeYawHigh = num;
}
simulated exec function TexSize(int i, int j)
{
if( !class'ROEngine.ROLevelInfo'.static.RODebugMode() )
return;
ScopeScriptedTexture.SetSize(i, j);
}
// Helper function for the scope system. The scope system checks here to see when it should draw the portal.
// if you want to limit any times the portal should/shouldn't be drawn, add them here.
// Ramm 10/27/03
simulated function bool ShouldDrawPortal()
{
// local  name thisAnim;
// local float  animframe;
// local float  animrate;
//
// GetAnimParams(0, thisAnim,animframe,animrate);
// if(bUsingSights && (IsInState('Idle') || IsInState('PostFiring')) && thisAnim != 'scope_shoot_last')
if( bAimingRifle )
return true;
else
return false;
}
simulated function PostBeginPlay()
{
super.PostBeginPlay();
// Get new scope detail value from KFWeapon
KFScopeDetail = class'KFMod.KFWeapon'.default.KFScopeDetail;
UpdateScopeMode();
}
// Handles initializing and swithing between different scope modes
simulated function UpdateScopeMode()
{
if (Level.NetMode != NM_DedicatedServer && Instigator != none && Instigator.IsLocallyControlled() &&
Instigator.IsHumanControlled() )
{
 if( KFScopeDetail == KF_ModelScope )
{
scopePortalFOV = default.scopePortalFOV;
ZoomedDisplayFOV = default.ZoomedDisplayFOV;
//bPlayerFOVZooms = false;
if (bUsingSights)
{
PlayerViewOffset = XoffsetScoped;
}
if( ScopeScriptedTexture == none )
{
      ScopeScriptedTexture = ScriptedTexture(Level.ObjectPool.AllocateObject(class'ScriptedTexture'));
}
     ScopeScriptedTexture.FallBackMaterial = ScriptedTextureFallback;
     ScopeScriptedTexture.SetSize(512,512);
     ScopeScriptedTexture.Client = Self;
if( ScriptedScopeCombiner == none )
{
// Construct the Combiner
ScriptedScopeCombiner = Combiner(Level.ObjectPool.AllocateObject(class'Combiner'));
         ScriptedScopeCombiner.Material1 = Texture'KillingFloorWeapons.CommandoCross';
         ScriptedScopeCombiner.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader';
         ScriptedScopeCombiner.CombineOperation = CO_Multiply;
         ScriptedScopeCombiner.AlphaOperation = AO_Use_Mask;
         ScriptedScopeCombiner.Material2 = ScopeScriptedTexture;
     }
if( ScopeScriptedShader == none )
{
         // Construct the scope shader
ScopeScriptedShader = Shader(Level.ObjectPool.AllocateObject(class'Shader'));
ScopeScriptedShader.Diffuse = ScriptedScopeCombiner;
ScopeScriptedShader.SelfIllumination = ScriptedScopeCombiner;
ScopeScriptedShader.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader';
}
     bInitializedScope = true;
}
else if( KFScopeDetail == KF_ModelScopeHigh )
{
scopePortalFOV = scopePortalFOVHigh;
ZoomedDisplayFOV = default.ZoomedDisplayFOVHigh;
//bPlayerFOVZooms = false;
if (bUsingSights)
{
PlayerViewOffset = XoffsetHighDetail;
}
if( ScopeScriptedTexture == none )
{
      ScopeScriptedTexture = ScriptedTexture(Level.ObjectPool.AllocateObject(class'ScriptedTexture'));
     }
ScopeScriptedTexture.FallBackMaterial = ScriptedTextureFallback;
     ScopeScriptedTexture.SetSize(1024,1024);
     ScopeScriptedTexture.Client = Self;
if( ScriptedScopeCombiner == none )
{
// Construct the Combiner
ScriptedScopeCombiner = Combiner(Level.ObjectPool.AllocateObject(class'Combiner'));
         ScriptedScopeCombiner.Material1 = Texture'KillingFloorWeapons.CommandoCross';
         ScriptedScopeCombiner.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader';
         ScriptedScopeCombiner.CombineOperation = CO_Multiply;
         ScriptedScopeCombiner.AlphaOperation = AO_Use_Mask;
         ScriptedScopeCombiner.Material2 = ScopeScriptedTexture;
     }
if( ScopeScriptedShader == none )
{
         // Construct the scope shader
ScopeScriptedShader = Shader(Level.ObjectPool.AllocateObject(class'Shader'));
ScopeScriptedShader.Diffuse = ScriptedScopeCombiner;
ScopeScriptedShader.SelfIllumination = ScriptedScopeCombiner;
ScopeScriptedShader.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader';
}
        bInitializedScope = true;
}
else if (KFScopeDetail == KF_TextureScope)
{
ZoomedDisplayFOV = default.ZoomedDisplayFOV;
PlayerViewOffset.X = default.PlayerViewOffset.X;
//bPlayerFOVZooms = true;
bInitializedScope = true;
}
}
}
simulated event RenderTexture(ScriptedTexture Tex)
{
local rotator RollMod;
RollMod = Instigator.GetViewRotation();
//RollMod.Roll -= 16384;
// Rpawn = ROPawn(Instigator);
// // Subtract roll from view while leaning - Ramm
// if (Rpawn != none && rpawn.LeanAmount != 0)
// {
//  RollMod.Roll += rpawn.LeanAmount;
// }
if(Owner != none && Instigator != none && Tex != none && Tex.Client != none)
    Tex.DrawPortal(0,0,Tex.USize,Tex.VSize,Owner,(Instigator.Location + Instigator.EyePosition()), RollMod,  scopePortalFOV );
}[/LEFT]
[/LEFT]

 
 
 
 
 
 
[LEFT]function float GetAIRating()[/LEFT]
 
[LEFT]{

local AIController B;
[LEFT]B = AIController(Instigator.Controller);
if ( (B == None) || (B.Enemy == None) )
return AIRating;
return (AIRating + 0.0003 * FClamp(1500 - VSize(B.Enemy.Location - Instigator.Location),0,1000));
}
function byte BestMode()
{
return 0;
}
function bool RecommendRangedAttack()
{
return true;
}
//TODO: LONG ranged?
function bool RecommendLongRangedAttack()
{
return true;
}
function float SuggestAttackStyle()
{
return -1.0;
}[/LEFT]
[/LEFT]

 
 
 
 
 
 
[LEFT]simulated function SetZoomBlendColor(Canvas c)[/LEFT]
 
[LEFT]{

local Byte    val;
[LEFT]local Color   clr;
local Color   fog;
clr.R = 255;
clr.G = 255;
clr.B = 255;
clr.A = 255;
if( Instigator.Region.Zone.bDistanceFog )
{
fog = Instigator.Region.Zone.DistanceFogColor;
val = 0;
val = Max( val, fog.R);
val = Max( val, fog.G);
val = Max( val, fog.B);
if( val > 128 )
{
val -= 128;
clr.R -= val;
clr.G -= val;
clr.B -= val;
}
}
c.DrawColor = clr;
}[/LEFT]
[/LEFT]

 
 
 
 
 
 
[LEFT]/**[/LEFT]
 
[LEFT]* Handles all the functionality for zooming in including

* setting the parameters for the weapon, pawn, and playercontroller
[LEFT]*
* @param bAnimateTransition whether or not to animate this zoom transition
*/
simulated function ZoomIn(bool bAnimateTransition)
{
super(BaseKFWeapon).ZoomIn(bAnimateTransition);
bAimingRifle = True;
if( KFHumanPawn(Instigator)!=None )
KFHumanPawn(Instigator).SetAiming(True);
if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none )
{
if( AimInSound != none )
{
        PlayOwnedSound(AimInSound, SLOT_Interact,,,,, false);
    }
}
}
/**
* Handles all the functionality for zooming out including
* setting the parameters for the weapon, pawn, and playercontroller
*
* @param bAnimateTransition whether or not to animate this zoom transition
*/
simulated function ZoomOut(bool bAnimateTransition)
{
super.ZoomOut(bAnimateTransition);
bAimingRifle = False;
if( KFHumanPawn(Instigator)!=None )
KFHumanPawn(Instigator).SetAiming(False);
if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none )
{
if( AimOutSound != none )
{
        PlayOwnedSound(AimOutSound, SLOT_Interact,,,,, false);
    }
    KFPlayerController(Instigator.Controller).TransitionFOV(KFPlayerController(Instigator.Controller).DefaultFOV,0.0);
}
}
simulated function WeaponTick(float dt)
{
super.WeaponTick(dt);
if( bAimingRifle && ForceZoomOutTime > 0 && Level.TimeSeconds - ForceZoomOutTime > 0 )
{
 ForceZoomOutTime = 0;
 ZoomOut(false);
 if( Role < ROLE_Authority)
ServerZoomOut(false);
}
}
// Force the weapon out of iron sights shortly after firing so the textured
// scope gets the same disadvantage as the 3d scope
simulated function bool StartFire(int Mode)
{
if( super.StartFire(Mode) )
{
    ForceZoomOutTime = Level.TimeSeconds + 0.4;
    return true;
}
return false;
}
/**
* Called by the native code when the interpolation of the first person weapon to the zoomed position finishes
*/
simulated event OnZoomInFinished()
{
local name anim;
local float frame, rate;
GetAnimParams(0, anim, frame, rate);
if (ClientState == WS_ReadyToFire)
{
    // Play the iron idle anim when we're finished zooming in
    if (anim == IdleAnim)
    {
       PlayIdle();
    }
}
if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none &&
    KFScopeDetail == KF_TextureScope )
{
KFPlayerController(Instigator.Controller).TransitionFOV(PlayerIronSightFOV,0.0);
}
}
simulated function bool CanZoomNow()
{
Return (!FireMode[0].bIsFiring && Instigator!=None && Instigator.Physics!=PHYS_Falling);
}
simulated event RenderOverlays(Canvas Canvas)
{
local int m;
local PlayerController PC;
if (Instigator == None)
    return;
// Lets avoid having to do multiple casts every tick - Ramm
PC = PlayerController(Instigator.Controller);
if(PC == None)
return;
if(!bInitializedScope && PC != none )
{
   UpdateScopeMode();
}
// draw muzzleflashes/smoke for all fire modes so idle state won't
// cause emitters to just disappear
Canvas.DrawActor(None, false, true); // amb: Clear the z-buffer here
for (m = 0; m < NUM_FIRE_MODES; m++)
{
    if (FireMode[m] != None)
    {
        FireMode[m].DrawMuzzleFlash(Canvas);
    }
}[/LEFT]
[/LEFT]

 
 
 
 
 
 
[LEFT]SetLocation( Instigator.Location + Instigator.CalcDrawOffset(self) );[/LEFT]
 
[LEFT]SetRotation( Instigator.GetViewRotation() + ZoomRotInterp);

PreDrawFPWeapon(); // Laurent -- Hook to override things before render (like rotation if using a staticmesh)
[LEFT]if(bAimingRifle && PC != none && (KFScopeDetail == KF_ModelScope || KFScopeDetail == KF_ModelScopeHigh))
{
if (ShouldDrawPortal())
{
if ( ScopeScriptedTexture != none )
{
Skins[LenseMaterialID] = ScopeScriptedShader;
ScopeScriptedTexture.Client = Self;   // Need this because this can get corrupted - Ramm
ScopeScriptedTexture.Revision = (ScopeScriptedTexture.Revision +1);
}
}
bDrawingFirstPerson = true;
  Canvas.DrawBoundActor(self, false, false,DisplayFOV,PC.Rotation,rot(0,0,0),Instigator.CalcZoomedDrawOffset(self));
   bDrawingFirstPerson = false;
}
// Added "bInIronViewCheck here. Hopefully it prevents us getting the scope overlay when not zoomed.
// Its a bit of a band-aid solution, but it will work til we get to the root of the problem - Ramm 08/12/04
else if( KFScopeDetail == KF_TextureScope && PC.DesiredFOV == PlayerIronSightFOV && bAimingRifle)
{
Skins[LenseMaterialID] = ScriptedTextureFallback;
SetZoomBlendColor(Canvas);
//Black-out either side of the main zoom circle.
Canvas.Style = ERenderStyle.STY_Normal;
Canvas.SetPos(0, 0);
Canvas.DrawTile(ZoomMat, (Canvas.SizeX - Canvas.SizeY) / 2, Canvas.SizeY, 0.0, 0.0, 8, 8);
Canvas.SetPos(Canvas.SizeX, 0);
Canvas.DrawTile(ZoomMat, -(Canvas.SizeX - Canvas.SizeY) / 2, Canvas.SizeY, 0.0, 0.0, 8, 8);
//The view through the scope itself.
Canvas.Style = 255;
Canvas.SetPos((Canvas.SizeX - Canvas.SizeY) / 2,0);
Canvas.DrawTile(ZoomMat, Canvas.SizeY, Canvas.SizeY, 0.0, 0.0, 1024, 1024);
//Draw some useful text.
Canvas.Font = Canvas.MedFont;
Canvas.SetDrawColor(200,150,0);
Canvas.SetPos(Canvas.SizeX * 0.16, Canvas.SizeY * 0.43);
Canvas.DrawText("Zoom: 2.50");
Canvas.SetPos(Canvas.SizeX * 0.16, Canvas.SizeY * 0.47);
}
else
{
Skins[LenseMaterialID] = ScriptedTextureFallback;
bDrawingFirstPerson = true;
Canvas.DrawActor(self, false, false, DisplayFOV);
bDrawingFirstPerson = false;
}
}
//=============================================================================
// Scopes
//=============================================================================
//------------------------------------------------------------------------------
// SetScopeDetail(RO) - Allow the players to change scope detail while ingame.
// Changes are saved to the ini file.
//------------------------------------------------------------------------------
//simulated exec function SetScopeDetail()
//{
// if( !bHasScope )
//  return;
//
// if (KFScopeDetail == KF_ModelScope)
//  KFScopeDetail = KF_TextureScope;
// else if ( KFScopeDetail == KF_TextureScope)
//  KFScopeDetail = KF_ModelScopeHigh;
// else if ( KFScopeDetail == KF_ModelScopeHigh)
//  KFScopeDetail = KF_ModelScope;
//
// AdjustIngameScope();
// class'KFMod.KFWeapon'.default.KFScopeDetail = KFScopeDetail;
// class'KFMod.KFWeapon'.static.StaticSaveConfig();  // saves the new scope detail value to the ini
//}
//------------------------------------------------------------------------------
// AdjustIngameScope(RO) - Takes the changes to the ScopeDetail variable and
// sets the scope to the new detail mode. Called when the player switches the
// scope setting ingame, or when the scope setting is changed from the menu
//------------------------------------------------------------------------------
simulated function AdjustIngameScope()
{
local PlayerController PC;
// Lets avoid having to do multiple casts every tick - Ramm
PC = PlayerController(Instigator.Controller);
if( !bHasScope )
return;
switch (KFScopeDetail)
{
case KF_ModelScope:
if( bAimingRifle )
DisplayFOV = default.ZoomedDisplayFOV;
if ( PC.DesiredFOV == PlayerIronSightFOV && bAimingRifle )
{
         if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none )
         {
                KFPlayerController(Instigator.Controller).TransitionFOV(KFPlayerController(Instigator.Controller).DefaultFOV,0.0);
}
}
break;
case KF_TextureScope:
if( bAimingRifle )
DisplayFOV = default.ZoomedDisplayFOV;
if ( bAimingRifle && PC.DesiredFOV != PlayerIronSightFOV )
{
         if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none )
         {
          KFPlayerController(Instigator.Controller).TransitionFOV(PlayerIronSightFOV,0.0);
         }
}
break;
case KF_ModelScopeHigh:
if( bAimingRifle )
{
if( ZoomedDisplayFOVHigh > 0 )
 DisplayFOV = default.ZoomedDisplayFOVHigh;
else
 DisplayFOV = default.ZoomedDisplayFOV;
}
if ( bAimingRifle && PC.DesiredFOV == PlayerIronSightFOV )
{
         if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none )
         {
                KFPlayerController(Instigator.Controller).TransitionFOV(KFPlayerController(Instigator.Controller).DefaultFOV,0.0);
         }
}
break;
}
// Make any chagned to the scope setup
UpdateScopeMode();
}
simulated event Destroyed()
{
if (ScopeScriptedTexture != None)
{
    ScopeScriptedTexture.Client = None;
    Level.ObjectPool.FreeObject(ScopeScriptedTexture);
    ScopeScriptedTexture=None;
}
if (ScriptedScopeCombiner != None)
{
ScriptedScopeCombiner.Material2 = none;
Level.ObjectPool.FreeObject(ScriptedScopeCombiner);
ScriptedScopeCombiner = none;
}
if (ScopeScriptedShader != None)
{
ScopeScriptedShader.Diffuse = none;
ScopeScriptedShader.SelfIllumination = none;
Level.ObjectPool.FreeObject(ScopeScriptedShader);
ScopeScriptedShader = none;
}
Super.Destroyed();
}
simulated function PreTravelCleanUp()
{
if (ScopeScriptedTexture != None)
{
    ScopeScriptedTexture.Client = None;
    Level.ObjectPool.FreeObject(ScopeScriptedTexture);
    ScopeScriptedTexture=None;
}
if (ScriptedScopeCombiner != None)
{
ScriptedScopeCombiner.Material2 = none;
Level.ObjectPool.FreeObject(ScriptedScopeCombiner);
ScriptedScopeCombiner = none;
}
if (ScopeScriptedShader != None)
{
ScopeScriptedShader.Diffuse = none;
ScopeScriptedShader.SelfIllumination = none;
Level.ObjectPool.FreeObject(ScopeScriptedShader);
ScopeScriptedShader = none;
}
}
defaultproperties
{
 ZoomMat=FinalBlend'KillingFloorWeapons.Xbow.CommandoCrossFinalBlend'
 lenseMaterialID=2
 scopePortalFOVHigh=22.000000
 scopePortalFOV=12.000000
 ScriptedTextureFallback=Combiner'KF_Weapons_Trip_T.Rifles.CBLens_cmb'
 ZoomedDisplayFOVHigh=35.000000
 bHasScope=True
 MagCapacity=1
 ReloadRate=0.010000
 WeaponReloadAnim="Reload_Crossbow"
 HudImage=Texture'KillingFloorHUD.WeaponSelect.crossbow_unselected'
 SelectedHudImage=Texture'KillingFloorHUD.WeaponSelect.Crossbow'
 bHasAimingMode=True
 IdleAimAnim="Idle_Iron"
 StandardDisplayFOV=65.000000
 TraderInfoTexture=Texture'KillingFloorHUD.Trader_Weapon_Images.Trader_CrossBow'
 PlayerIronSightFOV=32.000000
 ZoomedDisplayFOV=60.000000
 FireModeClass(0)=Class'KFMod.CrossbowFire'
 FireModeClass(1)=Class'KFMod.NoFire'
 PutDownAnim="PutDown"
 SelectSound=Sound'KF_XbowSnd.Xbow_Select'
 SelectForce="SwitchToAssaultRifle"
 AIRating=0.650000
 CurrentRating=0.650000
 Description="A recreational hunting weapon, featuring a firing trigger and a powerful integrated scope. "
 DisplayFOV=65.000000
 Priority=10
 CustomCrosshair=11
 CustomCrossHairTextureName="Crosshairs.HUD.Crosshair_Cross5"
 InventoryGroup=4
 GroupOffset=3
 PickupClass=Class'KFMod.CrossbowPickup'
 PlayerViewOffset=(X=15.000000,Y=16.000000,Z=-12.000000)
 BobDamping=6.000000
 AttachmentClass=Class'KFMod.CrossbowAttachment'
 IconCoords=(X1=253,Y1=146,X2=333,Y2=181)
 ItemName="Compound Crossbow"
 LightType=LT_None
 LightBrightness=0.000000
 LightRadius=0.000000
 Mesh=SkeletalMesh'KF_Weapons_Trip.Crossbow_Trip'
 Skins(0)=Combiner'KF_Weapons_Trip_T.Rifles.crossbow_cmb'
}[/LEFT]
[/LEFT]
 
It's not really all that complicated, I'd say take the time to analyse what everything does and you could probably learn a lot from it. Not all of the code there is strictly necessary to get the job done, it just polishes it up a bit (adding the ability to set scope detail and such).
Tbh I havent even looked into trying yet, Ive been multitasking to such an extent that im getting everything done a little at a time instead of one thing done one at a time :/
 
Upvote 0