Compare commits

..

6 Commits
master ... dev

103 changed files with 2068 additions and 2658 deletions

View File

@ -107,10 +107,6 @@ function PostRender(Canvas C)
local int x, y, center, barWidth, offset;
local int missesWidth, missesHeight, missesSpace;
local int missesX, missesY;
local TeamInfo team;
local int healthToGive, totalExpectedHealth;
local float textWidth, textHeight;
local string textToDraw;
// local Vector CamPos, ViewDir;
// local Rotator CamRot;
// local float OffsetX, BarLength, BarHeight, XL, YL, posY;
@ -260,47 +256,6 @@ function PostRender(Canvas C)
}
}
//// Draw quad damage bar
if (nicePawn != none && nicePawn.quadDamageRemaining > 0.0)
{
C.SetDrawColor(255, 255, 255);
barTexture = redBar;
center = C.ClipX * 0.5;
y = C.ClipY * 0.45;
barWidth = C.ClipX * 0.2;
barWidth *= nicePawn.quadDamageRemaining / class'NiceSkillEnforcerBruteA'.default.maximumDamageAdded;
x = center - (barWidth / 2);
C.SetPos(x, y);
Log("DRAWING" @ x @ y @ barWidth);
C.DrawTile(barTexture, barWidth, 32, 0, 0, barTexture.MaterialUSize(), barTexture.MaterialVSize());
}//native(466) final function DrawTile( material Mat, float XL, float YL, float U, float V, float UL, float VL );
team = C.ViewPort.Actor.Pawn.PlayerReplicationInfo.Team;
//// Draw health still in regen timer
healthToGive = ScrnHumanPawn(C.ViewPort.Actor.Pawn).clientHealthToGive;
if (healthToGive > 0) {
totalExpectedHealth = healthToGive + C.ViewPort.Actor.Pawn.health;;
C.Font = class'ROHUD'.Static.LoadSmallFontStatic(3);
if (totalExpectedHealth >= C.ViewPort.Actor.Pawn.healthMax) {
if(team.teamIndex == 0) {
C.SetDrawColor(255, 64, 64);
}
else {
C.SetDrawColor(
team.teamColor.R,
team.teamColor.G,
team.teamColor.B);
}
}
else {
C.SetDrawColor(128, 128, 128);
}
textToDraw = "+" $ healthToGive;
C.TextSize(textToDraw, textWidth, textHeight);
C.SetPos(C.ClipX * 0.05, C.ClipY * 0.9);
C.DrawText(textToDraw);
}
//// Draw cooldowns
if (nicePlayer.abilityManager == none)
return;
@ -318,7 +273,7 @@ function PostRender(Canvas C)
{
if (niceMutator.niceCounterSet[i].value != 0 || niceMutator.niceCounterSet[i].bShowZeroValue)
{
DrawCounter(C, niceMutator.niceCounterSet[i], x, y, team);
DrawCounter(C, niceMutator.niceCounterSet[i], x, y, C.ViewPort.Actor.Pawn.PlayerReplicationInfo.Team);
x += 128 + 4;
}
}

View File

