Co-op matches of editor campaigns
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0966e3318f
commit
abe01ff23e
13 files changed
+394
-44
No files matched your search
+58
-3
@@ -619,13 +619,68 @@ pub fn run_map_seed(run_seed: u32, mission: usize) -> u32 {
|
||||
// a mission of an editor campaign: its painted map or a random map (rolled from the run's
|
||||
// seed), the goals it can actually have, and its block scripts
|
||||
pub fn start_editor_mission(doc: &crate::campaign_doc::MissionDoc, i: usize, run_seed: u32) -> Game {
|
||||
editor_mission_mode(doc, i, run_seed, false)
|
||||
}
|
||||
|
||||
// the same mission for a co-op match: the other master seats (2, 3, 4) belong to the players, so
|
||||
// rival masters of the map are left out (like the built-in co-op missions) and so is the Rivals goal
|
||||
pub fn start_editor_coop_mission(doc: &crate::campaign_doc::MissionDoc, i: usize, run_seed: u32) -> Game {
|
||||
editor_mission_mode(doc, i, run_seed, true)
|
||||
}
|
||||
|
||||
// editor missions that can be played in co-op: the master areas need a map of at least 72x72,
|
||||
// and a goal other than beating rival masters
|
||||
pub fn is_editor_coop_mission(doc: &crate::campaign_doc::MissionDoc) -> bool {
|
||||
doc.size.0 >= 72 && doc.size.1 >= 72 && crate::campaign_doc::parse_goals(&doc.goals).iter().any(|g| *g != Goal::Rivals)
|
||||
}
|
||||
|
||||
pub fn editor_coop_indexes(doc: &crate::campaign_doc::CampaignDoc) -> Vec<usize> {
|
||||
doc.missions.iter().enumerate().filter(|(_, m)| is_editor_coop_mission(m)).map(|(i, _)| i).collect()
|
||||
}
|
||||
|
||||
pub fn next_editor_coop_mission(doc: &crate::campaign_doc::CampaignDoc, i: usize, dir: i32) -> usize {
|
||||
let list = editor_coop_indexes(doc);
|
||||
if list.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
let pos = list.iter().position(|m| *m == i).unwrap_or(0);
|
||||
list[((pos as i32 + dir).rem_euclid(list.len() as i32)) as usize]
|
||||
}
|
||||
|
||||
// a painted map without its rival masters: their creatures go, their tiles become unowned
|
||||
fn remove_rivals(g: &mut Game) {
|
||||
let sides: Vec<u8> = g.rivals.iter().map(|r| r.side).collect();
|
||||
if sides.is_empty() {
|
||||
return;
|
||||
}
|
||||
g.rivals.clear();
|
||||
g.ents.retain(|e| e.hero || !sides.contains(&e.side));
|
||||
let owners: Vec<Owner> = sides.iter().map(|&s| Owner::of_side(s)).collect();
|
||||
for t in g.map.t.iter_mut() {
|
||||
if owners.contains(&t.owner) {
|
||||
t.owner = Owner::None;
|
||||
if t.kind == Kind::Core {
|
||||
t.kind = Kind::Floor;
|
||||
}
|
||||
}
|
||||
}
|
||||
g.recount();
|
||||
}
|
||||
|
||||
fn editor_mission_mode(doc: &crate::campaign_doc::MissionDoc, i: usize, run_seed: u32, coop: bool) -> Game {
|
||||
use crate::campaign_doc::MapDoc;
|
||||
let generated = || start_mission_def(&generated_def(doc, run_map_seed(run_seed, i)), i, None, coop);
|
||||
let mut g = match &doc.map {
|
||||
MapDoc::Fixed { game } => match load_fixed_map(game) {
|
||||
Some(g) => g,
|
||||
None => start_mission_def(&generated_def(doc, run_map_seed(run_seed, i)), i, None, false),
|
||||
Some(mut g) => {
|
||||
if coop {
|
||||
remove_rivals(&mut g);
|
||||
}
|
||||
g
|
||||
}
|
||||
None => generated(),
|
||||
},
|
||||
MapDoc::Random => start_mission_def(&generated_def(doc, run_map_seed(run_seed, i)), i, None, false),
|
||||
MapDoc::Random => generated(),
|
||||
};
|
||||
g.msgs.clear();
|
||||
g.state = 0;
|
||||
|
||||
Reference in new issue
Block a user