Пасты (фрагменты кода)

Небольшие вырезки кода, который может быть применен для решения некоторых задач

Замена модельки подарка

Небольшой костыль, позволяющий изменить модельку дропнутого предмета. Скорее всего, это временное решение и в будущем возможность изменения модельки будет реализована в основном функционале

P.S. Возможен баг с прокручиванием новой модельки, словно она - шарик

hook.Add("OnEntityCreated", "IGS_ChangeGiftModel", function(ent)
	if IsValid(ent) and ent:GetClass() == "ent_igs" then
		timer.Simple(1, function()
			ent:SetModel("string modelName")
		end)
	end
end)

Скрытие сообщений от IGS в чате

В примере снизу скрывается сообщение об автовосстановлении ULX прав. Тема, из-за которой это реализовано: Как убрать сообщение об автовосстановлении

hook.Add("IGS.Loaded", "IGS_NotifyAllOverride", function()
	IGS.NotifyAll_ = IGS.NotifyAll_ or IGS.NotifyAll

	function IGS.NotifyAll(...)
		local args = {...}
		if args[1] and isstring(args[1]) and args[1]:StartWith("Автовосстановление ") then
			return
		end
		return IGS.NotifyAll_(unpack(args))
	end

	print("IGS. Оверрайд IGS.NotifyAll")
end)

Команда покупки кастомного количества игровой валюты

Изначально была написана для темы Ползунок выбора суммы валюты для покупки. В идеале для нее нужен интерфейс, где игрок вводит сколько он хочет валюты.

concommand.Add("igsbuymoney", function(pl, _, args)
	local sum = tonumber(args[1])
	if not sum then return end

	local ttw = 30 - (os.time() - (pl.last_igsbuymoney or 0))
	if ttw > 0 then
		IGS.Notify("Повторите через " .. string.NiceTime(ttw))
		return
	end

	local price_rub = math.Round(sum / 1000, 2) -- 1000 игровой за 1 рубль
	if price_rub <= 10 then
		IGS.Notify(pl, "Минимальная сумма заказа не достигнута")
		return
	end

	pl.last_igsbuymoney = os.time()
	if IGS.CanAfford(pl, price_rub) then
		pl:AddIGSFunds(-price_rub, "Покупка " .. string.Comma(sum) .. " игровой валюты", function()
			if not IsValid(pl) then return end
			pl:addMoney(sum)
		end)
	else
		IGS.Notify(pl, "Недостаточно денег на донат счету. Введите /IGSDeposit для пополнения")
	end
end)

За публикацию подобных штуковин вы можете получить награду “Моддер” на форуме

1 лайк

Не связано с GMD, но может пригодиться:

Запрет использования указанных тулов на нужных энтити

local limited_tools = {
	["material"] = true,
	["color"] = true
}

local disabled_ents = {
	["derma_printer"] = true,
}

hook.Add("CanTool", "disable_for_ents", function(_, tr, tool)
	if limited_tools[tool]
	and IsValid( tr.Entity )
	and disabled_ents[tr.Entity:GetClass()] then
		return false
	end
end)

Запрет делать прозрачные с одной стороны пропы

local restricted_props = {
	["models/props_building_details/storefront_template001a_bars.mdl"] = true,
	["models/props_combine/combine_window001.mdl"] = true,
	["models/props_combine/combine_fence01a.mdl"] = true,
	["models/props_combine/combine_fence01b.mdl"] = true
}

local material_tools = {
	["material"]    = true,
	["submaterial"] = true
}


local GetWeapon = PLAYER.GetActiveWeapon
local GetModel  = ENTITY.GetModel

hook.Add("CanTool","FuckCheatWalls",function(pl,tr,tool)
	-- Прозрачные с одной стороны пропы
	if (material_tools[tool] and restricted_props[GetModel(tr.Entity)])

	-- Режим "свечение мира". trigon.im/index.php?posts/36895/
	or (tool == "colour" and GetWeapon(pl)["Tool"] and GetWeapon(pl)["Tool"]["colour"]:GetClientNumber("mode",0) == 9)

	-- Админам + разрешаем
	and !pl:IsAdmin() then
		pl:ChatPrint("Извините, но на нашем сервере нельзя делать читерные укрытия")
		return false
	end
end)
1 лайк

Кешбек 20% с каждой покупки (не тестировался)

hook.Add("IGS.PlayerPurchasedItem", "cashback", function(pl, ITEM)
	pl:AddIGSFunds(ITEM.price * .2, "Кешбек за покупку " .. ITEM:Name())
end)

Разрешение активации только одного итема из категории

local function canActivate(pl, categ)
	for uid in pairs(IGS.PlayerPurchases(pl) or {}) do
		local ITEM = IGS.GetItemByUID(uid)
		if ITEM:Category() == categ then
			return "У вас уже есть покупка в этой категории"
		end
	end
