Overriding unit advancements
Moderator: Forum Moderators
Forum rules
- Please use [code] BBCode tags in your posts for embedding WML snippets.
- To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
Overriding unit advancements
Hello,
I am planning on changing the modification I am currently using for my Reign of the Lords add-on. Currently in SP I am using [advancefrom] but that is unwieldy and bad practice so I want to change to use events instead.
But the main disadvantage that using events has is that it does not display unit upgrades in the help menu. So my first question: is there anyway to update the help menu?
Secondly I am wondering what the best implementation for would be for the events?
Currently I am considering a
However, I thought to ask if there are any unforeseen side effects of that type of event? Also I wanted to ask if there is any better method of implementing?
A few people have mentioned using
I also considered a combination of
Would this number of events be a problem or negatively effect campaigns?
Thank you for your thoughts! Any ideas or suggestions would be welcome as I work through this idea and hopefully reach a better solution than [advancefrom].
I am planning on changing the modification I am currently using for my Reign of the Lords add-on. Currently in SP I am using [advancefrom] but that is unwieldy and bad practice so I want to change to use events instead.
But the main disadvantage that using events has is that it does not display unit upgrades in the help menu. So my first question: is there anyway to update the help menu?
Secondly I am wondering what the best implementation for would be for the events?
Currently I am considering a
pre advance
event that would check if the unit has any alternate advancements and if so modify them to display these alternate advancements:Code: Select all
[event]
name=pre advance
first_time_only=no
[filter]
type={UNIT}
[/filter]
{STORE_UNIT_VAR (id=$unit.id) advances_to unit_advances_to}
# check if this has already been done to this unit
[if]
[variable]
name=unit_advances_to
equals={ADVANCES_TO}
[/variable]
[then]
# IF SO then don't do it again
[/then]
[else]
# IF NOT than modify so the unit advances properly
[modify_unit]
[filter]
id=$unit.id
[/filter]
advances_to={ADVANCES_TO}
[/modify_unit]
[/else]
[/if]
{CLEAR_VARIABLE unit_advances_to}
[/event]
A few people have mentioned using
unit placed
events but unfortunately if a spearman is placed and then the spearman advances to a javelineer the javelineer doesn't count as being 'placed' and therefore is not modified. However, unit placed is more optimal because it modifies units immediately rather than after the fact which allows the player to see that they can advance (through the blue XP bar).I also considered a combination of
unit placed,post advance
event that would then account for all units which are either placed or advanced into. However, this is twice as many event conditions that need to be processed for every unit (and there are about 100). Would this number of events be a problem or negatively effect campaigns?
Thank you for your thoughts! Any ideas or suggestions would be welcome as I work through this idea and hopefully reach a better solution than [advancefrom].
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon.
Re: Overriding unit advancements
I think it would make sense to fire unit_placed after advancement.
It might be best solution to generate base_unit for everything, and on unit placed replace types.
If you are worried about number of events, can use single event for all of them. That would be easier with Lua mapping.
It might be best solution to generate base_unit for everything, and on unit placed replace types.
If you are worried about number of events, can use single event for all of them. That would be easier with Lua mapping.
Re: Overriding unit advancements
So are you saying that unit_placed is currently fired after advancement?
Okay yes I can do that, I currently am only generating events to override the advancements but I have base units for all of the units that have been modified so I can easily implement that instead.It might be best solution to generate base_unit for everything, and on unit placed replace types.
Okay thank you I will give that a try.If you are worried about number of events, can use single event for all of them. That would be easier with Lua mapping.
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon.
Re: Overriding unit advancements
The only disadvantage of the above method is that whenever you place a unit (for example when you recruit) it looks odd because it creates him and then reloads him.
Is there a way not to animate the [modify_unit] ?
Is there a way not to animate the [modify_unit] ?
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon.
Re: Overriding unit advancements
If you use lua you can modify the units stats directly by settign arributes instead of [midify_unit]. modify_unit also has the disadvantage that the effect will be lost when the unit is rebuild, for example when remove_object is called, this again can be fiuxed with a custom lua effect, then you also won't need the post_advance event anymore, untested code:
Code: Select all
[lua]
code = <<
local on_event = wesnoth.require("on_event")
--makes Spearman advance to bowman.
local unittable = {
["Spearman"] = { "Bowman"},
["Bowman"] = {"Knight"},
}
function wesnoth.effects.osd_fix_advancements(u)
local advances_to = unittable[u.type]
if advances_to then
u.advances_to= advances_to
end
end
on_event("unit_placed", function(cx)
local u = wesnoth.get_unit(cx.x1, cx.y1)
if u and not u.variables.has_osd_fix_advancements then
u.variables.has_osd_fix_advancements = true
u:add_modification("object", { wml.tag.effect { apply_to = "osd_fix_advancements" } } )
end
end)
>>
[/lua]
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.
Re: Overriding unit advancements
That is a good idea. I think lua be better in general but I never got around to learning the lua's syntax so I don't know if I could implement the events.
Basically I would like an event that modifies the advancements of a number of units. So if I wanted to make the code work for more units would I just add more strings to the unittable?
EDIT: Btw your code works well thank you! But I wonder, can I add any number of units like this?
EDIT 2: Error "unkown unit type: ROLElvish Ranger,ROLElvish Marksman"
I got this error when trying to assign the unit to advance to 2 different units. Is this not allowed in lua?
Basically I would like an event that modifies the advancements of a number of units. So if I wanted to make the code work for more units would I just add more strings to the unittable?
EDIT: Btw your code works well thank you! But I wonder, can I add any number of units like this?
Code: Select all
[lua]
code = <<
local on_event = wesnoth.require("on_event")
-- table --
-- ALL THE UNITS ON THE LEFT NOW ADVANCE TO THE UNITS ON THE RIGHT
-- table --
local unittable = {
["Elder Wose"] = { "ROLAncient Wose,ROLAncient Wose Shaman"},
["Ancient Wose"] = {"ROLArch Wose"},
["Wose"] = {"ROLElder Wose"},
["Elvish Sylph"] = { "ROLElvish Hierophant"},
["Elvish Sorceress"] = {"ROLElvish Enchantress,ROLElvish Battle Druid"},
["Elvish Hero"] = { "ROLElvish Prowler,ROLElvish Champion"},
["Elvish Druid"] = {"ROLElvish Shyde,ROLElvish Mystic"},
["Elvish Archer"] = { "ROLElvish Ranger,ROLElvish Marksman"},
["Elvish Avenger"] = { "ROLElvish Vendicator"},
["Elvish Champion"] = {"ROLElvish Halberdier,ROLElvish Legend"},
["Elvish High Lord"] = { "ROLElvish Majestic"},
["Elvish Marshal"] = {"ROLElvish Grand Master"},
["Elvish Sharpshooter"] = { "ROLElvish Deadeye"},
["Elvish Shyde"] = {"ROLElvish Star"},
["Elvish Outrider"] = { "ROLElvish Swift,ROLElvish Gryphonier"},
}
function wesnoth.effects.osd_fix_advancements(u)
local advances_to = unittable[u.type]
if advances_to then
u.advances_to= advances_to
end
end
on_event("unit_placed", function(cx)
local u = wesnoth.get_unit(cx.x1, cx.y1)
if u and not u.variables.has_osd_fix_advancements then
u.variables.has_osd_fix_advancements = true
u:add_modification("object", { wml.tag.effect { apply_to = "osd_fix_advancements" } } )
end
end)
>>
[/lua]
I got this error when trying to assign the unit to advance to 2 different units. Is this not allowed in lua?
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon.
Re: Overriding unit advancements
Most likely u.advances_to expects array {"a","b"}.
Re: Overriding unit advancements
Okay thank you I will try that
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon.
Re: Overriding unit advancements
Unfortunately the code doesn't seem to work on leaders. Or other units who are placed at the start. Is that expected behavior or have I messed up something?
EDIT: No not all units that are placed at the start of the scenario don't work so it must be a mistake I have made. It is seemingly unpredictable behavior but it appears units that are placed at the beginning when the map is created often do not advance properly. I will look into it further and post.
EDIT: No not all units that are placed at the start of the scenario don't work so it must be a mistake I have made. It is seemingly unpredictable behavior but it appears units that are placed at the beginning when the map is created often do not advance properly. I will look into it further and post.
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon.
Re: Overriding unit advancements
You coudl just also add the osd_fix_advancements object in a prestart event to cover these aswell. like adding
to my code above.
Also note that this [lua] tag should not go into an [event] but instead should be directly placed under [era]/[scenario] etc. basicially where you'd also place events.
Code: Select all
on_event("prestart", function()
for i, u in ipairs(wesnoth.get_units({})) do
if not u.variables.has_osd_fix_advancements then
u.variables.has_osd_fix_advancements = true
u:add_modification("object", { wml.tag.effect { apply_to = "osd_fix_advancements" } } )
end
end
end)
Also note that this [lua] tag should not go into an [event] but instead should be directly placed under [era]/[scenario] etc. basicially where you'd also place events.
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.
Re: Overriding unit advancements
Okay thank you! I actually am not using an era or scenario but instead a modification. Can I put it into the modification tag? Currently it is in an event inside a modification which may be the cause if the error.
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon.
Re: Overriding unit advancements
Great thank you!
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon.
Re: Overriding unit advancements
The code worked perfectly now that I put it directly into the modification! Also I was wondering are #ifdef 's supported within lua code?
EDIT: Apparently not
The reason I ask is because I was wondering if it is possible to define some of my advancements only if a certain campaign is running. But if that is not possible then I won't worry about it because it is not too critical.
EDIT: Apparently not
The reason I ask is because I was wondering if it is possible to define some of my advancements only if a certain campaign is running. But if that is not possible then I won't worry about it because it is not too critical.
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon.
Re: Overriding unit advancements
It's possible to do the samewith luas 'if'. but it requires some knowledge about the lua programming language. (variabe scope, how to add element to tables etc)
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.