Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Negotiations mission (Red Alert, scg47ea) #20975

Merged
merged 1 commit into from
May 3, 2024

Conversation

JovialFeline
Copy link
Contributor

@JovialFeline JovialFeline commented Jul 26, 2023

This adds Negotiations from Aftermath. It's a short mission featuring Tanya, some hostages in need of rescue, and many barrels in need of exploding.

Normal's more of a straight conversion. Thoughts on the Hard changes are welcome.

Feedback on the cameras would be dandy. The original relies on vision of old areas to avoid patrols, so cameras are used to give information when needed.

  • Standard reveals are the usual 6s, while more event-y ones are 20s.
  • Most barrel explosions also come with a 1s camera reveal, for fun and confirming kills.

Design changes:

Original: A hostage must die before the group will follow Tanya.
New: All hostages can be saved.

Original: If he lives, the helpful Guide will either follow Tanya until the mission ends, or stand still near the hostage fencing.
New: He can be escorted back to the church like the other civilians.

Original: Soviets produce tanks as soon as a War Factory is up, including Tesla Tanks.
New: Soviets will build a Service Depot before producing tanks. They also start with a Soviet Tech Center, which can be destroyed to stop production of Tesla Tanks or Shock Troopers.

Original: The General will retreat to the northwestern beach when Tanya or the Guide come within ~7 cells. A Soviet MCV will arrive if the General's left alone.
New: The General is faster and the retreat is activated sooner. Reinforcements will come if the General stays for 45s -> 30s.

  • This is done because of ORA Tanya's better speed and range, and because of the added tank delay from the Service Depot.
  • The reinforcement timing change doesn't seem drastic. The MCV boat should arrive as Tanya and the hostages are entering the forest -> near the forest patrol's starting point.

The MCV's arrival is revealed, and there's a notification for the General's flare.

Swapped some unit types around for convention's sake.

  • Soviet Chinook reinforcements now enter from a Badger.
  • Aside from Tanya, Allied Badger reinforcements now enter from Chinooks.
  • The 3 Rocket Soldiers owned by the Soviets are swapped for Flamethrowers.

The Allied reinforcements come with 2 more mechanics.

  • May need adjusting. The attrition can be rough with a solo mechanic if Soviet reinforcements are signaled. The original solo mechanic is bonkers, healing a medium tank from near death in ~10s compared to ~64s in ORA.

Hard difficulty:

All hostages must survive.

Tanya will encounter more early resistance.

  • If Tanya dies from a rocket, the launcher will be revealed (again) for the sake of clarity.

The return trip to the starting beach has some added enemies.

There is some more security around the prison and the BadGuy base area (where the MCV can deploy).

It's possible for Soviets to build Shock Troopers.


Notes on porting and such:

To mimic their original guard range, some dogs have a wider AutoTarget ScanRadius.

  • I felt less kooky once I saw that allies-03a/allies-03b also did this for its dogs.
  • While the original rules.ini says GuardRange=7, 9 seemed to be a closer match.

Guide's house is more vulnerable to damage, since ORA rifles do little to structures.

  • The house will take ~11.56s to die if left alone. Original is ~10s.
  • Could have reduced the HP 53% -> 23%, but wanted to preserve the crumbling structure effect.

This western passage is originally passable, so I cleared a path. The eastern passage has a (narrow) path that works, so it was left untouched.
RA95_RubbleWest

The Demolition Truck's explosion range is tightened, closer to the original's.

  • The Soviet truck can otherwise explode barrels by the prison, freeing the hostages.

The Chrono Tank reinforcements' entry and triggers are slightly moved to avoid spawning inside other units.

  • I don't know of a current way to order the Chrono Tanks' PortableChrono. I've instead implied that a Chronosphere is used to transport them.
    • This is consistent with Production Disruption or In The Nick of Time anyway.
    • They will be fully charged, and the Chronosphere sound is played instead of the tank shift sound.
    • I did manage the palette shift by moving a dummy unit. Mousetrap did something similar.

The patrolling tank encountered during the rescue is guarded by two Shock Troopers, so it's fortunately still a threat to ORA Tanya.

The Guide's movement is more direct.

  • He no longer pauses at the southern river crossing since ORA Tanya has no issue keeping up.
  • After the forest patrol is clear, he will head straight for the village bridge, instead of moving to the forest's middle or the forest patrol's starting point.

In case you're left to wonder why the Soviets' Demolition Truck goes hunting, that is the original hunu trigger.

  • BadGuys' units will hunt if Allied reinforcements have arrived and the General is dead.
  • This does not include units set to Area Guard. That leaves the truck, a handful of Flamethrowers, and BlockerTeam (1 Heavy Tank with 2 Shock Troopers).