end

IGS("Нож 1", "knife_1", 123)
	:SetDescription("Вы сможете активировать только 1 нож. Выбирайте с умом")
	:SetWeapon("class_knife_1")
	:SetCategory("Ножи")
	:SetCanActivate(function(pl)
		return canActivate(pl, "Ножи")
	end)

IGS("Нож 2", "knife_2", 123)
	:SetDescription("Вы сможете активировать только 1 нож. Выбирайте с умом")
	:SetWeapon("class_knife_2")
	:SetCategory("Ножи")
	:SetCanActivate(function(pl)
		return canActivate(pl, "Ножи")
	end)

А, ну раз такое дело то у меня тут репо полное сниппетов, примеров и мелких библиотек

1 лайк

Обновлено. Если используете – обязательно обновитесь

Выдача оружия при спавне всем, кто купил его, даже если игрок снимал галочку

-- Установить по пути:
-- addons/igs-modification/lua/autorun/server/force_weps_on_spawn.lua

local function bibuid(pl, ITEM)
	return "igs:gos:" .. pl:UniqueID() .. ":" .. ITEM:UID()
end

local function SetShouldPlayerReceiveWep(pl, ITEM, bGive)
	pl:SetNWBool("igs.gos." .. ITEM:ID(), bGive)
	bib.setBool(bibuid(pl, ITEM), bGive)
end

hook.Add("IGS.PlayerPurchasesLoaded", "force_give_weps_on_spawn", function(pl, purchases_)
	for uid in pairs(purchases_ or {}) do
		local ITEM = IGS.GetItemByUID(uid)
		if ITEM.swep then
			SetShouldPlayerReceiveWep(pl, ITEM, true)
		end
	end
end)

Откат транзакций за 7 дней (настраиваемо)

IGS.GetPlayerTransactionsBypassingLimit(function(txs)
	for i, tx in ipairs(txs) do
		local note = tx.Note or ""
		if note:StartWith("A: ") then continue end -- пропускаем реальные пополнения

		if (os.time() - tx.Time) >= 60 * 60 * 24 * 7 then
			print("Останавливаемся. Дальше пошли транзакции старее 7 дней")
			break
		end

		local s64, sum, id = tx.SteamID, tx.Sum, tx.ID
		local new_note = "Откат транзакции #" .. id .. "(" .. note .. ")"
		IGS.Transaction(s64, sum * -1, new_note, function()
			print("Транзакция #" .. id .. " отменена")
		end)
	end
end, nil, 10000)

Управление покупками игрока через Lua код

Удаление с инвентаря

-- inventory_id можно узнать через IGS.FetchInventory(fCallback, s64).
-- Функция вернет список предметов игрока. Например {{ID = 1234, Item = "uid"}, ...}
-- Функция IGS.StoreInventoryItem(fCallback, s64, sUid) добавляет предмет в инвентарь и в callback также возвращает inventory_id
local inventory_id = 1234
IGS.DeleteInventoryItem(function(bSuccessful)
	if bSuccessful then
		print("Предмет удален с инвентаря")
	else
		print("Предмет не удален. Возможно, ид предмета принадлежит другому проекту, либо предмет уже удален ранее")
	end
end, inventory_id)

Если игрок онлайн, то нужно также обновить его локальный инвентарь, чтобы игроку не отображался предмет, которого у него уже нет.

local pl = player.GetBySteamID("STEAM_0:1:23456789")
IGS.DeletePlayerInventoryItemLocally(pl, inventory_id)
-- /\ эта функция, используется когда игрок нажимает кнопку "Выбросить", либо "Активировать" на предмете в инвентаре, чтобы он больше там не отображался

Удаление активной покупки

Покупку можно только отключить. Запись останется в Базе Данных, но покупка больше не будет активной.

-- purchase_id можно узнать в момент выдачи предмета игроку функцией IGS.StoreLocalPurchase(s64, sItemUID, iDaysTerm_, fCallback)
-- Либо через IGS.GetPlayerPurchases(steamid64, fCallback) -> Список покупок: {{`ID`,`Server`,`Item`,`Purchase`,`Expire`(таймштамп),`SteamID`,`Nick`}, ...}
local purchase_id = 1234
IGS.DisablePurchase(purchase_id, function(bDisabled)
	print(bDisabled and "Покупка отключена" or "Услуга уже отключена")
end)

Если игрок онлайн, то действие услуги не отключится автоматически. Нужно перезагрузить список покупок

local pl = player.GetBySteamID("STEAM_0:1:23456789")
IGS.LoadPlayerPurchases(pl, function()
	IGS.Notify(pl, "Покупки перезагружены") -- уведомление в чат игроку
end)