16 Commits

Author SHA1 Message Date
ac6e0a8977 fix 9mm/HRG93R filter 2023-10-21 13:59:58 +03:00
561545de2b a little cleaning 2023-10-20 23:48:04 +03:00
6dfbcbb0b7 force GRI init 2023-10-20 23:30:45 +03:00
18fc55ce42 force skin update 2023-10-20 23:18:04 +03:00
6cc67da26b Merge branch 'replace-dlc-weapons-fix' 2023-10-20 22:56:15 +03:00
dc2108e482 Merge pull request #10 from GenZmeY/Halloween2023Update
Halloween 2023 Update
2023-10-20 22:54:26 +03:00
37944a25c4 remove DLC clones along with their originals from [CTI.RemoveItems] 2023-10-20 22:53:11 +03:00
ce070b66cd Merge branch 'master' into Halloween2023Update 2023-10-05 21:40:07 +03:00
8b446c735f Merge pull request #11 from GenZmeY/skins
Apply weapon skins for replaced DLCs
2023-10-05 20:25:52 +03:00
b54d2e6efc Merge branch 'linter' into skins 2023-10-05 20:21:32 +03:00
7e0151bf09 Merge branch 'linter' into Halloween2023Update 2023-10-05 20:21:21 +03:00
67f2007984 update megalinter ci/cd 2023-10-05 20:20:36 +03:00
e68dd3af38 apply weapon skins for replaced DLCs 2023-10-02 01:55:09 +03:00
f4cfa4948b unlock MG3 2023-09-26 01:52:14 +03:00
b7bb29a342 make the localization code a little more compact 2023-09-26 01:41:05 +03:00
47b02a78c4 update description 2023-09-19 23:11:33 +03:00
38 changed files with 433 additions and 180 deletions

View File

@ -30,7 +30,7 @@ jobs:
- name: MegaLinter - name: MegaLinter
id: ml id: ml
uses: oxsecurity/megalinter@v6 uses: oxsecurity/megalinter@v7
env: env:
VALIDATE_ALL_CODEBASE: true VALIDATE_ALL_CODEBASE: true
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -68,5 +68,5 @@ jobs:
with: with:
branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }} branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }}
commit_message: "[MegaLinter] Apply linters fixes" commit_message: "[MegaLinter] Apply linters fixes"
commit_user_name: megalinter-bot commit_user_name: "github-actions"
commit_user_email: nicolas.vuillamy@ox.security commit_user_email: "github-actions[bot]@users.noreply.github.com"

View File

@ -35,6 +35,19 @@ var private Array<CTI_RepInfo> RepInfos;
var private bool ReadyToSync; var private bool ReadyToSync;
// To bypass "Booleans may not be out parameters" error
struct BoolWrapper
{
var bool Value;
structdefaultproperties
{
Value = false
}
};
var private BoolWrapper DLCSkinUpdateRequired;
public simulated function bool SafeDestroy() public simulated function bool SafeDestroy()
{ {
`Log_Trace(); `Log_Trace();
@ -174,17 +187,7 @@ private function PostInit()
return; return;
} }
if (Unlocker.static.UnlockDLC(KFGI, KFGRI, UnlockDLC, RemoveItems, AddItems, LogLevel)) WeapDefs = Trader.static.GenerateWeapDefList(
{
`Log_Info("DLC unlocked");
}
if (bPreloadContent)
{
Preload(AddItems);
}
Trader.static.ModifyTrader(
KFGRI, KFGRI,
RemoveItems, RemoveItems,
AddItems, AddItems,
@ -194,7 +197,23 @@ private function PostInit()
bDisableItemLimitCheck, bDisableItemLimitCheck,
LogLevel); LogLevel);
WeapDefs = Trader.static.GetTraderWeapDefs(KFGRI, LogLevel); RemoveItems.Length = 0;
AddItems.Length = 0;
if (Unlocker.static.UnlockDLC(KFGI, KFGRI, UnlockDLC, WeapDefs, DLCSkinUpdateRequired, LogLevel))
{
`Log_Info("DLC unlocked");
}
`Log_Debug("DLCSkinUpdateRequired:" @ String(DLCSkinUpdateRequired.Value));
Trader.static.OverwriteTraderItems(KFGRI, WeapDefs, LogLevel);
`Log_Info("Trader items:" @ WeapDefs.Length);
if (bPreloadContent)
{
Preload(WeapDefs);
}
ReadyToSync = true; ReadyToSync = true;
@ -280,7 +299,7 @@ public function bool CreateRepInfo(Controller C)
if (RepInfo == None) return false; if (RepInfo == None) return false;
RepInfo.PrepareSync(Self, KFPlayerController(C), LogLevel); RepInfo.PrepareSync(Self, KFPlayerController(C), LogLevel, DLCSkinUpdateRequired.Value);
RepInfos.AddItem(RepInfo); RepInfos.AddItem(RepInfo);

View File

@ -11,6 +11,17 @@ function bool IsItemFiltered(STraderItem Item, optional bool bDebug)
if (Item.WeaponDef.default.PlatformRestriction != PR_All && class'KFUnlockManager'.static.IsPlatformRestricted(Item.WeaponDef.default.PlatformRestriction)) if (Item.WeaponDef.default.PlatformRestriction != PR_All && class'KFUnlockManager'.static.IsPlatformRestricted(Item.WeaponDef.default.PlatformRestriction))
return true; return true;
if (Has9mmGun())
{
if ((Item.ClassName == 'KFWeap_HRG_93r' || Item.ClassName == 'KFWeap_HRG_93r_Dual'))
return true;
}
else
{
if ((Item.ClassName == 'KFWeap_Pistol_9mm' || Item.ClassName == 'KFWeap_Pistol_Dual9mm'))
return true;
}
return false; return false;
} }

