Buffs in runtime

Everything about mods can be found here.

Moderator: Morax

Buffs in runtime

Postby PerfectWay » 06 Dec 2017, 21:03

Hi, all
I want to learn how to add some bonuses to units in the game. For example, + 10% to health or + 10% to damage.
I know how to do this before starting the game by modifying the blueprints
Code: Select all
function ModBlueprints(all_bps)
...
but I need it so that it can be done taking into account some condition, for example, pressing a button or building a certain structure, as in ExperimentalWar 2.8. For example, we are building a structure that raises the health of all mobile units by 50%, so after its completion, the characteristics of all existing units must be recalculated, and the characteristics of new units should take into account this bonus.
How can I implement such functionality? Maybe someone has already used this? I will be grateful for any advice.
PerfectWay
Crusader
 
Posts: 32
Joined: 12 Apr 2016, 10:51
Has liked: 6 times
Been liked: 0 time
FAF User Name: LastDragon

Re: Buffs in runtime

Postby PhilipJFry » 06 Dec 2017, 21:26

i don't know a lot about modding but what you try to do seems like something that the Alliance of Heroes mod can do
maybe franck83 can lend you a hand
cats>dogs
post logs
User avatar
PhilipJFry
Supreme Commander
 
Posts: 2635
Joined: 23 Mar 2016, 21:16
Location: Austria
Has liked: 232 times
Been liked: 348 times
FAF User Name: PhilipJFry

Re: Buffs in runtime

Postby Franck83 » 07 Dec 2017, 00:17

Hi PerfectWay,


You need some prerequisites to do what you want :

Ui (all user interface tools) and sim (all units, weapons and projectiles methods...) are running in different threads. So data exchanging is not automatic.

For example, if you want to click on a ok button of a dialog (Ui) and trigger a buff (sim), you need to use simcallbacks (this will send your data from ui to sim) :

(I assume you know how to create a dialog or a button in Ui)

Let's do it for a buildrate bonus :

Code: Select all
...
okBtn.OnClick = function(self)
...
   SimCallback   ({Func= 'SetBuildingSpeed', Args = {id = _id, BuildingRate = Your building rate}})
   dialog:Close()
end



You need to register your callback by hooking SimCallbacks.lua and type your function path :

Code: Select all
Callbacks.SetBuildingSpeed = import('/Mods/Heroes_Reloaded/Modules/UiToSim.lua').SetBuildingSpeed



Then in your file UiToSim.lua (you can type another path or file name) :

Code: Select all
function SetBuildingSpeed(Unit)
    local id = Unit.id
    local unit = GetUnitById(id)
    unit:SetBuildingRate(Unit.BuildingRate)
end



Then you need to hook unit.lua and add a function :

Code: Select all
SetBuildingRate = function(self, BuildRate)
       BuffBlueprint {
         Name = 'BuildingRateBuff',
         DisplayName = 'BuildingRateBuff',
         BuffType = 'BuildingRateBuff',
         Stacks = 'REPLACE',
         Duration = -1,
         Affects = {
            BuildRate = {
               Add = BuildRate or 0,
               Mult = 1,
            },
         },
   }
      Buff.ApplyBuff(self, 'BuildingRateBuff')
end,


You can do the same thing with other affects DamageRadius, Regen, MaxHealth....

I didn't test the code but i use theses features a lot in my mod.

For the buffs when you create a building, i recommend you to hook the OnStopBeingBuilt function in unit.lua.
Here you can test the kind of building made and if it's ok you can trigger your SetBuildingRate function in unit.lua.
Maybe your need to test it when it is destroyed to remove the buff.

Hope this will help, good luck !

Edit : i corrected a code error.
Last edited by Franck83 on 10 Dec 2017, 00:01, edited 2 times in total.
Alliance of Heroes Mod is out ! Try it ! It's in the Mod Vault !
User avatar
Franck83
Evaluator
 
Posts: 538
Joined: 30 Dec 2016, 11:59
Location: France
Has liked: 114 times
Been liked: 122 times
FAF User Name: Franck83

Re: Buffs in runtime

Postby PerfectWay » 09 Dec 2017, 23:17

Many thanks, Franck83, very detailed answer
Now I have a small question about the hooking mechanism: I have to create a full copy of the file and add the code to the desired function or I can make a file with the same name, but change only the function that I need, for example OnStopBeingBuilt in Unit.lua?
PerfectWay
Crusader
 
Posts: 32
Joined: 12 Apr 2016, 10:51
Has liked: 6 times
Been liked: 0 time
FAF User Name: LastDragon

Re: Buffs in runtime

Postby Franck83 » 09 Dec 2017, 23:56

If you want to hook unit.lua, you need to create a hook rep and follow the unit.lua original path.

\Mods\YourModName\Hook\lua\sim\unit.lua

So then you need to create an empty lua file called unit.lua.

This the hook code to add in your unit.lua (you need to hook the class and the function) :

Code: Select all
local OldUnit = Unit
Unit = Class(OldUnit) {
     OldOnStopBeingBuilt = Unit.OnStopBeingBuilt,
     OnStopBeingBuilt = function(Unit, builder, layer)
         Unit.OldOnStopBeingBuilt(Unit, builder, layer) -- Here you call the old function
         -- Add here your code.
     end,
}