For funsies, hostages following Tanya will panic if she dies. Their disregard for personal space in RA '95 meant they were likely to do it there as well.

@PunkPun
Copy link
Member

PunkPun commented Jul 26, 2023

Swapped some unit types around for convention's sake.

  • Soviet Chinook reinforcements now enter from a Badger.
  • Aside from Tanya, Allied Badger reinforcements now enter from Chinooks.

I think this can be reversed. If anything we would like to give chinook to both factions like in vanilla

@PunkPun
Copy link
Member

PunkPun commented Jul 26, 2023

I think the flare next to the general can extinguish after he's been killed, maybe a few minutes death timer? It feels a bit off when it's permanent.

Also the camera on the demo truck should be triggered from the other side of the fence. I've also noticed that if you don't blow up the demo while on the other side of the fence, it's a big struggle to keep the civilians alive

I'm also a bit stumped, if you get into this situation how do you proceed?

grafik

Copy link
Member

@PunkPun PunkPun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah I understand, but it's almost impossible to win as civilians will get themselves killed very quickly onto the infantry and flame tower

mods/ra/languages/lua/en.ftl Show resolved Hide resolved
@JovialFeline
Copy link
Contributor Author

I think the flare next to the general can extinguish after he's been killed, maybe a few minutes death timer? It feels a bit off when it's permanent.

How long should that be? I know from fiddling with Don't Drink The Water that the original flares seem to expire after 8m but I'm guessing that'd be too long.

Also the camera on the demo truck should be triggered from the other side of the fence. I've also noticed that if you don't blow up the demo while on the other side of the fence, it's a big struggle to keep the civilians alive

It can be, though in that case, you probably have barrels for the village patrol. They move clockwise and the dog especially should be easy to burn.

The demo truck camera should already spawn at the truck's death location unless it's attacking or I've goofed and this trigger only does it at its starting location.

	Trigger.OnKilled(SovietDemoTruck, function()
		if not SovietDemoTruck.IsIdle then
			return
		end
		SpawnPlayerCamera(SovietDemoTruck.Location, DateTime.Seconds(1), "camera.paradrop")
	end)

I'm also a bit stumped, if you get into this situation how do you proceed?

The intended route seems to be returning to the forest. Once there, the tank and shock troopers at the river will move through, north toward the village bridge. You can use the same hideout on the east edge to wait them out, then proceed to the church.

I'm a little irked to see them idle at the river crossing instead of the open church area, though. Odd.

@PunkPun
Copy link
Member

PunkPun commented Jul 26, 2023

The demo truck camera should already spawn at the truck's death location

Yeah it spawns, I mean the camera revealing the barrels

@JovialFeline
Copy link
Contributor Author

Update

The tank-guarding Shock Troopers are now Flamethrowers to reduce insta-deaths from fog.

  • At least for now, the forest team (with dogs) and northern Chinook team still have their Shock Troopers.

Allies are back to using Badgers for all their infantry drops.

Soviets use Chinooks and a handful of rocket launchers again.

  • There's some randomness in what northern edge cell the original Chinook spawns, but 9s until landing seems to be the average.

The explosion reveals should feel more responsive.

The money check for bot structure building is improved.

The General's flare will expire 30 seconds after he does. Tanya's flare expires after 5 minutes.

The timer now changes with difficulty.

  • Easy: 5 minutes
  • Normal: 4 minutes
  • Hard: 3 minutes
  • "every 5 minutes" is now "every few minutes" in the briefing text.

The "Keep all hostages alive" objective is still required for Hard, but also appears on Normal or Easy as an optional objective.

negotiations is listed with Tanya's usual targeting translation.

The copyright notice is added.

@PunkPun
Copy link
Member

PunkPun commented Aug 5, 2023

It's definitely easier with less shokies and with working patrols. Just the tiny cameras felt like there were enabled for too short. It's a blink it and you'll miss it

Without reading the briefing it might be difficult to to tell from where to call in allied reinforcements. I'm not wether we need to fix it, but it's something worth thinking about

@JovialFeline
Copy link
Contributor Author

JovialFeline commented Aug 6, 2023

Small changes:

  • Objectives now use the common utility functions, which had slipped my mind.
  • After hostages make it inside the church, a looping beacon is created at the starting beach. It will stop looping after Tanya triggers reinforcements.

Copy link
Member

@PunkPun PunkPun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps create the "Signal for reinforcements" objective when it's actually possible to do. Instead of the ping the objective could just specify the location

