Кэшбэк! $$$

Задумались о праздничных скидках в целях привлечения новых доноров?
Не спешите, у меня есть более крутое решение.

Работает по аналогии скидок, но кэшбэк стимулирует игроков пополнять баланс на большие суммы.

Пример:

  • Игрок видит плашку уведомляющую о мгновенном 25% кэшбэке до 7 января и хочет купить VIP на месяц. Стоимость привилегии 250 рублей, игрок пополняет баланс на 250 рублей, покупает привилегию и получает VIP и +50 рублей обратно на баланс.

В чём фишка: что-бы купить VIP за 200 рублей нужно пополнить баланс на 250 рублей, 50 рублей вернуться игроку на баланс.
Тем самым игрок получит приятную для себя скидку, на его балансе останутся мозолящие глаза 50 рублей (которые он вскоре захочет потратить и опять пополнит баланс), а вы получите дополнительные 50 рублей которые могли не получить в случае использования обычных скидок, все участники сделки в профите :wink:

  • Что-бы установить кэшбэк для всех предметов изменяйте переменную DefaultCaschback
  • Что-бы установить кэшбэк определённому предмету используйте ITEM метод :SetCashback

Мгновенный кэшбэк - простенький вариант, можно использовать во время праздников.

local DefaultCaschback = 0.2 -- 0 = отключить стандартный кэшбэк, 0.2 = 20%, 0.5 = 50%

hook.Add("IGS.PlayerPurchasedItem", "Cashback https://forum.gm-donate.net/t/keshbek/963", function(ply, item, id)
	if item.cashback_disable or DefaultCaschback <= 0 or item.cashback == 0 then return end

	local summ = math.floor(item.price * (item.cashback or DefaultCaschback))
	ply:AddIGSFunds(summ, "Cashback ".. summ .." - ".. (item.cashback or DefaultCaschback) * 100 .."%")

	IGS.Notify(ply, "Спасибо за покупку! Вы получили +".. PL_MONEY(summ) .." кэшбэка!")
end)

local ITEM = FindMetaTable("IGSItem")

function ITEM:DisableCashback(bool)
	self.cashback_disable = bool ~= false and true or nil
	return self
end

function ITEM:SetCashback(precent)
	self.cashback = precent
	return self
end
  • Путь: garrysmod/lua/autorun/gmd_cashback.lua

Кэшбэк раз в месяц - рекомендую использовать на постоянку, это добавит разнообразия к банальным скидкам и даст вам немного дополнительного $ профита $

local DefaultCaschback = 0 -- 0 = отключить стандартный кэшбэк, 0.2 = 20%, 0.5 = 50%

hook.Add("IGS.PlayerPurchasedItem", "Cashback https://forum.gm-donate.net/t/keshbek/963", function(ply, item, id)
	if item.cashback_disable or DefaultCaschback <= 0 or item.cashback == 0 then return end

	local path = "gmdcashback/".. os.date("*t").month
	file.CreateDir(path)

	path = path .."/".. ply:SteamID64() ..".txt"
	local prev = 0

	if file.Exists(path, "DATA") then
		prev = tonumber(file.Read(path, "DATA"))
	end

	local summ = math.floor(item.price * (item.cashback or DefaultCaschback))
	file.Write(path, prev + summ)
	ply:ChatPrint("Спасибо за покупку! В следующем месяце вы получите +".. summ .."₽ кэшбэка!")
end)

local ITEM = FindMetaTable("IGSItem")

function ITEM:DisableCashback(bool)
	self.cashback_disable = bool ~= false and true or nil
	return self
end

function ITEM:SetCashback(precent)
	self.cashback = precent
	return self
end

local function Cashback(ply)
	local path = "gmdcashback/".. os.date("*t").month - 1 .."/".. ply:SteamID64() ..".txt"
	if file.Exists(path, "DATA") then
		local summ = tonumber(file.Read(path, "DATA"))
		file.Delete(path)

		ply:AddIGSFunds(summ, "Monthly Cashback ".. summ)
		IGS.Notify(ply, "Вы получили ".. PL_MONEY(summ) .." кэшбэка за траты в прошлом месяце, наслаждайтесь!")
	end
end

hook.Add("PlayerFullLoad", "Cashback https://forum.gm-donate.net/t/keshbek/963", Cashback)

