datastreams are net messages
cl_hooks
Code:
--[[
© 2014 do not share, re-distribute or modify
without permission of its author.
Clockwork was created by Conna Wiles (also known as kurozael.)
--]]
-- Called when an entity's target ID HUD should be painted.
function cwStorage:HUDPaintEntityTargetID(entity, info)
local colorTargetID = Clockwork.option:GetColor("target_id");
local colorWhite = Clockwork.option:GetColor("white");
if (Clockwork.entity:IsPhysicsEntity(entity)) then
local model = string.lower(entity:GetModel());
if (self.containerList[model]) then
if (entity:GetNetworkedString("Name") != "") then
info.y = Clockwork.kernel:DrawInfo(entity:GetNetworkedString("Name"), info.x, info.y, colorTargetID, info.alpha);
else
info.y = Clockwork.kernel:DrawInfo(self.containerList[model][2], info.x, info.y, colorTargetID, info.alpha);
end;
info.y = Clockwork.kernel:DrawInfo("You can put stuff inside it.", info.x, info.y, colorWhite, info.alpha);
end;
end;
end;
-- Called when an entity's menu options are needed.
function cwStorage:GetEntityMenuOptions(entity, options)
if (Clockwork.entity:IsPhysicsEntity(entity)) then
local model = string.lower(entity:GetModel());
if (self.containerList[model]) then
options["Open"] = "cwContainerOpen";
end;
end;
end;
-- Called when the local player's storage is rebuilt.
function cwStorage:PlayerStorageRebuilt(panel, categories)
if (panel.storageType == "Container") then
local entity = Clockwork.storage:GetEntity();
if (IsValid(entity) and entity.cwMessage) then
local messageForm = vgui.Create("DForm", panel);
local helpText = messageForm:Help(entity.cwMessage);
messageForm:SetPadding(5);
messageForm:SetName("Message");
helpText:SetFont("Default");
panel:AddItem(messageForm);
end;
end;
end;
cl_plugin
Code:
--[[
© 2014 do not share, re-distribute or modify
without permission of its author.
Clockwork was created by Conna Wiles (also known as kurozael.)
--]]
Clockwork.datastream:Hook("StorageMessage", function(data)
local entity = data.entity;
local message = data.message;
if (IsValid(entity)) then
entity.cwMessage = message;
end;
end);
Clockwork.datastream:Hook("ContainerPassword", function(data)
local entity = data;
Derma_StringRequest("Password", "What is the password for this container?", nil, function(text)
Clockwork.datastream:Start("ContainerPassword", {text, entity});
end);
end);
sh_plugin
Code:
--[[
© 2014 do not share, re-distribute or modify
without permission of its author.
Clockwork was created by Conna Wiles (also known as kurozael.)
--]]
--[[
You don't have to do this, but I think it's nicer.
Alternatively, you can simply use the PLUGIN variable.
--]]
PLUGIN:SetGlobalAlias("cwStorage");
--[[ You don't have to do this either, but I prefer to seperate the functions. --]]
Clockwork.kernel:IncludePrefixed("cl_plugin.lua");
Clockwork.kernel:IncludePrefixed("sv_plugin.lua");
Clockwork.kernel:IncludePrefixed("sv_hooks.lua");
Clockwork.kernel:IncludePrefixed("cl_hooks.lua");
cwStorage.containerList = {
["models/props_wasteland/controlroom_storagecloset001a.mdl"] = {8, "Closet"},
["models/props_wasteland/controlroom_storagecloset001b.mdl"] = {15, "Closet"},
["models/props_wasteland/controlroom_filecabinet001a.mdl"] = {4, "File Cabinet"},
["models/props_wasteland/controlroom_filecabinet002a.mdl"] = {8, "File Cabinet"},
["models/props_c17/suitcase_passenger_physics.mdl"] = {5, "Suitcase"},
["models/props_junk/wood_crate001a_damagedmax.mdl"] = {8, "Wooden Crate"},
["models/props_junk/wood_crate001a_damaged.mdl"] = {8, "Wooden Crate"},
["models/props_interiors/furniture_desk01a.mdl"] = {4, "Desk"},
["models/props_c17/furnituredresser001a.mdl"] = {10, "Dresser"},
["models/props_c17/furnituredrawer001a.mdl"] = {8, "Drawer"},
["models/props_c17/furnituredrawer002a.mdl"] = {4, "Drawer"},
["models/props_c17/furniturefridge001a.mdl"] = {8, "Fridge"},
["models/props_c17/furnituredrawer003a.mdl"] = {8, "Drawer"},
["models/weapons/w_suitcase_passenger.mdl"] = {5, "Suitcase"},
["models/props_junk/trashdumpster01a.mdl"] = {15, "Dumpster"},
["models/props_junk/wood_crate001a.mdl"] = {8, "Wooden Crate"},
["models/props_junk/wood_crate002a.mdl"] = {10, "Wooden Crate"},
["models/items/ammocrate_rockets.mdl"] = {15, "Ammo Crate"},
["models/props_lab/filecabinet02.mdl"] = {8, "File Cabinet"},
["models/items/ammocrate_grenade.mdl"] = {15, "Ammo Crate"},
["models/props_junk/trashbin01a.mdl"] = {10, "Trash Bin"},
["models/props_c17/suitcase001a.mdl"] = {8, "Suitcase"},
["models/items/item_item_crate.mdl"] = {4, "Item Crate"},
["models/props_c17/oildrum001.mdl"] = {8, "Oildrum"},
["models/items/ammocrate_smg1.mdl"] = {15, "Ammo Crate"},
["models/items/ammocrate_ar2.mdl"] = {15, "Ammo Crate"}
};
sv_hooks
Code:
--[[
© 2014 do not share, re-distribute or modify
without permission of its author.
Clockwork was created by Conna Wiles (also known as kurozael.)
--]]
-- Called when Clockwork has loaded all of the entities.
function cwStorage:ClockworkInitPostEntity()
self:LoadStorage(); self.randomItems = {};
for k, v in pairs(Clockwork.item:GetAll()) do
if (!v("isRareItem") and !v("isBaseItem")) then
self.randomItems[#self.randomItems + 1] = {
v("uniqueID"),
v("weight")
};
end;
end;
end;
-- Called when data should be saved.
function cwStorage:SaveData()
self:SaveStorage();
end;
-- Called when a player attempts to breach an entity.
function cwStorage:PlayerCanBreachEntity(player, entity)
if (entity.cwInventory and entity.cwPassword) then
return true;
end;
end;
-- Called when an entity attempts to be auto-removed.
function cwStorage:EntityCanAutoRemove(entity)
if (self.storage[entity] or entity:GetNetworkedString("Name") != "") then
return false;
end;
end;
-- Called when an entity's menu option should be handled.
function cwStorage:EntityHandleMenuOption(player, entity, option, arguments)
local class = entity:GetClass();
if (class == "cw_locker" and arguments == "cwContainerOpen") then
self:OpenContainer(player, entity);
elseif (arguments == "cwContainerOpen") then
if (Clockwork.entity:IsPhysicsEntity(entity)) then
local model = string.lower(entity:GetModel());
if (self.containerList[model]) then
local containerWeight = self.containerList[model][1];
if (!entity.cwPassword or entity.cwIsBreached) then
self:OpenContainer(player, entity, containerWeight);
else
Clockwork.datastream:Start(player, "ContainerPassword", entity);
end;
end;
end;
end;
end;
-- Called when an entity has been breached.
function cwStorage:EntityBreached(entity, activator)
if (entity.cwInventory and entity.cwPassword) then
entity.cwIsBreached = true;
Clockwork.kernel:CreateTimer("ResetBreach"..entity:EntIndex(), 120, 1, function()
if (IsValid(entity)) then
entity.cwIsBreached = nil;
end;
end);
end;
end;
-- Called when an entity is removed.
function cwStorage:EntityRemoved(entity)
if (IsValid(entity) and !entity.cwIsBelongings) then
Clockwork.entity:DropItemsAndCash(entity.cwInventory, entity.cwCash, entity:GetPos(), entity);
entity.cwInventory = nil;
entity.cwCash = nil;
end;
end;
-- Called when a player's prop cost info should be adjusted.
function cwStorage:PlayerAdjustPropCostInfo(player, entity, info)
local model = string.lower(entity:GetModel());
if (self.containerList[model]) then
info.name = self.containerList[model][2];
end;
end;
sv_plugin
Code:
--[[
© 2014 do not share, re-distribute or modify
without permission of its author
Clockwork was created by Conna Wiles (also known as kurozael.)
--]]
Clockwork.datastream:Hook("ContainerPassword", function(player, data)
local password = data[1];
local entity = data[2];
if (IsValid(entity) and Clockwork.entity:IsPhysicsEntity(entity)) then
local model = string.lower(entity:GetModel());
if (cwStorage.containerList[model]) then
local containerWeight = cwStorage.containerList[model][1];
if (entity.cwPassword == password) then
cwStorage:OpenContainer(player, entity, containerWeight);
else
Clockwork.player:Notify(player, "You have entered an incorrect password!");
end;
end;
end;
end);
-- A function to get a random item.
function cwStorage:GetRandomItem(uniqueID)
if (uniqueID) then
uniqueID = string.lower(uniqueID);
end;
if (#self.randomItems <= 0) then
return;
end;
local randomItem = self.randomItems[
math.random(1, #self.randomItems)
];
if (randomItem) then
local itemTable = Clockwork.item:FindByID(randomItem[1]);
if (!uniqueID or string.find(string.lower(itemTable("category")), uniqueID)) then
return randomItem;
end;
end;
return self:GetRandomItem(uniqueID, runs);
end;
function cwStorage:CategoryExists(uniqueID)
if (uniqueID) then
local uniqueID = string.lower(uniqueID);
for i = 1, #self.randomItems do
local item = Clockwork.item:FindByID(self.randomItems[i][1]);
if (string.find(string.lower(item("category")), uniqueID)) then
return true;
end;
end;
return false;
else
return false;
end;
end;
-- A function to save the storage.
function cwStorage:SaveStorage()
local storage = {};
for k, v in pairs(self.storage) do
if (IsValid(v)) then
if (v.cwInventory and v.cwCash and (v.cwMessage or table.Count(v.cwInventory) > 0 or v.cwCash > 0 or v:GetNetworkedString("Name") != "")) then
local physicsObject = v:GetPhysicsObject();
local bMoveable = nil;
local startPos = v:GetStartPosition();
local model = v:GetModel();
if (v:IsMapEntity() and startPos) then
model = nil;
end;
if (IsValid(physicsObject)) then
bMoveable = physicsObject:IsMoveable();
end;
storage[#storage + 1] = {
name = v:GetNetworkedString("Name"),
model = model,
cash = v.cwCash,
color = { v:GetColor() },
angles = v:GetAngles(),
position = v:GetPos(),
message = v.cwMessage,
password = v.cwPassword,
startPos = startPos,
inventory = Clockwork.inventory:ToSaveable(v.cwInventory),
isMoveable = bMoveable
};
end;
end;
end;
Clockwork.kernel:SaveSchemaData("plugins/storage/"..game.GetMap(), storage);
end;
-- A function to load the storage.
function cwStorage:LoadStorage()
local storage = Clockwork.kernel:RestoreSchemaData("plugins/storage/"..game.GetMap());
self.storage = {};
for k, v in pairs(storage) do
if (!v.model) then
local entity = ents.FindInSphere((v.startPos or v.position), 16)[1];
if (IsValid(entity) and entity:IsMapEntity()) then
self.storage[entity] = entity;
entity.cwInventory = Clockwork.inventory:ToLoadable(v.inventory);
entity.cwPassword = v.password;
entity.cwMessage = v.message;
entity.cwCash = v.cash;
if (IsValid(entity:GetPhysicsObject())) then
if (!v.isMoveable) then
entity:GetPhysicsObject():EnableMotion(false);
else
entity:GetPhysicsObject():EnableMotion(true);
end;
end;
if (v.angles) then
entity:SetAngles(v.angles);
entity:SetPos(v.position);
end;
if (v.color) then
entity:SetColor(unpack(v.color));
end;
if (v.name != "") then
entity:SetNetworkedString("Name", v.name);
end;
end;
else
local entity = ents.Create("prop_physics");
entity:SetAngles(v.angles);
entity:SetModel(v.model);
entity:SetPos(v.position);
entity:Spawn();
if (IsValid(entity:GetPhysicsObject())) then
if (!v.isMoveable) then
entity:GetPhysicsObject():EnableMotion(false);
end;
end;
if (v.color) then
entity:SetColor(unpack(v.color));
end;
if (v.name != "") then
entity:SetNetworkedString("Name", v.name);
end;
self.storage[entity] = entity;
entity.cwInventory = Clockwork.inventory:ToLoadable(v.inventory);
entity.cwPassword = v.password;
entity.cwMessage = v.message;
entity.cwCash = v.cash;
end;
end;
end;
-- A function to open a container for a player.
function cwStorage:OpenContainer(player, entity, weight)
local inventory;
local cash = 0;
local model = string.lower(entity:GetModel());
local name = "";
if (!entity.cwInventory) then
self.storage[entity] = entity;
entity.cwInventory = {};
end;
if (!entity.cwCash) then
entity.cwCash = 0;
end;
if (self.containerList[model]) then
name = self.containerList[model][2];
else
name = "Container";
end;
inventory = entity.cwInventory;
cash = entity.cwCash;
if (!weight) then
weight = 8;
end;
if (entity:GetNetworkedString("Name") != "") then
name = entity:GetNetworkedString("Name");
end;
if (entity.cwMessage) then
Clockwork.datastream:Start(player, "StorageMessage", {
entity = entity, message = entity.cwMessage
});
end;
Clockwork.storage:Open(player, {
name = name,
weight = weight,
entity = entity,
distance = 192,
cash = cash,
inventory = inventory,
OnGiveCash = function(player, storageTable, cash)
storageTable.entity.cwCash = storageTable.cash;
end,
OnTakeCash = function(player, storageTable, cash)
storageTable.entity.cwCash = storageTable.cash;
end
});
end;