spawns.lua + Random map = Lua errors

The place to post your WML questions and answers.

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.
Post Reply
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

spawns.lua + Random map = Lua errors

Post by vghetto »

Hello,

This is my first post and off the bat I'm new to WML and Lua.

I managed to create a single player randomly generated map, by ripping off code from Random_Scenario.cfg, and integrating it with spawns.lua from The_Hammer_of_Thursagan campaign.

What it does is after a village is captured, an enemy peasant spawns out of the village and attacks the player.
Everything works fine expect for villages that are located on the edges of the map. In that case a Lua tries to spawn a unit outside the bounds of the randomly generated (40x40) map and throws out errors like these:

Code: Select all

20191028 22:05:34 error config: Invalid move_unit_fake destination: 32,0
20191028 22:05:34 error scripting/lua: ~add-ons/my_first_campaign/lua/spawns.lua:27: bad argument #2 to 'put_unit' (invalid location)
stack traceback:
        [C]: in field 'put_unit'
        ~add-ons/my_first_campaign/lua/spawns.lua:27: in local 'cmd'
        lua/wml-utils.lua:145: in field 'handle_event_commands'
        lua/wml-flow.lua:6: in function <lua/wml-flow.lua:5>

20191028 22:12:03 error config: Invalid move_unit_fake destination: 15,41
20191028 22:12:03 error scripting/lua: ~add-ons/my_first_campaign/lua/spawns.lua:27: bad argument #2 to 'put_unit' (invalid location)
stack traceback:
        [C]: in field 'put_unit'
        ~add-ons/my_first_campaign/lua/spawns.lua:27: in local 'cmd'
        lua/wml-utils.lua:145: in field 'handle_event_commands'
        lua/wml-flow.lua:6: in function <lua/wml-flow.lua:5>

Looking at the spawns.lua code, I see that it gets the location for where to spawn using wesnoth.get_locations like so:

Code: Select all

local locs = wesnoth.get_locations({T["not"] { T.filter {} } , T["and"] { x = x, y = y, radius = 1 } })
So, I have a few questions:
1) Is this considered a bug in the campaigns? Either The_Hammer_of_Thursagan or Eastern_Invasion (which I haven't tested, but I guess has the same problem)?

2) Or, is this considered a bug in wesnoth.get_locations (It shouldn't have returned invalid locations in the first place)?

To fix this momentarily, my guess is to pass the map dimensions (map_width map_height maybe?) as parameters to Lua and check against them, but as I said, I'm new to Lua and don't know how to do that. Any help on how to fix this would be greatly appreciated.
Thanks!
User avatar
Ravana
Forum Moderator
Posts: 3004
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: spawns.lua + Random map = Lua errors

Post by Ravana »

You should use wesnoth.get_locations({T["not"] { T.filter {} } , T["and"] { x = x, y = y, radius = 1, include_borders = false } })
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

Re: spawns.lua + Random map = Lua errors

Post by vghetto »

That fixed it for me, thank you.

Code: Select all

local locs = wesnoth.get_locations({T["not"] { T.filter {} } , T["and"] { x = x, y = y, radius = 1, include_borders = false } })
if #locs == 0 then locs = wesnoth.get_locations({T["not"] { T.filter {} } , T["and"] { x = x, y = y, radius = 2, include_borders = false } }) end
User avatar
octalot
General Code Maintainer
Posts: 786
Joined: July 17th, 2010, 7:40 pm
Location: Austria

Re: spawns.lua + Random map = Lua errors

Post by octalot »

If your random map generator can put villages next to impassible/unwalkable terrain then you should check for that too.

The two mainline maps that use this code aren't randomly generated, and all hexes adjacent to villages are walkable non-borders.
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

Re: spawns.lua + Random map = Lua errors

Post by vghetto »

octalot wrote: November 2nd, 2019, 9:21 pm If your random map generator can put villages next to impassible/unwalkable terrain then you should check for that too.

The two mainline maps that use this code aren't randomly generated, and all hexes adjacent to villages are walkable non-borders.
Yes indeed, how can that be done? I'm getting the problem you are talking about when I use the random cave generator.

I tried doing this:

Code: Select all

local locs = wesnoth.get_locations({T["not"] { T.filter {}, terrain = 'Qxu,Qxe,Qxua,Ql,Qlf,Mv,Mm^Xm,Md^Xm,Ms^Xm,Mdd^Xm,Xu,Xuc,Xue,Xos,Xom,Xoi,Xoc,Xv' } , T["and"] { x = x, y = y, radius = 1, include_borders = false } })
And this:

Code: Select all

local locs = wesnoth.get_locations({T["not"] { T.filter {}, T["and"] { x = x, y = y, radius = 1, include_borders = false, terrain = '!,Qxu,Qxe,Qxua,Ql,Qlf,Mv,Mm^Xm,Md^Xm,Ms^Xm,Mdd^Xm,Xu,Xuc,Xue,Xos,Xom,Xoi,Xoc,Xv' }  } })
but they didn't work. note the !,
Please help, thank you.
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

Re: spawns.lua + Random map = Lua errors

Post by vghetto »

None of this makes any sense to me but this seemed to have fixed the problem.

Code: Select all

                local locs = wesnoth.get_locations({T["not"] { T.filter {} }, terrain = '!,Qxu,Qxe,Qxua,Ql,Qlf,Mv,Mm^Xm,Md^Xm,Ms^Xm,Mdd^Xm,Xu,Xuc,Xue,Xos,Xom,Xoi,Xoc,Xv' , T["and"] { x = x, y = y, radius = 1, include_borders = false } })
                if #locs == 0 then locs = wesnoth.get_locations({T["not"] { T.filter {} } , terrain = '!,Qxu,Qxe,Qxua,Ql,Qlf,Mv,Mm^Xm,Md^Xm,Ms^Xm,Mdd^Xm,Xu,Xuc,Xue,Xos,Xom,Xoi,Xoc,Xv' , T["and"] { x = x, y = y, radius = 2, include_borders = false } }) end
I don't get what that T.filter is doing there exactly, could someone explain.
Also, please point out any other issues I should be looking out for, is there another or better way of doing the terrain checks? I'd like to know how. thanks.
User avatar
Celtic_Minstrel
Developer
Posts: 2214
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: spawns.lua + Random map = Lua errors

Post by Celtic_Minstrel »

The code you've written for the location filter (the T["not"] { T.filter {} }) there is:

Code: Select all

[not]
	[filter]
	[/filter]
[/not]
In a location filter, an empty [filter] tag means "match only locations with units on them", so an empty [filter] tag in a [not] tag inverts that to "match only locations with no unit on them".
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

Re: spawns.lua + Random map = Lua errors

Post by vghetto »

That makes perfect sense now. Thank you for taking the time in explaining it.
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

Re: spawns.lua + Random map = Lua errors

Post by vghetto »

If anyone is interested, I uploaded the code for my first ever wesnoth campaign to github.
I might make a proper post about it in the future. But, in general it is a SP random campaign where you can play in plain, marsh, desert or cave. There is also a beat the timer type scenario called volcano.

You start being able to recruit Sergeants only, and as you play, some of the enemy units might surrender to you. If they survive the round with you, they'll get added to your recruit list. Note, not all unit types that might surrender you'll be able to recruit.

You face anywhere from 1 up to 4 enemy factions at random. There is also a chance that one of the factions is an ally.

There are also rebels coming out of the villages in regular maps, and monsters coming out from villages in cave maps. (the reason for this thread)

Look at Credit.txt to see who I stole code from.

Code is here:
https://github.com/virtualghetto/Vaelia ... Adventures
Post Reply