local next_ply = 0
timer.Create("Cashback https://forum.gm-donate.net/t/keshbek/963", 60, 0, function() -- 99%  серверов перезагружаются как минимум раз в сутки, но это не аксиома
	next_ply = next_ply + 1
	if next_ply > #player.GetHumans() then
		next_ply = 1
	end

	local ply = player.GetHumans()[next_ply]
	if IsValid(ply) then
		Cashback(ply)
	end
end)

hook.Add("PlayerInitialSpawn", "FullLoadSetup", function(ply)
	hook.Add("SetupMove", ply, function(self, ply, _, cmd)
		if self == ply and not cmd:IsForced() then
			hook.Run("PlayerFullLoad", self)
			hook.Remove("SetupMove", self)
		end
	end)
end)
  • Путь: garrysmod/lua/autorun/gmd_cashback.lua

Пример установки кэшбэка определённому предмету:

IGS("VIP на месяц", "vip_na_mesyac")
:SetULXGroup("vip")
:SetPrice(150)
:SetTerm(30) -- 30 дней
:SetCategory("Группы")
:SetDescription("С этой покупкой вы станете офигенными, потому что в ней воооот такая куча крутых возможностей")
:SetCashback(0.3) -- 30%

Все это выглядит сложно, даже для меня, который как никто знает устройство IGS и увлечен маркетингом с 2015 года

Вопросы начинаются еще со второго абзаца

Игрок видит плашку уведомляющую о мгновенном кэшбэке до 7 января и хочет купить VIP за 200 рублей (которая обычно стоит 250 рублей), пополняет баланс на 250 рублей

Если вип стоит 200 руб, зачем ему пополнять счет на 250? Если в идее это можно перефразировать как “Для покупки этого предмета вам нужно пополнить счет на 250 руб, но 50 вернется вам на счет” или “Купите этот предмет за 250 руб, но получите 50 руб кешбека”, то это усложнение ради усложнения, которое сломает голову не только донатеру, но и тому, кто будет пытаться объяснить самому себе (кроме автора идеи) и другим как это работает


Почему бы вместо этого не сделать кешбек на каждое пополнение (или покупку), чтобы донатер не мог потратить деньги в 0?

Представим. VIP 250 руб, кешбек те же 20%

Дон пополняет баланс на 250 руб, чтобы купить эту випку. Ему приходит 250 + 20%, он покупает VIP и у него остается еще 50 руб. Видит допустим нож за 200 руб. Понимает, что это уже по сути не 200, а 150 руб. Пополняет еще 150 и у него снова останется 30 руб на балансе, которые будут мозолить ему глаза, пока бан не разлучит его с сервером

Как бы игрок не пытался выйти в 0, у него не получится и всегда будут мозолить какие-то цифры в балансе

И объяснить/визуализировать проще и сделать в 2 строки

Да, формулировка неудачная - поправил, вроде стало более понятно.
Механика работы кэшбэка знакома каждому, просто я решил привести пример для наглядного преимущества кэшбэка над обычными скидками.

Также немного упростил код (но фундаментально не улучшал его, тоесть не трогал то, что изменил бы в принципе работы)

Простой вариант:

hook.Add("IGS.PlayerPurchasedItem", "cashback", function(pl, ITEM)
	local perc = ITEM:GetMeta("cashback")
	if (perc or 0) <= 0 then return end

	local cutoff = math.floor(ITEM.price * perc)
	pl:AddIGSFunds(cutoff, "Cashback ".. cutoff .." - ".. (perc * 100) .."%")

	IGS.Notify(pl, "Спасибо за покупку! Вы получили +" .. PL_MONEY(cutoff) .. " кэшбэка!")
end)


local ITEM = FindMetaTable("IGSItem")

function ITEM:SetCashback(percent) -- 0.2 = возврат 20%
	return self:SetMeta("cashback", percent)
end

Раз в месяц (не проверял)

local ITEM = FindMetaTable("IGSItem")
function ITEM:SetCashback(percent) -- 0.2 = 20%, 0.5 = 50%
	return self:SetMeta("cashback", percent)
end


hook.Add("IGS.PlayerPurchasedItem", "cashback", function(pl, ITEM)
	local perc = ITEM:GetMeta("cashback")
	if (perc or 0) <= 0 then return end

	local summ = math.floor(ITEM.price * perc)
	local total = bib.incr(pl, "igs_cashback_" .. tonumber(os.date("%m")) .. "_" .. pl:SteamID64(), summ)

	pl:ChatPrint("Спасибо за покупку! В следующем месяце вы получите +" .. PL_MONEY(total) .. " кэшбэка!")
end)


