Credit to the commentary you left in your files.
TNO wrote civlua.lua, if we're assigning credit.
Credit to the commentary you left in your files.
Just wondering if Lua can allow the restriction of what units can be airlifted with the airport improvement?
local noAirlift = {
[gen.original.uSettlers.id]=true
}
function discreteEvents.onKeyPress(keyCode)
local activeUnit = civ.getActiveUnit()
if keyCode == keyboard.l and activeUnit then
if noAirlift[activeUnit.type.id] then
local origDomain = activeUnit.type.domain
activeUnit.type.domain = 2
civ.sleep(100)
activeUnit.type.domain = origDomain
end
end
end
local noAirlift = {
[gen.original.uSettlers.id]=true
}
for i=0,1000 do
function discreteEvents.onKeyPress(keyCode)
if keyCode == keyboard.j then
print("me")
end
end
end
function discreteEvents.onKeyPress(keyCode)
local activeUnit = civ.getActiveUnit()
if keyCode == keyboard.l and activeUnit then
if noAirlift[activeUnit.type.id] then
local origDomain = activeUnit.type.domain
activeUnit.type.domain = 2
civ.sleep(100)
activeUnit.type.domain = origDomain
end
end
end
local noAirlift = {
[gen.original.uSettlers.id]=true
}
for i=0,1000 do
function discreteEvents.onKeyPress(keyCode)
print("me")
end
end
function discreteEvents.onKeyPress(keyCode)
local activeUnit = civ.getActiveUnit()
if keyCode == keyboard.l and activeUnit then
if noAirlift[activeUnit.type.id] then
local origDomain = activeUnit.type.domain
activeUnit.type.domain = 2
civ.sleep(100)
activeUnit.type.domain = origDomain
end
end
end
gen.isUsedAirport(city)-->boolean
gen.setUsedAirport(city)-->void
gen.clearUsedAirport(city)-->void
Is there a place in the template that has aircraft defend first? I'm having a hard time figuring out where it is and want to include it in Tech's scenario. I wasn't sure if this was added as a toggle in more recent versions of the template.
I think I gave you sample code for that for Cold War, but let me know if you need me to program it for you, and I can do that.
-- use this function (defenderValueModifier) to add to (or subtract from) the calculated
-- defender value in order to change onChooseDefender
-- e.g. if you add 1e8 (100 million) to all air in air protected stacks
-- when attacked by a fighter, air units will always defend first if they
-- are available.
-- If the combat calculator gives an attacker an attack value of 0,
-- this is converted to a defenderValue of 1e7 (10 million)
-- If you want this to defend (and cancel the attack) instead of the air unit
-- (presuming it isn't an air unit itself), you could add 1e6 (1 million) instead
-- calculated defenderValues are defenderStrength/attackerStrength*healthPercentage.
-- This should be less than 10,000 (127*8 = 1016), unless you have defense multipliers
-- of 10 or more, and an attacker with 1 attack and facing a 1/8 penalty.
local function tileHasCarrierUnit(tile)
for unit in tile.units do
if gen.isCarryAir(unit.type) then
return true
end
end
return false
end
local function defenderValueModifier(defender,tile,attacker)
if gen.isAttackAir(attacker.type) and defender.type.domain == 1
and defender.type.range >= 2 and
not gen.hasAirbase(tile) and not tile.city and
not tileHasCarrierUnit(tile) then
return 1e8
else
return 0
end
end
-- register.onChooseDefender
--Registers a function that is called every time a unit is chosen to defend a tile.
--The first parameter is the default function as implemented by the game.
--It takes `tile` and `attacker` as parameters. You can call this to produce a
--result for cases you don't need to handle yourself. The second parameter
--is the tile that's being considered, the third is the attacking unit, and the
--fourth, `isCombat`, is a boolean that indicates if this invocation will be
--followed by combat. This function is also called by the AI to determine its
--goals, in which case `isCombat` is false.
function register.onChooseDefender(defaultFunction,tile,attacker,isCombat)
local bestDefenderValue = -math.huge
local bestDefender = nil
for possibleDefender in tile.units do
local attackerStrength, attackerFirepower, defenderStrength, defenderFirepower
= computeCombatStatistics(attacker,possibleDefender,false)
-- below is what appears to be the standard civ II calculation
--local defenderValue = defenderStrength*possibleDefender.hitpoints//possibleDefender.type.hitpoints
-- instead of defender strength, however, defenderStrength/attackerStrength is used to account
-- for attack buffs/debuffs (which are very few in original game)
local defenderValue = nil
if attackerStrength == 0 then
defenderValue = 1e7 -- 10 million
else
defenderValue = (defenderStrength/attackerStrength)*possibleDefender.hitpoints//possibleDefender.type.hitpoints
end
defenderValue = defenderValue + defenderValueModifier(possibleDefender,tile,attacker)
if defenderValue > bestDefenderValue or
(defenderValue == bestDefenderValue and possibleDefender.id < bestDefender.id) then
bestDefenderValue = defenderValue
bestDefender = possibleDefender
end
end
return bestDefender
--return defaultFunction(tile,attacker)
end
--[[
-- register.onChooseDefender
--Registers a function that is called every time a unit is chosen to defend a tile.
--The first parameter is the default function as implemented by the game.
--It takes `tile` and `attacker` as parameters. You can call this to produce a
--result for cases you don't need to handle yourself. The second parameter
--is the tile that's being considered, the third is the attacking unit, and the
--fourth, `isCombat`, is a boolean that indicates if this invocation will be
--followed by combat. This function is also called by the AI to determine its
--goals, in which case `isCombat` is false.
function register.onChooseDefender(defaultFunction,tile,attacker,isCombat)
local bestDefenderValue = -math.huge
local bestDefender = nil
for possibleDefender in tile.units do
local attackerStrength, attackerFirepower, defenderStrength, defenderFirepower
= computeCombatStatistics(attacker,possibleDefender,false)
local defenderValue = defenderStrength*possibleDefender.hitpoints//possibleDefender.type.hitpoints
if defenderValue > bestDefenderValue or
(defenderValue == bestDefenderValue and possibleDefender.id < bestDefender.id) then
bestDefenderValue = defenderValue
bestDefender = possibleDefender
end
end
return bestDefender
--return defaultFunction(tile,attacker)
end
--]]
-- onEnterTile(unit,previousTile)
-- executes when a unit successfully enters a tile (so not when it attacks
-- a unit or fails to enter a tile because it lacks movement points)
function events.onEnterTile(unit,previousTile)
if _global.eventTesting then
civ.ui.text("consolidated.onEnterTile: "..unit.type.name.." has entered tile ("..text.coordinates(unit.location)..") from tile ("..text.coordinates(previousTile)..").")
end
end
Hello @Prof. Garfield !Try putting a few extra newline (\n) characters in your text. Without the ^, it shouldn't display as a new line, but I think it will help the game display the text properly.
I met with the same issue as @civ2units with the dialogbox, and adding a \n at the end of the string won't solve the issue :
Ho, sorry, I wasn't thinking about a "long line" issue,Not at the end, in the middle.
The macro.txt file that explains the macro style events says the following about text:
Text:
This simply presents a pop--up text box to the player. The box includes whatever text you put between the Text and EndText lines. You can enter up to 10 lines of 255 characters per line, but keep in mind both the memory limits and the amount of text that will fit on the screen at one time. Short messages are generally best. The optional No Broadcast parameter (note the space between the words--it's required) specifies that this message should be shown only to the triggering civilization ("who").
I'm guessing that there may be some difficulty parsing longer sequences of characters without newlines, though I haven't properly tested this.
Ho, sorry, I wasn't thinking about a "long line" issue,
but about the "extended font masking the "ok" button in the bottom" ?
Much thanks prof !I think they are both related in the sense that if the text box is too wide, the OK button at the bottom doesn't get drawn, just as the top border doesn't get drawn.
I'm not sure what causes that, but it is not 255 characters without a newline, based on tests that I just did. 255 without a space causes a crash, but with spaces they are fine.
Correct -- it's caused by the total width of the box, including images (if there are any) and text. There seems to be a hard limit in the game's UI code (maybe a total width of 1024 pixels? That's just a guess, but it looks like about half the width of my screen which is running 1920x1080 resolution) beyond which the border and buttons of the box get messed up. @Dadais your example has a good-sized image, so that's going to require your text lines to be relatively short. You could get longer text lines to fit by scaling down the image, of course.I think they are both related in the sense that if the text box is too wide, the OK button at the bottom doesn't get drawn, just as the top border doesn't get drawn.
I'm not sure what causes that, but it is not 255 characters without a newline, based on tests that I just did. 255 without a space causes a crash, but with spaces they are fine.