mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-09 16:14:13 +00:00
Introducing OpenBYOND, an opensource BYOND toolkit. Replaces and fixes clusterfuck of python scripts.
This commit is contained in:
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "tools/OpenBYOND"]
|
||||
path = tools/OpenBYOND
|
||||
url = https://github.com/N3X15/OpenByond.git
|
||||
@@ -1,2 +1,2 @@
|
||||
python tools/DMITool/DMI.py compare-all ../Baystation12/icons/ icons/ compare_report.txt
|
||||
python tools/OpenBYOND/src/DMITool.py compare-all ../Baystation12/icons/ icons/ compare_report.txt
|
||||
pause
|
||||
@@ -1,2 +1,2 @@
|
||||
python tools/DMITool/DMI.py compare-all ../tgstation/icons/ icons/ compare_report_tg.txt
|
||||
python tools/OpenBYOND/src/DMITool.py compare-all ../tgstation/icons/ icons/ compare_report_tg.txt
|
||||
pause
|
||||
9557
compare_report.txt
9557
compare_report.txt
File diff suppressed because it is too large
Load Diff
@@ -2770,6 +2770,10 @@
|
||||
+ roman_shield
|
||||
+ spearglass0
|
||||
+ spearglass1
|
||||
- stun baton
|
||||
- stun baton_active
|
||||
- stun baton_nocell
|
||||
+ stunbaton
|
||||
+ stunbaton_nocell
|
||||
+ swordrainbow
|
||||
- telebaton_0
|
||||
@@ -3088,6 +3092,32 @@
|
||||
+ plant-23
|
||||
+ plant-24
|
||||
+ plant-25
|
||||
--- C:\Users\Rob\Documents\Projects\tgstation\icons\obj\machines\antimatter.dmi
|
||||
+++ C:\Users\Rob\Documents\Projects\vgstation13\icons\obj\machines\antimatter.dmi
|
||||
- control_critical
|
||||
- core0
|
||||
- core1
|
||||
- coreshield_1
|
||||
- coreshield_10
|
||||
- coreshield_11
|
||||
- coreshield_13
|
||||
- coreshield_14
|
||||
- coreshield_15
|
||||
- coreshield_2
|
||||
- coreshield_4
|
||||
- coreshield_5
|
||||
- coreshield_6
|
||||
- coreshield_7
|
||||
- coreshield_8
|
||||
- coreshield_9
|
||||
- jar-new
|
||||
- shield_11
|
||||
- shield_12
|
||||
- shield_13
|
||||
- shield_14
|
||||
- shield_15
|
||||
- shield_3
|
||||
- shield_7
|
||||
--- C:\Users\Rob\Documents\Projects\tgstation\icons\obj\machines\particle_accelerator.dmi
|
||||
+++ C:\Users\Rob\Documents\Projects\vgstation13\icons\obj\machines\particle_accelerator.dmi
|
||||
+ control_boxp3
|
||||
@@ -3111,19 +3141,23 @@
|
||||
--- C:\Users\Rob\Documents\Projects\tgstation\icons\obj\pipes\large.dmi
|
||||
+++ C:\Users\Rob\Documents\Projects\vgstation13\icons\obj\pipes\large.dmi
|
||||
C:\Users\Rob\Documents\Projects\tgstation\icons\obj\pipes\large.dmi: Received error, continuing: Traceback (most recent call last):
|
||||
File "tools/DMITool/DMI.py", line 133, in compare
|
||||
theirsDMI.parse()
|
||||
File "C:\Users\Rob\Documents\Projects\vgstation13\tools\DMITool\DMI\__init__.py", line 157, in parse
|
||||
img = Image.open(self.filename)
|
||||
File "tools/OpenBYOND/src/DMITool.py", line 133, in compare
|
||||
theirsDMI.loadMetadata()
|
||||
File "C:\Users\Rob\Documents\Projects\vgstation13\tools\OpenBYOND\src\com\byond\DMI\__init__.py", line 160, in loadMetadata
|
||||
self.load(flags | DMILoadFlags.NoImages)
|
||||
File "C:\Users\Rob\Documents\Projects\vgstation13\tools\OpenBYOND\src\com\byond\DMI\__init__.py", line 168, in load
|
||||
self.img = Image.open(self.filename)
|
||||
File "C:\Python33\lib\site-packages\PIL\Image.py", line 1996, in open
|
||||
raise IOError("cannot identify image file")
|
||||
OSError: cannot identify image file
|
||||
|
||||
C:\Users\Rob\Documents\Projects\vgstation13\icons\obj\pipes\large.dmi: Received error, continuing: Traceback (most recent call last):
|
||||
File "tools/DMITool/DMI.py", line 149, in compare
|
||||
mineDMI.parse()
|
||||
File "C:\Users\Rob\Documents\Projects\vgstation13\tools\DMITool\DMI\__init__.py", line 157, in parse
|
||||
img = Image.open(self.filename)
|
||||
File "tools/OpenBYOND/src/DMITool.py", line 149, in compare
|
||||
mineDMI.loadMetadata()
|
||||
File "C:\Users\Rob\Documents\Projects\vgstation13\tools\OpenBYOND\src\com\byond\DMI\__init__.py", line 160, in loadMetadata
|
||||
self.load(flags | DMILoadFlags.NoImages)
|
||||
File "C:\Users\Rob\Documents\Projects\vgstation13\tools\OpenBYOND\src\com\byond\DMI\__init__.py", line 168, in load
|
||||
self.img = Image.open(self.filename)
|
||||
File "C:\Python33\lib\site-packages\PIL\Image.py", line 1996, in open
|
||||
raise IOError("cannot identify image file")
|
||||
OSError: cannot identify image file
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Calculated Max Tech Levels:
|
||||
These tech levels have been determined by parsing ALL origin_tech variables in code included by C:\Users\Rob\Documents\Projects\vgstation13\baystation12.dme, C:\Users\Rob\Documents\Projects\vgstation13\tools\Redirector\Redirect_Tgstation.dme.
|
||||
These tech levels have been determined by parsing ALL origin_tech variables in code included by C:\Users\Rob\Documents\Projects\vgstation13\baystation12.dme.
|
||||
biotech: 8
|
||||
bluespace: 10
|
||||
combat: 8
|
||||
|
||||
@@ -8,7 +8,8 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/ammo_magazine/c45,"Ammunition Box (.45)",,,2,,,,,,,,,
|
||||
/obj/item/ammo_magazine/c9mm,"Ammunition Box (9mm)",,,2,,,,,,,,,
|
||||
/obj/item/ammo_magazine/mc9mm,"magazine (9mm)",,,2,,,,,,,,,
|
||||
/obj/item/brain,"[H]'s brain",3,,,,,,,,,,,
|
||||
/obj/item/ammo_magazine/mc9mm/empty,"magazine (9mm)",,,2,,,,,,,,,
|
||||
/obj/item/brain,"brain",3,,,,,,,,,,,
|
||||
/obj/item/clothing/glasses/hud,"HUD",2,,,,3,,,,,,,
|
||||
/obj/item/clothing/glasses/hud/health,"Health Scanner HUD",2,,,,3,,,,,,,
|
||||
/obj/item/clothing/glasses/hud/health/mech,"Integrated Medical Hud",2,,,,3,,,,,,,
|
||||
@@ -19,14 +20,18 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/clothing/glasses/meson/prescription,"prescription mesons",,,,2,2,,,,,,,
|
||||
/obj/item/clothing/glasses/meson/truesight,"The Lens of Truesight",,,,2,2,,,,,,,
|
||||
/obj/item/clothing/glasses/night,"Night Vision Goggles",,,,,2,,,,,,,
|
||||
/obj/item/clothing/glasses/thermal,"Optical Meson Scanner",,,,,3,,,,,,,4
|
||||
/obj/item/clothing/glasses/thermal/eyepatch,"Optical Thermal Eyepatch",,,,,3,,,,,,,4
|
||||
/obj/item/clothing/glasses/thermal/jensen,"Optical Thermal Implants",,,,,3,,,,,,,4
|
||||
/obj/item/clothing/glasses/thermal/monocle,"Thermonocle",,,,,3,,,,,,,4
|
||||
/obj/item/clothing/glasses/thermal,"Optical Thermal Scanner",,,,,3,,,,,,,
|
||||
/obj/item/clothing/glasses/thermal/eyepatch,"Optical Thermal Eyepatch",,,,,3,,,,,,,
|
||||
/obj/item/clothing/glasses/thermal/jensen,"Optical Thermal Implants",,,,,3,,,,,,,
|
||||
/obj/item/clothing/glasses/thermal/monocle,"Thermonocle",,,,,3,,,,,,,
|
||||
/obj/item/clothing/glasses/thermal/syndi,"Optical Meson Scanner",,,,,3,,,,,,,4
|
||||
/obj/item/clothing/mask/gas/voice,"gas mask",,,,,,,,,,,,4
|
||||
/obj/item/clothing/mask/gas/voice/space_ninja,"ninja mask",,,,,,,,,,,,4
|
||||
/obj/item/clothing/mask/gas/voice/space_ninja/proc,"ninja mask",,,,,,,,,,,,4
|
||||
/obj/item/clothing/shoes/syndigaloshes,"brown shoes",,,,,,,,,,,,3
|
||||
/obj/item/clothing/under/chameleon,"Black Jumpsuit",,,,,,,,,,,,3
|
||||
/obj/item/clothing/under/chameleon,"black jumpsuit",,,,,,,,,,,,3
|
||||
/obj/item/clothing/under/chameleon/all,"black jumpsuit",,,,,,,,,,,,3
|
||||
/obj/item/clothing/under/chameleon/verb,"black jumpsuit",,,,,,,,,,,,3
|
||||
/obj/item/device/aicard,"inteliCard",,,,,,4,,,,,4,
|
||||
/obj/item/device/analyzer,"analyzer",,,,1,1,,,,,,,
|
||||
/obj/item/device/analyzer/plant_analyzer,"plant analyzer",,,,1,1,,,,,,,
|
||||
@@ -35,32 +40,48 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/device/assembly/infra,"infrared emitter",,,,,2,,,,,,,
|
||||
/obj/item/device/assembly/mousetrap,"mousetrap",,,1,,,,,,,,,
|
||||
/obj/item/device/assembly/mousetrap/armed,"mousetrap",,,1,,,,,,,,,
|
||||
/obj/item/device/assembly/mousetrap/proc,"mousetrap",,,1,,,,,,,,,
|
||||
/obj/item/device/assembly/proc,"assembly",,,,,1,,,,,,,
|
||||
/obj/item/device/assembly/prox_sensor,"proximity sensor",,,,,1,,,,,,,
|
||||
/obj/item/device/assembly/signaler,"remote signaling device",,,,,1,,,,,,,
|
||||
/obj/item/device/assembly/signaler/proc,"remote signaling device",,,,,1,,,,,,,
|
||||
/obj/item/device/assembly/signaler/verb,"remote signaling device",,,,,1,,,,,,,
|
||||
/obj/item/device/assembly/timer,"timer",,,,,1,,,,,,,
|
||||
/obj/item/device/batterer,"mind batterer",,,3,,3,,,,,,,3
|
||||
/obj/item/device/chameleon,"chameleon-projector",,,,,4,,,,,,,4
|
||||
/obj/item/device/chameleon/proc,"chameleon-projector",,,,,4,,,,,,,4
|
||||
/obj/item/device/debugger,"debugger",,,,1,1,,,,,,,
|
||||
/obj/item/device/encryptionkey/binary,"item",,,,,,,,,,,,3
|
||||
/obj/item/device/encryptionkey/syndicate,"item",,,,,,,,,,,,3
|
||||
/obj/item/device/encryptionkey/syndicate/hacked,"Standard Encryption Key",,,,,,,,,,,,3
|
||||
/obj/item/device/flash,"flash",,,1,,2,,,,,,,
|
||||
/obj/item/device/flash/proc,"flash",,,1,,2,,,,,,,
|
||||
/obj/item/device/flash/synthetic,"synthetic flash",,,1,,2,,,,,,,
|
||||
/obj/item/device/gps,"Global Positioning System ([gpstag])",,,,2,,,,,,,2,
|
||||
/obj/item/device/gps/engineering,"Global Positioning System ([gpstag])",,,,2,,,,,,,2,
|
||||
/obj/item/device/gps/science,"Global Positioning System ([gpstag])",,,,2,,,,,,,2,
|
||||
/obj/item/device/gps,"Global Positioning System",,,,2,,,,,,,2,
|
||||
/obj/item/device/gps/engineering,"Global Positioning System",,,,2,,,,,,,2,
|
||||
/obj/item/device/gps/science,"Global Positioning System",,,,2,,,,,,,2,
|
||||
/obj/item/device/healthanalyzer,"Health Analyzer",1,,,,1,,,,,,,
|
||||
/obj/item/device/lightreplacer,"Shortcircuited [initial(name)]",,,,,3,2,,,,,,
|
||||
/obj/item/device/healthanalyzer/verb,"Health Analyzer",1,,,,1,,,,,,,
|
||||
/obj/item/device/lightreplacer,"light replacer",,,,,3,2,,,,,,
|
||||
/obj/item/device/lightreplacer/proc,"light replacer",,,,,3,2,,,,,,
|
||||
/obj/item/device/mass_spectrometer,"mass-spectrometer",2,,,,2,,,,,,,
|
||||
/obj/item/device/mass_spectrometer/adv,"advanced mass-spectrometer",2,,,,4,,,,,,,
|
||||
/obj/item/device/mmi,"Man-Machine Interface: [brainmob.real_name]",3,,,,,,,,,,,
|
||||
/obj/item/device/mmi,"Man-Machine Interface",3,,,,,,,,,,,
|
||||
/obj/item/device/mmi/posibrain,"positronic brain",,2,,4,,4,,,,,4,
|
||||
/obj/item/device/mmi/posibrain/proc,"positronic brain",,2,,4,,4,,,,,4,
|
||||
/obj/item/device/mmi/proc,"Man-Machine Interface",3,,,,,,,,,,,
|
||||
/obj/item/device/mmi/radio_enabled,"Radio-enabled Man-Machine Interface",4,,,,,,,,,,,
|
||||
/obj/item/device/mmi/radio_enabled/verb,"Radio-enabled Man-Machine Interface",4,,,,,,,,,,,
|
||||
/obj/item/device/multitool,"multitool",,,,1,1,,,,,,,
|
||||
/obj/item/device/multitool/uplink,"multitool",,,,1,1,,,,,,,
|
||||
/obj/item/device/paicard,"personal AI device",,,,,,,,,,,2,
|
||||
/obj/item/device/paicard/proc,"personal AI device",,,,,,,,,,,2,
|
||||
/obj/item/device/powersink,"power sink",,,,,,,,,,3,,5
|
||||
/obj/item/device/radio/beacon,"Tracking Beacon",,1,,,,,,,,,,
|
||||
/obj/item/device/radio/beacon/bacon,"Tracking Beacon",,1,,,,,,,,,,
|
||||
/obj/item/device/radio/beacon/bacon/proc,"Tracking Beacon",,1,,,,,,,,,,
|
||||
/obj/item/device/radio/beacon/syndicate,"suspicious beacon",,1,,,,,,,,,,7
|
||||
/obj/item/device/radio/beacon/verb,"Tracking Beacon",,1,,,,,,,,,,
|
||||
/obj/item/device/radio/headset/binary,"radio headset",,,,,,,,,,,,3
|
||||
/obj/item/device/radio/headset/syndicate,"radio headset",,,,,,,,,,,,3
|
||||
/obj/item/device/soulstone,"Soul Stone Shard",,4,,,,4,,,,,,
|
||||
@@ -76,30 +97,42 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/mecha_parts/chassis/phazon,"Phazon Chassis",,,,,,7,,,,,,
|
||||
/obj/item/mecha_parts/chassis/ripley,"Ripley Chassis",,,,,,2,,,,,2,
|
||||
/obj/item/mecha_parts/mecha_equipment,"mecha equipment",,,,,,2,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster,"Armor Booster Module (Close Combat Weaponry)",,,,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc,"Armor Booster Module (Close Combat Weaponry)",,,,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster,"Armor Booster Module (Ranged Weaponry)",,,,,,4,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc,"Armor Booster Module (Ranged Weaponry)",,,,,,4,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/generator,"Plasma Converter",,,,1,,,,2,,2,,
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/nuclear,"ExoNuclear Reactor",,,,3,,,,,,3,,
|
||||
/obj/item/mecha_parts/mecha_equipment/gravcatapult,"Armor Booster Module (Close Combat Weaponry)",,,,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/proc,"Plasma Converter",,,,1,,,,2,,2,,
|
||||
/obj/item/mecha_parts/mecha_equipment/gravcatapult,"Gravitational Catapult",,2,,,3,,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/proc,"mecha equipment",,,,,,2,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid,"Repair Droid",,,,,3,,,,,,3,
|
||||
/obj/item/mecha_parts/mecha_equipment/teleporter,"Teleporter",,10,,,,,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,"Energy Relay",,,,,4,,,,,,,2
|
||||
/obj/item/mecha_parts/mecha_equipment/tool,"",,,,,,2,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc,"Energy Relay",,,,,4,,,,,,,2
|
||||
/obj/item/mecha_parts/mecha_equipment/tool,"mecha equipment",,,,,,2,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/cable_layer,"Cable Layer",,,,,,2,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc,"Cable Layer",,,,,,2,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/drill,"Drill",,,,,,2,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill,"Diamond Drill",,,,3,,4,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/extinguisher,"Extinguisher",,,,,,2,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp,"Hydraulic Clamp",,,,,,2,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/rcd,"Mounted RCD",,3,,,4,4,,,,4,,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/safety_clamp,"KILL CLAMP",,,,,,2,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/sleeper,"",3,,,,,,,,,,2,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/sleeper,"Mounted Sleeper",3,,,,,,,,,,2,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc,"Mounted Sleeper",3,,,,,,,,,,2,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun,"Syringe Gun",4,,,,4,3,,,,,3,
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc,"Syringe Gun",4,,,,4,3,,,,,3,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon,"mecha weapon",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic,"General Ballisic Weapon",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg,"Ultra AC 2",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack,"SRM-8 Missile Rack",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar,"Banana Mortar",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang,"SOP-6 Grenade Launcher",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang,"SGL-6 Grenade Launcher",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang,"SOP-6 Grenade Launcher",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang/limited,"SOP-6 Grenade Launcher",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/mousetrap_mortar,"Mousetrap Mortar",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/proc,"General Ballisic Weapon",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot,"LBX AC 10 \""Scattershot\""",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy,"General Energy Weapon",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion,"mkIV Ion Heavy Cannon",,,3,,,3,,,,,,
|
||||
@@ -110,7 +143,8 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/honker,"HoNkER BlAsT 5000",,,3,,,3,,,,,,
|
||||
/obj/item/mecha_parts/mecha_equipment/wormhole_generator,"Wormhole Generator",,3,,,,,,,,,,
|
||||
/obj/item/mecha_parts/mecha_tracking,"Exosuit tracking beacon",,,,,2,,,,,,2,
|
||||
/obj/item/mecha_parts/part,"",,,,,,2,,,,,2,
|
||||
/obj/item/mecha_parts/mecha_tracking/proc,"Exosuit tracking beacon",,,,,2,,,,,,2,
|
||||
/obj/item/mecha_parts/part,"mecha part",,,,,,2,,,,,2,
|
||||
/obj/item/mecha_parts/part/durand_armour,"Durand Armour Plates",,,4,5,,5,,,,,,
|
||||
/obj/item/mecha_parts/part/durand_head,"Durand Head",,,,3,3,3,,,,,2,
|
||||
/obj/item/mecha_parts/part/durand_left_arm,"Durand Left Arm",,,,3,,3,,,,,2,
|
||||
@@ -135,7 +169,7 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/mecha_parts/part/odysseus_left_arm,"Odysseus Left Arm",,,,2,,2,,,,,2,
|
||||
/obj/item/mecha_parts/part/odysseus_left_leg,"Odysseus Left Leg",,,,2,,2,,,,,2,
|
||||
/obj/item/mecha_parts/part/odysseus_right_arm,"Odysseus Right Arm",,,,2,,2,,,,,2,
|
||||
/obj/item/mecha_parts/part/odysseus_right_leg,"Odysseus Carapace",,,,3,,3,,,,,,
|
||||
/obj/item/mecha_parts/part/odysseus_right_leg,"Odysseus Right Leg",,,,2,,2,,,,,2,
|
||||
/obj/item/mecha_parts/part/odysseus_torso,"Odysseus Torso",2,,,2,,2,,,,,2,
|
||||
/obj/item/mecha_parts/part/phazon_head,"Phazon Head",,,,,6,9,,,,,9,
|
||||
/obj/item/mecha_parts/part/phazon_left_arm,"Phazon Left Arm",,6,,,2,9,,,,,,
|
||||
@@ -171,7 +205,7 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/slime_extract/sepia,"sepia slime extract",4,,,,,,,,,,,
|
||||
/obj/item/slime_extract/silver,"silver slime extract",4,,,,,,,,,,,
|
||||
/obj/item/slime_extract/yellow,"yellow slime extract",4,,,,,,,,,,,
|
||||
/obj/item/stack,"",,,,,,1,,,,,,
|
||||
/obj/item/stack,"item",,,,,,1,,,,,,
|
||||
/obj/item/stack/light_w,"wired glass tiles",,,,,,1,,,,,,
|
||||
/obj/item/stack/medical,"medical pack",,,,,,1,,,,,,
|
||||
/obj/item/stack/medical/advanced,"medical pack",,,,,,1,,,,,,
|
||||
@@ -182,25 +216,29 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/stack/medical/ointment,"ointment",1,,,,,,,,,,,
|
||||
/obj/item/stack/medical/ointment/tajaran,"\improper Messa's Tear leaf",1,,,,,,,,,,,
|
||||
/obj/item/stack/medical/splint,"medical splint",,,,,,1,,,,,,
|
||||
/obj/item/stack/medical/splint/single,"medical splint",,,,,,1,,,,,,
|
||||
/obj/item/stack/nanopaste,"nanopaste",,,,3,,4,,,,,,
|
||||
/obj/item/stack/proc,"item",,,,,,1,,,,,,
|
||||
/obj/item/stack/rods,"metal rods",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet,"sheet",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/animalhide,"",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/animalhide,"sheet",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/animalhide/cat,"cat hide",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/animalhide/corgi,"corgi hide",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/animalhide/human,"human skin",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/animalhide/lizard,"lizard skin",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/animalhide/monkey,"monkey hide",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/animalhide/xeno,"alien hide",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/cloth,"cardboard",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/cardboard,"cardboard",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/cloth,"cloth",,,,,,2,,,,,,
|
||||
/obj/item/stack/sheet/glass,"glass",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/glass/plasmaglass,"plasma glass",,,,,,3,2,,,,,
|
||||
/obj/item/stack/sheet/glass/plasmarglass,"reinforced plasma glass",,,,,,4,2,,,,,
|
||||
/obj/item/stack/sheet/glass/proc,"glass",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/hairlesshide,"hairless hide",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/leather,"leather",,,,,,2,,,,,,
|
||||
/obj/item/stack/sheet/metal,"metal",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/metal/cyborg,"metal",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/mineral,"",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/mineral,"sheet",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/mineral/adamantine,"adamantine",,,,,,4,,,,,,
|
||||
/obj/item/stack/sheet/mineral/clown,"bananium",,,,,,4,,,,,,
|
||||
/obj/item/stack/sheet/mineral/diamond,"diamond",,,,,,6,,,,,,
|
||||
@@ -216,6 +254,7 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/stack/sheet/plasteel,"plasteel",,,,,,2,,,,,,
|
||||
/obj/item/stack/sheet/rglass,"reinforced glass",,,,,,2,,,,,,
|
||||
/obj/item/stack/sheet/rglass/cyborg,"reinforced glass",,,,,,2,,,,,,
|
||||
/obj/item/stack/sheet/rglass/proc,"reinforced glass",,,,,,2,,,,,,
|
||||
/obj/item/stack/sheet/wetleather,"wet leather",,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/wood,"wooden planks",1,,,,,1,,,,,,
|
||||
/obj/item/stack/sheet/xenochitin,"alien chitin",,,,,,1,,,,,,
|
||||
@@ -224,21 +263,35 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/stack/tile/grass,"grass tiles",1,,,,,,,,,,,
|
||||
/obj/item/stack/tile/light,"light tiles",,,,,,1,,,,,,
|
||||
/obj/item/stack/tile/plasteel,"floor tiles",,,,,,1,,,,,,
|
||||
/obj/item/stack/tile/plasteel/proc,"floor tiles",,,,,,1,,,,,,
|
||||
/obj/item/stack/tile/wood,"wood floor tiles",,,,,,1,,,,,,
|
||||
/obj/item/weapon/FixOVein,"FixOVein",3,,,,,1,,,,,,
|
||||
/obj/item/weapon/SWF_uplink,"station-bounced radio",,,,,1,,,,,,,
|
||||
/obj/item/weapon/aiModule,"AI Module",,,,,,,,,,,3,
|
||||
/obj/item/weapon/aiModule/corp,"'Antimov' Core AI Module",,,,,,,,,,,4,
|
||||
/obj/item/weapon/aiModule/antimov,"'Antimov' Core AI Module",,,,,,,,,,,4,
|
||||
/obj/item/weapon/aiModule/asimov,"'Asimov' Core AI Module",,,,,,4,,,,,3,
|
||||
/obj/item/weapon/aiModule/corp,"'Corporate' Core AI Module",,,,,,4,,,,,3,
|
||||
/obj/item/weapon/aiModule/freeform,"'Freeform' AI Module",,,,,,4,,,,,4,
|
||||
/obj/item/weapon/aiModule/freeformcore,"'Freeform' Core AI Module",,,,,,6,,,,,3,
|
||||
/obj/item/weapon/aiModule/keeper,"'Keeper' AI Module",,,,,,,,,,,3,
|
||||
/obj/item/weapon/aiModule/oneHuman,"'OneHuman' AI Module",,,,,,,,,,,3,
|
||||
/obj/item/weapon/aiModule/oxygen,"'Freeform' AI Module",,,,,,4,,,,,4,
|
||||
/obj/item/weapon/aiModule/protectStation,"'ProtectStation' AI Module",,,,,,,,,,,3,
|
||||
/obj/item/weapon/aiModule/nanotrasen,"'NT Default' Core AI Module",,,,,,4,,,,,3,
|
||||
/obj/item/weapon/aiModule/oneHuman,"'OneHuman' AI Module",,,,,,6,,,,,3,
|
||||
/obj/item/weapon/aiModule/oxygen,"'OxygenIsToxicToHumans' AI Module",2,,,,,4,,,,,3,
|
||||
/obj/item/weapon/aiModule/paladin,"'P.A.L.A.D.I.N.' Core AI Module",,,,,,6,,,,,3,
|
||||
/obj/item/weapon/aiModule/proc,"AI Module",,,,,,,,,,,3,
|
||||
/obj/item/weapon/aiModule/protectStation,"'ProtectStation' AI Module",,,,,,4,,,,,3,
|
||||
/obj/item/weapon/aiModule/prototypeEngineOffline,"'PrototypeEngineOffline' AI Module",,,,,,4,,,,,3,
|
||||
/obj/item/weapon/aiModule/purge,"'Purge' AI Module",,,,,,6,,,,,3,
|
||||
/obj/item/weapon/aiModule/quarantine,"'Quarantine' AI Module",2,,,,,4,,,,,3,
|
||||
/obj/item/weapon/aiModule/reset,"'NT Default' Core AI Module",,,,,,4,,,,,3,
|
||||
/obj/item/weapon/aiModule/reset,"'Reset' AI Module",,,,,,4,,,,,3,
|
||||
/obj/item/weapon/aiModule/robocop,"'Robocop' Core AI Module",,,,,,,,,,,4,
|
||||
/obj/item/weapon/aiModule/safeguard,"'Safeguard' AI Module",,,,,,4,,,,,3,
|
||||
/obj/item/weapon/aiModule/syndicate,"Hacked AI Module",,,,,,6,,,,,3,7
|
||||
/obj/item/weapon/aiModule/teleporterOffline,"'TeleporterOffline' AI Module",,,,,,4,,,,,3,
|
||||
/obj/item/weapon/aiModule/tyrant,"'T.Y.R.A.N.T.' Core AI Module",,,,,,6,,,,,3,2
|
||||
/obj/item/weapon/autopsy_scanner,"autopsy scanner",1,,,,,1,,,,,,
|
||||
/obj/item/weapon/autopsy_scanner/proc,"autopsy scanner",1,,,,,1,,,,,,
|
||||
/obj/item/weapon/autopsy_scanner/verb,"autopsy scanner",1,,,,,1,,,,,,
|
||||
/obj/item/weapon/butch,"Butcher's Cleaver",,,,,,1,,,,,,
|
||||
/obj/item/weapon/butch/meatcleaver,"Meat Cleaver",,,,,,1,,,,,,
|
||||
/obj/item/weapon/card/emag,"cryptographic sequencer",,,,,2,,,,,,,2
|
||||
@@ -246,14 +299,21 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/cautery,"cautery",1,,,,,1,,,,,,
|
||||
/obj/item/weapon/cell,"power cell",,,,,,,,,,1,,
|
||||
/obj/item/weapon/cell/crap,"\improper Nanotrasen brand rechargable AA battery",,,,,,,,,,0,,
|
||||
/obj/item/weapon/cell/crap/empty,"\improper Nanotrasen brand rechargable AA battery",,,,,,,,,,0,,
|
||||
/obj/item/weapon/cell/high,"high-capacity power cell",,,,,,,,,,2,,
|
||||
/obj/item/weapon/cell/high/empty,"high-capacity power cell",,,,,,,,,,2,,
|
||||
/obj/item/weapon/cell/hyper,"hyper-capacity power cell",,,,,,,,,,6,,
|
||||
/obj/item/weapon/cell/hyper/empty,"hyper-capacity power cell",,,,,,,,,,6,,
|
||||
/obj/item/weapon/cell/infinite,"infinite-capacity power cell!",,,,,,,,,,1,,
|
||||
/obj/item/weapon/cell/potato,"potato battery",,,,,,,,,,1,,
|
||||
/obj/item/weapon/cell/proc,"power cell",,,,,,,,,,1,,
|
||||
/obj/item/weapon/cell/secborg,"\improper Security borg rechargable D battery",,,,,,,,,,0,,
|
||||
/obj/item/weapon/cell/secborg/empty,"\improper Security borg rechargable D battery",,,,,,,,,,0,,
|
||||
/obj/item/weapon/cell/slime,"charged slime core",4,,,,,,,,,2,,
|
||||
/obj/item/weapon/cell/super,"super-capacity power cell",,,,,,,,,,5,,
|
||||
/obj/item/weapon/cell/super/empty,"super-capacity power cell",,,,,,,,,,5,,
|
||||
/obj/item/weapon/circuitboard,"Circuit board",,,,,,,,,,,2,
|
||||
/obj/item/weapon/circuitboard/HolodeckControl,"Circuit board (Holodeck Control)",,,,,,,,,,,4,
|
||||
/obj/item/weapon/circuitboard/aicore,"Circuit board (AI core)",2,,,,,,,,,,4,
|
||||
/obj/item/weapon/circuitboard/aifixer,"Circuit board (AI Integrity Restorer)",2,,,,,,,,,,3,
|
||||
/obj/item/weapon/circuitboard/air_management,"Circuit board (Atmospheric monitor)",,,,,,,,,,,2,
|
||||
@@ -331,7 +391,7 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/circuitboard/pipedispenser,"Circuit Board (Pipe Dispenser)",3,,,2,,,,,,2,3,
|
||||
/obj/item/weapon/circuitboard/pipedispenser/disposal,"Circuit Board (Disposal Pipe Dispenser)",3,,,2,,,,,,2,3,
|
||||
/obj/item/weapon/circuitboard/pod,"Circuit board (Massdriver control)",,,,,,,,,,,2,
|
||||
/obj/item/weapon/circuitboard/powermonitor,"Circuit board",,,,,,,,,,,2,
|
||||
/obj/item/weapon/circuitboard/powermonitor,"Circuit board (Power Monitor)",,,,,,,,,,,2,
|
||||
/obj/item/weapon/circuitboard/prison_shuttle,"Circuit board (Prison Shuttle)",,,,,,,,,,,2,
|
||||
/obj/item/weapon/circuitboard/prisoner,"Circuit board (Prisoner Management)",,,,,,,,,,,2,
|
||||
/obj/item/weapon/circuitboard/processor,"Circuit Board (Food Processor)",3,,,2,,,,,,2,3,
|
||||
@@ -341,7 +401,7 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/circuitboard/rdservercontrol,"Circuit Board (R&D Server Control)",,,,,,,,,,,2,
|
||||
/obj/item/weapon/circuitboard/reagentgrinder,"Circuit Board (All-In-One Grinder)",,,,2,,,,,,,3,
|
||||
/obj/item/weapon/circuitboard/recharge_station,"Circuit Board (Cyborg Recharging Station)",,,,,,,,,4,,3,
|
||||
/obj/item/weapon/circuitboard/research_shuttle,"Circuit board (Holodeck Control)",,,,,,,,,,,4,
|
||||
/obj/item/weapon/circuitboard/research_shuttle,"Circuit board (Research Shuttle)",,,,,,,,,,,2,
|
||||
/obj/item/weapon/circuitboard/robotics,"Circuit board (Robotics Control)",,,,,,,,,,,3,
|
||||
/obj/item/weapon/circuitboard/rust_core,"Internal circuitry (RUST tokamak core)",,3,,,5,,,4,,6,,
|
||||
/obj/item/weapon/circuitboard/rust_core_control,"Circuit board (RUST core controller)",,,,4,,,,,,,4,
|
||||
@@ -357,7 +417,7 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/circuitboard/shield_gen_ex,"Circuit board (Experimental hull shield generator)",,4,,,,,,3,,,,
|
||||
/obj/item/weapon/circuitboard/smartfridge,"Circuit Board (SmartFridge)",,,,2,,,,,,,3,
|
||||
/obj/item/weapon/circuitboard/smes,"Circuit Board (SMES)",,,,4,,,,,4,,4,
|
||||
/obj/item/weapon/circuitboard/solar_control,"Circuit board",,,,,,,,,,2,2,
|
||||
/obj/item/weapon/circuitboard/solar_control,"Circuit board (Solar Control)",,,,,,,,,,2,2,
|
||||
/obj/item/weapon/circuitboard/splicer,"Circuit board (Disease Splicer)",,,,,,,,,,,2,
|
||||
/obj/item/weapon/circuitboard/stationalert,"Circuit board (Station Alerts)",,,,,,,,,,,2,
|
||||
/obj/item/weapon/circuitboard/supplycomp,"Circuit board (Supply shuttle console)",,,,,,,,,,,3,
|
||||
@@ -381,21 +441,28 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/crowbar,"crowbar",,,,1,,,,,,,,
|
||||
/obj/item/weapon/crowbar/red,"crowbar",,,,1,,,,,,,,
|
||||
/obj/item/weapon/dart_cartridge,"dart cartridge",,,,,,2,,,,,,
|
||||
/obj/item/weapon/ectoplasm,"research",8,8,8,,8,8,,,,8,8,8
|
||||
/obj/item/weapon/flamethrower,"flamethrower",,,1,,,,,1,,,,
|
||||
/obj/item/weapon/flamethrower/full,"flamethrower",,,1,,,,,1,,,,
|
||||
/obj/item/weapon/flamethrower/proc,"flamethrower",,,1,,,,,1,,,,
|
||||
/obj/item/weapon/grenade/chem_grenade/large,"Large Chem Grenade",,,3,,,3,,,,,,
|
||||
/obj/item/weapon/grenade/empgrenade,"classic emp grenade",,,,,3,2,,,,,,
|
||||
/obj/item/weapon/grenade/flashbang,"clusterbang",,,1,,,2,,,,,,
|
||||
/obj/item/weapon/grenade/flashbang,"flashbang",,,1,,,2,,,,,,
|
||||
/obj/item/weapon/grenade/flashbang/cluster,"flashbang",,,1,,,2,,,,,,
|
||||
/obj/item/weapon/grenade/flashbang/clusterbang,"clusterbang",,,1,,,2,,,,,,
|
||||
/obj/item/weapon/grenade/flashbang/clusterbang/segment,"clusterbang segment",,,1,,,2,,,,,,
|
||||
/obj/item/weapon/grenade/flashbang/proc,"flashbang",,,1,,,2,,,,,,
|
||||
/obj/item/weapon/grenade/spawnergrenade,"delivery grenade",,,,,4,3,,,,,,
|
||||
/obj/item/weapon/grenade/spawnergrenade/manhacks,"manhack delivery grenade",,,,,4,3,,,,,,4
|
||||
/obj/item/weapon/grenade/spawnergrenade/spesscarp,"carp delivery grenade",,,,,4,3,,,,,,4
|
||||
/obj/item/weapon/grown/log,"sunflower",,,,,,1,,,,,,
|
||||
/obj/item/weapon/grown/novaflower,"deathnettle",,,3,,,,,,,,,
|
||||
/obj/item/weapon/grown/deathnettle,"deathnettle",,,3,,,,,,,,,
|
||||
/obj/item/weapon/grown/log,"tower-cap log",,,,,,1,,,,,,
|
||||
/obj/item/weapon/grown/nettle,"nettle",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun,"gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/dartgun,"dart gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/dartgun/proc,"dart gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/dartgun/vox,"alien dart gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/dartgun/vox/medical,"alien dart gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/dartgun/vox/raider,"alien dart gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/energy,"energy gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/energy/crossbow,"mini energy-crossbow",,,2,,2,,,,,,,5
|
||||
/obj/item/weapon/gun/energy/crossbow/largecrossbow,"Energy Crossbow",,,2,,2,,,,,,,5
|
||||
@@ -407,17 +474,20 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/gun/energy/laser,"laser gun",,,3,,2,,,,,,,
|
||||
/obj/item/weapon/gun/energy/laser/bluetag,"laser tag gun",,,1,,2,,,,,,,
|
||||
/obj/item/weapon/gun/energy/laser/captain,"laser gun",,,3,,2,,,,,,,
|
||||
/obj/item/weapon/gun/energy/laser/cyborg,"laser gun",,,3,,2,,,,,,,
|
||||
/obj/item/weapon/gun/energy/laser/practice,"practice laser gun",,,3,,2,,,,,,,
|
||||
/obj/item/weapon/gun/energy/laser/practice/sc_laser,"Old laser",,,3,,2,,,,,,,
|
||||
/obj/item/weapon/gun/energy/laser/redtag,"laser tag gun",,,1,,2,,,,,,,
|
||||
/obj/item/weapon/gun/energy/laser/retro,"retro laser",,,3,,2,,,,,,,
|
||||
/obj/item/weapon/gun/energy/laser/retro/sc_retro,"retro laser",,,3,,2,,,,,,,
|
||||
/obj/item/weapon/gun/energy/lasercannon,"laser cannon",,,4,,,3,,,,3,,
|
||||
/obj/item/weapon/gun/energy/lasercannon/cyborg,"laser cannon",,,4,,,3,,,,3,,
|
||||
/obj/item/weapon/gun/energy/meteorgun,"meteor gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/energy/meteorgun/pen,"meteor pen",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/energy/mindflayer,"mind flayer",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/energy/pulse_rifle,"pulse rifle",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/M1911,"m1911-P",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/cyborg,"pulse rifle",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/destroyer,"pulse destroyer",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/energy/staff,"staff of change",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/energy/staff/animate,"staff of animation",,,1,,,,,,,,,
|
||||
@@ -428,26 +498,36 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/gun/energy/temperature,"temperature gun",,,3,,2,4,,,,3,,
|
||||
/obj/item/weapon/gun/energy/xray,"xray laser gun",,,5,,2,3,,,,,,2
|
||||
/obj/item/weapon/gun/grenadelauncher,"grenade launcher",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/proc,"gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/projectile,"revolver",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/automatic,"revolver",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/automatic,"submachine gun",,,4,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/automatic/c20r,"\improper C-20r SMG",,,5,,,2,,,,,,8
|
||||
/obj/item/weapon/gun/projectile/automatic/c20r/sc_c20r,"\improper C-20r SMG",,,5,,,2,,,,,,8
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw,"\improper L6 SAW",,,5,,,1,,,,,,2
|
||||
/obj/item/weapon/gun/projectile/automatic/mini_uzi,"Uzi",,,5,,,2,,,,,,8
|
||||
/obj/item/weapon/gun/projectile/deagle,"desert eagle",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/deagle/camo,"desert eagle",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/deagle/gold,"desert eagle",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/detective,"revolver",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/detective/verb,"revolver",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/gyropistol,"gyrojet pistol",,,3,,,,,,,,,
|
||||
/obj/item/weapon/gun/projectile/mateba,"mateba",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/pistol,"\improper Stechtkin pistol",,,2,,,2,,,,,,2
|
||||
/obj/item/weapon/gun/projectile/proc,"revolver",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/russian,"Russian Revolver",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/russian/proc,"Russian Revolver",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/shotgun,"revolver",,,2,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel,"sawn-off shotgun",,,3,,,1,,,,,,
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel,"double-barreled shotgun",,,3,,,1,,,,,,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump,"shotgun",,,4,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat,"combat shotgun",,,5,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/proc,"shotgun",,,4,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/sc_pump,"shotgun",,,4,,,2,,,,,,
|
||||
/obj/item/weapon/gun/projectile/silenced,"silenced pistol",,,2,,,2,,,,,,8
|
||||
/obj/item/weapon/gun/projectile/silenced/sc_silenced,"silenced pistol",,,2,,,2,,,,,,8
|
||||
/obj/item/weapon/gun/syringe,"syringe gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/syringe/proc,"syringe gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/syringe/rapidsyringe,"rapid syringe gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/gun/verb,"gun",,,1,,,,,,,,,
|
||||
/obj/item/weapon/hand_tele,"hand tele",,3,,,1,,,,,,,
|
||||
/obj/item/weapon/handcuffs,"handcuffs",,,,,,1,,,,,,
|
||||
/obj/item/weapon/handcuffs/cable,"cable restraints",,,,,,1,,,,,,
|
||||
@@ -459,10 +539,11 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/handcuffs/cable/red,"cable restraints",,,,,,1,,,,,,
|
||||
/obj/item/weapon/handcuffs/cable/white,"cable restraints",,,,,,1,,,,,,
|
||||
/obj/item/weapon/handcuffs/cable/yellow,"cable restraints",,,,,,1,,,,,,
|
||||
/obj/item/weapon/handcuffs/cyborg,"handcuffs",,,,,,1,,,,,,
|
||||
/obj/item/weapon/hatchet,"hatchet",,,1,,,2,,,,,,
|
||||
/obj/item/weapon/hatchet/unathiknife,"duelling knife",,,1,,,2,,,,,,
|
||||
/obj/item/weapon/hemostat,"hemostat",1,,,,,1,,,,,,
|
||||
/obj/item/weapon/kitchen/utensil,"",,,,,,1,,,,,,
|
||||
/obj/item/weapon/kitchen/utensil,"weapon",,,,,,1,,,,,,
|
||||
/obj/item/weapon/kitchen/utensil/fork,"fork",,,,,,1,,,,,,
|
||||
/obj/item/weapon/kitchen/utensil/knife,"knife",,,,,,1,,,,,,
|
||||
/obj/item/weapon/kitchen/utensil/pfork,"plastic fork",,,,,,1,,,,,,
|
||||
@@ -474,9 +555,11 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/legcuffs,"legcuffs",,,,,,1,,,,,,
|
||||
/obj/item/weapon/legcuffs/beartrap,"bear trap",,,,,,1,,,,,,
|
||||
/obj/item/weapon/locator,"locator",,,,,1,,,,,,,
|
||||
/obj/item/weapon/match,"burnt match",,,,,,1,,,,,,
|
||||
/obj/item/weapon/match,"match",,,,,,1,,,,,,
|
||||
/obj/item/weapon/melee/baton,"stun baton",,,2,,,,,,,,,
|
||||
/obj/item/weapon/melee/baton/cattleprod,"stunprod",,,2,,,,,,,,,
|
||||
/obj/item/weapon/melee/baton/loaded,"stun baton",,,2,,,,,,,,,
|
||||
/obj/item/weapon/melee/baton/proc,"stun baton",,,2,,,,,,,,,
|
||||
/obj/item/weapon/melee/chainofcommand,"chain of command",,,4,,,,,,,,,
|
||||
/obj/item/weapon/melee/defibrilator,"emergency defibrilator",3,,,,,,,,,,,
|
||||
/obj/item/weapon/melee/energy/axe,"energy axe",,,3,,,,,,,,,
|
||||
@@ -497,8 +580,9 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/pickaxe,"pickaxe",,,,1,,1,,,,,,
|
||||
/obj/item/weapon/pickaxe/borgdrill,"cyborg mining drill",,,,1,,1,,,,,,
|
||||
/obj/item/weapon/pickaxe/brush,"brush",,,,1,,1,,,,,,
|
||||
/obj/item/weapon/pickaxe/diamond,"diamond mining drill",,,,5,,6,,,,4,,
|
||||
/obj/item/weapon/pickaxe/drill,"pickaxe",,,,2,,2,,,,3,,
|
||||
/obj/item/weapon/pickaxe/diamond,"diamond pickaxe",,,,4,,6,,,,,,
|
||||
/obj/item/weapon/pickaxe/diamonddrill,"diamond mining drill",,,,5,,6,,,,4,,
|
||||
/obj/item/weapon/pickaxe/drill,"mining drill",,,,2,,2,,,,3,,
|
||||
/obj/item/weapon/pickaxe/five_pick,"5/6 pick",,,,1,,1,,,,,,
|
||||
/obj/item/weapon/pickaxe/four_pick,"2/3 pick",,,,1,,1,,,,,,
|
||||
/obj/item/weapon/pickaxe/gold,"golden pickaxe",,,,,,4,,,,,,
|
||||
@@ -512,11 +596,15 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/pickaxe/three_pick,"1/2 pick",,,,1,,1,,,,,,
|
||||
/obj/item/weapon/pickaxe/two_pick,"1/3 pick",,,,1,,1,,,,,,
|
||||
/obj/item/weapon/pipe_dispenser,"Rapid Piping Device (RPD)",,,,4,,2,,,,,,
|
||||
/obj/item/weapon/pipe_dispenser/proc,"Rapid Piping Device (RPD)",,,,4,,2,,,,,,
|
||||
/obj/item/weapon/plastique,"plastic explosives",,,,,,,,,,,,2
|
||||
/obj/item/weapon/rcd,"rapid-construction-device (RCD)",,,,4,,2,,,,,,
|
||||
/obj/item/weapon/rcd/borg,"rapid-construction-device (RCD)",,,,4,,2,,,,,,
|
||||
/obj/item/weapon/rcd/proc,"rapid-construction-device (RCD)",,,,4,,2,,,,,,
|
||||
/obj/item/weapon/rcd_ammo,"compressed matter cartridge",,,,,,2,,,,,,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/bluespacetomato,"blue-space tomato",,3,,,,,,,,,,
|
||||
/obj/item/weapon/reagent_containers/spray/chemsprayer,"Plant-B-Gone",,,3,3,,3,,,,,,
|
||||
/obj/item/weapon/reagent_containers/spray/chemsprayer,"chem sprayer",,,3,3,,3,,,,,,
|
||||
/obj/item/weapon/research,"research",8,8,8,,8,8,,,,8,8,8
|
||||
/obj/item/weapon/retractor,"retractor",1,,,,,1,,,,,,
|
||||
/obj/item/weapon/scalpel,"scalpel",1,,,,,1,,,,,,
|
||||
/obj/item/weapon/scythe,"scythe",,,2,,,2,,,,,,
|
||||
@@ -548,6 +636,7 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/stock_parts/subspace/transmitter,"subspace transmitter",,3,,,5,5,,,,,,
|
||||
/obj/item/weapon/stock_parts/subspace/treatment,"subspace treatment disk",,2,,,2,5,,,,,3,
|
||||
/obj/item/weapon/storage/backpack/holding,"Bag of Holding",,4,,,,,,,,,,
|
||||
/obj/item/weapon/storage/backpack/holding/proc,"Bag of Holding",,4,,,,,,,,,,
|
||||
/obj/item/weapon/storage/toolbox,"toolbox",,,1,,,,,,,,,
|
||||
/obj/item/weapon/storage/toolbox/electrical,"electrical toolbox",,,1,,,,,,,,,
|
||||
/obj/item/weapon/storage/toolbox/emergency,"emergency toolbox",,,1,,,,,,,,,
|
||||
@@ -556,11 +645,14 @@ Atom,Name,biotech,bluespace,combat,engineering,magnets,materials,plasma,plasmate
|
||||
/obj/item/weapon/surgicaldrill,"surgical drill",1,,,,,1,,,,,,
|
||||
/obj/item/weapon/syntiflesh,"syntiflesh",2,,,,,,,,,,,
|
||||
/obj/item/weapon/teleportation_scroll,"scroll of teleportation",,4,,,,,,,,,,
|
||||
/obj/item/weapon/teleportation_scroll/proc,"scroll of teleportation",,4,,,,,,,,,,
|
||||
/obj/item/weapon/twohanded/dualsaber,"double-bladed energy sword",,,,,3,,,,,,,4
|
||||
/obj/item/weapon/twohanded/hfrequency,"high-frequency blade",,,5,,4,,,,,,,
|
||||
/obj/item/weapon/weldingtool,"welding tool",,,,1,,,,,,,,
|
||||
/obj/item/weapon/weldingtool/experimental,"Experimental Welding Tool",,,,4,,,3,,,,,
|
||||
/obj/item/weapon/weldingtool/experimental/proc,"Experimental Welding Tool",,,,4,,,3,,,,,
|
||||
/obj/item/weapon/weldingtool/hugetank,"Upgraded Welding Tool",,,,3,,,,,,,,
|
||||
/obj/item/weapon/weldingtool/largetank,"Industrial Welding Tool",,,,2,,,,,,,,
|
||||
/obj/item/weapon/weldingtool/proc,"welding tool",,,,1,,,,,,,,
|
||||
/obj/item/weapon/wirecutters,"wirecutters",,,,1,,1,,,,,,
|
||||
/obj/item/weapon/wrench,"wrench",,,,1,,1,,,,,,
|
||||
|
||||
|
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>DMITool</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.python.pydev.PyDevBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.python.pydev.pythonNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?eclipse-pydev version="1.0"?>
|
||||
|
||||
<pydev_project>
|
||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||
<path>/DMITool</path>
|
||||
</pydev_pathproperty>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">python</pydev_property>
|
||||
</pydev_project>
|
||||
@@ -1,202 +0,0 @@
|
||||
"""
|
||||
DMI SPLITTER-UPPER THING
|
||||
|
||||
Makes merging sprites a hell of a lot easier.
|
||||
by N3X15 <nexis@7chan.org>
|
||||
|
||||
Requires PIL and apng.py (included)
|
||||
Written for Python 2.7.
|
||||
"""
|
||||
|
||||
import sys, os, traceback, fnmatch, argparse
|
||||
|
||||
from DMI import DMI
|
||||
|
||||
args = ()
|
||||
|
||||
def main():
|
||||
opt = argparse.ArgumentParser() # version='0.1')
|
||||
opt.add_argument('-p', '--suppress-post-processing', dest='suppress_post_process', default=False, action='store_true')
|
||||
command = opt.add_subparsers(help='The command you wish to execute', dest='MODE')
|
||||
|
||||
_disassemble = command.add_parser('disassemble', help='Disassemble a single DMI file to a destination directory')
|
||||
_disassemble.add_argument('file', type=str, help='The DMI file to disassemble.', metavar='file.dmi')
|
||||
_disassemble.add_argument('destination', type=str, help='The directory in which to dump the resulting images.', metavar='dest/')
|
||||
|
||||
_disassemble_all = command.add_parser('disassemble-all', help='Disassemble a directory of DMI files to a destination directory')
|
||||
_disassemble_all.add_argument('source', type=str, help='The DMI files to disassemble.', metavar='source/')
|
||||
_disassemble_all.add_argument('destination', type=str, help='The directory in which to dump the resulting images.', metavar='dest/')
|
||||
|
||||
_compile = command.add_parser('compile', help='Compile a .dmi.mak file')
|
||||
_compile.add_argument('makefile', type=str, help='The .dmi.mak file to compile.', metavar='file.dmi.mak')
|
||||
_compile.add_argument('destination', type=str, help='The location of the resulting .dmi file.', metavar='file.dmi')
|
||||
|
||||
_compare = command.add_parser('compare', help='Compare two DMI files and note the differences')
|
||||
_compare.add_argument('theirs', type=str, help='One side of the difference', metavar='theirs.dmi')
|
||||
_compare.add_argument('mine', type=str, help='The other side.', metavar='mine.dmi')
|
||||
|
||||
_compare_all = command.add_parser('compare-all', help='Compare two DMI file directories and note the differences')
|
||||
_compare_all.add_argument('theirs', type=str, help='One side of the difference', metavar='theirs/')
|
||||
_compare_all.add_argument('mine', type=str, help='The other side.', metavar='mine/')
|
||||
_compare_all.add_argument('report', type=str, help='The file the report is saved to', metavar='report.txt')
|
||||
|
||||
_get_dmi_data = command.add_parser('get-dmi-data', help='Extract DMI header')
|
||||
_get_dmi_data.add_argument('file', type=str, help='DMI file', metavar='file.dmi')
|
||||
_get_dmi_data.add_argument('dest', type=str, help='The file where the DMI header will be saved', metavar='dest.txt')
|
||||
|
||||
_set_dmi_data = command.add_parser('set-dmi-data', help='Set DMI header')
|
||||
_set_dmi_data.add_argument('file', type=str, help='One side of the difference', metavar='file.dmi')
|
||||
_set_dmi_data.add_argument('metadata', type=str, help='DMI header file', metavar='metadata.txt')
|
||||
"""
|
||||
opt.add_argument('-d', '--disassemble', dest='disassemble', type=str, nargs=2, action=ModeAction, help='Disassemble a single .dmi file to a destination.', metavar='file.dmi dest/')
|
||||
opt.add_argument('-D', '--disassemble-all', dest='disassemble_all', type=str, nargs=2, action=ModeAction, help='Disassemble a directory of DMI files recursively to a destination.', metavar='dmi_files/ dest/')
|
||||
opt.add_argument('-c', '--compile', dest='make_dmi', type=str, nargs=2, action=ModeAction, help='Compile a .dmi.mak file to a DMI.', metavar='my.dmi.mak my.dmi')
|
||||
opt.add_argument('-c', '--compile', dest='make_dmi', type=str, nargs=2, action=ModeAction, help='Compile a .dmi.mak file to a DMI.', metavar='my.dmi.mak my.dmi')
|
||||
"""
|
||||
|
||||
args = opt.parse_args()
|
||||
print(args)
|
||||
if args.MODE == 'compile':
|
||||
make_dmi(args.makefile, args.destination, args)
|
||||
if args.MODE == 'compare':
|
||||
compare(args.theirs, args.mine, args, sys.stdout)
|
||||
if args.MODE == 'compare-all':
|
||||
compare_all(args.theirs, args.mine, args.report, args)
|
||||
elif args.MODE == 'disassemble':
|
||||
disassemble(args.file, args.destination, args)
|
||||
elif args.MODE == 'disassemble-all':
|
||||
disassemble_all(args.source, args.destination, args)
|
||||
elif args.MODE == 'get-dmi-data':
|
||||
get_dmi_data(args.file, args.dest, args)
|
||||
elif args.MODE == 'set-dmi-data':
|
||||
set_dmi_data(args.file, args.metadata, args)
|
||||
else:
|
||||
print('!!! Error, unknown MODE=%r' % args.MODE)
|
||||
|
||||
class ModeAction(argparse.Action):
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
# print('%s %s %s' % (namespace, values, option_string))
|
||||
namespace.MODE = self.dest
|
||||
namespace.args = values
|
||||
|
||||
def get_dmi_data(path, dest, parser):
|
||||
if(os.path.isfile(path)):
|
||||
dmi = DMI(path)
|
||||
with open(dest,'w') as f:
|
||||
f.write(dmi.getHeader())
|
||||
|
||||
def set_dmi_data(path, headerFile, parser):
|
||||
if(os.path.isfile(path)):
|
||||
dmi = DMI(path)
|
||||
with open(headerFile, 'r') as f:
|
||||
dmi.setHeader(f.read(), path)
|
||||
|
||||
def make_dmi(path, dest, parser):
|
||||
if(os.path.isfile(path)):
|
||||
dmi = None
|
||||
try:
|
||||
dmi = DMI(dest)
|
||||
dmi.make(path)
|
||||
dmi.save(dest)
|
||||
except SystemError as e:
|
||||
print("!!! Received SystemError in %s, halting: %s" % (dmi.filename, traceback.format_exc(e)))
|
||||
print('# of cells: %d' % len(dmi.states))
|
||||
print('Image h/w: %s' % repr(dmi.size))
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print("Received error, continuing: %s" % traceback.format_exc())
|
||||
|
||||
def disassemble(path, to, parser):
|
||||
print('\tD %s -> %s' % (path, to))
|
||||
if(os.path.isfile(path)):
|
||||
dmi = None
|
||||
try:
|
||||
dmi = DMI(path)
|
||||
dmi.extractTo(to, parser.suppress_post_process)
|
||||
except SystemError as e:
|
||||
print("!!! Received SystemError in %s, halting: %s" % (dmi.filename, traceback.format_exc(e)))
|
||||
print('# of cells: %d' % len(dmi.states))
|
||||
print('Image h/w: %s' % repr(dmi.size))
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print("Received error, continuing: %s" % traceback.format_exc())
|
||||
|
||||
def compare(theirsfile, minefile, parser, reportstream):
|
||||
print('\tD %s -> %s' % (theirsfile, minefile))
|
||||
theirs = []
|
||||
mine = []
|
||||
states = []
|
||||
o = ''
|
||||
if(os.path.isfile(theirsfile)):
|
||||
try:
|
||||
theirsDMI = DMI(theirsfile)
|
||||
theirsDMI.parse()
|
||||
theirs = theirsDMI.states
|
||||
except SystemError as e:
|
||||
print("!!! Received SystemError in %s, halting: %s" % (theirs.filename, traceback.format_exc(e)))
|
||||
print('# of cells: %d' % len(theirs.states))
|
||||
print('Image h/w: %s' % repr(theirs.size))
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print("Received error, continuing: %s" % traceback.format_exc())
|
||||
o += "\n {0}: Received error, continuing: {1}".format(theirsfile,traceback.format_exc())
|
||||
for stateName in theirs:
|
||||
if stateName not in states:
|
||||
states.append(stateName)
|
||||
if(os.path.isfile(minefile)):
|
||||
try:
|
||||
mineDMI = DMI(minefile)
|
||||
mineDMI.parse()
|
||||
mine = mineDMI.states
|
||||
except SystemError as e:
|
||||
print("!!! Received SystemError in %s, halting: %s" % (mine.filename, traceback.format_exc(e)))
|
||||
print('# of cells: %d' % len(mine.states))
|
||||
print('Image h/w: %s' % repr(mine.size))
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print("Received error, continuing: %s" % traceback.format_exc())
|
||||
o += "\n {0}: Received error, continuing: {1}".format(minefile,traceback.format_exc())
|
||||
for stateName in mine:
|
||||
if stateName not in states:
|
||||
states.append(stateName)
|
||||
for state in sorted(states):
|
||||
inTheirs = state in theirs
|
||||
inMine = state in mine
|
||||
if inTheirs and not inMine:
|
||||
o += '\n + {1}'.format(minefile, state)
|
||||
elif not inTheirs and inMine:
|
||||
o += '\n - {1}'.format(theirsfile, state)
|
||||
elif inTheirs and inMine:
|
||||
if theirs[state].ToString() != mine[state].ToString():
|
||||
o += '\n - {0}: {1}'.format(state,mine[state].ToString())
|
||||
o += '\n + {0}: {1}'.format(state,theirs[state].ToString())
|
||||
if o != '':
|
||||
reportstream.write('\n--- {0}'.format(theirsfile))
|
||||
reportstream.write('\n+++ {0}'.format(minefile))
|
||||
reportstream.write(o)
|
||||
|
||||
|
||||
def disassemble_all(in_dir, out_dir, parser):
|
||||
print('D_A %s -> %s' % (in_dir, out_dir))
|
||||
for root, dirnames, filenames in os.walk(in_dir):
|
||||
for filename in fnmatch.filter(filenames, '*.dmi'):
|
||||
path = os.path.join(root, filename)
|
||||
to = os.path.join(out_dir, path.replace(in_dir, '').replace(os.path.basename(path), ''))
|
||||
disassemble(path, to, parser)
|
||||
|
||||
|
||||
def compare_all(in_dir, out_dir, report, parser):
|
||||
with open(report, 'w') as report:
|
||||
report.write('# DMITool Difference Report: {0} {1}'.format(os.path.abspath(in_dir), os.path.abspath(out_dir)))
|
||||
for root, dirnames, filenames in os.walk(in_dir):
|
||||
for filename in fnmatch.filter(filenames, '*.dmi'):
|
||||
path = os.path.join(root, filename)
|
||||
to = os.path.join(out_dir, path.replace(in_dir, '').replace(os.path.basename(path), ''))
|
||||
to = os.path.join(to, filename)
|
||||
path = os.path.abspath(path)
|
||||
to = os.path.abspath(to)
|
||||
compare(path, to, parser, report)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,150 +0,0 @@
|
||||
import os
|
||||
from byond import directions
|
||||
from PIL import Image
|
||||
class State:
|
||||
name = ''
|
||||
hotspot = ''
|
||||
frames = 0
|
||||
dirs = 1
|
||||
movement = 0
|
||||
loop = 0
|
||||
rewind = 0
|
||||
delay = []
|
||||
icons = []
|
||||
|
||||
def __init__(self, nm):
|
||||
self.name = nm
|
||||
self.hotspot = ''
|
||||
self.frames = 0
|
||||
self.dirs = 1
|
||||
self.movement = 0
|
||||
self.loop = 0
|
||||
self.rewind = 0
|
||||
self.delay = []
|
||||
self.icons = []
|
||||
|
||||
def genManifest(self):
|
||||
'''
|
||||
state = "void"
|
||||
dirs = 4
|
||||
frames = 4
|
||||
delay = 2,2,2,2
|
||||
'''
|
||||
o = '\r\nstate = "{0}"'.format(self.name)
|
||||
o += self.genManifestLine('hotspot',self.hotspot,'')
|
||||
o += self.genManifestLine('frames',self.frames,-1)
|
||||
o += self.genManifestLine('dirs',self.dirs,-1)
|
||||
o += self.genManifestLine('movement',self.movement,0)
|
||||
o += self.genManifestLine('loop',self.loop,0)
|
||||
o += self.genManifestLine('rewind',self.rewind,0)
|
||||
o += self.genManifestLine('delay',self.delay,[])
|
||||
|
||||
return o
|
||||
|
||||
def genDMIH(self):
|
||||
o = '\r\nstate "%s" {' % self.name
|
||||
o += self.genDMIHLine('hotspot',self.hotspot,'')
|
||||
o += self.genDMIHLine('frames',self.frames,-1)
|
||||
tdirs = 'ONE'
|
||||
if self.dirs == 4:
|
||||
tdirs='CARDINAL'
|
||||
elif self.dirs == 8:
|
||||
tdirs='ALL'
|
||||
o += self.genDMIHLine('dirs',tdirs,'')
|
||||
o += self.genDMIHLine('movement',self.movement,0)
|
||||
o += self.genDMIHLine('loop',self.loop,0)
|
||||
o += self.genDMIHLine('rewind',self.rewind,0)
|
||||
o += self.genDMIHLine('delay',self.delay,[])
|
||||
|
||||
o += '\n\timport pngs {'
|
||||
for vdir in range(self.dirs):
|
||||
dir = directions.IMAGE_INDICES[vdir]
|
||||
o += '\n\t\tdirection "%s" {' % directions.getNameFromDir(dir)
|
||||
for f in range(self.frames):
|
||||
o += '\n\t\t\t"%s"' % self.getFrame(dir, f)
|
||||
o += '\n\t\t}'
|
||||
o += '\n\t}'
|
||||
o += "\n}"
|
||||
return o
|
||||
|
||||
def genDMIHLine(self,name,value,default):
|
||||
if value != default:
|
||||
if type(value) is list:
|
||||
value = ','.join(value)
|
||||
return '\n\t{0} = {1}'.format(name,value)
|
||||
return ''
|
||||
|
||||
def genManifestLine(self,name,value,default):
|
||||
if value != default:
|
||||
if type(value) is list:
|
||||
value = ','.join(value)
|
||||
return '\r\n {0} = {1}'.format(name,value)
|
||||
return ''
|
||||
|
||||
def ToString(self):
|
||||
o = '%s: %d frames, ' % (self.name, self.frames)
|
||||
o += '%d directions' % self.dirs
|
||||
#o += ' icons: ' + repr(self.icons)
|
||||
return o
|
||||
|
||||
def numIcons(self):
|
||||
return self.frames * self.dirs
|
||||
|
||||
def getFrame(self,direction,frame):
|
||||
dir = 0
|
||||
if self.dirs == 4 or self.dirs == 8:
|
||||
dir = directions.IMAGE_INDICES.index(direction)
|
||||
|
||||
frame=dir+(frame*self.dirs)
|
||||
return self.icons[frame]
|
||||
|
||||
def postProcess(self):
|
||||
filetype = "png"
|
||||
if(self.frames > 0):
|
||||
filetype = "gif"
|
||||
if(self.frames == 1 and self.dirs == 1):
|
||||
oldfilename = self.icons[0]
|
||||
self.icons[0] = self.icons[0].split('[')[0] + '.png'
|
||||
if os.path.isfile(self.icons[0]):
|
||||
os.remove(self.icons[0])
|
||||
os.rename(oldfilename, self.icons[0])
|
||||
return
|
||||
# print(' * POSTPROCESSING %s...'%self.name)
|
||||
frames = [None] * self.dirs
|
||||
frameFiles = [None] * self.dirs
|
||||
for dir in range(self.dirs):
|
||||
frames[dir] = []
|
||||
frameFiles[dir] = []
|
||||
i = 0
|
||||
for frame in range(self.frames):
|
||||
for dir in range(self.dirs):
|
||||
frames[dir] += [Image.open(self.icons[i])]
|
||||
frameFiles[dir] += [self.icons[i]]
|
||||
i += 1
|
||||
for dir in range(self.dirs):
|
||||
if(len(frames[dir]) <= 1):
|
||||
continue
|
||||
filename = '%s-ANIM[%d].apng' % (self.icons[0].split('[')[0], dir)
|
||||
if(len(self.delay) == 0):
|
||||
self.delay = [1] * self.frames
|
||||
if len(frames[dir]) != len(self.delay):
|
||||
print('Delay count doesn\'t match frame count (%d != %d)' % (len(frames[dir]), len(self.delay)))
|
||||
else:
|
||||
if os.path.isfile(filename):
|
||||
os.remove(filename)
|
||||
# print(' >>> Consolidating %d frames into %s...' % (len(frameFiles[dir]),filename))
|
||||
fixedDelays = []
|
||||
fi = 0
|
||||
for delay in self.delay:
|
||||
d = float(delay) / 10
|
||||
fi += 1
|
||||
# print ('Frame %d delay = %s' % (fi,d))
|
||||
fixedDelays += [d] # Required in order to work properly.
|
||||
# writeGif(filename, frames[dir], duration=fixedDelays, dither=0)
|
||||
# apng = APNG()
|
||||
# for fi in range(len(frames[dir])):
|
||||
# apng.addFrame(frameFiles[dir][fi],fixedDelays[fi]*1000, 1000)
|
||||
# apng.save(filename)
|
||||
# for nukeMe in frameFiles[dir]:
|
||||
# if os.path.isfile(nukeMe):
|
||||
# os.remove(nukeMe)
|
||||
@@ -1,317 +0,0 @@
|
||||
|
||||
import sys, os, glob, string, traceback, fnmatch, math, shutil
|
||||
|
||||
from PIL import Image, PngImagePlugin
|
||||
from .State import State
|
||||
from DMIH import *
|
||||
|
||||
class DMI:
|
||||
version = ''
|
||||
states = {}
|
||||
iw = 32
|
||||
ih = 32
|
||||
filename = ''
|
||||
pixels = None
|
||||
size = ()
|
||||
statelist = ''
|
||||
max_x = -1
|
||||
max_y = -1
|
||||
|
||||
def __init__(self, file):
|
||||
self.filename = file
|
||||
self.version = ''
|
||||
self.states = {}
|
||||
self.iw = 32
|
||||
self.ih = 32
|
||||
self.pixels = None
|
||||
self.size = ()
|
||||
self.statelist = 'LOLNONE'
|
||||
self.max_x = -1
|
||||
self.max_y = -1
|
||||
|
||||
def make(self, makefile):
|
||||
print('>>> Compiling %s -> %s' % (makefile, self.filename))
|
||||
h = DMIH()
|
||||
h.parse(makefile)
|
||||
for node in h.tokens:
|
||||
if type(node) is Variable:
|
||||
if node.name == 'height':
|
||||
self.ih = node.value
|
||||
elif node.name == 'weight':
|
||||
self.iw = node.value
|
||||
elif type(node) is directives.State:
|
||||
self.states[node.state.name] = node.state
|
||||
elif type(node) is directives.Import:
|
||||
if node.ftype == 'dmi':
|
||||
dmi = DMI(node.filedef)
|
||||
dmi.extractTo("_tmp/" + os.path.basename(node.filedef))
|
||||
for name in dmi.states:
|
||||
self.states[name] = dmi.states[name]
|
||||
|
||||
def save(self, to):
|
||||
|
||||
# Now build the manifest
|
||||
manifest = 'version = 4.0'
|
||||
manifest += '\r\n width = {0}'.format(self.iw)
|
||||
manifest += '\r\n height = {0}'.format(self.ih)
|
||||
|
||||
frames = []
|
||||
# Sort by name because I'm autistic like that.
|
||||
for name in sorted(self.states):
|
||||
manifest += self.states[name].genManifest()
|
||||
frames += self.states[name].icons
|
||||
|
||||
# Next bit borrowed from DMIDE.
|
||||
icons_per_row = math.ceil(math.sqrt(len(frames)))
|
||||
rows = icons_per_row
|
||||
if len(frames) > icons_per_row * rows:
|
||||
rows += 1
|
||||
map = Image.new('RGBA', (icons_per_row * self.iw, rows * self.ih))
|
||||
|
||||
x = 0
|
||||
y = 0
|
||||
for frame in frames:
|
||||
# print(frame)
|
||||
icon = Image.open(frame, 'r')
|
||||
map.paste(icon, (x * self.iw, y * self.ih))
|
||||
x += 1
|
||||
if x > icons_per_row:
|
||||
y += 1
|
||||
x = 0
|
||||
|
||||
# More borrowed from DMIDE:
|
||||
# undocumented class
|
||||
meta = PngImagePlugin.PngInfo()
|
||||
|
||||
# copy metadata into new object
|
||||
|
||||
reserved = ('interlace', 'gamma', 'dpi', 'transparency', 'aspect')
|
||||
for k, v in map.info.items():
|
||||
if k in reserved: continue
|
||||
meta.add_text(k, v, 1)
|
||||
# Only need one - Rob
|
||||
meta.add_text(b'Description', manifest.encode('ascii'), 1)
|
||||
|
||||
# and save
|
||||
map.save(to, 'PNG', pnginfo=meta)
|
||||
|
||||
print('>>> {0} states saved to {1}'.format(len(frames), to))
|
||||
|
||||
def getDMIH(self):
|
||||
o = '# DMI Header 1.0 - Generated by DMI.py'
|
||||
o += self.genDMIHLine('width', self.iw, -1)
|
||||
o += self.genDMIHLine('height', self.ih, -1)
|
||||
|
||||
for s in sorted(self.states):
|
||||
o += self.states[s].genDMIH()
|
||||
|
||||
return o
|
||||
|
||||
def genDMIHLine(self, name, value, default):
|
||||
if value != default:
|
||||
if type(value) is list:
|
||||
value = ','.join(value)
|
||||
return '\n{0} = {1}'.format(name, value)
|
||||
return ''
|
||||
|
||||
def extractTo(self, dest, suppress_post_process=False):
|
||||
print('>>> Extracting %s...' % self.filename)
|
||||
self.read(dest, suppress_post_process)
|
||||
|
||||
def getFrame(self, state, dir, frame):
|
||||
if state not in self.states:
|
||||
return None
|
||||
return self.states[state].getFrame(dir, frame)
|
||||
|
||||
def getHeader(self):
|
||||
img = Image.open(self.filename)
|
||||
# print(repr(img.info))
|
||||
if(b'Description' not in img.info):
|
||||
raise Exception("DMI Description is not in the information headers!")
|
||||
return img.info[b'Description'].decode('ascii')
|
||||
|
||||
def setHeader(self, newHeader, dest):
|
||||
img = Image.open(self.filename)
|
||||
|
||||
# More borrowed from DMIDE:
|
||||
# undocumented class
|
||||
meta = PngImagePlugin.PngInfo()
|
||||
|
||||
# copy metadata into new object
|
||||
|
||||
reserved = ('interlace', 'gamma', 'dpi', 'transparency', 'aspect','icc_profile')
|
||||
for k, v in img.info.items():
|
||||
if k in reserved: continue
|
||||
print(k,v)
|
||||
meta.add_text(k, v, 1)
|
||||
# Only need one - Rob
|
||||
meta.add_text(b'Description', newHeader.encode('ascii'), 1)
|
||||
|
||||
# and save
|
||||
img.save(dest + '.tmp', 'PNG', pnginfo=meta)
|
||||
shutil.move(dest + '.tmp', dest)
|
||||
|
||||
def parse(self, dest=None, suppress_post_process=True):
|
||||
if dest is None:
|
||||
suppress_post_process = True
|
||||
img = Image.open(self.filename)
|
||||
self.size = img.size
|
||||
# print(repr(img.info))
|
||||
if(b'Description' not in img.info):
|
||||
raise Exception("DMI Description is not in the information headers!")
|
||||
self.pixels = img.load()
|
||||
desc = img.info[b'Description'].decode('ascii')
|
||||
"""
|
||||
version = 4.0
|
||||
width = 32
|
||||
height = 32
|
||||
state = "fire"
|
||||
dirs = 4
|
||||
frames = 1
|
||||
state = "fire2"
|
||||
dirs = 1
|
||||
frames = 1
|
||||
state = "void"
|
||||
dirs = 4
|
||||
frames = 4
|
||||
delay = 2,2,2,2
|
||||
state = "void2"
|
||||
dirs = 1
|
||||
frames = 4
|
||||
delay = 2,2,2,2
|
||||
"""
|
||||
state = None
|
||||
x = 0
|
||||
y = 0
|
||||
self.statelist = desc
|
||||
ii = 0
|
||||
for line in desc.split("\n"):
|
||||
line = line.strip()
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
if '=' in line:
|
||||
(key, value) = line.split(' = ')
|
||||
key = key.strip()
|
||||
value = value.strip().replace('"', '')
|
||||
if key == 'version':
|
||||
self.version = value
|
||||
elif key == 'width':
|
||||
self.iw = int(value)
|
||||
self.max_x = img.size[0] / self.iw
|
||||
elif key == 'height':
|
||||
self.ih = int(value)
|
||||
self.max_y = img.size[1] / self.ih
|
||||
# print(('%s: {sz: %s,h: %d, w: %d, m_x: %d, m_y: %d}'%(self.filename,repr(img.size),self.ih,self.iw,self.max_x,self.max_y)))
|
||||
elif key == 'state':
|
||||
if state != None:
|
||||
# print(" + %s" % (state.ToString()))
|
||||
if(self.iw == 0 or self.ih == 0):
|
||||
if(len(self.states) > 0):
|
||||
raise SystemError("Width and height for each cell are not available.")
|
||||
else:
|
||||
self.iw = img.size[0]
|
||||
self.max_x = 1
|
||||
self.ih = img.size[1]
|
||||
self.max_y = 1
|
||||
elif(self.max_x == -1 or self.max_y == -1):
|
||||
self.max_x = img.size[0] / self.iw
|
||||
self.max_y = img.size[1] / self.iw
|
||||
for i in range(state.numIcons()):
|
||||
icon = self.extractNextIcon(state, img, dest, x, y, i)
|
||||
state.icons += [icon]
|
||||
x += 1
|
||||
# print('%s[%d:%d] x=%d, max_x=%d' % (self.filename,ii,i,x,self.max_x))
|
||||
if(x >= self.max_x):
|
||||
x = 0
|
||||
y += 1
|
||||
self.states[state.name] = state
|
||||
if not suppress_post_process:
|
||||
self.states[state.name].postProcess()
|
||||
ii += 1
|
||||
state = State(value)
|
||||
elif key == 'dirs':
|
||||
state.dirs = int(value)
|
||||
elif key == 'frames':
|
||||
state.frames = int(value)
|
||||
elif key == 'loop':
|
||||
state.loop = int(value)
|
||||
elif key == 'rewind':
|
||||
state.rewind = int(value)
|
||||
elif key == 'movement':
|
||||
state.movement = int(value)
|
||||
elif key == 'delay':
|
||||
state.delay = value.split(',')
|
||||
elif key == 'hotspot':
|
||||
state.hotspot = value
|
||||
else:
|
||||
print('Unknown key ' + key + ' (value=' + value + ')!')
|
||||
sys.exit()
|
||||
|
||||
self.states[state.name] = state
|
||||
for i in range(state.numIcons()):
|
||||
self.states[state.name].icons += [self.extractNextIcon(state, img, dest, x, y, i)]
|
||||
x += 1
|
||||
# print('%s[%d:%d] x=%d, max_x=%d' % (self.filename,ii,i,x,self.max_x))
|
||||
if(x >= self.max_x):
|
||||
x = 0
|
||||
y += 1
|
||||
if not suppress_post_process:
|
||||
self.states[state.name].postProcess()
|
||||
if dest is not None:
|
||||
outfolder = os.path.join(dest, os.path.basename(self.filename))
|
||||
nfn = self.filename.replace('.dmi', '.dmih')
|
||||
valid_chars = "-_.()[] %s%s" % (string.ascii_letters, string.digits)
|
||||
nfn = ''.join(c for c in nfn if c in valid_chars)
|
||||
nfn = os.path.join(outfolder, nfn)
|
||||
with open(nfn, 'w') as dmih:
|
||||
dmih.write(self.getDMIH())
|
||||
|
||||
print(' DONE! Extracted %d icon states.' % ii)
|
||||
|
||||
def extractNextIcon(self, state, img, dest, sx, sy, i):
|
||||
if(self.iw == 0 or self.ih == 0):
|
||||
print('--STATES:--')
|
||||
print(self.statelist)
|
||||
raise SystemError("Invalid state: " + state.ToString())
|
||||
# print(" X (%d,%d)"%(sx*self.iw,sy*self.ih))
|
||||
icon = Image.new(img.mode, (self.iw, self.ih))
|
||||
newpix = icon.load()
|
||||
# max_x = 0
|
||||
for y in range(self.ih):
|
||||
for x in range(self.iw):
|
||||
_x = x + (sx * self.iw)
|
||||
_y = y + (sy * self.ih)
|
||||
# if(_x>=self.iw or _y>=self.ih):
|
||||
# continue
|
||||
# if(_x<0 or _y<0):
|
||||
# continue
|
||||
try:
|
||||
newpix[x, y] = self.pixels[_x, _y]
|
||||
except IndexError as e:
|
||||
print("!!! Received IndexError in %s <%d,%d> = <%d,%d> + (<%d,%d> * <%d,%d>), max=<%d,%d> halting." % (self.filename, _x, _y, x, y, sx, sy, self.iw, self.ih, self.max_x, self.max_y))
|
||||
print('%s: {sz: %s,h: %d, w: %d, m_x: %d, m_y: %d}' % (self.filename, repr(img.size), self.ih, self.iw, self.max_x, self.max_y))
|
||||
print('# of cells: %d' % len(self.states))
|
||||
print('Image h/w: %s' % repr(self.size))
|
||||
print('State: ' + state.ToString())
|
||||
print('--STATES:--')
|
||||
print(self.statelist)
|
||||
sys.exit(1)
|
||||
if dest is None:
|
||||
return icon
|
||||
outfolder = os.path.join(dest, os.path.basename(self.filename))
|
||||
if not os.path.isdir(outfolder):
|
||||
print('\tMKDIR ' + outfolder)
|
||||
os.makedirs(outfolder)
|
||||
nfn = state.name + "[%d].png" % i
|
||||
valid_chars = "-_.()[] %s%s" % (string.ascii_letters, string.digits)
|
||||
nfn = ''.join(c for c in nfn if c in valid_chars)
|
||||
nfn = os.path.join(outfolder, nfn)
|
||||
if os.path.isfile(nfn):
|
||||
os.remove(nfn)
|
||||
try:
|
||||
icon.save(nfn)
|
||||
except SystemError as e:
|
||||
print("Received SystemError, halting: %s" % traceback.format_exc(e))
|
||||
print('{ih=%d,iw=%d,state=%s,dest=%s,sx=%d,sy=%d,i=%d}' % (self.ih, self.iw, state.ToString(), dest, sx, sy, i))
|
||||
sys.exit(1)
|
||||
return nfn
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
|
||||
class Variable(object):
|
||||
name=''
|
||||
value=None
|
||||
|
||||
def __init__(self,name,value):
|
||||
self.name=name
|
||||
self.value=value
|
||||
@@ -1,135 +0,0 @@
|
||||
'''
|
||||
Created on Feb 23, 2013
|
||||
|
||||
@author: Rob
|
||||
'''
|
||||
|
||||
from . import directives, Variable
|
||||
|
||||
valid_symbol_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
|
||||
|
||||
class DMIH(object):
|
||||
"""
|
||||
# DMI Header 1.0
|
||||
# ------------------------
|
||||
|
||||
height = 32
|
||||
width = 32
|
||||
|
||||
state "AMAZIN' RAISINS" {
|
||||
dirtype=CARDINAL
|
||||
frames=5
|
||||
|
||||
import pngs {
|
||||
direction NORTH {
|
||||
"amazinraisin-N-0.png"
|
||||
"amazinraisin-N-1.png"
|
||||
"amazinraisin-N-2.png"
|
||||
"amazinraisin-N-3.png"
|
||||
"amazinraisin-N-4.png"
|
||||
}
|
||||
direction EAST {
|
||||
"amazinraisin-E-0.png"
|
||||
"amazinraisin-E-1.png"
|
||||
"amazinraisin-E-2.png"
|
||||
"amazinraisin-E-3.png"
|
||||
"amazinraisin-E-4.png"
|
||||
}
|
||||
direction WEST {
|
||||
"amazinraisin-W-0.png"
|
||||
"amazinraisin-W-1.png"
|
||||
"amazinraisin-W-2.png"
|
||||
"amazinraisin-W-3.png"
|
||||
"amazinraisin-W-4.png"
|
||||
}
|
||||
direction SOUTH {
|
||||
"amazinraisin-S-0.png"
|
||||
"amazinraisin-S-1.png"
|
||||
"amazinraisin-S-2.png"
|
||||
"amazinraisin-S-3.png"
|
||||
"amazinraisin-S-4.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# File State orig State new
|
||||
import dmi "import/ohgodwhy.dmi" "Oh god why" "metroid5"
|
||||
|
||||
"""
|
||||
|
||||
tokens = []
|
||||
|
||||
'''
|
||||
directive arg1 {block}
|
||||
'''
|
||||
directives = {
|
||||
'direction': directives.Direction.Direction,
|
||||
'import': directives.Import.Import,
|
||||
'state': directives.State.State
|
||||
}
|
||||
|
||||
def parse(self, file):
|
||||
with open(file) as f:
|
||||
self.tokens = self.parseBlockContents(f)
|
||||
|
||||
def readSymbol(self, f):
|
||||
f.seek(f.tell() - 1) # Back up one char
|
||||
o = ''
|
||||
while True:
|
||||
c = f.read(1)
|
||||
if c in valid_symbol_chars:
|
||||
o += c
|
||||
else:
|
||||
return o
|
||||
|
||||
def readString(self, f, b):
|
||||
# f.seek(f.tell()-1) # Back up one char
|
||||
o = ''
|
||||
while True:
|
||||
c = f.read(1)
|
||||
if c == b:
|
||||
return o
|
||||
else:
|
||||
o += c
|
||||
|
||||
def parseBlockContents(self, f):
|
||||
buf = ''
|
||||
currentBlock = []
|
||||
memory = []
|
||||
_in = None
|
||||
memchanged = False
|
||||
while True:
|
||||
b = f.read(1) # .decode('utf-8')
|
||||
if b in ('"', "'"):
|
||||
memory += [self.readString(f, b)]
|
||||
memchanged = True
|
||||
|
||||
if b in valid_symbol_chars:
|
||||
memory += [self.readSymbol(f)]
|
||||
f.seek(f.tell() - 1) # Back up one char in case we have to deal with a block.
|
||||
memchanged = True
|
||||
|
||||
if b == '=':
|
||||
memory += ['=']
|
||||
memchanged = True
|
||||
|
||||
if b == '{':
|
||||
memory += [self.parseBlockContents(f)]
|
||||
memchanged = True
|
||||
|
||||
if b == '}' or b == '': # End of block or end of file.
|
||||
return currentBlock
|
||||
|
||||
if memchanged:
|
||||
token = None
|
||||
if len(memory) == 3:
|
||||
if memory[2] == '=':
|
||||
token = Variable(memory[0], memory[1])
|
||||
if len(memory) > 0:
|
||||
if memory[0] in self.directives:
|
||||
token = self.directives[memory[0]](memory[0], memory[1:])
|
||||
if token:
|
||||
currentBlock += [token]
|
||||
memory = []
|
||||
memchanged = False
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
'''
|
||||
Created on Feb 23, 2013
|
||||
|
||||
@author: Rob
|
||||
'''
|
||||
from .Directive import Directive
|
||||
from byond import directions
|
||||
|
||||
class Direction(Directive):
|
||||
'''
|
||||
Tells the compiler which frames will be used for this direction.
|
||||
'''
|
||||
|
||||
'''
|
||||
Which direction?
|
||||
'''
|
||||
dir=0
|
||||
|
||||
'''
|
||||
List of files.
|
||||
'''
|
||||
frames=[]
|
||||
def __init__(self,name,frames):
|
||||
Directive.__init__(self, name, [name,frames])
|
||||
_dir = directions.getDirFromName(name)
|
||||
if _dir:
|
||||
self.dir=_dir
|
||||
self.frames=frames
|
||||
@@ -1,14 +0,0 @@
|
||||
'''
|
||||
Created on Feb 23, 2013
|
||||
|
||||
@author: Rob
|
||||
'''
|
||||
|
||||
class Directive(object):
|
||||
'''
|
||||
Base type for directives.
|
||||
'''
|
||||
name = ''
|
||||
|
||||
def __init__(self,name,args):
|
||||
self.name=name
|
||||
@@ -1,50 +0,0 @@
|
||||
'''
|
||||
Created on Feb 23, 2013
|
||||
|
||||
@author: Rob
|
||||
'''
|
||||
from .Directive import Directive
|
||||
|
||||
class Import(Directive):
|
||||
'''
|
||||
Tells the compiler to import a file into the DMI.
|
||||
'''
|
||||
|
||||
'''
|
||||
pngs or dmi.
|
||||
'''
|
||||
ftype=''
|
||||
|
||||
'''
|
||||
The file(s) to import into the DMI.
|
||||
'''
|
||||
filedef=None
|
||||
|
||||
'''
|
||||
State(s) to import (DMIs)
|
||||
'''
|
||||
states={}
|
||||
|
||||
def __init__(self,name,params):
|
||||
Directive.__init__(self,name,params)
|
||||
self.ftype=params[0]
|
||||
if self.ftype=='pngs':
|
||||
self.filedef=params[1]
|
||||
elif self.ftype=='dmi':
|
||||
self.filedef=str(params[1])
|
||||
if type(params[2]) is list:
|
||||
for sn in params[2]:
|
||||
self.addState(sn)
|
||||
elif type(params[2]) is str:
|
||||
self.addState(params[2])
|
||||
|
||||
def addState(self,sn):
|
||||
oldname=None
|
||||
newname=None
|
||||
snp=sn.split('->')
|
||||
if snp.len == 2:
|
||||
(oldname, newname)=snp
|
||||
elif snp.len == 1:
|
||||
oldname=newname=snp[0]
|
||||
if oldname and newname:
|
||||
self.states[oldname]=newname
|
||||
@@ -1,51 +0,0 @@
|
||||
'''
|
||||
Created on Feb 23, 2013
|
||||
|
||||
@author: Rob
|
||||
'''
|
||||
from .Directive import Directive
|
||||
from .Import import Import
|
||||
from DMI import State
|
||||
from .. import Variable
|
||||
|
||||
directly_assignable={
|
||||
'hotspot':tuple,
|
||||
'dirs':int,
|
||||
'frames':int,
|
||||
'movement':int,
|
||||
'loop':int,
|
||||
'rewind':int,
|
||||
'delay':tuple
|
||||
}
|
||||
|
||||
class State(Directive):
|
||||
'''
|
||||
Tells the compiler to create a state with the specified variables and frames.
|
||||
'''
|
||||
|
||||
'''
|
||||
The actual state
|
||||
'''
|
||||
state = None
|
||||
imports = []
|
||||
def __init__(self,name,params):
|
||||
Directive.__init__(self,name,params)
|
||||
self.state=State()
|
||||
if params.len != 2:
|
||||
raise Exception('state directive requires 2 parameters. state "name" { }')
|
||||
self.state.name=params[0]
|
||||
for o in params[1]:
|
||||
if type(o) is Variable and o.name in directly_assignable:
|
||||
if o.name == 'dirs':
|
||||
if o.value == 'CARDINAL':
|
||||
o.value = 4
|
||||
elif o.value == 'ALL':
|
||||
o.value = 8
|
||||
else:
|
||||
o.value = 1
|
||||
setattr(self.state,o.name,directly_assignable[o.name](o.value))
|
||||
if type(o) is Import:
|
||||
if o.ftype == 'pngs':
|
||||
for dirblock in o.filedef:
|
||||
for i in range(dirblock.frames.len):
|
||||
self.state.setFrame(dirblock.dir, i, dirblock.frames[i])
|
||||
@@ -1,4 +0,0 @@
|
||||
from . import Direction, Directive, Import, State
|
||||
__all__ = [
|
||||
Direction, Directive, Import, State
|
||||
]
|
||||
@@ -1,313 +0,0 @@
|
||||
#!/usr/local/bin/python
|
||||
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
"""
|
||||
pngmerge -- composing APNG from PNG images
|
||||
Copyright (C) 2009 Kengo Ichiki <kichiki@users.sourceforge.net>
|
||||
$Id: pngmerge.py,v 1.1 2009/03/25 05:25:59 kengo Exp $
|
||||
"""
|
||||
|
||||
import sys
|
||||
import binascii
|
||||
import struct
|
||||
from PIL import Image
|
||||
|
||||
def i16(c):
|
||||
return c[1] + (c[0] << 8)
|
||||
def i32(c):
|
||||
return c[3] + (c[2] << 8) + (c[1] << 16) + (c[0] << 24)
|
||||
|
||||
def PNG_crc(f, cid, data):
|
||||
"Read and verify checksum"
|
||||
|
||||
crc1 = Image.core.crc32(data, Image.core.crc32(cid))
|
||||
crc2 = i16(f.read(2)), i16(f.read(2))
|
||||
if crc1 != crc2:
|
||||
raise SyntaxError("broken PNG file"\
|
||||
"(bad header checksum in %s)" % cid)
|
||||
|
||||
def PNG_header_read (f):
|
||||
header = f.read(8)
|
||||
if header != b'\x89PNG\x0d\x0a\x1a\x0a':
|
||||
print('Current file is not PNG file!')
|
||||
sys.exit()
|
||||
|
||||
def PNG_header_write (f):
|
||||
head = b'\x89PNG\x0d\x0a\x1a\x0a'
|
||||
f.write(head)
|
||||
|
||||
|
||||
def PNG_chunk_read (f):
|
||||
s = f.read(8)
|
||||
length = i32(s) # struct.unpack(">I", f.read(4))
|
||||
name = s[4:]
|
||||
data = f.read(length)
|
||||
crc = PNG_crc(f, name, data)
|
||||
# crc, = struct.unpack(">i", f.read(4))
|
||||
|
||||
# crc_ = binascii.crc32(name)
|
||||
# crc_ = binascii.crc32(data, crc_)
|
||||
# if crc != crc_:
|
||||
# print("corrupt data crc : ", crc, crc_)
|
||||
# sys.exit()
|
||||
|
||||
return (name, data, crc)
|
||||
|
||||
def PNG_chunk_write (f, name, data):
|
||||
crc = binascii.crc32(name)
|
||||
length = len(data)
|
||||
if length > 0:
|
||||
crc = binascii.crc32(data, crc)
|
||||
f.write(struct.pack(">I", length))
|
||||
f.write(name)
|
||||
if length > 0:
|
||||
f.write(data)
|
||||
f.write(struct.pack(">i", crc))
|
||||
|
||||
|
||||
|
||||
def PNG_IHDR_write (f, w, h, d, col, comp, filt, intl):
|
||||
name = 'IHDR'
|
||||
data = struct.pack(">IIbbbbb", w, h, d, col, comp, filt, intl)
|
||||
PNG_chunk_write (f, name, data)
|
||||
|
||||
|
||||
def PNG_IHDR_parse (data):
|
||||
if len(data) != 13:
|
||||
print("IHDR : length %d != 13" % (len(data)))
|
||||
sys.exit()
|
||||
|
||||
w, h, d, col, comp, filt, intl = struct.unpack(">IIbbbbb", data)
|
||||
return w, h, d, col, comp, filt, intl
|
||||
|
||||
|
||||
def PNG_acTL_write (f, nf, np):
|
||||
name = 'acTL'
|
||||
data = struct.pack(">II", nf, np)
|
||||
PNG_chunk_write (f, name, data)
|
||||
|
||||
def PNG_acTL_parse (data):
|
||||
if len(data) != 8:
|
||||
print("acTL : length %d != 8" % (len(data)))
|
||||
sys.exit()
|
||||
|
||||
nf, np = struct.unpack(">II", data)
|
||||
return nf, np
|
||||
|
||||
|
||||
def PNG_fcTL_write (f, ns, w, h, x0, y0, dn, dd, dop, bop):
|
||||
name = 'fcTL'
|
||||
data = struct.pack(">IIIIIHHBB",
|
||||
ns, w, h, x0, y0, dn, dd, dop, bop)
|
||||
PNG_chunk_write (f, name, data)
|
||||
|
||||
def PNG_fcTL_parse (data):
|
||||
if len(data) != 26:
|
||||
print("fcTL : length %d != 26" % (len(data)))
|
||||
sys.exit()
|
||||
|
||||
ns, w, h, x0, y0, dn, dd, dop, bop = struct.unpack(">IIIIIHHBB", data)
|
||||
return ns, w, h, x0, y0, dn, dd, dop, bop
|
||||
|
||||
|
||||
def PNG_fdAT_write (f, ns, data):
|
||||
name = 'fdAT'
|
||||
data_ = struct.pack(">I", ns) + data
|
||||
PNG_chunk_write (f, name, data_)
|
||||
|
||||
|
||||
|
||||
def usage():
|
||||
print('pngmerge -- composing APNG from PNG images')
|
||||
print('$Id: pngmerge.py,v 1.1 2009/03/25 05:25:59 kengo Exp $')
|
||||
print('USAGE: python pngmerge.py [options] file1 file2 ...')
|
||||
print('OPTIONS:')
|
||||
print('\t-o : output file name')
|
||||
print('\t-np : number of plays (default: 0 for looping)')
|
||||
print('\t-dn : numerator for delay time (default: 100)')
|
||||
print('\t-dd : denominator for delay time (default: 1000)')
|
||||
|
||||
# Making a builder class implementation so we're mildly more flexible.
|
||||
class APNG:
|
||||
frames = []
|
||||
np = 0
|
||||
i = 1
|
||||
|
||||
def __init__(self):
|
||||
self.frames = []
|
||||
self.np = 0
|
||||
self.i = 1
|
||||
def addFrame(self, infile, numerator=100, denominator=1000):
|
||||
self.frames += [(infile, numerator, denominator)]
|
||||
|
||||
def save(self, outputFile):
|
||||
with open(outputFile, 'wb') as apng:
|
||||
num_frames = len(self.frames)
|
||||
dop = 1 # APNG_DISPOSE_OP_BACKGROUND
|
||||
bop = 0 # APNG_BLEND_OP_SOURCE
|
||||
PNG_header_write(apng)
|
||||
|
||||
ns = 0 # number of sequence
|
||||
w0 = 0
|
||||
h0 = 0
|
||||
d0 = 0
|
||||
col0 = 0
|
||||
comp0 = 0
|
||||
filt0 = 0
|
||||
intl0 = 0
|
||||
for i in range(num_frames):
|
||||
filename, numerator, denominator = self.frames[i]
|
||||
print('Reading %s...' % filename)
|
||||
with open(filename, 'rb') as f_png:
|
||||
PNG_header_read (f_png)
|
||||
while 1:
|
||||
name, data, crc = PNG_chunk_read (f_png)
|
||||
if name == 'IEND':
|
||||
break
|
||||
elif name == 'IHDR':
|
||||
if(i == 0):
|
||||
w0, h0, d0, col0, comp0, filt0, intl0 = PNG_IHDR_parse (data)
|
||||
PNG_IHDR_write (apng, w0, h0, d0, col0, comp0, filt0, intl0)
|
||||
# acTL
|
||||
PNG_acTL_write (apng, nf, self.np)
|
||||
# fcTL
|
||||
PNG_fcTL_write (apng, ns, w0, h0, 0, 0, numerator, denominator, dop, bop)
|
||||
else:
|
||||
w, h, d, col, comp, filt, intl = PNG_IHDR_parse (data)
|
||||
if w != w0 or h != h0 or d != d0 or col != col0 or comp != comp0 or filt != filt0 or intl != intl0:
|
||||
print('something is wrong...')
|
||||
# fcTL
|
||||
PNG_fcTL_write (apng, ns, w0, h0, 0, 0, numerator, denominator, dop, bop)
|
||||
ns += 1
|
||||
elif name == 'IDAT':
|
||||
if(i == 0):
|
||||
# IDAT
|
||||
PNG_chunk_write (apng, name, data)
|
||||
else:
|
||||
# fdAT
|
||||
PNG_fdAT_write (apng, ns, data)
|
||||
ns += 1
|
||||
PNG_chunk_write (apng, 'IEND', '')
|
||||
|
||||
def main():
|
||||
file_apng = ''
|
||||
file_pngs = []
|
||||
np = 0 # number of plays
|
||||
dn = 100 # numerator of delay
|
||||
dd = 1000 # denominator of delay
|
||||
i = 1
|
||||
while i < len(sys.argv):
|
||||
if sys.argv[i] == '-o':
|
||||
file_apng = sys.argv[i + 1]
|
||||
i += 2
|
||||
elif sys.argv[i] == '-np':
|
||||
np = int(sys.argv[i + 1])
|
||||
i += 2
|
||||
elif sys.argv[i] == '-dn':
|
||||
dn = int(sys.argv[i + 1])
|
||||
i += 2
|
||||
elif sys.argv[i] == '-dd':
|
||||
dd = int(sys.argv[i + 1])
|
||||
i += 2
|
||||
elif sys.argv[i] == '-h' or sys.argv[i] == '--help':
|
||||
usage()
|
||||
sys.exit()
|
||||
else:
|
||||
file_pngs.append(sys.argv[i])
|
||||
i += 1
|
||||
|
||||
if file_apng == '' or file_pngs == []:
|
||||
usage()
|
||||
sys.exit()
|
||||
|
||||
f_apng = file(file_apng, 'wb')
|
||||
|
||||
nf = len(file_pngs) # number of frames
|
||||
|
||||
dop = 1 # APNG_DISPOSE_OP_BACKGROUND
|
||||
bop = 0 # APNG_BLEND_OP_SOURCE
|
||||
|
||||
PNG_header_write (f_apng)
|
||||
|
||||
|
||||
ns = 0 # number of sequence
|
||||
|
||||
# first frame
|
||||
f_png = file(file_pngs[0], 'rb')
|
||||
PNG_header_read (f_png)
|
||||
|
||||
w0 = 0
|
||||
h0 = 0
|
||||
d0 = 0
|
||||
col0 = 0
|
||||
comp0 = 0
|
||||
filt0 = 0
|
||||
intl0 = 0
|
||||
|
||||
while 1:
|
||||
name, data, crc = PNG_chunk_read (f_png)
|
||||
if name == 'IEND':
|
||||
break
|
||||
elif name == 'IHDR':
|
||||
w0, h0, d0, col0, comp0, filt0, intl0 = PNG_IHDR_parse (data)
|
||||
PNG_IHDR_write (f_apng, w0, h0, d0, col0, comp0, filt0, intl0)
|
||||
# acTL
|
||||
PNG_acTL_write (f_apng, nf, np)
|
||||
# fcTL
|
||||
PNG_fcTL_write (f_apng, ns, w0, h0, 0, 0, dn, dd, dop, bop)
|
||||
ns += 1
|
||||
elif name == 'IDAT':
|
||||
# IDAT
|
||||
PNG_chunk_write (f_apng, name, data)
|
||||
|
||||
f_png.close()
|
||||
|
||||
|
||||
# the following frames
|
||||
for i in range(1, len(file_pngs)):
|
||||
f_png = file(file_pngs[i], 'rb')
|
||||
PNG_header_read (f_png)
|
||||
|
||||
while 1:
|
||||
name, data, crc = PNG_chunk_read (f_png)
|
||||
if name == 'IEND':
|
||||
break
|
||||
elif name == 'IHDR':
|
||||
w, h, d, col, comp, filt, intl = PNG_IHDR_parse (data)
|
||||
if w != w0 or h != h0 or d != d0 or col != col0 or comp != comp0 or filt != filt0 or intl != intl0:
|
||||
print('something is wrong...')
|
||||
# fcTL
|
||||
PNG_fcTL_write (f_apng, ns, w0, h0, 0, 0, dn, dd, dop, bop)
|
||||
ns += 1
|
||||
elif name == 'IDAT':
|
||||
# fdAT
|
||||
PNG_fdAT_write (f_apng, ns, data)
|
||||
ns += 1
|
||||
|
||||
f_png.close()
|
||||
|
||||
# IEND
|
||||
name = 'IEND'
|
||||
data = ''
|
||||
PNG_chunk_write (f_apng, name, data)
|
||||
|
||||
f_apng.close()
|
||||
|
||||
sys.exit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,47 +0,0 @@
|
||||
'''
|
||||
Created on Feb 23, 2013
|
||||
|
||||
@author: Rob
|
||||
'''
|
||||
import sys
|
||||
# NORTH, SOUTH, EAST, and WEST are just #define statements built in DM.
|
||||
# They represent 1, 2, 4, and 8
|
||||
|
||||
NORTH = 1
|
||||
SOUTH = 2
|
||||
EAST = 4
|
||||
WEST = 8
|
||||
|
||||
IMAGE_INDICES=[
|
||||
SOUTH,
|
||||
NORTH,
|
||||
EAST,
|
||||
WEST,
|
||||
(SOUTH|EAST),
|
||||
(SOUTH|WEST),
|
||||
(NORTH|EAST),
|
||||
(NORTH|WEST)
|
||||
]
|
||||
|
||||
def getDirFromName(name):
|
||||
return getattr(sys.modules[__name__],name,None)
|
||||
|
||||
def getNameFromDir(dir):
|
||||
if dir == NORTH:
|
||||
return 'NORTH'
|
||||
elif dir == SOUTH:
|
||||
return 'SOUTH'
|
||||
elif dir == EAST:
|
||||
return 'EAST'
|
||||
elif dir == WEST:
|
||||
return 'WEST'
|
||||
elif dir == (NORTH|WEST):
|
||||
return 'NORTHWEST'
|
||||
elif dir == (NORTH|EAST):
|
||||
return 'NORTHEAST'
|
||||
elif dir == (SOUTH|EAST):
|
||||
return 'SOUTHEAST'
|
||||
elif dir == (SOUTH|WEST):
|
||||
return 'SOUTHWEST'
|
||||
else:
|
||||
return 'UNKNOWN (%d)' %dir
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,245 +0,0 @@
|
||||
'''
|
||||
Handy for doing palette-swaps.
|
||||
|
||||
mkmetroid --analyze metroid
|
||||
mkmetroid --generate-tpl standard.metroid metroid
|
||||
mkmetroid --make standard.metroid
|
||||
'''
|
||||
import os, argparse, math, numpy
|
||||
|
||||
from DMI import DMI
|
||||
from PIL import Image, ImageColor
|
||||
import colorsys
|
||||
|
||||
def main():
|
||||
opt = argparse.ArgumentParser()
|
||||
opt.add_argument('-A', '--analyze', dest='analyze', help='Examine a file named [arg].template.dmi and create a differential pallette')
|
||||
opt.add_argument('-p', '--primary-colors', dest='colors', action='append')
|
||||
opt.add_argument('-s', '--swap', nargs=2, dest='swap', action=SwapAction)
|
||||
opt.add_argument('-C', '--change-palette', nargs=2, dest='change_palette', help='Swap palette of a file named [arg].template.dmi, given a list of --swaps.')
|
||||
|
||||
p = opt.parse_args()
|
||||
|
||||
if p.analyze:
|
||||
analyze(p)
|
||||
|
||||
if p.change_palette:
|
||||
change_palette(p)
|
||||
|
||||
def rgb_clamp(i):
|
||||
if i<0:
|
||||
return 0
|
||||
if i>255:
|
||||
return 255
|
||||
return i
|
||||
class SwapAction(argparse.Action):
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
orig = ImageColor.getrgb(values[0])
|
||||
new = None
|
||||
if values[1]!='nil':
|
||||
new = ImageColor.getrgb(values[1])
|
||||
pcolors = [(orig,new)]
|
||||
if not getattr(namespace,self.dest):
|
||||
setattr(namespace,self.dest,[])
|
||||
ogod = getattr(namespace, self.dest)
|
||||
ogod += pcolors
|
||||
print('%r -> %r' % (values, pcolors))
|
||||
|
||||
def rgbtohsv(color):
|
||||
cout = colorsys.rgb_to_hsv(color[0]/255., color[1]/255., color[2]/255.)
|
||||
return (int(cout[0]*255),int(cout[1]*255),int(cout[2]*255))
|
||||
|
||||
def hsvtorgb(color):
|
||||
cout = colorsys.hsv_to_rgb(color[0]/255., color[1]/255., color[2]/255.)
|
||||
if len(color)==4:
|
||||
return (int(cout[0]*255),int(cout[1]*255),int(cout[2]*255),color[3])
|
||||
else:
|
||||
return (int(cout[0]*255),int(cout[1]*255),int(cout[2]*255))
|
||||
|
||||
def mkdelta(a,b):
|
||||
return ((a[0] - b[0]), (a[1] - b[1]), (a[2] - b[2]))
|
||||
|
||||
def swap_palettes(im,oldcolors,newcolors):
|
||||
data = numpy.array(im)
|
||||
r,g,b,a = data.T
|
||||
for i in range(len(oldcolors)):
|
||||
old=oldcolors[i]
|
||||
new=newcolors[i]
|
||||
if new != None:
|
||||
#selected = (r==old[0]) & (g==old[1]) & (b==old[2]) & (a==old[3])
|
||||
#data[..., :-1][selected]=new
|
||||
data[(data == old).all(axis = -1)] = new
|
||||
oldhex = '#%0.2x%0.2x%0.2x' % old[:3]
|
||||
newhex = '#%0.2x%0.2x%0.2x' % new[:3]
|
||||
print('{0} -> {1}'.format(oldhex,newhex))
|
||||
return Image.fromarray(data)
|
||||
|
||||
def change_palette(p):
|
||||
dmi_template = p.change_palette[0] + '.template.dmi'
|
||||
dmi = DMI(dmi_template)
|
||||
dmidir = 'tmp/' + os.path.basename(p.change_palette[0])
|
||||
if not os.path.exists(dmidir):
|
||||
os.makedirs(dmidir)
|
||||
|
||||
dmi.extractTo(dmidir)
|
||||
with open(p.change_palette[0] + ' report.htm', 'w') as h:
|
||||
h.write('''
|
||||
<html>
|
||||
<head>
|
||||
<title>Palette Swap Report for {0}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Palette Swap Report for {0}</h1>
|
||||
<img src="{0}" />
|
||||
<pre>{1}</pre>
|
||||
'''.format(dmi_template,dmi.statelist))
|
||||
for statename in sorted(dmi.states):
|
||||
state = dmi.states[statename]
|
||||
h.write('<h2>{0}</h2>'.format(statename))
|
||||
for iconf in state.icons:
|
||||
iconf = iconf.replace('\\', '/')
|
||||
icon = Image.open(iconf)
|
||||
cr = icon.getcolors()
|
||||
h.write('<table><tr><td rowspan="{0}"><img src="{1}"></td>'.format(len(cr), iconf))
|
||||
first = True
|
||||
oldcolors=[]
|
||||
newcolors=[]
|
||||
# First, analysis
|
||||
for ct in cr:
|
||||
(count, color) = ct
|
||||
if color[3] == 0:
|
||||
continue
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
h.write('<tr>')
|
||||
#print(repr(color))
|
||||
chex = '#%0.2x%0.2x%0.2x' % color[:3]
|
||||
h.write('<td style="background:{0};color:{0}">...</td>'.format(chex))
|
||||
alpha = ''
|
||||
if color[3] < 255:
|
||||
alpha = ' (A: {0})'.format(color[3])
|
||||
h.write('<td>{0}{1} × {2}</td>'.format(chex, alpha, count))
|
||||
found = None
|
||||
foundNew = None
|
||||
foundDelta=None
|
||||
closest = None
|
||||
print(repr(p.swap))
|
||||
for pcolor, new in p.swap:
|
||||
hsv_old = rgbtohsv(pcolor)
|
||||
hsv_current = rgbtohsv(color)
|
||||
delta = mkdelta(hsv_current,hsv_old)
|
||||
#delta = ((pcolor[0] - color[0]), (pcolor[1] - color[1]), (pcolor[2] - color[2]))
|
||||
dist = math.sqrt(delta[0] ** 2 + delta[1] ** 2 + delta[2] ** 2)
|
||||
if (closest is None or dist < closest) and math.fabs(delta[0]*255) < 25:
|
||||
closest = dist
|
||||
found = pcolor
|
||||
foundDelta = delta
|
||||
if new:
|
||||
hsv_new = rgbtohsv(new)
|
||||
#hsv_old = rgbtohsv(pcolor)
|
||||
#hsv_current = rgbtohsv(color)
|
||||
#delta = mkdelta(hsv_current,hsv_old)
|
||||
hsv_new=(rgb_clamp(hsv_new[0] + delta[0]), rgb_clamp(hsv_new[1] + delta[1]), rgb_clamp(hsv_new[2] + delta[2]), color[3])
|
||||
foundNew = hsvtorgb(hsv_new)
|
||||
else:
|
||||
foundNew = None
|
||||
if found:
|
||||
oldcolors += [color]
|
||||
newcolors += [foundNew]
|
||||
if foundNew:
|
||||
hex = '#%0.2x%0.2x%0.2x' % foundNew[:3]
|
||||
h.write('<td style="background:{0};color:{0}">...</td>'.format(hex))
|
||||
alpha = ''
|
||||
if foundNew[3] < 255:
|
||||
alpha = ' (A: {0})'.format(foundNew[3])
|
||||
h.write('<td>{0}{1} - Δ{2}</td>'.format(hex, alpha,foundDelta))
|
||||
else:
|
||||
hex = '#%0.2x%0.2x%0.2x' % found[:3]
|
||||
h.write('<td style="background:{0};color:{0}">...</td>'.format(hex))
|
||||
h.write('<td>(Ignore) - Δ{0}</td>'.format(foundDelta))
|
||||
else:
|
||||
h.write('<td colspan="2">N/A</td>')
|
||||
h.write('</tr>')
|
||||
h.write('</table><hr />')
|
||||
|
||||
# write us a new image.
|
||||
icon = swap_palettes(icon,oldcolors,newcolors)
|
||||
icon.save(iconf,'PNG')
|
||||
h.write('</body></html>')
|
||||
dmi.save(p.change_palette[1]+'.dmi')
|
||||
|
||||
def analyze(p):
|
||||
pcolors = []
|
||||
if p.colors is not None:
|
||||
for color in p.colors:
|
||||
pcolor = ImageColor.getrgb(color)
|
||||
pcolors += [pcolor]
|
||||
print('>>> Added %x%x%x' % pcolor)
|
||||
dmi_template = p.analyze + '.template.dmi'
|
||||
dmi = DMI(dmi_template)
|
||||
dmidir = 'tmp/' + os.path.basename(p.analyze)
|
||||
if not os.path.exists(dmidir):
|
||||
os.makedirs(dmidir)
|
||||
|
||||
dmi.extractTo(dmidir)
|
||||
with open(p.analyze + ' report.htm', 'w') as h:
|
||||
h.write('''
|
||||
<html>
|
||||
<head>
|
||||
<title>Color Report for {0}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Color Report for {0}</h1>
|
||||
<img src="{0}" />
|
||||
<pre>{1}</pre>
|
||||
'''.format(dmi_template,dmi.statelist))
|
||||
for statename in sorted(dmi.states):
|
||||
state = dmi.states[statename]
|
||||
h.write('<h2>{0}</h2>'.format(statename))
|
||||
for iconf in state.icons:
|
||||
iconf = iconf.replace('\\', '/')
|
||||
icon = Image.open(iconf)
|
||||
print(icon.mode)
|
||||
#icon=icon.convert()
|
||||
newicon = Image.new("RGBA", icon.size)
|
||||
newicon.paste(icon) # 3 is the alpha channel
|
||||
icon=newicon
|
||||
print(icon.mode)
|
||||
cr = icon.getcolors()
|
||||
h.write('<table><tr><td rowspan="{0}"><img src="{1}"></td>'.format(len(cr), iconf))
|
||||
first = True
|
||||
for ct in cr:
|
||||
(count, color) = ct
|
||||
if color[3] == 0:
|
||||
continue
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
h.write('<tr>')
|
||||
#print(repr(color))
|
||||
chex = '#%0.2x%0.2x%0.2x' % color[:3]
|
||||
h.write('<td style="background:{0};color:{0}">...</td>'.format(chex))
|
||||
alpha = ''
|
||||
if color[3] < 255:
|
||||
alpha = ' (A: {0})'.format(color[3])
|
||||
h.write('<td>{0}{1} × {2}</td>'.format(chex, alpha, count))
|
||||
found = None
|
||||
closest = None
|
||||
for pcolor in pcolors:
|
||||
dist = math.sqrt((pcolor[0] - color[0]) ** 2 + (pcolor[1] - color[1]) ** 2 + (pcolor[2] - color[2]) ** 2)
|
||||
if closest is None or dist < closest:
|
||||
closest = dist
|
||||
found = pcolor
|
||||
if found:
|
||||
hex = '#%0.2x%0.2x%0.2x' % found
|
||||
h.write('<td style="background:{0};color:{0}">...</td>'.format(hex))
|
||||
h.write('<td>{0} (dist:{1})</td>'.format(hex, closest))
|
||||
else:
|
||||
h.write('<td colspan="2">N/A</td>')
|
||||
h.write('</tr>')
|
||||
h.write('</table><hr />')
|
||||
h.write('</body></html>')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
1
tools/OpenBYOND
Submodule
1
tools/OpenBYOND
Submodule
Submodule tools/OpenBYOND added at 3dc0e752a8
@@ -1,306 +0,0 @@
|
||||
import os, sys, re
|
||||
"""
|
||||
Usage:
|
||||
$ python calculateMaxTechLevels.py path/to/your.dme .dm
|
||||
|
||||
calculateMaxTechLevels.py - Get techlevels of all objects and generate reports.
|
||||
|
||||
Copyright 2013 Rob "N3X15" Nelson <nexis@7chan.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
"""
|
||||
REGEX_TECH_ORIGIN = re.compile('^(?P<tabs>\t+)(?:var/)?origin_tech\s*=\s*"(?P<content>.+)"\s*$')
|
||||
REGEX_VARIABLE = re.compile('^(?P<tabs>\t+)(?:var/)?(?P<type>[a-zA-Z0-9_]*/)?(?P<variable>[a-zA-Z0-9_]+)\s*=\s*(?P<qmark>[\'"])(?P<content>.+)(?P=qmark)\s*$')
|
||||
REGEX_ATOMDEF = re.compile('^(?P<tabs>\t*)(?P<atom>[a-zA-Z0-9_/]+)\s*$')
|
||||
|
||||
#Calculated Max Tech Levels.
|
||||
CMTLs = {}
|
||||
|
||||
# All known atoms with tech origins.
|
||||
AtomTechOrigins = {}
|
||||
Atoms={}
|
||||
Nodes={}
|
||||
|
||||
class BYONDFileRef:
|
||||
"""
|
||||
Just to format file references differently.
|
||||
"""
|
||||
def __init__(self,string):
|
||||
self.value=string
|
||||
|
||||
def __repr__(self):
|
||||
return "'{0}'".format(self.value)
|
||||
|
||||
class BYONDString:
|
||||
"""
|
||||
Just to format file references differently.
|
||||
"""
|
||||
def __init__(self,string):
|
||||
self.value=string
|
||||
|
||||
def __repr__(self):
|
||||
return '"{0}"'.format(self.value)
|
||||
|
||||
class Atom:
|
||||
def __init__(self,path):
|
||||
self.path=path
|
||||
self.properties={}
|
||||
self.children={}
|
||||
self.parent=None
|
||||
|
||||
def InheritProperties(self):
|
||||
if self.parent:
|
||||
for key,value in self.parent.properties.items():
|
||||
if key not in self.properties:
|
||||
self.properties[key]=value
|
||||
for k in self.children.iterkeys():
|
||||
self.children[k].InheritProperties()
|
||||
|
||||
def debug(filename, line, path, message):
|
||||
print('{0}:{1}: {2} - {3}'.format(filename, line, '/'.join(path), message))
|
||||
|
||||
def ProcessFile(filename):
|
||||
with open(filename, 'r') as f:
|
||||
cpath = []
|
||||
popLevels = []
|
||||
pindent = 0 # Previous Indent
|
||||
ln = 0
|
||||
ignoreLevel = []
|
||||
debugOn = False
|
||||
for line in f:
|
||||
ln += 1
|
||||
if '/*' in line:
|
||||
ignoreLevel += ['*/']
|
||||
if '{"' in line:
|
||||
ignoreLevel += ['"}']
|
||||
if len(ignoreLevel) > 0:
|
||||
if ignoreLevel[-1] in line:
|
||||
ignoreLevel.pop()
|
||||
continue
|
||||
m = REGEX_ATOMDEF.match(line)
|
||||
if m is not None:
|
||||
numtabs = len(m.group('tabs'))
|
||||
atom = m.group('atom')
|
||||
atom_path = m.group('atom').split('/')
|
||||
|
||||
# Reserved words that show up on their own
|
||||
if atom in ('else', 'break', 'return', 'continue', 'spawn', 'proc'):
|
||||
continue
|
||||
|
||||
# Other things to ignore (false positives, comments)
|
||||
if atom.startswith('var/') or atom.startswith('//') or (numtabs > 0 and atom.strip().startswith('/')):
|
||||
continue
|
||||
|
||||
# Was used to debug a weird path resolution issue with mecha boards.
|
||||
#if line.startswith('/obj/item/weapon/circuitboard/mecha'):
|
||||
# debugOn = True
|
||||
if debugOn: print('{} > {}'.format(numtabs, line.rstrip()))
|
||||
if numtabs == 0:
|
||||
cpath = atom_path
|
||||
if cpath[0] != '':
|
||||
cpath.insert(0, '')
|
||||
popLevels = [len(cpath)]
|
||||
if debugOn: debug(filename, ln, cpath, '0')
|
||||
elif numtabs > pindent:
|
||||
cpath += atom_path
|
||||
popLevels += [len(atom_path)]
|
||||
if debugOn: debug(filename, ln, cpath, '>')
|
||||
elif numtabs < pindent:
|
||||
for i in range(pindent - numtabs):
|
||||
popsToDo = popLevels.pop()
|
||||
if debugOn: print(' pop {} {}'.format(popsToDo, popLevels))
|
||||
for i in range(popsToDo):
|
||||
cpath.pop()
|
||||
if debugOn: print(repr(cpath))
|
||||
cpath += atom_path
|
||||
if debugOn: debug(filename, ln, cpath, '<')
|
||||
elif numtabs == pindent:
|
||||
for i in range(popLevels.pop()):
|
||||
cpath.pop()
|
||||
if debugOn: print(repr(cpath))
|
||||
cpath += atom_path
|
||||
popLevels += [len(atom_path)]
|
||||
if debugOn: debug(filename, ln, cpath, '==')
|
||||
pindent = numtabs
|
||||
continue
|
||||
path = '/'.join(cpath)
|
||||
"""
|
||||
m = REGEX_TECH_ORIGIN.match(line)
|
||||
if m is not None:
|
||||
tech_origin = {}
|
||||
# materials=9;bluespace=10;magnets=3
|
||||
techchunks = m.group('content').split(';')
|
||||
for techchunk in techchunks:
|
||||
parts = techchunk.split('=')
|
||||
tech = parts[0]
|
||||
level = int(parts[1])
|
||||
tech_origin[tech] = level
|
||||
if tech not in CMTLs:
|
||||
CMTLs[tech] = level
|
||||
if CMTLs[tech] < level:
|
||||
CMTLs[tech] = level
|
||||
AtomTechOrigins[path] = tech_origin
|
||||
"""
|
||||
m = REGEX_VARIABLE.match(line)
|
||||
if m is not None:
|
||||
if path not in Atoms:
|
||||
Atoms[path] = Atom(path)
|
||||
name=m.group('variable')
|
||||
content=m.group('content')
|
||||
qmark=m.group('qmark')
|
||||
if qmark == '"':
|
||||
Atoms[path].properties[name]=BYONDString(content)
|
||||
else:
|
||||
Atoms[path].properties[name]=BYONDFileRef(content)
|
||||
|
||||
def Nodify(root='/',parent=None):
|
||||
Branch={}
|
||||
root_path=root.split('/')
|
||||
for path in Atoms.keys():
|
||||
cpath=path.split('/')
|
||||
if path.startswith(root) and (len(cpath)-len(root_path)) == 1:
|
||||
nodeName=cpath[-1]
|
||||
Branch[nodeName]=Atoms[path]
|
||||
Branch[nodeName].parent=parent
|
||||
Branch[nodeName].children=Nodify(path,Branch[nodeName])
|
||||
return Branch
|
||||
|
||||
def MakeTree():
|
||||
AtomTree=Atom('/')
|
||||
for key in Atoms:
|
||||
atom=Atoms[key]
|
||||
cpath=[]
|
||||
cNode=AtomTree
|
||||
fullpath=atom.path.split('/')
|
||||
truncatedPath=fullpath[1:]
|
||||
for path_item in truncatedPath:
|
||||
cpath+=[path_item]
|
||||
cpath_str='/'.join(['']+cpath)
|
||||
#if path_item == 'var':
|
||||
# if path_item not in cNode.properties:
|
||||
# cNode.properties[fullpath[-1]]='???'
|
||||
if path_item not in cNode.children:
|
||||
if cpath_str in Atoms:
|
||||
cNode.children[path_item] = Atoms[cpath_str]
|
||||
else:
|
||||
cNode.children[path_item]=Atom('/'.join(['']+cpath))
|
||||
cNode.children[path_item].parent=cNode
|
||||
cNode=cNode.children[path_item]
|
||||
AtomTree.InheritProperties()
|
||||
return AtomTree
|
||||
|
||||
def ProcessTechLevels(atom,path=''):
|
||||
global CMTLs, AtomTechOrigins, path2name
|
||||
for key,val in atom.properties.iteritems():
|
||||
if key == 'name':
|
||||
path2name[path]=val.value
|
||||
elif key == 'origin_tech':
|
||||
tech_origin = {}
|
||||
# materials=9;bluespace=10;magnets=3
|
||||
techchunks = val.value.split(';')
|
||||
for techchunk in techchunks:
|
||||
parts = techchunk.split('=')
|
||||
tech = parts[0]
|
||||
level = int(parts[1])
|
||||
tech_origin[tech] = level
|
||||
if tech not in CMTLs:
|
||||
CMTLs[tech] = level
|
||||
if CMTLs[tech] < level:
|
||||
CMTLs[tech] = level
|
||||
AtomTechOrigins[path] = tech_origin
|
||||
break
|
||||
for key,child in atom.children.iteritems():
|
||||
ProcessTechLevels(child,path+'/'+key)
|
||||
|
||||
def prettify(tree, indent=0):
|
||||
prefix=' '*indent
|
||||
for key in tree.iterkeys():
|
||||
atom=tree[key]
|
||||
print('{}{}/'.format(prefix,key))
|
||||
prettify(atom.children,indent+len(key))
|
||||
for propkey,value in atom.properties.iteritems():
|
||||
print('{}var/{} = {}'.format(' '*(indent+len(key)),propkey,repr(value)))
|
||||
|
||||
def ProcessFilesFromDME(dmefile='baystation12.dme', ext='.dm'):
|
||||
numFilesTotal = 0
|
||||
rootdir = os.path.dirname(dmefile)
|
||||
with open(dmefile, 'r') as dmeh:
|
||||
for line in dmeh:
|
||||
if line.startswith('#include'):
|
||||
inString = False
|
||||
# escaped=False
|
||||
filename = ''
|
||||
for c in line:
|
||||
"""
|
||||
if c == '\\' and not escaped:
|
||||
escaped = True
|
||||
continue
|
||||
if escaped:
|
||||
if
|
||||
escaped = False
|
||||
continue
|
||||
"""
|
||||
if c == '"':
|
||||
inString = not inString
|
||||
if not inString:
|
||||
filepath = os.path.join(rootdir, filename)
|
||||
if filepath.endswith(ext):
|
||||
# print('Processing {0}...'.format(filepath))
|
||||
ProcessFile(filepath)
|
||||
numFilesTotal += 1
|
||||
filename = ''
|
||||
continue
|
||||
else:
|
||||
if inString:
|
||||
filename += c
|
||||
|
||||
if os.path.isdir(sys.argv[1]):
|
||||
selectedDMEs = []
|
||||
for root, _, files in os.walk(sys.argv[1]):
|
||||
for filename in files:
|
||||
filepath = os.path.join(root, filename)
|
||||
if filepath.endswith('.dme'):
|
||||
ProcessFilesFromDME(filepath, sys.argv[2])
|
||||
selectedDMEs.append(filepath)
|
||||
break
|
||||
tree = MakeTree()
|
||||
path2name={}
|
||||
ProcessTechLevels(tree)
|
||||
with open(os.path.join(sys.argv[1], 'tech_origin_list.csv'), 'w') as w:
|
||||
with open(os.path.join(sys.argv[1], 'max_tech_origins.txt'), 'w') as mto:
|
||||
tech_columns = []
|
||||
mto.write('Calculated Max Tech Levels:\n These tech levels have been determined by parsing ALL origin_tech variables in code included by {0}.\n'.format(', '.join(selectedDMEs)))
|
||||
for tech in sorted(CMTLs.keys()):
|
||||
tech_columns.append(tech)
|
||||
mto.write('{:>15}: {}\n'.format(tech, CMTLs[tech]))
|
||||
w.write(','.join(['Atom','Name'] + tech_columns) + "\n")
|
||||
for atom in sorted(AtomTechOrigins.keys()):
|
||||
row = []
|
||||
row.append(atom)
|
||||
row.append('"'+path2name.get(atom,"").replace('"','""')+'"')
|
||||
for tech in tech_columns:
|
||||
if tech in AtomTechOrigins[atom]:
|
||||
row.append(str(AtomTechOrigins[atom][tech]))
|
||||
else:
|
||||
row.append('')
|
||||
w.write(','.join(row) + "\n")
|
||||
#prettify(tree.children)
|
||||
if os.path.isfile(sys.argv[1]):
|
||||
ProcessFilesFromDME(sys.argv[1], sys.argv[2])
|
||||
@@ -1,208 +0,0 @@
|
||||
import os, sys
|
||||
"""
|
||||
Usage:
|
||||
$ python countstrings.py path/to/your.dme .dm
|
||||
|
||||
CountStrings.py - Counts strings in DreamMaker code
|
||||
|
||||
Copyright 2013 Rob "N3X15" Nelson <nexis@7chan.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
"""
|
||||
def CountStringsIn(filename):
|
||||
with open(filename, 'r') as f:
|
||||
with open(filename + '.str', 'w') as debug:
|
||||
numStrings = 0
|
||||
inString = False
|
||||
inMegaString = False
|
||||
blockCommentLevel = 0
|
||||
embeddedLevel = 0
|
||||
lastChar = ''
|
||||
escaped = False
|
||||
buffer = ''
|
||||
while(True):
|
||||
c = f.read(1)
|
||||
if not c:
|
||||
if inString:
|
||||
print('{0}: UNTERMINATED STRING!'.format(filename))
|
||||
return numStrings
|
||||
if not inString:
|
||||
if c == '/':
|
||||
if lastChar == '/' and blockCommentLevel == 0:
|
||||
# debug.write("[LINECOMMENT:{0}]".format(f.tell()))
|
||||
# Seek to EOL.
|
||||
while(c not in '\r\n'):
|
||||
c = f.read(1)
|
||||
# debug.write("[ENDCOMMENT:{0}]".format(f.tell()))
|
||||
lastChar = ''
|
||||
continue
|
||||
if c == '*':
|
||||
if lastChar == '/':
|
||||
# debug.write("[BLOCKCOMMENT:{0}]".format(f.tell()))
|
||||
blockCommentLevel += 1
|
||||
while(blockCommentLevel > 0):
|
||||
c = f.read(1)
|
||||
if not c:
|
||||
return numStrings
|
||||
if c == '*':
|
||||
if lastChar == '/':
|
||||
blockCommentLevel += 1
|
||||
elif c == '/':
|
||||
if lastChar == '*':
|
||||
blockCommentLevel -= 1
|
||||
lastChar = c
|
||||
# debug.write("[ENDCOMMENT:{0}]".format(f.tell()))
|
||||
lastChar = ''
|
||||
continue
|
||||
elif c == '"':
|
||||
if lastChar == '{':
|
||||
# debug.write("[MEGASTRING:{0}]".format(f.tell()))
|
||||
inString = True
|
||||
inMegaString = True
|
||||
continue
|
||||
else:
|
||||
inString = True
|
||||
# debug.write("[NEWSTRING:{0}]".format(f.tell()))
|
||||
inMegaString = False
|
||||
continue
|
||||
elif c == '{':
|
||||
lastChar = c
|
||||
continue
|
||||
else:
|
||||
lastChar = c
|
||||
else:
|
||||
if c == '\\' and not escaped:
|
||||
escaped = True
|
||||
continue
|
||||
if escaped:
|
||||
escaped = False
|
||||
# debug.write("[ESCAPE:{0}]".format(repr(c)))
|
||||
if inString:
|
||||
buffer += '\\' + c
|
||||
lastChar = c
|
||||
continue
|
||||
if c in ('[', ']'):
|
||||
if c == '[':
|
||||
embeddedLevel += 1
|
||||
else:
|
||||
embeddedLevel -= 1
|
||||
buffer += c # +"<{0}>".format(str(embeddedLevel))
|
||||
lastChar = c
|
||||
continue
|
||||
if embeddedLevel > 0:
|
||||
buffer += c
|
||||
lastChar = c
|
||||
continue
|
||||
if inMegaString:
|
||||
if c == '}' and lastChar == '"':
|
||||
# debug.write("[ENDMEGASTRING]")
|
||||
inString = False
|
||||
inMegaString = False
|
||||
escaped = False
|
||||
numStrings += 1
|
||||
debug.write("\n[{0}]={1}".format(numStrings, repr(buffer)))
|
||||
buffer = ''
|
||||
continue
|
||||
else:
|
||||
if c == '"':
|
||||
inString = False
|
||||
# debug.write("[ENDSTRING:{0}]".format(f.tell()))
|
||||
numStrings += 1
|
||||
escaped = False
|
||||
debug.write("\n[{0}]={1}".format(numStrings, repr(buffer)))
|
||||
buffer = ''
|
||||
continue
|
||||
buffer += c
|
||||
lastChar = c
|
||||
return numStrings
|
||||
|
||||
def ProcessFiles(top='.', ext='.dm'):
|
||||
numStringsTotal = 0
|
||||
numStrings = 0
|
||||
numFilesTotal = 0
|
||||
maxStringsInFile = [0, '']
|
||||
for root, _, files in os.walk(top):
|
||||
for filename in files:
|
||||
filepath = os.path.join(root, filename)
|
||||
if filepath.endswith(ext):
|
||||
numStrings = CountStringsIn(filepath)
|
||||
numStringsTotal += numStrings
|
||||
if numStrings > maxStringsInFile[0]:
|
||||
maxStringsInFile = [numStrings, filepath]
|
||||
numFilesTotal += 1
|
||||
print(','.join([filepath, str(numStrings)]))
|
||||
print('>>> Total Strings: {0}'.format(numStringsTotal))
|
||||
print('>>> Total Files: {0}'.format(numFilesTotal))
|
||||
print('>>> Max Strings: {0} in {1}'.format(maxStringsInFile[0], maxStringsInFile[1]))
|
||||
|
||||
def ProcessFilesFromDME(dmefile='baystation12.dme', ext='.dm'):
|
||||
numStringsTotal = 0
|
||||
numStrings = 0
|
||||
numFilesTotal = 0
|
||||
maxStringsInFile = [0, '']
|
||||
rootdir = os.path.dirname(dmefile)
|
||||
with open(os.path.join(rootdir, 'stringcounts.csv'), 'w') as csv:
|
||||
with open(dmefile, 'r') as dmeh:
|
||||
for line in dmeh:
|
||||
if line.startswith('#include'):
|
||||
inString = False
|
||||
# escaped=False
|
||||
filename = ''
|
||||
for c in line:
|
||||
"""
|
||||
if c == '\\' and not escaped:
|
||||
escaped = True
|
||||
continue
|
||||
if escaped:
|
||||
if
|
||||
escaped = False
|
||||
continue
|
||||
"""
|
||||
if c == '"':
|
||||
inString = not inString
|
||||
if not inString:
|
||||
filepath = os.path.join(rootdir, filename)
|
||||
if filepath.endswith(ext):
|
||||
numStrings = CountStringsIn(filepath)
|
||||
numStringsTotal += numStrings
|
||||
if numStrings > maxStringsInFile[0]:
|
||||
maxStringsInFile = [numStrings, filepath]
|
||||
numFilesTotal += 1
|
||||
csv.write(','.join([filepath, str(numStrings)]) + "\n")
|
||||
filename = ''
|
||||
continue
|
||||
else:
|
||||
if inString:
|
||||
filename += c
|
||||
print('>>> Total Strings: {0}'.format(numStringsTotal))
|
||||
print('>>> Total Files: {0}'.format(numFilesTotal))
|
||||
print('>>> Max Strings: {0} in {1}'.format(maxStringsInFile[0], maxStringsInFile[1]))
|
||||
|
||||
if os.path.isdir(sys.argv[1]):
|
||||
for root, _, files in os.walk(sys.argv[1]):
|
||||
for filename in files:
|
||||
filepath = os.path.join(root, filename)
|
||||
if filepath.endswith('.dme'):
|
||||
ProcessFilesFromDME(filepath, sys.argv[2])
|
||||
sys.exit(0)
|
||||
if os.path.isfile(sys.argv[1]):
|
||||
ProcessFilesFromDME(sys.argv[1], sys.argv[2])
|
||||
# ProcessFiles(sys.argv[1], sys.argv[2])
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
import os, sys, re
|
||||
"""
|
||||
Usage:
|
||||
$ python fix_string_idiocy.py path/to/your.dme .dm
|
||||
|
||||
NOTE: NOT PERFECT, CREATES code-fixed DIRECTORY.
|
||||
*** MERGE THIS MANUALLY OR YOU WILL BREAK SHIT. ***
|
||||
|
||||
fix_string_idiocy.py - Combines multiple string append operations in DreamMaker code
|
||||
|
||||
Copyright 2013 Rob "N3X15" Nelson <nexis@7chan.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
"""
|
||||
REGEX_TO_COMBINE_AS_BLOCK = re.compile('^(?P<tabs>\t+)(?P<declaration>var/)?(?P<identifier>[A-Za-z\.]+)\s*(?P<operator>\+?)=\s*"(?P<content>.+)"\s*$')
|
||||
def ProcessFile(filename):
|
||||
fuckups = []
|
||||
with open(filename, 'r') as f:
|
||||
lastID = ''
|
||||
declaring=False
|
||||
lastLevel = 0
|
||||
lastWasAlert = False
|
||||
buffa = ''
|
||||
tempbuffa = ''
|
||||
tempfuckup = ''
|
||||
tempBackup = ''
|
||||
origIndentLevel=0
|
||||
ln = 0
|
||||
for line in f:
|
||||
ln += 1
|
||||
m = REGEX_TO_COMBINE_AS_BLOCK.match(line)
|
||||
if m is not None:
|
||||
level = m.group('tabs').count('\t')
|
||||
ID = m.group('identifier')
|
||||
content = m.group('content').strip()
|
||||
indent = '\t' * level
|
||||
#indentMore = '\t' * (level + 1)
|
||||
if ID == lastID and level == lastLevel:
|
||||
if not lastWasAlert:
|
||||
buffa += '\n' + indent + '// AUTOFIXED BY fix_string_idiocy.py'
|
||||
buffa += '\n' + indent + '// ' + tempfuckup
|
||||
buffa += '\n' + tempbuffa
|
||||
print(tempfuckup)
|
||||
fuckups.append(tempfuckup)
|
||||
msg = '{0}:{1}: {2}'.format(filename, ln, line.strip())
|
||||
print(msg)
|
||||
fuckups.append(msg)
|
||||
buffa += '\n'
|
||||
#buffa += indentMore
|
||||
buffa += content
|
||||
lastWasAlert = True
|
||||
else:
|
||||
if lastWasAlert:
|
||||
buffa += '"}'
|
||||
buffa += '\n' + ('\t'*origIndentLevel) + '// END AUTOFIX'
|
||||
buffa += '\n'
|
||||
lastWasAlert = False
|
||||
if tempBackup != '':
|
||||
buffa += tempBackup
|
||||
tempBackup = line
|
||||
tempbuffa = indent
|
||||
origIndentLevel=level
|
||||
if m.group('declaration') is None:
|
||||
tempbuffa += '{0} {2}= {{"{1}'.format(ID, content, m.group('operator'))
|
||||
else:
|
||||
tempbuffa += 'var/{0} {2}= {{"{1}'.format(ID, content, m.group('operator'))
|
||||
tempfuckup = '{0}:{1}: {2}'.format(filename, ln, line.strip())
|
||||
lastID = ID
|
||||
lastLevel = level
|
||||
else:
|
||||
if line.strip() == '':
|
||||
tempBackup += line
|
||||
continue
|
||||
if lastWasAlert:
|
||||
buffa += '"}'
|
||||
buffa += '\n' + indent + '// END AUTOFIX'
|
||||
buffa += '\n'
|
||||
lastWasAlert = False
|
||||
tempBackup = ''
|
||||
if tempBackup != '':
|
||||
buffa += tempBackup
|
||||
tempBackup = ''
|
||||
lastID = ''
|
||||
lastLevel = ''
|
||||
buffa += line
|
||||
fixpath = filename.replace('code' + os.sep, 'code-fixed' + os.sep)
|
||||
fixpath = fixpath.replace('interface' + os.sep, 'interface-fixed' + os.sep)
|
||||
fixpath = fixpath.replace('RandomZLevels' + os.sep, 'RandomZLevels-fixed' + os.sep)
|
||||
if len(fuckups) > 0:
|
||||
if not os.path.isdir(os.path.dirname(fixpath)):
|
||||
os.makedirs(os.path.dirname(fixpath))
|
||||
with open(fixpath, 'w') as fixes:
|
||||
fixes.write(buffa)
|
||||
else:
|
||||
if os.path.isfile(fixpath):
|
||||
os.remove(fixpath)
|
||||
# print(' Processed - {0} lines.'.format(ln))
|
||||
return fuckups
|
||||
|
||||
def ProcessFilesFromDME(dmefile='baystation12.dme', ext='.dm'):
|
||||
numFilesTotal = 0
|
||||
fileFuckups = {}
|
||||
rootdir = os.path.dirname(dmefile)
|
||||
with open(os.path.join(rootdir, 'stringcounts.csv'), 'w') as csv:
|
||||
with open(dmefile, 'r') as dmeh:
|
||||
for line in dmeh:
|
||||
if line.startswith('#include'):
|
||||
inString = False
|
||||
# escaped=False
|
||||
filename = ''
|
||||
for c in line:
|
||||
"""
|
||||
if c == '\\' and not escaped:
|
||||
escaped = True
|
||||
continue
|
||||
if escaped:
|
||||
if
|
||||
escaped = False
|
||||
continue
|
||||
"""
|
||||
if c == '"':
|
||||
inString = not inString
|
||||
if not inString:
|
||||
filepath = os.path.join(rootdir, filename)
|
||||
if filepath.endswith(ext):
|
||||
# print('Processing {0}...'.format(filepath))
|
||||
fileFuckups[filepath] = ProcessFile(filepath)
|
||||
numFilesTotal += 1
|
||||
filename = ''
|
||||
continue
|
||||
else:
|
||||
if inString:
|
||||
filename += c
|
||||
|
||||
if os.path.isdir(sys.argv[1]):
|
||||
for root, _, files in os.walk(sys.argv[1]):
|
||||
for filename in files:
|
||||
filepath = os.path.join(root, filename)
|
||||
if filepath.endswith('.dme'):
|
||||
ProcessFilesFromDME(filepath, sys.argv[2])
|
||||
sys.exit(0)
|
||||
if os.path.isfile(sys.argv[1]):
|
||||
ProcessFilesFromDME(sys.argv[1], sys.argv[2])
|
||||
Reference in New Issue
Block a user