local function give_cashback(pl)
	local uid = "igs_cashback_" .. tonumber(os.date("%m")) - 1 .. "_" .. pl:SteamID64()
	local cashback = bib.getNum(pl, uid)
	if not cashback then return end

	pl:AddIGSFunds(cashback, "Monthly Cashback")
	pl:ChatPrint("Вы получили " .. PL_MONEY(cashback) .. " кэшбэка за траты в прошлом месяце, наслаждайтесь!")

	bib.delete(uid)
end

hook.Add("IGS.PlayerPurchasesLoaded", "monthly_cashback", give_cashback)
1 симпатия

не знал про IGS.Notify и bib либу, хорошечные штуки.

Обновил мод

инструкция по установке

Добавлена возможность создания глобального кэшбэка (как в первой версии, хз почему я убрал его при разработке прошлого апдейта)

1 симпатия
[donate_igs-modification] addons/donate_igs-modification/lua/igs/mods/cashback.lua:43: attempt to perform arithmetic on field 'price' (a nil value)
  1. fn - addons/donate_igs-modification/lua/igs/mods/cashback.lua:43
   2. Run - addons/admin_ulib/lua/ulib/shared/hook.lua:109
    3. fOnFinish_ - igs/core_sv.lua:98
     4. fOnSuccess - igs/core_sv.lua:210
      5. fOnSuccess - igs/apinator.lua:71
       6. onsuccess - igs/apinator.lua:61
        7. unknown - lua/includes/modules/http.lua:58

у предмета нет цены, укажи ему цену
пример:

Но у него есть цена…

IGS("Премиум BATTLEPASS", "battlepass")
    :SetPrice(299)
    :SetIcon("https://i.imgur.com/wZBxakp.png")
    :SetOnActivate(function (ply) RunConsoleCommand('battlepass_give_pass', ply:SteamID64()) end)
    :SetDescription("Получай крутые награды в новой системе BATTLEPASS!")
    :SetCategory("BATTLEPASS")
    :SetHighlightColor(Color(255, 212, 51))

ёпт, опечатка.

[donate_igs-modification] addons/donate_igs-modification/lua/igs/mods/cashback.lua:43: attempt to index global 'IDS' (a nil value)
  1. unknown - addons/donate_igs-modification/lua/igs/mods/cashback.lua:43
   2. include - [C]:-1
    3. LoadFile - addons/donate_igs-modification/lua/autorun/igs-mods-loader.lua:16
     4. unknown - addons/donate_igs-modification/lua/autorun/igs-mods-loader.lua:25

merged

1 симпатия

При покупке предмета

[donate_igs-modification] addons/donate_igs-modification/lua/igs/mods/cashback.lua:44: attempt to call field 'incr' (a nil value)
  1. AddCashback - addons/donate_igs-modification/lua/igs/mods/cashback.lua:44
   2. fn - addons/donate_igs-modification/lua/igs/mods/cashback.lua:68
    3. Run - addons/admin_ulib/lua/ulib/shared/hook.lua:109
     4. fOnFinish_ - igs/core_sv.lua:98
      5. fOnSuccess - igs/core_sv.lua:210
       6. fOnSuccess - igs/apinator.lua:71
        7. onsuccess - igs/apinator.lua:61
         8. unknown - lua/includes/modules/http.lua:58

Еще один пул сделал, но проблему не решил

ну тут не моя опечатка))

merged

Так что делать то? Там числа какие-то арифметические я вообще не догоняю что он от меня хочет)

[donate_igs-modification] igs/dependencies/bib.lua:93: attempt to perform arithmetic on a string value
  1. AddCashback - igs/dependencies/bib.lua:93
   2. fn - addons/donate_igs-modification/lua/igs/mods/cashback.lua:68
    3. Run - addons/admin_ulib/lua/ulib/shared/hook.lua:109
     4. fOnFinish_ - igs/core_sv.lua:98
      5. fOnSuccess - igs/core_sv.lua:210
       6. fOnSuccess - igs/apinator.lua:71
        7. onsuccess - igs/apinator.lua:61
         8. unknown - lua/includes/modules/http.lua:58

typo solved

1 симпатия