@ -74,8 +74,6 @@ State MatchInProgress{
function ScoreKill(Controller Killer, Controller Other)
{
local NicePlayerController niceKiller;
local NiceHumanPawn niceKillerPawn;
local PlayerReplicationInfo OtherPRI;
local float KillScore;
local Controller C;
@ -200,15 +198,7 @@ function ScoreKill(Controller Killer, Controller Other)
}
/* End Marco's Kill Messages */
niceKiller = NicePlayerController(killer);
if (niceKiller != none && niceKiller.abilityManager != none) {
niceKillerPawn = NiceHumanPawn(niceKiller.pawn);
niceKiller.abilityManager.AddToAllCooldowns(-1);
}
if ( niceKillerPawn != none && NiceBoomStick(niceKillerPawn.weapon) != none
&& other != none && other.pawn != none && other.pawn.default.health >= 1000) {
niceKillerPawn.invincibilityTimer += 1.0;
}
}
function DramaticEvent(float BaseZedTimePossibility, optional float DesiredZedTimeDuration){

View File

@ -46,11 +46,10 @@ struct InvincExtentions{
var array<InvincExtentions> zedInvExtList;
var int headshotStack;
var float bruteTimer;
var float quadDamageRemaining;
replication{
reliable if(Role == ROLE_Authority)
headshotStack, hmgShieldLevel, forcedZedTimeCountDown, maniacTimeout, invincibilityTimer, safeMeleeMisses, ffScale,
currentCalibrationState, calibrationScore, gunslingerTimer, quadDamageRemaining;
currentCalibrationState, calibrationScore, gunslingerTimer;
reliable if(Role == ROLE_Authority)
ClientChangeWeapon;
reliable if(Role < ROLE_AUTHORITY)
@ -70,7 +69,7 @@ function ReplaceRequiredEquipment()
RequiredEquipment[0] = string(class'NiceMachete');
RequiredEquipment[1] = string(class'Nice9mmPlus');
RequiredEquipment[2] = string(class'ScrnFrag');
RequiredEquipment[3] = string(class'ScrnSyringe');
RequiredEquipment[3] = string(class'NiceSyringe');
RequiredEquipment[4] = string(class'KFMod.Welder');
}
@ -737,7 +736,6 @@ simulated function TakeDamage(int Damage, Pawn InstigatedBy, Vector Hitlocation,
local float healPotency;
local bool bOldArmorStops;
local float adrResistance;
local float oldHealthToGive;
local NicePlayerController nicePlayer;
ApplyWeaponStats(Weapon);
if(invincibilityTimer > 0)
@ -768,12 +766,7 @@ simulated function TakeDamage(int Damage, Pawn InstigatedBy, Vector Hitlocation,
damageType.default.bArmorStops = true;
}
lastExplosionDistance = 0.0; // hack, but scrn fucks with usotherwise
oldHealthToGive = healthToGive; // remember this to restore this value, in case we are using safeguard skill
super.TakeDamage(Damage, InstigatedBy, hitLocation, Momentum, damageType, HitIndex);
if (class'NiceVeterancyTypes'.static.HasSkill(nicePlayer, class'NiceSkillHeavySafeguard')) {
healthToGive = oldHealthToGive;
clientHealthToGive = healthToGive;
}
// Commando's zed time
if( forcedZedTimeCountDown <= 0.0
&& health < class'NiceSkillCommandoCriticalFocus'.default.healthBoundary && KFGameType(Level.Game) != none
@ -796,7 +789,7 @@ simulated function TakeDamage(int Damage, Pawn InstigatedBy, Vector Hitlocation,
if(ShieldStrength < 0)
ShieldStrength = 0;
health += HealAmount * 0.5;
TakeHealing(self, HealAmount * 0.5 + 1, HealPotency);
TakeHealing(self, HealAmount * 0.5, HealPotency);
}
if(ShieldStrength <= 0)
getFreeJacket();

View File

@ -212,6 +212,20 @@ simulated function ClientPostLogin(){
// Change HUD parameters
class'ScrnHUD'.default.EnemyHealthBarHeight = 4.0;
}
// fix crooked camera after you die with active `ViewShake`
function StopViewShaking() {
ShakeRotMax = vect(0, 0, 0);
ShakeRotRate = vect(0, 0, 0);
ShakeRotTime = vect(0, 0, 0);
ShakeOffsetMax = vect(0, 0, 0);
ShakeOffsetRate = vect(0, 0, 0);
ShakeOffsetTime = vect(0, 0, 0);
// add missing variables
ShakeOffset = vect(0, 0, 0);
ShakeRot = Rot(0, 0, 0);
}
function ShowLobbyMenu(){
Super.ShowLobbyMenu();
}

View File

@ -71,7 +71,6 @@ simulated function CalculateDamageScales( out float scale1, out float scale2,
local Vector victimPoint1, victimPoint2;
local float swap;
victimPoint1 = victim.location;
victimPoint2.z += victim.CollisionHeight * 0.25;
victimPoint2 = victim.location;
victimPoint2.z += victim.CollisionHeight * 0.75;
scale1 = GetDamageScale(victim, explosionLocation, victimPoint1,
@ -94,55 +93,40 @@ simulated function ServerExplode
float momentum,
Vector explLocation,
Pawn instigator,
optional bool allowDoubleExplosion,
optional Actor explosionTarget,
optional vector explosiveDirection,
optional bool preventProximityHeadDamage
optional vector explosiveDirection
){
local Actor victim;
local int numKilled;
local Vector dirToVictim;
local Vector hitLocation;
local float scale1, scale2;
local NiceMonster niceVictim;
if(Role < ROLE_Authority) return;
foreach VisibleActors(class'Actor', victim, explRadius, explLocation){
if(victim == none || victim == self) continue;
if(victim.role < ROLE_Authority) continue;
if(ExtendedZCollision(victim) != none) continue;
if(Trigger(victim) != none) continue;
niceVictim = NiceMonster(victim);
dirToVictim = Normal(victim.location - explLocation);
hitLocation = victim.location - 0.5 *
(victim.collisionHeight + victim.collisionRadius) * dirToVictim;
CalculateDamageScales( scale1, scale2,
victim, explLocation, explRadius, explExp);
// Deal head damage if explosion is close enough to the victim's head
if ( niceVictim != none && !preventProximityHeadDamage
&& niceVictim.GetDistanceToHead(explLocation) <= explRadius * 0.1)
{
ServerDealDamage( victim, explDamage, instigator,
hitLocation, 0.0 * dirToVictim,
explDmgType, 0.5);
}
// Deal main damage
if(scale1 > 0 || scale2 > 0) {
ServerDealDamage(
victim,
explDamage * FMax(scale1, scale2),
instigator,
hitLocation,
FMax(scale1, scale2) * momentum * dirToVictim,
if(scale1 > 0){
ServerDealDamage( victim, explDamage * scale1, instigator,
hitLocation, scale1 * momentum * dirToVictim,
explDmgType);
}
if(niceVictim != none) {
if (niceVictim.health <= 0) {
numKilled += 1;
}
else {
niceVictim.concussionCountdown = 10.0;
}
// Deal secondary damage
if(allowDoubleExplosion && victim != none && scale2 > 0){
ServerDealDamage( victim, explDamage * scale2, instigator,
hitLocation, scale2 * momentum * dirToVictim,
explDmgType);
}
if(NiceMonster(victim) != none && NiceMonster(victim).health <= 0)
numKilled ++;
}
if(numKilled >= 4)
KFGameType(level.game).DramaticEvent(0.05);
@ -219,45 +203,34 @@ simulated function RemovePoisonAndBleed(NiceHumanPawn healed)
}
// Tells server to heal given human pawn.
simulated function ServerHealTarget(
NiceHumanPawn healed,
float charPotency,
Pawn instigator
) {
simulated function ServerHealTarget(NiceHumanPawn healed, float charPotency,
Pawn instigator){
local NiceHumanPawn healer;
local PlayerController healedPC;
local KFPlayerReplicationInfo KFPRI;
local NiceMedicGun healingTool;
local float healTotal;
local float healPotency;
if(instigator == none || healed == none) return;
if(healed.health <= 0 || healed.health >= healed.healthMax) return;
KFPRI = KFPlayerReplicationInfo(instigator.PlayerReplicationInfo);
if(KFPRI == none || KFPRI.ClientVeteranSkill == none) return;
if(KFPRI == none || KFPRI.ClientVeteranSkill == none)
return;
healer = NiceHumanPawn(instigator);
if(healer == none) return;
healingTool = NiceMedicGun(healer.weapon);
if(healer == none)
return;
healPotency = KFPRI.ClientVeteranSkill.static.GetHealPotency(KFPRI);
healTotal = charPotency * healPotency;
healer.AlphaAmount = 255;
if(healingTool != none) {
healingTool.ClientSuccessfulHeal(healer, healed);
}
healedPC = PlayerController(healed.controller);
if(healedPC != none) {
healedPC.ClientMessage(
"You've been healed by" @ healer.GetPlayerName(),
'CriticalEvent');
}
if(NiceMedicGun(healer.weapon) != none)
NiceMedicGun(healer.weapon).ClientSuccessfulHeal(healer, healed);
if(healed.health >= healed.healthMax){
healed.GiveHealth(healTotal, healed.healthMax);
return;
}
HandleNiceHealingMechanicsAndSkills(healer, healed, healPotency);
if(healed.health < healed.healthMax){
healed.TakeHealing(healed, healTotal, healPotency, healingTool);
healed.TakeHealing( healed, healTotal, healPotency,
KFWeapon(instigator.weapon));
}
RemovePoisonAndBleed(healed);
}
@ -288,6 +261,9 @@ simulated function HandleNiceDamageMechanicsAndSkills
hasSkill(nicePlayer, class'NiceSkillCommandoTranquilizer');
hasZEDFrenzy = class'NiceVeterancyTypes'.static.
hasSkill(nicePlayer, class'NiceSkillMedicZEDFrenzy');
// Medic's suppression
if(hasTranquilizer)
niceZed.mind = FMin(niceZed.mind, 0.5);
// Medic's frenzy
if(hasZEDFrenzy && nicePlayer.IsZedTimeActive()){
niceZed.madnessCountDown =

View File

@ -128,7 +128,7 @@ function bool PreventDeath(Pawn Killed, Controller Killer, class<DamageType> dam
class'NiceSkillDemoReactiveArmor'.default.explExponent,
class'NiceDamTypeDemoSafeExplosion',
class'NiceSkillDemoReactiveArmor'.default.explMomentum,
killed.location, killed
killed.location, killed, true
);
return true;
}

View File

@ -29,7 +29,7 @@ struct NiceAbilityDescription{
// Image to be used as an ability's icon
var Texture icon;
// Default cooldown duration
var int cooldownLength;
var float cooldownLength;
// Can ability be canceled once activated?
var bool canBeCancelled;
};
@ -39,7 +39,7 @@ struct NiceAbilityStatus{
// Complete description of ability in question
var NiceAbilityDescription description;
// Current cooldown value
var int cooldown;
var float cooldown;
// Current state of an ability
var EAbilityState myState;
};
@ -65,7 +65,7 @@ function AddAbility(NiceAbilityDescription description){
if(currentAbilities[i].description.ID ~= description.ID)
return;
newRecord.description = description;
newRecord.cooldown = 0;
newRecord.cooldown = 0.0;
newRecord.myState = ASTATE_READY;
currentAbilities[currentAbilitiesAmount] = newRecord;
currentAbilitiesAmount += 1;
@ -147,7 +147,7 @@ function SetAbilityState(int abilityIndex, EAbilityState newState){
// Changes ability's cooldown by a given amount.
// If this brings cooldown to zero or below -
// resets current ability to a 'ready' (ASTATE_READY) state.
function AddToCooldown(int abilityIndex, int delta){
function AddToCooldown(int abilityIndex, float delta){
if(abilityIndex < 0 || abilityIndex >= currentAbilitiesAmount) return;
if(currentAbilities[abilityIndex].myState != ASTATE_COOLDOWN) return;
currentAbilities[abilityIndex].cooldown += delta;
@ -155,21 +155,12 @@ function AddToCooldown(int abilityIndex, int delta){
SetAbilityState(abilityIndex, ASTATE_READY);
hackCounter ++;
}
function AddToAllCooldowns(int delta){
function Tick(float deltaTime){
local int i;
for (i = 0; i < currentAbilitiesAmount; i += 1) {
if (currentAbilities[i].myState == ASTATE_COOLDOWN) {
currentAbilities[i].cooldown += delta;
if(currentAbilities[i].cooldown <= 0) {
SetAbilityState(i, ASTATE_READY);
if(Role != Role_AUTHORITY) return;
for(i = 0;i < currentAbilitiesAmount;i ++)
AddToCooldown(i, -deltaTime);
}
}
}
hackCounter ++;
}
defaultproperties
{
maxAbilitiesAmount=5

View File

@ -1,4 +1,4 @@
class NiceDamTypeMedicDart extends NiceDamageTypeVetDemolitions
class NiceDamTypeMedicDart extends NiceDamageTypeVetCommando
abstract;
defaultproperties
{

View File

@ -35,16 +35,6 @@ static function float GetMagCapacityMod(KFPlayerReplicationInfo KFPRI, KFWeapon
return class'NiceSkillCommandoLargerMags'.default.sizeBonus;
return 1.0;
}
// Change the cost of particular ammo
static function float GetAmmoCostScaling(KFPlayerReplicationInfo KFPRI, class<Pickup> Item)
{
local class<NiceWeaponPickup> pickupClass;
pickupClass = class<NiceWeaponPickup>(Item);
if(IsPerkedPickup(pickupClass) && HasSkill(NicePlayerController(KFPRI.Owner), class'NiceSkillCommandoLargerMags')) {
return class'NiceSkillCommandoLargerMags'.default.sizeBonus;
}
return 1.0;
}
static function float GetSyringeChargeRate(KFPlayerReplicationInfo KFPRI){
return 1.5;
}
@ -112,7 +102,7 @@ defaultproperties
OnHUDIcons(3)=(PerkIcon=Texture'ScrnTex.Perks.Perk_Commando_Blue',StarIcon=Texture'ScrnTex.Perks.Hud_Perk_Star_Blue',DrawColor=(B=255,G=255,R=255,A=255))
OnHUDIcons(4)=(PerkIcon=Texture'ScrnTex.Perks.Perk_Commando_Purple',StarIcon=Texture'ScrnTex.Perks.Hud_Perk_Star_Purple',DrawColor=(B=255,G=255,R=255,A=255))
OnHUDIcons(5)=(PerkIcon=Texture'ScrnTex.Perks.Perk_Commando_Orange',StarIcon=Texture'ScrnTex.Perks.Hud_Perk_Star_Orange',DrawColor=(B=255,G=255,R=255,A=255))
CustomLevelInfo="Level up by doing damage with perked weapons|15% faster reload with all weapons|10% faster movement speed|You get four additional Zed-Time Extensions|See health and cloaked zeds from 16 meters distance|Better Syringe handling"
CustomLevelInfo="Level up by doing damage with perked weapons|15% faster reload with all weapons|10% faster movement speed|You get four additional Zed-Time Extensions|See health and cloacked zeds from 16 meters distance|Better Syringe handling"
PerkIndex=3
OnHUDIcon=Texture'KillingFloorHUD.Perks.Perk_Commando'
OnHUDGoldIcon=Texture'KillingFloor2HUD.Perk_Icons.Perk_Commando_Gold'

View File

@ -8,7 +8,6 @@ static function GetHitEffects(out class<xEmitter> HitEffects[4], int VictimHealt
}
defaultproperties
{
stoppingPower=0.5
stunMultiplier=0.600000
bIsExplosive=True
DeathString="%o filled %k's body with shrapnel."

View File

@ -39,13 +39,12 @@ static function int AddDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injured,
perkDamage = float(InDamage);
if(DmgType == class'NiceDamTypeDemoExplosion')
return 1.6 * perkDamage;
if(IsPerkedPickup(pickupClass) && class<NiceDamTypeDemoExplosion>(DmgType) != none)
if(IsPerkedPickup(pickupClass))
perkDamage *= 1.25;
else if( pickupClass != none && pickupClass.default.weight <= class'NiceSkillDemoOffperk'.default.weightBound
&& HasSkill(NicePlayerController(KFPRI.Owner), class'NiceSkillDemoOffperk') )
perkDamage *= class'NiceSkillDemoOffperk'.default.damageBonus;
if( KFPRI != none && class<NiceDamTypeDemoExplosion>(DmgType) == none
&& IsPerkedPickup(pickupClass)
if( KFPRI != none && class<NiceDamTypeDemoBlunt>(DmgType) != none
&& SomeoneHasSkill(NicePlayerController(KFPRI.Owner), class'NiceSkillDemoOnperk') )
perkDamage *= class'NiceSkillDemoOnperk'.default.damageBonus;
return perkDamage;

View File

@ -15,6 +15,7 @@ static function AbilityActivated(
NicePlayerController relatedPlayer)
{
local NiceHumanPawn nicePawn;
local NiceMonster victim;
if (relatedPlayer == none) return;
nicePawn = NiceHumanPawn(relatedPlayer.pawn);
@ -36,23 +37,6 @@ static function AbilityActivated(
{
nicePawn.bruteTimer =
class'NiceSkillEnforcerBruteA'.default.abilityDuration;
nicePawn.quadDamageRemaining = class'NiceSkillEnforcerBruteA'.default.maximumDamageAdded;
}
}
static function ModAbilityCooldown( string abilityID,
NicePlayerController relatedPlayer,
out float cooldown)
{
local NiceHumanPawn nicePawn;
if (relatedPlayer == none) return;
nicePawn = NiceHumanPawn(relatedPlayer.pawn);
if (nicePawn == none) return;
if (abilityID == "brute")
{
nicePawn.quadDamageRemaining = 0;
}
}

View File

@ -16,15 +16,12 @@ static function array<int> GetProgressArray(byte ReqNum, optional out int Double
// Other bonuses
static function int AddDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injured, KFPawn DamageTaker, int InDamage, class<DamageType> DmgType)
{
local int bruteAbilityIndex;
local float fDamage, addedDamage;
local float fDamage;
local NicePlayerController nicePlayer;
local NiceHumanPawn nicePawn;
local NiceMonster niceTarget;
fDamage = float(InDamage);
nicePlayer = NicePlayerController(KFPRI.Owner);
nicePawn = NiceHumanPawn(nicePlayer.pawn);
niceTarget = NiceMonster(injured);
if ( niceTarget != none
&& niceTarget.bFrozenZed
@ -34,20 +31,9 @@ static function int AddDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injured,
(1 + class'NiceSkillEnforcerFinisherRounds'.default.damageBonus);
}
if( nicePlayer != none && nicePlayer.abilityManager != none
&& nicePawn != none && nicePawn.quadDamageRemaining > 0
&& nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillEnforcerBruteA'.default.abilityID))
{
addedDamage = fDamage * class'NiceSkillEnforcerBruteA'.default.damageMult - fDamage;
if (addedDamage >= nicePawn.quadDamageRemaining) {
addedDamage = nicePawn.quadDamageRemaining;
nicePawn.quadDamageRemaining = 0.0;
bruteAbilityIndex = nicePlayer.abilityManager.GetAbilityIndex(class'NiceSkillEnforcerBruteA'.default.abilityID);
nicePlayer.abilityManager.SetAbilityState(bruteAbilityIndex, ASTATE_COOLDOWN);
}
else {
nicePawn.quadDamageRemaining -= addedDamage;
}
fDamage += addedDamage;
fDamage *= class'NiceSkillEnforcerBruteA'.default.damageMult;
}
return int(fDamage);
}
@ -78,6 +64,15 @@ static function class<Grenade> GetNadeType(KFPlayerReplicationInfo KFPRI){
return class'NiceCryoNade';
}
static function float AddExtraAmmoFor(KFPlayerReplicationInfo KFPRI, Class<Ammunition> AmmoType){
local float bonusNades;
// Default bonus
bonusNades = 2;
if(AmmoType == class'FragAmmo')
return 1.0 + 0.2 * bonusNades;
return 1.0;
}
static function int ReduceDamage(KFPlayerReplicationInfo KFPRI, KFPawn Injured, Pawn Instigator, int InDamage, class<DamageType> DmgType){
local float fDamage;
fDamage = float(inDamage);
@ -185,7 +180,7 @@ defaultproperties
SkillGroupA(4)=class'NiceSkillEnforcerZEDBarrage'
SkillGroupB(0)=class'NiceSkillEnforcerUnkillable'
SkillGroupB(1)=class'NiceSkillEnforcerMultitasker'
SkillGroupB(2)=class'NiceSkillHeavySafeguard'
SkillGroupB(2)=class'NiceSkillEnforcerFinisherRounds'
SkillGroupB(3)=class'NiceSkillEnforcerBruteA'
SkillGroupB(4)=class'NiceSkillEnforcerZEDIceGiant'
progressArray0(0)=100

View File

@ -7,5 +7,5 @@ defaultproperties
stunMult=3.000000
spreadMult=0.500000
SkillName="Bombard"
SkillEffects="Your perked weapons are 3 times as good at stunning and have omly half as much spread."
SkillEffects="Your perked weapons are 3 times as good at stunning."
}

View File

@ -5,7 +5,6 @@ var string abilityID;
var float coolDown;
var float abilityDuration;
var float damageMult;
var float maximumDamageAdded;
function static SkillSelected(NicePlayerController nicePlayer)
{
@ -30,7 +29,6 @@ function static SkillDeSelected(NicePlayerController nicePlayer)
defaultproperties
{
maximumDamageAdded=10000
abilityID="brute"
cooldown=60.000000
abilityDuration=5.0

View File

@ -219,6 +219,8 @@ static function int AddRegDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injure
}
// Allows to buff only fire component of damage.
static function int AddFireDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injured, KFPawn DamageTaker, int InDamage, class<NiceWeaponDamageType> DmgType){
if(DmgType != none)
return InDamage * DmgType.default.heatPart;
return InDamage;
}
static function float stunDurationMult(KFPlayerReplicationInfo KFPRI, KFMonster Injured, KFPawn DamageTaker, class<NiceWeaponDamageType> DmgType){

View File

@ -3,5 +3,4 @@ class NiceHeavyFire extends NiceFire;
defaultproperties
{
maxBonusContLenght=3
aimingSpreadReductionCoefficient = 0.0
}

View File

@ -66,19 +66,15 @@ simulated function WeaponTick(float dt){
}
super.WeaponTick(dt);
}
simulated function ClientSuccessfulHeal(
NiceHumanPawn healer,
NiceHumanPawn healed
){
if(healed == none) {
simulated function ClientSuccessfulHeal(NiceHumanPawn healer, NiceHumanPawn healed){
if(healed == none)
return;
}
if(instigator != none && PlayerController(instigator.controller) != none) {
PlayerController(instigator.controller).ClientMessage(
"You've healed" @ healed.GetPlayerName(),
'CriticalEvent');
}
if(instigator != none && PlayerController(instigator.controller) != none)
PlayerController(instigator.controller).
ClientMessage("You've healed"@healed.GetPlayerName(), 'CriticalEvent');
if(NiceHumanPawn(instigator) != none && PlayerController(healed.controller) != none)
PlayerController(healed.controller).
ClientMessage("You've been healed by"@healer.GetPlayerName(), 'CriticalEvent');
}
defaultproperties

View File

@ -18,47 +18,31 @@ var Shader ScopeScriptedShader; // The shader that combi
var Material ScriptedTextureFallback; // The texture to render if the users system doesn't support shaders
// new scope vars
var Combiner ScriptedScopeCombiner;
var Material TexturedScopeTexture;
var texture TexturedScopeTexture;
var bool bInitializedScope; // Set to true when the scope has been initialized
var string ZoomMatRef;
var string ScriptedTextureFallbackRef;
var Material CrosshairTex;
var texture CrosshairTex;
var string CrosshairTexRef;
static function Material PreloadUnknownMaterial(string reference) {
local Material result;
// Try to load as various types of materials
result = FinalBlend(DynamicLoadObject(reference, class'FinalBlend', true));
if(result != none) {
return result;
}
result = Combiner(DynamicLoadObject(reference, class'Combiner', true));
if(result != none) {
return result;
}
result = Shader(DynamicLoadObject(reference, class'Shader', true));
if(result != none) {
return result;
}
result = Texture(DynamicLoadObject(reference, class'Texture', true));
if(result != none) {
return result;
}
result = Material(DynamicLoadObject(reference, class'Material'));
return result;
}
static function PreloadAssets(Inventory Inv, optional bool bSkipRefCount){
local NiceScopedWeapon W;
super.PreloadAssets(Inv, bSkipRefCount);
if(default.ZoomMat == none && default.ZoomMatRef != ""){
default.ZoomMat = PreloadUnknownMaterial(default.ZoomMatRef);
// Try to load as various types of materials
default.ZoomMat = FinalBlend(DynamicLoadObject(default.ZoomMatRef, class'FinalBlend', true));
if(default.ZoomMat == none)
default.ZoomMat = Combiner(DynamicLoadObject(default.ZoomMatRef, class'Combiner', true));
if(default.ZoomMat == none)
default.ZoomMat = Shader(DynamicLoadObject(default.ZoomMatRef, class'Shader', true));
if(default.ZoomMat == none)
default.ZoomMat = Texture(DynamicLoadObject(default.ZoomMatRef, class'Texture', true));
if(default.ZoomMat == none)
default.ZoomMat = Material(DynamicLoadObject(default.ZoomMatRef, class'Material'));
}
if(default.ScriptedTextureFallback == none && default.ScriptedTextureFallbackRef != "")
default.ScriptedTextureFallback = PreloadUnknownMaterial(default.ScriptedTextureFallbackRef);
default.ScriptedTextureFallback = texture(DynamicLoadObject(default.ScriptedTextureFallbackRef, class'texture'));
if(default.CrosshairTex == none && default.CrosshairTexRef != "")
default.CrosshairTex = PreloadUnknownMaterial(default.CrosshairTexRef);
default.CrosshairTex = Texture(DynamicLoadObject(default.CrosshairTexRef, class'texture'));
W = NiceScopedWeapon(Inv);
if(W != none){
W.ZoomMat = default.ZoomMat;

View File

@ -14,7 +14,6 @@ var float prReqPrecise; // How precise must head-shot be
var float lockonTime;
var float flinchMultiplier; // How effective is weapon for flinching zeds
var float stunMultiplier; // How effective is weapon for stunning zeds
var float stunLengthMultiplier; // For how long is weapon going to stun zeds
var float heatPart; // How much of this damage should be a heat component?
var float freezePower; // How good is weapon at freezing?
var float bodyDestructionMult; // How much more damage do to body on a head-shot?
@ -28,7 +27,6 @@ var const int MediumZedMinHealth; // If zed's base Health >= this
var float PenDmgReduction; // Penetration damage reduction after hitting small zed
var float penDecapReduction; // Penetration decapitaion effectiveness reduction after hitting small zed
var float penIncapReduction; // Penetration incapacitation (flinch or stun) effectiveness reduction after hitting small zed
var float stoppingPower; // How much stopping power the gun has - % amount zeds will be made to slow down when shot
var bool bIsProjectile; // If original damage type's version was derived from 'KFProjectileWeaponDamageType', then set this to true
// Scales exp gain according to given HardcoreLevel
static function float getScale(int HL){
@ -85,13 +83,11 @@ defaultproperties
prReqPrecise=0.750000
flinchMultiplier=1.000000
stunMultiplier=1.000000
stunLengthMultiplier=1.000000
bodyDestructionMult=1.000000
headSizeModifier=1.000000
BigZedPenDmgReduction=0.500000
BigZedMinHealth=1000
MediumZedPenDmgReduction=0.750000
stoppingPower=0.0
MediumZedMinHealth=500
PenDmgReduction=0.700000
PawnDamageEmitter=None

View File

@ -12,7 +12,6 @@
// E-mail: dkanus@gmail.com
//======================================================================================================================
class NiceBullet extends Actor;
// Link to interaction with the server
var NiceReplicationInfo niceRI;
// Controller of our instigator
@ -21,6 +20,7 @@ var NicePlayerController nicePlayer;
var NicePlayerController localPlayer;
// Link to our mutator
var NicePack niceMutator;
//======================================================================================================================
// Battle bullet characteristic
var float charOrigDamage;
@ -180,29 +180,22 @@ var string ambientSoundRef;
//======================================================================================================================
// Functions
static function PreloadAssets(){
if (default.ambientSound == none && default.ambientSoundRef != "") {
if(default.ambientSound == none && default.ambientSoundRef != "")
default.ambientSound = sound(DynamicLoadObject(default.ambientSoundRef, class'Sound', true));
}
if (default.staticMesh == none && default.staticMeshRef != "") {
if(default.staticMesh == none && default.staticMeshRef != "")
UpdateDefaultStaticMesh(StaticMesh(DynamicLoadObject(default.staticMeshRef, class'StaticMesh', true)));
}
if (default.mesh == none && default.meshRef != "") {
if(default.mesh == none && default.meshRef != "")
UpdateDefaultMesh(Mesh(DynamicLoadObject(default.meshRef, class'Mesh', true)));
}
if (default.regularImpact.noise == none && default.regularImpact.noiseRef != "") {
if(default.regularImpact.noise == none && default.regularImpact.noiseRef != "")
default.regularImpact.noise =
sound(DynamicLoadObject(default.regularImpact.noiseRef, class'Sound', true));
}
if (default.explosionImpact.noise == none && default.explosionImpact.noiseRef != "") {
if(default.explosionImpact.noise == none && default.explosionImpact.noiseRef != "")
default.explosionImpact.noise =
sound(DynamicLoadObject(default.explosionImpact.noiseRef, class'Sound', true));
}
if (default.disintegrationImpact.noise == none && default.disintegrationImpact.noiseRef != "") {
if(default.disintegrationImpact.noise == none && default.disintegrationImpact.noiseRef != "")
default.disintegrationImpact.noise =
sound(DynamicLoadObject(default.disintegrationImpact.noiseRef, class'Sound', true));
}
}
static function bool UnloadAssets(){
default.AmbientSound = none;
UpdateDefaultStaticMesh(none);
@ -212,26 +205,20 @@ static function bool UnloadAssets() {
default.disintegrationImpact.noise = none;
return true;
}
function PostBeginPlay(){
super.PostBeginPlay();
bounceHeadMod = 1.0;
}
function UpdateTrails(){
local Actor trailBase;
// Do nothing on dedicated server
if (Level.NetMode == NM_DedicatedServer) {
if(Level.NetMode == NM_DedicatedServer)
return;
}
// Spawn necessary trails first
if (trailClass != none && bulletTrail == none) {
if(trailClass != none && bulletTrail == none)
bulletTrail = Spawn(trailClass, self);
}
if (trailXClass != none && bulletXTrail == none) {
if(trailXClass != none && bulletXTrail == none)
bulletXTrail = Spawn(trailXClass, self);
}
// Handle positioning differently for stuck and regular projectiles
if(bStuck && base != none){
if(bUseBone){
@ -248,30 +235,25 @@ function UpdateTrails() {
bulletXTrail.SetRelativeRotation(relativeRotation);
}
}
} else {
trailBase = self;
}
else
trailBase = self;
// Update lifetime and base (latter is for non-bone attachments only)
if(bulletTrail != none){
if (trailBase != none) {
if(trailBase != none)
bulletTrail.SetBase(trailBase);
}
bulletTrail.lifespan = lifeSpan;
}
if(bulletXTrail != none){
if (trailBase != none) {
if(trailBase != none)
bulletXTrail.SetBase(trailBase);
}
bulletXTrail.lifespan = lifeSpan;
}
}
function ResetPathBuilding(){
finishedSegmentPart = -1.0;
shiftPoint = location;
}
// Resets default values for this bullet.
// Must be called before each new use of a bullet.
function Renew(){
@ -284,129 +266,98 @@ function Renew() {
ResetIgnoreList();
ResetPathBuilding();
}
simulated function Tick(float delta){
super.Tick(delta);
if (localPlayer == none) {
if(localPlayer == none)
localPlayer = NicePlayerController(Level.GetLocalPlayerController());
}
if(charFuseTime > 0){
charFuseTime -= delta;
if(charFuseTime < 0){
if(charExplodeOnFuse && !charIsDud){
GenerateImpactEffects(explosionImpact, location, movementDirection);
if (bStuck) {
if(bStuck)
class'NiceBulletAdapter'.static.Explode(self, niceRI, location, base);
} else {
else
class'NiceBulletAdapter'.static.Explode(self, niceRI, location);
}
}
if (!charExplodeOnFuse) {
if(!charExplodeOnFuse)
GenerateImpactEffects(disintegrationImpact, location, movementDirection);
}
KillBullet();
}
}
if(bInitFinished && !bInitFinishDetected){
bInitFinishDetected = true;
UpdateTrails();
}
if (bInitFinished && !bBulletDead && !bStuck) {
if(bInitFinished && !bBulletDead && !bStuck)
DoProcessMovement(delta);
}
if(bInitFinished && bStuck){
if (base == none || (KFMonster(base) != none && KFMonster(base).health <= 0)) {
if(base == none || (KFMonster(base) != none && KFMonster(base).health <= 0))
nicePlayer.ExplodeStuckBullet(stuckID);
}
}
}
// Extracts pawn actor from it's auxiliary collision
// @param other Actor we collided with
// @return Pawn we're interested in
function Actor GetMainActor(Actor other){
if (other == none) {
if(other == none)
return none;
}
if (!other.IsA('KFPawn') && !other.IsA('KFMonster')) {
// Try owner
if (other.owner.IsA('KFPawn') || other.owner.IsA('KFMonster')) {
return other.owner;
}
if( KFPawn(other) == none && KFMonster(other) == none
&& (KFPawn(other.owner) != none || KFMonster(other.owner) != none) )
other = other.owner;
// Try base
if (other.base.IsA('KFPawn') || other.base.IsA('KFMonster')) {
return other.base;
}
}
if( KFPawn(other) == none && KFMonster(other) == none
&& (KFPawn(other.base) != none || KFMonster(other.base) != none) )
other = other.base;
return other;
}
// Returns 'true' if passed actor is either world geometry, 'Level' itself or nothing ('none')
// Neither of these related to pawn damage dealing
function bool IsLevelActor(Actor other){
if (other == none) {
if(other == none)
return true;
}
return (other.bWorldGeometry || other == Level);
}
// Adds given actor and every colliding object connected to it to ignore list
// Removes their collision in case ignore is active (see 'bIgnoreIsActive')
function TotalIgnore(Actor other){
// These mark what objects, associated with 'other' we also need to ignore
local KFPawn pawnOther;
local KFMonster zedOther;
if (other == none) {
if(other == none)
return;
}
// Try to find main actor as KFPawn
pawnOther = KFPawn(other);
if (pawnOther == none) {
if(pawnOther == none)
pawnOther = KFPawn(other.base);
}
if (pawnOther == none) {
if(pawnOther == none)
pawnOther = KFPawn(other.owner);
}
// Try to find main actor as KFMonster
zedOther = KFMonster(other);
if (zedOther == none) {
if(zedOther == none)
zedOther = KFMonster(other.base);
}
if (zedOther == none) {
if(zedOther == none)
zedOther = KFMonster(other.owner);
}
// Ignore everything that's associated with this actor and can have collision
IgnoreActor(other);
IgnoreActor(other.base);
IgnoreActor(other.owner);
if (pawnOther != none) {
if(pawnOther != none)
IgnoreActor(pawnOther.AuxCollisionCylinder);
}
if (zedOther != none) {
if(zedOther != none)
IgnoreActor(zedOther.MyExtCollision);
}
}
// Adds a given actor to ignore list and removes it's collision in case ignore is active (see 'bIgnoreIsActive')
function IgnoreActor(Actor other){
local int i;
local IgnoreEntry newIgnoredEntry;
// Check if that's a non-level actor and not already on the list
if (IsLevelActor(other)) {
if(IsLevelActor(other))
return;
}
for (i = 0; i < ignoredActors.Length; i ++) {
if (ignoredActors[i].ignored == other) {
for(i = 0;i < ignoredActors.Length;i ++)
if(ignoredActors[i].ignored == other)
return;
}
}
// Add actor to the ignore list & disable collision if needed
if(other != none){
// Make entry
@ -414,63 +365,47 @@ function IgnoreActor(Actor other) {
newIgnoredEntry.bExtDisabled = !other.bCollideActors;
// Add and activate it
ignoredActors[ignoredActors.Length] = newIgnoredEntry;
if (bIgnoreIsActive) {
if(bIgnoreIsActive)
other.SetCollision(false);
}
}
}
// Restores ignored state of the actors and zeroes our ignored arrays
function ResetIgnoreList(){
SetIgnoreActive(false);
ignoredActors.Length = 0;
}
// Activates/deactivates ignore for actors on the ignore list.
// Ignore deactivation doesn't restore collision if actor was set to not collide prior most recent ignore activation.
// Activating ignore when it's already active does nothing; same with deactivation.
// Ignore deactivation is supposed to be used in the same function call in which activation took place before.
function SetIgnoreActive(bool bActive){
local int i;
// Do nothing if we're already in a correct state
if (bActive == bIgnoreIsActive) {
if(bActive == bIgnoreIsActive)
return;
}
// Change ignore state & disable collision for ignored actors
bIgnoreIsActive = bActive;
for (i = 0; i < ignoredActors.Length; i ++) {
for(i = 0;i < ignoredActors.Length;i ++)
if(ignoredActors[i].ignored != none){
// Mark actors that were set to not collide before activation
if (bActive && !ignoredActors[i].ignored.bCollideActors) {
if(bActive && !ignoredActors[i].ignored.bCollideActors)
ignoredActors[i].bExtDisabled = true;
}
// Change collision for actors that weren't externally modified
if (!ignoredActors[i].bExtDisabled) {
if(!ignoredActors[i].bExtDisabled)
ignoredActors[i].ignored.SetCollision(!bActive);
}
// After we deactivated our rules - forget about external modifications
if (!bActive) {
if(!bActive)
ignoredActors[i].bExtDisabled = false;
}
}
}
}
function SetHumanPawnCollision(bool bEnable){
local int i;
if (niceMutator == none) {
if(niceMutator == none)
niceMutator = class'NicePack'.static.Myself(Level);
}
for (i = 0; i < niceMutator.recordedHumanPawns.Length; i ++) {
if (niceMutator.recordedHumanPawns[i] != none) {
for(i = 0;i < niceMutator.recordedHumanPawns.Length;i ++)
if(niceMutator.recordedHumanPawns[i] != none)
niceMutator.recordedHumanPawns[i].bBlockHitPointTraces = bEnable;
}
}
}
function float CheckHeadshot(KFMonster kfZed, Vector hitLocation, Vector hitDirection){
local float hsMod;
local float precision;
@ -478,7 +413,6 @@ function float CheckHeadshot(KFMonster kfZed, Vector hitLocation, Vector hitDire
local NiceMonster niceZed;
local KFPlayerReplicationInfo KFPRI;
local class<NiceVeterancyTypes> niceVet;
niceZed = NiceMonster(kfZed);
hitDirection = Normal(hitDirection);
bIsShotgunBullet = ClassIsChildOf(charDamageType, class'NiceDamageTypeVetEnforcer');
@ -486,36 +420,27 @@ function float CheckHeadshot(KFMonster kfZed, Vector hitLocation, Vector hitDire
hsMod = bounceHeadMod; // NICETODO: Add bounce and perk and damage type head-shot zones bonuses
hsMod *= charDamageType.default.headSizeModifier;
hsMod *= bounceHeadMod;
if (nicePlayer != none) {
if(nicePlayer != none)
KFPRI = KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo);
}
if (KFPRI != none) {
if(KFPRI != none)
niceVet = class<NiceVeterancyTypes>(KFPRI.ClientVeteranSkill);
}
if (niceVet != none) {
if(niceVet != none)
hsMod *= niceVet.static.GetHeadshotCheckMultiplier(KFPRI, charDamageType);
}
precision = niceZed.IsHeadshotClient(hitLocation, hitDirection, niceZed.clientHeadshotScale * hsMod);
if (
precision <= 0.0 &&
bIsShotgunBullet &&
nicePlayer != none &&
class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillSupportGraze')
) {
if(precision <= 0.0 && bIsShotgunBullet && nicePlayer != none && class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillSupportGraze')){
bGrazing = true;
hsMod *= class'NiceSkillSupportGraze'.default.hsBonusZoneMult;
precision = niceZed.IsHeadshotClient(hitLocation, hitDirection, niceZed.clientHeadshotScale * hsMod);
}
return precision;
} else {
if (kfZed.IsHeadShot(hitLocation, hitDirection, 1.0)) {
}
else{
if(kfZed.IsHeadShot(hitLocation, hitDirection, 1.0))
return 1.0;
} else {
else
return 0.0;
}
}
}
// Makes bullet trace a directed line segment given by start and end points.
// All traced actors and geometry are then properly affected by corresponding 'HandleHitPawn', 'HandleHitZed' and
// 'HandleHitWall' functions.
@ -532,7 +457,6 @@ function DoTraceLine(Vector lineStart, Vector lineEnd) {
local array<int> hitPoints;
local KFMonster tracedZed;
local KFPawn tracedPawn;
lineDirection = (lineEnd - lineStart);
lineDirection = (lineDirection) / VSize(lineDirection);
// Do not trace for disabled bullets and prevent infinite loops
@ -540,79 +464,64 @@ function DoTraceLine(Vector lineStart, Vector lineEnd) {
iterationCount ++;
// Trace next object
if(!bGhost || localPlayer == none || localPlayer.tracesThisTick <= localPlayer.tracesPerTickLimit){
if (Instigator != none) {
if(Instigator != none)
tracedActor = Instigator.Trace(hitLocation, hitNormal, lineEnd, lineStart, true);
} else {
else
tracedActor = none;
}
localPlayer.tracesThisTick ++;
} else {
}
else
tracedActor = none;
}
if (
charAffectedByScream &&
!charIsDud &&
localPlayer != none &&
localPlayer.localCollisionManager != none &&
localPlayer.localCollisionManager.IsCollidingWithAnything(lineStart, lineEnd)
) {
if(charAffectedByScream && !charIsDud && localPlayer != none && localPlayer.localCollisionManager != none && localPlayer.localCollisionManager.IsCollidingWithAnything(lineStart, lineEnd))
HandleScream(lineStart, lineDirection);
}
if(tracedActor != none && IsLevelActor(tracedActor)){
HandleHitWall(tracedActor, hitLocation, hitNormal);
break;
} else {
}
else{
TotalIgnore(tracedActor);
tracedActor = GetMainActor(tracedActor);
}
// If tracing between current trace points haven't found anything and tracing step is less than segment's length
// -- shift tracing bounds
if (tracedActor == none) {
if(tracedActor == none)
return;
}
// First, try to handle pawn like a zed; if fails, - try to handle it like 'KFPawn'
tracedZed = KFMonster(tracedActor);
tracedPawn = KFPawn(tracedActor);
if (
tracedPawn != none &&
NiceHumanPawn(instigator) != none &&
(NiceHumanPawn(instigator).ffScale <= 0 && NiceMedicProjectile(self) == none)
) {
if(tracedPawn != none && NiceHumanPawn(instigator) != none &&
(NiceHumanPawn(instigator).ffScale <= 0 && NiceMedicProjectile(self) == none) )
continue;
}
if(tracedZed != none){
if(tracedZed.Health > 0){
headshotLevel = CheckHeadshot(tracedZed, hitLocation, lineDirection);
HandleHitZed(tracedZed, hitLocation, lineDirection, headshotLevel);
}
} else if (tracedPawn != none && tracedPawn.Health > 0) {
if (tracedPawn.Health > 0) {
}
else if(tracedPawn != none && tracedPawn.Health > 0){
if(tracedPawn.Health > 0)
HandleHitPawn(tracedPawn, hitLocation, lineDirection, hitPoints);
}
} else {
else
HandleHitWall(tracedActor, hitLocation, hitNormal);
}
}
}
// Replaces current path segment with the next one.
// Doesn't check whether or not we've finished with the current segment.
function BuildNextPathSegment(){
// Only set start point to our location when we build path segment for the first time
// After that we can't even assume that bullet is exactly in the 'pathSegmentE' point
if (finishedSegmentPart < 0.0) {
if(finishedSegmentPart < 0.0)
pathSegmentS = Location;
} else {
else
pathSegmentS = pathSegmentE;
}
movementDirection += (movementAcceleration * trajUpdFreq) / movementSpeed;
pathSegmentE = pathSegmentS + movementDirection * movementSpeed * trajUpdFreq;
finishedSegmentPart = 0.0;
shiftPoint = pathSegmentS;
}
// Updates 'shiftPoint' to the next bullet position in current segment.
// Does nothing if current segment is finished or no segment was built at all.
// @param delta Amount of time bullet has to move through the segment.
@ -622,11 +531,9 @@ function float ShiftInSegment(float delta) {
local float remainingTime;
// Part of segment we can pass in a given time
local float segmentPartWeCanPass;
// Exit if there's no segment in progress
if (finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0) {
if(finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0)
return delta;
}
// [movementSpeed * delta] / [movementSpeed * trajUpdFreq] = [delta / trajUpdFreq]
segmentPartWeCanPass = delta / trajUpdFreq;
// If we can move through the rest of the segment - move to end point and mark it finished
@ -634,20 +541,19 @@ function float ShiftInSegment(float delta) {
remainingTime = delta - (1.0 - finishedSegmentPart) * trajUpdFreq;
finishedSegmentPart = 1.1;
shiftPoint = pathSegmentE;
} else {
}
// Otherwise compute new 'shiftPoint' normally
else{
remainingTime = 0.0;
finishedSegmentPart += (delta / trajUpdFreq);
shiftPoint = pathSegmentS + movementDirection * movementSpeed * trajUpdFreq * finishedSegmentPart;
}
return remainingTime;
}
// Moves bullet according to settings and decides when and how much tracing should it do.
// @param delta Amount of time passed after previous bullet movement
function DoProcessMovement(float delta){
local Vector tempVect;
SetIgnoreActive(true);
//SetHumanPawnCollision(true);
// Simple linear movement
@ -661,12 +567,12 @@ function DoProcessMovement(float delta) {
// If in future complex movement would be re-enabled, - we want to set first point of the path to
// the location of bullet at a time and not use outdated information.
finishedSegmentPart = -1.0;
} else {
// Non-linear movement support
while(delta > 0.0) {
if (finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0) {
BuildNextPathSegment();
}
// Non-linear movement support
else{
while(delta > 0.0){
if(finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0)
BuildNextPathSegment();
// Remember current 'shiftPoint'. That's where we stopped tracing last time and where we must resume.
tempVect = shiftPoint;
// Update 'shiftPoint' (bullet position)
@ -679,27 +585,20 @@ function DoProcessMovement(float delta) {
Move(shiftPoint - location);
}
SetRotation(Rotator(movementDirection));
if (charMinExplosionDist > 0) {
if(charMinExplosionDist > 0)
charMinExplosionDist -= VSize(tempVect);
}
SetIgnoreActive(false);
//SetHumanPawnCollision(false);
}
function Stick(Actor target, Vector hitLocation){
local Vector boneStrickOrig;
local ExplosionData expData;
local Actor resultTarget;
local NiceMonster targetZed;
local name boneStick;
local float distToBone, t;
if (bGhost) {
local float distToBone;
local float t;
local Vector boneStrickOrig;
local ExplosionData expData;
if(bGhost)
return;
}
expData.instigator = instigator;
expData.sourceWeapon = sourceWeapon;
expData.bulletClass = class;
expData.explosionDamageType = charExplosionDamageType;
expData.explosionDamage = charExplosionDamage;
expData.explosionRadius = charExplosionRadius;
@ -708,20 +607,24 @@ function Stick(Actor target, Vector hitLocation) {
expData.fuseTime = charFuseTime;
expData.explodeOnFuse = charExplodeOnFuse;
expData.affectedByScream = charAffectedByScream;
if (!target.IsA('NiceMonster')) {
hitLocation = (hitLocation - target.location) << target.rotation;
boneStick = 'None';
resultTarget = target;
} else {
expData.sourceWeapon = sourceWeapon;
targetZed = NiceMonster(target);
if(targetZed == none){
expData.bulletClass = class;
expData.instigator = instigator;
niceRI.ServerStickProjectile(KFHumanPawn(instigator), target, 'None', hitLocation - target.location,
Rotator(movementDirection), expData);
class'NiceProjectileSpawner'.static.StickProjectile(KFHumanPawn(instigator), target, 'None',
hitLocation - target.location, Rotator(movementDirection), expData);
}
else{
expData.bulletClass = class;
expData.instigator = instigator;
boneStick = targetZed.GetClosestBone(hitLocation, movementDirection, distToBone);
if (CheckHeadshot(targetZed, hitLocation, movementDirection) > 0.0) {
if(CheckHeadshot(targetZed, hitLocation, movementDirection) > 0.0)
boneStick = targetZed.HeadBone;
}
if (boneStick == targetZed.HeadBone) {
if(boneStick == targetZed.HeadBone)
expData.stuckToHead = true;
}
boneStrickOrig = targetZed.GetBoneCoords(boneStick).origin;
t = movementDirection.x * (boneStrickOrig.x - hitLocation.x) +
movementDirection.y * (boneStrickOrig.y - hitLocation.y) +
@ -729,60 +632,37 @@ function Stick(Actor target, Vector hitLocation) {
t /= VSizeSquared(movementDirection);
t *= 0.5;
hitLocation = hitLocation + t * movementDirection;
hitLocation -= boneStrickOrig;
resultTarget = targetZed;
niceRI.ServerStickProjectile(KFHumanPawn(instigator), targetZed, boneStick,
hitLocation - boneStrickOrig, Rotator(movementDirection), expData);
class'NiceProjectileSpawner'.static.StickProjectile(KFHumanPawn(instigator), targetZed, boneStick,
hitLocation - boneStrickOrig, Rotator(movementDirection), expData);
}
niceRI.ServerStickProjectile(
KFHumanPawn(instigator),
resultTarget,
boneStick,
hitLocation,
Rotator(movementDirection),
expData
);
class'NiceProjectileSpawner'.static.StickProjectile(
KFHumanPawn(instigator),
resultTarget,
boneStick,
hitLocation,
Rotator(movementDirection),
expData
);
KillBullet();
}
function DoExplode(Vector explLocation, Vector impactNormal){
if (charIsDud) {
if(charIsDud)
return;
}
if (bStuck) {
if(bStuck)
class'NiceBulletAdapter'.static.Explode(self, niceRI, explLocation, base);
} else {
else
class'NiceBulletAdapter'.static.Explode(self, niceRI, explLocation);
}
GenerateImpactEffects(explosionImpact, explLocation, impactNormal, true, true);
if (bShakeViewOnExplosion) {
if(bShakeViewOnExplosion)
ShakeView(explLocation);
}
KillBullet();
}
function HandleHitWall(Actor wall, Vector hitLocation, Vector hitNormal){
local bool bBulletTooWeak;
if(charExplodeOnWallHit && !charIsDud && charMinExplosionDist <= 0.0){
DoExplode(hitLocation, hitNormal);
return;
} else {
}
else{
class'NiceBulletAdapter'.static.HitWall(self, niceRI, wall, hitLocation, hitNormal);
GenerateImpactEffects(regularImpact, hitLocation, hitNormal, true, true);
if (charIsSticky) {
if(charIsSticky)
Stick(wall, hitLocation);
}
}
if(bShouldBounce && !bDisableComplexMovement){
movementDirection = (movementDirection - 2.0 * hitNormal * (movementDirection dot hitNormal));
bBulletTooWeak = !class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false);
@ -790,133 +670,97 @@ function HandleHitWall(Actor wall, Vector hitLocation, Vector hitNormal) {
ResetPathBuilding();
ResetIgnoreList();
bounceHeadMod *= 2;
} else if (movementFallTime > 0.0) {
}
else if(movementFallTime > 0.0){
charIsDud = true;
lifeSpan = movementFallTime;
movementFallTime = 0.0;
movementDirection = vect(0,0,0);
ResetPathBuilding();
ResetIgnoreList();
} else {
bBulletTooWeak = true;
}
if (bBulletTooWeak) {
else
bBulletTooWeak = true;
if(bBulletTooWeak)
KillBullet();
}
}
function HandleHitPawn(KFPawn hitPawn, Vector hitLocation, Vector hitDirection, array<int> hitPoints){
if(charExplodeOnPawnHit && !charIsDud && charMinExplosionDist <= 0.0){
DoExplode(hitLocation, hitDirection);
GenerateImpactEffects(explosionImpact, hitLocation, hitDirection);
return;
} else {
class'NiceBulletAdapter'.static.HitPawn(self, niceRI, hitPawn, hitLocation, hitDirection, hitPoints);
if (bGenRegEffectOnPawn) {
GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false);
}
else{
class'NiceBulletAdapter'.static.HitPawn(self, niceRI, hitPawn, hitLocation, hitDirection, hitPoints);
if(bGenRegEffectOnPawn)
GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false);
}
if(!class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false)){
charPenetrationCount += 1;
KillBullet();
}
}
function HandleHitZed(KFMonster targetZed, Vector hitLocation, Vector hitDirection, float headshotLevel){
local bool bHitZedCalled;
if(class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillDemoDirectApproach')){
class'NiceBulletAdapter'.static.HitZed(self, niceRI, targetZed, hitLocation, hitDirection, headshotLevel);
if (bGenRegEffectOnPawn) {
if(bGenRegEffectOnPawn)
GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false);
}
bHitZedCalled = true;
}
if(charExplodeOnPawnHit && !charIsDud && charMinExplosionDist <= 0.0){
class'NiceBulletAdapter'.static.Explode(self, niceRI, hitLocation, targetZed);
GenerateImpactEffects(explosionImpact, hitLocation, hitDirection);
if (bShakeViewOnExplosion) {
if(bShakeViewOnExplosion)
ShakeView(hitLocation);
}
KillBullet();
return;
} else {
if (!bHitZedCalled) {
class'NiceBulletAdapter'.static.HitZed(
self,
niceRI,
targetZed,
hitLocation,
hitDirection,
headshotLevel
);
if (bGenRegEffectOnPawn) {
GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false);
}
else{
if(!bHitZedCalled){
class'NiceBulletAdapter'.static.HitZed(self, niceRI, targetZed, hitLocation, hitDirection, headshotLevel);
if(bGenRegEffectOnPawn)
GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false);
}
bHitZedCalled = true;
if(!bGhost && !bAlreadyHitZed){
bAlreadyHitZed = true;
if (nicePlayer != none && niceRI != none) {
if(nicePlayer != none && niceRI != none)
niceRI.ServerJunkieExtension(nicePlayer, headshotLevel > 0.0);
}
}
if (charIsSticky) {
if(charIsSticky)
Stick(targetZed, hitLocation);
}
}
if (!class'NiceBulletAdapter'.static.ZedPenetration(
charDamage,
self,
targetZed,
(headshotLevel > 0.0),
(headshotLevel > charDamageType.default.prReqPrecise)
)
) {
if(!class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, targetZed, (headshotLevel > 0.0), (headshotLevel > charDamageType.default.prReqPrecise))){
charPenetrationCount += 1;
KillBullet();
}
}
function HandleScream(Vector disintegrationLocation, Vector entryDirection){
if (!charIsDud) {
if(!charIsDud)
GenerateImpactEffects(disintegrationImpact, disintegrationLocation, entryDirection);
}
class'NiceBulletAdapter'.static.HandleScream(self, niceRI, disintegrationLocation, entryDirection);
}
function GenerateImpactEffects(
ImpactEffect effect,
Vector hitLocation,
Vector hitNormal,
optional bool bWallImpact,
optional bool bGenerateDecal
) {
function GenerateImpactEffects(ImpactEffect effect, Vector hitLocation, Vector hitNormal,
optional bool bWallImpact, optional bool bGenerateDecal){
local float actualCullDistance;
local float actualImpactShift;
local bool generatedEffect;
// No need to play visuals on a server, for a dead bullets or in case there's no local player at all
if (Level.NetMode == NM_DedicatedServer || bBulletDead || localPlayer == none) {
if(Level.NetMode == NM_DedicatedServer || bBulletDead || localPlayer == none)
return;
}
if (!localPlayer.CanSpawnEffect(bGhost) && !effect.bImportanEffect) {
if(!localPlayer.CanSpawnEffect(bGhost) && !effect.bImportanEffect)
return;
}
// -- Classic effect
if (effect.bPlayROEffect && !bBulletDead) {
if(effect.bPlayROEffect && !bBulletDead)
Spawn(class'ROBulletHitEffect',,, hitLocation, rotator(-hitNormal));
}
// -- Generate decal
if(bGenerateDecal && effect.decalClass != none){
// Find appropriate cull distance for this decal
actualCullDistance = effect.decalClass.default.cullDistance;
// Double cull distance if local player is an instigator
if (instigator != none && localPlayer == instigator.Controller) {
if(instigator != none && localPlayer == instigator.Controller)
actualCullDistance *= 2; // NICETODO: magic number
}
// Spawn decal
if(!localPlayer.BeyondViewDistance(hitLocation, actualCullDistance)){
Spawn(effect.decalClass, self,, hitLocation, rotator(- hitNormal));
@ -925,11 +769,10 @@ function GenerateImpactEffects(
}
// -- Generate custom effect
if(effect.emitterClass != none && EffectIsRelevant(hitLocation, false)){
if (bWallImpact) {
if(bWallImpact)
actualImpactShift = effect.emitterShiftWall;
} else {
else
actualImpactShift = effect.emitterShiftPawn;
}
Spawn(effect.emitterClass,,, hitLocation - movementDirection * actualImpactShift, rotator(movementDirection));
generatedEffect = true;
}
@ -940,43 +783,28 @@ function GenerateImpactEffects(
Spawn(class'NiceSoundCls',,, hitLocation);
generatedEffect = true;
}
if (generatedEffect) {
if(generatedEffect)
localPlayer.AddEffect();
}
}
function ShakeView(Vector hitLocation){
local float distance, scale;
if (nicePlayer == none || shakeRadiusMult < 0.0) {
if(nicePlayer == none || shakeRadiusMult < 0.0)
return;
}
distance = VSize(hitLocation - nicePlayer.ViewTarget.Location);
if(distance < charExplosionRadius * shakeRadiusMult){
if (distance < charExplosionRadius) {
if(distance < charExplosionRadius)
scale = 1.0;
} else {
else
scale = (charExplosionRadius * ShakeRadiusMult - distance) / (charExplosionRadius);
}
nicePlayer.ShakeView(
shakeRotMag * scale,
shakeRotRate,
shakeRotTime,
shakeOffsetMag * scale,
shakeOffsetRate,
shakeOffsetTime
);
nicePlayer.ShakeView(shakeRotMag*scale, shakeRotRate, shakeRotTime, shakeOffsetMag * scale, shakeOffsetRate, shakeOffsetTime);
}
}
function KillBullet(){
local int i;
if(bulletTrail != none){
for(i = 0;i < bulletTrail.Emitters.Length;i ++){
if (bulletTrail.Emitters[i] == none) {
if(bulletTrail.Emitters[i] == none)
continue;
}
bulletTrail.Emitters[i].ParticlesPerSecond = 0;
bulletTrail.Emitters[i].InitialParticlesPerSecond = 0;
bulletTrail.Emitters[i].RespawnDeadParticles = false;
@ -984,7 +812,6 @@ function KillBullet() {
bulletTrail.SetBase(none);
bulletTrail.AutoDestroy = true;
}
if(bulletXTrail != none){
bulletXTrail.mRegen = false;
bulletXTrail.LifeSpan = LifeSpan;
@ -994,12 +821,12 @@ function KillBullet() {
SoundVolume = 0;
LifeSpan = FMin(LifeSpan, 0.1);
}
event Destroyed(){
KillBullet();
}
defaultproperties {
defaultproperties
{
insideBouncesLeft=2
trajUpdFreq=0.100000
maxTraceCycles=128

View File

@ -9,132 +9,57 @@
// E-mail: dkanus@gmail.com
//======================================================================================================================
class NiceBulletAdapter extends Object;
var const int BigZedMinHealth; // If zed's base Health >= this value, zed counts as Big
var const int MediumZedMinHealth; // If zed's base Health >= this value, zed counts as Medium-size
static function Explode(
NiceBullet bullet,
NiceReplicationInfo niceRI,
Vector hitLocation,
optional Actor explosionTarget
) {
static function Explode(NiceBullet bullet, NiceReplicationInfo niceRI, Vector hitLocation, optional Actor explosionTarget){
if(!bullet.bGhost){
niceRI.ServerExplode(
bullet.charExplosionDamage,
bullet.charExplosionRadius,
bullet.charExplosionExponent,
bullet.charExplosionDamageType,
bullet.charExplosionMomentum,
hitLocation,
bullet.instigator,
explosionTarget,
Vector(bullet.Rotation),
bullet.bStuck
);
if (KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead) {
niceRI.ServerDealDamage(
KFMonster(bullet.base),
bullet.charExplosionDamage,
bullet.instigator,
hitLocation,
bullet.charExplosionMomentum * vect(0, 0, -1),
bullet.charExplosionDamageType,
1.0
);
niceRI.ServerExplode(bullet.charExplosionDamage, bullet.charExplosionRadius, bullet.charExplosionExponent,
bullet.charExplosionDamageType, bullet.charExplosionMomentum, hitLocation, bullet.instigator, true,
explosionTarget, Vector(bullet.Rotation));
if(KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead)
niceRI.ServerDealDamage(KFMonster(bullet.base), bullet.charExplosionDamage, bullet.instigator, hitLocation,
bullet.charExplosionMomentum * vect(0,0,-1), bullet.charExplosionDamageType, 1.0);
}
}
}
static function HandleCalibration (
static function HandleCalibration
(
bool isHeadshot,
NiceHumanPawn nicePawn,
NiceMonster targetZed
){
if (nicePawn == none || nicePawn.currentCalibrationState != CALSTATE_ACTIVE) {
return;
}
if(nicePawn == none) return;
if(nicePawn.currentCalibrationState != CALSTATE_ACTIVE) return;
nicePawn.ServerUpdateCalibration(isHeadshot, targetZed);
}
static function HitWall(
NiceBullet bullet,
NiceReplicationInfo niceRI,
Actor targetWall,
Vector hitLocation,
Vector hitNormal
) {
static function HitWall(NiceBullet bullet, NiceReplicationInfo niceRI, Actor targetWall,
Vector hitLocation, Vector hitNormal){
local NicePlayerController nicePlayer;
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
if (nicePlayer == none) {
if(nicePlayer == none)
return;
}
if (!bullet.bAlreadyHitZed) {
if(!bullet.bAlreadyHitZed)
HandleCalibration(false, NiceHumanPawn(bullet.Instigator), none);
}
if (
!targetWall.bStatic &&
!targetWall.bWorldGeometry &&
nicePlayer != none &&
(nicePlayer.wallHitsLeft > 0 || Projectile(targetWall) != none)
) {
niceRI.ServerDealDamage(
targetWall,
bullet.charOrigDamage,
bullet.Instigator,
hitLocation,
bullet.charMomentumTransfer * hitNormal,
bullet.charDamageType
);
if(!targetWall.bStatic && !targetWall.bWorldGeometry && nicePlayer != none && (nicePlayer.wallHitsLeft > 0 || Projectile(targetWall) != none)){
niceRI.ServerDealDamage(targetWall, bullet.charOrigDamage, bullet.Instigator, hitLocation,
bullet.charMomentumTransfer * hitNormal, bullet.charDamageType);
nicePlayer.wallHitsLeft --;
}
}
static function HandleScream(
NiceBullet bullet,
NiceReplicationInfo niceRI,
Vector location,
Vector entryDirection
) {
static function HandleScream(NiceBullet bullet, NiceReplicationInfo niceRI, Vector location, Vector entryDirection){
bullet.charIsDud = true;
}
static function HitPawn(
NiceBullet bullet,
NiceReplicationInfo niceRI,
KFPawn targetPawn,
Vector hitLocation,
Vector hitNormal,
array<int> hitPoints
) {
static function HitPawn(NiceBullet bullet, NiceReplicationInfo niceRI, KFPawn targetPawn, Vector hitLocation,
Vector hitNormal, array<int> hitPoints){
local NiceMedicProjectile niceDart;
niceDart = NiceMedicProjectile(bullet);
if (niceDart == none) {
niceRI.ServerDealDamage(
targetPawn,
bullet.charDamage,
bullet.instigator,
HitLocation,
hitNormal * bullet.charMomentumTransfer,
bullet.charDamageType
);
} else {
if(niceDart == none)
niceRI.ServerDealDamage(targetPawn, bullet.charDamage, bullet.instigator, HitLocation,
hitNormal * bullet.charMomentumTransfer, bullet.charDamageType);
else
niceRI.ServerHealTarget(NiceHumanPawn(targetPawn), bullet.charDamage, bullet.instigator);
}
}
static function HitZed(
NiceBullet bullet,
NiceReplicationInfo niceRI,
KFMonster kfZed,
Vector hitLocation,
Vector hitNormal,
float headshotLevel
) {
static function HitZed(NiceBullet bullet, NiceReplicationInfo niceRI, KFMonster kfZed, Vector hitLocation,
Vector hitNormal, float headshotLevel){
local bool bIsHeadshot, bIsPreciseHeadshot;
local float actualDamage;
local int lockonTicks;
@ -143,54 +68,37 @@ static function HitZed(
local NiceHumanPawn nicePawn;
local NicePlayerController nicePlayer;
local class<NiceVeterancyTypes> niceVet;
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
if (
nicePlayer != none &&
nicePlayer.abilityManager != none &&
nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillEnforcerBruteA'.default.abilityID)
) {
if ( nicePlayer != none && nicePlayer.abilityManager != none
&& nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillEnforcerBruteA'.default.abilityID)) {
headshotLevel = 0.0;
}
bIsHeadshot = (headshotLevel > 0.0);
bIsPreciseHeadshot = (headshotLevel > bullet.charDamageType.default.prReqPrecise);
if (!bullet.bAlreadyHitZed || bIsHeadshot) {
if(!bullet.bAlreadyHitZed || bIsHeadshot)
HandleCalibration(bIsHeadshot, NiceHumanPawn(bullet.Instigator), NiceMonster(kfZed));
}
if (bIsHeadshot && bullet.sourceWeapon != none) {
if(bIsHeadshot && bullet.sourceWeapon != none)
bullet.sourceWeapon.lastHeadshotTime = bullet.Level.TimeSeconds;
}
if (nicePlayer == none) {
if(nicePlayer == none)
return;
}
nicePawn = NiceHumanPawn(bullet.instigator);
if (
!bIsHeadshot &&
nicePawn != none &&
nicePlayer.abilityManager != none &&
nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillSharpshooterReaperA'.default.abilityID)
) {
if( !bIsHeadshot
&& nicePawn != none
&& nicePlayer.abilityManager != none
&& nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillSharpshooterReaperA'.default.abilityID))
nicePawn.ServerCooldownAbility(class'NiceSkillSharpshooterReaperA'.default.abilityID);
}
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
if (bullet.charCausePain) {
if(bullet.charCausePain)
actualDamage = bullet.charOrigDamage;
} else {
else
actualDamage = bullet.charDamage;
}
if (headshotLevel > 0) {
if(headshotLevel > 0)
actualDamage *= bullet.charContiniousBonus;
}
if (bullet.bGrazing) {
if(bullet.bGrazing)
actualDamage *= class'NiceSkillSupportGraze'.default.grazeDamageMult;
}
bullet.bGrazing = false;
if (
kfZed == bullet.lockonZed &&
bullet.lockonTime > bullet.sourceWeapon.stdFireRate &&
niceVet != none &&
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterKillConfirmed')
) {
if(kfZed == bullet.lockonZed && bullet.lockonTime > bullet.sourceWeapon.stdFireRate
&& niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterKillConfirmed')){
lockOnTickRate =class'NiceSkillSharpshooterKillConfirmed'.default.stackDelay;
lockonTicks = Ceil(bullet.lockonTime / lockOnTickRate) - 1;
lockonTicks = Min(class'NiceSkillSharpshooterKillConfirmed'.default.maxStacks, lockonTicks);
@ -199,57 +107,35 @@ static function HitZed(
//damageMod *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
actualDamage *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
}
if (!bullet.bGhost) {
niceRI.ServerDealDamage(
kfZed,
actualDamage,
bullet.instigator,
hitLocation,
bullet.charMomentumTransfer * hitNormal,
bullet.charDamageType,
headshotLevel,
bullet.lockonTime
);
}
if(!bullet.bGhost)
niceRI.ServerDealDamage(kfZed, actualDamage, bullet.instigator, hitLocation,
bullet.charMomentumTransfer * hitNormal, bullet.charDamageType, headshotLevel, bullet.lockonTime);
//// Handle angled shots
angle = asin(hitNormal.Z);
// Apply angled shots
if((angle > 0.8 || angle < -0.45) && bullet.bCanAngleDamage && kfZed != none){
bullet.bCanAngleDamage = false;
bullet.bAlreadyHitZed = true;
if (ZedPenetration(bullet.charDamage, bullet, kfZed, bIsHeadshot, bIsPreciseHeadshot)) {
if(ZedPenetration(bullet.charDamage, bullet, kfZed, bIsHeadshot, bIsPreciseHeadshot))
HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel);
}
}
//// 'Bore' support skill
if (
niceVet != none &&
nicePlayer.IsZedTimeActive() &&
bullet.insideBouncesLeft > 0 &&
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBore')
) {
if( niceVet != none && nicePlayer.IsZedTimeActive() && bullet.insideBouncesLeft > 0
&& niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBore')){
// Count one bounce
bullet.insideBouncesLeft --;
// Swap head-shot level
if (headshotLevel <= 0.0) {
if(headshotLevel <= 0.0)
headshotLevel = class'NiceSkillSupportZEDBore'.default.minHeadshotPrecision;
} else {
else
headshotLevel = -headshotLevel;
}
// Deal next batch of damage
ZedPenetration(bullet.charDamage, bullet, kfZed, false, false);
HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel);
}
bullet.insideBouncesLeft = 2;
}
static function bool ZedPenetration(
out float Damage,
NiceBullet bullet,
KFMonster targetZed,
bool bIsHeadshot,
bool bIsPreciseHeadshot
) {
static function bool ZedPenetration(out float Damage, NiceBullet bullet, KFMonster targetZed, bool bIsHeadshot, bool bIsPreciseHeadshot){
local float reductionMod;
local NiceMonster niceZed;
local NicePlayerController nicePlayer;
@ -258,49 +144,31 @@ static function bool ZedPenetration(
local class<NiceWeaponDamageType> niceDmgType;
// True if we can penetrate even body, but now penetrating a head and shouldn't reduce damage too much
local bool bEasyHeadPenetration;
// Init variables
niceZed = NiceMonster(targetZed);
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
niceVet = none;
if (nicePlayer != none) {
if(nicePlayer != none)
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
}
niceDmgType = bullet.charDamageType;
bEasyHeadPenetration = bIsHeadshot && !niceDmgType.default.bPenetrationHSOnly;
reductionMod = 1.0f;
// Apply zed reduction and perk reduction of reduction`
if(niceZed != none){
// Railgun skill exception
if (
niceVet != none &&
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterZEDRailgun') &&
nicePlayer.IsZedTimeActive()
) {
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterZEDRailgun') && nicePlayer.IsZedTimeActive())
return true;
}
if (niceZed.default.Health >= default.BigZedMinHealth && !bEasyHeadPenetration) {
if(niceZed.default.Health >= default.BigZedMinHealth && !bEasyHeadPenetration)
reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
} else if (niceZed.default.Health >= default.MediumZedMinHealth && !bEasyHeadPenetration) {
else if(niceZed.default.Health >= default.MediumZedMinHealth && !bEasyHeadPenetration)
reductionMod *= niceDmgType.default.MediumZedPenDmgReduction;
}
} else {
else
reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
}
if (niceVet != none) {
reductionMod = niceVet.static.GetPenetrationDamageMulti(
KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo),
reductionMod,
niceDmgType
);
}
if(niceVet != none)
reductionMod = niceVet.static.GetPenetrationDamageMulti(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo), reductionMod, niceDmgType);
actualMaxPenetrations = niceDmgType.default.maxPenetrations;
if (
niceVet != none &&
!bullet.charWasHipFired &&
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterSurgical') &&
bIsHeadshot
) {
if(niceVet != none && !bullet.charWasHipFired && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterSurgical') && bIsHeadshot){
actualMaxPenetrations += 1;
reductionMod = FMax(reductionMod, class'NiceSkillSharpshooterSurgical'.default.penDmgReduction);
}
@ -308,24 +176,20 @@ static function bool ZedPenetration(
Damage *= reductionMod * niceDmgType.default.PenDmgReduction;
bullet.decapMod *= reductionMod * niceDmgType.default.PenDecapReduction;
bullet.incapMod *= reductionMod * niceDmgType.default.PenIncapReduction;
if (niceVet != none && actualMaxPenetrations >= 0) {
if(niceVet != none && actualMaxPenetrations >= 0)
actualMaxPenetrations +=
niceVet.static.GetAdditionalPenetrationAmount(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
}
if (!bIsHeadshot && niceDmgType.default.bPenetrationHSOnly) {
if(!bIsHeadshot && niceDmgType.default.bPenetrationHSOnly)
return false;
}
if (actualMaxPenetrations < 0) {
if(actualMaxPenetrations < 0)
return true;
}
if (Damage / bullet.charOrigDamage < (niceDmgType.default.PenDmgReduction ** (actualMaxPenetrations + 1)) + 0.0001 || Damage < 1) {
if(Damage / bullet.charOrigDamage < (niceDmgType.default.PenDmgReduction ** (actualMaxPenetrations + 1)) + 0.0001 || Damage < 1)
return false;
}
return true;
}
defaultproperties {
defaultproperties
{
BigZedMinHealth=1000
MediumZedMinHealth=500
}

View File

@ -20,7 +20,6 @@ var() bool bSemiMustBurst;
var() int MaxBurstLength;
var() int burstShotsMade;
var bool bResetRecoil; // Set this flag to 'true' to disable recoil for the next shot; flag will be automatically reset to 'false' after that
var float aimingSpreadReductionCoefficient;
var bool zoomOutOnShot;
var bool bShouldBounce;
var bool bCausePain;
@ -39,10 +38,6 @@ var bool projAffectedByScream;
var bool bShouldStick;
var int resetTicks;
var float niceNextFireTime;
var float minimalSpreadScale;
var float activeSpreadScale;
var float spreadGainedPerShot;
var float spreadLostPerSecond;
struct FireModeContext{
var bool bHipfire;
var NiceWeapon sourceWeapon;
@ -157,15 +152,9 @@ simulated function int GetBurstLength(){
}
return currentContext.burstLength;
}
simulated function ModeTick(float delta){
local float headLevel;
local NiceMonster currTarget;
if (spreadLostPerSecond > 0 && activeSpreadScale > minimalSpreadScale
&& niceNextFireTime + fireRate <= Level.TimeSeconds) {
activeSpreadScale -= spreadLostPerSecond * delta;
activeSpreadScale = FMax(minimalSpreadScale, activeSpreadScale);
}
if(currentContext.Instigator == none)
currentContext.Instigator = NiceHumanPawn(Instigator);
if(currentContext.sourceWeapon == none)
@ -488,7 +477,7 @@ simulated function HandleRecoil(float Rec)
KFW= KFWeapon(Weapon);
if (KFW.bAimingRifle)
{
Rec *= aimingSpreadReductionCoefficient;
Rec *= 0.5;
}
if (nicePawn.stationaryTime > 0.0 && class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillHeavyStablePosition'))
{
@ -559,7 +548,7 @@ function DoFireEffect(){
if(!Weapon.WeaponCentered() && !KFWeap.bAimingRifle)
StartProj = StartProj + Weapon.Hand * Y * ProjSpawnOffset.Y + Z * ProjSpawnOffset.Z;
other = Weapon.Trace(HitLocation, HitNormal, StartProj, StartTrace, false);
activeSpread = fireShots[currentShot].spread * activeSpreadScale;
activeSpread = fireShots[currentShot].spread;
if(class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillEnforcerBombard')){
bPinpoint = true;
activeSpread *= class'NiceSkillEnforcerBombard'.default.spreadMult;
@ -618,15 +607,6 @@ function DoFireEffect(){
else if(Instigator.Physics == PHYS_Falling && Instigator.PhysicsVolume.Gravity.Z > class'PhysicsVolume'.default.Gravity.Z)
Instigator.AddVelocity((KickMomentum * LowGravKickMomentumScale) >> Instigator.GetViewRotation());
}
if (activeSpreadScale < 1.0) {
if (KFWeap.bAimingRifle) {
activeSpreadScale += spreadGainedPerShot * 0.5;
}
else {
activeSpreadScale += spreadGainedPerShot;
}
activeSpreadScale = FMin(1.0, activeSpreadScale);
}
}
simulated function float TraceZed(out NiceMonster tracedZed, optional out Vector hitLoc, optional out Vector hitNorm,
optional float hsMultiplier){
@ -699,7 +679,6 @@ simulated function UpdateFireSpeed(){
}
// This function is called when next fire time needs to be updated
simulated function float UpdateNextFireTime(float fireTimeVar){
local float usedFireRate;
local float burstSlowDown;
local NiceHumanPawn nicePawn;
local class<NiceVeterancyTypes> niceVet;
@ -707,19 +686,11 @@ simulated function float UpdateNextFireTime(float fireTimeVar) {
if(nicePawn != none)
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(nicePawn.PlayerReplicationInfo);
fireTimeVar = FMax(fireTimeVar, Level.TimeSeconds);
usedFireRate = fireRate;
if (maxBonusContLenght > 1) {
if (currentContLenght <= maxBonusContLenght) {
usedFireRate *= 0.8 + 0.2 * (maxBonusContLenght - currentContLenght);
} else {
usedFireRate *= 0.8;
}
}
if(bFireOnRelease){
if(bIsFiring)
fireTimeVar += MaxHoldTime + usedFireRate;
fireTimeVar += MaxHoldTime + FireRate;
else
fireTimeVar = Level.TimeSeconds + usedFireRate;
fireTimeVar = Level.TimeSeconds + FireRate;
}
else{
if(currentContext.bIsBursting && GetBurstLength() > 1){
@ -730,10 +701,10 @@ simulated function float UpdateNextFireTime(float fireTimeVar) {
burstSlowDown = 1.0;
else
burstSlowDown = 1.3;
fireTimeVar += usedFireRate * burstSlowDown;
fireTimeVar += FireRate * burstSlowDown;
}
else
fireTimeVar += usedFireRate;
fireTimeVar += FireRate;
fireTimeVar = FMax(fireTimeVar, Level.TimeSeconds);
}
return fireTimeVar;
@ -750,10 +721,4 @@ defaultproperties
contBonusReset=True
maxBonusContLenght=1
AmmoPerFire=1
minimalSpreadScale=1
activeSpreadScale=1
spreadGainedPerShot=0
spreadLostPerSecond=0
RecoilVelocityScale = 0
aimingSpreadReductionCoefficient = 0.5
}

View File

@ -1,160 +1,76 @@
class NiceProjectileSpawner extends Actor
dependson(NiceBullet);
// NICETODO: use flags correctly
static function MakeProjectile(
Vector start,
Rotator dir,
NiceFire.ShotType shotParams,
NiceFire.FireModeContext fireContext,
optional bool bForceComplexTraj,
optional bool bDuplReal,
optional bool bSkipGhosts
) {
static function MakeProjectile(Vector start, Rotator dir, NiceFire.ShotType shotParams, NiceFire.FireModeContext fireContext, optional bool bForceComplexTraj,
optional bool bDuplReal, optional bool bSkipGhosts){
local int i;
local NicePack niceMut;
niceMut = class'NicePack'.static.Myself(fireContext.Instigator.Level);
if (niceMut == none) {
if(niceMut == none)
return;
}
if (fireContext.Instigator.Role < ROLE_Authority || bDuplReal) {
if(fireContext.Instigator.Role < ROLE_Authority || bDuplReal)
SpawnProjectile(Start, Dir, shotParams, fireContext, false, bForceComplexTraj);
}
if(fireContext.Instigator.Role == ROLE_Authority && niceMut != none && !bSkipGhosts){
for(i = 0;i < niceMut.playersList.Length;i ++){
if (niceMut.playersList[i] != fireContext.Instigator.Controller) {
niceMut.playersList[i].ClientSpawnGhostProjectile(
start,
dir.pitch,
dir.yaw,
dir.roll,
shotParams,
fireContext,
bForceComplexTraj
);
if(niceMut.playersList[i] != fireContext.Instigator.Controller)
niceMut.playersList[i].ClientSpawnGhostProjectile(start, dir.pitch, dir.yaw, dir.roll, shotParams, fireContext, bForceComplexTraj);
}
}
}
}
static function StickProjectile(
KFHumanPawn instigator,
Actor base,
name bone,
Vector shift,
Rotator direction,
NiceBullet.ExplosionData expData,
optional bool bDuplReal,
optional bool bSkipGhosts
) {
static function StickProjectile(KFHumanPawn instigator, Actor base, name bone, Vector shift, Rotator direction,
NiceBullet.ExplosionData expData, optional bool bDuplReal, optional bool bSkipGhosts){
local int i;
local NicePack niceMut;
niceMut = class'NicePack'.static.Myself(expData.Instigator.Level);
if (niceMut == none) {
if(niceMut == none)
return;
}
niceMut.stuckCounter ++;
if (expData.Instigator.Role < ROLE_Authority) {
SpawnStuckProjectile(
instigator,
base,
bone,
shift,
direction,
expData,
false,
niceMut.stuckCounter
);
}
if(expData.Instigator.Role < ROLE_Authority)
SpawnStuckProjectile(instigator, base, bone, shift, direction, expData, false, niceMut.stuckCounter);
if(expData.Instigator.Role == ROLE_Authority && niceMut != none){
for(i = 0;i < niceMut.playersList.Length;i ++){
if (
(niceMut.playersList[i] != expData.Instigator.Controller && !bSkipGhosts) ||
(niceMut.playersList[i] == expData.Instigator.Controller && bDuplReal)
) {
niceMut.playersList[i].ClientStickGhostProjectile(
instigator,
base,
bone,
shift,
direction,
expData,
niceMut.stuckCounter
);
if( (niceMut.playersList[i] != expData.Instigator.Controller && !bSkipGhosts)
|| (niceMut.playersList[i] == expData.Instigator.Controller && bDuplReal) )
niceMut.playersList[i].ClientStickGhostProjectile(instigator, base, bone, shift, direction, expData,
niceMut.stuckCounter);
}
}
}
}
static function NiceBullet SpawnProjectile(
Vector Start,
Rotator Dir,
NiceFire.ShotType shotParams,
NiceFire.FireModeContext fireContext,
optional bool bIsGhost,
optional bool bForceComplexTraj
) {
static function NiceBullet SpawnProjectile(Vector Start, Rotator Dir, NiceFire.ShotType shotParams, NiceFire.FireModeContext fireContext, optional bool bIsGhost, optional bool bForceComplexTraj){
local Actor other;
local NiceBullet niceProj;
local Vector HitLocation, HitNormal;
local NicePlayerController nicePlayer;
local class<NiceVeterancyTypes> niceVet;
// No class - no projectile
if (shotParams.bulletClass == none) {
if(shotParams.bulletClass == none)
return none;
}
// Try to spawn
if (fireContext.Instigator != none) {
if(fireContext.Instigator != none)
niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir);
}
// Try harder
if(niceProj == none && fireContext.Instigator != none){
other = fireContext.Instigator.Trace(
HitLocation,
HitNormal,
Start,
fireContext.Instigator.Location + fireContext.Instigator.EyePosition(),
false,
Vect(0, 0, 1)
);
if (other != none) {
other = fireContext.Instigator.Trace(HitLocation, HitNormal, Start, fireContext.Instigator.Location + fireContext.Instigator.EyePosition(), false, Vect(0,0,1));
if(other != none)
Start = HitLocation;
}
niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir);
}
// Give up if failed after these two attempts
if (niceProj == none) {
if(niceProj == none)
return none;
}
niceProj.Renew();
// Initialize projectile
if (fireContext.Instigator != none) {
if(fireContext.Instigator != none)
nicePlayer = NicePlayerController(fireContext.Instigator.Controller);
}
if (nicePlayer != none) {
if(nicePlayer != none)
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(nicePlayer.PlayerReplicationInfo);
}
niceProj.bGhost = bIsGhost;
// Fill-up data about what damage should projectile deal
niceProj.charDamage = shotParams.damage;
if (
niceVet != none &&
fireContext.bIsBursting &&
niceVet.static.hasSkill(nicePlayer, class'NiceSkillCommandoExplosivePower')
) {
if(niceVet != none && fireContext.bIsBursting && niceVet.static.hasSkill(nicePlayer, class'NiceSkillCommandoExplosivePower'))
niceProj.charDamage *= class'NiceSkillCommandoExplosivePower'.default.dmgMod;
}
if (
niceVet != none &&
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBulletStorm') &&
nicePlayer.IsZedTimeActive()
) {
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBulletStorm') && nicePlayer.IsZedTimeActive())
niceProj.charDamage = shotParams.damage * class'NiceSkillSupportZEDBulletStorm'.default.damageCut;
}
niceProj.charOrigDamage = niceProj.charDamage;
niceProj.charDamageType = shotParams.shotDamageType;
niceProj.charExplosionDamageType = shotParams.explosionDamageType;
@ -176,9 +92,8 @@ static function NiceBullet SpawnProjectile(
niceProj.charContiniousBonus = fireContext.continiousBonus;
// Fill-up data about at what speed should projectile travel
niceProj.movementSpeed = shotParams.projSpeed;
if (niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoOnperk')) {
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoOnperk'))
niceProj.movementSpeed *= class'NiceSkillDemoOnperk'.default.speedBonus;
}
niceProj.movementDirection = Vector(niceProj.rotation);
niceProj.charAffectedByScream = shotParams.projAffectedByScream;
niceProj.charIsSticky = shotParams.bShouldStick;
@ -188,47 +103,29 @@ static function NiceBullet SpawnProjectile(
niceProj.charExplosionExponent *= class'NiceSkillDemoVolatile'.default.falloffMult;
niceProj.charMinExplosionDist *= class'NiceSkillDemoVolatile'.default.safeDistanceMult;
}
if (
niceVet != none &&
niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoZEDFullBlast') &&
nicePlayer.IsZedTimeActive()
) {
if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoZEDFullBlast') && nicePlayer.IsZedTimeActive()){
niceProj.charExplosionRadius *= class'NiceSkillDemoZEDFullBlast'.default.explRadiusMult;
niceProj.charExplosionExponent = 0.0;
}
if (bForceComplexTraj) {
if(bForceComplexTraj)
niceProj.bDisableComplexMovement = false;
}
if (niceProj.Instigator != none && NicePlayerController(niceProj.Instigator.Controller) != none) {
if(niceProj.Instigator != none && NicePlayerController(niceProj.Instigator.Controller) != none)
niceProj.niceRI = NicePlayerController(niceProj.Instigator.Controller).NiceRI;
}
// And some leftovers
//niceProj.bShouldBounce = shotParams.bShouldBounce;
niceProj.bInitFinished = true;
return niceProj;
}
static function SpawnStuckProjectile(
KFHumanPawn instigator,
Actor base,
name bone,
Vector shift,
Rotator direction,
NiceBullet.ExplosionData expData,
bool bIsGhost,
int stuckID
) {
static function SpawnStuckProjectile(KFHumanPawn instigator, Actor base, name bone, Vector shift, Rotator direction,
NiceBullet.ExplosionData expData, bool bIsGhost, int stuckID){
local Pawn justPawn;
local NiceFire.ShotType shotParams;
local NiceFire.FireModeContext fireContext;
local NiceBullet spawnedBullet;
local NicePlayerController nicePlayer;
nicePlayer = NicePlayerController(instigator.Controller);
if (base == none || nicePlayer == none) {
if(base == none || nicePlayer == none)
return;
}
justPawn = Pawn(base);
fireContext.instigator = NiceHumanPawn(instigator);
fireContext.sourceWeapon = expData.sourceWeapon;
@ -242,9 +139,8 @@ static function SpawnStuckProjectile(
shotParams.explodeOnFuse = expData.explodeOnFuse;
shotParams.projAffectedByScream = expData.affectedByScream;
spawnedBullet = SpawnProjectile(base.location, direction, shotParams, fireContext, bIsGhost);
if (spawnedBullet == none) {
if(spawnedBullet == none)
return;
}
spawnedBullet.stuckID = stuckID;
spawnedBullet.bStuck = true;
nicePlayer.RegisterStuckBullet(spawnedBullet);
@ -256,14 +152,15 @@ static function SpawnStuckProjectile(
spawnedBullet.SetRelativeRotation(Rotator(Vector(direction) << justPawn.GetBoneRotation(bone, 0)));
spawnedBullet.bUseBone = true;
spawnedBullet.stuckBone = bone;
} else {
}
else{
spawnedBullet.SetBase(base);
spawnedBullet.SetRelativeLocation(shift);
spawnedBullet.SetRelativeRotation(direction - base.rotation);
}
}
defaultproperties {
defaultproperties
{
bHidden=True
RemoteRole=ROLE_SimulatedProxy
LifeSpan=1.000000

View File

@ -146,7 +146,6 @@ var bool bAutoReloadPaused; // This is used to 'pause' auto relo
var float autoReloadPauseFrame; // Frame at which current pause began
var bool bAutoReloadRateApplied; // Flag that remembers whether or not we've already applied reload speed up for current auto reload (to avoid constant animation's speed updates)
var float autoReloadSpeedModifier;
var bool updatedDefaultReloadValues;
// Acrtive reload-related variables
// Active reload state
enum EActiveReloadState{
@ -220,8 +219,6 @@ static function bool UnloadAssets(){
return default.ReferenceCount == 0;
}
simulated function PostBeginPlay(){
local float swapSpeedMod, reloadSpeedMod;
if(default.recordedZoomTime < 0)
default.recordedZoomTime = ZoomTime;
recordedZoomTime = default.recordedZoomTime;
@ -243,31 +240,6 @@ simulated function PostBeginPlay(){
if(FireModeClass[0] != none)
stdFireRate = FireModeClass[0].default.fireRate;
super.PostBeginPlay();
// Hack solution - speed up reload and swap speed
swapSpeedMod = 2.0;
reloadSpeedMod = 1.5;
bringUpTime /= swapSpeedMod;
putDownTime /= swapSpeedMod;
selectAnimRate *= swapSpeedMod;
putDownAnimRate *= swapSpeedMod;
quickPutDownTime /= swapSpeedMod;
quickBringUpTime /= swapSpeedMod;
if (!default.updatedDefaultReloadValues) {
if(reloadType == RTYPE_AUTO) {
if (fireModeClass[0] != none) {
fireModeClass[0].default.FireAnimRate *= reloadSpeedMod;
}
if (fireModeClass[1] != none) {
fireModeClass[1].default.FireAnimRate *= reloadSpeedMod;
}
} else {
reloadRate /= reloadSpeedMod;
reloadAnimRate *= reloadSpeedMod;
default.reloadRate = reloadRate;
default.reloadAnimRate = reloadAnimRate;
}
default.updatedDefaultReloadValues = true;
}
}
// Allows to prevent leaving iron sights unwillingly
@ -1122,7 +1094,6 @@ simulated function int GetMagazineAmmo(){
else
return MagAmmoRemaining;
}
simulated function bool AllowReload(){
local int actualMagSize;
actualMagSize = GetMagazineAmmo();
@ -1156,7 +1127,6 @@ simulated function float GetCurrentReloadMult(){
local NiceHumanPawn nicePawn;
local NicePlayerController nicePlayer;
local class<NiceVeterancyTypes> niceVet;
nicePawn = NiceHumanPawn(Instigator);
nicePlayer = NicePlayerController(Instigator.Controller);
if(nicePawn != none)

View File

@ -3,7 +3,7 @@ defaultproperties
{
Weight=6.000000
cost=750
AmmoCost=25
AmmoCost=19
BuyClipSize=40
PowerValue=55
SpeedValue=80

View File

@ -3,7 +3,7 @@ defaultproperties
{
Weight=6.000000
cost=750
AmmoCost=26
AmmoCost=19
BuyClipSize=30
PowerValue=40
SpeedValue=80

View File

@ -3,7 +3,7 @@ defaultproperties
{
Weight=6.000000
cost=750
AmmoCost=19
AmmoCost=22
BuyClipSize=30
PowerValue=40
SpeedValue=85

View File

@ -19,7 +19,7 @@ defaultproperties
StereoFireSoundRef="KF_LAWSnd.LAW_FireST"
NoAmmoSoundRef="KF_LAWSnd.LAW_DryFire"
DamageType=class'NiceDamTypeLAWBlunt'
DamageMax=350
DamageMax=750
bSplashDamage=True
bRecommendSplashDamage=True
bWaitForRelease=True

View File

@ -39,32 +39,114 @@ function TakeDamage(int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Mo
Explode(HitLocation, vect(0,0,1));
}
}
simulated function HurtRadius( float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation )
{
local actor Victims;
local float damageScale, dist;
local vector dir;
local int NumKilled;
local KFMonster KFMonsterVictim;
local bool bMonster;
local Pawn P;
local KFPawn KFP;
local array<Pawn> CheckedPawns;
local int i;
local bool bAlreadyChecked;
local SRStatsBase Stats;
simulated function HurtRadius(
float damageAmount,
float damageRadius,
class<DamageType> damageType,
float momentum,
Vector hitLocation
) {
local NicePlayerController niceController;
local NiceReplicationInfo niceRI;
if ( bHurtEntry )
return;
bHurtEntry = true;
if (instigator == none) return;
niceController = NicePlayerController(instigator.controller);
if (niceController == none) return;
niceRI = niceController.niceRI;
if (niceRI == none) return;
if( Role == ROLE_Authority && Instigator != none && Instigator.PlayerReplicationInfo != none )
Stats = SRStatsBase(Instigator.PlayerReplicationInfo.SteamStatsAndAchievements);
Destroy();
foreach CollidingActors (class 'Actor', Victims, DamageRadius, HitLocation)
{
P = none;
KFMonsterVictim = none;
bMonster = false;
KFP = none;
bAlreadyChecked = false;
niceRI.ServerExplode(damageAmount,
damageRadius,
1.0,
niceExplosiveDamage,
momentum,
hitLocation,
instigator);
// don't let blast damage affect fluid - VisibleCollisingActors doesn't really work for them - jag
if( (Victims != self) && (Hurtwall != Victims) && (Victims.Role == ROLE_Authority) && !Victims.IsA('FluidSurfaceInfo')
&& ExtendedZCollision(Victims)==None )
{
if( (Instigator==None || Instigator.Health<=0) && KFPawn(Victims)!=None )
Continue;
dir = Victims.Location - HitLocation;
dist = FMax(1,VSize(dir));
dir = dir/dist;
damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius);
if ( Instigator == None || Instigator.Controller == None )
{
Victims.SetDelayedDamageInstigatorController( InstigatorController );
}
P = Pawn(Victims);
if( P != none ) {
for (i = 0; i < CheckedPawns.Length; i++) {
if (CheckedPawns[i] == P) {
bAlreadyChecked = true;
break;
}
}
if( bAlreadyChecked )
continue;
CheckedPawns[CheckedPawns.Length] = P;
KFMonsterVictim = KFMonster(Victims);
if( KFMonsterVictim != none && KFMonsterVictim.Health <= 0 )
KFMonsterVictim = none;
KFP = KFPawn(Victims);
if( KFMonsterVictim != none ) {
damageScale *= KFMonsterVictim.GetExposureTo(Location + 15 * -Normal(PhysicsVolume.Gravity));
bMonster = true; // in case TakeDamage() and further Die() deletes the monster
}
else if( KFP != none ) {
damageScale *= KFP.GetExposureTo(Location + 15 * -Normal(PhysicsVolume.Gravity));
}
if ( damageScale <= 0)
continue;
}
if(NiceMonster(Victims) != none)
Victims.TakeDamage(damageScale * DamageAmount,Instigator,Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir
,(damageScale * Momentum * dir), niceExplosiveDamage);
else
Victims.TakeDamage(damageScale * DamageAmount,Instigator,Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir
,(damageScale * Momentum * dir), DamageType);
if( bMonster && (KFMonsterVictim == none || KFMonsterVictim.Health < 1) ) {
NumKilled++;
}
if (Vehicle(Victims) != None && Vehicle(Victims).Health > 0)
{
Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, InstigatorController, DamageType, Momentum, HitLocation);
}
}
}
if( Role == ROLE_Authority )
{
if ( bBlewInHands && NumKilled >= 5 && Stats != none )
class'ScrnAchievements'.static.ProgressAchievementByID(Stats.Rep, 'SuicideBomber', 1);
if ( NumKilled >= 4 )
{
KFGameType(Level.Game).DramaticEvent(0.05);
}
else if ( NumKilled >= 2 )
{
KFGameType(Level.Game).DramaticEvent(0.03);
}
}
bHurtEntry = false;
}
// Overridden to spawn different AvoidMarker
simulated function HitWall( vector HitNormal, actor Wall ){

View File

@ -4,8 +4,8 @@ defaultproperties
ProjectileSpeed=48250.000000
FireAimedAnim="Fire"
RecoilRate=0.040000
maxVerticalRecoilAngle=115
maxHorizontalRecoilAngle=0
maxVerticalRecoilAngle=550
maxHorizontalRecoilAngle=225
ShellEjectClass=Class'ROEffects.KFShellEjectAK'
ShellEjectBoneName="Shell_eject"
bAccuracyBonusForSemiAuto=True

View File

@ -10,6 +10,4 @@ defaultproperties
KDeathVel=1400.000000
KDeathUpKick=150.000000
VehicleDamageScaling=0.700000
stunMultiplier=3.0
stunLengthMultiplier=2.0
}

View File

@ -4,8 +4,8 @@ defaultproperties
{
WeaponPickupClass=class'NiceM41APickup'
AmmoPickupAmount=66
MaxAmmo=264
InitialAmount=66
MaxAmmo=300
InitialAmount=75
PickupClass=class'NiceM41AAmmoPickup'
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
IconCoords=(X1=336,Y1=82,X2=382,Y2=125)

View File

@ -3,7 +3,7 @@ class NiceM41APickup extends NiceM41APrimaryPickup;
defaultproperties
{
crossPerkIndecies(0)=6
AmmoCost=24
AmmoCost=60
BuyClipSize=1
SecondaryAmmoShortName="M41A Frag Grenades"
PrimaryWeaponPickup=class'NiceM41APrimaryPickup'

View File

@ -3,7 +3,7 @@ defaultproperties
{
cost=750
Weight=7.000000
AmmoCost=25
AmmoCost=66
BuyClipSize=66
PowerValue=70
SpeedValue=100

View File

@ -3,7 +3,7 @@ defaultproperties
{
WeaponPickupClass=class'NiceM41APickup'
AmmoPickupAmount=1
MaxAmmo=5
MaxAmmo=8
InitialAmount=2
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
IconCoords=(X1=434,Y1=253,X2=506,Y2=292)

View File

@ -5,8 +5,8 @@ defaultproperties
contBonus=1.400000
FireAimedAnim="Fire_Iron"
RecoilRate=0.050000
maxVerticalRecoilAngle=100
maxHorizontalRecoilAngle=0
maxVerticalRecoilAngle=400
maxHorizontalRecoilAngle=200
ShellEjectClass=Class'ROEffects.KFShellEjectAK'
ShellEjectBoneName="Shell_eject"
bAccuracyBonusForSemiAuto=True

View File

@ -17,7 +17,7 @@ defaultproperties
MagazineBone="clip"
bHasScope=True
ZoomedDisplayFOVHigh=50.000000
MagCapacity=60
MagCapacity=30
ReloadRate=3.500000
ReloadAnim="Reload"
ReloadAnimRate=1.000000

View File

@ -2,7 +2,7 @@ class NiceSA80LSWAmmo extends NiceAmmo;
defaultproperties
{
WeaponPickupClass=class'NiceSA80LSWPickup'
AmmoPickupAmount=60
AmmoPickupAmount=30
MaxAmmo=360
InitialAmount=90
PickupClass=class'NiceSA80LSWAmmoPickup'

View File

@ -1,7 +1,7 @@
class NiceSA80LSWAmmoPickup extends NiceAmmoPickup;
defaultproperties
{
AmmoAmount=60
AmmoAmount=30
InventoryType=class'NiceSA80LSWAmmo'
PickupMessage="5.56x45"
StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'

View File

@ -4,8 +4,8 @@ defaultproperties
ProjectileSpeed=46500.000000
FireAimedAnim="Iron_Idle"
RecoilRate=0.050000
maxVerticalRecoilAngle=75
maxHorizontalRecoilAngle=0
maxVerticalRecoilAngle=300
maxHorizontalRecoilAngle=150
ShellEjectClass=Class'ROEffects.KFShellEjectBullpup'
ShellEjectBoneName="Shell_eject"
bAccuracyBonusForSemiAuto=True

View File

@ -3,8 +3,8 @@ defaultproperties
{
cost=200
Weight=5.000000
AmmoCost=10
BuyClipSize=60
AmmoCost=5
BuyClipSize=30
PowerValue=41
SpeedValue=60
RangeValue=60

View File

@ -12,12 +12,12 @@ simulated function HandleRecoil(float Rec)
defaultproperties
{
ProjectileSpeed=42650.000000
maxBonusContLenght=10
maxBonusContLenght=5
contBonusReset=false
FireAimedAnim="FireLoop"
RecoilRate=0.040000
maxVerticalRecoilAngle=25
maxHorizontalRecoilAngle=0
maxVerticalRecoilAngle=450
maxHorizontalRecoilAngle=225
ShellEjectClass=Class'ROEffects.KFShellEjectSCAR'
ShellEjectBoneName="ejector"
FireSoundRef="HMG_S.XMV.XMV-Fire-1"

View File

@ -0,0 +1,19 @@
class NiceDamTypeHFRAssaultRifle extends NiceDamTypeFire
abstract;
defaultproperties
{
heatPart=0.500000
HeadShotDamageMult=6.000000
bCheckForHeadShots=True
WeaponClass=class'NiceHFR'
DeathString="%k killed %o (Horzine Flame Rifle)."
FemaleSuicide="%o shot herself in the foot."
MaleSuicide="%o shot himself in the foot."
bRagdollBullet=True
PawnDamageEmitter=Class'ROEffects.ROBloodPuff'
LowGoreDamageEmitter=Class'ROEffects.ROBloodPuffNoGore'
LowDetailEmitter=Class'ROEffects.ROBloodPuffSmall'
KDamageImpulse=5500.000000
KDeathVel=175.000000
KDeathUpKick=15.000000
}

View File

@ -1,5 +1,316 @@
class NiceHFR extends NiceScopedWeapon;
// Modification of the AAR525 weapons by: [B.R]HekuT
class NiceHFR extends KFWeapon;
#exec OBJ LOAD FILE=KillingFloorWeapons.utx
#exec OBJ LOAD FILE=KillingFloorHUD.utx
#exec OBJ LOAD FILE=Inf_Weapons_Foley.uax
#exec OBJ LOAD FILE=KF_Weapons5_Scopes_Trip_T.utx
var() Material ZoomMat;
var() int lenseMaterialID;
var() float scopePortalFOVHigh;
var() float scopePortalFOV;
var() vector XoffsetScoped;
var() vector XoffsetHighDetail;
var() int scopePitch;
var() int scopeYaw;
var() int scopePitchHigh;
var() int scopeYawHigh;
var ScriptedTexture ScopeScriptedTexture;
var Shader ScopeScriptedShader;
var Material ScriptedTextureFallback;
var Combiner ScriptedScopeCombiner;
var Combiner ScriptedScopeStatic;
var texture TexturedScopeTexture;
var bool bInitializedScope;
var string ZoomMatRef;
var string ScriptedTextureFallbackRef;
static function PreloadAssets(Inventory Inv, optional bool bSkipRefCount)
{
super.PreloadAssets(Inv, bSkipRefCount);
default.ZoomMat = FinalBlend(DynamicLoadObject(default.ZoomMatRef, class'FinalBlend', true));
default.ScriptedTextureFallback = texture(DynamicLoadObject(default.ScriptedTextureFallbackRef, class'texture', true));
if ( M99SniperRifle(Inv) != none )
{
M99SniperRifle(Inv).ZoomMat = default.ZoomMat;
M99SniperRifle(Inv).ScriptedTextureFallback = default.ScriptedTextureFallback;
}
}
static function bool UnloadAssets()
{
if ( super.UnloadAssets() )
{
default.ZoomMat = none;
default.ScriptedTextureFallback = none;
}
return true;
}
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);
}
simulated function bool ShouldDrawPortal()
{
if( bAimingRifle )
return true;
else
return false;
}
simulated function PostBeginPlay()
{
super.PostBeginPlay();
KFScopeDetail = class'KFMod.KFWeapon'.default.KFScopeDetail;
UpdateScopeMode();
}
simulated function UpdateScopeMode()
{
if (Level.NetMode != NM_DedicatedServer && Instigator != none && Instigator.IsLocallyControlled() &&
Instigator.IsHumanControlled() )
{
if( KFScopeDetail == KF_ModelScope )
{
scopePortalFOV = default.scopePortalFOV;
ZoomedDisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV);
if (bAimingRifle)
{
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 )
{
ScriptedScopeCombiner = Combiner(Level.ObjectPool.AllocateObject(class'Combiner'));
ScriptedScopeCombiner.Material1 = Texture'KF_Weapons5_Scopes_Trip_T.Scope.MilDot';
ScriptedScopeCombiner.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader';
ScriptedScopeCombiner.CombineOperation = CO_Multiply;
ScriptedScopeCombiner.AlphaOperation = AO_Use_Mask;
ScriptedScopeCombiner.Material2 = ScopeScriptedTexture;
}
if( ScopeScriptedShader == none )
{
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 = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOVHigh);
if (bAimingRifle)
{
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 )
{
ScriptedScopeCombiner = Combiner(Level.ObjectPool.AllocateObject(class'Combiner'));
ScriptedScopeCombiner.Material1 = Texture'KF_Weapons5_Scopes_Trip_T.Scope.MilDot';
ScriptedScopeCombiner.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader';
ScriptedScopeCombiner.CombineOperation = CO_Multiply;
ScriptedScopeCombiner.AlphaOperation = AO_Use_Mask;
ScriptedScopeCombiner.Material2 = ScopeScriptedTexture;
}
if( ScopeScriptedShader == none )
{
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 = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV);
PlayerViewOffset.X = default.PlayerViewOffset.X;
bInitializedScope = true;
}
}
}
simulated event RenderTexture(ScriptedTexture Tex)
{
local rotator RollMod;
RollMod = Instigator.GetViewRotation();
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 );
}
/**
* Handles all the functionality for zooming in including
* setting the parameters for the weapon, pawn, and playercontroller
*
* @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 event OnZoomInFinished()
{
local name anim;
local float frame, rate;
GetAnimParams(0, anim, frame, rate);
if (ClientState == WS_ReadyToFire)
{
if (anim == IdleAnim)
{
PlayIdle();
}
}
if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none &&
KFScopeDetail == KF_TextureScope )
{
KFPlayerController(Instigator.Controller).TransitionFOV(PlayerIronSightFOV,0.0);
}
}
simulated event RenderOverlays(Canvas Canvas)
{
local int m;
local PlayerController PC;
if (Instigator == none)
return;
PC = PlayerController(Instigator.Controller);
if(PC == none)
return;
if(!bInitializedScope && PC != none )
{
UpdateScopeMode();
}
Canvas.DrawActor(none, false, true);
for (m = 0; m < NUM_FIRE_MODES; m++)
{
if (FireMode[m] != none)
{
FireMode[m].DrawMuzzleFlash(Canvas);
}
}
SetLocation( Instigator.Location + Instigator.CalcDrawOffset(self) );
SetRotation( Instigator.GetViewRotation() + ZoomRotInterp);
PreDrawFPWeapon();
if(bAimingRifle && PC != none && (KFScopeDetail == KF_ModelScope || KFScopeDetail == KF_ModelScopeHigh))
{
if (ShouldDrawPortal())
{
if ( ScopeScriptedTexture != none )
{
Skins[LenseMaterialID] = ScopeScriptedShader;
ScopeScriptedTexture.Client = Self;
ScopeScriptedTexture.Revision = (ScopeScriptedTexture.Revision +1);
}
}
bDrawingFirstPerson = true;
Canvas.DrawBoundActor(self, false, false,DisplayFOV,PC.Rotation,rot(0,0,0),Instigator.CalcZoomedDrawOffset(self));
bDrawingFirstPerson = false;
}
else if( KFScopeDetail == KF_TextureScope && PC.DesiredFOV == PlayerIronSightFOV && bAimingRifle)
{
Skins[LenseMaterialID] = ScriptedTextureFallback;
SetZoomBlendColor(Canvas);
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);
Canvas.Style = 255;
Canvas.SetPos((Canvas.SizeX - Canvas.SizeY) / 2,0);
Canvas.DrawTile(ZoomMat, Canvas.SizeY, Canvas.SizeY, 0.0, 0.0, 1024, 1024);
Canvas.Font = Canvas.MedFont;
Canvas.SetDrawColor(200,150,0);
Canvas.SetPos(Canvas.SizeX * 0.16, Canvas.SizeY * 0.43);
Canvas.DrawText("Zoom: 3.0");
Canvas.SetPos(Canvas.SizeX * 0.16, Canvas.SizeY * 0.47);
}
else
{
Skins[LenseMaterialID] = ScriptedTextureFallback;
bDrawingFirstPerson = true;
Canvas.DrawActor(self, false, false, DisplayFOV);
bDrawingFirstPerson = false;
}
}
simulated function float CalcAspectRatioAdjustedFOV(float AdjustFOV)
{
local KFPlayerController KFPC;
@ -22,15 +333,204 @@ simulated function float CalcAspectRatioAdjustedFOV(float AdjustFOV)
return AdjustFOV;
}
}
simulated function AdjustIngameScope()
{
local PlayerController PC;
if(Instigator == none || PlayerController(Instigator.Controller) == none)
return;
PC = PlayerController(Instigator.Controller);
if( !bHasScope )
return;
switch (KFScopeDetail)
{
case KF_ModelScope:
if( bAimingRifle )
DisplayFOV = CalcAspectRatioAdjustedFOV(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 = CalcAspectRatioAdjustedFOV(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 = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOVHigh);
}
else
{
DisplayFOV = CalcAspectRatioAdjustedFOV(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;
}
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;
}
}
state PendingClientWeaponSet
{
simulated function Timer()
{
if ( Pawn(Owner) != none && !bIsReloading )
{
ClientWeaponSet(bPendingSwitch);
}
if ( IsInState('PendingClientWeaponSet') )
{
SetTimer(0.1, false);
}
}
simulated function BeginState()
{
SetTimer(0.1, false);
}
simulated function EndState()
{
}
}
simulated function SetZoomBlendColor(Canvas c)
{
local Byte val;
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;
}
function bool RecommendRangedAttack()
{
return true;
}
function float SuggestAttackStyle()
{
return -1.0;
}
function bool RecommendLongRangedAttack()
{
return true;
}
simulated function AnimEnd(int channel)
{
if(!FireMode[1].IsInState('FireLoop'))
{
Super.AnimEnd(channel);
}
}
simulated function WeaponTick(float dt)
{
Super.WeaponTick(dt);
}
simulated function bool StartFire(int Mode)
{
if( Mode == 0 )
return super.StartFire(Mode);
if( !super.StartFire(Mode) )
return false;
if( AmmoAmount(0) <= 0 )
{
return false;
}
AnimStopLooping();
if( !FireMode[Mode].IsInState('FireLoop') && (AmmoAmount(0) > 0) )
{
FireMode[Mode].StartFiring();
return true;
}
else
{
return false;
}
return true;
}
defaultproperties
{
reloadPreEndFrame=0.339
reloadEndFrame=0.732
reloadChargeEndFrame=-1.000000
reloadMagStartFrame=0.643
reloadChargeStartFrame=-1.000000
magazineBone="Magazine"
lenseMaterialID=3
scopePortalFOVHigh=22.000000
scopePortalFOV=12.000000
@ -38,13 +538,13 @@ defaultproperties
ScriptedTextureFallbackRef="NicePackT.HFR.CBLens_cmb"
bHasScope=True
ZoomedDisplayFOVHigh=35.000000
MagCapacity=50
MagCapacity=10
ReloadRate=3.000000
ReloadAnim="Reload"
ReloadAnimRate=0.600000
WeaponReloadAnim="Reload_M4"
bSteadyAim=True
Weight=5.000000
Weight=7.000000
bHasAimingMode=True
IdleAimAnim="Idle"
StandardDisplayFOV=60.000000
@ -62,7 +562,7 @@ defaultproperties
PlayerIronSightFOV=65.000000
ZoomedDisplayFOV=32.000000
FireModeClass(0)=class'NiceHFRPFire'
FireModeClass(1)=Class'KFMod.NoFire'
FireModeClass(1)=class'NiceHFRBurstFire'
PutDownAnim="PutDown"
AIRating=0.700000
CurrentRating=0.700000

View File

@ -1,10 +1,10 @@
class NiceHFRAmmo extends NiceAmmo;
class NiceHFRAmmo extends KFAmmunition;
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
defaultproperties
{
AmmoPickupAmount=75
MaxAmmo=300
InitialAmount=75
AmmoPickupAmount=15
MaxAmmo=100
InitialAmount=40
PickupClass=class'NiceHFRAmmoPickup'
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
IconCoords=(X1=336,Y1=82,X2=382,Y2=125)

View File

@ -1,7 +1,7 @@
class NiceHFRAmmoPickup extends NiceAmmoPickup;
class NiceHFRAmmoPickup extends KFAmmoPickup;
defaultproperties
{
AmmoAmount=50
AmmoAmount=15
InventoryType=class'NiceHFRAmmo'
PickupMessage="Fire balloon"
StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'

View File

@ -1,11 +0,0 @@
class NiceHFRBullet extends NiceBullet;
defaultproperties
{
bDisableComplexMovement=False
trailXClass=None
StaticMeshRef="ZED_FX_SM.Energy.ZED_FX_Energy_Card"
DrawScale=0.500000
ambientSoundRef="KF_FY_ZEDV2SND.WEP_ZEDV2_Projectile_Loop"
explosionImpact=(bImportanEffect=True,decalClass=Class'KFMod.FlameThrowerBurnMark_Medium',EmitterClass=Class'KFMod.ZEDMKIIPrimaryProjectileImpact',emitterShiftWall=20.000000,emitterShiftPawn=20.000000,noiseRef="KF_FY_ZEDV2SND.WEP_ZEDV2_Projectile_Explode",noiseVolume=2.000000)
}

View File

@ -1,29 +1,25 @@
class NiceHFRPFire extends NiceFire;
class NiceHFRPFire extends KFFire;
defaultproperties
{
ProjectileSpeed=2000.000000
FireAimedAnim="Fire_Iron"
RecoilRate=0.070000
maxVerticalRecoilAngle=70
maxHorizontalRecoilAngle=35
RecoilRate=0.120000
maxVerticalRecoilAngle=500
bAccuracyBonusForSemiAuto=True
bRandomPitchFireSound=False
FireSoundRef="KF_FY_ZEDV2SND.WEP_ZEDV2_Fire_M"
StereoFireSoundRef="KF_FY_ZEDV2SND.WEP_ZEDV2_Fire_S"
NoAmmoSoundRef="KF_ZEDGunSnd.KF_WEP_ZED_Dryfire"
DamageType=class'NiceDamTypeHFR'
FireSoundRef="KF_SP_LongmusketSnd.KFO_Sniper_Fire_M"
StereoFireSoundRef="KF_SP_LongmusketSnd.KFO_Sniper_Fire_S"
NoAmmoSoundRef="KF_AK47Snd.AK47_DryFire"
DamageType=class'NiceDamTypeHFRAssaultRifle'
DamageMax=50
Momentum=8500.000000
bWaitForRelease=False
bWaitForRelease=True
TransientSoundVolume=1.200000
TransientSoundRadius=500.000000
FireLoopAnim="Fire"
FireAnimRate=0.909000
TweenTime=0.025000
FireForce="AssaultRifleFire"
FireRate=0.096000
bulletClass=class'NiceHFRBullet'
FireRate=0.600000
AmmoClass=class'NiceHFRAmmo'
AmmoPerFire=1
ShakeRotMag=(X=50.000000,Y=50.000000,Z=350.000000)
@ -36,4 +32,5 @@ defaultproperties
FlashEmitterClass=Class'ROEffects.MuzzleFlash1stSPSniper'
aimerror=42.000000
Spread=0.015000
SpreadStyle=SS_Random
}

View File

@ -1,19 +1,18 @@
class NiceHFRPickup extends NiceWeaponPickup;
class NiceHFRPickup extends KFWeaponPickup;
defaultproperties
{
Weight=5.000000
AmmoCost=26
BuyClipSize=50
Weight=7.000000
AmmoCost=30
BuyClipSize=15
PowerValue=100
SpeedValue=100
RangeValue=40
cost=750
Description="Advanced horzine flame rifle."
ItemName="Horzine flame rifle"
ItemShortName="HFR"
AmmoItemName="Fire balloon"
AmmoMesh=StaticMesh'KillingFloorStatics.FT_AmmoMesh'
CorrespondingPerkIndex=3
CorrespondingPerkIndex=5
EquipmentCategoryID=3
InventoryType=class'NiceHFR'
PickupMessage="You got the HFR."

View File

@ -1,6 +1,6 @@
class NiceHFRTendril extends FlameTendril;
defaultproperties
{
Damage=16.000000
Damage=36.000000
MyDamageType=class'NiceDamTypeHFR'
}

View File

@ -1,8 +1,6 @@
class NiceDamTypeKrissM extends NiceDamageTypeVetDemolitions
class NiceDamTypeKrissM extends NiceDamageTypeVetCommando
abstract;
defaultproperties
{
stoppingPower=0.25
HeadShotDamageMult=1.500000
WeaponClass=class'NiceKrissMMedicGun'
}

View File

@ -13,8 +13,8 @@ defaultproperties
ShellEjectBoneName="Shell_eject"
NoAmmoSoundRef="KF_MP7Snd.MP7_DryFire"
DamageType=class'NiceDamTypeKrissM'
DamageMin=48
DamageMax=48
DamageMin=35
DamageMax=35
Momentum=12500.000000
FireRate=0.040000
AmmoClass=class'NiceKrissMAmmo'
@ -27,8 +27,4 @@ defaultproperties
FlashEmitterClass=Class'ROEffects.MuzzleFlash1stMP'
Spread=500.0
SpreadStyle=SS_Random
minimalSpreadScale=0.0
activeSpreadScale=0.0
spreadGainedPerShot=0.125
spreadLostPerSecond=0.5
}

View File

@ -17,7 +17,7 @@ defaultproperties
AmmoItemName="45. ACP Ammo"
AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo'
EquipmentCategoryID=3
CorrespondingPerkIndex=6
CorrespondingPerkIndex=3
InventoryType=class'NiceKrissMMedicGun'
PickupMessage="You got the KRISS Vector Medic Gun"
PickupSound=Sound'KF_KrissSND.Handling.KF_WEP_KRISS_Handling_Pickup'

View File

@ -1,8 +1,7 @@
class NiceDamTypeM7A3M extends NiceDamageTypeVetDemolitions
class NiceDamTypeM7A3M extends NiceDamageTypeVetCommando
abstract;
defaultproperties
{
stoppingPower=0.15
HeadShotDamageMult=2.000000
WeaponClass=class'NiceM7A3MMedicGun'
}

View File

@ -3,8 +3,8 @@ defaultproperties
{
WeaponPickupClass=class'NiceM7A3MPickup'
AmmoPickupAmount=30
MaxAmmo=160
InitialAmount=40
MaxAmmo=180
InitialAmount=45
PickupClass=class'NiceM7A3MAmmoPickup'
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
IconCoords=(X1=336,Y1=82,X2=382,Y2=125)

View File

@ -1,7 +1,7 @@
class NiceM7A3MAmmoPickup extends NiceAmmoPickup;
defaultproperties
{
AmmoAmount=30
AmmoAmount=15
InventoryType=class'NiceM7A3MAmmo'
PickupMessage="Rounds 7.6x40mm"
StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'

View File

@ -34,8 +34,4 @@ defaultproperties
aimerror=42.000000
Spread=500.0
SpreadStyle=SS_Random
minimalSpreadScale=0.0
activeSpreadScale=0.0
spreadGainedPerShot=0.25
spreadLostPerSecond=0.5
}

View File

@ -3,7 +3,7 @@ defaultproperties
{
Weight=5.000000
cost=1250
AmmoCost=50
AmmoCost=33
BuyClipSize=30
PowerValue=45
SpeedValue=60
@ -14,7 +14,7 @@ defaultproperties
AmmoItemName="7.6x40mm Ammo"
AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo'
EquipmentCategoryID=3
CorrespondingPerkIndex=6
CorrespondingPerkIndex=3
InventoryType=class'NiceM7A3MMedicGun'
PickupMessage="You got the M7A3 Medic Gun"
PickupSound=Sound'KF_M7A3Snd.M7A3_Pickup'

View File

@ -1,8 +1,7 @@
class NiceDamTypeMP5M extends NiceDamageTypeVetDemolitions
class NiceDamTypeMP5M extends NiceDamageTypeVetCommando
abstract;
defaultproperties
{
stoppingPower=0.15
HeadShotDamageMult=2.000000
WeaponClass=class'NiceMP5MMedicGun'
}

View File

@ -5,9 +5,9 @@ defaultproperties
FireEndStereoSoundRef="KF_MP5Snd.MP5_Fire_Loop_End_S"
AmbientFireSoundRef="KF_MP5Snd.MP5_Fire_Loop"
ProjectileSpeed=21250.000000
RecoilRate=0.0100000
maxVerticalRecoilAngle=40
maxHorizontalRecoilAngle=20
RecoilRate=0.0075000
maxVerticalRecoilAngle=160
maxHorizontalRecoilAngle=80
RecoilVelocityScale=0.000000
ShellEjectClass=Class'ROEffects.KFShellEjectMP5SMG'
ShellEjectBoneName="Shell_eject"
@ -15,12 +15,8 @@ defaultproperties
DamageType=class'NiceDamTypeMP5M'
DamageMin=35
DamageMax=35
Spread=750.0
Spread=500.0
SpreadStyle=SS_Random
minimalSpreadScale=0.0
activeSpreadScale=0.0
spreadGainedPerShot=0.25
spreadLostPerSecond=1.0
Momentum=5500.000000
FireRate=0.075000
AmmoClass=class'NiceMP5MAmmo'

View File

@ -14,7 +14,7 @@ defaultproperties
AmmoItemName="9x19mm Ammo"
AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo'
EquipmentCategoryID=3
CorrespondingPerkIndex=6
CorrespondingPerkIndex=3
VariantClasses(0)=Class'KFMod.CamoMP5MPickup'
InventoryType=class'NiceMP5MMedicGun'
PickupMessage="You got the MP5M Medic Gun"

View File

@ -1,10 +1,9 @@
class NiceDamTypeMP7M extends NiceDamageTypeVetDemolitions
class NiceDamTypeMP7M extends NiceDamageTypeVetCommando
abstract;
defaultproperties
{
bPenetrationHSOnly=True
MaxPenetrations=1
HeadShotDamageMult=2.250000
stoppingPower=0.15
WeaponClass=class'NiceMP7MMedicGun'
}

View File

@ -25,10 +25,6 @@ defaultproperties
ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000)
ShakeOffsetTime=1.250000
FlashEmitterClass=Class'ROEffects.MuzzleFlash1stMP'
Spread=750.0
Spread=500.0
SpreadStyle=SS_Random
minimalSpreadScale=0.0
activeSpreadScale=0.0
spreadGainedPerShot=0.1
spreadLostPerSecond=0.5
}

View File

@ -15,7 +15,7 @@ defaultproperties
AmmoItemName="4.6x30mm Ammo"
AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo'
EquipmentCategoryID=3
CorrespondingPerkIndex=6
CorrespondingPerkIndex=3
InventoryType=class'NiceMP7MMedicGun'
PickupMessage="You got the MP7M Medic Gun"
PickupSound=Sound'KF_MP7Snd.MP7_Pickup'

View File

@ -58,6 +58,5 @@ defaultproperties
ShakeOffsetTime=3.500000
BotRefireRate=2.500000
aimerror=2.000000
Spread=2000.000000
FireAnimRate=1.25
Spread=3000.000000
}

View File

@ -10,7 +10,7 @@ defaultproperties
reloadMagStartFrame=0.278000
reloadChargeStartFrame=-1.000000
FirstPersonFlashlightOffset=(X=-20.000000,Y=-22.000000,Z=8.000000)
MagCapacity=42
MagCapacity=28
ReloadRate=2.600000
ReloadAnim="Reload"
ReloadAnimRate=1.000000

View File

@ -3,9 +3,6 @@ defaultproperties
{
bCanFireIncomplete=True
ProjectileSpeed=3500.000000
maxVerticalRecoilAngle=1250
maxHorizontalRecoilAngle=750
FireRate=0.600000
DamageType=class'NiceDamTypeNailGunWeak'
AmmoPerFire=7
SpreadStyle=SS_Random

View File

@ -3,9 +3,9 @@ class NiceNailGunAmmo extends NiceAmmo;
defaultproperties
{
WeaponPickupClass=class'NiceNailGunPickup'
AmmoPickupAmount=42
MaxAmmo=210
InitialAmount=52
AmmoPickupAmount=28
MaxAmmo=168
InitialAmount=84
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
IconCoords=(X1=451,Y1=445,X2=510,Y2=500)
}

View File

@ -10,8 +10,8 @@ defaultproperties
bShouldBounce=True
bCausePain=True
bulletClass=class'NiceNail'
maxVerticalRecoilAngle=0
maxHorizontalRecoilAngle=0
maxVerticalRecoilAngle=1250
maxHorizontalRecoilAngle=750
bRandomPitchFireSound=True
FireSoundRef="KF_NailShotgun.NailShotgun_Fire_Single_M"
StereoFireSoundRef="KF_NailShotgun.NailShotgun_Fire_Single_S"
@ -19,7 +19,7 @@ defaultproperties
DamageType=class'NiceDamTypeNailGun'
DamageMax=66
FireAnimRate=1.250000
FireRate=0.300000
FireRate=0.400000
AmmoClass=class'NiceNailGunAmmo'
ShakeRotTime=3.000000
ShakeOffsetTime=2.000000

View File

@ -3,8 +3,8 @@ defaultproperties
{
Weight=8.000000
cost=250
AmmoCost=27
BuyClipSize=42
AmmoCost=17
BuyClipSize=28
PowerValue=70
SpeedValue=55
RangeValue=25

View File

@ -1,7 +1,6 @@
class NiceSpasAltFire extends NiceSpasFire;
defaultproperties
{
ProjPerFire=8
maxVerticalRecoilAngle=300
maxHorizontalRecoilAngle=180
FireAnimRate=0.650000

View File

@ -6,7 +6,7 @@ defaultproperties
{
Weight=6.000000
cost=750
AmmoCost=22
AmmoCost=34
BuyClipSize=5
PowerValue=55
SpeedValue=42

View File

@ -1,108 +1,8 @@
class NiceSyringe extends NiceMeleeWeapon;
var () int HealBoostAmount;
var float RegenTimer;
var localized string SuccessfulHealMessage;
replication
{
reliable if( Role == ROLE_Authority )
ClientSuccessfulHeal;
class NiceSyringe extends ScrnSyringe;
}
simulated function PostBeginPlay()
{
// Weapon will handle FireMode instantiation
Super.PostBeginPlay();
if( Role == ROLE_Authority ) {
HealBoostAmount = default.HealBoostAmount;
}
}
// The server lets the client know they successfully healed someone
simulated function ClientSuccessfulHeal(String HealedName)
{
if( PlayerController(Instigator.Controller) != none )
{
PlayerController(Instigator.controller).ClientMessage(SuccessfulHealMessage$HealedName, 'CriticalEvent');
}
}
simulated function Timer()
{
Super.Timer();
if( KFPawn(Instigator)!=None && KFPawn(Instigator).bIsQuickHealing>0 && ClientState==WS_ReadyToFire )
{
if( KFPawn(Instigator).bIsQuickHealing==1 )
{
if( !HackClientStartFire() )
{
if( Instigator.Health>=Instigator.HealthMax || ChargeBar()<0.75 )
KFPawn(Instigator).bIsQuickHealing = 2; // Was healed by someone else or some other error occurred.
SetTimer(0.2,False);
return;
}
KFPawn(Instigator).bIsQuickHealing = 2;
SetTimer(FireMode[1].FireRate+0.5,False);
}
else
{
Instigator.SwitchToLastWeapon();
KFPawn(Instigator).bIsQuickHealing = 0;
}
}
else if( ClientState==WS_Hidden && KFPawn(Instigator)!=None )
KFPawn(Instigator).bIsQuickHealing = 0; // Weapon was changed, ensure to reset this.
}
simulated function bool HackClientStartFire()
{
if( StartFire(1) )
{
if( Role<ROLE_Authority )
ServerStartFire(1);
FireMode[1].ModeDoFire(); // Force to start animating.
return true;
}
return false;
}
defaultproperties
{
MagCapacity=1
bChangeClipIcon=True
hudClipTexture=Texture'KillingFloorHUD.HUD.Hud_Syringe'
BloodSkinSwitchArray=0
HealBoostAmount = 100
TraderInfoTexture=Texture'KillingFloorHUD.WeaponSelect.Syringe'
FireModeClass(0)=Class'NicePack.NiceSyringeFire'
FireModeClass(1)=Class'NicePack.NiceSyringeAltFire'
PickupClass=Class'NicePack.NiceSyringePickup'
bKFNeverThrow = false
Skins(0)=Combiner'KF_Weapons_Trip_T.equipment.medInjector_cmb'
weaponRange=90.000000
Weight=0.000000
AIRating=-2.000000
bMeleeWeapon=False
Priority=6
InventoryGroup=5
GroupOffset=2
BobDamping=8.000000
AttachmentClass=Class'KFMod.SyringeAttachment'
IconCoords=(X1=169,Y1=39,X2=241,Y2=77)
ItemName="Med-Syringe"
Mesh=SkeletalMesh'KF_Weapons_Trip.Syringe_Trip'
AmbientGlow=2
AmmoCharge(0)=500
DisplayFOV=85.000000
StandardDisplayFOV=85.0
HudImage=texture'KillingFloorHUD.WeaponSelect.Syring_unselected'
SelectedHudImage=texture'KillingFloorHUD.WeaponSelect.Syringe'
bConsumesPhysicalAmmo=true
SuccessfulHealMessage="You healed "
defaultproperties {
ItemName="Nice Med-Syringe"
FireModeClass(0)=class'NiceSyringeFire'
FireModeClass(1)=class'NiceSyringeAltFire'
PickupClass=class'NiceSyringePickup'
}

View File

@ -1,90 +1 @@
class NiceSyringeAltFire extends NiceMeleeFire;
var float InjectDelay;
var float HealeeRange;
function DoFireEffect()
{
SetTimer(InjectDelay, False);
if ( Level.NetMode != NM_StandAlone && Level.Game.NumPlayers > 1 && KFPlayerController(Instigator.Controller) != none &&
KFSteamStatsAndAchievements(KFPlayerController(Instigator.Controller).SteamStatsAndAchievements) != none )
{
KFSteamStatsAndAchievements(KFPlayerController(Instigator.Controller).SteamStatsAndAchievements).AddSelfHeal();
}
}
function Timer()
{
local float HealSum, HealPotency;
local KFPlayerReplicationInfo KFPRI;
KFPRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
HealSum = NiceSyringe(Weapon).HealBoostAmount;
HealPotency = 1.0;
if ( KFPRI != none && KFPRI.ClientVeteranSkill != none )
HealPotency = KFPRI.ClientVeteranSkill.Static.GetHealPotency(KFPRI);
HealSum *= HealPotency;
Load = 1;
ReduceAmmoClient();
if ( NiceHumanPawn(Instigator) != none )
NiceHumanPawn(Instigator).TakeHealing(NiceHumanPawn(Instigator), HealSum, HealPotency, KFWeapon(Instigator.Weapon));
else
KFPawn(Instigator).GiveHealth(HealSum, Instigator.HealthMax);
}
function bool AllowFire()
{
if (Instigator.Health >= Instigator.HealthMax)
return false;
return Weapon.AmmoAmount(ThisModeNum) >= AmmoPerFire;
}
event ModeDoFire()
{
Load = 1;
Super.ModeDoFire();
}
function PlayFiring()
{
if ( Weapon.Mesh != None )
{
if ( FireCount > 0 )
{
if ( Weapon.HasAnim(FireLoopAnim) )
{
Weapon.PlayAnim(FireLoopAnim, FireLoopAnimRate, 0.0);
}
else
{
Weapon.PlayAnim(FireAnim, FireAnimRate, 0.0);
}
}
else
{
Weapon.PlayAnim(FireAnim, FireAnimRate, 0.0);
}
}
Weapon.PlayOwnedSound(FireSound,SLOT_Interact,TransientSoundVolume,,TransientSoundRadius,Default.FireAnimRate/FireAnimRate,false);
ClientPlayForceFeedback(FireForce); // jdf
FireCount++;
}
defaultproperties {
AmmoClass=class'NiceSyringeAmmo'
AmmoPerFire=1
TweenTime=0.1
TransientSoundVolume=1.8
FireAnim="AltFire"
FireRate=3.60000
bModeExclusive=true
InjectDelay=0.1
HealeeRange=70.000000
}
class NiceSyringeAltFire extends ScrnSyringeAltFire;

View File

@ -1,12 +0,0 @@
class NiceSyringeAmmo extends NiceAmmo;
defaultproperties {
WeaponPickupClass=class'NiceSyringePickup'
AmmoPickupAmount=0
MaxAmmo=4
InitialAmount=1
PickupClass=class'NiceSyringeAmmoPickup'
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
IconCoords=(X1=336,Y1=82,X2=382,Y2=125)
ItemName="Healing juice"
}

View File

@ -1,8 +0,0 @@
class NiceSyringeAmmoPickup extends NiceAmmoPickup;
defaultproperties {
AmmoAmount=1
InventoryType=class'NiceSyringe'
PickupMessage="Healing juice"
StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'
}

View File

@ -1,208 +1,23 @@
class NiceSyringeFire extends NiceMeleeFire;
class NiceSyringeFire extends ScrnSyringeFire;
var float LastHealAttempt;
var float HealAttemptDelay;
var float LastHealMessageTime;
var float HealMessageDelay;
var localized string NoHealTargetMessage;
var KFHumanPawn CachedHealee;
var transient float PendingHealTime;
// default == 80
const SEARCH_RADIUS=120.0;
simulated function DestroyEffects()
{
super.DestroyEffects();
if (CachedHealee != None)
CachedHealee = none;
}
simulated function bool AllowFire() {
local KFHumanPawn Healtarget;
local string healeeName;
if (!super.AllowFire()) {
return false;
}
if (CanFindHealee()) {
if( CachedHealee.PlayerReplicationInfo != none &&
CachedHealee.PlayerReplicationInfo.PlayerName != "")
{
HealeeName = CachedHealee.PlayerReplicationInfo.PlayerName;
}
else {
HealeeName = CachedHealee.MenuName;
}
NiceSyringe(Weapon).ClientSuccessfulHeal(HealeeName);
// Give the messages if we missed our heal, can't find a target, etc
if ( KFPlayerController(Instigator.Controller) != none )
{
if ( LastHealAttempt + HealAttemptDelay < Level.TimeSeconds)
{
PlayerController(Instigator.controller).ClientMessage(NoHealTargetMessage, 'CriticalEvent');
LastHealAttempt = Level.TimeSeconds;
}
if ( Level.TimeSeconds - LastHealMessageTime > HealMessageDelay )
{
// if there's a Player within 2 meters who needs healing, say that we're trying to heal them
foreach Instigator.VisibleCollidingActors(class'KFHumanPawn', Healtarget, 100)
{
if ( Healtarget != Instigator && Healtarget.Health < Healtarget.HealthMax )
{
PlayerController(Instigator.Controller).Speech('AUTO', 5, "");
LastHealMessageTime = Level.TimeSeconds;
break;
}
}
}
}
return true;
}
return false;
}
function Timer()
{
local KFPlayerReplicationInfo PRI;
local int MedicReward;
local KFHumanPawn Healed;
local float HealSum, HealPotency; // for modifying based on perks
PRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
Healed = CachedHealee;
HealPotency = 1.0;
CachedHealee = none;
if ( Healed != none && Healed.Health > 0 && Healed != Instigator )
{
Load = 1;
ReduceAmmoClient();
if ( PRI != none && PRI.ClientVeteranSkill != none )
HealPotency = PRI.ClientVeteranSkill.Static.GetHealPotency(PRI);
HealSum = NiceSyringe(Weapon).HealBoostAmount;
HealSum *= HealPotency;
MedicReward = HealSum;
if ( (Healed.Health + Healed.healthToGive + MedicReward) > Healed.HealthMax )
{
MedicReward = Healed.HealthMax - (Healed.Health + Healed.healthToGive);
if ( MedicReward < 0 )
{
MedicReward = 0;
}
}
if ( NiceHumanPawn(Healed) != none )
NiceHumanPawn(Healed).TakeHealing(NiceHumanPawn(Instigator), HealSum, HealPotency, KFWeapon(Instigator.Weapon));
else
Healed.GiveHealth(HealSum, Healed.HealthMax);
// Tell them we're healing them
PlayerController(Instigator.Controller).Speech('AUTO', 5, "");
LastHealMessageTime = Level.TimeSeconds;
if ( PRI != None )
{
if ( MedicReward > 0 && KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements) != none )
{
KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements).AddDamageHealed(MedicReward);
}
// Give the medic reward money as a percentage of how much of the person's health they healed
MedicReward = int((FMin(float(MedicReward),Healed.HealthMax)/Healed.HealthMax) * 60); // Increased to 80 in Balance Round 6, reduced to 60 in Round 7
if ( class'ScrnBalance'.default.Mut.bMedicRewardFromTeam && Healed.PlayerReplicationInfo != none && Healed.PlayerReplicationInfo.Team != none ) {
// give money from team wallet
if ( Healed.PlayerReplicationInfo.Team.Score >= MedicReward ) {
Healed.PlayerReplicationInfo.Team.Score -= MedicReward;
PRI.Score += MedicReward;
}
}
else
PRI.Score += MedicReward;
if ( KFHumanPawn(Instigator) != none )
{
KFHumanPawn(Instigator).AlphaAmount = 255;
}
}
}
}
function KFHumanPawn GetHealee()
{
function KFHumanPawn GetHealee() {
local KFHumanPawn KFHP, BestKFHP;
local vector Dir;
local float TempDot, BestDot;
Dir = vector(Instigator.GetViewRotation());
foreach Instigator.VisibleCollidingActors(class'KFHumanPawn', KFHP, 80.0)
{
if ( KFHP.Health < KFHP.HealthMax && KFHP.Health > 0 )
{
foreach Instigator.VisibleCollidingActors(class'KFHumanPawn', KFHP, SEARCH_RADIUS) {
if (KFHP.Health < KFHP.HealthMax && KFHP.Health > 0) {
TempDot = Dir dot (KFHP.Location - Instigator.Location);
if ( TempDot > 0.7 && TempDot > BestDot )
{
if (TempDot > 0.7 && TempDot > BestDot) {
BestKFHP = KFHP;
BestDot = TempDot;
}
}
}
return BestKFHP;
}
// Can we find someone to heal
function bool CanFindHealee()
{
local KFHumanPawn Healtarget;
Healtarget = GetHealee();
CachedHealee = Healtarget;
// Can't use syringe if we can't find a target
if ( Healtarget == none )
{
if ( KFPlayerController(Instigator.Controller) != none )
{
KFPlayerController(Instigator.Controller).CheckForHint(53);
}
return false;
}
// Can't use syringe if our target is already being healed to full health.
if ( (Healtarget.Health == Healtarget.Healthmax) || ((Healtarget.healthToGive + Healtarget.Health) >= Healtarget.Healthmax) )
{
return false;
}
return true;
}
function float GetFireSpeed()
{
if ( KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill != none )
{
return KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill.Static.GetFireSpeedMod(KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo), Weapon);
}
return 1;
}
defaultproperties {
AmmoClass=class'NiceSyringeAmmo'
ammoPerFire=1
FireAnims(0)="Fire"
FireRate=2.800000
damageDelay=0.36
HealAttemptDelay=0.5
HealMessageDelay=10.0
NoHealTargetMessage="You must be near another player to heal them!"
bWaitForRelease=true
}

View File

@ -1,19 +1,6 @@
class NiceSyringePickup extends NiceWeaponPickup;
class NiceSyringePickup extends ScrnSyringePickup;
defaultproperties {
ItemName="Med-Syringe"
InventoryType=Class'NicePack.NiceSyringe'
Weight=0.000000
cost=100
AmmoCost=40
BuyClipSize=1
PickupMessage="You got the Med-Syringe."
PickupSound=Sound'Inf_Weapons_Foley.AmmoPickup'
PickupForce="AssaultRiflePickup"
StaticMesh=StaticMesh'KF_pickups_Trip.Syringe_pickup'
CollisionHeight=5.000000
EquipmentCategoryID=0
ItemShortName="Syringe"
AmmoItemName="Healing juice"
Description="Basic equipment, necessary for survival."
ItemName="Nice Med-Syringe"
InventoryType=class'NiceSyringe'
}

View File

@ -27,20 +27,23 @@ Ignores StartChargingFP;
bFrustrated = false;
if(Controller != none)
NiceZombieFleshPoundController(Controller).RageFrustrationTimer = 0;
if( Health>0 && !bZapped )
{
SetGroundSpeed(GetOriginalGroundSpeed());
}
if( Level.NetMode!=NM_DedicatedServer )
ClientChargingAnims();
NetUpdateTime = Level.TimeSeconds - 1;
}
simulated function UpdateGroundSpeed() {
super(NiceMonster).UpdateGroundSpeed();
if (!bShotAnim) {
groundSpeed *= 2.3;
}
}
function Tick( float Delta )
{
if( !bShotAnim )
{
SetGroundSpeed(OriginalGroundSpeed * 2.3);//2.0;
}
// Keep the flesh pound moving toward its target when attacking
if( Role == ROLE_Authority && bShotAnim)
{

View File

@ -37,7 +37,7 @@ function RangedAttack(Actor A) {
//Increment the number of consecutive shtos taken and apply the cool down if needed
totalShots ++;
consecutiveShots ++;
if(consecutiveShots < 3 && totalShots > maxNormalShots && VSize(a.location - location) <= 900)
if(consecutiveShots < 3 && totalShots > maxNormalShots)
NextFireProjectileTime = Level.TimeSeconds;
else{
NextFireProjectileTime = Level.TimeSeconds + ProjectileFireInterval + (FRand() * 2.0);

View File

@ -0,0 +1,30 @@
class NiceBloatVomit extends KFBloatVomit;
// limit how much you can damage zeds
const DAMAGECOUNT=10;
var private transient int DamageTicked;
auto state Flying {
simulated function ProcessTouch(Actor Other, Vector HitLocation) {
// add damage limit
if (DamageTicked >= DAMAGECOUNT) {
BlowUp(HitLocation);
return;
}
if (ExtendedZCollision(Other) != none) {
return;
}
if (
Other != Instigator &&
(Other.IsA('Pawn') || Other.IsA('DestroyableObjective') || Other.bProjTarget)
) {
DamageTicked += 1;
// warn("DamageTicked: " $ DamageTicked);
// use server DelayedHurtRadius() instead?
HurtRadius(Damage, DamageRadius, MyDamageType, MomentumTransfer, HitLocation);
}
else if (Other != Instigator && Other.bBlockActors) {
HitWall(Normal(HitLocation - Location), Other);
}
}
}

View File

@ -173,7 +173,8 @@ function SpawnTwoShots()
if ( !SavedFireProperties.bInitialized )
{
SavedFireProperties.AmmoClass = Class'SkaarjAmmo';
SavedFireProperties.ProjectileClass = Class'KFBloatVomit';
// use fixed bile class, to prevent super high damage to zeds
SavedFireProperties.ProjectileClass = Class'NiceBloatVomit';
SavedFireProperties.WarnTargetPct = 1;
SavedFireProperties.MaxRange = 500;
SavedFireProperties.bTossed = False;
@ -185,13 +186,13 @@ function SpawnTwoShots()
// Turn off extra collision before spawning vomit, otherwise spawn fails
ToggleAuxCollision(false);
FireRotation = Controller.AdjustAim(SavedFireProperties,FireStart,600);
Spawn(Class'KFBloatVomit',,,FireStart,FireRotation);
Spawn(SavedFireProperties.ProjectileClass,,,FireStart,FireRotation);
FireStart-=(0.5*CollisionRadius*Y);
FireRotation.Yaw -= 1200;
spawn(Class'KFBloatVomit',,,FireStart, FireRotation);
spawn(SavedFireProperties.ProjectileClass,,,FireStart, FireRotation);
FireStart+=(CollisionRadius*Y);
FireRotation.Yaw += 2400;
spawn(Class'KFBloatVomit',,,FireStart, FireRotation);
spawn(SavedFireProperties.ProjectileClass,,,FireStart, FireRotation);
// Turn extra collision back on
ToggleAuxCollision(true);
}

View File

@ -915,16 +915,9 @@ state Charging
// How many charge attacks we can do randomly 1-3
NumChargeAttacks = Rand(2) + 1;
}
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
if (bShotAnim) {
groundSpeed *= 1.25;
} else {
groundSpeed *= 2.5;
}
}
function EndState()
{
SetGroundSpeed(GetOriginalGroundSpeed());
bChargingPlayer = False;
ChargeDamage = 0;
if( Level.NetMode!=NM_DedicatedServer )
@ -949,6 +942,7 @@ state Charging
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
}
SetGroundSpeed(OriginalGroundSpeed * 1.25);
if( LookTarget!=none )
{
Acceleration = AccelRate * Normal(LookTarget.Location - Location);
@ -962,6 +956,16 @@ state Charging
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
}
// Zapping slows him down, but doesn't stop him
if( bZapped )
{
SetGroundSpeed(OriginalGroundSpeed * 1.5);
}
else
{
SetGroundSpeed(OriginalGroundSpeed * 2.5);
}
}
Global.Tick(Delta);
@ -1067,6 +1071,7 @@ State Escaping extends Charging // Got hurt and running away...
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
}
SetGroundSpeed(GetOriginalGroundSpeed());
}
else
{
@ -1076,20 +1081,23 @@ State Escaping extends Charging // Got hurt and running away...
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
}
// Zapping slows him down, but doesn't stop him
if( bZapped )
{
SetGroundSpeed(OriginalGroundSpeed * 1.5);
}
else
{
SetGroundSpeed(OriginalGroundSpeed * 2.5);
}
}
Global.Tick(Delta);
}
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
if (bShotAnim) {
groundSpeed *= 1.25;
} else {
groundSpeed *= 2.5;
}
}
function EndState()
{
SetGroundSpeed(GetOriginalGroundSpeed());
bChargingPlayer = False;
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();

View File

@ -52,6 +52,7 @@ defaultproperties
ClawMeleeDamageRange=85.000000
ImpaleMeleeDamageRange=45.000000
fuelRatio=0.400000
bFrugalFuelUsage=False
clientHeadshotScale=1.200000
ZapThreshold=5.000000
ZappedDamageMod=1.250000
@ -97,9 +98,6 @@ defaultproperties
HealthMax=8000.000000
Health=8000
HeadScale=1.300000
stoppingRecoveryRate=0.1
maxStoppingEffect=0.2
minStoppingThreshold=0.6
MenuName="Nice Patriarch"
MovementAnims(0)="WalkF"
MovementAnims(1)="WalkF"

View File

@ -182,6 +182,18 @@ function TakeDamageClient(int Damage, Pawn InstigatedBy, Vector HitLocation, Vec
if (bDecapitated)
Died(InstigatedBy.Controller, damageType, HitLocation);
}
function TakeFireDamage(int Damage, Pawn Instigator)
{
Super.TakeFireDamage(Damage, Instigator);
// Adjust movement speed if not charging
if (!bChargingPlayer)
{
if (bBurnified)
GroundSpeed = GetOriginalGroundSpeed() * BurnGroundSpeedMul;
else
GroundSpeed = GetOriginalGroundSpeed();
}
}
function ClawDamageTarget()
{
local KFHumanPawn HumanTarget;
@ -299,16 +311,19 @@ Ignores StartCharging;
NetUpdateTime = Level.TimeSeconds - 1;
}
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
groundSpeed = groundSpeed + ((groundSpeed * 0.75 / maxRageCounter * (rageCounter + 1) * rageSpeedTween));
}
function EndState()
{
bChargingPlayer = false;
NiceZombieBruteController(Controller).RageFrustrationTimer = 0;
if (Health > 0)
{
GroundSpeed = GetOriginalGroundSpeed();
if (bBurnified)
GroundSpeed *= BurnGroundSpeedMul;
}
if( Level.NetMode!=NM_DedicatedServer )
ClientChargingAnims();
@ -316,8 +331,12 @@ Ignores StartCharging;
}
function Tick(float Delta)
{
if (!bShotAnim) {
if (!bShotAnim)
{
RageSpeedTween = FClamp(RageSpeedTween + (Delta * 0.75), 0, 1.0);
GroundSpeed = OriginalGroundSpeed + ((OriginalGroundSpeed * 0.75 / MaxRageCounter * (RageCounter + 1) * RageSpeedTween));
if (bBurnified)
GroundSpeed *= BurnGroundSpeedMul;
}
Global.Tick(Delta);

View File

@ -33,6 +33,7 @@ var bool bServerBlock;
var bool bClientBlock;
var float BlockDmgMul; // Multiplier for damage taken from blocked shots
var float BlockFireDmgMul;
var float BurnGroundSpeedMul; // Multiplier for ground speed when burning
replication
{
reliable if(Role == ROLE_Authority)
@ -60,6 +61,7 @@ defaultproperties
BlockAddScale=2.500000
BlockDmgMul=0.100000
BlockFireDmgMul=1.000000
BurnGroundSpeedMul=0.700000
StunThreshold=4.000000
flameFuel=0.500000
clientHeadshotScale=1.300000
@ -108,7 +110,6 @@ defaultproperties
Health=1000
HeadHeight=2.500000
HeadScale=1.300000
minStoppingThreshold=0.1
MenuName="Brute"
MovementAnims(0)="BruteWalkC"
MovementAnims(1)="BruteWalkC"
@ -122,7 +123,7 @@ defaultproperties
AmbientSound=SoundGroup'ScrnZedPack_S.Brute.BruteIdle1Shot'
Mesh=SkeletalMesh'ScrnZedPack_A.BruteMesh'
PrePivot=(Z=0.000000)
Skins(0)=Texture'NicePackT.MonsterBrute.WPCBruteT'
Skins(0)=Combiner'ScrnZedPack_T.Brute.Brute_Final'
Mass=600.000000
RotationRate=(Yaw=45000,Roll=0)
}

View File

@ -5,8 +5,6 @@ class NiceZombieClot extends NiceZombieClotBase;
#exec OBJ LOAD FILE=KF_Specimens_Trip_T.utx
#exec OBJ LOAD FILE=MeanZedSkins.utx
var float sirenBoostTimeout;
function ClawDamageTarget()
{
local vector PushDir;
@ -111,33 +109,9 @@ simulated function int DoAnimAction( name AnimName )
}
return super.DoAnimAction( AnimName );
}
function DealDecapDamage( int damage,
Pawn instigatedBy,
Vector hitLocation,
Vector momentum,
class<NiceWeaponDamageType> damageType,
float headshotLevel,
KFPlayerReplicationInfo KFPRI,
optional float lockonTime) {
if (sirenBoostTimeout > 0) {
RemoveHead();
} else {
super.DealDecapDamage(damage, instigatedBy, hitLocation, momentum,
damageType, headshotLevel, KFPRI, lockonTime);
}
}
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
if (sirenBoostTimeout > 0) {
groundSpeed *= 1.5;
}
}
simulated function Tick(float DeltaTime)
{
super.Tick(DeltaTime);
if (sirenBoostTimeout >= 0) {
sirenBoostTimeout -= deltaTime;
}
if( bShotAnim && Role == ROLE_Authority )
{
if( LookTarget!=none )

View File

@ -34,13 +34,10 @@ event Landed(vector HitNormal)
}
event Bump(actor Other)
{
local int actualDamage;
// TODO: is there a better way
if(bPouncing && KFHumanPawn(Other)!=none )
{
actualDamage = MeleeDamage;
ModDamageFromZed(actualDamage, class'NiceZedMeleeDamageType');
KFHumanPawn(Other).TakeDamage(((actualDamage * 0.95) + (actualDamage * (FRand() * 0.1))), self ,self.Location,self.velocity, class'NiceZedMeleeDamageType');
KFHumanPawn(Other).TakeDamage(((MeleeDamage - (MeleeDamage * 0.05)) + (MeleeDamage * (FRand() * 0.1))), self ,self.Location,self.velocity, class'NiceZedMeleeDamageType');
if (KFHumanPawn(Other).Health <=0)
{
//TODO - move this to humanpawn.takedamage? Also see KFMonster.MeleeDamageTarget

View File

@ -49,6 +49,7 @@ function SetMindControlled(bool bNewMindControlled)
if( bNewMindControlled != bZedUnderControl )
{
SetGroundSpeed(OriginalGroundSpeed * 1.25);
Health *= 1.25;
HealthMax *= 1.25;
}
@ -251,21 +252,21 @@ Ignores StartChargingFP;
if(fpController == none)
fpController.RageFrustrationTimer = 0;
if( Health>0 && !bZapped )
{
SetGroundSpeed(GetOriginalGroundSpeed());
}
if( Level.NetMode!=NM_DedicatedServer )
ClientChargingAnims();
NetUpdateTime = Level.TimeSeconds - 1;
}
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
if (!bShotAnim) {
groundSpeed *= 2.3;
}
}
function Tick( float Delta )
{
if( !bShotAnim )
{
SetGroundSpeed(OriginalGroundSpeed * 2.3);//2.0;
if( !bFrustrated && !bZedUnderControl && Level.TimeSeconds>RageEndTime )
{
GoToState('');
@ -329,16 +330,11 @@ Ignores StartChargingFP;
state ChargeToMarker extends RageCharging
{
Ignores StartChargingFP;
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
if (!bShotAnim) {
groundSpeed *= 2.3;
}
}
function Tick( float Delta )
{
if( !bShotAnim )
{
SetGroundSpeed(OriginalGroundSpeed * 2.3);
if( !bFrustrated && !bZedUnderControl && Level.TimeSeconds>RageEndTime )
{
GoToState('');
@ -441,7 +437,7 @@ function SpinDamage(actor Target)
local vector HitLocation;
local Name TearBone;
local Float dummy;
local int damageAmount;
local float DamageAmount;
local vector PushDir;
local KFHumanPawn HumanTarget;
if(target==none)
@ -456,7 +452,6 @@ function SpinDamage(actor Target)
}
if (Target !=none && Target.IsA('KFDoorMover'))
{
ModDamageFromZed(DamageAmount, class'NiceZedMeleeDamageType');
Target.TakeDamage(DamageAmount , self ,HitLocation,pushdir, class'NiceZedMeleeDamageType');
PlaySound(MeleeAttackHitSound, SLOT_Interact, 1.25);
}
@ -466,7 +461,6 @@ function SpinDamage(actor Target)
if (HumanTarget.Controller != none)
HumanTarget.Controller.ShakeView(RotMag, RotRate, RotTime, OffsetMag, OffsetRate, OffsetTime);
ModDamageFromZed(DamageAmount, class'NiceZedMeleeDamageType');
//TODO - line below was KFPawn. Does this whole block need to be KFPawn, or is it OK as KFHumanPawn?
KFHumanPawn(Target).TakeDamage(DamageAmount, self ,HitLocation,pushdir, class'NiceZedMeleeDamageType');

View File

@ -80,8 +80,6 @@ defaultproperties
Health=1650
HeadHeight=2.500000
HeadScale=1.300000
maxStoppingEffect=0.05
minStoppingThreshold=0.68
MenuName="Nice Flesh Pound"
MovementAnims(0)="PoundWalk"
MovementAnims(1)="WalkB"

View File

@ -45,6 +45,7 @@ function SetMindControlled(bool bNewMindControlled)
if( bNewMindControlled != bZedUnderControl )
{
SetGroundSpeed(OriginalGroundSpeed * 1.25);
Health *= 1.25;
HealthMax *= 1.25;
}
@ -72,6 +73,13 @@ function RangedAttack(Actor A){
if(!bShotAnim && !bDecapitated && VSize(A.Location - Location) <= 700)
GoToState('RunningState');
}
simulated function Tick(float DeltaTime){
super.Tick(DeltaTime);
if(IsInState('RunningState'))
SetGroundSpeed(GetOriginalGroundSpeed() * 1.875);
else
SetGroundSpeed(GetOriginalGroundSpeed());
}
state RunningState{
// Set the zed to the zapped behavior
simulated function SetZappedBehavior(){
@ -86,6 +94,7 @@ state RunningState{
if(bZapped)
GoToState('');
else{
SetGroundSpeed(OriginalGroundSpeed * 1.875);
bRunning = true;
if(Level.NetMode != NM_DedicatedServer)
PostNetReceive();
@ -94,6 +103,7 @@ state RunningState{
}
}
function EndState(){
SetGroundSpeed(GetOriginalGroundSpeed());
bRunning = false;
if(Level.NetMode != NM_DedicatedServer)
PostNetReceive();
@ -102,10 +112,6 @@ state RunningState{
NetUpdateTime = Level.TimeSeconds - 1;
}
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
groundSpeed *= 1.875;
}
function RemoveHead(){
GoToState('');
Global.RemoveHead();

View File

@ -60,7 +60,6 @@ defaultproperties
HeadHeight=1.000000
HeadScale=1.350000
AmbientSoundScaling=8.000000
stoppingRecoveryRate=0.05
MenuName="Nice Husk"
MovementAnims(0)="WalkF"
MovementAnims(1)="WalkB"

View File

@ -105,11 +105,15 @@ State SawingLoop
else GoToState('');
}
}
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
if (bWasRaged || bCharging) {
groundSpeed *= 3.5;
}
simulated function float GetOriginalGroundSpeed()
{
local float result;
result = OriginalGroundSpeed;
if ( bWasRaged || bCharging )
result *= 3.5;
else if( bZedUnderControl )
result *= 1.25;
return result;
}
state RunningState
{
@ -120,6 +124,7 @@ state RunningState
GoToState('');
else {
bCharging = true;
SetGroundSpeed(GetOriginalGroundSpeed());
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
NetUpdateTime = Level.TimeSeconds - 1;
@ -128,6 +133,8 @@ state RunningState
function EndState()
{
bCharging = False;
if( !bZapped )
SetGroundSpeed(GetOriginalGroundSpeed());
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
}
@ -156,8 +163,6 @@ defaultproperties
ChallengeSound(2)=None
ChallengeSound(3)=None
ScoringValue=300
maxStoppingEffect=0.25
minStoppingThreshold=0.25
MenuName="Jason"
AmbientSound=Sound'ScrnZedPack_S.Jason.Jason_Sound'
Mesh=SkeletalMesh'ScrnZedPack_A.JasonMesh'

View File

@ -83,6 +83,7 @@ function SetMindControlled(bool bNewMindControlled)
if( bNewMindControlled != bZedUnderControl )
{
SetGroundSpeed(OriginalGroundSpeed * 1.25);
Health *= 1.25;
HealthMax *= 1.25;
}
@ -184,9 +185,8 @@ state RunningState
{
return false;
}
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
groundSpeed *= 3.5;
simulated function float GetOriginalGroundSpeed() {
return 3.5 * OriginalGroundSpeed;
}
function BeginState(){
local NiceHumanPawn rageTarget, rageCause;
@ -214,6 +214,7 @@ state RunningState
if(bZapped)
GoToState('');
else{
SetGroundSpeed(OriginalGroundSpeed * 3.5);
bCharging = true;
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
@ -223,6 +224,10 @@ state RunningState
}
function EndState()
{
if( !bZapped )
{
SetGroundSpeed(GetOriginalGroundSpeed());
}
bCharging = False;
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
@ -260,9 +265,8 @@ State SawingLoop
{
return false;
}
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
groundSpeed *= attackChargeRate;
simulated function float GetOriginalGroundSpeed() {
return OriginalGroundSpeed * AttackChargeRate;
}
function bool CanGetOutOfWay()
{
@ -275,6 +279,7 @@ State SawingLoop
// Randomly have the scrake charge during an attack so it will be less predictable
if(Health/HealthMax < 0.5 || FRand() <= 0.95)
{
SetGroundSpeed(OriginalGroundSpeed * AttackChargeRate);
bCharging = true;
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
@ -322,6 +327,8 @@ State SawingLoop
{
AmbientSound=default.AmbientSound;
MeleeDamage = Max( DifficultyDamageModifer() * default.MeleeDamage, 1 );
SetGroundSpeed(GetOriginalGroundSpeed());
bCharging = False;
if(Level.NetMode != NM_DedicatedServer)
PostNetReceive();

View File

@ -63,8 +63,6 @@ defaultproperties
HealthMax=1000.000000
Health=1000
HeadHeight=2.200000
maxStoppingEffect=0.15
minStoppingThreshold=0.15
MenuName="Nice Scrake"
MovementAnims(0)="SawZombieWalk"
MovementAnims(1)="SawZombieWalk"

View File

@ -3,7 +3,6 @@ class NiceZombieShiver extends NiceZombieShiverBase;
var float TeleportBlockTime;
var float HeadOffsetY;
var transient bool bRunning, bClientRunning;
var float teleportAttackCooldownEndTime;
replication
{
reliable if ( Role == ROLE_Authority)
@ -39,39 +38,6 @@ simulated function PostBeginPlay()
}
}
}
function bool CanAttack(Actor target) {
if (level.timeSeconds < teleportAttackCooldownEndTime)
return false;
return super.CanAttack(target);
}
simulated event SetAnimAction(name NewAction) {
local int meleeAnimIndex;
if (bFrozenZed) return;
if (newAction == '') return;
if (newAction == 'Claw') {
meleeAnimIndex = Rand(2); // Shivers only have two animations now
newAction = meleeAnims[meleeAnimIndex];
currentDamtype = zombieDamType[meleeAnimIndex];
} else if(newAction == 'DoorBash') {
currentDamtype = zombieDamType[Rand(3)];
}
expectingChannel = DoAnimAction(NewAction);
if (AnimNeedsWait(newAction)) {
bWaitForAnim = true;
} else {
bWaitForAnim = false;
}
if (level.netMode != NM_Client) {
animAction = newAction;
bResetAnimAct = True;
resetAnimActTime = level.timeSeconds + 0.3;
}
}
simulated function Destroyed()
{
if (Level.NetMode != NM_DedicatedServer && MatAlphaSkin != none)
@ -213,6 +179,7 @@ state Running
Global.Tick(Delta);
if (RunUntilTime < Level.TimeSeconds)
GotoState('');
GroundSpeed = GetOriginalGroundSpeed();
}
function BeginState()
{
@ -223,12 +190,13 @@ state Running
function EndState()
{
bRunning = false;
GroundSpeed = global.GetOriginalGroundSpeed();
RunCooldownEnd = Level.TimeSeconds + PeriodRunCoolBase + FRand() * PeriodRunCoolRan;
MovementAnims[0] = WalkAnim;
}
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
groundSpeed *= 2.5;
function float GetOriginalGroundSpeed()
{
return global.GetOriginalGroundSpeed() * 2.5;
}
function bool CanSpeedAdjust()
{
@ -251,6 +219,14 @@ simulated function bool AnimNeedsWait(name TestAnim)
}
return ExpectingChannel == 0;
}
simulated function float GetOriginalGroundSpeed()
{
local float result;
result = OriginalGroundSpeed;
if( bZedUnderControl )
result *= 1.25;
return result;
}
simulated function HandleAnimation(float Delta)
{
// hehehe
@ -315,7 +291,7 @@ simulated function Tick(float Delta)
{
SetCollision(true, true);
FlashTeleport();
SetCollision(true, false);
SetCollision(false, false);
FadeStage = 2;
}
}
@ -356,7 +332,7 @@ function StartTeleport()
{
FadeStage = 1;
AlphaFader = 255;
SetCollision(true, false);
SetCollision(false, false);
bFlashTeleporting = true;
}
function FlashTeleport()
@ -414,7 +390,6 @@ function FlashTeleport()
Teleported:
bFlashTeleporting = false;
LastFlashTime = Level.TimeSeconds;
teleportAttackCooldownEndTime = level.timeSeconds + 0.5;
}
function Died(Controller Killer, class<DamageType> damageType, vector HitLocation)
{
@ -464,16 +439,10 @@ simulated function int DoAnimAction( name AnimName )
}
defaultproperties
{
headOffsetY=-3.000000
HeadOffsetY=-3.000000
idleInsertFrame=0.468000
onlineHeadshotOffset=(X=19.000000,Z=39.000000)
scoringValue=15
headRadius=8.000000
headHeight=3.000000
// Override third animation just in case.
// However it shouldn't be required since we've already changed
// `SetAnimAction` function to only use first two animations
meleeAnims(0)="Claw"
meleeAnims(1)="Claw2"
meleeAnims(2)="Claw"
OnlineHeadshotOffset=(X=19.000000,Z=39.000000)
ScoringValue=15
HeadRadius=8.000000
HeadHeight=3.000000
}

View File

@ -223,10 +223,9 @@ simulated function HurtRadius(float DamageAmount, float DamageRadius, class<Dama
local float InitMomentum;
local float damageScale, dist;
local vector dir;
local int UsedDamageAmount;
local float UsedDamageAmount;
local KFHumanPawn humanPawn;
local class<NiceVeterancyTypes> niceVet;
local NiceZombieClot niceClot;
if (bHurtEntry || Health <= 0 || HeadHealth <= 0 || bIsStunned)
return;
@ -244,10 +243,6 @@ simulated function HurtRadius(float DamageAmount, float DamageRadius, class<Dama
if (Victims.bStatic || Victims.Physics == PHYS_None || !FastTrace(Victims.Location, Location) )
continue; // skip this actor
niceClot = NiceZombieClot(victims);
if (niceClot != none) {
niceClot.sirenBoostTimeout = 10.0;
}
Momentum = InitMomentum;
// don't let blast damage affect fluid - VisibleCollisingActors doesn't really work for them - jag
// Or Karma actors in this case. Self inflicted Death due to flying chairs is uncool for a zombie of your stature.
@ -271,7 +266,7 @@ simulated function HurtRadius(float DamageAmount, float DamageRadius, class<Dama
UsedDamageAmount = 100000; // Siren always shatters glass
else
UsedDamageAmount = DamageAmount;
ModDamageFromZed(UsedDamageAmount, DamageType);
Victims.TakeDamage(damageScale * UsedDamageAmount,Instigator, Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir, (damageScale * Momentum * dir), DamageType);
if (Instigator != none && Vehicle(Victims) != none && Vehicle(Victims).Health > 0)
@ -286,12 +281,6 @@ simulated function HurtRadius(float DamageAmount, float DamageRadius, class<Dama
function RemoveHead(){
Super.RemoveHead();
}
simulated function UpdateGroundSpeed() {
super.UpdateGroundSpeed();
if (bShotAnim) {
groundSpeed *= 0.65;
}
}
simulated function Tick( float Delta )
{
local float currScreamTime;
@ -306,11 +295,17 @@ simulated function Tick( float Delta )
{
if( bShotAnim )
{
SetGroundSpeed(GetOriginalGroundSpeed() * 0.65);
if( LookTarget!=none )
{
Acceleration = AccelRate * Normal(LookTarget.Location - Location);
}
}
else
{
SetGroundSpeed(GetOriginalGroundSpeed());
}
}
if(Role == ROLE_Authority && screamStartTime > 0){
currScreamTime = Level.TimeSeconds - screamStartTime;

View File

@ -709,6 +709,7 @@ defaultproperties
HealEnergyDrain=0.200000
ProjectileFireInterval=5.000000
BurnDamageScale=1.000000
mind=0.000000
bFireImmune=False
MoanVoice=SoundGroup'KF_EnemiesFinalSnd_CIRCUS.Husk.Husk_Talk'
BleedOutDuration=5.000000

View File

@ -24,7 +24,6 @@ class NiceMonster extends KFMonster
#exec OBJ LOAD FILE=KF_EnemyGlobalSndTwo.uax
#exec OBJ LOAD FILE=KFZED_FX_T.utx
var bool initializationComplete;
//==============================================================================
//==============================================================================
// > Affliction system
@ -76,15 +75,13 @@ var float stunLoopStart, stunLoopEnd, idleInsertFrame;
var bool bWasIdleStun; // Were we using idleanimation for stun?
var float prevStunAnimFrame; // At which tick we were?
//==============================================================================
// >> Another default stun system allows to stun zeds by repeatedly dealing
// >> Another default stun system allows tostuns zeds by repeatedly dealing
// head damage to them fast enough:
// 1. Dealing head damage increases accumulated damage
// 2. If head damage was received for a certain time period, -
// accumulated damage starts to decrease
// 3. If accumulated damage is high enough, passes 'IsStunPossible' check
// - normal duration stun activates
// How much more time will this zed spend concussed?
var float concussionCountdown;
// and has low enough mind level - normal duration stun activates
// Accumulated head damage
var float accHeadDamage;
// Rate (per second) at which accumulated head damage diminishes
@ -94,6 +91,16 @@ var float headRecoveryTime;
// Count down variable for above mentioned time
var float headRecoveryCountDown;
//==============================================================================
//==============================================================================
// > Mind system
// Largly underdeveloped and currently only exists to decide whether or not
// zed can be stunned by accumulating head damage
// Current mind level (1.0 - default and maximum value)
var float mind;
// Treshold, required for stun by accumulated head damage
var float accStunMindLvl;
//==============================================================================
//==============================================================================
// > Temperature system
@ -127,25 +134,10 @@ var float heatDissipationRate;
var float heatTicksPerSecond;
// Tracks last time heat tick occured
var float lastHeatTick;
var float scorchmarkDamage;
var float MIN_HEAT, MAX_HEAT;
//==============================================================================
//==============================================================================
// > Speed system
// Manages speed modifications from weapon attacks and other effects.
//
// This variable stores with how much stopping power zed was affected.
// Is a value from 0.0 to 1.0 and `1 - stoppingEffect` acts as speed multiplier
// for the zed
var float stoppingEffect;
// How much stopping effect would be recovred in a second
var float stoppingRecoveryRate;
// Maximum `stoppingEffect` value zed can accumulate
var float maxStoppingEffect;
// Minimal stopping threshold for the zed (supposed to be subtracted from
// incoming effects' strenght).
var float minStoppingThreshold;
// If set to 'true' - low-value ticks of fire DoT will waste accordingly small
// amount of fuel, otherwise they will always waste some minimal amount,
// resulting in a loss of potential damage
var bool bFrugalFuelUsage;
//==============================================================================
//==============================================================================
@ -230,7 +222,6 @@ simulated function PostBeginPlay(){
SavedExtCollision = MyExtCollision.bCollideActors;
}
}
initializationComplete = true;
}
//==============================================================================
@ -371,15 +362,6 @@ simulated function FearTick(float deltaTime){
+ 0.75 * accelRate * Normal(Location - fearCenter);
}
//==============================================================================
// >> Decrease active stopping power on the zed as the time goes by
simulated function StoppingPowerTick(float deltaTime) {
if (stoppingEffect <= 0.0 || concussionCountdown > 0.0) {
return;
}
stoppingEffect -= deltaTime * stoppingRecoveryRate;
stoppingEffect = FMax(0, stoppingEffect);
}
//==============================================================================
// >> Set of functions to handle animation changes during stun
simulated function CalcRemainigStunStructure( name seqName,
float oFrame,
@ -473,10 +455,10 @@ function AccumulateHeadDamage( float addDamage,
bool bIsHeadshot,
NicePlayerController nicePlayer){
if(bIsHeadshot){
AccHeadDamage += addDamage * 0.5;
AccHeadDamage += addDamage;
HeadRecoveryCountDown = HeadRecoveryTime;
if(AccHeadDamage > (default.HeadHealth / 1.5)
&& (concussionCountdown > 0.0 && IsStunPossible()))
&& (Mind <= AccStunMindLvl && IsStunPossible()))
DoStun(nicePlayer.pawn,,,, 1.0);
}
else if(HeadRecoveryCountDown > 0.0)
@ -484,13 +466,11 @@ function AccumulateHeadDamage( float addDamage,
HeadRecoveryTime / 2);
}
function HeadDamageRecoveryTick(float delta){
concussionCountdown -= delta;
concussionCountdown = FMax(0.0, concussionCountdown);
headRecoveryCountDown -= delta;
headRecoveryCountDown = FMax(0.0, headRecoveryCountDown);
if(headRecoveryCountDown <= 0.0)
accHeadDamage -= delta * HeadDamageRecoveryRate;
accHeadDamage = FMax(accHeadDamage, 0.0);
HeadRecoveryCountDown -= delta;
HeadRecoveryCountDown = FMax(0.0, HeadRecoveryCountDown);
if(HeadRecoveryCountDown <= 0.0)
AccHeadDamage -= delta * HeadDamageRecoveryRate;
AccHeadDamage = FMax(AccHeadDamage, 0.0);
}
//==============================================================================
// >> Function that calls actual 'HeatTick' when needed
@ -500,11 +480,6 @@ simulated function FakeHeatTick(float deltaTime){
local float oFrame;
local float oRate;
local NiceMonsterController niceZedController;
if (bOnFire) {
// 100 of the scorchmark damage should restore every 1/10 of a second
scorchmarkDamage += deltaTime * 10 * 100;
scorchmarkDamage = FMin(scorchmarkDamage, 100);
}
if(lastHeatTick + (1 / HeatTicksPerSecond) < Level.TimeSeconds){
if(bOnFire && !bBurningBehavior)
SetBurningBehavior();
@ -552,6 +527,15 @@ simulated function FakeHeatTick(float deltaTime){
// >> Ticks from TWI's code
// Updates zed's speed if it's not relevant;
// code, specific to standalone game and listen servers was cut out
simulated function NonRelevantSpeedupTick(float deltaTime){
if(Level.netMode == NM_Client || !CanSpeedAdjust()) return;
if(Level.TimeSeconds - LastReplicateTime > 0.5)
SetGroundSpeed(default.GroundSpeed * (300.0 / default.GroundSpeed));
else{
LastSeenOrRelevantTime = Level.TimeSeconds;
SetGroundSpeed(GetOriginalGroundSpeed());
}
}
// Kill zed if it has been bleeding long enough
simulated function BleedOutTick(float deltaTick)
@ -602,6 +586,7 @@ simulated function TWITick(float deltaTime){
// If we've flagged this character to be destroyed next tick, handle that
if(bDestroyNextTick && TimeSetDestroyNextTickTime < Level.TimeSeconds)
Destroy();
NonRelevantSpeedupTick(deltaTime);
// Reset AnimAction
if(bResetAnimAct && ResetAnimActTime < Level.TimeSeconds){
AnimAction = '';
@ -624,10 +609,8 @@ simulated function Tick(float deltaTime){
DecapTick(deltaTime);
FearTick(deltaTime);
StunTick(deltaTime);
StoppingPowerTick(deltaTime);
HeadDamageRecoveryTick(deltaTime);
FakeHeatTick(deltaTime);
UpdateGroundSpeed();
// TWI's tick
TWITick(deltaTime);
}
@ -684,19 +667,6 @@ simulated function float IsHeadshotClient( Vector Loc,
return 1.0 - (distance / (headRadius * headScale * additionalScale));
return 0.0;
}
// Calculates distance from `location` to this zed's head.
simulated function float GetDistanceToHead(Vector location) {
local Coords headBoneCoords;
local Vector headLocation;
if(headBone == '') {
return 0.0;
}
headBoneCoords = GetBoneCoords(headBone);
headLocation =
headBoneCoords.Origin + headHeight * headScale * headBoneCoords.XAxis;
return VSize(location - headLocation);
}
// In case of a future modifications:
// check if it's a player doing damage before relying on it
function ModDamage( out int damage,
@ -750,6 +720,9 @@ function ModRegularDamage( out int damage,
damage = niceVet.static.AddRegDamage( KFPRI, self,
KFPawn(instigatedBy), damage,
damageType);
// Add some damage against crispy zeds
if(bCrispified)
damage += (Max(1200 - default.Health, 0) * damage) / 1200;
// Skills bonuses
if(nicePlayer == none) return;
hasOverkillSkill = class'NiceVeterancyTypes'.static.
@ -827,9 +800,6 @@ function int ModBodyDamage( out int damage,
bIsHeadShot = (headshotLevel > 0.0);
if(instigatedBy != none)
nicePlayer = NicePlayerController(instigatedBy.Controller);
if (bFrozenZed && damageType != none && damageType.default.bIsExplosive) {
damage *= 1.5;
}
// On damaging critical spot (so far only head) - do body destruction
if(bIsHeadShot && damageType != none)
damage *= damageType.default.bodyDestructionMult;
@ -841,14 +811,13 @@ function int ModBodyDamage( out int damage,
return painDamage;
}
// Do effects, based on fire damage dealt to monster
function FireDamageEffects(out int damage,
function FireDamageEffects( int damage,
Pawn instigatedBy,
Vector hitLocation,
Vector momentum,
class<NiceWeaponDamageType> damageType,
float headshotLevel,
KFPlayerReplicationInfo KFPRI){
local float heatDelta, bonusFireDamage;
damage = FMax(0.0, damage);
iceCrustStrenght = FMax(0.0, iceCrustStrenght);
if(bFrozenZed){
@ -866,31 +835,18 @@ function FireDamageEffects(out int damage,
}
damage /= 10;
}
if(damage <= 0) {
return;
}
if(damage <= 0) return;
// Turn up the heat!
// (we can only make it twice as hot with that damage,
// but set limit at least at 50, as if we've dealt at least 25 heat damage)
heatDelta = (damage * HeatIncScale())
heat += (damage * HeatIncScale())
* FMin(1.0, FMax(0.0, (2 - Abs(heat) / FMax(25, Abs(damage) ))));
if (concussionCountdown > 0) {
heat += heatDelta * 2;
} else {
heat += heatDelta;
}
CapHeat();
// Change damage type if new one was stronger
if(!bOnFire || damage * HeatIncScale() > lastBurnDamage){
fireDamageClass = damageType;
burnInstigator = instigatedBy;
}
// Double heat damage at the cost of the fuel, if zed is already on fire
if (bOnFire) {
bonusFireDamage = FMax(FMin(damage, flameFuel) * 0.25, 0);
flameFuel -= bonusFireDamage;
damage += bonusFireDamage;
}
// Set on fire, if necessary
if(heat > GetIgnitionPoint() && !bOnFire && bCanBurn){
bBurnified = true;
@ -1031,11 +987,6 @@ function DealHeadDamage( int damage,
// Actual damage effects
// Skull injury killed a zed
if(HeadHealth <= 0) return;
// Additional weakpoint damage to burning zeds from non-flame weapons
if (bOnFire) {
damage += scorchmarkDamage * (1 - damageType.default.heatPart);
scorchmarkDamage *= damageType.default.heatPart;
}
HeadHealth -= damage;
if(nicePlayer != none && IsFinisher(damage, damageType, nicePlayer, true))
HeadHealth -= damage;
@ -1218,9 +1169,6 @@ function EPainReaction GetRightPainReaction(int painDamage,
local int stunScore, flinchScore;
local bool bStunPass, bFlinchPass, bMiniFlinshPass;
local class<NiceVeterancyTypes> niceVet;
if (bOnFire) {
return PREACTION_NONE;
}
if(KFPRI != none)
niceVet = class<NiceVeterancyTypes>(KFPRI.ClientVeteranSkill);
stunScore = painDamage;
@ -1289,9 +1237,8 @@ function float GetstunDurationMult( Pawn instigatedBy,
if(KFPRI == none) return stunDurationMultiplier;
niceVet = class<NiceVeterancyTypes>(KFPRI.ClientVeteranSkill);
if(niceVet == none) return stunDurationMultiplier;
if(damageType == none) return stunDurationMultiplier;
// Perk's bonuses out
return stunDurationMultiplier * damageType.default.stunLengthMultiplier *
return stunDurationMultiplier *
niceVet.static.stunDurationMult( KFPRI, self, KFPawn(instigatedBy),
damageType);
}
@ -1666,14 +1613,12 @@ function TakeDamageClient( int damage,
KFPRI = KFPlayerReplicationInfo(instigatedBy.PlayerReplicationInfo);
if(headHealth <= 0)
headshotLevel = 0.0;
// Handle special weapon effects
HandleStoppingPower(damageType, headshotLevel);
// Handle elemental damage components
ExtractElementalDamage( regDamage, heatDamage, damage,
instigatedBy, hitLocation, momentum,
damageType, KFPRI, headshotLevel, lockonTime);
FireDamageEffects(HeatDamage, instigatedBy, hitLocation,
momentum, damageType, headshotLevel, KFPRI);
FireDamageEffects( HeatDamage, instigatedBy, hitLocation, momentum,
damageType, headshotLevel, KFPRI);
FrostEffects( instigatedBy, hitLocation, momentum,
damageType, headshotLevel, KFPRI);
// Handle body parts damage components
@ -1683,9 +1628,9 @@ function TakeDamageClient( int damage,
headshotLevel, lockonTime);
DoRightPainReaction( painDamage, instigatedBy, hitLocation, momentum,
damageType, headshotLevel, KFPRI);
DealPartsDamage( bodyDamage, headDamage,
instigatedBy, hitLocation, momentum, damageType,
KFPRI, headshotLevel, lockonTime);
DealPartsDamage( bodyDamage, headDamage, instigatedBy,
hitLocation, momentum, damageType, KFPRI,
headshotLevel, lockonTime);
AddKillAssistant(instigatedBy, bodyDamage);
// Rewrite values of last deal damage, instigator, etc.
UpdateLastDamageVars( instigatedBy, bodyDamage, damageType,
@ -1694,28 +1639,6 @@ function TakeDamageClient( int damage,
// like why the fuck is it being done HERE? Makes no fucking sense
bBackstabbed = false;
}
function HandleStoppingPower(
class<NiceWeaponDamageType> damageType,
float headshotLevel
) {
local float strength;
local float actualMinStoppingThreshold, actualMaxStoppingEffect;
strength = damageType.default.stoppingPower;
if (headshotLevel > 0.0) {
strength *= 2;
}
if (concussionCountdown > 0) {
actualMinStoppingThreshold = FMax(0.0, minStoppingThreshold - 0.2);
actualMaxStoppingEffect = FMin(0.9, maxStoppingEffect + 0.2);
}
else {
actualMinStoppingThreshold = minStoppingThreshold;
actualMaxStoppingEffect = maxStoppingEffect;
}
strength = FMax(0, strength - actualMinStoppingThreshold);
stoppingEffect = FMin(actualMaxStoppingEffect, stoppingEffect + strength);
}
function TakeDamage(int damage,
Pawn instigatedBy,
Vector hitLocation,
@ -1761,12 +1684,15 @@ function TakeDamage(int damage,
}
}
function TakeFireDamage(int damage, Pawn instigator){
local bool bLowFuel, bHighHeat;
local Vector DummyHitLoc, DummyMomentum;
super(Skaarj).TakeDamage( damage, instigator, dummyHitLoc,
dummyMomentum, fireDamageClass);
lastBurnDamage = damage;
// Melt em' :)
if(FlameFuel <= 0)
bHighHeat = heat > default.health / 20;
bLowFuel = FlameFuel < 0.75 * InitFlameFuel;
if(FlameFuel <= 0 || bHighHeat && bLowFuel)
ZombieCrispUp();
}
function TakeFrostDamage(int damage, Pawn instigator){
@ -1790,33 +1716,26 @@ simulated function ZombieCrispUp(){
}
simulated function HeatTick(){
local float iceDamage;
local float heatRelativeLevel, heatMultiplier;
heatRelativeLevel = FMin(heat, flameFuel) / initFlameFuel;
if (heatRelativeLevel < 0.05) {
heatMultiplier = 1.5;
} else {
heatMultiplier = 1.1;
}
// Update heat value
if(!bOnFire || flameFuel <= 0)
heat *= heatDissipationRate;
else{
if(flameFuel < heat) {
heat = flameFuel * heatMultiplier + (heat - flameFuel) * heatDissipationRate;
} else {
heat = heat * heatMultiplier;
if(flameFuel < heat)
heat = flameFuel * 1.1 + (heat - flameFuel) * heatDissipationRate;
else
heat = heat * 1.1;
if(bFrugalFuelUsage)
flameFuel -= heat;
else
flameFuel -= FMax(heat, InitFlameFuel / 15);
}
}
flameFuel = FMax(0, flameFuel - heat);
CapHeat();
if(Abs(heat) < 1)
heat = 0.0;
// Update on-fire status
if(bOnFire){
if(heat > 0) {
TakeFireDamage(heat, burnInstigator);
}
if(heat > 0)
TakeFireDamage(heat + rand(5), burnInstigator);
else{
bBurnified = false;
UnSetBurningBehavior();
@ -1842,9 +1761,9 @@ simulated function HeatTick(){
}
simulated function SetBurningBehavior(){
bBurningBehavior = true;
if(default.Health >= 1000) {
return;
}
if(default.Health >= 1000) return;
if(Role == Role_Authority)
Intelligence = BRAINS_Retarded;
MovementAnims[0] = BurningWalkFAnims[Rand(3)];
WalkAnims[0] = BurningWalkFAnims[Rand(3)];
MovementAnims[1] = BurningWalkAnims[0];
@ -1860,6 +1779,7 @@ simulated function UnSetBurningBehavior(){
if(Role == Role_Authority){
Intelligence = default.Intelligence;
if(!bZapped){
SetGroundSpeed(GetOriginalGroundSpeed());
AirSpeed = default.AirSpeed;
WaterSpeed = default.WaterSpeed;
}
@ -1871,50 +1791,6 @@ simulated function UnSetBurningBehavior(){
WalkAnims[i] = default.WalkAnims[i];
}
}
simulated function SetGroundSpeed(float newGroundSpeed) {
if (initializationComplete) {
UpdateGroundSpeed();
} else {
// Let `KFMonster`'s code setup original speed for this zed.
// This is a hack to be removed later, when we'll be untangling
// initialization code
super.SetGroundSpeed(newGroundSpeed);
}
}
simulated function UpdateGroundSpeed() {
if (TryNonRelevantSpeedup()) {
return;
}
groundSpeed = GetOriginalGroundSpeed();
groundSpeed *= (1.0 - stoppingEffect);
if (bDecapitated) {
groundSpeed *= 0.8;
}
if (bCrispified) {
groundSpeed *= 1.25;
}
}
simulated function ModDamageFromZed(
out int damage,
class<DamageType> damageType
) {
if (bCrispified) {
damage *= 2;
}
}
// If this function returns `true`, then we shouldn't touch speed further,
// because a speed hack was used for the zed
simulated function bool TryNonRelevantSpeedup(){
if(level.netMode == NM_Client || !CanSpeedAdjust()) {
return false;
}
if(level.timeSeconds - lastReplicateTime > 0.5) {
groundSpeed = default.groundSpeed * (300.0 / default.groundSpeed);
return true;
}
lastSeenOrRelevantTime = level.timeSeconds;
return false;
}
simulated function ServerDropFaster(NiceHumanPawn nicePawn){
if(nicePawn == none) return;
if(Health > 0)
@ -1932,7 +1808,7 @@ simulated function RemoveHead(){
if(kfDmgType != none && kfDmgType.default.bIsMeleeDamage)
bMeleeDecapitated = true;
SetAnimAction('HitF');
UpdateGroundSpeed();
SetGroundSpeed(GroundSpeed *= 0.80);
// No more raspy breathin'...cuz he has no throat or mouth :S
AmbientSound = MiscSound;
if(Health > 0)
@ -2131,8 +2007,8 @@ function float HeatIncScale(){
return 100.0 / default.health;
}
function CapHeat(){
heat = FMin(heat, MAX_HEAT);
heat = FMax(heat, MIN_HEAT);
heat = FMin(heat, 135 + rand(10) - 5);
heat = FMax(heat, -150 + rand(10) - 5);
}
function bool TryMeleeReachTarget(out Vector hitLocation){
local Actor hitActor;
@ -2173,7 +2049,6 @@ function bool MeleeDamageTarget(int hitDamage, Vector pushDir){
local KFHumanPawn kfHumanPawn;
if(Level.netMode == NM_Client) return false;
if(controller == none || controller.target == none) return false;
ModDamageFromZed(hitDamage, niceZombieDamType);
// Melee for doors
kfHumanPawn = KFHumanPawn(controller.target);
bTargetIsDoor = controller.target.IsA('KFDoorMover');
@ -2326,10 +2201,13 @@ defaultproperties
lastStunTime=-1.000000
headDamageRecoveryRate=100.000000
headRecoveryTime=1.000000
mind=1.000000
accStunMindLvl=0.500000
bCanBurn=True
fuelRatio=0.750000
heatDissipationRate=0.666000
heatTicksPerSecond=3.000000
bFrugalFuelUsage=True
clientHeadshotScale=1.000000
FrozenMaterial=Texture'HTec_A.Overlay.IceOverlay'
ShatteredIce=class'NiceIceChunkEmitter'
@ -2338,12 +2216,7 @@ defaultproperties
DamageToMonsterScale=5.000000
RagdollLifeSpan=120.000000
ControllerClass=class'NiceMonsterController'
stoppingEffect=0.0
stoppingRecoveryRate=0.025
maxStoppingEffect=0.25
minStoppingThreshold=0.0
MIN_HEAT = -150.0
MAX_HEAT = 200.0
Begin Object Class=KarmaParamsSkel Name=KarmaParamsSkelN
KConvulseSpacing=(Max=2.200000)
KLinearDamping=0.150000

Some files were not shown because too many files have changed in this diff Show More