Lua Parameters Help

Scapeh

Chieftain
Joined
May 20, 2020
Messages
7
Location
UK
Hey!
I currently have a working mod for razing cities if they are hit by a nuclear weapon, and it works very well, the only issue is, it doesn't work for the AI.
This is something that I would like as it would be game changing if it could. A way of "fixing" the issue with the AI nuking the same city repeatedly.

I can't work out why it doesn't work for them, I'm assuming the events used to call it aren't used for AI actions?

Here is my WorldInput.lua:

Code:
include("WorldInput_Expansion2.lua");

function WMDStrike( plot, unit, eWMD )
    local tParameters = {};
    tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
    tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
    tParameters[UnitOperationTypes.PARAM_WMD_TYPE] = eWMD;
 
    if (UnitManager.CanStartOperation(unit, UnitOperationTypes.WMD_STRIKE, nil, tParameters)) then
        ExposedMembers.City_Razing.Strike_Parameters = {X = tParameters[UnitOperationTypes.PARAM_X], Y = tParameters[UnitOperationTypes.PARAM_Y], Warhead = eWMD};
    
        UnitManager.RequestOperation(unit, UnitOperationTypes.WMD_STRIKE, tParameters);
        UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
    end
end

function ICBMStrike( fromCity, sourcePlotX, sourcePlotY, targetPlot, eWMD )
    local tParameters = {};
    tParameters[CityCommandTypes.PARAM_X0] = sourcePlotX;
    tParameters[CityCommandTypes.PARAM_Y0] = sourcePlotY;
    tParameters[CityCommandTypes.PARAM_X1] = targetPlot:GetX();
    tParameters[CityCommandTypes.PARAM_Y1] = targetPlot:GetY();
    tParameters[CityCommandTypes.PARAM_WMD_TYPE] = eWMD;

    if (CityManager.CanStartCommand(fromCity, CityCommandTypes.WMD_STRIKE, tParameters)) then
        ExposedMembers.City_Razing.Strike_Parameters = {X = tParameters[UnitOperationTypes.PARAM_X1], Y = tParameters[UnitOperationTypes.PARAM_Y1], Warhead = eWMD};

        CityManager.RequestCommand(fromCity, CityCommandTypes.WMD_STRIKE, tParameters);
        UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
    end
end

function City_Razing_Initialize()
    if (not ExposedMembers.City_Razing) then
        ExposedMembers.City_Razing = {};
    end
end
City_Razing_Initialize();

I'm sure i'm doing something wrong as my Lua knowledge is very limited, but i'd love to know if there's a way for the AI to utilize this?
 
Last edited:
I've managed to get it to work a lot better by hooking onto WMDDetonated Event, works completely flawless for the player.

This function fires when the AI nukes a city but nothing happens, looks like the parameters used in my WorldInput don't work for the AI - Is there another way to get the AI's target plot when they choose a nuke target, or am I just doing something wrong?

Thanks in advance!
 
Last edited:
I thought that may be the case, I'm guessing we currently have no way of checking their targets, or checking which plots have fallout on them etc with what's currently available to us?
Thanks though :thumbsup:
 
There is something like Game.GetFalloutManager(); with functions like GetFalloutTurnsRemaining(), SetFalloutTurnsRemaining(), AddFallout(), RemoveFallout(), GetFalloutPreventsWork(), SetFalloutPreventsWork()
Combine this with events WMDDetonated and WMDFalloutChanged.
What else do you need?
 
Ah those are quite useful, however I'm still quite new to Lua. Do you know if it's possible to write something that will check for the presence of fallout on all cities on the map with the WMDDetonated event?
This could be used to then remove cities on those plots.
This would eliminate the need for WorldInput changes, and also make it work for the AI.

This is what I currently use for the player only:

Code:
local Remove_City:boolean = true;

function CheckArea()
    if (ExposedMembers.City_Razing.Strike_Parameters ~= nil) then
        local Plot = Map.GetPlot(ExposedMembers.City_Razing.Strike_Parameters.X, ExposedMembers.City_Razing.Strike_Parameters.Y);
      
        if (Plot ~= nil) then
            CheckPlot(Plot);
        end
        ExposedMembers.City_Razing.Strike_Parameters = nil;
    end
end

function CheckPlot(Plot:table)
    if Plot:IsCity() then
         if Remove_City then
            WorldBuilder.CityManager():RemoveAt(Plot);
        end
    end
end

function OnWMDDetonated(players)
    local players:table = Game:GetPlayers();
    for i, pPlayer in ipairs(players) do
        CheckArea();
        print("Razing City");
    end
end

function Initialize() 
    if (not ExposedMembers.City_Razing) then
        ExposedMembers.City_Razing = {};
    end

    Events.WMDDetonated.Add(OnWMDDetonated);
end
Initialize();
 
Last edited:
Are you sure that this detonated event just doesn’t pass coordinates of the strike? Because that would be the first thing I would check. Use ... parameter and print out all of them.
If coordinates are not passed, then just scan the entire map for new fallout and detect the middle of it which would be a city. Or if you want to destroy the city even if it was not a direct hit, then any fallout plot with a city would do.
 
Wow that's actually great thanks, I didn't know about checking for parameters like that, that event passes 4 args and it looks like it's the exact plot coordinates. I tested nuking various tiles.

I'm not really sure how to call the params for the event to use as a plot location, as they are just numbers :crazyeye:
 
Last edited:
Hey, thanks guys!
It just turns out I was just not looking hard enough, was able to find out everything I needed thanks to being able to print out the args.
Events.WMDDetonated has 4 paramaters being (iX, iY, playerID, eWMD) and it works like a charm!

Is there a better or more efficient way that I should be removing a city other than this?
Code:
function CheckPlot(Plot:table)
    if Plot:IsCity() then
            WorldBuilder.CityManager():RemoveAt(Plot);
    end
end
It does freeze for a fraction a second when doing this, which isn't really a problem, but if there's a way to eliminate this then all the better.

On a side note, your real strategy mod is pretty much the only reason I still play Civ 6, so really impressive job with the little tools we have.
 
Last edited:
Top Bottom