- Joined
- Jun 26, 2020
- Messages
- 1,927
I tried to update the Lua pure code version of my Bounty Controller but every time I saved it the editor closes and I don't know why, I wrote it in the VSCode with pluggins and never displayed me a syntax error or something like that, to see what is happening here is the code:
Lua:
--The pure Lua version of the Bounty Controller
--GUI version: https://www.hiveworkshop.com/threads/gui-bounty-controller.332114/
do
Bounty_Controller = nil
local LocalPlayer = nil
--selfs can be edited (obviously only valid values)
local DEF_COLOR_GOLD = "ffcc00"
local DEF_COLOR_LUMBER = "32cd32"
local DEF_SIZE = 10
local DEF_LIFE_SPAN = 3.50
local DEF_AGE = 0.00
local DEF_SPEED = 64
local DEF_DIRECTION = 90
local DEF_FADE_POINT = 2.50
local DEF_STATE = "gold"
local DEF_HEIGHT = 0
local DEF_SHOW = true
local DEF_SHOW_NOTHING = false
local DEF_ALLOW_FRIEND_FIRE = false
local DEF_EFFECT = "UI\\Feedback\\GoldCredit\\GoldCredit.mdl"
local DEF_SHOW_EFFECT = true
local DEF_PERMANENT = false
local LIMIT_RECURSION = 16 --If a loop caused by recursion is doing in porpouse you can edit the tolerance of how many calls can do
local t1 = CreateTrigger()
local t2 = CreateTrigger()
local current = nil
local Bounties0 = {}
local Bounties1 = {}
local Bounties2 = {}
local Recursion = 0
-- This function is runned at the map initialization, if you wanna use it to your bounties, you can do it
local function SetData()
--[[Peasant]] Bounty.Set(FourCC("hpea"), 15, 5, 3)
for i = 0, PLAYER_NEUTRAL_AGGRESSIVE do
SetPlayerState(Player(i), PLAYER_STATE_GIVES_BOUNTY, 0)
end
end
globals(function(_ENV)
BountyEvent = 0.0
BountyDeadEvent = 0.0
end)
function IsBounty(value)
return getmetatable(value) == BountyMT
end
-- The order it returns (if there is no error) is: number, Bounty
local function ValidValues(v1, v2)
if type(v1) == "number" and IsBounty(v2) then
return v1, v2
elseif IsBounty(v1) and type(v2) == "number" then
return v2, v1
else
error("Wrong operators", 3)
end
end
BountyMT = {
__index = function (t, k)
if BountyMT[k] then
return BountyMT[k]
elseif k == "Amount" or
k == "Color" or
k == "Size" or
k == "LifeSpan" or
k == "Age" or
k == "Speed" or
k == "Direction" or
k == "FadePoint" or
k == "State" or
k == "Height" or
k == "Show" or
k == "ShowNothing" or
k == "AllowFriendFire" or
k == "Effect" or
k == "ShowEff" or
k == "Permanent" or
k == "Receiver" or
k == "UnitPos" or
k == "LocPos" or
k == "TextTag" or
k == "PosX" or
k == "PosY" or
k == "KillingUnit" or
k == "DyingUnit" or
k == "canSee" then
return rawget(t, k)
else
error("This field don't exist " .. tostring(k), 2)
end
end,
__newindex = function (t, k ,v)
if BountyMT[k] then
error("You can't edit this method " .. tostring(k), 2)
elseif k == "Amount" or
k == "Color" or
k == "Size" or
k == "LifeSpan" or
k == "Age" or
k == "Speed" or
k == "Direction" or
k == "FadePoint" or
k == "State" or
k == "Height" or
k == "Show" or
k == "ShowNothing" or
k == "AllowFriendFire" or
k == "Effect" or
k == "ShowEff" or
k == "Permanent" or
k == "Receiver" or
k == "UnitPos" or
k == "LocPos" or
k == "TextTag" or
k == "PosX" or
k == "PosY" or
k == "KillingUnit" or
k == "DyingUnit" or
k == "canSee" then
rawset(t, k, v)
else
error("You can't add new fields " .. tostring(k), 2)
end
end,
__add = function (v1, v2)
local num, bounty = ValidValues(v1, v2)
local new = Bounty.Copy(bounty)
new.Amount = new.Amount + num
return new
end,
__sub = function (v1, v2)
local num, bounty = ValidValues(v1, v2)
local new = Bounty.Copy(bounty)
new.Amount = new.Amount - num
return new
end,
__mul = function (v1, v2)
local num, bounty = ValidValues(v1, v2)
local new = Bounty.Copy(bounty)
new.Amount = new.Amount * num
return new
end,
__div = function (v1, v2)
local num, bounty = ValidValues(v1, v2)
local new = Bounty.Copy(bounty)
new.Amount = new.Amount / num
return new
end,
__mod = function (v1, v2)
local num, bounty = ValidValues(v1, v2)
local new = Bounty.Copy(bounty)
new.Amount = new.Amount % num
return new
end,
__pow = function (v1, v2)
local num, bounty = ValidValues(v1, v2)
local new = Bounty.Copy(bounty)
new.Amount = new.Amount ^ num
return new
end,
__gc = function (t)
print(t)
end,
__name = "Bounty",
__tostring = function (t)
return "Bounty: |cff" .. Bounty.Sign(t.Bounty) .. t.Bounty .. t.Color .. "|r"
end
}
function BountyMT:destroy()
if self.LocPos then
RemoveLocation(self.LocPos)
end
self.canSee = nil
Recursion = Recursion - 1
end
function BountyMT:CanSee(p, flag)
self.canSee[p] = flag
end
function BountyMT:Seeing(p)
return self.canSee[p]
end
function BountyMT:Run()
local what
if Recursion > LIMIT_RECURSION then --If there is recursion that don't stop soon, the system stops automatically
warn("There is a recursion with the Bounty system, check if you are not creating a infinite loop.")
self:destroy()
return nil
end
if self.State == "gold" then
what = PLAYER_STATE_RESOURCE_GOLD
elseif self.State == "lumber" then
what = PLAYER_STATE_RESOURCE_LUMBER
else
self:destroy()
return nil --If the state is not valid, the process stop
end
if self.Amount == 0 and not self.ShowNothing then
self.Show = false
self.ShowEff = false
end
AdjustPlayerStateSimpleBJ(self.Receiver, what, self.Amount)
if not self.Color then
if self.State == "gold" then
self.Color = DEF_COLOR_GOLD
elseif self.State == "lumber" then
self.Color = DEF_COLOR_LUMBER
end
end
if self.LocPos then
self.PosX = GetLocationX(self.LocPos)
self.PosY = GetLocationY(self.LocPos)
elseif self.UnitPos then
self.PosX = GetUnitX(self.UnitPos)
self.PosY = GetUnitY(self.UnitPos)
else
self.Show = false
self.ShowEff = false --If there is no position to the text, the text and the effect won't show
end
self.TextTag = CreateTextTag()
SetTextTagPermanent(self.TextTag, self.Permanent)
SetTextTagText(self.TextTag, "|cff" .. self.Color .. Bounty.Sign(self.Amount) .. I2S(self.Amount) .. "|r", TextTagSize2Height(self.Size))
SetTextTagVisibility(self.TextTag, self:Seeing(LocalPlayer) and self.Show)
SetTextTagPos(self.TextTag, self.PosX, self.PosY, self.Height)
SetTextTagFadepoint(self.TextTag, self.FadePoint)
SetTextTagLifespan(self.TextTag, self.LifeSpan)
SetTextTagVelocityBJ(self.TextTag, self.Speed, self.Direction)
SetTextTagAge(self.TextTag, self.Age)
if self.ShowEff then
DestroyEffect(AddSpecialEffect(self.Effect, self.PosX, self.PosY))
end
current = self
what = self.TextTag
globals.BountyEvent = 0.00
globals.BountyEvent = 1.00
current = self
self:destroy()
return what
end
function BountyMT:Call(bounty, pos, myplayer, addplayer, perm)
self.Amount = bounty
self.UnitPos = pos
self.Receiver = myplayer
self:CanSee(myplayer, addplayer)
self.Permanent = perm
return self:Run()
end
function BountyMT:ChangeReceiver(newPlayer, removePrevious, addNew)
self:CanSee(self.Receiver, not removePrevious)
self.Receiver = newPlayer
self:CanSee(newPlayer, addNew)
end
Bounty = setmetatable({
--The functions to the bounty stats
SetBase = function(id, base)
Bounties0[id] = base
end,
SetDice = function(id, dice)
Bounties1[id] = dice
end,
SetSides = function(id, sides)
Bounties2[id] = sides
end,
Set = function(id, base, dice, side)
Bounty.SetBase(id, base)
Bounty.SetDice(id, dice)
Bounty.SetSides(id, side)
end,
--The static functions to get the bounty stats (that you set before)
GetBase = function(id)
return Bounties0[id] or 0
end,
GetDice = function(id)
return Bounties1[id] or 0
end,
GetSides = function(id)
return Bounties2[id] or 0
end,
Get = function(id)
return Bounty.GetBase(id) + GetRandomInt(0, Bounty.GetDice(id) * Bounty.GetSides(id))
end,
GetCurrent = function()
return current
end,
Sign = function (i)
return i < 0 and "" or "+"
end,
Copy = function (bounty)
if IsBounty(bounty) then
local new = setmetatable({}, BountyMT)
for k, v in pairs(bounty) do
new[k] = v
end
return new
else
error("Wrong argument, expected Bounty", 2)
end
end,
create = function()
Recursion = Recursion + 1
local self = setmetatable({}, BountyMT)
self.Amount = 0
self.Size = DEF_SIZE
self.LifeSpan = DEF_LIFE_SPAN
self.Age = DEF_AGE
self.Speed = DEF_SPEED
self.Direction = DEF_DIRECTION
self.FadePoint = DEF_FADE_POINT
self.State = DEF_STATE
self.Height = DEF_HEIGHT
self.Show = DEF_SHOW
self.ShowNothing = DEF_SHOW_NOTHING
self.Effect = DEF_EFFECT
self.ShowEff = DEF_SHOW_EFFECT
self.Permanent = DEF_PERMANENT
self.AllowFriendFire = DEF_ALLOW_FRIEND_FIRE
self.PosX = 0.00
self.PosY = 0.00
return self
end
},{
__index = function (t, k)
if k == "SetBase" or
k == "SetDice" or
k == "SetSides" or
k == "Set" or
k == "GetBase" or
k == "GetDice" or
k == "GetSides" or
k == "Get" or
k == "GetCurrent" or
k == "Sign" or
k == "create" then
return rawget(t, k)
else
error("This field don't exist " .. tostring(k), 2)
end
end,
__newindex = function (t, k ,v)
if k == "SetBase" or
k == "SetDice" or
k == "SetSides" or
k == "Set" or
k == "GetBase" or
k == "GetDice" or
k == "GetSides" or
k == "Get" or
k == "GetCurrent" or
k == "Sign" or
k == "create" then
rawset(t, k, v)
else
error("You can't add new fields " .. tostring(k), 2)
end
end,
__name = "Bounty",
__tostring = function (t)
return "Class: Bounty"
end
})
local oldBlizzard = InitBlizzard
function InitBlizzard()
--The trigger that runs when a unit dies
Bounty_Controller = CreateTrigger()
TriggerRegisterAnyUnitEventBJ(Bounty_Controller, EVENT_PLAYER_UNIT_DEATH)
TriggerAddCondition(Bounty_Controller, Condition(function()
return GetKillingUnit() ~= nil --If there is not killing unit then the process stop
end))
TriggerAddAction(Bounty_Controller, function()
local self = Bounty.create()
self.KillingUnit = GetKillingUnit()
self.DyingUnit = GetDyingUnit()
self.Amount = Bounty.Get(GetUnitTypeId(self.DyingUnit))
self.Receiver = GetOwningPlayer(self.KillingUnit)
self:CanSee(self.Receiver, true)
self.UnitPos = self.DyingUnit
current = self
globals.BountyDeadEvent=0.00
globals.BountyDeadEvent=1.00
current = self
if IsUnitEnemy(self.DyingUnit, self.Receiver) or self.AllowFriendFire then
self:Run()
else
self:destroy()
end
end)
--Last details
TriggerRegisterVariableEvent(t1, "BountyDeadEvent", EQUAL, 1.00)
TriggerRegisterVariableEvent(t2, "BountyEvent", EQUAL, 1.00)
LocalPlayer = GetLocalPlayer()
SetData()
oldBlizzard()
end
function RegisterBountyDeadEvent(func)
return TriggerAddAction(t1, func)
end
function TriggerRegisterBountyDeadEvent(t, func)
TriggerRegisterVariableEvent(t, "BountyDeadEvent", EQUAL, 1.00)
return TriggerAddAction(t, func)
end
function GetNativeBountyDeadTrigger()
return t1
end
function RegisterBountyEvent(func)
return TriggerAddAction(t2, func)
end
function TriggerRegisterBountyEvent(t, func)
TriggerRegisterVariableEvent(t, "BountyEvent", EQUAL, 1.00)
return TriggerAddAction(t, func)
end
function GetNativeBountyTrigger()
return t2
end
end