Skip to content

Commit 35bd4a2

Browse files
committed
Attempt to detect add/removeitem usage involving locals
1 parent a0c52bd commit 35bd4a2

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "StandardsValidator"
3-
version = "2.19.0"
3+
version = "2.20.0"
44
edition = "2021"
55

66
[dependencies]

WARNINGS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ This line includes commas or puts quotes around the reputation amount. This is p
321321
### Adds topic which is not defined in this file
322322
`AddTopic X` crashes Morrowind.exe if topic `X` does not exist. If the topic is defined in a master file, all is well.
323323

324+
### Uses global variable quantity which is not defined in this file
325+
`AddItem X Y` and `RemoveItem X Y` don't work in Morrowind.exe if `Y` is a local variable.
326+
324327
## Magic
325328

326329
### Uses effect

src/validators/scripts.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ pub struct ScriptValidator {
4242
add_topic: Regex,
4343
added_topics: HashMap<String, Vec<String>>,
4444
topics: HashSet<String>,
45+
globals: HashSet<String>,
46+
add_remove_item: Regex,
47+
quantity_globals: HashMap<String, Vec<String>>,
4548
}
4649

4750
struct ScriptInfo {
@@ -130,6 +133,9 @@ impl Handler<'_> for ScriptValidator {
130133
self.topics.insert(dial.id.to_ascii_lowercase());
131134
}
132135
}
136+
TES3Object::GlobalVariable(global) => {
137+
self.globals.insert(global.id.to_ascii_lowercase());
138+
}
133139
_ => {}
134140
}
135141
}
@@ -254,6 +260,30 @@ impl Handler<'_> for ScriptValidator {
254260
}
255261
}
256262
}
263+
if let Some(captures) = self.add_remove_item.captures(code) {
264+
let mut capture = captures.get(7);
265+
if capture.is_none() {
266+
capture = captures.get(8);
267+
}
268+
if let Some(string) = capture {
269+
if string.as_str() != "getpccrimelevel" {
270+
let id = string.as_str().to_ascii_lowercase();
271+
let description = if let TES3Object::DialogueInfo(info) = record {
272+
format!("Info {} in topic {}", info.id, topic.id)
273+
} else if let TES3Object::Script(script) = record {
274+
format!("Script {}", script.id)
275+
} else {
276+
String::new()
277+
};
278+
let entry = self.quantity_globals.get_mut(&id);
279+
if let Some(sources) = entry {
280+
sources.push(description);
281+
} else {
282+
self.quantity_globals.insert(id, vec![description]);
283+
}
284+
}
285+
}
286+
}
257287
}
258288

259289
fn on_cellref(
@@ -324,6 +354,17 @@ impl Handler<'_> for ScriptValidator {
324354
);
325355
}
326356
}
357+
for (global, sources) in &self.quantity_globals {
358+
if self.globals.contains(global) {
359+
continue;
360+
}
361+
for source in sources {
362+
println!(
363+
"{} uses global variable quantity {} which is not defined in this file",
364+
source, global
365+
);
366+
}
367+
}
327368
}
328369
}
329370

@@ -384,6 +425,9 @@ impl ScriptValidator {
384425
let mod_reputation = Regex::new(r"^[,\s]*modreputation[,\s]")?;
385426
let mod_facrep = Regex::new(r#"modpcfacrep[,\s]+([0-9"-]+)([,\s]+([^,\s]+))?[,\s]*$"#)?;
386427
let add_topic = Regex::new(r#"^([,\s]*|.*?->[,\s]*)addtopic[,\s]+("([^"]+)"|([^\s"]+))"#)?;
428+
let add_remove_item = Regex::new(
429+
r#"^([,\s]*|.*?->[,\s]*)(add|remove)item[,\s]+("([^"]+)"|([^\s"]+))[,\s]+([+-]?[0-9]+|"([^"]+)"|([^\s"]+))"#,
430+
)?;
387431
Ok(Self {
388432
unique_heads,
389433
scripts: HashMap::new(),
@@ -406,6 +450,9 @@ impl ScriptValidator {
406450
add_topic,
407451
added_topics: HashMap::new(),
408452
topics: HashSet::new(),
453+
globals: HashSet::new(),
454+
add_remove_item,
455+
quantity_globals: HashMap::new(),
409456
})
410457
}
411458

0 commit comments

Comments
 (0)