Could delay the church objective as well, so there's less to read at the start of the mission. Ofc mission should still fail on blowing up the church.

When the timer ran out I got this crash
Actor 'c2 (dead)' does not define a property 'Kill'

@JovialFeline
Copy link
Contributor Author

Thank you. I can't figure how that re-kill may have happened without Tanya shooting the hostage, but that possibility was easy enough to test and the new check should handle any premature deaths.


  • If a hostage scheduled for execution is already dead, a random survivor will be chosen instead. If every hostage is dead, execution is skipped.

  • The escort and signal objectives are delayed until they're more relevant. The beach beacon is removed.

  • The destroy objective is declared after the hostages are escorted. It's still possible to destroy all Soviets for victory without reinforcements, so long as hostages are escorted to the church at some point.

  • A Chrono Tank timing goof is fixed. The tanks can be triggered after hostages enter the church -> Allied reinforcements are signaled.

  • The hostage pen's executioner is set to Defend stance.

  • The returning forest patrol will have another waypoint in their path so their dogs won't run ahead as much, and another reveal is added. The reveals for that group's return can trigger after hostages are freed -> after the group moves all the way south to the Guide house, like Blocker Team does for their own reveal.

  • Blocker Team's path to the Guide house skips the forest patrol's starting point and makes a traffic jam less likely.

Copy link
Member

@PunkPun PunkPun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the tech centre be sold off upon the destruction of the command centre? Because it isn't

The mission is better now that there's less objective at the start, but you are still bombarded with text when you return the hostages to the church. I dunno how but it should be best to spread it out a bit more.

Signal flare detected could also be more specific. Perhaps flare detected in the west?

The church itself could also be highlighted somehow? I think it would be best to somehow highlight it upon saving the helpful civilian

I also really enjoyed the extra troops on hard difficulty. They made the mission feel more complete

@JovialFeline
Copy link
Contributor Author

JovialFeline commented Sep 3, 2023

  • I've considered including that Tech Center in the fire sale if the General never signaled for help. It's owned by BadGuy (owner of the MCV). It should be easy enough to add once that check is done; FireSale does its thing with whatever player gets passed as an argument.

  • I'll have to ponder the objective stuff more. Ideally, I'd add the destroy objective after a delay but the game will see all objectives done and trigger victory. That is less of a problem on Hard where saving every hostage is required and only gets ticked done once all Soviets are gone.

  • Funny enough, I used to have SignalFlareNorth as the notification but went back and forth on it. Perhaps the west one will fit better with how the player's map is gonna look.

  • D'ya have any particular ideas for the church? Should I bring back the beacon? :p

  • Normal indeed feels a bit empty to me when I play it now, yeah. Glad you dig it.

@PunkPun
Copy link
Member

PunkPun commented Sep 3, 2023

perhaps change the objective to

-Get hostages to church.
+Get hostages to town.

and once you cross the river make the civilians go to church automatically?

The helpful civilian already calls this place town

@JovialFeline
Copy link
Contributor Author

Took longer than expected, but some more changes got done.


Made some vision tweaks so the church should be more obvious, and the church itself will provide vision until a hostage is loaded. The trigger ordering hostages to enter is extended to match that vision circle.

Changed objectives so their messages are spaced out a bit, even the primary ones.

Swapped the SignalFlare notification for SignalFlareWest.

Two oddball crash scenarios are fixed.

  • Tanya bombs Guide's house shortly before he's added to the world.
  • BadGuy attempts to build a structure with an owned husk in the way.

The Guide will reroute if the bridge is out.

  • He will also have a quicker reaction to the forest patrol's death and the hostages' freedom.

The northern edge team is moved a bit so they won't be partly obscured by the edge shroud.

Blocker Team will correctly start moving south as the prison is revealed, rather than when the General retreats.

BadGuy's units near the forward base will join in USSR's attack if it's destroyed.

The Soviets can sell off their Tech Center when appropriate to speed up the end.

Details: It will be sold after one of two events: the Forward Command is destroyed or the base built by BadGuy's reinforced MCV becomes useless. It's considered useless when that base is missing its Construction Yard, defenses, War Factory, and Barracks. Timelines I've considered and tested:
  • A: The Forward Command is destroyed, triggering USSR's fire sale. The General did not signal for help, so BadGuy's MCV will never come.

    • The Tech Center will be included in USSR's fire sale.
  • B: The Forward Command is destroyed after BadGuy's MCV arrival. The Tech Center remains intact.

    • If BadGuy's base is still okay, don't sell the Tech Center yet.
    • If BadGuy's base becomes useless, sell the Tech Center and send its occupants hunting.
      • If the difficulty is Hard, the remainder of BadGuy's base will do the same.
  • C: The Forward Command is intact after BadGuy's MCV arrival.

    • If BadGuy's base becomes useless, USSR will take ownership of the Tech Center. It will later be sold as part of the USSR fire sale.
  • D: The Forward Command is intact after BadGuy's MCV arrival, but Tanya demolishes the MCV before it can deploy.

    • The result will be like a useless base in timeline B.

