Ravana's Lua thread

Discussion of Lua and LuaWML support, development, and ideas.

Moderators: Forum Moderators, Developers

Ravana's Lua thread

Postby Ravana » January 8th, 2018, 8:02 am

I have been rewriting Orocia logic in Lua. When designing format for bonuses for enemy units, I reached solution that I think should be possible to do in more elegant way.

I want to hold bonus definitions in table, where combination of turn number and difficulty setting returns what modifications to apply that turn. However, those bonuses can refer to WML variables, which should be retrieved only once it is correct turn (local adaptive_multiplier = V.ORM_difficulty_setting). I solved it by having all effects return function which when called retrieves variable and returns function.

Any suggestions how to improve this?

Relevant code parts
Code: Select all
-- each turn bonus of current turn is applied
function ORM.fun.apply_wave_modifications()
   if ORM.unit_bonuses["t"..wesnoth.current.turn] == nil then return end
   
   local difficulty = V.ORM_difficulty_mode
   local units = wesnoth.get_units { side = 1 }
   local bonus = ORM.unit_bonuses["t"..wesnoth.current.turn][difficulty]
   for i,u in ipairs(units) do
      wesnoth.add_modification(u, "trait", ORM.bonus.evaluate(bonus))
   end
end

-- functions to initialize and evaluate bonuses
function ORM.bonus.evaluate(bonus)
   local name = bonus.name
   bonus = ORM.fun.map(function(e) return e() end, bonus)
   bonus.name = name
   return bonus
end

-- Usable for building trait that includes multiple bonuses
function ORM.bonus.build(name, effects)
   effects.name = name
   return effects
end

-- bonus definition
function ORM.bonus.swift(movement_modifier, strike_modifier)
   return ORM.bonus.build("swift", {ORM.effect.increase_movement(movement_modifier), ORM.effect.increase_strikes(strike_modifier)})
end

function ORM.effect.increase_movement(movement_modifier)
   return function()
      local adaptive_multiplier = V.ORM_difficulty_setting
      return T.effect{
         apply_to = "movement",
         increase=tostring(movement_modifier*adaptive_multiplier).."%"
      }
   end
end

function ORM.effect.increase_strikes(strike_modifier)
   return function()
      local adaptive_multiplier = V.ORM_difficulty_setting
      return T.effect{
         apply_to = "attack",
         increase_attacks=tostring(strike_modifier*adaptive_multiplier).."%"
      }
   end
end

-- data file, defines initial wave bonuses
ORM.unit_bonuses = {
   t2 = {
      ultrahardcore=ORM.bonus.swift(50, 0)
   }
}

-- https://en.wikibooks.org/wiki/Lua_Functional_Programming/Functions
function ORM.fun.map(func, array)
   local new_array = {}
   for i,v in ipairs(array) do
      new_array[i] = func(v)
   end
   return new_array
end
User avatar
Ravana
Moderator
 
Posts: 1514
Joined: January 29th, 2012, 12:49 am
Location: Estonia

Re: Ravana's Lua thread

Postby Ravana » January 9th, 2018, 6:45 am

Spent an hour finding that this results in each further call of g having changed x available.
Code: Select all
y=2
function f(x)
   return function()
      x=2*x
      wesnoth.message(tostring(x))
   end
end
g = f(y)
g()
g()

Adding local keyword before assignment solved it.
User avatar
Ravana
Moderator
 
Posts: 1514
Joined: January 29th, 2012, 12:49 am
Location: Estonia

Re: Ravana's Lua thread

Postby Ravana » January 10th, 2018, 2:55 am

Is there any easy way to call modify_unit including $this_unit from Lua?
User avatar
Ravana
Moderator
 
Posts: 1514
Joined: January 29th, 2012, 12:49 am
Location: Estonia

Re: Ravana's Lua thread

Postby Ravana » January 14th, 2018, 8:35 am

Trying to find out why having this function active(with rush mod on) results in OOS. It is called on side 1 turn refresh.

Code: Select all
function ORM.fun.apply_rush_mod()
   if wesnoth.game_config.mp_settings.active_mods:find("EXI_Rush_Mod") then
      local movement_modifier
      if V.ORM_castledestruction_setting then
         movement_modifier = 1.3
      else
         movement_modifier = 1.8
      end
      if wesnoth.current.turn <= 1 then
         movement_modifier = 1
      end
      local units = wesnoth.get_units{
         side = 1,
         T["not"]{
            T.filter_wml{
               T.status{
                  ORM_rush_mod="yes"
               }
            }
         }
      }

      for i,u in ipairs(units) do
         wesnoth.add_modification(u, "object", {
            ORM.effect.get(ORM.effect.add_status("ORM_rush_mod"))
         })
         u.moves = u.moves * movement_modifier
      end
   end
end

Is it safe to add object and change writable field of same unit reference?

Likely related
Code: Select all
20180116 09:27:55< vn971> UPD: was able to solve my task "+2 movement on turn 1"  on wesnoth-1.12.
20180116 09:27:55< vn971> It consists of these steps: 1. give an object with duration="turn" with a text-only ability/description 2. Add a object with duration="forever" to increase movement. 3. At start of turn 1 for each side (event), for each unit, set unit.moves = unit.max_moves  4. At start of turn 2, add an object with duration="forever" to decrease movement.
20180116 09:31:35< vn971> step 2 is needed because replays will break if I just set movement+2 from Lua. Somewhy, when I play a game, Lua works, but when a replay is happening, such changes are not respected, wesnoth says OOS. Step 3 is needed because wesnoth apparently has a bug of not really applying movement increase on turn 1. BUT, contrary to that, replays will _accept_ the movement then. So if you modify from Lua, then game works, replays don't. If you
20180116 09:31:35< vn971>  use duration="turn" then replays work, but the game itself won't. OK, and step 4 is needed to decrease the movement back, because it was previously set with duration="forever", as I already explained why.
20180116 09:45:10< vn971> I wonder if some of those steps reveal actual wesnoth bugs ^
20180116 09:46:35< vn971> For example, allowing writing legit Lua code that will work in game but will not work in replays feels like a bug. Object with duration=turn that increases movement and does not work feels like a bug too.
20180116 09:55:17< Ravana_> that should be the cause of my current oos then
User avatar
Ravana
Moderator
 
Posts: 1514
Joined: January 29th, 2012, 12:49 am
Location: Estonia


Return to Lua Labs

Who is online

Users browsing this forum: No registered users and 1 guest