Trader Config + Reserved Vehicle Slots

This commit is contained in:
He-Man 2018-01-07 02:41:38 +01:00
parent ec3953435a
commit 773d863c58
6 changed files with 187 additions and 186 deletions

View File

@ -54,6 +54,7 @@ forceRestartTime = 14400; // 4 hour restarts
};
// vehicles - Max vehicle slots is calculated from per vehicle limits below. Warning! Higher the number lower the performance.
ReservedVehSlots = 50; // Reserved Vehicle Slots (only needed, if you store non-Epoch Vehicles in the Database)
disableAutoRefuel = "true"; // Removes auto refuel from all buildings at server startup.
simulationHandlerOld = "false"; // When enabled this feature disables simulation on vehicles that are not nea players. Can help improve client fps at the cost of server fps.
VehLockMessages = "true"; // Give players a hint, that the Vehicle is locked / unlocked
@ -121,7 +122,24 @@ forceRestartTime = 14400; // 4 hour restarts
};
NPCSlotsLimit = 30; // Max number of traders static or dynamic. Warning! Higher the number lower performance.
forceStaticTraders = "true"; // disables traders moving from work to home
TraderGodMode = "false"; // If true, Trader can not be killed by Players
storedVehicleLimit = 15; // Vehicles more than x stored in ALL Traders will automatically be deleted on Restart.
StaticTraderItemPurge[] = {100,15}; // {ItemCount,ReducePercent} - If a static trader have more than x different items, on restart the items will be reduced by y percent
DynamicTraderRespawnCount = 100 // If a dynamic Trader have more than x different Items, he will respawn on another Spot (with start Items)
TraderItemCountPerItem[] = {50,5}; // If the Trader has more than x pieces of an Item, it will be reduced to y pieces (on Restart)
TraderItemsDeleteInstant[] = { // List of Items, that will be deleted from Trader instant after sell
// "ItemVehDoc1",
// "ItemVehDoc2",
// "ItemVehDoc3",
// "ItemVehDoc4"
};
TraderItemsDeleteRestart[] = { // List of Items, that will be deleted from Trader on Restart
// "ItemLockbox",
// "ItemSafe",
// "ItemGoldBar10oz"
};
// Spawntables
forcedVehicleSpawnTable = ""; // leave blank for default. Options: "allowedVehiclesList","allowedVehiclesList_CUP","allowedVehiclesList_MAD","allowedVehiclesList_MADCUP"
forcedLootSpawnTable = ""; // leave blank for default. Options: "CfgLootTable","CfgLootTable_CUP","CfgLootTable_MAD","CfgLootTable_MADCUP"

View File

@ -29,6 +29,7 @@ if (!isNull _trader) then {
[_player, "UAV"] call EPOCH_server_triggerEvent;
_objHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _slot];
["AI", _objHiveKey] call EPOCH_fnc_server_hiveDEL;
["AI_ITEMS", _objHiveKey] call EPOCH_fnc_server_hiveDEL;
};
// send karma stat to seller
_kIndex = EPOCH_communityStats find "Karma";

View File

