class a_MonsterOptimizer extends Actor config(HideMut); var PlayerController PC; var float NumSequences; var int NewTicks, CurrentZone; //for tick comparing var bool Opt_Launched, //optimizer started LowGore, //Client Low Gore == KillingFloor.ini, parameter UseLowGore Cooldown; //Flag for ZoneInfo zed search var int NumZeds, //Num spawned Zeds NumberOfZonesChecked; //Number of checked zones var array cachedZeds; //cache zeds for culling and other purposes var array deadZeds; //cache zeds for ragdoll management var array ZoneInfos; var ZoneInfo Zone; //=========================Configz var config array KFMonsterGibClassNames; //Gibs aka severed arms var config array KFMonsterGibletsClassNames; //giblets - small parts that spawn when arm, leg or etc. has been lost var config array KFMonsterGibEmitters; //5000 tons of bloods and particles... var config array KFMonsterClassNames_Standard, //Default monster classes KFMonsterClassNames_Circus, //Circus KFMonsterClassNames_Halloween, //Halloween KFMonsterClassNames_XMas; //Xmas var config array CustomZeds; //Scrn zeds var config array NiceZeds; //NiceZeds var config array LagEmitters; //Firebug shit var config array TWIGoreBackup, TWIGibEmitters; //================== //===============================Structures for optimizer paramas struct EmitLightControl { var bool UseFireTweaks; //Use or not fire tweaks var float LightRadius; //Light radius for fire emitters var ELightType LightType; //Light tyoe var byte LightBrightness; var byte LightHue; //Color var byte LightSaturation; var bool bDynamicLight; //Should be dynamic? var bool bSpecialLit; //Don't lit dynamic actors var bool UseAdditionalTweaks; //Use additional tweaks flashlight and etc. var bool FixDoshLighting; //Attempt to fix dosh mesh lighting }; struct OptParams //for ambient sounds { var string WholeMapSearchMethod; //Use zoneinfo.zoneactors search or use DynamicActors search var bool ConsNetSpeed; //Constant net speed var bool bMonsterSpotted; var float ZedCullDistance; //Cull distance for zeds var float Timer; var int Ticks; //every goddamn tick optimizer will detect decapped zeds var int nozed_NetSpeed; //NetSpeed without zeds var int new_NetSpeed; //NetSpeed with zeds var bool UseUnlit; //if unlit zed will appear in full brightness var byte AmbientGlow; //if unlit this will regulate zed's brightness var bool bSeasonedOff; //disable season zeds //replace seasoned(super laggy) zeds with default. Fuk u twi for 70 bones skeletons and MSM_Smooth_Only shit. //Read dat fucking manual first var bool bLagOff; var ESoundOcclusion SoundOcclusion; //Sound occlusion == what will block sounds(bsp, static meshes, none and etc) var float SoundRadius; //Ambient Sound radius //=====================Seasoned zeds shit var bool bStandard; var bool bCircus; var bool bHillBilly; var bool bXmas; //=====================Seasoned zeds shit //================================Gore related tweaks var string GoreLevel; //my gore level preset for twi classes //Gibs var bool bNoRagdolls; //Destroy Ragdolls them var float RagdollLifeSpan; var bool bAdvancedGibs; var bool bUnlitGibs; var bool bHideGibs; var float GibsLifespan; var bool GibUseDeferRendering; var int GibMaxLights; var bool GibUseCollisionStaticMesh; var bool GibAcceptProjectors; var bool GibStaticLighting; //Giblets var bool bAdvancedGiblets; var bool bUnlitGiblets; var bool bHideGiblets; var float GibletsLifespan; var bool GibletsUseDeferRendering; var int GibletsMaxLights; var bool GibletsUseCollisionStaticMesh; var bool GibletsAcceptProjectors; var bool GibletsStaticLighting; //===============================Gore related tweaks end var bool UserSettingsToEmitters; var int ZedSearchRadius; }; struct EMB //Emitter backups. /////////Stub//////Should rewrite dis { //contains variables from Particle emitter class. Used to backup and edit particle emitter classes var string ClassName; //Particle emitter name var bool bHidden; var bool bUnlit; var bool Disabled; //Disable Emitter var float InitialParticlesPerSecond; //plz make it 500000000000000000000 var bool UseCollision; //Use collision for emitter particles var bool AcceptsProjectors; //Accept projectors or don't var float LifeSpan; }; struct EMP_backups { var string ClassName; var bool bHidden; var bool bUnlit; var float LifeSpan; //lifespan applies to emitter class var array CEMP; //particle emitters array }; struct GorePresets //Gore presets for my emitters { var string PresetName; var string PresetDescription; var array EmittersToLoad; }; //===============================Structures for optimizer paramas var OptParams CurrentOptParams; //Current optimizer parameters var EmitLightControl LC; //Firebug and lighting shit also dosh meshlighting fix var EMP_backups EMP_backSingle; //for backuping emitters properties, single emitter var array EMP_back; //for backuping emitters properties, emitters array var EMB User_EMPS; //User settings for all emitters var array Gore_Presets; //Gore_Presets. mb should add custom? var GorePresets Gore_Preset; //Single Gore Preset for using in structure arrays var array > BackupGore, LowGoreE, OptGore, NoGore; function startOptimize() { local int i; PC = Level.GetLocalPlayerController(); if(CurrentOptParams.WholeMapSearchMethod ~= "ZoneActors") //Zone infos stuff only dependent to ZoneActors search method { CurrentZone = 0; ForEach AllActors(class'ZoneInfo', Zone) { //PC.ClientMessage(PC.GameReplicationInfo.PRIArray.length); ZoneInfos[i] = Zone; i++; } for(i=0;i 0 && CurrentOptParams.nozed_NetSpeed > 0) //Change my netspeed NetSpeedChanger(); if(cachedZeds.length > 0) //use cooling only if there are zeds and client "saw" them. { //Apply our shit CullZedsOnMap(); //for wave based maps use KFGameReplicationInfo(myKFPC.GameReplicationInfo).MaxMonsters } if(deadZeds.length > 0) { ControlRagdolls(); //for ragdoll controlling } } simulated function Tick(float Delta) { if(CurrentOptParams.Ticks == 0) return; NewTicks++; if (NewTicks == CurrentOptParams.Ticks) { DetectHeadless(); } } //Cache Spawned Zeds simulated function cacheZeds() { local KFMonster KFM; local int i; if (KFGameReplicationInfo(PC.GameReplicationInfo).TimeToNextWave > 0) //Don't work on trader time { cachedZeds.length = 0; //And destroy cached on previous wave zeds if they exist return; } if (PC.AcknowledgedPawn == none && CurrentOptParams.WholeMapSearchMethod != "ZoneActors") //Do not work if we dont have pawn however zoneinfo search will work return; //Incase of spectating with my stuff turned on switch (CurrentOptParams.WholeMapSearchMethod) { case "AllActors": ForEach PC.AcknowledgedPawn.AllActors(class'KFMonster', KFM) { if(KFM.Physics == PHYS_KarmaRagdoll) // cache this to dead zeds { deadZeds[deadZeds.length] = KFM; } else // cache this to alive zeds { if(KFM.CullDistance != CurrentOptParams.ZedCullDistance) //if we having culldistance property on a Monster => it is already been cached { cachedZeds[cachedZeds.length] = KFM; } } } break; case "ZoneActors": if(!CoolDown && PC.PlayerReplicationInfo.PlayerZone != none) //Wait for cooldown { for(i=0; i it is already been cached { cachedZeds[cachedZeds.length] = KFM; //PC.ClientMEssage("Was cached" @ CachedZeds.Length @ "zeds"); } } NumberOfZonesChecked++; } //PC.ClientMessage(cachedZeds.length @ deadZeds.length); CurrentZone++; if (NumberOfZonesChecked == ZoneInfos.length - 1) //back to checking player zone { Cooldown = false; NumberOfZonesChecked = 0; } if (CurrentZone >= ZoneInfos.length) CurrentZone = 0; break; case "DynamicActors": forEach PC.AcknowledgedPawn.DynamicActors (class'KFMonster', KFM) { if (KFM.Physics == PHYS_KarmaRagdoll) //cache this to dead zeds { deadZeds[deadZeds.length] = KFM; } else //cache this to alive zeds { if (KFM.CullDistance != CurrentOptParams.ZedCullDistance) //if we having culldistance set on a Monster => it is already been cached { cachedZeds[cachedZeds.length] = KFM; } } } break; case "RadiusActors": foreach PC.AcknowledgedPawn.CollidingActors(class'KFMonster', KFM, CurrentOptParams.ZedSearchRadius) { if (KFM.Physics == PHYS_KarmaRagdoll) //cache this to dead zeds { deadZeds[deadZeds.length] = KFM; } else //cache this to alive zeds { if (KFM.CullDistance != CurrentOptParams.ZedCullDistance) //if we having culldistance set on a Monster => it is already been cached { cachedZeds[cachedZeds.length] = KFM; } } } break; } } simulated function CullZedsOnMap() //Apply our tweaks to cached zeds { local int i; local KFMonster KFM; for(i = 0; i < cachedZeds.length; i++) { if(cachedZeds[i] == none || cachedZeds[i].Health <= 0) //Remove killed zeds { cachedZeds.Remove(i,1); continue; } KFM = cachedZeds[i]; if(KFM == none) //none check continue; if(CurrentOptParams.bMonsterSpotted) //&& int(NumSequences%2)>0) { MonsterSpotted(KFM); //REMOVE IT } if(KFM.cullDistance != CurrentOptParams.ZedCullDistance) { KFM.cullDistance = CurrentOptParams.ZedCullDistance; KFM.bUnlit = CurrentOptParams.UseUnlit; KFM.AmbientGlow = CurrentOptParams.AmbientGlow; KFM.SoundOcclusion = CurrentOptParams.SoundOcclusion; KFM.SoundRadius = CurrentOptParams.SoundRadius; } } } simulated function MonsterSpotted(KFMOnster KFMO) //Remove IT { local string KFMonsterST; if(KFMO == none) return; KFMonsterST = string(KFMO); if(Instr(caps(KFMonsterST), "STALKER") != -1 && !KFMO.bSpotted) { KFMO.Skins[0] = Finalblend'KFX.StalkerGlow'; KFMO.Skins[1] = Finalblend'KFX.StalkerGlow'; KFMO.bUnlit = true; } if(Instr(caps(KFMonsterST), "GHOST") != -1 && !KFMO.bSpotted) { KFMO.Skins[0] = Finalblend'KFX.StalkerGlow'; KFMO.Skins[1] = Finalblend'KFX.StalkerGlow'; KFMO.bUnlit = true; } if(Instr(caps(KFMonsterST), "BOSS") != -1 || Instr(caps(KFMonsterST), "PAT") != -1 || Instr(caps(KFMonsterST), "HARD") != -1) { if(KFMO.bCloaked == true ) { KFMO.Skins[0] = Finalblend'KFX.StalkerGlow'; KFMO.Skins[1] = Finalblend'KFX.StalkerGlow'; KFMO.bUnlit = true; } if(KFMO.bHidden == true) //Remove hard pat bullshit KFMO.bHidden = false; } } simulated function NetSpeedChanger() //Netspeed changer cuz lazy me { if (CurrentOptParams.ConsNetSpeed) //Change netspeed { PC.SetNetSpeed(CurrentOptParams.New_NetSpeed); //constant netspeed return; } if (KFGameReplicationInfo(PC.GameReplicationInfo).TimeToNextWave > 0 || !KFGameReplicationInfo(PC.GameReplicationInfo).bWaveInProgress) { PC.SetNetSpeed(CurrentOptParams.nozed_NetSpeed); // same as PC.ConsoleCommand("netspeed x"), but faster } else if (KFGameReplicationInfo(PC.GameReplicationInfo).bWaveInProgress || KFGameReplicationInfo(PC.GameReplicationInfo).MaxMonsters > 0) { PC.SetNetSpeed(CurrentOptParams.New_NetSpeed); // same as PC.ConsoleCommand("netspeed x"), but faster } } simulated function ControlRagdolls() { local int i; for (i=0; i < deadZeds.length; i++) { if (deadZeds[i]==none) //Avoid log-spam { deadZeds.Remove(i,1); continue; } //PC.ClientMessage(deadZeds[i].name @ deadZeds[i].lifespan @ deadZeds[i].bCollideWorld); if (CurrentOptParams.bNoRagdolls) //Destroy ragdolls { if (deadZeds[i].Destroy()) deadZeds.Remove(i,1); else { deadZeds[i].bDestroyNextTick = true; deadZeds.Remove(i,1); } } else if(!deadZeds[i].bCollideWorld) //set lifespan only once { //vanilla dead zeds don't have bCollideWorld deadZeds[i].Lifespan = CurrentOptParams.RagdollLifeSpan; deadZeds[i].bCollideWorld = true; //Bodies just fall through floor without that } } if (DeadZeds.length > Level.MaxRagdolls) //destroying our ragdolls with lifespan cuz sometimes engine ragdoll destroying bugging out { for (i=0; i < DeadZeds.length - Level.MaxRagdolls; i++) if (DeadZeds[DeadZeds.length-1].Destroy()) //Destroying last ragdolls in our array DeadZeds.Remove(DeadZeds.length-1,1); //Removing none references } } //================================Firebug shit simulated function FirebugDisabler() //Some tweaks to burn emitters { local class E; local int i; if (LowGore) { //Some tweaks to Alt burn emitter class'KFAltMonsterFlame'.default.Emitters[0] = class'HideMut.KFBurnEffect_FPS'.default.Emitters[0]; //light class'KFAltMonsterFlame'.default.LightRadius = LC.LightRadius; class'KFAltMonsterFlame'.default.LightType = LC.LightType; class'KFAltMonsterFlame'.default.LightBrightness = LC.LightBrightness; class'KFAltMonsterFlame'.default.LightHue = LC.LightHue; class'KFAltMonsterFlame'.default.LightSaturation = LC.LightSaturation; class'KFAltMonsterFlame'.default.bDynamicLight = LC.bDynamicLight; class'KFAltMonsterFlame'.default.bSpecialLit = LC.bSpecialLit; } if (LagEmitters.length == 0) return; //Lighting tweaks (from pulse to steady light cuz of fps drops when using multiple pulse lights) for (i=0;i= 0) E.default.LightRadius = LC.LightRadius; E.default.LightType = LC.LightType; if (LC.LightBrightness >= 0) E.default.LightBrightness = LC.LightBrightness; if (LC.LightHue >= 0) E.default.LightHue = LC.LightHue; if (LC.LightSaturation >= 0) E.default.LightSaturation = LC.LightSaturation; E.default.bDynamicLight = LC.bDynamicLight; E.default.bSpecialLit = LC.bSpecialLit; } //Some tweaks to Burn emitter class'KFMonsterFlame'.default.LightRadius = LC.LightRadius; class'KFMonsterFlame'.default.LightType = LC.LightType; class'KFMonsterFlame'.default.LightBrightness = LC.LightBrightness; class'KFMonsterFlame'.default.LightHue = LC.LightHue; class'KFMonsterFlame'.default.LightSaturation = LC.LightSaturation; class'KFMonsterFlame'.default.bDynamicLight = LC.bDynamicLight; class'KFMonsterFlame'.default.bSpecialLit = LC.bSpecialLit; } //=======================================================for preloading assets hax ofc simulated function LoadZedsAssets(byte Asset) { local KFMonster KFM; local int i; /* KFMonsterClassNames_Standard, //Default monster classes KFMonsterClassNames_Circus, //Circus KFMonsterClassNames_Halloween, //Halloween KFMonsterClassNames_XMas; */ switch (Asset) { case 0: //Standard for (i=0; i NewClass; local vector SpawnLoc; NewClass = class( DynamicLoadObject( ClassName, class'Class', true ) ); if( NewClass!=none ) { if ( PC != none ) { SpawnLoc = PC.Location; } else return; PC.Spawn( NewClass,,,SpawnLoc); } } //=======================================================for preloading assets hax ofc end //Simple function that copy All particle emitter inline set from source to target //return -1 if error //If Target has more emitters that source, emitters will be nopped if NoneFlag or left intact simulated function int LoadAndPolluteGoreEmitters(string sourceName, string targetName, optional bool NoneFlag) { local class Source; local class Target; local int k; Source = class(DynamicLoadObject(sourceName, class'class', true)); Target = class(DynamicLoadObject(targetName, class'class', true)); if(Source==none || Target == none ) return -1; for(k=0; k < Target.default.Emitters.Length; k++) { if(Source.default.Emitters[k] == none && NoneFlag) //if NoneFlag overwrite particle emitters with nones Target.default.Emitters[k] = none; else if(Source.default.Emitters[k] == none && !NoneFlag) //stop on first none reference break; Target.default.Emitters[k] = Source.default.Emitters[k]; } return 1; } //Load emitter defaults from backup classes simulated function LoadGoreEmitters(string targetName, byte EmitterNumber) { local int i; local Class Target; local array > SourceArray; if(BackupGore.length == 0 && EmitterNumber==0) { BackupGore[0] = class(DynamicLoadObject(TWIGoreBackup[0], class'class', true)); BackupGore[1] = class(DynamicLoadObject(TWIGoreBackup[1], class'class', true)); BackupGore[2] = class(DynamicLoadObject(TWIGoreBackup[2], class'class', true)); BackupGore[3] = class(DynamicLoadObject(TWIGoreBackup[3], class'class', true)); } if(OptGore.length == 0 && EmitterNumber==1) { OptGore[0] = class(DynamicLoadObject(TWIGoreBackup[4], class'class', true)); OptGore[1] = class(DynamicLoadObject(TWIGoreBackup[5], class'class', true)); OptGore[2] = class(DynamicLoadObject(TWIGoreBackup[6], class'class', true)); OptGore[3] = class(DynamicLoadObject(TWIGoreBackup[7], class'class', true)); } if(LowGoreE.length == 0 && EmitterNumber==2) { LowGoreE[0] = class(DynamicLoadObject(TWIGoreBackup[8], class'class', true)); LowGoreE[1] = class(DynamicLoadObject(TWIGoreBackup[9], class'class', true)); LowGoreE[2] = class(DynamicLoadObject(TWIGoreBackup[10], class'class', true)); LowGoreE[3] = class(DynamicLoadObject(TWIGoreBackup[11], class'class', true)); } if(NoGore.length == 0 && EmitterNumber==3) { NoGore[0] = class(DynamicLoadObject(TWIGoreBackup[12], class'class', true)); NoGore[1] = class(DynamicLoadObject(TWIGoreBackup[13], class'class', true)); NoGore[2] = class(DynamicLoadObject(TWIGoreBackup[14], class'class', true)); NoGore[3] = class(DynamicLoadObject(TWIGoreBackup[15], class'class', true)); } Target = class(DynamicLoadObject(targetName, class'class', true)); if(Target == none ) return; switch (EmitterNumber) { case 0: SourceArray = BackupGore; break; case 1: SourceArray = OptGore; break; case 2: SourceArray = LowGoreE; break; case 3: SourceArray = NoGore; break; } for(i=0;i CLEmitter; if (EMP_back.length==0) return; for (i=0;i(DynamicLoadObject(EMP_back[i].ClassName, class'class', true)); if(CLEmitter==none) continue; for (k=0; k < CLEmitter.default.Emitters.Length; k++) { CLEmitter.default.Emitters[k].Disabled = EMP_back[i].CEMP[k].Disabled; CLEmitter.default.Emitters[k].UseCollision = EMP_back[i].CEMP[k].UseCollision; CLEmitter.default.Emitters[k].AcceptsProjectors = EMP_back[i].CEMP[k].AcceptsProjectors; } } } //Reset flag indicates that emitter should reset to default parameters simulated function AnotherGoreEmitterLoad(string EmitterToLoad, EMB EmitterPrefs) { /* var EMP_backups EMP_backSingle; //for backuping emitters properties, single emitter var array EMP_back; //for backuping emitters properties, emitters array */ local Class CLEmitter; local int k; CLEmitter = class(DynamicLoadObject(EmitterToLoad, class'class', true)); if(CLEmitter==none) return; // backuping our emitters EMP_backSingle.ClassName = string(CLEmitter); EMP_backSingle.bHidden = CLEmitter.default.bHidden; EMP_backSingle.bUnlit = CLEmitter.default.bUnlit; EMP_backSingle.Lifespan = CLEmitter.default.LifeSpan; for(k=0; k < CLEmitter.default.Emitters.Length; k++) //Backuping particle emitters preferences { EMP_backSingle.CEMP[k].ClassName = string(CLEmitter.default.Emitters[k]); EMP_backSingle.CEMP[k].Disabled = CLEmitter.default.Emitters[k].Disabled; EMP_backSingle.CEMP[k].UseCollision = CLEmitter.default.Emitters[k].UseCollision; EMP_backSingle.CEMP[k].AcceptsProjectors = CLEmitter.default.Emitters[k].AcceptsProjectors; } if(EMP_back.length !=0) { EMP_back.length = EMP_back.length + 1; EMP_back[EMP_back.length] = EMP_backSingle; } else EMP_back[EMP_back.length] = EMP_backSingle; // Apply our tweaks CLEmitter.default.bHidden = EmitterPrefs.bHidden; CLEmitter.default.bUnlit = EmitterPrefs.bUnlit; CLEmitter.default.LifeSpan = EmitterPrefs.Lifespan; for(k=0; k < CLEmitter.default.Emitters.Length; k++) { CLEmitter.default.Emitters[k].UseCollision = EmitterPrefs.UseCollision; ClEmitter.default.Emitters[k].Disabled = EmitterPrefs.Disabled; //Disable all particle emitters ClEmitter.default.Emitters[k].AcceptsProjectors = EmitterPrefs.AcceptsProjectors; } } //Rewrite this and make this shit dynamic //===================================================================== simulated function AddStandardGorePresets() { local int i,k; local class ClEmitter; Gore_Preset.PresetName = "OPTIMIZED_TWI"; Gore_Preset.PresetDescription = "Optimized TWI shit..."; Gore_Preset.EmittersToLoad.Insert(0, KFMonsterGibEmitters.length); for (i=0; i< KFMonsterGibEmitters.length; i++) { Gore_Preset.EmittersToLoad[i].ClassName = KFMonsterGibEmitters[i]; Gore_Preset.EmittersToLoad[i].bHidden = false; Gore_Preset.EmittersToLoad[i].bUnlit = true; Gore_Preset.EmittersToLoad[i].LifeSpan = 5; CLEmitter = class(DynamicLoadObject(KFMonsterGibEmitters[i], class'class', true)); // if (CLEmitter == none) // PC.ClientMessage("OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" @ KFMonsterGibEmitters[i]); Gore_Preset.EmittersToLoad[i].CEMP.Insert(0, CLEmitter.default.Emitters.Length); for (k=0; k < CLEmitter.default.Emitters.Length; k++) //Editing particle emitters { Gore_Preset.EmittersToLoad[i].CEMP[k].ClassName = string(CLEmitter.default.Emitters[k]); Gore_Preset.EmittersToLoad[i].CEMP[k].Disabled = false; if (int(CLEmitter.default.Emitters[k].InitialParticlesPerSecond / CLEmitter.default.Emitters[k].MaxParticles) > 350) //not fucking 0.00000001 Gore_Preset.EmittersToLoad[i].CEMP[k].InitialParticlesPerSecond = float(CLEmitter.default.Emitters[k].MaxParticles * 200); //0.01 ms to spawn else Gore_Preset.EmittersToLoad[i].CEMP[k].InitialParticlesPerSecond = CLEmitter.default.Emitters[k].InitialParticlesPerSecond; //else let's save old value Gore_Preset.EmittersToLoad[i].CEMP[k].UseCollision = CLEmitter.default.Emitters[k].UseCollision; Gore_Preset.EmittersToLoad[i].CEMP[k].AcceptsProjectors = false; } } Gore_Presets[0] = Gore_Preset; Gore_Preset.PresetName = "NO_GORE"; Gore_Preset.PresetDescription = "No gore at all. Disables all emitters."; Gore_Preset.EmittersToLoad.Insert(0, KFMonsterGibEmitters.length); for (i=0; i< KFMonsterGibEmitters.length; i++) { Gore_Preset.EmittersToLoad[i].ClassName = KFMonsterGibEmitters[i]; Gore_Preset.EmittersToLoad[i].bHidden = true; Gore_Preset.EmittersToLoad[i].bUnlit = true; Gore_Preset.EmittersToLoad[i].LifeSpan = 0.5; CLEmitter = class(DynamicLoadObject(KFMonsterGibEmitters[i], class'class', true)); Gore_Preset.EmittersToLoad[i].CEMP.Insert(0, CLEmitter.default.Emitters.Length); for (k=0; k < CLEmitter.default.Emitters.Length; k++) //Editing particle emitters { Gore_Preset.EmittersToLoad[i].CEMP[k].ClassName = string(CLEmitter.default.Emitters[k]); Gore_Preset.EmittersToLoad[i].CEMP[k].Disabled = true; Gore_Preset.EmittersToLoad[i].CEMP[k].UseCollision = false; Gore_Preset.EmittersToLoad[i].CEMP[k].AcceptsProjectors = false; } } Gore_Presets[1] = Gore_Preset; Gore_Preset.PresetName = "LOW_GORE"; Gore_Preset.PresetDescription = "Low gore."; Gore_Preset.EmittersToLoad.Insert(0, KFMonsterGibEmitters.length); for (i=0; i< KFMonsterGibEmitters.length; i++) { Gore_Preset.EmittersToLoad[i].ClassName = KFMonsterGibEmitters[i]; Gore_Preset.EmittersToLoad[i].bHidden = false; Gore_Preset.EmittersToLoad[i].bUnlit = true; Gore_Preset.EmittersToLoad[i].LifeSpan = 5; CLEmitter = class(DynamicLoadObject(KFMonsterGibEmitters[i], class'class', true)); Gore_Preset.EmittersToLoad[i].CEMP.Insert(0, CLEmitter.default.Emitters.Length); for (k=0; k < CLEmitter.default.Emitters.Length; k++) //Editing particle emitters { Gore_Preset.EmittersToLoad[i].CEMP[k].ClassName = string(CLEmitter.default.Emitters[k]); Gore_Preset.EmittersToLoad[i].CEMP[k].Disabled = false; if (int(CLEmitter.default.Emitters[k].InitialParticlesPerSecond / CLEmitter.default.Emitters[k].MaxParticles) > 350) //not fucking 0.00000001 Gore_Preset.EmittersToLoad[i].CEMP[k].InitialParticlesPerSecond = float(CLEmitter.default.Emitters[k].MaxParticles * 200); //0.01 ms to spawn else Gore_Preset.EmittersToLoad[i].CEMP[k].InitialParticlesPerSecond = CLEmitter.default.Emitters[k].InitialParticlesPerSecond; //else let's save old value Gore_Preset.EmittersToLoad[i].CEMP[k].UseCollision = false; Gore_Preset.EmittersToLoad[i].CEMP[k].AcceptsProjectors = false; } } Gore_Presets[2] = Gore_Preset; Gore_Preset.PresetName = "TWI"; Gore_Preset.PresetDescription = "Just TWI shit..."; Gore_Preset.EmittersToLoad.Insert(0, KFMonsterGibEmitters.length); for (i=0; i< KFMonsterGibEmitters.length; i++) { CLEmitter = class(DynamicLoadObject(KFMonsterGibEmitters[i], class'class', true)); Gore_Preset.EmittersToLoad[i].ClassName = KFMonsterGibEmitters[i]; Gore_Preset.EmittersToLoad[i].bHidden = false; Gore_Preset.EmittersToLoad[i].bUnlit = false; Gore_Preset.EmittersToLoad[i].LifeSpan = CLEmitter.default.Lifespan; Gore_Preset.EmittersToLoad[i].CEMP.Insert(0, CLEmitter.default.Emitters.Length); for (k=0; k < CLEmitter.default.Emitters.Length; k++) //Editing particle emitters { Gore_Preset.EmittersToLoad[i].CEMP[k].ClassName = string(CLEmitter.default.Emitters[k]); Gore_Preset.EmittersToLoad[i].CEMP[k].Disabled = false; Gore_Preset.EmittersToLoad[i].CEMP[k].InitialParticlesPerSecond = CLEmitter.default.Emitters[k].InitialParticlesPerSecond; //else let's save old value Gore_Preset.EmittersToLoad[i].CEMP[k].UseCollision = CLEmitter.default.Emitters[k].UseCollision; Gore_Preset.EmittersToLoad[i].CEMP[k].AcceptsProjectors = false; } } Gore_Presets[3] = Gore_Preset; } simulated function ApplyStandardGorePresets(string SetPresetName) { local int i,k, l; local class ClEmitter; for (l=0; l < Gore_Presets.length; l++) { if (Gore_Presets[l].PresetName == SetPresetName) { Gore_Preset = Gore_Presets[l]; for (i=0; i< KFMonsterGibEmitters.length; i++) { if (Gore_Preset.EmittersToLoad[i].ClassName == KFMonsterGibEmitters[i]) { CLEmitter = class(DynamicLoadObject(KFMonsterGibEmitters[i], class'class', true)); CLEmitter.default.bHidden = Gore_Preset.EmittersToLoad[i].bHidden; CLEmitter.default.bUnlit = Gore_Preset.EmittersToLoad[i].bUnlit; CLEmitter.default.LifeSpan = Gore_Preset.EmittersToLoad[i].LifeSpan; //PC.ClientMessage("Hidden is" @ CLEmitter.default.bHidden @ "Unlit is" @ CLEmitter.default.bUnlit @ "Lifespan is" @ CLEmitter.default.LifeSpan); for (k=0; k < CLEmitter.default.Emitters.Length; k++) //Editing particle emitters { CLEmitter.default.Emitters[k].Disabled = Gore_Preset.EmittersToLoad[i].CEMP[k].Disabled; //PC.ClientMessage("Disabled is" @ Gore_Preset.EmittersToLoad[i].CEMP[k].Disabled @ "on" @ CLEmitter.default.Emitters[k]); CLEmitter.default.Emitters[k].InitialParticlesPerSecond = Gore_Preset.EmittersToLoad[i].CEMP[k].InitialParticlesPerSecond; //PC.ClientMessage("Initial particles are" @ Gore_Preset.EmittersToLoad[i].CEMP[k].InitialParticlesPerSecond); CLEmitter.default.Emitters[k].UseCollision = Gore_Preset.EmittersToLoad[i].CEMP[k].UseCollision; //PC.ClientMessage(Gore_Preset.EmittersToLoad[i].CEMP[k].UseCollision); CLEmitter.default.Emitters[k].AcceptsProjectors = Gore_Preset.EmittersToLoad[i].CEMP[k].AcceptsProjectors; //PC.ClientMessage(Gore_Preset.EmittersToLoad[i].CEMP[k].AcceptsProjectors); } break; } } break; } else continue; } } //===================================================================== //Some gore-related emitter tweaks simulated function OptimizeGore() { //local int i; GibAndGibletsTweaks(false); /* if(CurrentOptParams.UserSettingsToEmitters) //load user settings { for (i=0; i < KFMonsterGibEmitters.length; i++) { AnotherGoreEmitterLoad(KFMonsterGibEmitters[i], User_EMPS); //Load user settings } } */ if(Gore_Presets.length == 0) AddStandardGorePresets(); ApplyStandardGorePresets(CurrentOptParams.GoreLevel); //Apply our gore parameters switch(CurrentOptParams.GoreLevel) { case "OPTIMIZED_TWI": LoadGoreEmitters(TWIGibEmitters[0], 1); LoadGoreEmitters(TWIGibEmitters[1], 1); LoadGoreEmitters(TWIGibEmitters[2], 1); LoadGoreEmitters(TWIGibEmitters[3], 1); break; case "TWI": LoadGoreEmitters(TWIGibEmitters[0], 0); LoadGoreEmitters(TWIGibEmitters[1], 0); LoadGoreEmitters(TWIGibEmitters[2], 0); LoadGoreEmitters(TWIGibEmitters[3], 0); break; case "NO_GORE": //No gore preset LoadGoreEmitters(TWIGibEmitters[0], 3); LoadGoreEmitters(TWIGibEmitters[1], 3); LoadGoreEmitters(TWIGibEmitters[2], 3); LoadGoreEmitters(TWIGibEmitters[3], 3); break; case "LOW_GORE": LoadGoreEmitters(TWIGibEmitters[0], 2); LoadGoreEmitters(TWIGibEmitters[1], 2); LoadGoreEmitters(TWIGibEmitters[2], 2); LoadGoreEmitters(TWIGibEmitters[3], 2); break; case "GORY!": break; case "BLOOD FOR THE BLOOD GOD!": break; } } // Tweaks for gibz and giblets // Pollute gib classes, flag reset to default parameters simulated function PolluteGibClasses(string GibGlass,optional bool Reset) { local class KFGib; KFGib = GetGibletsClassFromString(GibGlass); if (KFGib==none) return; if (!Reset) { KFGib.default.bHidden = CurrentOptParams.bHideGibs; KFGib.default.bUnlit = CurrentOptParams.bUnlitGibs; KFGib.default.LifeSpan= CurrentOptParams.GibsLifespan; if (CurrentOptParams.GibUseDeferRendering) { KFGib.default.Style = STY_Additive; //Enable defer rendering KFGib.default.bDeferRendering = true; } KFGib.default.MaxLights = CurrentOptParams.GibMaxLights; KFGib.default.bUseCollisionStaticMesh= CurrentOptParams.GibUseCollisionStaticMesh; KFGib.default.bAcceptsProjectors = CurrentOptParams.GibAcceptProjectors; KFGib.default.bStaticLighting = CurrentOptParams.GibStaticLighting; } else { KFGib.default.bHidden = false; KFGib.default.bUnlit = false; KFGib.default.LifeSpan= 6.0; if (CurrentOptParams.GibUseDeferRendering) { KFGib.default.Style = STY_Normal; } KFGib.default.MaxLights = 4; KFGib.default.bUseCollisionStaticMesh= true; KFGib.default.bAcceptsProjectors = true; KFGib.default.bStaticLighting = false; } } simulated function PolluteGibletsClasses(string GibletGlass,optional bool Reset) { local class KFSevered; KFSevered = GetGibClassFromString(GibletGlass); if (KFSevered==none) return; if (!Reset) { KFSevered.default.bHidden = CurrentOptParams.bHideGiblets; KFSevered.default.bUnlit = CurrentOptParams.bUnlitGiblets; KFSevered.default.LifeSpan = CurrentOptParams.GibletsLifespan; if (CurrentOptParams.GibletsUseDeferRendering) { KFSevered.default.Style = STY_Additive; //Enable defer rendering KFSevered.default.bDeferRendering = true; } KFSevered.default.MaxLights = CurrentOptParams.GibletsMaxLights; KFSevered.default.bUseCollisionStaticMesh= CurrentOptParams.GibletsUseCollisionStaticMesh; KFSevered.default.bAcceptsProjectors = CurrentOptParams.GibletsAcceptProjectors; KFSevered.default.bStaticLighting = CurrentOptParams.GibletsStaticLighting; } else { KFSevered.default.bHidden = false; KFSevered.default.bUnlit = false; KFSevered.default.LifeSpan = 8.0; if (CurrentOptParams.GibletsUseDeferRendering) { KFSevered.default.Style = STY_Normal; //Disable defer rendering KFSevered.default.bDeferRendering = true; } KFSevered.default.MaxLights = 4; KFSevered.default.bUseCollisionStaticMesh= false; KFSevered.default.bAcceptsProjectors = true; KFSevered.default.bStaticLighting = false; } } simulated function GibAndGibletsTweaks(bool Reset) { local int i; if (CurrentOptParams.bAdvancedGiblets) { for (i=0; i KFM; if(!Reset) { KFM = GetMonsterClassFromString(MonsterClassToLoad); if(KFM==none) return; KFM.default.cullDistance = CurrentOptParams.ZedCullDistance; KFM.default.bUnlit = CurrentOptParams.useUnlit; KFM.default.AmbientGlow =CurrentOptParams.AmbientGlow; KFM.default.SoundOcclusion = CurrentOptParams.SoundOcclusion; KFM.default.SoundRadius = CurrentOptParams.SoundRadius; } else { KFM.default.cullDistance = 0; KFM.default.bUnlit = false; KFM.default.AmbientGlow = 0; KFM.default.SoundOcclusion = Occlusion_Default; KFM.default.SoundRadius = 300; } } //Pollute default zed classes and detect gametype simulated function PolluteDefaults(bool Reset) { local int i; for(i=0; i KFMonsterClassNames, array KFMReplace) { local int i,k; local class KFM, ReplaceKFM; local string MeshName; //OFC some bullshit first... /*Shaders. Need to re-do this... class'ZombieClot_HALLOWEEN'.default.ClotSkins[0] = shader'Chaos_WeaponPack_T.Clot_standard_shader'; class'ZombieClot_HALLOWEEN'.default.ClotSkins[1] = shader'Chaos_WeaponPack_T.Clot_standard_shader'; class'ZombieClot_HALLOWEEN'.default.ClotSkins[2] = shader'Chaos_WeaponPack_T.Clot_standard_shader'; class'ZombieClot_HALLOWEEN'.default.ClotSkins[3] = shader'Chaos_WeaponPack_T.Clot_standard_shader'; class'ZombieClot_HALLOWEEN'.default.ClotSkins[4] = shader'Chaos_WeaponPack_T.Clot_standard_shader'; class'ZombieClot_HALLOWEEN'.default.ClotSkins[5] = shader'Chaos_WeaponPack_T.Clot_standard_shader'; */ if (KFMonsterClassNames.length != KFMReplace.length) return; class'ZombieGoreFast_CIRCUS'.default.bHeadGibbed=false; //go fuck your mouth with your circus shit for (i=0; i GetGibletsClassFromString(string String) { //for conversion from string to class reference return class(DynamicLoadObject(String, class'class', true)); } simulated function class GetGibClassFromString(string String) { //for conversion from string to class reference return class(DynamicLoadObject(String, class'class', true)); } simulated function class GetMonsterClassFromString(string String) { //for conversion from string to class reference return class(DynamicLoadObject(String, class'class', true)); } //==============String to class conversion simulated function class GetEmitterClassFromString(string String) { //for conversion from string to class reference return class(DynamicLoadObject(String, class'class', true)); } defaultproperties { bHidden=true bUnlit=true }