mirror of
https://github.com/open-goal/jak-project
synced 2026-08-04 09:09:52 -04:00
decomp3: more engine stuff, fix ja macro detection for jak 2/3, unmerged let matcher, part-tracker-spawn macro (#3436)
- `aligner` - `effect-control` - `pov-camera` - `powerups` - `los-control-h` - `airlock` - `water-anim` - `blocking-plane` - `proc-focusable-spawner` - `idle-control` - `enemy-h` - `nav-enemy-h` - `enemy` - `enemy-states` - `particle-curves` - `base-plat` - `plat` - `bouncer` - `elevator` - `rigid-body` - `rigid-body-queue` - `process-taskable` - `scene-actor` - `warp-gate` - `guard-projectile` - `metalhead-projectile` - `los-control` - `joint-exploder` - `ragdoll-test` - `debris` - `shield-sphere` - `text` - `target-launch`
This commit is contained in:
@@ -243,6 +243,15 @@ Matcher Matcher::let(bool is_star,
|
||||
return m;
|
||||
}
|
||||
|
||||
Matcher Matcher::unmerged_let(const std::vector<LetEntryMatcher>& entries,
|
||||
const std::vector<Matcher>& elts) {
|
||||
Matcher m;
|
||||
m.m_kind = Kind::UNMERGED_LET;
|
||||
m.m_entry_matchers = entries;
|
||||
m.m_sub_matchers = elts;
|
||||
return m;
|
||||
}
|
||||
|
||||
bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out, const Env* const env) const {
|
||||
switch (m_kind) {
|
||||
case Kind::ANY:
|
||||
@@ -722,6 +731,64 @@ bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out, const Env* cons
|
||||
return false;
|
||||
}
|
||||
|
||||
case Kind::UNMERGED_LET: {
|
||||
auto as_let = dynamic_cast<LetElement*>(input->try_as_single_active_element());
|
||||
if (as_let) {
|
||||
size_t entries_matched = 0;
|
||||
Form* innermost_let_body = nullptr;
|
||||
// first try to find the innermost let, matching all let entries with the entry matchers
|
||||
// throughout
|
||||
as_let->apply_form([&](Form* form) {
|
||||
for (int idx = 0; idx < form->size(); idx++) {
|
||||
auto* f = form->at(idx);
|
||||
// if this is the entry of the outermost let, try to do the first match
|
||||
if (f->parent_form->parent_element == as_let) {
|
||||
if (m_entry_matchers.at(entries_matched)
|
||||
.do_match(as_let->entries().at(0), maps_out, env)) {
|
||||
entries_matched++;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto let = dynamic_cast<LetElement*>(f);
|
||||
if (!let) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto let_body = dynamic_cast<LetElement*>(let->body()->at(0));
|
||||
if (!let_body) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_entry_matchers.at(entries_matched)
|
||||
.do_match(let_body->entries().at(0), maps_out, env)) {
|
||||
entries_matched++;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (entries_matched == m_entry_matchers.size()) {
|
||||
innermost_let_body = let_body->body();
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (entries_matched == m_entry_matchers.size() && innermost_let_body) {
|
||||
// now match body of innermost let
|
||||
for (int i = 0; i < (int)m_sub_matchers.size(); ++i) {
|
||||
Form fake;
|
||||
fake.elts().push_back(innermost_let_body->elts().at(i));
|
||||
if (!m_sub_matchers.at(i).do_match(&fake, maps_out, env)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
ASSERT(false);
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user