Overloading lua functions
Moderator: Forum Moderators
- lhybrideur
- Posts: 369
- Joined: July 9th, 2019, 1:46 pm
Overloading lua functions
Hi everyone,
I'm currently developing a campaign that an item management system written in lua from another add-on (LotI).
I am trying to overload a function to modify which unit can use what.
I have already succeeded for function that does not take an input parameter, but I cannot find how to do the same with a function that takes an input parameter.
Here are the function I want to overload and the function I want to use to overload it.
Original function
Custom function in main.lua
Integration of the custom function in a start event
The problem here is that I need to give the unit as an input but I don't understand how
I'm currently developing a campaign that an item management system written in lua from another add-on (LotI).
I am trying to overload a function to modify which unit can use what.
I have already succeeded for function that does not take an input parameter, but I cannot find how to do the same with a function that takes an input parameter.
Here are the function I want to overload and the function I want to use to overload it.
Original function
Code: Select all
-- Determine the list of item sorts (e.g. sword,staff,boots) that can be equipped by this unit.
-- Returns the Lua table { sword = 1, armour = 1, ... }.
function loti.util.list_equippable_sorts(unit)
local unit_type = unit.type
-- Doppelganger can't equip anything (but can drink potions).
if unit_type:match( "doppelganger" ) then
return { potion = 1 }
end
-- Everyone can equip rings/amulets/cloaks and use potions/books.
local can_equip = { ring = 1, amulet = 1, cloak = 1, potion = 1, limited = 1 }
-- All corporeal beings except bats can wear armour.
if not ( unit_type == "Ghost" or unit_type == "Wraith" or unit_type == "Spectre"
or unit_type == "Shadow" or unit_type == "Nightgaunt" or unit_type == "Dark Shade"
or unit_type:match(" Bat$") )
then
can_equip.armour = 1
can_equip.helm = 1
can_equip.gauntlets = 1
can_equip.boots = 1
end
-- Analyze the list of attacks. Allow weapons that are logical for this unit.
for attack in pairs(loti.util.list_attacks(unit)) do
if attack:match("sword$") or attack == "saber"
or attack == "war talon" or attack == "war blade"
or attack == "mberserk" or attack == "whirlwind"
or attack == "spectral blades"
then can_equip.sword = 1
elseif attack:match("axe$") or attack == "berserker frenzy"
then can_equip.axe = 1
elseif attack:match("staff$")
then can_equip.staff = 1
elseif attack == "crossbow" or attack == "slurbow"
then can_equip.xbow = 1
elseif attack:match("bow$")
then can_equip.bow = 1
elseif attack == "dagger"
then can_equip.dagger = 1
elseif attack == "knife" or attack == "throwing knives"
then can_equip.knife = 1
elseif attack == "mace" or attack == "mace-spiked"
or attack == "morning star" or attack == "club"
or attack == "flail" or attack == "scourge"
or attack == "mace_berserk" or attack == "hammer"
or attack == "hammer_runic"
then can_equip.mace = 1
elseif attack == "halberd" or attack == "scythe"
or attack == "scythe-whirlwind"
then can_equip.polearm = 1
elseif attack:match("claws$")
then can_equip.claws = 1
elseif attack == "sling" or attack == "bolas" or attack == "net"
then can_equip.sling = 1
elseif attack == "touch" or attack == "baneblade"
or attack == "faerie touch" or attack == "vine"
or attack == "torch"
then can_equip.essence = 1
elseif attack == "thunderstick" or attack == "dragonstaff"
then can_equip.thunderstick = 1
elseif attack == "spear" or attack == "javelin"
or attack == "lance" or attack == "spike"
or attack == "pike" or attack == "trident"
or attack == "trident-blade" or attack == "pitchfork"
then can_equip.spear = 1
end
end
-- Some magician-like units can carry a staff (even if they don't attack with it).
if unit_type == "Lich" or unit_type == "09 Ancient Lich" or unit_type == "Lich King"
or unit_type == "Demilich" or unit_type == "Infernal Knight"
or unit_type == "Dark Adept" or unit_type == "Elvish Shyde"
or unit_type == "Elvish Seer" or unit_type == "Elvish Sylph"
or unit_type == "Celestial Messenger" or unit_type == "Prophet"
or unit_type == "Mage of Light" or unit_type == "Stormrider"
or unit_type == "Sword Mage" or unit_type == "Knight of Magic"
or unit_type == "Warlock" or unit_type == "Faerie Incarnation"
or unit_type == "Elvish Overlord" or unit_type == "Lethalia_lich_weakened"
then
can_equip.staff = 1
end
-- Return the list of equippable item sorts for this unit
return can_equip
end
Code: Select all
-- Determine the list of item sorts (e.g. sword,staff,boots) that can be equipped by this unit.
-- Returns the Lua table { sword = 1, armour = 1, ... }.
local function list_equippable_sorts_loi(unit)
local list = loti.util.list_equippable_sorts(unit)
local unit_type = unit.type
-- Doppelganger can't equip anything (but can drink potions).
if unit_type:match( "doppelganger" ) then
return { potion = 1 }
end
-- Everyone can equip rings/amulets/cloaks and use potions/books.
local can_equip_loi = { ring = 1, amulet = 1, potion = 1}
-- All corporeal beings except bats can wear armour.
if not ( unit_type == "Ghost" or unit_type == "Wraith" or unit_type == "Spectre"
or unit_type == "Shadow" or unit_type == "Nightgaunt" or unit_type == "Dark Shade"
or unit_type:match(" Bat$") )
then
can_equip_loi.armour = 1
can_equip_loi.helm = 1
can_equip_loi.gauntlets = 1
can_equip_loi.boots = 1
end
if ( unit.type=="Dune Apothecary" or unit.type=="Young Man" or unit.type=="Dune Rover" or unit.type=="Dune Explorer" or unit.type=="Dune Ranger" or unit.type=="Dune Soldier" or unit.type=="Dune Spearguard" or unit.type=="Dune Spearmaster" or unit.type=="Dune Swordsman" or unit.type=="Dune Blademaster" or unit.type=="Dwarvish Arcanister" or unit.type=="Dwarvish Fighter" or unit.type=="Dwarvish Steelclad" or unit.type=="Dwarvish Lord" or unit.type=="Dwarvish Guardsman" or unit.type=="Dwarvish Stalwart" or unit.type=="Dwarvish Sentinel" or unit.type=="Dwarvish Runemaster" or unit.type=="Elvish Fighter" or unit.type=="Elvish Captain" or unit.type=="Elvish Marshal" or unit.type=="Cavalryman" or unit.type=="Dragoon" or unit.type=="Cavalier" or unit.type=="Heavy Infantryman" or unit.type=="Shock Trooper" or unit.type=="Iron Mauler" or unit.type=="Spearman" or unit.type=="Swordsman" or unit.type=="Royal Guard" or unit.type=="Royal Warrior" or unit.type=="Sergeant" or unit.type=="Lieutenant" or unit.type=="General" or unit.type=="Grand Marshal" or unit.type=="Merman Hoplite" or unit.type=="Naga Fighter" or unit.type=="Saurian Ambusher" or unit.type=="Saurian Flanker" or unit.type=="Chocobone" or unit.type=="Revenant" or unit.type=="Draug" or unit.type=="Silver Shield" or unit.type=="Pikeman" or unit.type=="Guardian" or unit.type=="Guard" or unit.type=="Shield Guard" or unit.type=="Legion Archer" or unit.type=="Legion Longbowman" or unit.type=="Legion Elite Longbowman" or unit.type=="Legion Horseman" or unit.type=="Legion Knight" or unit.type=="Legion Cavalier" or unit.type=="Legion Soldier" or unit.type=="Legion Swordsman" or unit.type=="Legion Champion" or unit.type=="Legion Spearman" or unit.type=="Legion Halberdier" or unit.type=="Legion Executioner" or unit.type=="Legion Trooper" or unit.type=="Legion Guardian" or unit.type=="Legion Sentinel" or unit.type=="Naga Guardian" or unit.type=="Naga Warden" or unit.type=="Naga Sentinel" or unit.type=="Chevalier" or unit.type=="Crusader" or unit.type=="Sentry" or unit.type=="Custodian" or unit.type=="Boar Rider" or unit.type=="Boar Knight" or unit.type=="Boar Cataphract" or unit.type=="Rouser" or unit.type=="Overlord" or unit.type=="Gallant Carapace" or unit.type=="Warrior Carapace" or unit.type=="Guard" or unit.type=="Protector" or unit.type=="Captain" or unit.type=="Chieftain" or unit.type=="Death Baron" or unit.type=="Skeleton Rider" or unit.type=="Bone Knight")
then
can_equip_loi.cloak = 1
end
if ( unit.type == "Elvish shaman" or unit.type == "Young Man" or unit.type == "Elvish Druid" or unit.type == "Elvish Shyde" or unit.type == "Elvish Sorceress" or unit.type == "Elvish Enchantress" or unit.type == "Elvish Sylph" or unit.type == "Dark Adept" or unit.type == "Dark Sorcerer" or unit.type == "Lich" or unit.type == "Necromancer" or unit.type == "Elder Mage" or unit.type == "Scholar" or unit.type == "Mage" or unit.type == "Red Mage" or unit.type == "Great Mage" or unit.type == "Silver Mage" or unit.type == "White Mage" or unit.type == "Mage of Light" or unit.type == "Mermaid Initiate" or unit.type == "Mermaid Enchantress" or unit.type == "Mermaid Siren" or unit.type == "Mermaid Priestess" or unit.type == "Mermaid Diviner" or unit.type == "Saurian Augur" or unit.type == "Saurian Oracle" or unit.type == "Saurian Soothsayer" or unit.type == "Troll Shaman" or unit.type == "Ancient Lich" or unit.type == "Adept" or unit.type == "Enchantress" or unit.type == "Sorceress" or unit.type == "Forest Mage" or unit.type == "Mage of Nature" or unit.type == "Tempest mage" or unit.type == "Mage of Storms" or unit.type == "Adept of Light" or unit.type == "Cleric" or unit.type == "Prophetess of Light" or unit.type == "Shaman" or unit.type == "Mystic" or unit.type == "Warlock" or unit.type == "Elder" or unit.type == "Orcish Shaman" or unit.type == "Orcish Warlock" or unit.type == "Orcish Sorcerer" or unit.type == "Shadow Initiate" or unit.type == "Shadow Mage" or unit.type == "Shadow Lord" or unit.type == "Wizard" or unit.type == "Sorcerer" or unit.type == "Empyrean Druid" or unit.type == "Moon Cleric" or unit.type == "Moon Enchantress" or unit.type == "Sun Priestess" or unit.type == "Sun Sorceress" or unit.type == "Elvish Acolyte" or unit.type == "Elvish Ascetic" or unit.type == "Elvish Mystic" or unit.type == "Elvish Avatar" or unit.type == "Sprite" or unit.type == "Fire Faerie" or unit.type == "Dryad" or unit.type == "Forest Spirit" or unit.type == "Initiate" or unit.type == "Deathmastere" or unit.type == "Lich Lord" or unit.type == "Elder Lich Lord" or unit.type == "Blood Apprentice" or unit.type == "Blood Manipulator" or unit.type == "Blood Apprentice" or unit.type == "Sangel" or unit.type == "Flesh Artisan" or unit.type == "Sire" or unit.type == "Methusalem" or unit.type == "Heretic" or unit.type == "Warmonger" or unit.type == "Scribe" or unit.type == "Savant" or unit.type == "Arbiter" or unit.type == "Rune Forger" or unit.type == "Seeker" or unit.type == "Pathfinder" or unit.type == "Skyrunner" or unit.type == "Strombringer" or unit.type == "Prophetess" or unit.type == "Ascendant" )
then
can_equip_loi.limited = 1
end
-- Analyze the list of attacks. Allow weapons that are logical for this unit.
for attack in pairs(loti.util.list_attacks(unit)) do
if attack:match("sword$") or attack == "saber"
or attack == "war talon" or attack == "war blade"
or attack == "mberserk" or attack == "whirlwind"
or attack == "spectral blades"
then can_equip_loi.sword = 1
elseif attack:match("axe$") or attack == "berserker frenzy"
then can_equip_loi.axe = 1
elseif attack:match("staff$")
then can_equip_loi.staff = 1
elseif attack == "crossbow" or attack == "slurbow"
then can_equip_loi.xbow = 1
elseif attack:match("bow$")
then can_equip_loi.bow = 1
elseif attack == "dagger"
then can_equip_loi.dagger = 1
elseif attack == "knife" or attack == "throwing knives"
then can_equip_loi.knife = 1
elseif attack == "mace" or attack == "mace-spiked"
or attack == "morning star" or attack == "club"
or attack == "flail" or attack == "scourge"
or attack == "mace_berserk" or attack == "hammer"
or attack == "hammer_runic"
then can_equip_loi.mace = 1
elseif attack == "halberd" or attack == "scythe"
or attack == "scythe-whirlwind"
then can_equip_loi.polearm = 1
elseif attack:match("claws$")
then can_equip_loi.claws = 1
elseif attack == "sling" or attack == "bolas" or attack == "net"
then can_equip_loi.sling = 1
elseif attack == "touch" or attack == "baneblade"
or attack == "faerie touch" or attack == "vine"
or attack == "torch"
then can_equip_loi.essence = 1
elseif attack == "thunderstick" or attack == "dragonstaff"
then can_equip_loi.thunderstick = 1
elseif attack == "spear" or attack == "javelin"
or attack == "lance" or attack == "spike"
or attack == "pike" or attack == "trident"
or attack == "trident-blade" or attack == "pitchfork"
then can_equip_loi.spear = 1
end
end
-- Some magician-like units can carry a staff (even if they don't attack with it).
if unit_type == "Lich" or unit_type == "09 Ancient Lich" or unit_type == "Lich King"
or unit_type == "Demilich" or unit_type == "Infernal Knight"
or unit_type == "Dark Adept" or unit_type == "Elvish Shyde"
or unit_type == "Elvish Seer" or unit_type == "Elvish Sylph"
or unit_type == "Celestial Messenger" or unit_type == "Prophet"
or unit_type == "Mage of Light" or unit_type == "Stormrider"
or unit_type == "Sword Mage" or unit_type == "Knight of Magic"
or unit_type == "Warlock" or unit_type == "Faerie Incarnation"
or unit_type == "Elvish Overlord" or unit_type == "Lethalia_lich_weakened"
then
can_equip_loi.staff = 1
end
-- Return the list of equippable item sorts for this unit
list.can_equip = can_equip_loi
end
return { list_equippable_sorts_loi = list_equippable_sorts_loi}
Code: Select all
[event]
name = start
[lua]
code = << wesnoth.require('~add-ons/Legends_of_Idaamub_beta/lua/main').list_equippable_sorts_loi() >>
[/lua]
[/event]
Last edited by lhybrideur on July 22nd, 2020, 8:17 am, edited 2 times in total.
- Elvish_Hunter
- Posts: 1575
- Joined: September 4th, 2009, 2:39 pm
- Location: Lintanir Forest...
Re: Overloading lua functions
So the problem isn't "how to override a Lua function", but "how to pass a unit as argument to a function called into a Lua tag".lhybrideur wrote: ↑July 15th, 2020, 1:47 pm The problem here is that I need to give the unit as an input but I don't understand how
The fact is that the start event doesn't have auto-stored primary and secondary units, otherwise you could've used the [args] sub-tag to pass its ID to a wesnoth.get_units() call and acquire the unit in this way.
Perhaps your best bet would be to assign the result of wesnoth.require to a variable (let's call it
loi_helper
), then acquire all the units you want with wesnoth.get_units(), iterate over them with an ipairs cycle and run your function on all of them.Completely untested code:
Code: Select all
[event]
name = start
[lua]
code = <<
local loi_helper = wesnoth.require('~add-ons/Legends_of_Idaamub_beta/lua/main')
for index, unit in ipairs(wesnoth.get_units({ side = 1 }) do
loi_helper.list_equippable_sorts_loi(unit)
end
>>
[/lua]
[/event]
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
- lhybrideur
- Posts: 369
- Joined: July 9th, 2019, 1:46 pm
Re: Overloading lua functions
Nice. I like it. Thank you very much. I will try that right now.
I only hope unit is not dynamically filled by another function somewhere.
P.S.: I changed the title.
I only hope unit is not dynamically filled by another function somewhere.
P.S.: I changed the title.
- lhybrideur
- Posts: 369
- Joined: July 9th, 2019, 1:46 pm
Re: How to pass a unit as argument to a function called into a Lua tag
It does not crash, but neither does it work. I think I need to find when
I will post when I have found.
list_equippable_sorts_loi(unit)
is called so as to call my overloading function at the right time. I will post when I have found.
- lhybrideur
- Posts: 369
- Joined: July 9th, 2019, 1:46 pm
Re: Overloading lua functions
So, the function is called dynamically at the beginning of another function.
So I am back to trying to overload list_equippable_sorts(unit)
I can get loti.util from anywhere but I don't understand how to change what returns loti.util.list_equippable_sorts(unit)
If nothing else works, I will copy paste the whole file in my add-on, but that would be the ugly way around
Code: Select all
local function onshow(unit)
local equippable_sorts = loti.util.list_equippable_sorts(unit)
.
.
.
end
I can get loti.util from anywhere but I don't understand how to change what returns loti.util.list_equippable_sorts(unit)
If nothing else works, I will copy paste the whole file in my add-on, but that would be the ugly way around