标签:stat load head auth elf process person res nat
目前正在翻看官方SRC
收获如下
[class‘Weapon‘]
simulated function CalcWeaponFire(vector StartTrace, vector EndTrace, optional out array<ImpactInfo> ImpactList, optional vector Extent) : ImpactInfo
/**
* CalcWeaponFire: Simulate an instant hit shot.
* This doesn‘t deal any damage nor trigger any effect. It just simulates a shot and returns
* the hit information, to be post-processed later.
*
* ImpactList returns a list of ImpactInfo containing all listed impacts during the simulation.
* CalcWeaponFire however returns one impact (return variable) being the first geometry impact
* straight, with no direction change. If you were to do refraction, reflection, bullet penetration
* or something like that, this would return exactly when the crosshair sees:
* The first ‘real geometry‘ impact, skipping invisible triggers and volumes.
*
* @param StartTrace world location to start trace from
* @param EndTrace world location to end trace at
* @param Extent extent of trace performed
* @output ImpactList list of all impacts that occured during simulation
* @return first ‘real geometry‘ impact that occured.
*
* @note if an impact didn‘t occur, and impact is still returned, with its HitLocation being the EndTrace value.
*/
simulated function ImpactInfo CalcWeaponFire(vector StartTrace, vector EndTrace, optional out array<ImpactInfo> ImpactList, optional vector Extent)
{
local vector HitLocation, HitNormal, Dir;
local Actor HitActor;
local TraceHitInfo HitInfo;
local ImpactInfo CurrentImpact;
local PortalTeleporter Portal;
local float HitDist;
local bool bOldBlockActors, bOldCollideActors;
// Perform trace to retrieve hit info
HitActor = GetTraceOwner().Trace(HitLocation, HitNormal, EndTrace, StartTrace, TRUE, Extent, HitInfo, TRACEFLAG_Bullet);
// If we didn‘t hit anything, then set the HitLocation as being the EndTrace location
if( HitActor == None )
{
HitLocation = EndTrace;
}
// Convert Trace Information to ImpactInfo type.
CurrentImpact.HitActor = HitActor;
CurrentImpact.HitLocation = HitLocation;
CurrentImpact.HitNormal = HitNormal;
CurrentImpact.RayDir = Normal(EndTrace-StartTrace);
CurrentImpact.StartTrace = StartTrace;
CurrentImpact.HitInfo = HitInfo;
// Add this hit to the ImpactList
ImpactList[ImpactList.Length] = CurrentImpact;
// check to see if we‘ve hit a trigger.
// In this case, we want to add this actor to the list so we can give it damage, and then continue tracing through.
if( HitActor != None )
{
if (PassThroughDamage(HitActor))
{
// disable collision temporarily for the actor we can pass-through
HitActor.bProjTarget = false;
bOldCollideActors = HitActor.bCollideActors;
bOldBlockActors = HitActor.bBlockActors;
if (HitActor.IsA(‘Pawn‘))
{
// For pawns, we need to disable bCollideActors as well
HitActor.SetCollision(false, false);
// recurse another trace
CalcWeaponFire(HitLocation, EndTrace, ImpactList, Extent);
}
else
{
if( bOldBlockActors )
{
HitActor.SetCollision(bOldCollideActors, false);
}
// recurse another trace and override CurrentImpact
CurrentImpact = CalcWeaponFire(HitLocation, EndTrace, ImpactList, Extent);
}
// and reenable collision for the trigger
HitActor.bProjTarget = true;
HitActor.SetCollision(bOldCollideActors, bOldBlockActors);
}
else
{
// if we hit a PortalTeleporter, recurse through
Portal = PortalTeleporter(HitActor);
if( Portal != None && Portal.SisterPortal != None )
{
Dir = EndTrace - StartTrace;
HitDist = VSize(HitLocation - StartTrace);
// calculate new start and end points on the other side of the portal
StartTrace = Portal.TransformHitLocation(HitLocation);
EndTrace = StartTrace + Portal.TransformVectorDir(Normal(Dir) * (VSize(Dir) - HitDist));
//@note: intentionally ignoring return value so our hit of the portal is used for effects
//@todo: need to figure out how to replicate that there should be effects on the other side as well
CalcWeaponFire(StartTrace, EndTrace, ImpactList, Extent);
}
}
}
return CurrentImpact;
}
simulated function InstantFire() 其中调用了 ProcessInstantHit()
原理:
对 玩家武器位置 以 GetAdjustedAim() 为方向 发射Trace(类似U3d Raycast)进行模拟武器伤害输出计算 得到 RealImpact
对RealImpact调用ProcessInstantHit,参数 <当前武器,RealImpact>
/**
* Performs an ‘Instant Hit‘ shot.
* Also, sets up replication for remote clients,
* and processes all the impacts to deal proper damage and play effects.
*
* Network: Local Player and Server
*/
simulated function InstantFire()
{
local vector StartTrace, EndTrace;
local Array<ImpactInfo> ImpactList;
local int Idx;
local ImpactInfo RealImpact;
// define range to use for CalcWeaponFire()
StartTrace = Instigator.GetWeaponStartTraceLocation();
EndTrace = StartTrace + vector(GetAdjustedAim(StartTrace)) * GetTraceRange();
// Perform shot
RealImpact = CalcWeaponFire(StartTrace, EndTrace, ImpactList);
if (Role == ROLE_Authority)
{
/* FlushPersistentDebugLines();
DrawDebugSphere( StartTrace, 10, 10, 0, 255, 0 );
DrawDebugSphere( EndTrace, 10, 10, 255, 0, 0 );
DrawDebugSphere( RealImpact.HitLocation, 10, 10, 0, 0, 255 );
`log( self@GetFuncName()@Instigator@RealImpact.HitLocation@RealImpact.HitActor );*/
// Set flash location to trigger client side effects.
// if HitActor == None, then HitLocation represents the end of the trace (maxrange)
// Remote clients perform another trace to retrieve the remaining Hit Information (HitActor, HitNormal, HitInfo...)
// Here, The final impact is replicated. More complex bullet physics (bounce, penetration...)
// would probably have to run a full simulation on remote clients.
SetFlashLocation(RealImpact.HitLocation);
}
// Process all Instant Hits on local player and server (gives damage, spawns any effects).
for (Idx = 0; Idx < ImpactList.Length; Idx++)
{
ProcessInstantHit(CurrentFireMode, ImpactList[Idx]);
}
}
simulated function ProcessInstantHit(byte FiringMode, ImpactInfo Impact, optional int NumHits)
作为子级被InstantFire()调用
作为父级被class‘KFWeapon‘::simulated function ProcessInstantHitEx(byte FiringMode, ImpactInfo Impact, optional int NumHits, optional out float out_PenetrationVal, optional int ImpactNum)调用,其中所有延续KFWeapon的类如KFWeap_MedicBase和KFWeap_Assaultrifle_Medic可以重写以实现自定义
原理:
对ImpactInfo::HitActor执行即刻的TakeDamage
/**
* Processes a successful ‘Instant Hit‘ trace and eventually spawns any effects.
* Network: LocalPlayer and Server
* @param FiringMode: index of firing mode being used
* @param Impact: hit information
* @param NumHits (opt): number of hits to apply using this impact
* this is useful for handling multiple nearby impacts of multihit weapons (e.g. shotguns)
* without having to execute the entire damage code path for each one
* an omitted or <= 0 value indicates a single hit
*/
simulated function ProcessInstantHit(byte FiringMode, ImpactInfo Impact, optional int NumHits)
{
local int TotalDamage;
local KActorFromStatic NewKActor;
local StaticMeshComponent HitStaticMesh;
if (Impact.HitActor != None)
{
// default damage model is just hits * base damage
NumHits = Max(NumHits, 1);
TotalDamage = InstantHitDamage[CurrentFireMode] * NumHits;
if ( Impact.HitActor.bWorldGeometry )
{
HitStaticMesh = StaticMeshComponent(Impact.HitInfo.HitComponent);
if ( (HitStaticMesh != None) && HitStaticMesh.CanBecomeDynamic() )
{
NewKActor = class‘KActorFromStatic‘.Static.MakeDynamic(HitStaticMesh);
if ( NewKActor != None )
{
Impact.HitActor = NewKActor;
}
}
}
Impact.HitActor.TakeDamage( TotalDamage, Instigator.Controller,
Impact.HitLocation, InstantHitMomentum[FiringMode] * Impact.RayDir,
InstantHitDamageTypes[FiringMode], Impact.HitInfo, self );
}
}
--
大体思路:
进行Trace确定ImpactInfo,原理是运用CalcWeaponFire(),方法类似于InstantFire(),然后判断HitZoneIndex == HZI_Head是否成立以检测是否爆头
目前在BGWeap_Assaultrifle_Medic.uc中 爆头提示 的实现
class BGWeap_Assaultrifle_Medic extends KFWeap_MedicBase;
simulated function ProcessInstantHitEx( byte FiringMode, ImpactInfo Impact, optional int NumHits, optional out float out_PenetrationVal, optional int ImpactNum )
{
local int HitZoneIndex;
local KFPawn ImpactTarget;
local KFPawn_Human HealTarget;
local KFPawn_Monster KFPM_Victim;
local KFPlayerController doer;
local KFPlayerController KFPC;
ImpactTarget=KFPawn(Impact.HitActor);
HealTarget=KFPawn_Human(ImpactTarget);
KFPM_Victim=KFPawn_Monster(ImpactTarget);
doer=KFPlayerController(Instigator.Controller);
if(KFPM_Victim!=None && !KFPM_Victim.bIsHeadless)
{
HitZoneIndex=KFPM_Victim.HitZones.Find(‘ZoneName‘, Impact.HitInfo.BoneName);
if(HitZoneIndex == HZI_Head && KFPM != none && KFPM.IsAliveAndWell())
{
if(doer.GetPerk()==class‘KFPerk_FieldMedic‘)
{
doer.ServerTeamSay("[HMT401_BUFF]Healing AOE Triggered");
ForEach WorldInfo.AllControllers(class‘KFPlayerController‘, KFPC)
{
if(KFPC.Pawn!=None)
{
KFPC.Pawn.Health=Min(KFPC.Pawn.Health+1, KFPC.Pawn.HealthMax);
KFPC.TeamMessage(KFPC.PlayerReplicationInfo,"[HMT401_BUFF]Getting healed +2 by headshots from "$doer.PlayerReplicationInfo.PlayerName, ‘Event‘);
}
}
}
}
}
super.ProcessInstantHitEx(FiringMode, Impact, NumHits, out_PenetrationVal, ImpactNum);
}
defaultproperties
{
// Healing charge
HealAmount=20 //Changed from 15 to 20
HealFullRechargeSeconds=10
// Inventory
InventorySize=7
GroupPriority=100
WeaponSelectTexture=Texture2D‘ui_weaponselect_tex.UI_WeaponSelect_MedicAssault‘
SecondaryAmmoTexture=Texture2D‘UI_SecondaryAmmo_TEX.MedicDarts‘
// Shooting Animations
FireSightedAnims[0]=Shoot_Iron
FireSightedAnims[1]=Shoot_Iron2
FireSightedAnims[2]=Shoot_Iron3
// FOV
MeshFOV=75
MeshIronSightFOV=52
PlayerIronSightFOV=70
// Depth of field
DOF_FG_FocalRadius=85
DOF_FG_MaxNearBlurSize=2.5
Begin Object Name=FirstPersonMesh
SkeletalMesh=SkeletalMesh‘WEP_1P_Medic_Assault_MESH.Wep_1stP_Medic_Assault_Rig‘
AnimSets(0)=AnimSet‘WEP_1P_Medic_Assault_ANIM.Wep_1stP_Medic_Assault_Anim‘
End Object
Begin Object Name=StaticPickupComponent
StaticMesh=StaticMesh‘WEP_3P_Pickups_MESH.Wep_Medic_Assault_Pickup‘
End Object
AttachmentArchetype=KFWeaponAttachment‘WEP_Medic_Assault_ARCH.Wep_Medic_Assault_3P‘
// Zooming/Position
PlayerViewOffset=(X=15.0,Y=6.5,Z=-3)
IronSightPosition=(X=12,Y=0,Z=0)
// Ammo
MagazineCapacity[0]=30
SpareAmmoCapacity[0]=360
InitialSpareMags[0]=3
bCanBeReloaded=true
bReloadFromMagazine=true
// Recoil
maxRecoilPitch=200
minRecoilPitch=150
maxRecoilYaw=175
minRecoilYaw=-125
RecoilRate=0.085
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=900
RecoilMinPitchLimit=65035
RecoilISMaxYawLimit=75
RecoilISMinYawLimit=65460
RecoilISMaxPitchLimit=375
RecoilISMinPitchLimit=65460
IronSightMeshFOVCompensationScale=1.5
// DEFAULT_FIREMODE
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D‘ui_firemodes_tex.UI_FireModeSelect_BulletAuto‘
FiringStatesArray(DEFAULT_FIREMODE)=WeaponFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
WeaponProjectiles(DEFAULT_FIREMODE)=class‘KFProj_Bullet_AssaultRifle‘
InstantHitDamageTypes(DEFAULT_FIREMODE)=class‘KFDT_Ballistic_Assault_Medic‘
FireInterval(DEFAULT_FIREMODE)=+0.1 // 650 to 600
Spread(DEFAULT_FIREMODE)=0.0085
InstantHitDamage(DEFAULT_FIREMODE)=40
FireOffset=(X=30,Y=4.5,Z=-5)
// ALTFIRE_FIREMODE
AmmoCost(ALTFIRE_FIREMODE)=25 //decrease 16.7%
// BASH_FIREMODE
InstantHitDamage(BASH_FIREMODE)=27
InstantHitDamageTypes(BASH_FIREMODE)=class‘KFDT_Bludgeon_Assault_Medic‘
// Fire Effects
MuzzleFlashTemplate=KFMuzzleFlash‘WEP_Medic_Assault_ARCH.Wep_Medic_Assault_MuzzleFlash‘
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent‘WW_WEP_SA_MedicAssault.Play_SA_MedicAssault_Fire_3P_Loop‘, FirstPersonCue=AkEvent‘WW_WEP_SA_MedicAssault.Play_SA_MedicAssault_Fire_1P_Loop‘)
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent‘WW_WEP_SA_MedicAssault.Play_SA_MedicAssault_Fire_3P_Single‘, FirstPersonCue=AkEvent‘WW_WEP_SA_MedicAssault.Play_SA_MedicAssault_Fire_1P_Single‘)
WeaponFireLoopEndSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent‘WW_WEP_SA_MedicAssault.Play_SA_MedicAssault_Fire_3P_EndLoop‘, FirstPersonCue=AkEvent‘WW_WEP_SA_MedicAssault.Play_SA_MedicAssault_Fire_1P_EndLoop‘)
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent‘WW_WEP_SA_MedicAssault.Play_SA_MedicAssault_Handling_DryFire‘
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent‘WW_WEP_SA_MedicDart.Play_WEP_SA_Medic_Dart_DryFire‘
// Advanced (High RPM) Fire Effects
bLoopingFireAnim(DEFAULT_FIREMODE)=true
bLoopingFireSnd(DEFAULT_FIREMODE)=true
SingleFireSoundIndex=ALTFIRE_FIREMODE
// Attachments
bHasIronSights=true
bHasFlashlight=true
AssociatedPerkClasses(0)=class‘KFPerk_FieldMedic‘
AssociatedPerkClasses(1)=class‘KFPerk_Commando‘
}
参考Instant Healing Mut
http://www.cnblogs.com/ArHShRn/p/7140193.html
[Developing]HeadshotRecover Mut - 爆头回血插件 - Killing Floor 2
标签:stat load head auth elf process person res nat
原文地址:http://www.cnblogs.com/ArHShRn/p/7140201.html