diff --git a/ic10emu/build.rs b/ic10emu/build.rs index 5dd8cec..bd1a0da 100644 --- a/ic10emu/build.rs +++ b/ic10emu/build.rs @@ -18,11 +18,70 @@ where pub deprecated: bool, } +struct ReprEnumVariant

+where + P: Display + FromStr, +{ + pub value: P, + pub deprecated: bool, + pub props: Vec<(String, String)> +} + fn write_repr_enum<'a, T: std::io::Write, I, P>( writer: &mut BufWriter, name: &str, variants: I, use_phf: bool, +) where + P: Display + FromStr + 'a, + I: IntoIterator)>, +{ + let additional_strum = if use_phf { "#[strum(use_phf)]\n" } else { "" }; + let repr = std::any::type_name::

(); + write!( + writer, + "#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, EnumString, AsRefStr, EnumProperty, EnumIter, FromRepr, Serialize, Deserialize)]\n\ + {additional_strum}\ + #[repr({repr})]\n\ + pub enum {name} {{\n" + ) + .unwrap(); + for (name, variant) in variants { + let variant_name = name.replace('.', "").to_case(Case::Pascal); + let serialize = vec![name.clone()]; + let serialize_str = serialize + .into_iter() + .map(|s| format!("serialize = \"{s}\"")) + .collect::>() + .join(", "); + let mut props = Vec::new(); + if variant.deprecated { + props.push("deprecated = \"true\"".to_owned()); + } + for (prop_name, prop_val) in &variant.props { + props.push(format!("{prop_name} = \"{prop_val}\"")); + } + let val = &variant.value; + props.push(format!("value = \"{val}\"")); + let props_str = if !props.is_empty() { + format!(", props( {} )", props.join(", ")) + } else { + "".to_owned() + }; + writeln!( + writer, + " #[strum({serialize_str}{props_str})] {variant_name} = {val}{repr}," + ) + .unwrap(); + } + writeln!(writer, "}}").unwrap(); +} + +fn write_enum<'a, T: std::io::Write, I, P>( + writer: &mut BufWriter, + name: &str, + variants: I, + use_phf: bool, ) where P: Display + FromStr + 'a, I: IntoIterator)>, @@ -72,7 +131,7 @@ fn write_logictypes() { let output_file = File::create(dest_path).unwrap(); let mut writer = BufWriter::new(&output_file); - let mut logictypes: Vec<(String, EnumVariant)> = Vec::new(); + let mut logictypes: Vec<(String, ReprEnumVariant)> = Vec::new(); let l_infile = Path::new("data/logictypes.txt"); let l_contents = fs::read_to_string(l_infile).unwrap(); @@ -80,42 +139,26 @@ fn write_logictypes() { let mut it = line.splitn(3, ' '); let name = it.next().unwrap(); let val_str = it.next().unwrap(); - let val: Option = val_str.parse().ok(); + let value: u16 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u16: {err}")); let docs = it.next(); let deprecated = docs .map(|docs| docs.trim().to_uppercase() == "DEPRECATED") .unwrap_or(false); - - if let Some(val) = val { - if let Some((_other_name, variant)) = logictypes - .iter_mut() - .find(|(_, variant)| variant.value == Some(val)) - { - variant.aliases.push(name.to_string()); - variant.deprecated = deprecated; - } else { - logictypes.push(( - name.to_string(), - EnumVariant { - aliases: Vec::new(), - value: Some(val), - deprecated, - }, - )); - } - } else { - logictypes.push(( - name.to_string(), - EnumVariant { - aliases: Vec::new(), - value: val, - deprecated, - }, - )); + let mut props = Vec::new(); + if let Some(docs) = docs { + props.push(("docs".to_owned(), docs.to_owned())); } + logictypes.push(( + name.to_string(), + ReprEnumVariant { + value, + deprecated, + props, + }, + )); } - let mut slotlogictypes: Vec<(String, EnumVariant)> = Vec::new(); + let mut slotlogictypes: Vec<(String, ReprEnumVariant)> = Vec::new(); let sl_infile = Path::new("data/slotlogictypes.txt"); let sl_contents = fs::read_to_string(sl_infile).unwrap(); @@ -123,39 +166,23 @@ fn write_logictypes() { let mut it = line.splitn(3, ' '); let name = it.next().unwrap(); let val_str = it.next().unwrap(); - let val: Option = val_str.parse().ok(); + let value: u8 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u8: {err}")); let docs = it.next(); let deprecated = docs .map(|docs| docs.trim().to_uppercase() == "DEPRECATED") .unwrap_or(false); - - if let Some(val) = val { - if let Some((_other_name, variant)) = slotlogictypes - .iter_mut() - .find(|(_, variant)| variant.value == Some(val)) - { - variant.aliases.push(name.to_string()); - variant.deprecated = deprecated; - } else { - slotlogictypes.push(( - name.to_string(), - EnumVariant { - aliases: Vec::new(), - value: Some(val), - deprecated, - }, - )); - } - } else { - slotlogictypes.push(( - name.to_string(), - EnumVariant { - aliases: Vec::new(), - value: val, - deprecated, - }, - )); + let mut props = Vec::new(); + if let Some(docs) = docs { + props.push(("docs".to_owned(), docs.to_owned())); } + slotlogictypes.push(( + name.to_string(), + ReprEnumVariant { + value, + deprecated, + props, + }, + )); } write_repr_enum(&mut writer, "LogicType", &logictypes, true); @@ -198,7 +225,7 @@ fn write_enums() { )); } - write_repr_enum(&mut writer, "LogicEnums", &enums_map, true); + write_enum(&mut writer, "LogicEnums", &enums_map, true); println!("cargo:rerun-if-changed=data/enums.txt"); } @@ -210,7 +237,7 @@ fn write_modes() { let output_file = File::create(dest_path).unwrap(); let mut writer = BufWriter::new(&output_file); - let mut batchmodes: Vec<(String, EnumVariant)> = Vec::new(); + let mut batchmodes: Vec<(String, ReprEnumVariant)> = Vec::new(); let b_infile = Path::new("data/batchmodes.txt"); let b_contents = fs::read_to_string(b_infile).unwrap(); @@ -218,37 +245,19 @@ fn write_modes() { let mut it = line.splitn(3, ' '); let name = it.next().unwrap(); let val_str = it.next().unwrap(); - let val: Option = val_str.parse().ok(); + let value: u8 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u8: {err}")); - if let Some(val) = val { - if let Some((_other_name, variant)) = batchmodes - .iter_mut() - .find(|(_, variant)| variant.value == Some(val)) - { - variant.aliases.push(name.to_string()); - } else { - batchmodes.push(( - name.to_string(), - EnumVariant { - aliases: Vec::new(), - value: Some(val), - deprecated: false, - }, - )); - } - } else { - batchmodes.push(( - name.to_string(), - EnumVariant { - aliases: Vec::new(), - value: val, - deprecated: false, - }, - )); - } + batchmodes.push(( + name.to_string(), + ReprEnumVariant { + value, + deprecated: false, + props: Vec::new(), + }, + )); } - let mut reagentmodes: Vec<(String, EnumVariant)> = Vec::new(); + let mut reagentmodes: Vec<(String, ReprEnumVariant)> = Vec::new(); let r_infile = Path::new("data/reagentmodes.txt"); let r_contents = fs::read_to_string(r_infile).unwrap(); @@ -256,34 +265,16 @@ fn write_modes() { let mut it = line.splitn(3, ' '); let name = it.next().unwrap(); let val_str = it.next().unwrap(); - let val: Option = val_str.parse().ok(); + let value: u8 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u8: {err}")); + reagentmodes.push(( + name.to_string(), + ReprEnumVariant { + value, + deprecated: false, + props: Vec::new(), + }, + )); - if let Some(val) = val { - if let Some((_other_name, variant)) = reagentmodes - .iter_mut() - .find(|(_, variant)| variant.value == Some(val)) - { - variant.aliases.push(name.to_string()); - } else { - reagentmodes.push(( - name.to_string(), - EnumVariant { - aliases: Vec::new(), - value: Some(val), - deprecated: false, - }, - )); - } - } else { - reagentmodes.push(( - name.to_string(), - EnumVariant { - aliases: Vec::new(), - value: val, - deprecated: false, - }, - )); - } } write_repr_enum(&mut writer, "BatchMode", &batchmodes, false); @@ -381,12 +372,50 @@ fn write_instructions_enum() { println!("cargo:rerun-if-changed=data/instructions.txt"); } +fn write_stationpedia() { + let out_dir = env::var_os("OUT_DIR").unwrap(); + + let dest_path = Path::new(&out_dir).join("stationpedia_prefabs.rs"); + let output_file = File::create(dest_path).unwrap(); + let mut writer = BufWriter::new(&output_file); + + let mut prefabs: Vec<(String, ReprEnumVariant)> = Vec::new(); + let l_infile = Path::new("data/stationpedia.txt"); + let l_contents = fs::read_to_string(l_infile).unwrap(); + + for line in l_contents.lines().filter(|l| !l.trim().is_empty()) { + let mut it = line.splitn(3, ' '); + let val_str = it.next().unwrap(); + let value: i32 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid i32: {err}")); + let name = it.next().unwrap(); + let title = it.next(); + + let mut props = Vec::new(); + if let Some(title) = title { + props.push(("title".to_owned(), title.to_owned())); + } + + prefabs.push(( + name.to_string(), + ReprEnumVariant { + value, + deprecated: false, + props, + }, + )); + } + + write_repr_enum(&mut writer, "StationpediaPrefab", &prefabs, true); + + println!("cargo:rerun-if-changed=data/stationpdeia.txt"); +} + fn main() { - // write_instructions(); write_logictypes(); write_modes(); write_constants(); write_enums(); write_instructions_enum(); + write_stationpedia(); } diff --git a/ic10emu/data/enums.txt b/ic10emu/data/enums.txt index 46ef9b3..6c492db 100644 --- a/ic10emu/data/enums.txt +++ b/ic10emu/data/enums.txt @@ -81,6 +81,7 @@ LogicType.AlignmentError 243 LogicType.Apex 238 LogicType.AutoLand 226 Engages the automatic landing algorithm. The rocket will automatically throttle and turn on and off its engines to achieve a smooth landing. LogicType.AutoShutOff 218 Turns off all devices in the rocket upon reaching destination +LogicType.BestContactFilter 267 LogicType.Bpm 103 Bpm LogicType.BurnTimeRemaining 225 Estimated time in seconds until fuel is depleted. Calculated based on current fuel usage. LogicType.CelestialHash 242 @@ -346,6 +347,11 @@ PowerMode.Charging 3 PowerMode.Discharged 1 PowerMode.Discharging 2 PowerMode.Idle 0 +ReEntryProfile.High 3 +ReEntryProfile.Max 4 +ReEntryProfile.Medium 2 +ReEntryProfile.None 0 +ReEntryProfile.Optimal 1 RobotMode.Follow 1 RobotMode.MoveToTarget 2 RobotMode.None 0 @@ -353,6 +359,12 @@ RobotMode.PathToTarget 5 RobotMode.Roam 3 RobotMode.StorageFull 6 RobotMode.Unload 4 +RocketMode.Chart 5 +RocketMode.Discover 4 +RocketMode.Invalid 0 +RocketMode.Mine 2 +RocketMode.None 1 +RocketMode.Survey 3 SlotClass.AccessCard 22 SlotClass.Appliance 18 SlotClass.Back 3 @@ -388,10 +400,18 @@ SlotClass.ScanningHead 36 SlotClass.SensorProcessingUnit 30 SlotClass.SoundCartridge 34 SlotClass.Suit 2 +SlotClass.SuitMod 39 SlotClass.Tool 17 SlotClass.Torpedo 20 SlotClass.Uniform 12 SlotClass.Wreckage 33 +SorterInstruction.FilterPrefabHashEquals 1 +SorterInstruction.FilterPrefabHashNotEquals 2 +SorterInstruction.FilterQuantityCompare 5 +SorterInstruction.FilterSlotTypeCompare 4 +SorterInstruction.FilterSortingClassCompare 3 +SorterInstruction.LimitNextExecutionByCount 6 +SorterInstruction.None 0 SortingClass.Appliances 6 SortingClass.Atmospherics 7 SortingClass.Clothing 5 diff --git a/ic10emu/data/logictypes.txt b/ic10emu/data/logictypes.txt index e363bdc..ccd785a 100644 --- a/ic10emu/data/logictypes.txt +++ b/ic10emu/data/logictypes.txt @@ -1,14 +1,15 @@ Acceleration 216 Change in velocity. Rockets that are deccelerating when landing will show this as negative value. Activate 9 1 if device is activated (usually means running), otherwise 0 AirRelease 75 The current state of the air release system, for example AirRelease = 1 for a Hardsuit sets Air Release to On -AlignmentError 243 -Apex 238 +AlignmentError 243 +Apex 238 AutoLand 226 Engages the automatic landing algorithm. The rocket will automatically throttle and turn on and off its engines to achieve a smooth landing. AutoShutOff 218 Turns off all devices in the rocket upon reaching destination +BestContactFilter 267 Bpm 103 Bpm BurnTimeRemaining 225 Estimated time in seconds until fuel is depleted. Calculated based on current fuel usage. -CelestialHash 242 -CelestialParentHash 250 +CelestialHash 242 +CelestialParentHash 250 Channel0 165 Channel 0 on a cable network which should be considered volatile Channel1 166 Channel 1 on a cable network which should be considered volatile Channel2 167 Channel 2 on a cable network which should be considered volatile @@ -18,10 +19,10 @@ Channel5 170 Channel 5 on a cable network which should be considered volatile Channel6 171 Channel 6 on a cable network which should be considered volatile Channel7 172 Channel 7 on a cable network which should be considered volatile Charge 11 The current charge the device has -Chart 256 -ChartedNavPoints 259 +Chart 256 +ChartedNavPoints 259 ClearMemory 62 When set to 1, clears the counter memory (e.g. ExportCount). Will set itself back to 0 when actioned -CollectableGoods 101 +CollectableGoods 101 Color 38 \n Whether driven by concerns for clarity, safety or simple aesthetics, {LINK:Stationeers;Stationeers} have access to a small rainbow of colors for their constructions. These are the color setting for devices, represented as an integer.\n\n0: Blue\n1: Grey\n2: Green\n3: Orange\n4: Red\n5: Yellow\n6: White\n7: Black\n8: Brown\n9: Khaki\n10: Pink\n11: Purple\n\n It is an unwavering universal law that anything higher than 11 will be purple. The {LINK:ODA;ODA} is powerless to change this. Similarly, anything lower than 0 will be Blue.\n Combustion 98 The assess atmosphere is on fire. Returns 1 if atmosphere is on fire, 0 if not. CombustionInput 146 The assess atmosphere is on fire. Returns 1 if device's input network is on fire, 0 if not. @@ -31,34 +32,34 @@ CombustionOutput 148 The assess atmosphere is on fire. Returns 1 if device's Out CombustionOutput2 149 The assess atmosphere is on fire. Returns 1 if device's Output2 network is on fire, 0 if not. CompletionRatio 61 How complete the current production is for this device, between 0 and 1 ContactTypeId 198 The type id of the contact. -CurrentCode 261 -CurrentResearchPodType 93 -Density 262 +CurrentCode 261 +CurrentResearchPodType 93 +Density 262 DestinationCode 215 Unique identifier code for a destination on the space map. -Discover 255 -DistanceAu 244 -DistanceKm 249 -DrillCondition 240 +Discover 255 +DistanceAu 244 +DistanceKm 249 +DrillCondition 240 DryMass 220 The Mass in kilograms of the rocket excluding fuel. The more massive the rocket the more fuel will be required to move to a new location in space. -Eccentricity 247 +Eccentricity 247 ElevatorLevel 40 Level the elevator is currently at ElevatorSpeed 39 Current speed of the elevator -EntityState 239 +EntityState 239 EnvironmentEfficiency 104 The Environment Efficiency reported by the machine, as a float between 0 and 1 Error 4 1 if device is in error state, otherwise 0 -ExhaustVelocity 235 +ExhaustVelocity 235 ExportCount 63 How many items exported since last ClearMemory ExportQuantity 31 Total quantity of items exported by the device ExportSlotHash 42 DEPRECATED ExportSlotOccupant 32 DEPRECATED Filtration 74 The current state of the filtration system, for example Filtration = 1 for a Hardsuit sets filtration to On -FlightControlRule 236 +FlightControlRule 236 Flush 174 Set to 1 to activate the flush function on the device ForceWrite 85 Forces Logic Writer devices to rewrite value -ForwardX 227 -ForwardY 228 -ForwardZ 229 -Fuel 99 +ForwardX 227 +ForwardY 228 +ForwardZ 229 +Fuel 99 Harvest 69 Performs the harvesting action for any plant based machinery Horizontal 20 Horizontal setting of the device HorizontalRatio 34 Radio of horizontal setting for device @@ -67,30 +68,29 @@ ImportCount 64 How many items imported since last ClearMemory ImportQuantity 29 Total quantity of items imported by the device ImportSlotHash 43 DEPRECATED ImportSlotOccupant 30 DEPRECATED -Inclination 246 -Index 241 +Inclination 246 +Index 241 InterrogationProgress 157 Progress of this sattellite dish's interrogation of its current target, as a ratio from 0-1 LineNumber 173 The line number of current execution for an integrated circuit running on this device. While this number can be written, use with caution Lock 10 1 if device is locked, otherwise 0, can be set in most devices and prevents the user from access the values -ManualResearchRequiredPod 94 +ManualResearchRequiredPod 94 Mass 219 The total Mass of the rocket in kilograms including fuel and cargo. The more massive the rocket the more fuel will be required to move to a new location in space. Maximum 23 Maximum setting of the device -MinWattsToContact 163 Minimum required amount of watts from the dish hitting the target trader contact to start interrogating the contact -MineablesInQueue 96 -MineablesInVicinity 95 -MinedQuantity 266 +MineablesInQueue 96 +MineablesInVicinity 95 +MinedQuantity 266 MinimumWattsToContact 163 Minimum required amount of watts from the dish hitting the target trader contact to start interrogating the contact Mode 3 Integer for mode state, different devices will have different mode states available to them -NavPoints 258 -NextWeatherEventTime 97 +NavPoints 258 +NextWeatherEventTime 97 None 0 No description On 28 The current state of the device, 0 for off, 1 for on Open 2 1 if device is open, otherwise 0 OperationalTemperatureEfficiency 150 How the input pipe's temperature effects the machines efficiency -OrbitPeriod 245 -Orientation 230 +OrbitPeriod 245 +Orientation 230 Output 70 The output operation for a sort handling device, such as a stacker or sorter, when in logic mode the device will only action one repetition when set zero or above and then back to -1 and await further instructions -PassedMoles 234 +PassedMoles 234 Plant 68 Performs the planting action for any plant based machinery PlantEfficiency1 52 DEPRECATED PlantEfficiency2 53 DEPRECATED @@ -202,33 +202,31 @@ RatioWaterInput 113 The ratio of water in device's input network RatioWaterInput2 123 The ratio of water in device's Input2 network RatioWaterOutput 133 The ratio of water in device's Output network RatioWaterOutput2 143 The ratio of water in device's Output2 network -ReEntryAltitude 237 +ReEntryAltitude 237 Reagents 13 Total number of reagents recorded by the device RecipeHash 41 Current hash of the recipe the device is set to produce -ReferenceId 217 +ReferenceId 217 RequestHash 60 When set to the unique identifier, requests an item of the provided type from the device RequiredPower 33 Idle operating power quantity, does not necessarily include extra demand power -ReturnFuelCost 100 -Richness 263 +ReturnFuelCost 100 +Richness 263 Rpm 155 The number of revolutions per minute that the device's spinning mechanism is doing -SemiMajorAxis 248 +SemiMajorAxis 248 Setting 12 A variable setting that can be read or written, depending on the device -SettingInput 91 -SettingInputHash 91 The input setting for the device -SettingOutput 92 -SettingOutputHash 91 The output setting for the device +SettingInput 91 The input setting for the device +SettingOutput 92 The output setting for the device SignalID 87 Returns the contact ID of the strongest signal from this Satellite SignalStrength 86 Returns the degree offset of the strongest contact -Sites 260 -Size 264 +Sites 260 +Size 264 SizeX 160 Size on the X (right) axis of the object in largeGrids (a largeGrid is 2meters) SizeY 161 Size on the Y(Up) axis of the object in largeGrids (a largeGrid is 2meters) SizeZ 162 Size on the Z(Forward) axis of the object in largeGrids (a largeGrid is 2meters) SolarAngle 22 Solar angle of the device -SolarIrradiance 176 +SolarIrradiance 176 SoundAlert 175 Plays a sound alert on the devices speaker Stress 156 Machines get stressed when working hard. When Stress reaches 100 the machine will automatically shut down -Survey 257 +Survey 257 TargetPadIndex 158 The index of the trader landing pad on this devices data network that it will try to call a trader in to land TargetX 88 The target position in X dimension in world coordinates TargetY 89 The target position in Y dimension in world coordinates @@ -251,15 +249,15 @@ TotalMolesInput 115 Returns the total moles of the device's Input Network TotalMolesInput2 125 Returns the total moles of the device's Input2 Network TotalMolesOutput 135 Returns the total moles of the device's Output Network TotalMolesOutput2 145 Returns the total moles of the device's Output2 Network -TotalQuantity 265 -TrueAnomaly 251 +TotalQuantity 265 +TrueAnomaly 251 VelocityMagnitude 79 The current magnitude of the velocity vector VelocityRelativeX 80 The current velocity X relative to the forward vector of this VelocityRelativeY 81 The current velocity Y relative to the forward vector of this VelocityRelativeZ 82 The current velocity Z relative to the forward vector of this -VelocityX 231 -VelocityY 232 -VelocityZ 233 +VelocityX 231 +VelocityY 232 +VelocityZ 233 Vertical 21 Vertical setting of the device VerticalRatio 35 Radio of vertical setting for device Volume 67 Returns the device atmosphere volume diff --git a/ic10emu/data/stationpedia.txt b/ic10emu/data/stationpedia.txt index 9250587..7c65011 100644 --- a/ic10emu/data/stationpedia.txt +++ b/ic10emu/data/stationpedia.txt @@ -157,7 +157,7 @@ -746362430 DynamicCrateCableSupplies Crate (Cabling Supplies) 166707648 DynamicCrateConveyorSupplies Crate (Conveyor Supplies) -282237045 DynamicCratePipeSupplies Crate (Pipe Supplies) --2085885850 DynamicGPR Ground Penetrating Radar (GPR) +-2085885850 DynamicGPR -1713611165 DynamicGasCanisterAir Portable Gas Tank (Air) -322413931 DynamicGasCanisterCarbonDioxide Portable Gas Tank (CO2) -1741267161 DynamicGasCanisterEmpty Portable Gas Tank @@ -225,6 +225,7 @@ -626453759 Invar Invar -666742878 Iron Iron -842048328 ItemActiveVent Kit (Active Vent) +1871048978 ItemAdhesiveInsulation Adhesive Insulation 1722785341 ItemAdvancedTablet Advanced Tablet 176446172 ItemAlienMushroom Alien Mushroom -9559091 ItemAmmoBox Ammo Box @@ -500,6 +501,8 @@ 288111533 ItemKitIceCrusher Kit (Ice Crusher) 2067655311 ItemKitInsulatedLiquidPipe Kit (Insulated Liquid Pipe) 452636699 ItemKitInsulatedPipe Kit (Insulated Pipe) +-27284803 ItemKitInsulatedPipeUtility Kit (Insulated Pipe Utility Gas) +-1831558953 ItemKitInsulatedPipeUtilityLiquid Kit (Insulated Pipe Utility Liquid) -1708400347 ItemKitInsulatedWaterPipe Insulated Water Pipe Kit 1935945891 ItemKitInteriorDoors Kit (Interior Doors) 489494578 ItemKitLadder Kit (Ladder) @@ -793,6 +796,13 @@ -2038663432 ItemStelliteGlassSheets Stellite Glass Sheets -1897868623 ItemStelliteIngot Ingot (Stellite) -1335056202 ItemSugarCane Sugar Cane +1447327071 ItemSuitAdvancedAC Advanced AC Suit +711019524 ItemSuitEmergency Emergency Suit +70631292 ItemSuitHard Hard Suit +-2020709888 ItemSuitInsulated Insulated Suit +-1274308304 ItemSuitModCryogenicUpgrade Cryogenic Suit Upgrade +-942170293 ItemSuitNormal Normal Suit +416903029 ItemSuitSpace Space Suit 318109626 ItemSuitStorage Kit (Suit Storage) -229808600 ItemTablet Handheld Tablet -1782380726 ItemTankConnector Kit (Tank Connector) @@ -1342,6 +1352,10 @@ 35149429 StructureInLineTankGas1x2 In-Line Tank Gas 543645499 StructureInLineTankLiquid1x1 In-Line Tank Small Liquid -1183969663 StructureInLineTankLiquid1x2 In-Line Tank Liquid +1818267386 StructureInsulatedInLineTankGas1x1 Insulated In-Line Tank Small Gas +-177610944 StructureInsulatedInLineTankGas1x2 Insulated In-Line Tank Gas +-813426145 StructureInsulatedInLineTankLiquid1x1 Insulated In-Line Tank Small Liquid +1452100517 StructureInsulatedInLineTankLiquid1x2 Insulated In-Line Tank Liquid -1967711059 StructureInsulatedPipeCorner Insulated Pipe (Corner) -92778058 StructureInsulatedPipeCrossJunction Insulated Pipe (Cross Junction) 1328210035 StructureInsulatedPipeCrossJunction3 Insulated Pipe (3-Way Junction) @@ -1422,6 +1436,7 @@ 546002924 StructureLogicRocketUplink Logic Uplink 1822736084 StructureLogicSelect Logic Select -767867194 StructureLogicSlotReader Slot Reader +873418029 StructureLogicSorter Logic Sorter 1220484876 StructureLogicSwitch Lever 321604921 StructureLogicSwitch2 Switch -693235651 StructureLogicTransmitter Logic Transmitter @@ -1638,7 +1653,6 @@ 1570931620 StructureTraderWaypoint Trader Waypoint -1423212473 StructureTransformer Transformer (Large) -1065725831 StructureTransformerMedium Transformer (Medium) --771036757 StructureTransformerMedium(Reversed) Transformer Reversed (Medium) 833912764 StructureTransformerMediumReversed Transformer Reversed (Medium) -890946730 StructureTransformerSmall Transformer (Small) 1054059374 StructureTransformerSmallReversed Transformer Reversed (Small) diff --git a/ic10emu/generate_data.py b/ic10emu/generate_data.py index 187bd7e..afece3d 100644 --- a/ic10emu/generate_data.py +++ b/ic10emu/generate_data.py @@ -210,7 +210,7 @@ def extract_data(install_path: Path, data_path: Path, language: str): continue key = key.text value = value.text - if key is None: + if key is None or any(bad in key for bad in "(){}|[]") : continue crc_u = binascii.crc32(key.encode('utf-8')) crc_i: int = struct.unpack("i", struct.pack("I", crc_u))[0] diff --git a/ic10emu/src/grammar.rs b/ic10emu/src/grammar.rs index 027dc14..b1ff57e 100644 --- a/ic10emu/src/grammar.rs +++ b/ic10emu/src/grammar.rs @@ -11,12 +11,9 @@ pub mod generated { use crate::interpreter::ICError; use serde::{Deserialize, Serialize}; use std::str::FromStr; - use strum::AsRefStr; - use strum::Display; - use strum::EnumIter; - use strum::EnumProperty; - use strum::EnumString; - use strum::IntoEnumIterator; + use strum::{ + AsRefStr, Display, EnumIter, EnumProperty, EnumString, FromRepr, IntoEnumIterator, + }; include!(concat!(env!("OUT_DIR"), "/instructions.rs")); include!(concat!(env!("OUT_DIR"), "/logictypes.rs")); @@ -1081,7 +1078,9 @@ impl Number { } pub fn value_i64(&self, signed: bool) -> i64 { match self { - Number::Enum(val) | Number::Float(val) | Number::Constant(val) => interpreter::f64_to_i64(*val, signed), + Number::Enum(val) | Number::Float(val) | Number::Constant(val) => { + interpreter::f64_to_i64(*val, signed) + } Number::Binary(val) | Number::Hexadecimal(val) => *val, Number::String(s) => const_crc32::crc32(s.as_bytes()) as i32 as i64, } diff --git a/ic10emu/src/vm/object/macros.rs b/ic10emu/src/vm/object/macros.rs index accde95..cdb3fef 100644 --- a/ic10emu/src/vm/object/macros.rs +++ b/ic10emu/src/vm/object/macros.rs @@ -1,5 +1,5 @@ macro_rules! object_trait { - (intf {$trait_name:ident $trt:path}) => { + (@intf {$trait_name:ident $trt:path}) => { paste::paste! { #[allow(missing_docs)] pub type [<$trt Ref>]<'a, T> = &'a dyn $trt::ID>; @@ -7,30 +7,37 @@ macro_rules! object_trait { pub type [<$trt RefMut>]<'a, T> = &'a mut dyn $trt::ID>; } }; - ( $trait_name:ident {$($trt:path),*}) => { + (@body $trait_name:ident $($trt:path),*) => { + type ID; + fn id(&self) -> &Self::ID; + + fn type_name(&self) -> &str; + + fn as_object(&self) -> &dyn $trait_name; + + fn as_object_mut(&mut self) -> &mut dyn $trait_name; + + + paste::paste!{$( + #[inline(always)] + fn [](&self) -> Option<[<$trt Ref>]> { + None + } + + #[inline(always)] + fn [](&mut self) -> Option<[<$trt RefMut>]> { + None + } + )*} + }; + ( $trait_name:ident $(: $($bound:tt)* )? {$($trt:path),*}) => { $( - $crate::vm::object::macros::object_trait!{intf {$trait_name $trt}} + $crate::vm::object::macros::object_trait!{@intf {$trait_name $trt}} )* - pub trait $trait_name { - type ID; - fn id(&self) -> &Self::ID; + pub trait $trait_name $(: $($bound)* )? { - fn as_object(&self) -> &dyn $trait_name; - - fn as_object_mut(&mut self) -> &mut dyn $trait_name; - - paste::paste!{$( - #[inline(always)] - fn [](&self) -> Option<[<$trt Ref>]> { - None - } - - #[inline(always)] - fn [](&mut self) -> Option<[<$trt RefMut>]> { - None - } - )*} + $crate::vm::object::macros::object_trait!{@body $trait_name $($trt),*} } }; } @@ -64,6 +71,10 @@ macro_rules! ObjectInterface { &self.$field_id } + fn type_name(&self) -> &str { + std::any::type_name::() + } + #[inline(always)] fn as_object(&self) -> &dyn $trait_name { self @@ -114,25 +125,25 @@ pub(crate) use ObjectTrait; macro_rules! tag_object_traits { { @tag - tag=$trt_name:ident; + tag=$trt_name:ident $(: $($obj_bound:tt)* )?; acc={ $($tagged_trt:ident,)* } $(#[$attr:meta])* - $viz:vis trait $trt:ident $(: $($bound:path)* )? { + $viz:vis trait $trt:ident $(: $($trt_bound:path)* )? { $($tbody:tt)* } $($used:tt)* } => { #[doc = concat!("Autotagged with ", stringify!($trt_name))] $(#[$attr])* - $viz trait $trt : $($($bound)* +)? $trt_name { + $viz trait $trt : $($($trt_bound)* +)? $trt_name { $($tbody)* } - $crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name; acc={ $trt, $($tagged_trt,)* } $($used)* } + $crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name $(: $($obj_bound)* )?; acc={ $trt, $($tagged_trt,)* } $($used)* } }; { @tag - tag=$trt_name:ident; + tag=$trt_name:ident $(: $($obj_bound:tt)* )?; acc={ $($tagged_trt:ident,)* } impl $name:ident for $trt:path { $($body:tt)* @@ -143,19 +154,19 @@ macro_rules! tag_object_traits { impl $name for $trt { $($body)* } - $crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name; acc={ $($tagged_trt,)* } $($used)* } + $crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name $(: $($obj_bound)* )?; acc={ $($tagged_trt,)* } $($used)* } }; { @tag - tag=$trt_name:ident; + tag=$trt_name:ident $(: $($obj_bound:tt)* )?; acc={ $($tagged_trt:ident,)* } } => { // end tagged traits {$trt_name} - $crate::vm::object::macros::object_trait!($trt_name { $($tagged_trt),* }); + $crate::vm::object::macros::object_trait!($trt_name $(: $($obj_bound)* )? { $($tagged_trt),* }); }; - { #![object_trait($trt_name:ident)] $($tree:tt)* } => { + { #![object_trait($trt_name:ident $(: $($bound:tt)* )? )] $($tree:tt)* } => { $crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name; acc={} $($tree)* } }; } diff --git a/ic10emu/src/vm/object/mod.rs b/ic10emu/src/vm/object/mod.rs index 688a608..2dd70d2 100644 --- a/ic10emu/src/vm/object/mod.rs +++ b/ic10emu/src/vm/object/mod.rs @@ -2,6 +2,7 @@ use macro_rules_attribute::derive; mod macros; mod traits; +mod stationpedia; use macros::ObjectInterface; use traits::*; diff --git a/ic10emu/src/vm/object/stationpedia.rs b/ic10emu/src/vm/object/stationpedia.rs new file mode 100644 index 0000000..861f708 --- /dev/null +++ b/ic10emu/src/vm/object/stationpedia.rs @@ -0,0 +1,26 @@ +use std::str::FromStr; + +use serde::{Deserialize, Serialize}; +use strum::{AsRefStr, Display, EnumIter, EnumProperty, EnumString, FromRepr}; + +use crate::vm::object::BoxedObject; + +include!(concat!(env!("OUT_DIR"), "/stationpedia_prefabs.rs")); + +pub enum PrefabTemplate { + Hash(i32), + Name(String), +} + +pub fn object_from_prefab_template(template: &PrefabTemplate) -> Option { + let prefab = match template { + PrefabTemplate::Hash(hash) => StationpediaPrefab::from_repr(*hash), + PrefabTemplate::Name(name) => StationpediaPrefab::from_str(name).ok(), + }; + match prefab { + // Some(StationpediaPrefab::ItemIntegratedCircuit10) => Some() + // Some(StationpediaPrefab::StructureCircuitHousing) => Some() + // Some(StationpediaPrefab::StructureRocketCircuitHousing) => Some() + _ => None, + } +} diff --git a/ic10emu/src/vm/object/traits.rs b/ic10emu/src/vm/object/traits.rs index a42130f..d71eb90 100644 --- a/ic10emu/src/vm/object/traits.rs +++ b/ic10emu/src/vm/object/traits.rs @@ -1,7 +1,9 @@ +use std::fmt::Debug; + use crate::{grammar, vm::{object::{macros::tag_object_traits, ObjectID}, VM}}; tag_object_traits! { - #![object_trait(Object)] + #![object_trait(Object: Debug)] pub trait Memory { fn size(&self) -> usize; @@ -53,3 +55,8 @@ tag_object_traits! { } +impl Debug for dyn Object { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Object: (ID = {:?}, Type = {})", self.id(), self.type_name()) + } +}