Latest Posts

Topic: Give goods periodically in script

PkK

Topic Opener
Joined: 2012-01-06, 11:19
Posts: 236
Ranking
Widelands-Forum-Junkie
Posted at: 2015-02-18, 19:36

I used to have modified startiong conditions that periodically would give goods for build 18. I updated them (name of wares, etc) for current bzr, but they are not working (I do not see the expected periodic jump in wares). Here's the one for barbarians:

http://colecovision.eu/stuff/sc64_headquarters_cheat.lua

What am I doing wrong?

Philipp


Top Quote
GunChleoc
Avatar
Joined: 2013-10-07, 14:56
Posts: 3324
Ranking
One Elder of Players
Location: RenderedRect
Posted at: 2015-02-18, 19:43

You will definitely want the commented out get_buildings function. It will give you an array, but since the player has only 1 headquarter, you can simply grab the first element. Something like this should work:

for i=1,100000 do
     sleep(600000)
     local hq = wl.Game().players[player.number].get_buildings("headquarters")[1]

      if hq:get_wares("water") < 1280 then
         hq:set_wares("water", hq:get_wares("water") + 128)
       end

Headquarters are always warehouses, so you don't need the check there.

Documentation for get_buildings is on this page:

https://wl.widelands.org/docs/wl/autogen_wl_game/

Edited: 2015-02-18, 19:48

Busy indexing nil values

Top Quote
PkK

Topic Opener
Joined: 2012-01-06, 11:19
Posts: 236
Ranking
Widelands-Forum-Junkie
Posted at: 2015-02-18, 19:53

What's the issue with
local hq = wl.Game().map:get_field(sf.x, sf.y).immovable
it seemed to work fine in build 18 (and would work no matter if the starting building was a hq or a warehouse). Also, your proposal looks like it might fail if the starting building no longer exists.

Unfortunately, your prosal gives me

[../src/scripting/lua_errors.cc:22] [string "tribes/barbarians/scripting/sc64_headquarters..."]:80: bad argument #1 to 'get_buildings' (table expected, got string)


Philipp
Edited: 2015-02-18, 19:53

Top Quote
PkK

Topic Opener
Joined: 2012-01-06, 11:19
Posts: 236
Ranking
Widelands-Forum-Junkie
Posted at: 2015-02-18, 20:21

Actually on checking closer, I see that the only thing that fails with my script is the test of the type. I need that one to make sure I have a warehouse or hq atthe tsart location.

Did the type change since buid 18? What should I check for now instead of

hq.type == "warehouse"
Edited: 2015-02-18, 20:22

Top Quote
PkK

Topic Opener
Joined: 2012-01-06, 11:19
Posts: 236
Ranking
Widelands-Forum-Junkie
Posted at: 2015-02-18, 20:31

Found out by trial and error: It needs to be "Warehouse" insetad of "warehouse".

Philipp

Edit: Sorry, false positive, forgot to save after enabling check. I still don'tknow how to check that I have a hq.

Edited: 2015-02-18, 20:36

Top Quote
wl-zocker

Joined: 2011-12-30, 16:37
Posts: 495
Ranking
Tribe Member
Location: Germany
Posted at: 2015-02-18, 20:55

It needs to be local hq = wl.Game().players[player.number]:get_buildings("headquarters")[1] with a colon before get_buildings() (don't ask me why).

From infrastructure.lua: immovable.descr.type_name == "warehouse".

You can also use the following which is more general (not checked, I have not worked with Lua for a while now, so I do not remember the exact syntax):

local wh = wl.Game().players[player.number]:get_buildings("headquarters")[1] or wl.Game().players[player.number]:get_buildings("warehouse")[1]

-- which is equivalent to

local wh = wl.Game().players[player.number]:get_buildings("headquarters")[1]
if wh = nil then wh = wl.Game().players[player.number]:get_buildings("warehouse")[1]
-- you can add ports if you want

You are right, you need to check if you found a building at all (if wh then), but not for its type.

This way is more general because a) you can easily add it to fortified_village, where the citadel is at sf.x, sf.y and b) it still gives you resources when the headquarters has been destroyed.

Some general notes:

  • Your idea with get_field().immovable should work, but you need to check the type then.
  • You can use while true do if you want an infinite loop.
  • You can give yourself bread and strong beer periodically so that the battle arena works.
Edited: 2015-02-18, 20:56

"Only few people know how much one has to know in order to know how little one knows." - Werner Heisenberg

Top Quote
PkK

Topic Opener
Joined: 2012-01-06, 11:19
Posts: 236
Ranking
Widelands-Forum-Junkie
Posted at: 2015-02-18, 21:04

Thanks for the long reply. I'll look into your warehouse finding later.

I had just found out about [code] immovable.descr.type_name [/code] Myself (using grep in the widelands directory)

Now let's see if this works to make a game against multiple AIs challenging (worked reasonable in build 18).

Philipp


Top Quote
SirVer

Joined: 2009-02-19, 14:18
Posts: 1445
Ranking
One Elder of Players
Location: Germany - Munich
Posted at: 2015-02-19, 06:00

It needs to be local hq = wl.Game().players[player.number]:get_buildings("headquarters")[1] with a colon before get_buildings() (don't ask me why).

I can clear that up :). Details are here, but what is boiling down to is that the colon is just syntactic sugar. That means the next two lines are exactly the same:

p:a_function(a, b)

is the same in Lua as

p.a_function(p, a, b)

So the column means: pass the table that stands before the column as the first argument to the function I am calling after it.


Top Quote
wl-zocker

Joined: 2011-12-30, 16:37
Posts: 495
Ranking
Tribe Member
Location: Germany
Posted at: 2015-02-19, 07:27

SirVer wrote:

It needs to be local hq = wl.Game().players[player.number]:get_buildings("headquarters")[1] with a colon before get_buildings() (don't ask me why).

I can clear that up :). Details are here, but what is boiling down to is that the colon is just syntactic sugar. That means the next two lines are exactly the same:

p:a_function(a, b)

is the same in Lua as

p.a_function(p, a, b)

So the column means: pass the table that stands before the column as the first argument to the function I am calling after it.

I have read the tutorial linked there when I was creating the tutorials. What is still unclear to me: How do I know/find out whether I have to use p.func(a) and when p:func(a) other than by trial-and-error or looking at examples in the code? That is, is there a way to document that in the .cc files from which the documentation is created? These docs are the place where I expect(ed) such things.


"Only few people know how much one has to know in order to know how little one knows." - Werner Heisenberg

Top Quote
GunChleoc
Avatar
Joined: 2013-10-07, 14:56
Posts: 3324
Ranking
One Elder of Players
Location: RenderedRect
Posted at: 2015-02-19, 07:36

I think we would all benefit from having short usage examples for the more complicated functions. I found the documentation for this function difficult to read as well.


Busy indexing nil values

Top Quote