PunkPun
PunkPun previously approved these changes Sep 11, 2023
Copy link
Member

@PunkPun PunkPun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mission plays really well, LGTM

Copy link
Member

@abcdefg30 abcdefg30 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like sublime work! Left a few comments which are mostly style nits.

mods/ra/maps/negotiations/negotiations-ai.lua Outdated Show resolved Hide resolved
Comment on lines 108 to 112
local okay = Utils.Any(types, function(type)
return BadGuy.HasPrerequisites( { type } )
end)

return okay
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
local okay = Utils.Any(types, function(type)
return BadGuy.HasPrerequisites( { type } )
end)
return okay
return Utils.Any(types, function(type)
return BadGuy.HasPrerequisites({ type })
end)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. That was left behind when I removed the many, many debug messages.

end

IsHarvesterNeeded = function(player)
return player.HasPrerequisites( { "proc" } ) and #player.GetActorsByType("harv") < 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return player.HasPrerequisites( { "proc" } ) and #player.GetActorsByType("harv") < 1
return player.HasPrerequisites({ "proc" }) and #player.GetActorsByType("harv") < 1

return false, "blocked"
end

local actor = Actor.Create(structure.type, true, { Owner = player, Location = structure.location } )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
local actor = Actor.Create(structure.type, true, { Owner = player, Location = structure.location } )
local actor = Actor.Create(structure.type, true, { Owner = player, Location = structure.location })


LinkCooperativeObjectives = function()
local greeceActor = Greece.GetActorsByType("player")[1]
Trigger.Clear(greeceActor, "OnPlayerWon")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has to do with the way objectives are set up to address #20975 (review) 's bit about objective message spam. The mission has points where this can happen:

  1. Greece completes a primary objective.
  2. Greece has completed all primary objectives, and is considered a winner. This triggers the OnPlayerWon added by InitObjectives from campaign.lua.
  3. Mission completion isn't triggered because this is a co-op mission under the hood, and their ally England needs to also win.
  4. After a delay, Greece receives a new primary objective and the mission carries on.

At step 2, there would normally be the speech announcement "Mission accomplished." The options I saw were to remove the trigger from Greece, or put a rewritten InitObjectives into the mission. I figured the first option was less awkward. A little after this line, England's win hands Greece the normal announcement.

Ideally, I'd just set primary objectives at the start and delay showing/announcing them in a more straightforward way, but I realize that's a bit niche.

end
-- Patrolling groups will need to halt.
hunter.Stop()
hunter.Hunt()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IdleHunt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these will be groups using OnIdle to form up on a patrol location, wait until all live members of the group are there, then form up on the next location. An OnIdle clear followed by IdleHunt might be worth doing, though.

Comment on lines 895 to 931
local guide = Actor.Create("c1", false, { Owner = GoodGuy, Location = GuideHouse.Location, SubCell = 4, Facing = Angle.South } )

Trigger.OnAddedToWorld(guide, function()
GuideToForest(guide)
end)

Trigger.AfterDelay(15, function()
if GuideHouse.IsDead then
return
end
guide.IsInWorld = true
end)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
local guide = Actor.Create("c1", false, { Owner = GoodGuy, Location = GuideHouse.Location, SubCell = 4, Facing = Angle.South } )
Trigger.OnAddedToWorld(guide, function()
GuideToForest(guide)
end)
Trigger.AfterDelay(15, function()
if GuideHouse.IsDead then
return
end
guide.IsInWorld = true
end)
Trigger.AfterDelay(15, function()
if GuideHouse.IsDead then
return
end
local guide = Actor.Create("c1", true, { Owner = GoodGuy, Location = GuideHouse.Location, SubCell = 4, Facing = Angle.South })
GuideToForest(guide)
end)

return
end

if not (actor.Type == "e1" and guide.Location == GuideBarrelGoal.Location) then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if not (actor.Type == "e1" and guide.Location == GuideBarrelGoal.Location) then
if actor.Type ~= "e1" or guide.Location ~= GuideBarrelGoal.Location then