View File

@ -1,9 +1,11 @@
class CTI_RepInfo extends ReplicationInfo; class CTI_RepInfo extends ReplicationInfo
dependson(WeaponReplacements);
const CAPACITY = 64; // max: 128 const CAPACITY = 64; // max: 128
const Trader = class'Trader'; const Trader = class'Trader';
const LocalMessage = class'CTI_LocalMessage'; const LocalMessage = class'CTI_LocalMessage';
const Replacements = class'WeaponReplacements';
struct ReplicationStruct struct ReplicationStruct
{ {
@ -19,7 +21,9 @@ var public bool PendingSync;
var private CTI CTI; var private CTI CTI;
var private E_LogLevel LogLevel; var private E_LogLevel LogLevel;
var private GameReplicationInfo GRI;
var private KFPlayerController KFPC; var private KFPlayerController KFPC;
var private KFPlayerReplicationInfo KFPRI;
var private KFGFxWidget_PartyInGame PartyInGameWidget; var private KFGFxWidget_PartyInGame PartyInGameWidget;
var private GFxObject Notification; var private GFxObject Notification;
@ -29,15 +33,18 @@ var private String NotificationRightText;
var private int NotificationPercent; var private int NotificationPercent;
var private int WaitingGRI; var private int WaitingGRI;
var private int WaitingGRIThreshold;
var private int WaitingGRILimit; var private int WaitingGRILimit;
var private ReplicationStruct RepData; var private ReplicationStruct RepData;
var private Array<class<KFWeaponDefinition> > RepArray; var private Array<class<KFWeaponDefinition> > RepArray;
var private bool SkinUpdateRequired;
replication replication
{ {
if (bNetInitial && Role == ROLE_Authority) if (bNetInitial && Role == ROLE_Authority)
LogLevel; LogLevel, SkinUpdateRequired;
} }
public simulated function bool SafeDestroy() public simulated function bool SafeDestroy()
@ -104,13 +111,14 @@ private reliable client function Send(ReplicationStruct RD)
Sync(); Sync();
} }
public function PrepareSync(CTI _CTI, KFPlayerController _KFPC, E_LogLevel _LogLevel) public function PrepareSync(CTI _CTI, KFPlayerController _KFPC, E_LogLevel _LogLevel, bool _SkinUpdateRequired)
{ {
`Log_Trace(); `Log_Trace();
CTI = _CTI; CTI = _CTI;
KFPC = _KFPC; KFPC = _KFPC;
LogLevel = _LogLevel; LogLevel = _LogLevel;
SkinUpdateRequired = _SkinUpdateRequired;
} }
private simulated function Progress(int Value, int Size) private simulated function Progress(int Value, int Size)
@ -132,7 +140,7 @@ private simulated function Finished()
`Log_Trace(); `Log_Trace();
if (WorldInfo.GRI == None && WaitingGRI++ < WaitingGRILimit) if (GetGRI(WaitingGRI > WaitingGRIThreshold) == None && WaitingGRI++ < WaitingGRILimit)
{ {
`Log_Debug("Finished: Waiting GRI" @ WaitingGRI); `Log_Debug("Finished: Waiting GRI" @ WaitingGRI);
NotifyWaitingGRI(); NotifyWaitingGRI();
@ -140,7 +148,7 @@ private simulated function Finished()
return; return;
} }
KFGRI = KFGameReplicationInfo(WorldInfo.GRI); KFGRI = KFGameReplicationInfo(GRI);
if (KFGRI != None) if (KFGRI != None)
{ {
`Log_Debug("Finished: Trader.static.OverwriteTraderItems"); `Log_Debug("Finished: Trader.static.OverwriteTraderItems");
@ -149,14 +157,70 @@ private simulated function Finished()
} }
else else
{ {
`Log_Error("Incompatible Replication info:" @ String(WorldInfo.GRI)); `Log_Error("Incompatible Replication info:" @ String(GRI));
NotifyIncompatibleGRI(); NotifyIncompatibleGRI();
} }
ShowReadyButton(); ShowReadyButton();
Cleanup(); if (SkinUpdateRequired)
SafeDestroy(); {
SetTimer(1.0f, true, nameof(UpdateSkinsDLC));
}
else
{
ClientCleanup();
}
}
private simulated function UpdateSkinsDLC()
{
local SWeapReplace WeapReplace;
`Log_Debug("Wait for spawn");
if (GetKFPRI() != None && KFPRI.bHasSpawnedIn)
{
foreach Replacements.default.DLC(WeapReplace)
{
// sometimes "WeapReplace.Weap.default.SkinItemId" can give values greater than zero while actually being zero
// this is the same bug that prevents creating the correct default config
// so for now lets shorten the check a little so that the skinId of the WeapReplace is guaranteed to be correct
// but if this bug is ever fixed, then its worth replacing the check with this one:
// if (WeapReplace.WeapParent.default.SkinItemId > 0 && WeapReplace.Weap.default.SkinItemId != WeapReplace.WeapParent.default.SkinItemId)
// to reduce the number of meaningless disk writes
if (WeapReplace.WeapParent.default.SkinItemId > 0)
{
`Log_Debug("Update skin for:" @ String(WeapReplace.WeapDef) @ "SkinId:" @ WeapReplace.WeapParent.default.SkinItemId);
class'KFWeaponSkinList'.static.SaveWeaponSkin(WeapReplace.WeapDef, WeapReplace.WeapParent.default.SkinItemId);
}
}
ClearTimer(nameof(UpdateSkinsDLC));
ClientCleanup();
}
}
private simulated function GameReplicationInfo GetGRI(optional bool ForcedSearch = false)
{
`Log_Trace();
if (GRI == None)
{
GRI = WorldInfo.GRI;
}
if (GRI == None && ForcedSearch)
{
foreach WorldInfo.DynamicActors(class'GameReplicationInfo', GRI) break;
}
if (WorldInfo.GRI == None && GRI != None)
{
`Log_Warn("Force initialization of WorldInfo.GRI" @ String(GRI));
WorldInfo.GRI = GRI;
}
return GRI;
} }
private simulated function KFPlayerController GetKFPC() private simulated function KFPlayerController GetKFPC()
@ -175,6 +239,19 @@ private simulated function KFPlayerController GetKFPC()
return KFPC; return KFPC;
} }
private simulated function KFPlayerReplicationInfo GetKFPRI()
{
`Log_Trace();
if (KFPRI != None) return KFPRI;
if (GetKFPC() == None) return None;
KFPRI = KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo);
return KFPRI;
}
public reliable client function WriteToChatLocalized( public reliable client function WriteToChatLocalized(
E_CTI_LocalMessageType LMT, E_CTI_LocalMessageType LMT,
optional String HexColor, optional String HexColor,
@ -284,11 +361,18 @@ private simulated function KeepNotification()
NotificationPercent); NotificationPercent);
} }
private reliable server function Cleanup() private simulated function ClientCleanup()
{
`Log_Debug("Cleanup");
ServerCleanup();
SafeDestroy();
}
private reliable server function ServerCleanup()
{ {
`Log_Trace(); `Log_Trace();
`Log_Debug("Cleanup"); `Log_Debug("Cleanup" @ GetKFPC() @ GetKFPRI() == None? "" : GetKFPRI().PlayerName);
if (!CTI.DestroyRepInfo(GetKFPC())) if (!CTI.DestroyRepInfo(GetKFPC()))
{ {
`Log_Debug("Cleanup (forced)"); `Log_Debug("Cleanup (forced)");
@ -329,7 +413,7 @@ private simulated function NotifyIncompatibleGRI()
WriteToChatLocalized( WriteToChatLocalized(
CTI_IncompatibleGRI, CTI_IncompatibleGRI,
class'KFLocalMessage'.default.InteractionColor, class'KFLocalMessage'.default.InteractionColor,
String(WorldInfo.GRI.class)); String(GRI.class));
WriteToChatLocalized( WriteToChatLocalized(
CTI_IncompatibleGRIWarning, CTI_IncompatibleGRIWarning,
class'KFLocalMessage'.default.InteractionColor); class'KFLocalMessage'.default.InteractionColor);
@ -345,5 +429,6 @@ defaultproperties
NotificationPercent = 0 NotificationPercent = 0
WaitingGRI = 0 WaitingGRI = 0
WaitingGRIThreshold = 15
WaitingGRILimit = 30 WaitingGRILimit = 30
} }

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_AutoTurret extends KFWeapDef_AutoTurret
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_AutoTurret'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_AutoTurret'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_BladedPistol extends KFWeapDef_BladedPistol
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_BladedPistol'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_BladedPistol'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_Blunderbuss extends KFWeapDef_Blunderbuss
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_Blunderbuss'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_Blunderbuss'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_ChainBat extends KFWeapDef_ChainBat
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_ChainBat'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_ChainBat'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_ChiappaRhino extends KFWeapDef_ChiappaRhino
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_ChiappaRhino'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_ChiappaRhino'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_ChiappaRhinoDual extends KFWeapDef_ChiappaRhinoDual
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_ChiappaRhinoDual'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_ChiappaRhinoDual'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_CompoundBow extends KFWeapDef_CompoundBow
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_CompoundBow'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_CompoundBow'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_Doshinegun extends KFWeapDef_Doshinegun
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_Doshinegun'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_Doshinegun'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_DualBladed extends KFWeapDef_DualBladed
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_DualBladed'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_DualBladed'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_FAMAS extends KFWeapDef_FAMAS
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_FAMAS'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_FAMAS'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_G18 extends KFWeapDef_G18
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_G18'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_G18'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_G36C extends KFWeapDef_G36C
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_G36C'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_G36C'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_GravityImploder extends KFWeapDef_GravityImploder
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_GravityImploder'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_GravityImploder'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_HVStormCannon extends KFWeapDef_HVStormCannon
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_HVStormCannon'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_HVStormCannon'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_IonThruster extends KFWeapDef_IonThruster
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_IonThruster'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_IonThruster'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -0,0 +1,13 @@
class CTI_WeapDef_MG3 extends KFWeapDef_MG3
abstract;
static function String GetItemLocalization(String KeyName)
{
return class'KFGame.KFWeapDef_MG3'.static.GetItemLocalization(KeyName);
}
defaultproperties
{
SharedUnlockId = SCU_None
WeaponClassPath = "CTI.CTI_Weap_LMG_MG3"
}

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_Mine_Reconstructor extends KFWeapDef_Mine_Reconstructor
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_Mine_Reconstructor'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_Mine_Reconstructor'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_Minigun extends KFWeapDef_Minigun
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_Minigun'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_Minigun'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_MosinNagant extends KFWeapDef_MosinNagant
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_MosinNagant'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_MosinNagant'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_ParasiteImplanter extends KFWeapDef_ParasiteImplanter
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_ParasiteImplanter'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_ParasiteImplanter'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_Pistol_DualG18 extends KFWeapDef_Pistol_DualG18
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_Pistol_DualG18'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_Pistol_DualG18'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_Pistol_G18C extends KFWeapDef_Pistol_G18C
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_Pistol_G18C'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_Pistol_G18C'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_Rifle_FrostShotgunAxe extends KFWeapDef_Rifle_FrostShotgunAxe
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_Rifle_FrostShotgunAxe'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_Rifle_FrostShotgunAxe'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_Scythe extends KFWeapDef_Scythe
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_Scythe'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_Scythe'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_Shotgun_S12 extends KFWeapDef_Shotgun_S12
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_Shotgun_S12'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_Shotgun_S12'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_ShrinkRayGun extends KFWeapDef_ShrinkRayGun
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_ShrinkRayGun'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_ShrinkRayGun'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_ThermiteBore extends KFWeapDef_ThermiteBore
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_ThermiteBore'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_ThermiteBore'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_ZedMKIII extends KFWeapDef_ZedMKIII
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_ZedMKIII'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_ZedMKIII'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -3,9 +3,7 @@ class CTI_WeapDef_Zweihander extends KFWeapDef_Zweihander
static function String GetItemLocalization(String KeyName) static function String GetItemLocalization(String KeyName)
{ {
local Array<String> Strings; return class'KFGame.KFWeapDef_Zweihander'.static.GetItemLocalization(KeyName);
ParseStringIntoArray(class'KFGame.KFWeapDef_Zweihander'.default.WeaponClassPath, Strings, ".", true);
return Localize(Strings[1], KeyName, Strings[0]);
} }
defaultproperties defaultproperties

View File

@ -0,0 +1,6 @@
class CTI_Weap_LMG_MG3 extends KFWeap_LMG_MG3;
defaultproperties
{
}

View File

@ -91,11 +91,11 @@ public static function Array<class<KFWeaponDefinition> > GetTraderWeapDefsDLC(KF
return WeapDefs; return WeapDefs;
} }
public static simulated function ModifyTrader( public static simulated function Array< class<KFWeaponDefinition> > GenerateWeapDefList(
KFGameReplicationInfo KFGRI, KFGameReplicationInfo KFGRI,
const out Array<class<KFWeaponDefinition> > RemoveItems, const out Array<class<KFWeaponDefinition> > RemoveItems,
const out Array<class<KFWeaponDefinition> > AddItems, const out Array<class<KFWeaponDefinition> > AddItems,
bool ReplaceMode, bool RemoveAll,
bool RemoveHRG, bool RemoveHRG,
bool RemoveDLC, bool RemoveDLC,
bool bDisableItemLimitCheck, bool bDisableItemLimitCheck,
@ -103,14 +103,14 @@ public static simulated function ModifyTrader(
{ {
local KFGFxObject_TraderItems TraderItems; local KFGFxObject_TraderItems TraderItems;
local STraderItem Item; local STraderItem Item;
local Array<class<KFWeaponDefinition> > WeapDefs; local Array< class<KFWeaponDefinition> > WeapDefs;
local int Index; local int Index;
`Log_TraceStatic(); `Log_TraceStatic();
TraderItems = GetTraderItems(KFGRI, LogLevel); TraderItems = GetTraderItems(KFGRI, LogLevel);
if (!ReplaceMode) if (!RemoveAll)
{ {
foreach TraderItems.SaleItems(Item) foreach TraderItems.SaleItems(Item)
{ {
@ -126,9 +126,12 @@ public static simulated function ModifyTrader(
} }
for (Index = 0; Index < AddItems.Length; ++Index) for (Index = 0; Index < AddItems.Length; ++Index)
{
if (WeaponClassIsUnique(AddItems[Index].default.WeaponClassPath, WeapDefs, LogLevel))
{ {
WeapDefs.AddItem(AddItems[Index]); WeapDefs.AddItem(AddItems[Index]);
} }
}
WeapDefs.Sort(ByPrice); WeapDefs.Sort(ByPrice);
@ -143,7 +146,7 @@ public static simulated function ModifyTrader(
WeapDefs.Length = ITEMS_LIMIT; WeapDefs.Length = ITEMS_LIMIT;
} }
OverwriteTraderItems(KFGRI, WeapDefs, LogLevel); return WeapDefs;
} }
public static simulated function OverwriteTraderItems( public static simulated function OverwriteTraderItems(

View File

@ -1,4 +1,5 @@
class Unlocker extends Object class Unlocker extends Object
dependson(WeaponReplacements)
abstract; abstract;
// TODO: // TODO:
@ -7,8 +8,7 @@ class Unlocker extends Object
// but how? 🤔 // but how? 🤔
const Trader = class'Trader'; const Trader = class'Trader';
const Replacements = class'WeaponReplacements';
var private const Array<class<KFWeaponDefinition> > WeapDefDLCReplacements;
public static function bool IsValidTypeUnlockDLC(String UnlockType, E_LogLevel LogLevel) public static function bool IsValidTypeUnlockDLC(String UnlockType, E_LogLevel LogLevel)
{ {
@ -31,8 +31,8 @@ public static function bool UnlockDLC(
KFGameInfo KFGI, KFGameInfo KFGI,
KFGameReplicationInfo KFGRI, KFGameReplicationInfo KFGRI,
String UnlockType, String UnlockType,
out Array<class<KFWeaponDefinition> > RemoveItems, out Array<class<KFWeaponDefinition> > WeapDefs,
out Array<class<KFWeaponDefinition> > AddItems, out BoolWrapper DLCSkinUpdateRequired,
E_LogLevel LogLevel) E_LogLevel LogLevel)
{ {
`Log_TraceStatic(); `Log_TraceStatic();
@ -41,12 +41,13 @@ public static function bool UnlockDLC(
{ {
case "true": case "true":
case "auto": case "auto":
return Auto(KFGI, KFGRI, RemoveItems, AddItems, LogLevel); return Auto(KFGI, KFGRI, WeapDefs, DLCSkinUpdateRequired, LogLevel);
case "replaceweapons": case "replaceweapons":
return ReplaceWeapons(KFGRI, RemoveItems, AddItems, LogLevel); return ReplaceWeapons(KFGRI, WeapDefs, DLCSkinUpdateRequired, LogLevel);
case "replacefilter": case "replacefilter":
DLCSkinUpdateRequired.Value = false;
return ReplaceFilter(KFGI, LogLevel); return ReplaceFilter(KFGI, LogLevel);
case "false": case "false":
@ -58,8 +59,8 @@ public static function bool UnlockDLC(
private static function bool Auto( private static function bool Auto(
KFGameInfo KFGI, KFGameInfo KFGI,
KFGameReplicationInfo KFGRI, KFGameReplicationInfo KFGRI,
out Array<class<KFWeaponDefinition> > RemoveItems, out Array<class<KFWeaponDefinition> > WeapDefs,
out Array<class<KFWeaponDefinition> > AddItems, out BoolWrapper DLCSkinUpdateRequired,
E_LogLevel LogLevel) E_LogLevel LogLevel)
{ {
local bool CustomGFxManager; local bool CustomGFxManager;
@ -79,53 +80,60 @@ private static function bool Auto(
if (CustomGFxManager) if (CustomGFxManager)
{ {
return ReplaceWeapons(KFGRI, RemoveItems, AddItems, LogLevel); return ReplaceWeapons(KFGRI, WeapDefs, DLCSkinUpdateRequired, LogLevel);
} }
else else
{ {
DLCSkinUpdateRequired.Value = false;
return ReplaceFilter(KFGI, LogLevel); return ReplaceFilter(KFGI, LogLevel);
} }
} }
private static function bool ReplaceWeapons( private static function bool ReplaceWeapons(
KFGameReplicationInfo KFGRI, KFGameReplicationInfo KFGRI,
out Array<class<KFWeaponDefinition> > RemoveItems, out Array<class<KFWeaponDefinition> > WeapDefs,
out Array<class<KFWeaponDefinition> > AddItems, out BoolWrapper DLCSkinUpdateRequired,
E_LogLevel LogLevel) E_LogLevel LogLevel)
{ {
local Array<class<KFWeaponDefinition> > WeapDefsDLCs; local class<KFWeaponDefinition> WeapDef;
local class<KFWeaponDefinition> WeapDefDLC;
local class<KFWeaponDefinition> WeapDefReplacement; local class<KFWeaponDefinition> WeapDefReplacement;
local bool Unlock, PartialUnlock; local bool Unlock, PartialUnlock;
local int Index;
`Log_TraceStatic(); `Log_TraceStatic();
`Log_Debug("Unlock by replace weapons");
Unlock = false; Unlock = false;
PartialUnlock = false; PartialUnlock = false;
DLCSkinUpdateRequired.Value = false;
WeapDefsDLCs = Trader.static.GetTraderWeapDefsDLC(KFGRI, LogLevel); for (Index = 0; Index < WeapDefs.Length; Index++)
foreach WeapDefsDLCs(WeapDefDLC)
{ {
WeapDefReplacement = PickReplacementWeapDefDLC(WeapDefDLC, LogLevel); WeapDef = WeapDefs[Index];
if (WeapDef.default.SharedUnlockId == SCU_None) continue;
WeapDefReplacement = PickReplacementWeapDefDLC(WeapDef, LogLevel);
if (WeapDefReplacement != None) if (WeapDefReplacement != None)
{ {
Unlock = true; Unlock = true;
if (AddItems.Find(WeapDefReplacement) == INDEX_NONE) DLCSkinUpdateRequired.Value = true;
if (WeapDefs.Find(WeapDefReplacement) == INDEX_NONE)
{ {
AddItems.AddItem(WeapDefReplacement); WeapDefs[Index] = WeapDefReplacement;
`Log_Debug(WeapDef @ "replaced by" @ WeapDefReplacement);
}
else
{
WeapDefs.Remove(Index--, 1);
`Log_Debug("Skip already unlocked weapon:" @ WeapDef);
} }
`Log_Debug(WeapDefDLC @ "replaced by" @ WeapDefReplacement);
} }
else else
{ {
PartialUnlock = true; PartialUnlock = true;
`Log_Warn("Can't unlock item:" @ WeapDefDLC @ "SharedUnlockId:" @ WeapDefDLC.default.SharedUnlockId); `Log_Warn("Can't unlock item:" @ WeapDef @ "SharedUnlockId:" @ WeapDef.default.SharedUnlockId);
}
if (RemoveItems.Find(WeapDefDLC) == INDEX_NONE)
{
RemoveItems.AddItem(WeapDefDLC);
} }
} }
@ -139,15 +147,15 @@ private static function bool ReplaceWeapons(
private static function class<KFWeaponDefinition> PickReplacementWeapDefDLC(class<KFWeaponDefinition> WeapDefDLC, E_LogLevel LogLevel) private static function class<KFWeaponDefinition> PickReplacementWeapDefDLC(class<KFWeaponDefinition> WeapDefDLC, E_LogLevel LogLevel)
{ {
local class<KFWeaponDefinition> WeapDef; local SWeapReplace WeapReplace;
`Log_TraceStatic(); `Log_TraceStatic();
foreach default.WeapDefDLCReplacements(WeapDef) foreach Replacements.default.DLC(WeapReplace)
{ {
if (ClassIsChildOf(WeapDef, WeapDefDLC)) if (ClassIsChildOf(WeapReplace.WeapDef, WeapDefDLC))
{ {
return WeapDef; return WeapReplace.WeapDef;
} }
} }
@ -158,6 +166,8 @@ private static function bool ReplaceFilter(KFGameInfo KFGI, E_LogLevel LogLevel)
{ {
`Log_TraceStatic(); `Log_TraceStatic();
`Log_Debug("Unlock by replace filter");
if (KFGI == None) return false; if (KFGI == None) return false;
if (KFGameInfo_VersusSurvival(KFGI) != None) if (KFGameInfo_VersusSurvival(KFGI) != None)
@ -174,32 +184,5 @@ private static function bool ReplaceFilter(KFGameInfo KFGI, E_LogLevel LogLevel)
defaultproperties defaultproperties
{ {
WeapDefDLCReplacements.Add(class'CTI_WeapDef_AutoTurret')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_BladedPistol')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_Blunderbuss')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_ChainBat')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_ChiappaRhino')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_ChiappaRhinoDual')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_CompoundBow')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_Doshinegun')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_DualBladed')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_FAMAS')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_G18')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_G36C')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_GravityImploder')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_HVStormCannon')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_IonThruster')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_Mine_Reconstructor')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_Minigun')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_MosinNagant')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_ParasiteImplanter')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_Pistol_DualG18')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_Pistol_G18C')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_Rifle_FrostShotgunAxe')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_Scythe')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_Shotgun_S12')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_ShrinkRayGun')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_ThermiteBore')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_ZedMKIII')
WeapDefDLCReplacements.Add(class'CTI_WeapDef_Zweihander')
} }

View File

@ -0,0 +1,189 @@
class WeaponReplacements extends Object;
struct SWeapReplace
{
var const class<KFWeaponDefinition> WeapDef;
var const class<KFWeaponDefinition> WeapDefParent;
var const class<KFWeapon> Weap;
var const class<KFWeapon> WeapParent;
};
var public const Array<SWeapReplace> DLC;
defaultproperties
{
DLC.Add({(
WeapDef=class'CTI_WeapDef_AutoTurret',
WeapDefParent=class'KFWeapDef_AutoTurret',
Weap=class'CTI_Weap_AutoTurret',
WeapParent=class'KFWeap_AutoTurret'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_BladedPistol',
WeapDefParent=class'KFWeapDef_BladedPistol',
Weap=class'CTI_Weap_Pistol_Bladed',
WeapParent=class'KFWeap_Pistol_Bladed'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_Blunderbuss',
WeapDefParent=class'KFWeapDef_Blunderbuss',
Weap=class'CTI_Weap_Pistol_Blunderbuss',
WeapParent=class'KFWeap_Pistol_Blunderbuss'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_ChainBat',
WeapDefParent=class'KFWeapDef_ChainBat',
Weap=class'CTI_Weap_Blunt_ChainBat',
WeapParent=class'KFWeap_Blunt_ChainBat'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_ChiappaRhino',
WeapDefParent=class'KFWeapDef_ChiappaRhino',
Weap=class'CTI_Weap_Pistol_ChiappaRhino',
WeapParent=class'KFWeap_Pistol_ChiappaRhino'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_ChiappaRhinoDual',
WeapDefParent=class'KFWeapDef_ChiappaRhinoDual',
Weap=class'CTI_Weap_Pistol_ChiappaRhinoDual',
WeapParent=class'KFWeap_Pistol_ChiappaRhinoDual'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_CompoundBow',
WeapDefParent=class'KFWeapDef_CompoundBow',
Weap=class'CTI_Weap_Bow_CompoundBow',
WeapParent=class'KFWeap_Bow_CompoundBow'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_Doshinegun',
WeapDefParent=class'KFWeapDef_Doshinegun',
Weap=class'CTI_Weap_AssaultRifle_Doshinegun',
WeapParent=class'KFWeap_AssaultRifle_Doshinegun'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_DualBladed',
WeapDefParent=class'KFWeapDef_DualBladed',
Weap=class'CTI_Weap_Pistol_DualBladed',
WeapParent=class'KFWeap_Pistol_DualBladed'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_FAMAS',
WeapDefParent=class'KFWeapDef_FAMAS',
Weap=class'CTI_Weap_AssaultRifle_FAMAS',
WeapParent=class'KFWeap_AssaultRifle_FAMAS'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_G18',
WeapDefParent=class'KFWeapDef_G18',
Weap=class'CTI_Weap_SMG_G18',
WeapParent=class'KFWeap_SMG_G18'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_G36C',
WeapDefParent=class'KFWeapDef_G36C',
Weap=class'CTI_Weap_AssaultRifle_G36C',
WeapParent=class'KFWeap_AssaultRifle_G36C'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_GravityImploder',
WeapDefParent=class'KFWeapDef_GravityImploder',
Weap=class'CTI_Weap_GravityImploder',
WeapParent=class'KFWeap_GravityImploder'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_HVStormCannon',
WeapDefParent=class'KFWeapDef_HVStormCannon',
Weap=class'CTI_Weap_HVStormCannon',
WeapParent=class'KFWeap_HVStormCannon'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_IonThruster',
WeapDefParent=class'KFWeapDef_IonThruster',
Weap=class'CTI_Weap_Edged_IonThruster',
WeapParent=class'KFWeap_Edged_IonThruster'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_MG3',
WeapDefParent=class'KFWeapDef_MG3',
Weap=class'CTI_Weap_LMG_MG3',
WeapParent=class'KFWeap_LMG_MG3'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_Mine_Reconstructor',
WeapDefParent=class'KFWeapDef_Mine_Reconstructor',
Weap=class'CTI_Weap_Mine_Reconstructor',
WeapParent=class'KFWeap_Mine_Reconstructor'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_Minigun',
WeapDefParent=class'KFWeapDef_Minigun',
Weap=class'CTI_Weap_Minigun',
WeapParent=class'KFWeap_Minigun'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_MosinNagant',
WeapDefParent=class'KFWeapDef_MosinNagant',
Weap=class'CTI_Weap_Rifle_MosinNagant',
WeapParent=class'KFWeap_Rifle_MosinNagant'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_ParasiteImplanter',
WeapDefParent=class'KFWeapDef_ParasiteImplanter',
Weap=class'CTI_Weap_Rifle_ParasiteImplanter',
WeapParent=class'KFWeap_Rifle_ParasiteImplanter'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_Pistol_DualG18',
WeapDefParent=class'KFWeapDef_Pistol_DualG18',
Weap=class'CTI_Weap_Pistol_DualG18',
WeapParent=class'KFWeap_Pistol_DualG18'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_Pistol_G18C',
WeapDefParent=class'KFWeapDef_Pistol_G18C',
Weap=class'CTI_Weap_Pistol_G18C',
WeapParent=class'KFWeap_Pistol_G18C'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_Rifle_FrostShotgunAxe',
WeapDefParent=class'KFWeapDef_Rifle_FrostShotgunAxe',
Weap=class'CTI_Weap_Rifle_FrostShotgunAxe',
WeapParent=class'KFWeap_Rifle_FrostShotgunAxe'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_Scythe',
WeapDefParent=class'KFWeapDef_Scythe',
Weap=class'CTI_Weap_Edged_Scythe',
WeapParent=class'KFWeap_Edged_Scythe'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_Shotgun_S12',
WeapDefParent=class'KFWeapDef_Shotgun_S12',
Weap=class'CTI_Weap_Shotgun_S12',
WeapParent=class'KFWeap_Shotgun_S12'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_ShrinkRayGun',
WeapDefParent=class'KFWeapDef_ShrinkRayGun',
Weap=class'CTI_Weap_ShrinkRayGun',
WeapParent=class'KFWeap_ShrinkRayGun'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_ThermiteBore',
WeapDefParent=class'KFWeapDef_ThermiteBore',
Weap=class'CTI_Weap_RocketLauncher_ThermiteBore',
WeapParent=class'KFWeap_RocketLauncher_ThermiteBore'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_ZedMKIII',
WeapDefParent=class'KFWeapDef_ZedMKIII',
Weap=class'CTI_Weap_ZedMKIII',
WeapParent=class'KFWeap_ZedMKIII'
)})
DLC.Add({(
WeapDef=class'CTI_WeapDef_Zweihander',
WeapDefParent=class'KFWeapDef_Zweihander',
Weap=class'CTI_Weap_Edged_Zweihander',
WeapParent=class'KFWeap_Edged_Zweihander'
)})
}

View File

@ -69,7 +69,7 @@ example: [b]Item=KFGame.KFWeapDef_Mac10[/b] will remove MAC10 from sale.
[*]Set [b]bDLC=True[/b] to remove DLC items. [*]Set [b]bDLC=True[/b] to remove DLC items.
[*]Use [b][CTI.AddItems][/b] to add items to the trader inventory. [*]Use [b][CTI.AddItems][/b] to add items to the trader inventory.
example: [b]Item=WeaponPack.KFWeapDef_XM25[/b] will add [url=https://steamcommunity.com/sharedfiles/filedetails/?id=1147408497]XM25[/url] to sale. example: [b]Item=WeaponPackExt.KFWeapDef_XM25[/b] will add [url=https://steamcommunity.com/sharedfiles/filedetails/?id=1147408497]XM25[/url] to sale.
[/list] [/list]
❗️ Note that if you need an empty list anywhere (for example, you don't want to delete some of the traders's weapons), leave at least one line there: ❗️ Note that if you need an empty list anywhere (for example, you don't want to delete some of the traders's weapons), leave at least one line there: