1use std::fmt::{Display, Formatter};
4
5use bitflags::bitflags;
6
7use crate::context::ScopeContext;
8use crate::everything::Everything;
9use crate::game::Game;
10use crate::helpers::{camel_case_to_separated_words, display_choices, snake_case_to_camel_case};
11use crate::item::Item;
12use crate::lowercase::Lowercase;
13use crate::report::{ErrorKey, err};
14use crate::token::Token;
15
16#[cfg(any(feature = "vic3", feature = "ck3", feature = "eu5"))]
18type ScopesBits = u128;
19#[cfg(not(any(feature = "vic3", feature = "ck3", feature = "eu5")))]
20type ScopesBits = u64;
21
22bitflags! {
23 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
36 #[rustfmt::skip] pub struct Scopes: ScopesBits {
38 const None = 1<<0;
40 const Value = 1<<1;
41 const Bool = 1<<2;
42 const Flag = 1<<3;
43
44 #[cfg(any(feature = "vic3", feature = "imperator", feature = "eu5"))]
47 const Color = 1<<4;
48 #[cfg(any(feature = "vic3", feature = "imperator", feature = "eu5", feature = "hoi4"))]
49 const Country = 1<<5;
50 const Character = 1<<6;
51 #[cfg(any(feature = "ck3", feature = "vic3", feature = "eu5", feature = "imperator"))]
52 const Culture = 1<<7;
53 #[cfg(any(feature = "ck3", feature = "vic3", feature = "imperator", feature = "eu5"))]
54 const Province = 1<<8;
55 #[cfg(any(feature = "vic3", feature = "imperator", feature = "eu5"))]
56 const Pop = 1<<9;
57 #[cfg(any(feature = "vic3", feature = "imperator"))]
58 const Party = 1<<10;
59 #[cfg(feature = "eu5")]
60 const PopType = 1<<10; #[cfg(any(feature = "ck3", feature = "vic3", feature = "imperator", feature = "eu5"))]
62 const Religion = 1<<11;
63 #[cfg(any(feature = "vic3", feature = "imperator", feature = "hoi4"))]
64 const State = 1<<12;
65 #[cfg(feature = "eu5")]
66 const Trait = 1<<12; #[cfg(any(feature = "ck3", feature = "vic3", feature = "imperator", feature = "eu5"))]
68 const War = 1<<13;
69 #[cfg(any(feature = "vic3", feature = "hoi4"))]
70 const StrategicRegion = 1<<14;
71 #[cfg(feature = "eu5")]
72 const Invalid = 1<<14; #[cfg(any(feature = "ck3", feature = "vic3"))]
74 const Decision = 1<<15;
75 #[cfg(feature = "eu5")]
76 const Date = 1<<15; #[cfg(feature = "ck3")] const Accolade = 1<<16;
80 #[cfg(feature = "ck3")] const AccoladeType = 1<<17;
81 #[cfg(feature = "ck3")] const Activity = 1<<18;
82 #[cfg(feature = "ck3")] const ActivityType = 1<<19;
83 #[cfg(feature = "ck3")] const Army = 1<<20;
84 #[cfg(feature = "ck3")] const Artifact = 1<<21;
85 #[cfg(feature = "ck3")] const CasusBelli = 1<<22;
86 #[cfg(feature = "ck3")] const CharacterMemory = 1<<23;
87 #[cfg(feature = "ck3")] const Combat = 1<<24;
88 #[cfg(feature = "ck3")] const CombatSide = 1<<25;
89 #[cfg(feature = "ck3")] const CouncilTask = 1<<26;
90 #[cfg(feature = "ck3")] const CulturePillar = 1<<27;
91 #[cfg(feature = "ck3")] const CultureTradition = 1<<28;
92 #[cfg(feature = "ck3")] const Doctrine = 1<<29;
93 #[cfg(feature = "ck3")] const Dynasty = 1<<30;
94 #[cfg(feature = "ck3")] const DynastyHouse = 1<<31;
95 #[cfg(feature = "ck3")] const Faction = 1<<32;
96 #[cfg(feature = "ck3")] const Faith = 1<<33;
97 #[cfg(feature = "ck3")] const GovernmentType = 1<<34;
98 #[cfg(feature = "ck3")] const GreatHolyWar = 1<<35;
99 #[cfg(feature = "ck3")] const HolyOrder = 1<<36;
100 #[cfg(feature = "ck3")] const Inspiration = 1<<37;
101 #[cfg(feature = "ck3")] const LandedTitle = 1<<38;
102 #[cfg(feature = "ck3")] const MercenaryCompany = 1<<39;
103 #[cfg(feature = "ck3")] const Scheme = 1<<40;
104 #[cfg(feature = "ck3")] const Secret = 1<<41;
105 #[cfg(feature = "ck3")] const StoryCycle = 1<<42;
106 #[cfg(feature = "ck3")] const Struggle = 1<<43;
107 #[cfg(feature = "ck3")] const TitleAndVassalChange = 1<<44;
108 #[cfg(feature = "ck3")] const Trait = 1<<45;
109 #[cfg(feature = "ck3")] const TravelPlan = 1<<46;
110 #[cfg(feature = "ck3")] const VassalContract = 1<<47;
111 #[cfg(feature = "ck3")] const VassalObligationLevel = 1<<48;
112 #[cfg(feature = "ck3")] const HoldingType = 1<<49;
114 #[cfg(feature = "ck3")] const TaxSlot = 1<<50;
115 #[cfg(feature = "ck3")] const EpidemicType = 1<<51;
117 #[cfg(feature = "ck3")] const Epidemic = 1<<52;
118 #[cfg(feature = "ck3")] const LegendType = 1<<53;
119 #[cfg(feature = "ck3")] const Legend = 1<<54;
120 #[cfg(feature = "ck3")] const GeographicalRegion = 1<<55;
121 #[cfg(feature = "ck3")] const Domicile = 1<<56;
123 #[cfg(feature = "ck3")] const AgentSlot = 1<<57;
124 #[cfg(feature = "ck3")] const TaskContract = 1<<58;
125 #[cfg(feature = "ck3")] const TaskContractType = 1<<59;
126 #[cfg(feature = "ck3")] const Regiment = 1<<60;
127 #[cfg(feature = "ck3")] const CasusBelliType = 1<<61;
128 #[cfg(feature = "ck3")] const CourtPosition = 1<<62;
130 #[cfg(feature = "ck3")] const CourtPositionType = 1<<63;
131 #[cfg(feature = "ck3")] const Situation = 1<<64;
133 #[cfg(feature = "ck3")] const SituationParticipantGroup = 1<<65;
134 #[cfg(feature = "ck3")] const SituationSubRegion = 1<<66;
135 #[cfg(feature = "ck3")] const Confederation = 1<<67;
136 #[cfg(feature = "ck3")] const HouseAspiration = 1<<68;
138 #[cfg(feature = "ck3")] const HouseRelation = 1<<69;
139 #[cfg(feature = "ck3")] const HouseRelationType = 1<<70;
140 #[cfg(feature = "ck3")] const HouseRelationLevel = 1<<71;
141 #[cfg(feature = "ck3")] const ConfederationType = 1<<72;
142 #[cfg(feature = "ck3")] const GreatProject = 1<<73;
143 #[cfg(feature = "ck3")] const ProjectContribution = 1<<74;
144 #[cfg(feature = "ck3")] const CultureInnovation = 1<<75;
145 #[cfg(feature = "ck3")] const GreatProjectType = 1<<76;
146
147 #[cfg(feature = "vic3")] const Battle = 1<<16;
148 #[cfg(feature = "vic3")] const BattleSide = 1<<17;
149 #[cfg(feature = "vic3")] const Building = 1<<18;
150 #[cfg(feature = "vic3")] const BuildingType = 1<<19;
151 #[cfg(feature = "vic3")] const CharacterRole = 1<<20;
152 #[cfg(feature = "vic3")] const CivilWar = 1<<21;
153 #[cfg(feature = "vic3")] const CulturalCommunity = 1<<22;
154 #[cfg(feature = "vic3")] const NewCombatUnit = 1<<23;
155 #[cfg(feature = "vic3")] const CommanderOrderType = 1<<24;
156 #[cfg(feature = "vic3")] const CountryCreation = 1<<25;
157 #[cfg(feature = "vic3")] const CountryDefinition = 1<<26;
158 #[cfg(feature = "vic3")] const CountryFormation = 1<<27;
159 #[cfg(feature = "vic3")] const Decree = 1<<28;
160 #[cfg(feature = "vic3")] const DiplomaticAction = 1<<29;
161 #[cfg(feature = "vic3")] const DiplomaticPact = 1<<30;
162 #[cfg(feature = "vic3")] const DiplomaticPlay = 1<<31;
163 #[cfg(feature = "vic3")] const DiplomaticRelations = 1<<32;
164 #[cfg(feature = "vic3")] const Front = 1<<33;
165 #[cfg(feature = "vic3")] const Goods = 1<<34;
166 #[cfg(feature = "vic3")] const Hq = 1<<35;
167 #[cfg(feature = "vic3")] const Ideology = 1<<36;
168 #[cfg(feature = "vic3")] const Institution = 1<<37;
169 #[cfg(feature = "vic3")] const InstitutionType = 1<<38;
170 #[cfg(feature = "vic3")] const InterestMarker = 1<<39;
171 #[cfg(feature = "vic3")] const InterestGroup = 1<<40;
172 #[cfg(feature = "vic3")] const InterestGroupTrait = 1<<41;
173 #[cfg(feature = "vic3")] const InterestGroupType = 1<<42;
174 #[cfg(feature = "vic3")] const JournalEntry = 1<<43;
175 #[cfg(feature = "vic3")] const Law = 1<<44;
176 #[cfg(feature = "vic3")] const LawType = 1<<45;
177 #[cfg(feature = "vic3")] const Market = 1<<46;
178 #[cfg(feature = "vic3")] const MarketGoods = 1<<47;
179 #[cfg(feature = "vic3")] const Objective = 1<<48;
180 #[cfg(feature = "vic3")] const PoliticalMovement = 1<<49;
181 #[cfg(feature = "vic3")] const PopType = 1<<50;
182 #[cfg(feature = "vic3")] const ShippingLanes = 1<<51;
183 #[cfg(feature = "vic3")] const StateRegion = 1<<52;
184 #[cfg(feature = "vic3")] const StateTrait = 1<<53;
185 #[cfg(feature = "vic3")] const Technology = 1<<54;
186 #[cfg(feature = "vic3")] const TechnologyStatus = 1<<55;
187 #[cfg(feature = "vic3")] const Theater = 1<<56;
188 #[cfg(feature = "vic3")] const CombatUnitType = 1<<57;
189 #[cfg(feature = "vic3")] const MilitaryFormation = 1<<58;
190 #[cfg(feature = "vic3")] const Sway = 1<<59;
191 #[cfg(feature = "vic3")] const StateGoods = 1<<60;
192 #[cfg(feature = "vic3")] const DiplomaticDemand = 1<<61;
193 #[cfg(feature = "vic3")] const Company = 1<<62;
194 #[cfg(feature = "vic3")] const CompanyType = 1<<63;
195 #[cfg(feature = "vic3")] const TravelNode = 1<<64;
196 #[cfg(feature = "vic3")] const TravelNodeDefinition = 1<<65;
197 #[cfg(feature = "vic3")] const TravelConnection = 1<<66;
198 #[cfg(feature = "vic3")] const TravelConnectionDefinition = 1<<67;
199 #[cfg(feature = "vic3")] const Invasion = 1<<68;
200 #[cfg(feature = "vic3")] const MobilizationOption = 1<<69;
201 #[cfg(feature = "vic3")] const PowerBlocPrincipleGroup = 1<<70;
202 #[cfg(feature = "vic3")] const DiplomaticPlayType = 1<<71;
203 #[cfg(feature = "vic3")] const DiplomaticCatalyst = 1<<72;
204 #[cfg(feature = "vic3")] const DiplomaticCatalystType = 1<<73;
205 #[cfg(feature = "vic3")] const DiplomaticCatalystCategory = 1<<74;
206 #[cfg(feature = "vic3")] const PoliticalLobby = 1<<75;
207 #[cfg(feature = "vic3")] const PoliticalLobbyType = 1<<76;
208 #[cfg(feature = "vic3")] const PoliticalLobbyAppeasement = 1<<77;
209 #[cfg(feature = "vic3")] const PowerBloc = 1<<78;
210 #[cfg(feature = "vic3")] const PowerBlocIdentity = 1<<79;
211 #[cfg(feature = "vic3")] const PowerBlocPrinciple = 1<<80;
212 #[cfg(feature = "vic3")] const HarvestCondition = 1<<81;
213 #[cfg(feature = "vic3")] const PoliticalMovementType = 1<<82;
214 #[cfg(feature = "vic3")] const HarvestConditionType = 1<<83;
215 #[cfg(feature = "vic3")] const TreatyArticle = 1<<84;
216 #[cfg(feature = "vic3")] const TreatyOptions = 1<<85;
217 #[cfg(feature = "vic3")] const TreatyArticleOptions = 1<<86;
218 #[cfg(feature = "vic3")] const Treaty = 1<<87;
219 #[cfg(feature = "vic3")] const BuildingGroup = 1<<88;
220 #[cfg(feature = "vic3")] const Amendment = 1<<89;
221 #[cfg(feature = "vic3")] const AmendmentType = 1<<90;
222 #[cfg(feature = "vic3")] const GeographicRegion = 1<<91;
223 #[cfg(feature = "vic3")] const WarGoal = 1<<92;
224 #[cfg(feature = "vic3")] const WarGoalType = 1<<93;
225 #[cfg(feature = "vic3")] const InterestTierType = 1<<94;
226 #[cfg(feature = "vic3")] const NavalBattle = 1<<95;
227 #[cfg(feature = "vic3")] const NavalMission = 1<<96;
228 #[cfg(feature = "vic3")] const NavalMissionType = 1<<97;
229 #[cfg(feature = "vic3")] const Ship = 1<<98;
230 #[cfg(feature = "vic3")] const ShipGroup = 1<<99;
231 #[cfg(feature = "vic3")] const ShipModificationType = 1<<100;
232 #[cfg(feature = "vic3")] const ShipType = 1<<101;
233 #[cfg(feature = "vic3")] const Strait = 1<<102;
234 #[cfg(feature = "vic3")] const StraitType = 1<<103;
235
236 #[cfg(feature = "imperator")] const Area = 1<<16;
237 #[cfg(feature = "imperator")] const CountryCulture = 1<<17;
238 #[cfg(feature = "imperator")] const CultureGroup = 1<<18;
239 #[cfg(feature = "imperator")] const Deity = 1<<19;
240 #[cfg(feature = "imperator")] const Family = 1<<20;
241 #[cfg(feature = "imperator")] const Governorship = 1<<21;
242 #[cfg(feature = "imperator")] const GreatWork = 1<<22;
243 #[cfg(feature = "imperator")] const Job = 1<<23;
244 #[cfg(feature = "imperator")] const Legion = 1<<24;
245 #[cfg(feature = "imperator")] const LevyTemplate = 1<<25;
246 #[cfg(feature = "imperator")] const Region = 1<<26;
247 #[cfg(feature = "imperator")] const Siege = 1<<27;
248 #[cfg(feature = "imperator")] const SubUnit = 1<<28;
249 #[cfg(feature = "imperator")] const Treasure = 1<<29;
250 #[cfg(feature = "imperator")] const Unit = 1<<30;
251
252 #[cfg(feature = "eu5")] const Location = 1<<16;
253 #[cfg(feature = "eu5")] const Unit = 1<<17;
254 #[cfg(feature = "eu5")] const SubUnit = 1<<18;
255 #[cfg(feature = "eu5")] const Dynasty = 1<<19;
256 #[cfg(feature = "eu5")] const Combat = 1<<20;
257 #[cfg(feature = "eu5")] const CombatSide = 1<<21;
258 #[cfg(feature = "eu5")] const Siege = 1<<22;
259 #[cfg(feature = "eu5")] const ColonialCharter = 1<<23;
260 #[cfg(feature = "eu5")] const Market = 1<<24;
261 #[cfg(feature = "eu5")] const ProvinceDefinition = 1<<25;
262 #[cfg(feature = "eu5")] const Area = 1<<26;
263 #[cfg(feature = "eu5")] const Region = 1<<27;
264 #[cfg(feature = "eu5")] const SubContinent = 1<<28;
265 #[cfg(feature = "eu5")] const Continent = 1<<29;
266 #[cfg(feature = "eu5")] const Group = 1<<30;
267 #[cfg(feature = "eu5")] const Language = 1<<31;
268 #[cfg(feature = "eu5")] const Rebels = 1<<32;
269 #[cfg(feature = "eu5")] const Trade = 1<<33;
270 #[cfg(feature = "eu5")] const ReligiousSchool = 1<<34;
271 #[cfg(feature = "eu5")] const Goods = 1<<35;
272 #[cfg(feature = "eu5")] const Demand = 1<<36;
273 #[cfg(feature = "eu5")] const Privateer = 1<<37;
274 #[cfg(feature = "eu5")] const Exploration = 1<<38;
275 #[cfg(feature = "eu5")] const Mercenary = 1<<39;
276 #[cfg(feature = "eu5")] const WorkOfArt = 1<<40;
277 #[cfg(feature = "eu5")] const Government = 1<<41;
278 #[cfg(feature = "eu5")] const InternationalOrganization = 1<<42;
279 #[cfg(feature = "eu5")] const HolySite = 1<<43;
280 #[cfg(feature = "eu5")] const Institution = 1<<44;
281 #[cfg(feature = "eu5")] const Loan = 1<<45;
282 #[cfg(feature = "eu5")] const Building = 1<<46;
283 #[cfg(feature = "eu5")] const Law = 1<<47;
284 #[cfg(feature = "eu5")] const Policy = 1<<48;
285 #[cfg(feature = "eu5")] const Price = 1<<49;
286 #[cfg(feature = "eu5")] const Situation = 1<<50;
287 #[cfg(feature = "eu5")] const BuildingType = 1<<51;
288 #[cfg(feature = "eu5")] const Disaster = 1<<52;
289 #[cfg(feature = "eu5")] const ReligiousAspect = 1<<53;
290 #[cfg(feature = "eu5")] const EstatePrivilege = 1<<54;
291 #[cfg(feature = "eu5")] const CabinetAction = 1<<55;
292 #[cfg(feature = "eu5")] const GovernmentReform = 1<<56;
293 #[cfg(feature = "eu5")] const Cabinet = 1<<57;
294 #[cfg(feature = "eu5")] const ProductionMethod = 1<<58;
295 #[cfg(feature = "eu5")] const GraphicalCulture = 1<<59;
296 #[cfg(feature = "eu5")] const DiseaseOutbreak = 1<<60;
297 #[cfg(feature = "eu5")] const Disease = 1<<61;
298 #[cfg(feature = "eu5")] const ParliamentIssue = 1<<62;
299 #[cfg(feature = "eu5")] const ParliamentType = 1<<63;
300 #[cfg(feature = "eu5")] const Resolution = 1<<64;
301 #[cfg(feature = "eu5")] const God = 1<<65;
302 #[cfg(feature = "eu5")] const Avatar = 1<<66;
303 #[cfg(feature = "eu5")] const ReligiousFaction = 1<<67;
304 #[cfg(feature = "eu5")] const SubjectType = 1<<68;
305 #[cfg(feature = "eu5")] const Cardinal = 1<<69;
306 #[cfg(feature = "eu5")] const ActiveResolution = 1<<70;
307 #[cfg(feature = "eu5")] const Estate = 1<<71;
308 #[cfg(feature = "eu5")] const AudioCulture = 1<<72;
309 #[cfg(feature = "eu5")] const AdvanceType = 1<<73;
310 #[cfg(feature = "eu5")] const CharacterInteraction = 1<<74;
311 #[cfg(feature = "eu5")] const CountryInteraction = 1<<75;
312 #[cfg(feature = "eu5")] const GenericAction = 1<<76;
313 #[cfg(feature = "eu5")] const UnitType = 1<<77;
314 #[cfg(feature = "eu5")] const LevySetup = 1<<78;
315 #[cfg(feature = "eu5")] const ParliamentAgenda = 1<<79;
316 #[cfg(feature = "eu5")] const CasusBelli = 1<<80;
317 #[cfg(feature = "eu5")] const RelationType = 1<<81;
318 #[cfg(feature = "eu5")] const DisasterType = 1<<82;
319 #[cfg(feature = "eu5")] const SubUnitCategory = 1<<83;
320 #[cfg(feature = "eu5")] const PeaceTreaty = 1<<84;
321 #[cfg(feature = "eu5")] const ArtistType = 1<<85;
322 #[cfg(feature = "eu5")] const WorkOfArtType = 1<<86;
323 #[cfg(feature = "eu5")] const ChildEducation = 1<<87;
324 #[cfg(feature = "eu5")] const Mission = 1<<88;
325 #[cfg(feature = "eu5")] const MissionTask = 1<<89;
326 #[cfg(feature = "eu5")] const RecruitmentMethod = 1<<90;
327 #[cfg(feature = "eu5")] const RegencyType = 1<<91;
328 #[cfg(feature = "eu5")] const UnitAbility = 1<<92;
329 #[cfg(feature = "eu5")] const SocietalValueType = 1<<93;
330 #[cfg(feature = "eu5")] const RoadType = 1<<94;
331 #[cfg(feature = "eu5")] const LanguageFamily = 1<<95;
332 #[cfg(feature = "eu5")] const CultureGroup = 1<<96;
333 #[cfg(feature = "eu5")] const HeirSelection = 1<<97;
334 #[cfg(feature = "eu5")] const EstateType = 1<<98;
335 #[cfg(feature = "eu5")] const Dialect = 1<<99;
336 #[cfg(feature = "eu5")] const Ethnicity = 1<<100;
337 #[cfg(feature = "eu5")] const InternationalOrganizationType = 1<<101;
338 #[cfg(feature = "eu5")] const Payment = 1<<102;
339 #[cfg(feature = "eu5")] const SpecialStatus = 1<<103;
340 #[cfg(feature = "eu5")] const LandOwnershipRule = 1<<104;
341 #[cfg(feature = "eu5")] const WeatherSystem = 1<<105;
342 #[cfg(feature = "eu5")] const FormableCountry = 1<<106;
343 #[cfg(feature = "eu5")] const Hegemony = 1<<107;
344 #[cfg(feature = "eu5")] const HolySiteDefinition = 1<<108;
345 #[cfg(feature = "eu5")] const HolySiteType = 1<<109;
346 #[cfg(feature = "eu5")] const CountryRank = 1<<110;
347 #[cfg(feature = "eu5")] const LocationRank = 1<<111;
348 #[cfg(feature = "eu5")] const ReligiousFocus = 1<<112;
349 #[cfg(feature = "eu5")] const ReligiousFigure = 1<<113;
350 #[cfg(feature = "eu5")] const Climate = 1<<114;
351 #[cfg(feature = "eu5")] const Vegetation = 1<<115;
352 #[cfg(feature = "eu5")] const Topography = 1<<116;
353 #[cfg(feature = "eu5")] const Age = 1<<117;
354 #[cfg(feature = "eu5")] const EmploymentSystem = 1<<118;
355 #[cfg(feature = "eu5")] const MilitaryStance = 1<<119;
356 #[cfg(feature = "eu5")] const UnitTemplate = 1<<120;
357 #[cfg(feature = "eu5")] const UnitFormationPreference = 1<<121;
358 #[cfg(feature = "eu5")] const ScriptableHintDefinition = 1<<122;
359 #[cfg(feature = "eu5")] const ScriptedGeography = 1<<123;
360 #[cfg(feature = "eu5")] const ReligionGroup = 1<<124;
361
362 #[cfg(feature = "hoi4")] const Ace = 1<<16;
363 #[cfg(feature = "hoi4")] const Combatant = 1<<17;
364 #[cfg(feature = "hoi4")] const Division = 1<<18;
365 #[cfg(feature = "hoi4")] const IndustrialOrg = 1<<19;
366 #[cfg(feature = "hoi4")] const Operation = 1<<20;
367 #[cfg(feature = "hoi4")] const PurchaseContract = 1<<21;
368 #[cfg(feature = "hoi4")] const RaidInstance = 1<<22;
369 #[cfg(feature = "hoi4")] const SpecialProject = 1<<23;
370 #[cfg(feature = "hoi4")] const CombinedCountryAndState = 1<<24;
372 #[cfg(feature = "hoi4")] const CombinedCountryAndCharacter = 1<<25;
373 }
374}
375
376impl Scopes {
379 pub const fn non_primitive() -> Scopes {
380 Scopes::all()
381 .difference(Scopes::None.union(Scopes::Value).union(Scopes::Bool).union(Scopes::Flag))
382 }
383
384 pub const fn primitive() -> Scopes {
385 Scopes::Value.union(Scopes::Bool).union(Scopes::Flag)
386 }
387
388 pub const fn all_but_none() -> Scopes {
389 Scopes::all().difference(Scopes::None)
390 }
391
392 pub fn from_snake_case(s: &str) -> Option<Scopes> {
394 #[cfg(feature = "ck3")]
395 if Game::is_ck3() {
396 match s {
398 "ghw" => return Some(Scopes::GreatHolyWar),
399 "story" => return Some(Scopes::StoryCycle),
400 "great_holy_war" | "story_cycle" => return None,
401 _ => (),
402 }
403 }
404
405 Scopes::from_name(&snake_case_to_camel_case(s))
406 }
407
408 pub fn from_snake_case_multi(s: &str) -> Option<Scopes> {
411 let mut scopes = Scopes::empty();
412 for part in s.split('|') {
413 if let Some(scope) = Scopes::from_snake_case(part) {
414 scopes |= scope;
415 } else {
416 return None;
417 }
418 }
419 if scopes == Scopes::empty() {
422 return None;
423 }
424 Some(scopes)
425 }
426}
427
428impl Display for Scopes {
429 fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
430 if *self == Scopes::all() {
431 write!(f, "any scope")
432 } else if *self == Scopes::primitive() {
433 write!(f, "any primitive scope")
434 } else if *self == Scopes::non_primitive() {
435 write!(f, "non-primitive scope")
436 } else if *self == Scopes::all_but_none() {
437 write!(f, "any except none scope")
438 } else {
439 let mut vec = Vec::new();
440 for (name, _) in self.iter_names() {
441 vec.push(camel_case_to_separated_words(name));
442 }
443 let vec: Vec<&str> = vec.iter().map(String::as_ref).collect();
444 display_choices(f, &vec, "or")
445 }
446 }
447}
448
449#[derive(Copy, Clone, Debug, Eq, PartialEq)]
451pub enum ArgumentValue {
452 #[cfg(any(feature = "ck3", feature = "vic3", feature = "eu5"))]
454 Scope(Scopes),
455 Item(Item),
457 #[cfg(any(feature = "ck3", feature = "vic3", feature = "eu5"))]
459 ScopeOrItem(Scopes, Item),
460 #[cfg(feature = "ck3")]
462 TraitTrack,
463 #[cfg(any(feature = "vic3", feature = "imperator", feature = "eu5"))]
465 Modif,
466 #[cfg(any(feature = "vic3", feature = "ck3", feature = "eu5"))]
468 Identifier(&'static str),
469 #[cfg(feature = "eu5")]
471 Multiple(&'static [ArgumentValue]),
472 UncheckedValue,
474 #[cfg(feature = "ck3")]
476 Removed(&'static str, &'static str),
477}
478
479#[allow(unused_variables)] pub fn scope_to_scope(name: &Token, inscopes: Scopes) -> Option<(Scopes, Scopes)> {
490 let scope_to_scope = match Game::game() {
491 #[cfg(feature = "ck3")]
492 Game::Ck3 => crate::ck3::tables::targets::scope_to_scope,
493 #[cfg(feature = "vic3")]
494 Game::Vic3 => crate::vic3::tables::targets::scope_to_scope,
495 #[cfg(feature = "imperator")]
496 Game::Imperator => crate::imperator::tables::targets::scope_to_scope,
497 #[cfg(feature = "eu5")]
498 Game::Eu5 => crate::eu5::tables::targets::scope_to_scope,
499 #[cfg(feature = "hoi4")]
500 Game::Hoi4 => crate::hoi4::tables::targets::scope_to_scope,
501 };
502 let scope_to_scope_removed = match Game::game() {
503 #[cfg(feature = "ck3")]
504 Game::Ck3 => crate::ck3::tables::targets::scope_to_scope_removed,
505 #[cfg(feature = "vic3")]
506 Game::Vic3 => crate::vic3::tables::targets::scope_to_scope_removed,
507 #[cfg(feature = "imperator")]
508 Game::Imperator => crate::imperator::tables::targets::scope_to_scope_removed,
509 #[cfg(feature = "eu5")]
510 Game::Eu5 => crate::eu5::tables::targets::scope_to_scope_removed,
511 #[cfg(feature = "hoi4")]
512 Game::Hoi4 => crate::hoi4::tables::targets::scope_to_scope_removed,
513 };
514
515 let name_lc = name.as_str().to_ascii_lowercase();
516 #[allow(unused_assignments)] if let scopes @ Some((from, _)) = scope_to_scope(&name_lc) {
518 #[cfg(feature = "vic3")]
519 if Game::is_vic3() && name_lc == "type" {
520 let mut outscopes = Scopes::empty();
523 if inscopes.contains(Scopes::Building) {
524 outscopes |= Scopes::BuildingType;
525 }
526 if inscopes.contains(Scopes::Company) {
527 outscopes |= Scopes::CompanyType;
528 }
529 if inscopes.contains(Scopes::DiplomaticPlay) {
530 outscopes |= Scopes::DiplomaticPlayType;
531 }
532 if inscopes.contains(Scopes::DiplomaticCatalyst) {
533 outscopes |= Scopes::DiplomaticCatalystType;
534 }
535 if inscopes.contains(Scopes::PoliticalLobby) {
536 outscopes |= Scopes::PoliticalLobbyType;
537 }
538 if inscopes.contains(Scopes::Institution) {
539 outscopes |= Scopes::InstitutionType;
540 }
541 if inscopes.contains(Scopes::InterestGroup) {
542 outscopes |= Scopes::InterestGroupType;
543 }
544 if inscopes.contains(Scopes::Law) {
545 outscopes |= Scopes::LawType;
546 }
547 if inscopes.contains(Scopes::PoliticalMovement) {
548 outscopes |= Scopes::PoliticalMovementType;
549 }
550 if inscopes.contains(Scopes::HarvestCondition) {
551 outscopes |= Scopes::HarvestConditionType;
552 }
553 if !outscopes.is_empty() {
554 return Some((from, outscopes));
555 }
556 }
557 scopes
558 } else if let Some((version, explanation)) = scope_to_scope_removed(&name_lc) {
559 let msg = format!("`{name}` was removed in {version}");
560 err(ErrorKey::Removed).strong().msg(msg).info(explanation).loc(name).push();
561 Some((Scopes::all(), Scopes::all_but_none()))
562 } else {
563 None
564 }
565}
566
567pub fn scope_prefix(prefix: &Token) -> Option<(Scopes, Scopes, ArgumentValue)> {
577 let scope_prefix = match Game::game() {
578 #[cfg(feature = "ck3")]
579 Game::Ck3 => crate::ck3::tables::targets::scope_prefix,
580 #[cfg(feature = "vic3")]
581 Game::Vic3 => crate::vic3::tables::targets::scope_prefix,
582 #[cfg(feature = "imperator")]
583 Game::Imperator => crate::imperator::tables::targets::scope_prefix,
584 #[cfg(feature = "eu5")]
585 Game::Eu5 => crate::eu5::tables::targets::scope_prefix,
586 #[cfg(feature = "hoi4")]
587 Game::Hoi4 => crate::hoi4::tables::targets::scope_prefix,
588 };
589 let prefix_lc = prefix.as_str().to_ascii_lowercase();
590 scope_prefix(&prefix_lc)
591}
592
593pub fn needs_prefix(arg: &str, data: &Everything, scopes: Scopes) -> Option<&'static str> {
601 match Game::game() {
602 #[cfg(feature = "ck3")]
603 Game::Ck3 => crate::ck3::scopes::needs_prefix(arg, data, scopes),
604 #[cfg(feature = "vic3")]
605 Game::Vic3 => crate::vic3::scopes::needs_prefix(arg, data, scopes),
606 #[cfg(feature = "imperator")]
607 Game::Imperator => crate::imperator::scopes::needs_prefix(arg, data, scopes),
608 #[cfg(feature = "eu5")]
609 Game::Eu5 => crate::eu5::scopes::needs_prefix(arg, data, scopes),
610 #[cfg(feature = "hoi4")]
611 Game::Hoi4 => crate::hoi4::scopes::needs_prefix(arg, data, scopes),
612 }
613}
614
615pub fn scope_iterator(
625 name: &Token,
626 data: &Everything,
627 sc: &mut ScopeContext,
628) -> Option<(Scopes, Scopes)> {
629 let scope_iterator = match Game::game() {
630 #[cfg(feature = "ck3")]
631 Game::Ck3 => crate::ck3::tables::iterators::iterator,
632 #[cfg(feature = "vic3")]
633 Game::Vic3 => crate::vic3::tables::iterators::iterator,
634 #[cfg(feature = "imperator")]
635 Game::Imperator => crate::imperator::tables::iterators::iterator,
636 #[cfg(feature = "eu5")]
637 Game::Eu5 => crate::eu5::tables::iterators::iterator,
638 #[cfg(feature = "hoi4")]
639 Game::Hoi4 => crate::hoi4::tables::iterators::iterator,
640 };
641 let scope_iterator_removed = match Game::game() {
642 #[cfg(feature = "ck3")]
643 Game::Ck3 => crate::ck3::tables::iterators::iterator_removed,
644 #[cfg(feature = "vic3")]
645 Game::Vic3 => crate::vic3::tables::iterators::iterator_removed,
646 #[cfg(feature = "imperator")]
647 Game::Imperator => crate::imperator::tables::iterators::iterator_removed,
648 #[cfg(feature = "eu5")]
649 Game::Eu5 => crate::eu5::tables::iterators::iterator_removed,
650 #[cfg(feature = "hoi4")]
651 Game::Hoi4 => crate::hoi4::tables::iterators::iterator_removed,
652 };
653
654 let name_lc = Lowercase::new(name.as_str());
655 if let scopes @ Some(_) = scope_iterator(&name_lc, name, data) {
656 return scopes;
657 }
658 if let Some((version, explanation)) = scope_iterator_removed(name_lc.as_str()) {
659 let msg = format!("`{name}` iterators were removed in {version}");
660 err(ErrorKey::Removed).strong().msg(msg).info(explanation).loc(name).push();
661 return Some((Scopes::all(), Scopes::all()));
662 }
663 #[cfg(feature = "jomini")]
664 if Game::is_jomini() && data.scripted_lists.exists(name.as_str()) {
665 data.scripted_lists.validate_call(name, data, sc);
666 return data
667 .scripted_lists
668 .base(name)
669 .and_then(|base| scope_iterator(&Lowercase::new(base.as_str()), base, data));
670 }
671 #[cfg(feature = "hoi4")]
672 let _ = &data; #[cfg(feature = "hoi4")]
674 let _ = ≻ None
676}