diff --git a/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd.sqf b/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd.sqf index e7955c9e..0ef71452 100644 --- a/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd.sqf +++ b/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd.sqf @@ -120,11 +120,24 @@ if !(isNull EPOCH_lastNPCtradeTarget) then { _CurControl lbDelete _id; _cryptoCount = 0; _sizeOut = lbSize _PlayerItemsOutBox; + + _BlackMarketPurchaseMulti = ["CfgBlackMarket", "BlackMarketPurchaseMulti", 1] call EPOCH_fnc_returnConfigEntryV2; + _BlackMarketSellMulti = ["CfgBlackMarket", "BlackMarketSellMulti", 1] call EPOCH_fnc_returnConfigEntryV2; + _Blackmarket_SpecialPrices = ["CfgBlackMarket", "Blackmarket_SpecialPrices", []] call EPOCH_fnc_returnConfigEntryV2; + if (_sizeOut > 0) then { for "_i" from 0 to (_sizeOut - 1) do { _item = lbData [_PlayerItemsOutBox, _i]; _rounds = lbValue [_PlayerItemsOutBox, _i]; _worth = getNumber (_config >> _item >> "price"); + if (EPOCH_lastNPCtradeTarget getvariable ["Epoch_BlackMarketTrader",false]) then { + _worth = _worth * _BlackMarketSellMulti; + { + if (_item isEqualTo (_x select 0)) exitwith { + _worth = _x select 1; + }; + } foreach _Blackmarket_SpecialPrices; + }; _maxrnd = 1; if ([_item,"cfgMagazines"] call Epoch_fnc_isAny) then { _maxrnd = getnumber (configfile >> "cfgMagazines" >> _item >> "count"); @@ -144,6 +157,14 @@ if !(isNull EPOCH_lastNPCtradeTarget) then { _itemTax = getNumber (_config >> _item >> "tax"); _tax = _worth * (EPOCH_taxRate + _itemTax); _worth = ceil(_worth + _tax); + if (EPOCH_lastNPCtradeTarget getvariable ["Epoch_BlackMarketTrader",false]) then { + _worth = _worth * _BlackMarketPurchaseMulti; + { + if (_item isEqualTo (_x select 0)) exitwith { + _worth = _x select 2; + }; + } foreach _Blackmarket_SpecialPrices; + }; _maxrnd = 1; if ([_item,"cfgMagazines"] call Epoch_fnc_isAny) then { _maxrnd = getnumber (configfile >> "cfgMagazines" >> _item >> "count"); diff --git a/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd2.sqf b/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd2.sqf index f6832e3e..ebac3ac9 100644 --- a/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd2.sqf +++ b/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd2.sqf @@ -67,6 +67,10 @@ if !(isNull EPOCH_lastNPCtradeTarget) then { }; }; if (_allowAdd) then { + _BlackMarketPurchaseMulti = ["CfgBlackMarket", "BlackMarketPurchaseMulti", 1] call EPOCH_fnc_returnConfigEntryV2; + _BlackMarketSellMulti = ["CfgBlackMarket", "BlackMarketSellMulti", 1] call EPOCH_fnc_returnConfigEntryV2; + _Blackmarket_SpecialPrices = ["CfgBlackMarket", "Blackmarket_SpecialPrices", []] call EPOCH_fnc_returnConfigEntryV2; + _maxrnd = 1; if ([_uiItem,"cfgMagazines"] call Epoch_fnc_isAny) then { _maxrnd = getnumber (configfile >> "cfgMagazines" >> _uiItem >> "count"); @@ -138,6 +142,14 @@ if !(isNull EPOCH_lastNPCtradeTarget) then { _itemTax = getNumber (_config >> _item >> "tax"); _tax = _worth * (EPOCH_taxRate + _itemTax); _worth = ceil(_worth + _tax); + if (EPOCH_lastNPCtradeTarget getvariable ["Epoch_BlackMarketTrader",false]) then { + _worth = _worth * _BlackMarketPurchaseMulti; + { + if (_item isEqualTo (_x select 0)) exitwith { + _worth = _x select 2; + }; + } foreach _Blackmarket_SpecialPrices; + }; _maxrnd = 1; if ([_item,"cfgMagazines"] call Epoch_fnc_isAny) then { _maxrnd = getnumber (configfile >> "cfgMagazines" >> _item >> "count"); diff --git a/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd3.sqf b/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd3.sqf index a120e5a7..62eb2ac0 100644 --- a/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd3.sqf +++ b/Sources/epoch_code/compile/traders/EPOCH_npcTraderAdd3.sqf @@ -53,6 +53,9 @@ if (isClass (_config >> _uiItem)) then { _cryptoCount = 0; _sizeOut = lbSize _TraderItemsOutBox; if (_sizeOut > 0) then { + _BlackMarketPurchaseMulti = ["CfgBlackMarket", "BlackMarketPurchaseMulti", 1] call EPOCH_fnc_returnConfigEntryV2; + _BlackMarketSellMulti = ["CfgBlackMarket", "BlackMarketSellMulti", 1] call EPOCH_fnc_returnConfigEntryV2; + _Blackmarket_SpecialPrices = ["CfgBlackMarket", "Blackmarket_SpecialPrices", []] call EPOCH_fnc_returnConfigEntryV2; for "_i" from 0 to (_sizeOut - 1) do { _item = lbData [_TraderItemsOutBox, _i]; _rounds = lbValue [_TraderItemsOutBox, _i]; @@ -60,6 +63,14 @@ if (isClass (_config >> _uiItem)) then { _itemTax = getNumber (_config >> _item >> "tax"); _tax = _worth * (EPOCH_taxRate + _itemTax); _worth = ceil (_worth + _tax); + if (EPOCH_lastNPCtradeTarget getvariable ["Epoch_BlackMarketTrader",false]) then { + _worth = _worth * _BlackMarketPurchaseMulti; + { + if (_item isEqualTo (_x select 0)) exitwith { + _worth = _x select 2; + }; + } foreach _Blackmarket_SpecialPrices; + }; _maxrnd = 1; if ([_item,"cfgMagazines"] call Epoch_fnc_isAny) then { _maxrnd = getnumber (configfile >> "cfgMagazines" >> _item >> "count"); diff --git a/Sources/epoch_config/Configs/CfgBlackMarket.hpp b/Sources/epoch_config/Configs/CfgBlackMarket.hpp new file mode 100644 index 00000000..829fb1f7 --- /dev/null +++ b/Sources/epoch_config/Configs/CfgBlackMarket.hpp @@ -0,0 +1,27 @@ +class CfgBlackMarket +{ + StaticBlackMarketIdx[] = {}; // Static Traders with this index (starts from 0) defined in epoch_server_settings\configs\maps\worldname -> staticNpcPos + // will always get set to BlackMarkets + // Example: {0,2} will set the 1st and 3rd defined static trader as a BlackMarket + + BlackMarketTraderCount = 2; // 2 Random Traders will be set to BlackMarkets (change every Restart) + ShowBlackMarketTraders = "true"; // Show Marker for Blackmarket Traders? + BlackMarketMarkerColor = "ColorRed"; // Marker color for Blackmarket Traders (if ShowBlackMarketTraders = "true") + BlackMarketPurchaseMulti = 5; // Multi on purchase on top of the default price + BlackMarketSellMulti = 0.8; // Multi on Sell for the default price + BlackMarketItemsCount = 50; // Count of items for each class (will get refilled after each purchase anyway!) + + BlackMarketUseLootList = "true"; // Use the Epoch LootList to prepare the available Items within the BlackMarket + BlackMarketExtraItems[] = { // Items in BlackMarket, that are not within the LootTable +// "MBK_01_EPOCH", // Can be a Vehicle +// "ItemComboLock" // Or Items / Magazines + }; + + Blackmarket_SpecialPrices[] = { // Do not use the default Multis, but this special prices for listed items +// {"SatchelCharge_Remote_Mag",50,500} // Sell Price = 50 | Purchase Price = 500 + }; + + Blackmarket_BlackList[] = { // These classes are not listed in Blackmarket (doesnt matter if in Loot or not) +// "ItemGoldBar10oz" + }; +}; \ No newline at end of file diff --git a/Sources/epoch_config/sandbox_config.hpp b/Sources/epoch_config/sandbox_config.hpp index b5d44af7..26d81507 100644 --- a/Sources/epoch_config/sandbox_config.hpp +++ b/Sources/epoch_config/sandbox_config.hpp @@ -66,6 +66,7 @@ showHUD[] = true // Vehicle display panels }; +#include "Configs\CfgBlackMarket.hpp" #include "Configs\CfgServicePoint.hpp" #include "Configs\CfgItemSort.hpp" #include "Configs\CfgTraderMissions.hpp" diff --git a/Sources/epoch_server/compile/epoch_traders/EPOCH_server_loadTraders.sqf b/Sources/epoch_server/compile/epoch_traders/EPOCH_server_loadTraders.sqf index 344c124c..bd193232 100644 --- a/Sources/epoch_server/compile/epoch_traders/EPOCH_server_loadTraders.sqf +++ b/Sources/epoch_server/compile/epoch_traders/EPOCH_server_loadTraders.sqf @@ -159,6 +159,7 @@ for "_i" from 0 to (_maxTraderLimit-1) do { _markers = ["StaticTrader",_pos] call EPOCH_server_createGlobalMarkerSet; _agent setVariable["MARKER_REF", _markers]; }; + EPOCH_StaticTraders pushback _agent; } else { // Spawn dynamic traders @@ -200,6 +201,7 @@ for "_i" from 0 to (_maxTraderLimit-1) do { _markers = ["DynamicTrader",_pos] call EPOCH_server_createGlobalMarkerSet; _agent setVariable["MARKER_REF", _markers]; }; + Epoch_DynamicTraders pushback _agent; } else { // diag_log format ["EPOCH_DEBUG: TraderSlot: %1 | Supressed Trader Load - Too much items (%2) and will respawn",_i,count (_arr select 0)]; diff --git a/Sources/epoch_server/compile/epoch_traders/EPOCH_server_spawnTraders.sqf b/Sources/epoch_server/compile/epoch_traders/EPOCH_server_spawnTraders.sqf index 5c423ccd..24780ea1 100644 --- a/Sources/epoch_server/compile/epoch_traders/EPOCH_server_spawnTraders.sqf +++ b/Sources/epoch_server/compile/epoch_traders/EPOCH_server_spawnTraders.sqf @@ -120,6 +120,7 @@ for "_i" from 1 to _spawnCount do { }; EPOCH_Traders pushback _agent; _Traderblocks pushback [getpos _agent, _TraderMinDistance]; + Epoch_DynamicTraders pushback _agent; }; }; }; diff --git a/Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeNPCTrade.sqf b/Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeNPCTrade.sqf index 01882696..04f42dea 100644 --- a/Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeNPCTrade.sqf +++ b/Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeNPCTrade.sqf @@ -24,6 +24,10 @@ params ["_trader","_itemsIn","_itemsOut","_player",["_token","",[""]] ]; _playerUID = getplayeruid _player; _EnableTempVehTrade = ["CfgEpochClient", "EnableTempVehTrade", false] call EPOCH_fnc_returnConfigEntryV2; +_BlackMarketPurchaseMulti = ["CfgBlackMarket", "BlackMarketPurchaseMulti", 1] call EPOCH_fnc_returnConfigEntryV2; +_BlackMarketSellMulti = ["CfgBlackMarket", "BlackMarketSellMulti", 1] call EPOCH_fnc_returnConfigEntryV2; +_Blackmarket_SpecialPrices = ["CfgBlackMarket", "Blackmarket_SpecialPrices", []] call EPOCH_fnc_returnConfigEntryV2; + _serverSettingsConfig = configFile >> "CfgEpochServer"; _vehicleSold = false; _vehicleBought = false; @@ -63,6 +67,14 @@ if (_slot != -1) then { _x params ["_item","_itemQty"]; if (isClass (_config >> _item)) then { _itemWorth = getNumber(_config >> _item >> "price"); + if (_trader getvariable ["Epoch_BlackMarketTrader",false]) then { + _itemWorth = _itemWorth * _BlackMarketSellMulti; + { + if (_item isEqualTo (_x select 0)) exitwith { + _itemWorth = _x select 1; + }; + } foreach _Blackmarket_SpecialPrices; + }; _maxrnd = 1; if ([_item,"cfgMagazines"] call Epoch_fnc_isAny) then { _maxrnd = getnumber (configfile >> "cfgMagazines" >> _item >> "count"); @@ -157,6 +169,14 @@ if (_slot != -1) then { _itemTax = getNumber(_config >> _item >> "tax"); _tax = _itemWorth * (EPOCH_taxRate + _itemTax); _itemWorth = ceil (_itemWorth + _tax); + if (_trader getvariable ["Epoch_BlackMarketTrader",false]) then { + _itemWorth = _itemWorth * _BlackMarketPurchaseMulti; + { + if (_item isEqualTo (_x select 0)) exitwith { + _itemWorth = _x select 2; + }; + } foreach _Blackmarket_SpecialPrices; + }; _maxrnd = 1; if ([_item,"cfgMagazines"] call Epoch_fnc_isAny) then { _maxrnd = getnumber (configfile >> "cfgMagazines" >> _item >> "count"); @@ -323,9 +343,11 @@ if (_slot != -1) then { }; _tradeTotal = _tradeIn + _tradeOut; if !(_returnIn isequalto [] && _returnOut isEqualTo []) then { - _trader setVariable["AI_ITEMS", [_itemClasses, _itemQtys], true]; - _objHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _slot]; - ["AI_ITEMS", _objHiveKey, EPOCH_expiresAIdata, [_itemClasses, _itemQtys]] call EPOCH_fnc_server_hiveSETEX; + if !(_trader getvariable ["Epoch_BlackMarketTrader",false]) then { + _trader setVariable["AI_ITEMS", [_itemClasses, _itemQtys], true]; + _objHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _slot]; + ["AI_ITEMS", _objHiveKey, EPOCH_expiresAIdata, [_itemClasses, _itemQtys]] call EPOCH_fnc_server_hiveSETEX; + }; if !(_tradeTotal isequalto 0) then { _playerCryptoLimit = EPOCH_customVarLimits select _cIndex; _playerCryptoLimit params ["_playerCryptoLimitMax","_playerCryptoLimitMin"]; diff --git a/Sources/epoch_server/init/server_init.sqf b/Sources/epoch_server/init/server_init.sqf index 9710153e..78367779 100644 --- a/Sources/epoch_server/init/server_init.sqf +++ b/Sources/epoch_server/init/server_init.sqf @@ -182,12 +182,110 @@ call EPOCH_server_createTeleport; diag_log "Epoch: Loading NPC traders"; EPOCH_Traders = []; +EPOCH_StaticTraders = []; +Epoch_DynamicTraders = []; EPOCH_NPCSlotsLimit call EPOCH_server_loadTraders; diag_log "Epoch: Spawning NPC traders"; call EPOCH_server_spawnTraders; publicvariable "EPOCH_Traders"; +// Start Black Market Traders +_StaticBlackMarketIdx = ["CfgBlackMarket", "StaticBlackMarketIdx", []] call EPOCH_fnc_returnConfigEntryV2; +_BlackMarketTraderCount = ["CfgBlackMarket", "BlackMarketTraderCount", 0] call EPOCH_fnc_returnConfigEntryV2; +_ShowBlackMarketTraders = ["CfgBlackMarket", "ShowBlackMarketTraders", true] call EPOCH_fnc_returnConfigEntryV2; +_BlackMarketMarkerColor = ["CfgBlackMarket", "BlackMarketMarkerColor", "ColorRed"] call EPOCH_fnc_returnConfigEntryV2; +_BlackMarketItemsCount = ["CfgBlackMarket", "BlackMarketItemsCount", 100] call EPOCH_fnc_returnConfigEntryV2; +_BlackMarketUseLootList = ["CfgBlackMarket", "BlackMarketUseLootList", true] call EPOCH_fnc_returnConfigEntryV2; +_BlackMarketExtraItems = ["CfgBlackMarket", "BlackMarketExtraItems", []] call EPOCH_fnc_returnConfigEntryV2; +_Blackmarket_BlackList = ["CfgBlackMarket", "Blackmarket_BlackList", []] call EPOCH_fnc_returnConfigEntryV2; + + // Start Calculate The Items for BlackMarkets + _lootTableIndex = if (EPOCH_modCUPVehiclesEnabled) then {if (EPOCH_mod_madArma_Enabled) then {3} else {1}} else {if (EPOCH_mod_madArma_Enabled) then {2} else {0}}; + _lootTableClass = ["CfgLootTable","CfgLootTable_CUP","CfgLootTable_MAD","CfgLootTable_MADCUP"] select _lootTableIndex; + if !(EPOCH_forcedLootSpawnTable isEqualTo "") then { + _lootTableClass = EPOCH_forcedLootSpawnTable; + }; + _AllowedSpawnItemList = []; + _PricingList = (missionConfigFile >> "CfgPricing") call BIS_fnc_getCfgSubClasses; + if (_BlackMarketUseLootList) then { + _noprice = []; + _fncadditems = { + _itemsarray = getarray (_this >> "items"); + { + if !((_x select 1) isEqualTo 0) then { + if ((_x select 0 select 1) isequalto "CfgLootTable") then { + (configfile >> _lootTableClass >> (_x select 0 select 0)) call _fncadditems; + } + else { + if ((_x select 0 select 0) in _PricingList) then { + _AllowedSpawnItemList pushbackunique (_x select 0 select 0); + } + else { + if !((_x select 0 select 0) in _noprice) then { + diag_log format ["%1 is in your LootTable, but not have a price!!!",(_x select 0 select 0)]; + _noprice pushback (_x select 0 select 0); + }; + }; + }; + }; + } foreach _itemsarray; + }; + { + _tables = (getarray (_x >> "tables")); + { + _check = _x; + if !(_check isEqualType []) then { + _check = [_x]; + }; + (configfile >> _lootTableClass >> (_check select 0)) call _fncadditems; + } foreach _tables; + } foreach ("true" configclasses (configfile >> "CfgMainTable")); + }; + _arrtmp = +_AllowedSpawnItemList; + _arrtmp = _arrtmp + (_BlackMarketExtraItems select {_x in _PricingList}); + _arrtmp = _arrtmp - _Blackmarket_BlackList; + _arrcnttmp = []; + { + _arrcnttmp pushback _BlackMarketItemsCount; + } foreach _arrtmp; + // Convert Starter Trader Magazines from mags to rounds + { + _maxrnd = 1; + if ([_x,"cfgMagazines"] call Epoch_fnc_isAny) then { + _maxrnd = getnumber (configfile >> "cfgMagazines" >> _x >> "count"); + }; + if (_maxrnd > 1) then { + _currentStock = (_arrcnttmp select _foreachindex)*_maxrnd; + _arrcnttmp set [_foreachindex, _currentStock]; + }; + } foreach _arrtmp; + + // Check the spawned BlackMarket Traders and handle them + _BlackMarketTraders = []; + { + if (_foreachindex in _StaticBlackMarketIdx) then { + _BlackMarketTraders pushback _x; + }; + } foreach EPOCH_StaticTraders; + for "_i" from 1 to _BlackMarketTraderCount do { + if (count Epoch_DynamicTraders > 0) then { + _trader = selectrandom Epoch_DynamicTraders; + Epoch_DynamicTraders = Epoch_DynamicTraders - [_trader]; + _BlackMarketTraders pushback _trader; + }; + }; + + { + if (_ShowBlackMarketTraders) then { + _markers = ["StaticTrader",getpos _x,"BlackMarket Trader"] call EPOCH_server_createGlobalMarkerSet; + {_x setmarkercolor _BlackMarketMarkerColor;} foreach _markers; + }; + _x setVariable ["AI_ITEMS", [_arrtmp,_arrcnttmp], true]; + _x setvariable ["Epoch_BlackMarketTrader",true,true]; + } foreach _BlackMarketTraders; +// End Black Market Traders + if (([_serverSettingsConfig, "ReplaceCarService", false] call EPOCH_fnc_returnConfigEntry)) then { { private _shop = "paintshop" createvehicle (getpos _x);