@ -13,7 +13,10 @@
https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_server/compile/epoch_traders/EPOCH_server_loadTraders.sqf
*/
//[[[cog import generate_private_arrays ]]]
private ["_agent","_aiTables","_arr","_class","_config","_currentStock","_existingStock","_home","_indexStock","_limit","_markers","_objHiveKey","_pos","_randomAIUniform","_response","_schedule","_serverSettingsConfig","_staticTrader","_staticTradersArrCount","_staticTradersArray","_storedVehicleLimit","_toBeRemoved","_traderSlotIndex","_work"];
private [ "_TraderGodMode","_StaticTraderItemPurge","_DynamicTraderRespawnCount","_TraderItemsDeleteRestart","_TraderInit","_TraderItemsClean","_newstock","_agent","_aiTables",
"_arr","_config","_currentStock","_existingStock","_indexStock","_limit","_markers","_objHiveKey","_pos","_randomAIUniform","_response","_response2","_schedule",
"_serverSettingsConfig","_staticTrader","_staticTradersArrCount","_staticTradersArray","_storedVehicleLimit","_traderSlotIndex","_work","_arrchanged","_deleteat"
];
//[[[end]]]
params [["_maxTraderLimit",0]];
@ -23,208 +26,186 @@ _config = (configFile >> "CfgEpoch" >> worldName);
_staticTradersArray append getArray(_config >> "staticNpcPos");
_staticTradersArrCount = count _staticTradersArray;
_aiTables = getArray(_config >> "traderUniforms");
_serverSettingsConfig = configFile >> "CfgEpochServer";
_TraderGodMode = [_serverSettingsConfig, "TraderGodMode", false] call EPOCH_fnc_returnConfigEntry;
_storedVehicleLimit = [_serverSettingsConfig, "storedVehicleLimit", 20] call EPOCH_fnc_returnConfigEntry;
_StaticTraderItemPurge = [_serverSettingsConfig, "StaticTraderItemPurge", []] call EPOCH_fnc_returnConfigEntry;
_DynamicTraderRespawnCount = [_serverSettingsConfig, "DynamicTraderRespawnCount", 150] call EPOCH_fnc_returnConfigEntry;
_TraderItemCountPerItem = [_serverSettingsConfig, "TraderItemCountPerItem", [100,100]] call EPOCH_fnc_returnConfigEntry;
_TraderItemsDeleteRestart = [_serverSettingsConfig, "TraderItemsDeleteRestart", []] call EPOCH_fnc_returnConfigEntry;
_TraderInit = {
addToRemainsCollector[_this];
_this allowdamage !_TraderGodMode;
_this addUniform _randomAIUniform;
_this setDir _dir;
_this setVariable ["AI_SLOT", _i, true];
_this setVariable ["AI_ITEMS", _arr, true];
_this disableAI "FSM";
_this setBehaviour "CARELESS";
_this setCombatMode "RED";
_this setSkill 0;
_this addEventHandler ["Killed", { _this call EPOCH_server_traderKilled; }];
};
_TraderItemsClean = {
private ["_idx","_delete","_k"];
_idx = 0;
for "_k" from 1 to (count (_arr select 0)) do {
_delete = false;
_item = _arr select 0 select _idx;
_limit = ["CfgTraderLimits", _item, 100] call EPOCH_fnc_returnConfigEntryV2;
_currentStock = (_arr select 1) param[_idx, 0];
if (_currentStock >= (_TraderItemCountPerItem select 0)) then {
_currentStock = _TraderItemCountPerItem select 1;
(_arr select 1) set [_idx,_currentStock];
_arrchanged = true;
};
if (_limit == 0 || _currentStock == 0) then {
// diag_log format ["EPOCH_DEBUG: TraderSlot: %1 | Removed %2 from Trader | _limit: %3 | _currentStock: %4",_i,str _item, _limit,_currentStock];
_arrchanged = true;
_delete = true;
}
else {
if (_item in _TraderItemsDeleteRestart) then {
// diag_log format ["EPOCH_DEBUG: TraderSlot: %1 | Removed %2 from Trader (Items to remove on Restart)",_i,str _item];
_arrchanged = true;
_delete = true;
}
else {
if (_currentStock > _limit) then {
_arrchanged = true;
(_arr select 1) set [_idx,_limit];
_currentStock = _limit;
};
if (_item isKindOf "Air" || _item isKindOf "Ship" || _item isKindOf "LandVehicle" || _item isKindOf "Tank") then {
_newstock = 0;
for "_k" from 1 to _currentStock do {
if (EPOCH_storedVehicleCount < _storedVehicleLimit) then {
_newstock = _newstock + 1;
EPOCH_storedVehicleCount = EPOCH_storedVehicleCount + 1;
if !(_item in EPOCH_traderStoredVehicles) then {
EPOCH_traderStoredVehicles pushBack _item;
EPOCH_traderStoredVehiclesCnt pushBack 1;
}
else {
_indexStock = EPOCH_traderStoredVehicles find _item;
if (_indexStock != -1) then {
_existingStock = EPOCH_traderStoredVehiclesCnt select _indexStock;
EPOCH_traderStoredVehiclesCnt set [_indexStock, (_existingStock + 1)];
};
};
};
};
if !(_newstock == _currentStock) then {
_arrchanged = true;
if (_newstock > 0) then {
// diag_log format ["EPOCH_DEBUG: TraderSlot: %1 | Changed stock of %2 from Trader | _currentStock: %3 | _newstock: %4 | EPOCH_storedVehicleCount: %5 | _storedVehicleLimit: %6",_i,str _item,_currentStock,_newstock,EPOCH_storedVehicleCount,_storedVehicleLimit];
(_arr select 1) set [_idx,_newstock];
}
else {
// diag_log format ["EPOCH_DEBUG: TraderSlot: %1 | Removed %2 from Trader | EPOCH_storedVehicleCount: %3 | _storedVehicleLimit: %4",_i,str _item,EPOCH_storedVehicleCount,_storedVehicleLimit];
_delete = true;
};
};
};
};
};
if (_delete) then {
(_arr select 0) deleteat _idx;
(_arr select 1) deleteat _idx;
}
else {
_idx = _idx + 1;
};
};
};
EPOCH_storedVehicleCount = 0;
for "_i" from 0 to (_maxTraderLimit-1) do {
_traderSlotIndex = EPOCH_TraderSlots pushBack _i;
_randomAIUniform = selectRandom _aiTables;
_arr = [[], []];
_arrchanged = false;
_objHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _i];
_response = ["AI_ITEMS", _objHiveKey] call EPOCH_fnc_server_hiveGETRANGE;
if ((_response select 0) == 1 && (_response select 1) isEqualType []) then {
_arr = (_response select 1);
if (_arr isEqualTo []) then {
_arr = [[], []];
};
};
if (_arr isEqualTo [[], []]) then{
_arr = EPOCH_starterTraderItems;
_arrchanged = true;
};
call _TraderItemsClean;
// Spawn static traders first
if (_staticTradersArrCount > 0 && _i < _staticTradersArrCount) then {
_staticTrader = _staticTradersArray select _i;
_staticTrader params ["_class","_pos","_dir"];
_agent = createAgent [_class, _pos, [], 0, "CAN_COLLIDE"];
_randomAIUniform = selectRandom _aiTables;
_agent addUniform _randomAIUniform;
_agent setDir _dir;
_agent setPosATL _pos;
_agent setVariable ["AI_SLOT", _i, true];
_agent disableAI "FSM";
_agent setBehaviour "CARELESS";
_agent setCombatMode "RED";
_agent setSkill 0;
_agent addEventHandler ["Killed", { _this call EPOCH_server_traderKilled; }];
_arr = [[], []];
_objHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _i];
_response = ["AI_ITEMS", _objHiveKey] call EPOCH_fnc_server_hiveGETRANGE;
if ((_response select 0) == 1 && (_response select 1) isEqualType []) then {
_arr = (_response select 1);
if (_arr isEqualTo []) then {
_arr = [[], []];
if (count (_arr select 0) > (_StaticTraderItemPurge select 0)) then {
// diag_log format ["EPOCH_DEBUG: TraderSlot: %1 | Cleaning %2 Items from Trader | before: %3",_i,((count (_arr select 0))*(_StaticTraderItemPurge select 1)/100), count (_arr select 0)];
_arrchanged = true;
for "_j" from 1 to ((count (_arr select 0))*(_StaticTraderItemPurge select 1)/100) do {
_deleteat = (round random (count (_arr select 0)-1));
(_arr select 0) deleteAt _deleteat;
(_arr select 1) deleteAt _deleteat;
};
_toBeRemoved = [];
// count vehicles
{
_limit = ["CfgTraderLimits", _x, 100] call EPOCH_fnc_returnConfigEntryV2;
_currentStock = (_arr select 1) param[_forEachIndex, 0];
if (_limit == 0) then {
// mark for removal since limit is 0
_toBeRemoved pushBack _forEachIndex;
_currentStock = 0;
} else {
// lower to limit current qty is over limit
if (_currentStock > _limit) then {
(_arr select 1) set [_forEachIndex,_limit];
_currentStock = _limit;
};
};
if (_x isKindOf "Air" || _x isKindOf "Ship" || _x isKindOf "LandVehicle" || _x isKindOf "Tank") then {
if (EPOCH_storedVehicleCount <= _storedVehicleLimit) then {
EPOCH_storedVehicleCount = EPOCH_storedVehicleCount + _currentStock;
// Count how many of this vehicle are in stock at any trader.
if !(_x in EPOCH_traderStoredVehicles) then {
EPOCH_traderStoredVehicles pushBack _x;
EPOCH_traderStoredVehiclesCnt pushBack _currentStock;
} else {
_indexStock = EPOCH_traderStoredVehicles find _x;
if (_indexStock != -1) then {
_existingStock = EPOCH_traderStoredVehiclesCnt select _indexStock;
EPOCH_traderStoredVehiclesCnt set [_indexStock, (_existingStock + _currentStock)];
};
};
} else {
_toBeRemoved pushBack _forEachIndex;
};
};
} forEach (_arr select 0);
// remove any marked for removal
{
(_arr select 0) deleteAt _x;
(_arr select 1) deleteAt _x
} forEach _toBeRemoved;
};
if (_arr isEqualTo [[], []]) then{
_arr = EPOCH_starterTraderItems;
EPOCH_TraderSlots deleteAt _traderSlotIndex;
_agent = createAgent [_class, _pos, [], 0, "CAN_COLLIDE"];
_agent call _TraderInit;
_agent setPosATL _pos;
if (_arrchanged) then {
// diag_log format ["EPOCH_DEBUG: TraderSlot: %1 | Saved",_i];
["AI_ITEMS", _objHiveKey, EPOCH_expiresAIdata, _arr] call EPOCH_fnc_server_hiveSETEX;
};
_agent setVariable ["AI_ITEMS", _arr, true];
EPOCH_TraderSlots deleteAt _traderSlotIndex;
if (EPOCH_SHOW_TRADERS) then {
_markers = ["StaticTrader",_pos] call EPOCH_server_createGlobalMarkerSet;
_agent setVariable["MARKER_REF", _markers];
};
} else {
}
else {
// Spawn dynamic traders
_objHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _i];
_response = ["AI", _objHiveKey] call EPOCH_fnc_server_hiveGETRANGE;
if ((_response select 0) == 1 && (_response select 1) isEqualType [] && !((_response select 1) isEqualTo [])) then {
_arr = (_response select 1);
_class = _arr select 0; //"C_man_1"
_home = _arr select 1;
_work = _arr select 2;
_response2 = ["AI", _objHiveKey] call EPOCH_fnc_server_hiveGETRANGE;
if ((_response2 select 0) == 1 && (_response2 select 1) isEqualType [] && !((_response2 select 1) isEqualTo [])) then {
(_response2 select 1) params ["_class","_home","_work"];
if (_home isEqualType [] && _work isEqualType []) then {
// check schedule
_pos = _home;
_schedule = [9, 17];
if ((_work select 1) isEqualType []) then {
_schedule = _work select 1;
}
else {
diag_log format ["DEBUG INVAILD SCHEDULE: SLOT: %1 CLASS: %2 POS: %3 WORK: %4", _i, _class, _pos, _work];
// diag_log format ["DEBUG INVAILD SCHEDULE: SLOT: %1 CLASS: %2 POS: %3 WORK: %4", _i, _class, _pos, _work];
};
if (daytime > (_schedule select 0) && daytime < (_schedule select 1)) then {
_pos = (_work select 0);
};
_agent = createAgent [_class, _pos, [], 0, "NONE"];
addToRemainsCollector[_agent];
_randomAIUniform = selectRandom _aiTables;
_agent addUniform _randomAIUniform;
// _agent enableSimulationGlobal false;
_agent setPos _pos;
_agent addEventHandler ["Killed", { _this call EPOCH_server_traderKilled; }];
if !(EPOCH_forceStaticTraders) then {
[_agent, _home, _work] execFSM "\epoch_server\system\Trader_brain.fsm";
};
_agent setVariable ["AI_SLOT", _i, true];
_arr = [[],[]];
_objHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _i];
_response = ["AI_ITEMS", _objHiveKey] call EPOCH_fnc_server_hiveGETRANGE;
if ((_response select 0) == 1 && (_response select 1) isEqualType []) then {
_arr = (_response select 1);
if (_arr isEqualTo []) then {
_arr = [[], []];
};
_toBeRemoved = [];
// count vehicles
{
_limit = ["CfgTraderLimits", _x, 100] call EPOCH_fnc_returnConfigEntryV2;
_currentStock = (_arr select 1) param[_forEachIndex, 0];
if (_limit == 0) then {
// mark for removal since limit is 0
_toBeRemoved pushBack _forEachIndex;
_currentStock = 0;
} else {
// lower to limit current qty is over limit
if (_currentStock > _limit) then {
(_arr select 1) set [_forEachIndex,_limit];
_currentStock = _limit;
};
};
if (_x isKindOf "Air" || _x isKindOf "Ship" || _x isKindOf "LandVehicle" || _x isKindOf "Tank") then {
if (EPOCH_storedVehicleCount <= _storedVehicleLimit) then {
EPOCH_storedVehicleCount = EPOCH_storedVehicleCount + _currentStock;
// Count how many of this vehicle are in stock at any trader.
if !(_x in EPOCH_traderStoredVehicles) then {
EPOCH_traderStoredVehicles pushBack _x;
EPOCH_traderStoredVehiclesCnt pushBack _currentStock;
} else {
_indexStock = EPOCH_traderStoredVehicles find _x;
if (_indexStock != -1) then {
_existingStock = EPOCH_traderStoredVehiclesCnt select _indexStock;
EPOCH_traderStoredVehiclesCnt set [_indexStock, (_existingStock + _currentStock)];
};
};
} else {
_toBeRemoved pushBack _forEachIndex;
};
};
} forEach (_arr select 0);
// remove any marked for removal
{
(_arr select 0) deleteAt _x;
(_arr select 1) deleteAt _x
} forEach _toBeRemoved;
if (_arr isEqualTo [[], []]) then{
_arr = EPOCH_starterTraderItems;
if !(count (_arr select 0) >= _DynamicTraderRespawnCount) then {
EPOCH_TraderSlots deleteAt _traderSlotIndex;
_agent = createAgent [_class, _pos, [], 0, "NONE"];
_dir = random 360;
_agent call _TraderInit;
if (_arrchanged) then {
// diag_log format ["EPOCH_DEBUG: TraderSlot: %1 | Saved",_i];
["AI_ITEMS", _objHiveKey, EPOCH_expiresAIdata, _arr] call EPOCH_fnc_server_hiveSETEX;
};
};
_agent setVariable ["AI_ITEMS", _arr, true];
EPOCH_TraderSlots deleteAt _traderSlotIndex;
if (EPOCH_SHOW_TRADERS) then {
_markers = ["DynamicTrader",_pos] call EPOCH_server_createGlobalMarkerSet;
_agent setVariable["MARKER_REF", _markers];
if !(EPOCH_forceStaticTraders) then {
[_agent, _home, _work] execFSM "\epoch_server\system\Trader_brain.fsm";
};
if (EPOCH_SHOW_TRADERS) then {
_markers = ["DynamicTrader",_pos] call EPOCH_server_createGlobalMarkerSet;
_agent setVariable["MARKER_REF", _markers];
};
}
else {
// diag_log format ["EPOCH_DEBUG: TraderSlot: %1 | Supressed Trader Load - Too much items (%2) and will respawn",_i,count (_arr select 0)];
["AI", _objHiveKey] call EPOCH_fnc_server_hiveDEL;
["AI_ITEMS", _objHiveKey] call EPOCH_fnc_server_hiveDEL;
};
};
};

View File

@ -13,8 +13,10 @@
https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_server/compile/epoch_traders/EPOCH_server_spawnTraders.sqf
*/
//[[[cog import generate_private_arrays ]]]
private ["_acceptableBlds","_agent","_aiClass","_aiTables","_buildingHome","_buildingWork","_buildings","_checkBuilding","_config","_endTime","_home","_homes","_markers","_objHiveKey","_pos","_position","_randomAIUniform","_return","_schedule","_slot","_spawnCount","_startTime","_traderHomes","_usedBuildings","_work"];
private ["_serverSettingsConfig","_acceptableBlds","_agent","_aiClass","_aiTables","_buildingHome","_buildingWork","_buildings","_checkBuilding","_config","_endTime","_home","_homes","_markers","_objHiveKey","_pos","_position","_randomAIUniform","_return","_schedule","_slot","_spawnCount","_startTime","_traderHomes","_usedBuildings","_work"];
//[[[end]]]
_serverSettingsConfig = configFile >> "CfgEpochServer";
_TraderGodMode = [_serverSettingsConfig, "TraderGodMode", false] call EPOCH_fnc_returnConfigEntry;
_spawnCount = count EPOCH_TraderSlots;
_config = (configFile >> "CfgEpoch" >> worldName);
_aiTables = getArray(_config >> "traderUniforms");
@ -55,6 +57,7 @@ for "_i" from 1 to _spawnCount do {
};
_agent = createAgent[_aiClass, _pos, [], 0, "CAN_COLLIDE"];
addToRemainsCollector[_agent];
_agent allowdamage !_TraderGodMode;
_agent addUniform _randomAIUniform;
_slot = EPOCH_TraderSlots deleteAt 0;
_agent setVariable["AI_SLOT", _slot, true];

View File

@ -19,6 +19,7 @@ params ["_trader","_itemsIn","_itemsOut","_player",["_token","",[""]] ];
_playerUID = getplayeruid _player;
_serverSettingsConfig = configFile >> "CfgEpochServer";
_vehicleSold = false;
_vehicleBought = false;
@ -103,20 +104,18 @@ if (_slot != -1) then {
if (_makeTradeIn) then {
_returnIn pushBack _item;
_qtyIndex = _itemClasses find _item;
if (_qtyIndex == -1) then {
_itemClasses pushBack _item;
_itemQtys pushBack _itemQty;
_tradeIn = _tradeIn + _itemWorth;
_current_crypto = _current_crypto + _itemWorth;
_tradeQtyTotal = _tradeQtyTotal + _itemQty;
} else {
_currQty = _itemQtys select _qtyIndex;
_itemQtys set[_qtyIndex, (_currQty + _itemQty)];
_tradeIn = _tradeIn + _itemWorth;
_current_crypto = _current_crypto + _itemWorth;
_tradeQtyTotal = _tradeQtyTotal + _itemQty;
_tradeIn = _tradeIn + _itemWorth;
_current_crypto = _current_crypto + _itemWorth;
_tradeQtyTotal = _tradeQtyTotal + _itemQty;
if !(_item in ([_serverSettingsConfig, "TraderItemsDeleteInstant", []] call EPOCH_fnc_returnConfigEntry)) then {
_qtyIndex = _itemClasses find _item;
if (_qtyIndex == -1) then {
_itemClasses pushBack _item;
_itemQtys pushBack _itemQty;
} else {
_currQty = _itemQtys select _qtyIndex;
_itemQtys set[_qtyIndex, (_currQty + _itemQty)];
};
};
// send karma stat to seller
_kIndex = EPOCH_communityStats find "Karma";
@ -133,7 +132,6 @@ if (_slot != -1) then {
if ((_response select 0) == 1 && (_response select 1) isEqualType []) then {
_bankData = _response select 1;
if !(_bankData isEqualTo[]) then {
_serverSettingsConfig = configFile >> "CfgEpochServer";
_MaxBankDebit = [_serverSettingsConfig, "MaxBankDebitforTrade", -999999] call EPOCH_fnc_returnConfigEntry;
_bankBalance = _bankData select 0;
if (_bankBalance < _MaxBankDebit) then {

View File

@ -184,8 +184,8 @@ if !(EPOCH_forcedVehicleSpawnTable isEqualTo "") then {
_allowedVehiclesList = getArray(_epochConfig >> worldName >> _allowedVehicleListName);
_vehicleSlotLimit = 0;
{_vehicleSlotLimit = _vehicleSlotLimit + (_x select 1)} forEach _allowedVehiclesList;
_ReservedSlots = 50;
_vehicleSlotLimit = _vehicleSlotLimit + _ReservedSlots;
_ReservedVehSlots = [_serverSettingsConfig, "ReservedVehSlots", 50] call EPOCH_fnc_returnConfigEntry;
_vehicleSlotLimit = _vehicleSlotLimit + _ReservedVehSlots;
if (EPOCH_useOldLoadVehicles) then {
_vehicleSlotLimit call EPOCH_load_vehicles_old;
} else {