guide.Move(GuideBarrelGoal.Location)
local revoked = false
local revokeTargets = Utils.Where( { Executioner, PrisonBarrel1, PrisonBarrel2, PrisonBarrel3, PrisonBarrel4 }, IsAlive)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
local revokeTargets = Utils.Where( { Executioner, PrisonBarrel1, PrisonBarrel2, PrisonBarrel3, PrisonBarrel4 }, IsAlive)
local revokeTargets = Utils.Where({ Executioner, PrisonBarrel1, PrisonBarrel2, PrisonBarrel3, PrisonBarrel4 }, IsAlive)


RemoveActor = function(actor, delay)
Trigger.AfterDelay(delay or 0, function()
if not (actor and actor.IsInWorld) then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if not (actor and actor.IsInWorld) then
if not actor or not actor.IsInWorld then

@JovialFeline JovialFeline force-pushed the negotiations branch 2 times, most recently from 2ea9666 to f74635a Compare September 26, 2023 00:46
@JovialFeline JovialFeline force-pushed the negotiations branch 2 times, most recently from 4760956 to 55459ec Compare December 17, 2023 02:31
@JovialFeline
Copy link
Contributor Author

JovialFeline commented Dec 17, 2023

The last time I made changes, this got stalled for a while with a crash until #21076 fixed that. This is rebased now with other minor adjustments after rereading and retesting.

Changes from September:

(Where did the year go?)

Changed Chrono Tanks to shift into the fight themselves. The dummy unit and its rules have been removed.

Simplified some soldier reinforcements, along with the Guide's spawn.

Simplified Hard dog reinforcements. There was some unnecessary code left from experiments with dogs in the village. Some dogs were created but not in the world until triggered, to avoid their early death from the demo truck explosion. Both dogs are now created normally at the start and given later orders with triggers.

Style tweaks galore.

Changes from today:

Pointed map.yaml at the new(ish) campaign/en.ftl and changed the prison's tooltip to use its translation.

Added a death check to the forest patrol's dog whine.

Added some comments and renamed some things for clarity's sake.

The Guide is extra forbidden from shooting barrels near the prison if the hostages are already free. He still had a chance to do this under certain circumstances:

  • Tanya killed the executioner directly, leaving behind barrels.
  • Tanya lingered north of the prison as Soviet infantry approached the intact barrels.
  • The Guide stood at Waypoint 22, his favorite barrel shooting spot.

The Guide is no longer too polite to infiltrate a friendly church.


Dec 19: BadGuy's pause between structure (re)builds is a few seconds shorter.


Feb 10: Rebased.


Feb 24

Made the StartGameNotification change more graceful.

  • Monster Tank Madness and Mousetrap should probably get this treatment too so load/save speeches play.

Fixed a pair of goofs where I forgot OnAnyKilled triggers will only fire once.

Added a death check to GroupHuntOnDamaged just in case.

Fixed potential crashes for two unlikely events:

  • The Guide dies the instant before he stops to detour around a broken bridge.
  • On Hard, Tanya takes the north route past the tank, kills one of the scattered beach guards with explosive barrels, and does this before the General can arrive there.

Added and tweaked some more comments.

@Porenutak
Copy link
Contributor

Porenutak commented Apr 29, 2024

On hard difficulty the first dog appear while tanya is still in air. On faster speeds its hard micro. Eats me little 10x. I would advice to delay dog at least for 1 sec. Otherwise looks good. Tested on all diffculties and game speeds.

@JovialFeline
Copy link
Contributor Author

That seems reasonable. Funny story, I figured its early appearance would make things easier for two reasons:

  • Tanya can be given an attack order for the dog while still airborne.
  • The dog is extra sure to be ahead of the incoming soldiers, who might "eat" a click if they mix together.

Figuring anybody would know the first bit is a weird assumption on my part, and my concern with the second is likely overblown with how fast dogs move. It shouldn't be hard to adjust the timing.

Does it sound okay if I keep the dog's appearance the same as a warning but delay the actual attack?

@Porenutak
Copy link
Contributor

sure

@JovialFeline
Copy link
Contributor Author

JovialFeline commented Apr 30, 2024

Delayed the start dog's attack a bit. The timeline (at least as I logged it):

  • Tanya activates the trigger at tick 82.
  • Tanya touches the ground at 180.
  • Dog begins its attack at 185 212.

Copy link
Contributor

@Porenutak Porenutak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@PunkPun PunkPun merged commit 670067a into OpenRA:bleed May 3, 2024
3 checks passed
@PunkPun
Copy link
Member

PunkPun commented May 3, 2024

changelog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants