[Developing]HeadshotRecover Mut - 爆头回血插件 - Killing Floor 2

目前正在翻看官方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( [email protected]()@[email protected]@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

时间: 2024-10-01 22:17:40

[Developing]HeadshotRecover Mut - 爆头回血插件 - Killing Floor 2的相关文章

[Developed]InstantHealing Mut - 即刻回血插件 - Killing Floor 2

目前待解决问题:不能与两个以上Mut并用 (如RestricPW) 待拓展功能:第一针效率100%,第二针+10%,第三针+20%:对于HMT401来说三针总共效率增加130% -- 原理: 扩展Mutator,利用 function ModifyPlayer(Pawn Other) /* called by GameInfo.RestartPlayer() change the players jumpz, etc. here */ function ModifyPlayer(Pawn Oth

jQuery封装tab选项卡组件(自定义自动功能和延迟显示功能)

效果图 tab.html <!DOCTYPE html> <html lang="zh-CN"><!-- 设置简体中文 --> <head> <meta charset="UTF-8"> <title>tab</title> <link rel="stylesheet" href="../css/base.css"> <lin

jQuery封装的tab组件(可选自动+可选延迟处理+按需加载)

效果图 tab2.html <!DOCTYPE html> <html lang="zh-CN"><!-- 设置简体中文 --> <head> <meta charset="UTF-8"> <title>tab2按需加载</title> <link rel="stylesheet" href="../css/base.css"> &

[KF2][Mut&amp;Gm Tutorial]Modding第二步:开始制作你的第一个简易Mutator

在这之前请确保 [KF2][Mut&Gm Tutorial]Modding第一步:设置好KF2的UnrealScript编译环境 如果你是一个电脑爱好者但是没有编程基础,请打开记事本或者npp跟着学习(下文统称初级玩家):如果你是一个编程爱好者或者Experienced Programmer(高级玩家),请按照以上文章配置好UsIDE跟着学习 注意:此教程制作出来的插件只适用于单人单机SOLO模式 涉及到服务器以及多人的插件 因为涉及到PRI和GRI等网络流对象(玩家网络复制信息 游戏网络复制信

无插件纯Web 3D机房,HTML5+WebGL倾力打造

前言 最近项目开发任务告一段落,刚好有时间整理这大半年的一些成果.使用html5时间还不久,对js的认识还不够深入.没办法,以前一直搞java,对js的一些语言特性和概念一时还转换不过来. 上一篇介绍了项目中做的一个彩虹爆炸图,主要用了 html5的canvas的2d绘制技术.这一回我想介绍一下项目中的一个亮点技术:html5的3D,以及如何用它打造精美的3D机房监控系统. 目标效果图 下图是客户给找的一张的效果参考图,希望机房至少能达到下面的3D效果. 懂的人都知道,这可是一张设计公司出的装修

ECSHOP 银联电子支付(ChinaPay)插件 掉用JAVA签名

帮客户集成接口时候发现客户网站PHP版本达不到要求 只要调用JAVA来解决问题<?php /** * ECSHOP 银联电子支付(ChinaPay)插件 * ============================================================================ * @author: qq:3037704620 * @email: 3037704620#qq.com * @date: 2017-01-02 */ if (!defined('IN_E

浮动【电梯】或【回到顶部】小插件:iElevator.js

iElevator.js 是一个jquery小插件,使用简单,兼容IE6,支持UMD和3种配置方式,比锚点更灵活. Default Options _defaults = { floors: null, btns: null, backtop: null, selected: '', sticky: -1, visible: { isHide: 'no', numShow: 0 }, speed: 400, show: function(me) { me.element.show(); }, h

推荐10款免费而优秀的图表插件

开发人员很多时候需要使用图表来表现一些数据,而一张图表往往能够比几行密密麻麻的数字表格更能直观地展示数据内容.随着Web技术的发展,从传统只能依靠于flash.IE的vml,各个浏览器尚不统一的svg,到如今规范统一的canvas.svg为代表的html5技术,表现点.线.面要素的技术已经越来越规范成熟.我在本篇文章中收集了10款免费开源且比较优秀的图表制作插件,以供各位参考. 1,ichartjs(国产) ichartjs是一款优秀的国产开源插件,作者是王鹤,英文名taylor,毕业于南昌大学

chrome http Request Header 修改插件

chrome http Request Header 修改插件 2013-05-31 11:03:03|  分类: JavaScript |  标签:chrome  extensions  change  http  header  |举报|字号 订阅 下载LOFTER我的照片书  | 最近因为需要搞 Chrome 的浏览器插件,所以了解了 Chrome Extensions 的一些基本知识.Chrome 插件都可以在以下目中找到. C:\Users\YouName\AppData\Local\