Cyrenaica "commendation" bug

A new story begins...
The sequel to a real classic: Panzer Corps is back!

Moderator: Panzer Corps 2 Moderators

Post Reply
nexusno2000
Sr. Colonel - Wirbelwind
Sr. Colonel - Wirbelwind
Posts: 1709
Joined: Mon Feb 24, 2014 5:15 pm
Contact:

Cyrenaica "commendation" bug

Post by nexusno2000 »

I'm replaying (and recording) the Italian Cyenaica campaign, and noticing a weird bug:

Mission 7: Toburk
I have 2 CP (this campaign reuses the code from AO commendation points to track bonus core slots)

This gives me 50+10=60 core slots

So far, so good.

I get the explosives and move them to the ship, then get the msg verifying OK, so I SHOULD get +1 CP

HOWEVER, I do not.

Mission 8: Interception at El Mechili
I start with only 2 CP, should be 3

(I've even added the CP display code to the lua to verify)

So instead of 48+12=60 slots, I only get 58.

It's not THAT big of a deal, but it'll carry forward for the rest of the campaign, so annoying. Also, my OCD-lite lol

(btw I rechecked old saves from the first time I played the campaign, and it's the same issue)

I've looked at the Tobruk lua and scenario/objectives, and it seems... fine, at least on first glance.

Anyone else notice this?
Green Knight
https://www.youtube.com/c/GreenKnight2001
nexusno2000
Sr. Colonel - Wirbelwind
Sr. Colonel - Wirbelwind
Posts: 1709
Joined: Mon Feb 24, 2014 5:15 pm
Contact:

Re: Cyrenaica "commendation" bug

Post by nexusno2000 »

Unrelated, I found this minor bug while looking for clues to the commendation bug:

C:\Program Files (x86)\Steam\steamapps\common\Panzer Corps 2\PanzerCorps2\Content\Campaigns\ITGB_40_Cyrenaica\IT_40_OperationE\06_IT_Bardia\06_IT_Bardia.lua (1 hit)
hero.extra_traits = {UnitTrait.OnTheRoll, UnitTrait.ReducesSlots, UnitTrait.HitAndRun}

ReducedSlots is spelled wrong.

Annibale Bergonzoli should look like this:

local hero = NewHero()
hero.portrait = "/Game/Gui/Common/Heroes/it_in_annibale_bergonzoli.it_in_annibale_bergonzoli"
hero.name = NSLOCTEXT("06_IT_Bardia", "Annibale_Bergonzoli", "Annibale Bergonzoli")
hero.extra_traits = {UnitTrait.OnTheRoll, UnitTrait.ReducedSlots, UnitTrait.HitAndRun}
local action = world:MakeNewHeroAction(_id, hero)
world:Exec(action)
Green Knight
https://www.youtube.com/c/GreenKnight2001
nexusno2000
Sr. Colonel - Wirbelwind
Sr. Colonel - Wirbelwind
Posts: 1709
Joined: Mon Feb 24, 2014 5:15 pm
Contact:

Re: Cyrenaica "commendation" bug

Post by nexusno2000 »

I get this msg when delivering the explosives:

msg = NSLOCTEXT("07_IT_Tobruk", "ship_unit_sunken", "The San Giorgio will never be caught by the British. Set it ablaze!")

But I never see this - it just tells me about the bonus hero objective.

objective_status = ObjectiveStatus.Active,
reward_notify = NSLOCTEXT("07_IT_Tobruk", "sangiorgio_reward", "Bonus Objective Completed: Destroy the supplies on the San Giorgio \n\nCore Slots gained: %d ")

I guess I will have to deep dive into the files...
Green Knight
https://www.youtube.com/c/GreenKnight2001
Tassadar
Lieutenant Colonel - Elite Panther D
Lieutenant Colonel - Elite Panther D
Posts: 1345
Joined: Mon Mar 11, 2019 1:03 pm

Re: Cyrenaica "commendation" bug

Post by Tassadar »

I had the same issue when playing my AARs back in the day, alongside a few minor script bugs. I'm afraid it was not addressed yet - while I was hoping for a patch the teams seems to have moved to working on the Allied Operations - Italy DLC. A tiny bit of hope remains that someone will address these issues, as seeing them lingering on so long after the release is a shame and not something I normally see in Slitherine titles, especially this game.
nexusno2000
Sr. Colonel - Wirbelwind
Sr. Colonel - Wirbelwind
Posts: 1709
Joined: Mon Feb 24, 2014 5:15 pm
Contact:

Re: Cyrenaica "commendation" bug

Post by nexusno2000 »

Tassadar wrote: Thu Feb 12, 2026 4:49 pm I had the same issue when playing my AARs back in the day, alongside a few minor script bugs. I'm afraid it was not addressed yet - while I was hoping for a patch the teams seems to have moved to working on the Allied Operations - Italy DLC. A tiny bit of hope remains that someone will address these issues, as seeing them lingering on so long after the release is a shame and not something I normally see in Slitherine titles, especially this game.
Thanks for the feedback.

I suppose I could just find the error and fix it myself, but I'm not sure it's worth the effort: I already completed my recording for the scenario, and I would rather not redo it.

Maybe I still will.

But I will use the console to give me the 2 slots they stole from me :D
Green Knight
https://www.youtube.com/c/GreenKnight2001
nexusno2000
Sr. Colonel - Wirbelwind
Sr. Colonel - Wirbelwind
Posts: 1709
Joined: Mon Feb 24, 2014 5:15 pm
Contact:

Re: Cyrenaica "commendation" bug

Post by nexusno2000 »

Relatedly: shame there is no console command for Commendation Points
Green Knight
https://www.youtube.com/c/GreenKnight2001
nexusno2000
Sr. Colonel - Wirbelwind
Sr. Colonel - Wirbelwind
Posts: 1709
Joined: Mon Feb 24, 2014 5:15 pm
Contact:

Re: Cyrenaica "commendation" bug

Post by nexusno2000 »

This is the fixed version of 07_IT_Tobruk.lua

-------------------------
--- Message utilities ---
-------------------------

function MessageSequence(messages) -- Show messages in a navigable sequence
for i, msg in ipairs(messages) do
TutorialMessageImg(msg.img,msg.notify, false)
end
end

-------------------------
-- Commendation points --
-------------------------

player_owner_id = 1 --id of the reward player target
player = world:GetPlayer(player_owner_id) --player reference (dont touch)
--reward_header = NS--LOCTEXT("07_IT_Tobruk", "reward_header", "Reward") --text displayed as header in deploy phase (if cp reard available)
--reward_message = NS--LOCTEXT("07_IT_Tobruk", "reward_message", "You gained %d core slots!") --text displayed as message in deploy phase (if cp reard available)

core_slots =
{
6, --1 cp reward
10, --2 cp reward
12, --3 cp reward
14, --4 cp reward
16, --5 cp reward
20 --6 cp reward
}

function DeployPhase_Trigger() --link this as New Round Trigger
return world.round == 0
end

function DeployPhase_Action() --link this as action for DeployPhase_Trigger
if campaign == nil then return end
if campaign.comm_points == nil then return end
--player.resource1_icon = "/Game/Gui/GameplayUI/hud_commendation_icon"
--player.resource1_tooltip = NS--LOCTEXT("common", "commendation_points", "Commendation Points")
player.resource1 = campaign.comm_points
if player.resource1 == 0 then
return
else
player.max_core_slots = player.max_core_slots + core_slots[player.resource1]
--MessageBox(reward_header, string.format(tostring(reward_message), core_slots[player.resource1]))
end
end


--string_1 = NS--LOCTEXT("scenario_Trial - SidiBarrani-Defender_Final", "string_1", "Generale, British reinforcements have arrived from the East. Be ready to hold the line!")

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- PLAYER HEROES --
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


---------------------------------------------------
-- CREATE AND ASSIGN MULTIPLE RETREATERS HEROES --
---------------------------------------------------

--TRIGGER
function AlwaysTrue()
return true
end

--ACTION
function CreateAndAssignHeroes_Players_Action() -- Create and Assign Heroes (call functions in sequence)
CreateAndAssignHero_PitassiMannella()
CreateAndAssignHero_DarioVenturi()
end

--ENRICO PITASSI MANNELLA
function CreateAndAssignHero_PitassiMannella() -- Create and Assign Hero 1 (player, portrait, name, traits, unit)
local data =
{
unit = 0, -- ID of unit to assign hero
portrait = "/Game/Gui/Common/Heroes/it_in_enrico_pitassi_mannella.it_in_enrico_pitassi_mannella", -- portrait path
name = NSLOCTEXT("07_IT_Tobruk", "Enrico_Mannella", "Enrico Pitassi Mannella"), -- localized name
traits = {UnitTrait.LethalAttack, UnitTrait.ExpertSupport}, -- traits array
silent = true -- hide creation popup?
}
local hero = NewHero()
local unit = world:GetUnit(data.unit)
hero.portrait = data.portrait
hero.name = data.name
hero.extra_traits = data.traits
local action = world:MakeNewHeroAction(unit.owner_id, hero)
action.silent = data.silent
world:Exec(action)
action = world:MakeAssignHeroAction(unit, hero.id)
world:Exec(action)
end

--DARIO VENTURI
function CreateAndAssignHero_DarioVenturi() -- Create and Assign Hero 2 (player, portrait, name, traits, unit)
local data =
{
unit = 60, -- ID of unit to assign hero
portrait = "/Game/Gui/Common/Heroes/IT/it_in_05.it_in_05", -- portrait path
name = NSLOCTEXT("07_IT_Tobruk", "Dario_Venturi", "Dario Venturi"), -- localized name
traits = {UnitTrait.NoSplit, UnitTrait.Survivor, UnitTrait.FastRetreat}, -- traits array
silent = true -- hide creation popup?
}
local hero = NewHero()
local unit = world:GetUnit(data.unit)
hero.portrait = data.portrait
hero.name = data.name
hero.extra_traits = data.traits
local action = world:MakeNewHeroAction(unit.owner_id, hero)
action.silent = data.silent
world:Exec(action)
action = world:MakeAssignHeroAction(unit, hero.id)
world:Exec(action)
end

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ENEMY HEROES --
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-- AI HW Infantry

function CreateAndAssignEnemyHero1(unit_id)
local hero = NewHero()
local unit = world:GetUnit(unit_id)
hero.portrait = "/Game/Gui/Common/Heroes/au_arthur_allen.au_arthur_allen"
hero.name = NSLOCTEXT("07_IT_Tobruk", "Arthur_Allen", "Arthur Allen")
hero.extra_traits = {UnitTrait.LightningAttack, UnitTrait.DoubleAttack, UnitTrait.Butcher }
local action = world:MakeNewHeroAction(unit.owner_id, hero)
world:Exec(action)

local assign_hero_action = world:MakeAssignHeroAction(unit, hero.id)
world:Exec(assign_hero_action)
end

function EnemyHero1()
CreateAndAssignEnemyHero1(18) -- specify id of the unit which will get this hero
end

-- AI HW Infantry

function CreateAndAssignEnemyHero2(unit_id)
local hero = NewHero()
local unit = world:GetUnit(unit_id)
hero.portrait = "/Game/Gui/Common/Heroes/au_savige.au_savige"
hero.name = NSLOCTEXT("07_IT_Tobruk", "Stanley_Savige", "Stanley Savige")
hero.extra_traits = {UnitTrait.FlagKiller, UnitTrait.Unyielding, UnitTrait.Vigilant}
local action = world:MakeNewHeroAction(unit.owner_id, hero)
world:Exec(action)

local assign_hero_action = world:MakeAssignHeroAction(unit, hero.id)
world:Exec(assign_hero_action)
end

function EnemyHero2()
CreateAndAssignEnemyHero2(42) -- specify id of the unit which will get this hero
end

-- AI HW Infantry

function CreateAndAssignEnemyHero3(unit_id)
local hero = NewHero()
local unit = world:GetUnit(unit_id)
hero.portrait = "/Game/Gui/Common/Heroes/au_horace_robertson.au_horace_robertson"
hero.name = NSLOCTEXT("07_IT_Tobruk", "Horace_Robertson", "Horace Robertson")
hero.extra_traits = {UnitTrait.ShockTactics, UnitTrait.DoubleMassAttack, UnitTrait.Vigilant}
local action = world:MakeNewHeroAction(unit.owner_id, hero)
world:Exec(action)

local assign_hero_action = world:MakeAssignHeroAction(unit, hero.id)
world:Exec(assign_hero_action)
end

function EnemyHero3()
CreateAndAssignEnemyHero3(17) -- specify id of the unit which will get this hero
end

-- AI Cruiser mk. IV

function CreateAndAssignEnemyHero4(unit_id)
local hero = NewHero()
local unit = world:GetUnit(unit_id)
hero.portrait = "/Game/Gui/Common/Heroes/gb_william_gott.gb_william_gott"
hero.name = NSLOCTEXT("07_IT_Tobruk", "William_Gott", "William Gott")
hero.extra_traits = {UnitTrait.OverwhelmingAttack, UnitTrait.SuperiorManeuver, UnitTrait.FearsomeReputation}
local action = world:MakeNewHeroAction(unit.owner_id, hero)
world:Exec(action)

local assign_hero_action = world:MakeAssignHeroAction(unit, hero.id)
world:Exec(assign_hero_action)
end

function EnemyHero4()
CreateAndAssignEnemyHero4(5) -- specify id of the unit which will get this hero
end

function MatchStartAction()
--utilities = require("/utilities")
end

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- SAN GIORGIO MISSION ---
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-----------------------------
--- SAN GIORGIO INIT DATA ---
-----------------------------

function SanGiorgio_Init()
SanGiorgio_Data =
{
player = 1,
intro_notify =
{
{
img = "IT_40_OperationE/Images/TMI_TelleraTalking.jpg",
msg = NSLOCTEXT("07_IT_Tobruk", "sangiorgio_intro_1", "Generale, the defense of Tobruch may be our last stand to hold Cyrenaica... But we must consider what would happen if the city falls.")
},
{
img = "IT_40_OperationE/Images/TMI_SanGiorgio.jpg",
msg = NSLOCTEXT("07_IT_Tobruk", "sangiorgio_intro_2", "We cannot let the British acquire the supplies stored on the ship San Giorgio.")
},
{
img = "IT_40_OperationE/Images/TMI_IT_Truck03.jpg",
msg = NSLOCTEXT("07_IT_Tobruk", "sangiorgio_intro_3", "A highly specialized demolition unit is ready for duty: you'll escort it to get the explosives and then to reach the ship...")
},
{
img = "IT_40_OperationE/Images/TMI_TelleraAngryYelling.jpg",
msg = NSLOCTEXT("07_IT_Tobruk", "sangiorgio_intro_4", "It would be better to see it engulfed in flames than in the hands of the enemy!")
}
},
demolition =
{
unit = 60,
hasExplosive = false,
death_notify =
{
img = "IT_40_OperationE/Images/TMI_DestroyedTruck.jpg",
msg = NSLOCTEXT("07_IT_Tobruk", "demolition_unit_death", "The demolition unit has been destroyed... The mission has failed!")
}
},
explosive =
{
unit = 36,
locations = { {11,15}, {12,15}, {13,15}, {12,16}, {13,16} },
take_notify =
{
img = "IT_40_OperationE/Images/TMI_TelleraAngryYelling.jpg",
msg = NSLOCTEXT("07_IT_Tobruk", "explosive_unit_taken", "Explosive secured. To the San Giorgio, now!!")
},
death_notify =
{
img = "IT_40_OperationE/Images/TMI_TelleraAngryYelling.jpg",
msg = NSLOCTEXT("07_IT_Tobruk", "explosive_unit_death", "The explosives depot has been destroyed... The mission has failed!")
}
},
ship =
{
unit = 2,
locations = { {17, 5}, {17,6}, {18,5}, {19,6} },
sink_notify =
{
img = "IT_40_OperationE/Images/TMI_SinkingShip.jpg",
msg = NSLOCTEXT("07_IT_Tobruk", "ship_unit_sunken", "The San Giorgio will never be caught by the British. Set it ablaze!")
},
death_notify =
{
img = "IT_40_OperationE/Images/TMI_SinkingShip.jpg",
msg = NSLOCTEXT("07_IT_Tobruk", "ship_unit_death", "The San Giorgio cruiser has been destroyed... The mission has failed!")
}
},
objective_status = ObjectiveStatus.Active,
reward_notify = NSLOCTEXT("07_IT_Tobruk", "sangiorgio_reward", "Bonus Objective Completed: Destroy the supplies on the San Giorgio \n\nCore Slots gained: %d ")
}
end

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- SAN GIORGIO CANNOT MOVE ---
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

function SanGiorgio_NoMove_Action()
local units = { 2 }
for _,u in ipairs(units) do
local unit = world:GetUnit(u)
if unit ~= nil then
unit.move_points = 0
end
end
end

-----------------------------------------------
--- SAN GIORGIO DEMOLITION UNIT DEATH CHECK ---
-----------------------------------------------

function SanGiorgio_Demolition_Unit_Death_Trigger(action)
return action.unit == SanGiorgio_Data.demolition.unit
end

function SanGiorgio_Demolition_Unit_Death_Action(action)
if SanGiorgio_Data.objective_status == ObjectiveStatus.Active then
SanGiorgio_Data.objective_status = ObjectiveStatus.Fail
TutorialMessageImg(SanGiorgio_Data.demolition.death_notify.img, SanGiorgio_Data.demolition.death_notify.msg, false)
end
end

----------------------------------------------
--- SAN GIORGIO EXPLOSIVE UNIT DEATH CHECK ---
----------------------------------------------

function SanGiorgio_Explosive_Unit_Death_Trigger(action)
return action.unit == SanGiorgio_Data.explosive.unit
end

function SanGiorgio_Explosive_Unit_Death_Action(action)
if SanGiorgio_Data.objective_status == ObjectiveStatus.Active then
SanGiorgio_Data.objective_status = ObjectiveStatus.Fail
TutorialMessageImg(SanGiorgio_Data.explosive.death_notify.img, SanGiorgio_Data.explosive.death_notify.msg, false)
end
end

-----------------------------------------
--- SAN GIORGIO SHIP UNIT DEATH CHECK ---
-----------------------------------------

function SanGiorgio_Ship_Unit_Death_Trigger(action)
return action.unit == SanGiorgio_Data.ship.unit
end

function SanGiorgio_Ship_Unit_Death_Action(action)
if SanGiorgio_Data.objective_status == ObjectiveStatus.Active then
SanGiorgio_Data.objective_status = ObjectiveStatus.Fail
TutorialMessageImg(SanGiorgio_Data.ship.death_notify.img, SanGiorgio_Data.ship.death_notify.msg, false)
end
end

-----------------------------------------
--- SAN GIORGIO TAKE EXPLOSIVE (Move) ---
-----------------------------------------

function SanGiorgio_Take_Explosive_Trigger(action)
if SanGiorgio_Data.objective_status == ObjectiveStatus.Active then
if action.unit == SanGiorgio_Data.demolition.unit then
local unit = world:GetUnit(action.unit)
for i, position in ipairs(SanGiorgio_Data.explosive.locations) do
if position == unit.position then
return true
end
end
end
end
return false
end

function SanGiorgio_Take_Explosive_Action()
SanGiorgio_Data.demolition.hasExplosive = true
local unit = world:GetUnit(SanGiorgio_Data.explosive.unit)
local action = world:MakeUndeployAction(unit)
world:Exec(action)
action = world:MakeReserveAction(unit, true)
world:Exec(action)
TutorialMessageImg(SanGiorgio_Data.explosive.take_notify.img, SanGiorgio_Data.explosive.take_notify.msg, false)
end

-------------------------------------
--- SAN GIORGIO REACH SHIP (Move) ---
-------------------------------------

function SanGiorgio_Reach_Ship_Trigger(action)
if SanGiorgio_Data.objective_status == ObjectiveStatus.Active then
if action.unit == SanGiorgio_Data.demolition.unit and SanGiorgio_Data.demolition.hasExplosive then
local unit = world:GetUnit(action.unit)
for i, position in ipairs(SanGiorgio_Data.ship.locations) do
if position == unit.position then
return true
end
end
end
end
return false
end

function SanGiorgio_Reach_Ship_Action()
SanGiorgio_Data.objective_status = ObjectiveStatus.Success
local unit = world:GetUnit(SanGiorgio_Data.demolition.unit)
local action = world:MakeUndeployAction(unit)
world:Exec(action)
action = world:MakeReserveAction(unit, true)
world:Exec(action)
--unit = world:GetUnit(SanGiorgio_Data.ship.unit)
--local action = world:MakeUndeployAction(unit)
--world:Exec(action)
--action = world:MakeReserveAction(unit, true)
--world:Exec(action)
TutorialMessageImg(SanGiorgio_Data.ship.sink_notify.img, SanGiorgio_Data.ship.sink_notify.msg, false)
end

------------------------------------
--- SAN GIORGIO CUSTOM OBJECTIVE ---
------------------------------------

function SanGiorgio_Success()
return SanGiorgio_Data and SanGiorgio_Data.objective_status == ObjectiveStatus.Success
end

function SanGiorgio_Fail()
return SanGiorgio_Data and SanGiorgio_Data.objective_status == ObjectiveStatus.Fail
end

--------------------------
--- SAN GIORGIO REWARD ---
--------------------------

function SanGiorgio_Reward_Trigger(action)
return action.side == 1 and action.objective == 3 and action.status == ObjectiveStatus.Success
end

function SanGiorgio_Reward_Action(action)
if campaign == nil then
return
end
if campaign.comm_points == nil then
campaign.comm_points = 0
end
campaign.comm_points = campaign.comm_points + 1
UpdateCommendationPoints()

result = core_slots[campaign.comm_points]
if campaign.comm_points > 1 then
result = core_slots[campaign.comm_points] - core_slots[campaign.comm_points - 1]
end
MessageBox(string.format(tostring(SanGiorgio_Data.reward_notify), result))
end

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- SOLARO + PILASTRINO REWARD ---
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

function SolaroPilastrino_Reward_Trigger(action)
return action.side == 1 and action.objective == 2 and action.status == ObjectiveStatus.Success
end

function SolaroPilastrino_Reward_Action(action)
--TutorialMessage(string_GainsHero)
MessageBox ( NSLOCTEXT("07_IT_Tobruk", "solaro_pilastrino_reward", "Bonus Objective Completed: Hold Forte Solaro and Forte Pilastrino \n\nHero gained: Enrico Pitassi Mannella"))
CreateMannella()
end

--string_GainsHero = NS--LOCTEXT("scenario", "string_GainsHero", "Generale, due to your formidable actions Enrico Pitassi Mannella has been assigned to our army.")

function CreateMannella()
local hero = NewHero()
hero.portrait = "/Game/Gui/Common/Heroes/it_in_enrico_pitassi_mannella.it_in_enrico_pitassi_mannella"
hero.name = NSLOCTEXT("07_IT_Tobruk", "Enrico_Pitassi_Mannella", "Enrico Pitassi Mannella")
hero.extra_traits = {UnitTrait.LethalAttack, UnitTrait.ExpertSupport, UnitTrait.DoubleSupport}
local action = world:MakeNewHeroAction(player_owner_id, hero)
world:Exec(action)
end

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- NEGATIVE FEEDBACK --
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

EnemyPlayer = 0

--CONTROLLO BASATO SUL TURNO ATTUALE + NUMERO NEMICI MORTI

--Assegno gli id delle unita da controllare
enemy_units = {54,56,58,55,41,42,7,16,5,4,13,6,14,18,12,17,15,1,38,57,45,59,43,44,52,46,53,50,30,29,28,21,49,25,51,27,31,22,48,47,24,11,19,20,9,23,26}

--Controllo con un ciclo se le unita da controllare sono morte
function CountTheDead()
local dead = 0
for _,unit_id in ipairs(enemy_units) do
local unit = world:GetUnit(unit_id)
if (unit == nil) then
dead = dead + 1
end
end

return dead
end

-- NEGATIVE FEEDBACK 1 --------------------------------------------------------------------------------------------------------------------------------------------

string_NF1 = NSLOCTEXT("07_IT_Tobruk", "string_NF1", "British reinforcements are coming from all directions. We don't have any other information. Be ready to hold the entire perimeter!")

function SpawnUnit(owner_id, data)
local owner = world:GetPlayer(owner_id)
local create_action = world:MakePurchaseAction(owner, data[1], data[2], data[3])
create_action.auxiliary = true
create_action.cost = 0
create_action.faction = owner.factions[1]
world:Exec(create_action)
demolition_unit = world:GetUnit(create_action.id)
deploy_action = world:MakeDeployAction(demolition_unit, demolition_unit_spawn_location)
world:Exec(deploy_action)
end

--Condizione chiamata dall'editor, che chiama il ciclo CountTheDead e ritorna vero se uguale al valore inserito
function EnemiesAreDead_1()
return CountTheDead() >= 24 and world.round <= 10

end

--Effetto chiamato dall'editor, che si verifica quando la condizione e vera
function EnemiesAreDead_1_Spawn(action)
--Printo un messaggio
TutorialMessageImg("IT_40_OperationE/Images/TMI_TelleraAngryYelling.jpg",string_NF1)
SpawnUnits_NF1()
end

--SPAWN DEI NEMICI

--Effetto chiamato dall'editor, che assegna le zone di spawn e le unita da spawnare
function SpawnUnits_NF1(action)
--Il giocatore che controlla le unita spawnate
-- Player = 0
--Racchiudo le zone di spawn in un array
zone_NF1 = {{1,7},{1,8},{1,9},{3,17},{4,17},{5,18},{4,19},{20,27},{21,27},{22,26},{28,21},{29,20}}
--Determino le unita da spawnare (truppa, trasporto, overstrenght, esperienza)
local unit1 = {"BL7-2inch", "", 0, 2400}
local unit2 = {"MatildaII", "", 0, 3000}
local unit3 = {"QF3inchAA", "", 0, 2500}
local unit4 = {"CruiserMkIII", "", 0, 2800}
local unit5 = {"BL6inch26cwt", "UniversalCarrier", 0, 2500}
local unit6 = {"VickersMkVI", "", 0, 2700}
local unit7 = {"CruiserMkIII", "", 0, 2800}
local unit8 = {"QF3-7inchAA", "", 0, 2400}
local unit9 = {"MatildaII", "", 0, 2600}
local unit10 = {"Bofors37mmPortee", "", 0, 2800}
local unit11 = {"Commando", "UniversalCarrier", 0, 3000}
local unit12 = {"Commando", "UniversalCarrier", 0, 2900}
--Racchiudo le unita da spawnare in un array
NF1_Units = { unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12 }
--Spawno le unita (giocatore che le controlla, zone di spawn, unita da spawnare)
SpawnWave_NF1(EnemyPlayer, zone_NF1, NF1_Units)
end

--Spawn delle unita
function SpawnWave_NF1(EnemyPlayer, zone, units)

local owner = world:GetPlayer(EnemyPlayer)

local cur_hex = 1

-- Iterate through all units and spawn each one
for _,u in ipairs(units) do
-- Find the next vacant hex in the zone
while zone[cur_hex] do
hex = world:GetHex(zone[cur_hex])
if hex:GetUnit(0) == nil then break end -- found
cur_hex = cur_hex + 1
end

-- If we have run out of hexes in the zone, stop
if not zone[cur_hex] then return end

-- Create the unit in the free hex we've found
-- 1. Create and execute purchase action, use unit type, transport type and overstrength as parameters
local create_action = world:MakePurchaseAction(owner, u[1], u[2], u[3])
create_action.auxiliary = false -- spawn core units bonus reward
create_action.cost = 0 -- don't take money for units we generate
create_action.faction = owner.factions[1] --set to first faction of owning player for created units
world:Exec(create_action)

-- 2. Create and execute deploy action, place the unit in the hex we've picked.
local unit = world:GetUnit(create_action.id)
deploy_action = world:MakeDeployAction(unit, zone[cur_hex])
world:Exec(deploy_action)

-- 3. Now modify the unit to set its experience to the value we need.
unit.experience = u[4]

-- 4. Now modify the unit to set its aggressiveness to the value we need.
player_aggressiveness = { 0, 85, 70, 70 }
unit.aggressiveness = player_aggressiveness[EnemyPlayer+1]

end
end

--------------------------------------------------------------------------------------------------------------------------------------------------------
--- DEFEAT ON DISBAND
---------------------------------------------------------------------------------------------------------------------------------------------------------

function Disband_Trigger(action)
local r = action.unit == SanGiorgio_Data.demolition.unit
or action.unit == SanGiorgio_Data.explosive.unit
or SanGiorgio_Data.ship.unit
end

function Disband_Action(action)
local data =
{
notify =
{
NSLOCTEXT("07_IT_Tobruk", "disband_notify_1", "You disbanded a key unit for the Bonus Objective! \n\nConsider to undo, otherwise the objective will fail."),
NSLOCTEXT("07_IT_Tobruk", "disband_notify_2", "You disbanded a key structure for the Bonus Objective! \n\nConsider to undo, otherwise the objective will fail.")
}
}
if action.unit == SanGiorgio_Data.explosive.unit then
MessageBox(data.notify[2])
else
MessageBox(data.notify[1])
end
end

-------------------------
-- COMMENDATION POINTS --
-------------------------
-- Adds the HUD update that shows current CP

function OnMapStart()
local player = world:GetPlayer(1)
player.resource1_icon = "/Game/Gui/GameplayUI/hud_commendation_icon"
player.resource1 = campaign.comm_points
player.resource1_tooltip = NSLOCTEXT("common", "commendation_points", "Commendation Points")
end

function UpdateCommendationPoints()
local player = world:GetPlayer(1)
player.resource1 = campaign.comm_points
end
Last edited by nexusno2000 on Thu Feb 12, 2026 6:15 pm, edited 1 time in total.
Green Knight
https://www.youtube.com/c/GreenKnight2001
nexusno2000
Sr. Colonel - Wirbelwind
Sr. Colonel - Wirbelwind
Posts: 1709
Joined: Mon Feb 24, 2014 5:15 pm
Contact:

Re: Cyrenaica "commendation" bug

Post by nexusno2000 »

I did 4 changes:

1. Fix the objective status so it's actually == Success when you bring back the explosives

FROM
function SanGiorgio_Success()
return objective_status == ObjectiveStatus.Success
end

function SanGiorgio_Fail()
return objective_status == ObjectiveStatus.Fail
end

TO
function SanGiorgio_Success()
return SanGiorgio_Data and SanGiorgio_Data.objective_status == ObjectiveStatus.Success
end

function SanGiorgio_Fail()
return SanGiorgio_Data and SanGiorgio_Data.objective_status == ObjectiveStatus.Fail
end

2. Prevents ANY disband from causing the bonus objective to fail

FROM
return action.unit == SanGiorgio_Data.demolition.unit
or action.unit == SanGiorgio_Data.explosive.unit
or SanGiorgio_Data.ship.unit

TO
function Disband_Trigger(action)
return action.unit == SanGiorgio_Data.demolition.unit
or action.unit == SanGiorgio_Data.explosive.unit
or action.unit == SanGiorgio_Data.ship.unit
end

3. Display current CP

-------------------------
-- COMMENDATION POINTS --
-------------------------
-- Adds the HUD update that shows current CP

function OnMapStart()
local player = world:GetPlayer(1)
player.resource1_icon = "/Game/Gui/GameplayUI/hud_commendation_icon"
player.resource1 = campaign.comm_points
player.resource1_tooltip = NSLOCTEXT("common", "commendation_points", "Commendation Points")
end

function UpdateCommendationPoints()
local player = world:GetPlayer(1)
player.resource1 = campaign.comm_points
end

4. Update CP

FROM
function SanGiorgio_Reward_Action(action)
if campaign == nil then return end
if campaign.comm_points == nil then campaign.comm_points = 0 end

campaign.comm_points = campaign.comm_points + 1

TO
function SanGiorgio_Reward_Action(action)
if campaign == nil then return end
if campaign.comm_points == nil then campaign.comm_points = 0 end

campaign.comm_points = campaign.comm_points + 1
UpdateCommendationPoints() -- <- add this
Green Knight
https://www.youtube.com/c/GreenKnight2001
nexusno2000
Sr. Colonel - Wirbelwind
Sr. Colonel - Wirbelwind
Posts: 1709
Joined: Mon Feb 24, 2014 5:15 pm
Contact:

Re: Cyrenaica "commendation" bug

Post by nexusno2000 »

3 & 4 are only relevant if you want to see CP and track them as it updates.
Green Knight
https://www.youtube.com/c/GreenKnight2001
nexusno2000
Sr. Colonel - Wirbelwind
Sr. Colonel - Wirbelwind
Posts: 1709
Joined: Mon Feb 24, 2014 5:15 pm
Contact:

Re: Cyrenaica "commendation" bug

Post by nexusno2000 »

Scenario 8: Interception of El Mechili

Script error due to the script trying to spawn a tank with a transport...

local unit6 = {"VickersMkVI", "UniversalCarrier", 0, 3000}

Should read:

local unit6 = {"VickersMkVI", "", 0, 3000}

Update you 08_IT_ElMechili.lua to fix this issue.
Green Knight
https://www.youtube.com/c/GreenKnight2001
nexusno2000
Sr. Colonel - Wirbelwind
Sr. Colonel - Wirbelwind
Posts: 1709
Joined: Mon Feb 24, 2014 5:15 pm
Contact:

Re: Cyrenaica "commendation" bug

Post by nexusno2000 »

So... scenarios 6, 7, and 8 all have bugs :D

Maybe we will find more? :mrgreen:
Green Knight
https://www.youtube.com/c/GreenKnight2001
Panzer73
Administrative Corporal - SdKfz 232 8Rad
Administrative Corporal - SdKfz 232 8Rad
Posts: 166
Joined: Sun Mar 21, 2021 11:18 am

Re: Cyrenaica "commendation" bug

Post by Panzer73 »

Thanks for the fixes!
nexusno2000
Sr. Colonel - Wirbelwind
Sr. Colonel - Wirbelwind
Posts: 1709
Joined: Mon Feb 24, 2014 5:15 pm
Contact:

Re: Cyrenaica "commendation" bug

Post by nexusno2000 »

Panzer73 wrote: Thu Feb 19, 2026 1:45 pm Thanks for the fixes!
I've reported the bugs (and the fixes), so maybe they'll get fixed. Eventually.
Green Knight
https://www.youtube.com/c/GreenKnight2001
Post Reply

Return to “Panzer Corps 2”