So the engine will execute your code after executing the original OnStopBeingBuilt function.

Good luck !
Alliance of Heroes Mod is out ! Try it ! It's in the Mod Vault !
User avatar
Franck83
Evaluator
 
Posts: 538
Joined: 30 Dec 2016, 11:59
Location: France
Has liked: 114 times
Been liked: 122 times
FAF User Name: Franck83

Re: Buffs in runtime

Postby Franck83 » 10 Dec 2017, 00:13

An easy way to do what you want is to add a category in your building unit blueprint that will trigger the buff :

Example : adding a RESEARCHCENTER category.

Code: Select all
Categories = {
        'RESEARCHCENTER', -- Your add
        'SELECTABLE',
...
    },



Then in your unit.lua

Code: Select all
local OldUnit = Unit
Unit = Class(OldUnit) {
         OldOnStopBeingBuilt = Unit.OnStopBeingBuilt,
         OnStopBeingBuilt = function(Unit, builder, layer)
            Unit.OldOnStopBeingBuilt(Unit, builder, layer) -- Here you call the old function
            if Unit then
                local id = Unit:GetEntityId()
                local bp = Unit:GetBlueprint()
                if table.find(bp.Categories, 'RESEARCHCENTER') then
                    -- Cast your buff
                end
            end
         end,
}
Last edited by Franck83 on 10 Dec 2017, 00:29, edited 1 time in total.
Alliance of Heroes Mod is out ! Try it ! It's in the Mod Vault !
User avatar
Franck83
Evaluator
 
Posts: 538
Joined: 30 Dec 2016, 11:59
Location: France
Has liked: 114 times
Been liked: 122 times
FAF User Name: Franck83

Re: Buffs in runtime

Postby PerfectWay » 10 Dec 2017, 00:26

Thanks, i will try to implement this
PerfectWay
Crusader
 
Posts: 32
Joined: 12 Apr 2016, 10:51
Has liked: 6 times
Been liked: 0 time
FAF User Name: LastDragon

Re: Buffs in runtime

Postby Franck83 » 10 Dec 2017, 00:39

When you will cast your buff, it depends if you want to apply it on new units only or on already built .

You may need this function for immediate buff on already build units :

Code: Select all
local units = Unit:GetAIBrain():GetUnitsAroundPoint(categories.MOBILE, Unit:GetPosition(), 1000, 'Ally') -- grab all mobile units in 1000 area distance around your research center
BuffBlueprint {
         Name = MaxHealthBuff',
         DisplayName = 'MaxHealthBuff',
         BuffType = 'MaxHealth',
         Stacks = 'REPLACE',
         Duration = -1,
         Affects = {
            MaxHealth = {
                Mult = 1.2, -- 20% Max Health buff
            },
         },
}

for k, unit in units do
    -- casting your buff on each grabbed unit
    Buff.ApplyBuff(unit , 'MaxHealthBuff')
end
Alliance of Heroes Mod is out ! Try it ! It's in the Mod Vault !
User avatar
Franck83
Evaluator
 
Posts: 538
Joined: 30 Dec 2016, 11:59
Location: France
Has liked: 114 times
Been liked: 122 times
FAF User Name: Franck83

Re: Buffs in runtime

Postby Franck83 » 10 Dec 2017, 16:48

I'm just thinking that since your building triggers the buffs, a better way (or the perfectway :)) would be to just edit your individual unit script.

For example, building a UEF radar (UEB3101_Script.lua) providing a 20% vision buff to all existing (only) units around :
Code: Select all
local Buff = import('/lua/sim/buff.lua')
local TRadarUnit = import('/lua/terranunits.lua').TRadarUnit

UEB3101 = Class(TRadarUnit) {
   OnStopBeingBuilt = function(self,builder,layer)
      TRadarUnit.OnStopBeingBuilt(self,builder,layer)
      local units = self:GetAIBrain():GetUnitsAroundPoint(categories.MOBILE, self:GetPosition(), 1000, 'Ally') -- grab all mobile units in 1000 area distance around the radar
      BuffBlueprint {
         Name = 'VisionRadius',
         DisplayName = 'VisionRadius',
         BuffType = 'VisionRadius',
         Stacks = 'REPLACE',
         Duration = -1,
         Affects = {
            VisionRadius = {
            Mult = 1.2, -- +20% vision radius
         },
      },
      for k, unit in units do
         Buff.ApplyBuff(unit , 'VisionRadius')
      end         
   }
end,
}
TypeClass = UEB3101
Alliance of Heroes Mod is out ! Try it ! It's in the Mod Vault !
User avatar
Franck83
Evaluator
 
Posts: 538
Joined: 30 Dec 2016, 11:59
Location: France
Has liked: 114 times
Been liked: 122 times
FAF User Name: Franck83

Re: Buffs in runtime

Postby PerfectWay » 12 Dec 2017, 22:36

This is a good idea, but what about the units that will be built after the radar is completed? For them, the buff will not be applied. A radius of 1000 is how much this is? What is the metric system based on?
PerfectWay
Crusader
 
Posts: 32
Joined: 12 Apr 2016, 10:51
Has liked: 6 times
Been liked: 0 time
FAF User Name: LastDragon

Next

Return to Mods & Tools

Who is online

Users browsing this forum: No registered users and 1 guest