diff --git a/.gitignore b/.gitignore index aa2528a7fe9..f2ce0fe4b80 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ *.lk *.backup data/ +cfg/ diff --git a/.travis.yml b/.travis.yml index e1e3e6fd726..02174a82978 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: c env: - BYOND_MAJOR="503" - BYOND_MINOR="1224" + BYOND_MAJOR="507" + BYOND_MINOR="1282" before_install: - sudo apt-get update -qq @@ -19,4 +19,5 @@ install: script: - shopt -s globstar - (! grep 'step_[xy]' maps/**/*.dmm) + - (! find nano/templates/ -type f -exec md5sum {} + | sort | uniq -D -w 32 | grep nano) - DreamMaker baystation12.dme diff --git a/baystation12.dme b/baystation12.dme index 033657f790e..daef472b358 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -16,6 +16,7 @@ #include "code\setup.dm" #include "code\stylesheet.dm" #include "code\world.dm" +#include "code\__HELPERS\datum_pool.dm" #include "code\__HELPERS\files.dm" #include "code\__HELPERS\game.dm" #include "code\__HELPERS\global_lists.dm" @@ -32,6 +33,7 @@ #include "code\__HELPERS\type2type.dm" #include "code\__HELPERS\unsorted.dm" #include "code\__HELPERS\vector.dm" +#include "code\_defines\chemical_effects.dm" #include "code\_defines\research.dm" #include "code\_onclick\adjacent.dm" #include "code\_onclick\ai.dm" @@ -50,6 +52,7 @@ #include "code\_onclick\hud\other_mobs.dm" #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" +#include "code\_onclick\hud\spell_screen_objects.dm" #include "code\ATMOSPHERICS\_atmos_setup.dm" #include "code\ATMOSPHERICS\_atmospherics_helpers.dm" #include "code\ATMOSPHERICS\atmospherics.dm" @@ -84,15 +87,12 @@ #include "code\ATMOSPHERICS\components\unary\unary_base.dm" #include "code\ATMOSPHERICS\components\unary\vent_pump.dm" #include "code\ATMOSPHERICS\components\unary\vent_scrubber.dm" -#include "code\controllers\_DynamicAreaLighting_TG.dm" #include "code\controllers\autotransfer.dm" #include "code\controllers\communications.dm" #include "code\controllers\configuration.dm" #include "code\controllers\emergency_shuttle_controller.dm" -#include "code\controllers\failsafe.dm" #include "code\controllers\hooks-defs.dm" #include "code\controllers\hooks.dm" -#include "code\controllers\lighting_controller.dm" #include "code\controllers\master_controller.dm" #include "code\controllers\shuttle_controller.dm" #include "code\controllers\subsystems.dm" @@ -103,18 +103,18 @@ #include "code\controllers\Processes\disease.dm" #include "code\controllers\Processes\emergencyShuttle.dm" #include "code\controllers\Processes\event.dm" +#include "code\controllers\Processes\garbage.dm" #include "code\controllers\Processes\inactivity.dm" -#include "code\controllers\Processes\lighting.dm" #include "code\controllers\Processes\machinery.dm" #include "code\controllers\Processes\mob.dm" #include "code\controllers\Processes\nanoui.dm" #include "code\controllers\Processes\obj.dm" #include "code\controllers\Processes\pipenet.dm" -#include "code\controllers\Processes\powernet.dm" #include "code\controllers\Processes\Shuttle.dm" #include "code\controllers\Processes\sun.dm" #include "code\controllers\Processes\supply.dm" #include "code\controllers\Processes\ticker.dm" +#include "code\controllers\Processes\turf.dm" #include "code\controllers\Processes\vote.dm" #include "code\controllers\ProcessScheduler\core\_define.dm" #include "code\controllers\ProcessScheduler\core\_stubs.dm" @@ -211,7 +211,6 @@ #include "code\game\response_team.dm" #include "code\game\shuttle_engines.dm" #include "code\game\skincmd.dm" -#include "code\game\smoothwall.dm" #include "code\game\sound.dm" #include "code\game\supplyshuttle.dm" #include "code\game\antagonist\antagonist.dm" @@ -266,9 +265,17 @@ #include "code\game\gamemodes\cult\cult.dm" #include "code\game\gamemodes\cult\cult_items.dm" #include "code\game\gamemodes\cult\cult_structures.dm" +#include "code\game\gamemodes\cult\hell_universe.dm" #include "code\game\gamemodes\cult\ritual.dm" #include "code\game\gamemodes\cult\runes.dm" #include "code\game\gamemodes\cult\talisman.dm" +#include "code\game\gamemodes\cult\cultify\mob.dm" +#include "code\game\gamemodes\cult\cultify\obj.dm" +#include "code\game\gamemodes\cult\cultify\turf.dm" +#include "code\game\gamemodes\endgame\endgame.dm" +#include "code\game\gamemodes\endgame\supermatter_cascade\blob.dm" +#include "code\game\gamemodes\endgame\supermatter_cascade\portal.dm" +#include "code\game\gamemodes\endgame\supermatter_cascade\universe.dm" #include "code\game\gamemodes\events\black_hole.dm" #include "code\game\gamemodes\events\clang.dm" #include "code\game\gamemodes\events\dust.dm" @@ -315,7 +322,9 @@ #include "code\game\machinery\bees_items.dm" #include "code\game\machinery\biogenerator.dm" #include "code\game\machinery\bioprinter.dm" +#include "code\game\machinery\bluespacerelay.dm" #include "code\game\machinery\buttons.dm" +#include "code\game\machinery\CableLayer.dm" #include "code\game\machinery\cell_charger.dm" #include "code\game\machinery\cloning.dm" #include "code\game\machinery\constructable_frame.dm" @@ -326,6 +335,7 @@ #include "code\game\machinery\doppler_array.dm" #include "code\game\machinery\flasher.dm" #include "code\game\machinery\floodlight.dm" +#include "code\game\machinery\floorlayer.dm" #include "code\game\machinery\hologram.dm" #include "code\game\machinery\holosign.dm" #include "code\game\machinery\igniter.dm" @@ -358,6 +368,7 @@ #include "code\game\machinery\turret_control.dm" #include "code\game\machinery\turrets.dm" #include "code\game\machinery\vending.dm" +#include "code\game\machinery\wall_frames.dm" #include "code\game\machinery\washing_machine.dm" #include "code\game\machinery\wishgranter.dm" #include "code\game\machinery\atmoalter\area_atmos_computer.dm" @@ -367,12 +378,7 @@ #include "code\game\machinery\atmoalter\pump.dm" #include "code\game\machinery\atmoalter\scrubber.dm" #include "code\game\machinery\bots\bots.dm" -#include "code\game\machinery\bots\cleanbot.dm" -#include "code\game\machinery\bots\ed209bot.dm" -#include "code\game\machinery\bots\floorbot.dm" -#include "code\game\machinery\bots\medbot.dm" #include "code\game\machinery\bots\mulebot.dm" -#include "code\game\machinery\bots\secbot.dm" #include "code\game\machinery\camera\camera.dm" #include "code\game\machinery\camera\camera_assembly.dm" #include "code\game\machinery\camera\motion.dm" @@ -464,6 +470,7 @@ #include "code\game\machinery\kitchen\smartfridge.dm" #include "code\game\machinery\pipe\construction.dm" #include "code\game\machinery\pipe\pipe_dispenser.dm" +#include "code\game\machinery\pipe\pipelayer.dm" #include "code\game\machinery\telecomms\broadcaster.dm" #include "code\game\machinery\telecomms\logbrowser.dm" #include "code\game\machinery\telecomms\machine_interactions.dm" @@ -504,7 +511,6 @@ #include "code\game\objects\weapons.dm" #include "code\game\objects\effects\aliens.dm" #include "code\game\objects\effects\bump_teleporter.dm" -#include "code\game\objects\effects\chemsmoke.dm" #include "code\game\objects\effects\effect_system.dm" #include "code\game\objects\effects\explosion_particles.dm" #include "code\game\objects\effects\gibs.dm" @@ -517,6 +523,9 @@ #include "code\game\objects\effects\portals.dm" #include "code\game\objects\effects\spiders.dm" #include "code\game\objects\effects\step_triggers.dm" +#include "code\game\objects\effects\chem\chemsmoke.dm" +#include "code\game\objects\effects\chem\foam.dm" +#include "code\game\objects\effects\chem\water.dm" #include "code\game\objects\effects\decals\cleanable.dm" #include "code\game\objects\effects\decals\contraband.dm" #include "code\game\objects\effects\decals\crayon.dm" @@ -539,7 +548,9 @@ #include "code\game\objects\items\bodybag.dm" #include "code\game\objects\items\contraband.dm" #include "code\game\objects\items\crayons.dm" +#include "code\game\objects\items\glassjar.dm" #include "code\game\objects\items\latexballoon.dm" +#include "code\game\objects\items\paintkit.dm" #include "code\game\objects\items\shooting_range.dm" #include "code\game\objects\items\toys.dm" #include "code\game\objects\items\trash.dm" @@ -622,7 +633,6 @@ #include "code\game\objects\items\weapons\stunbaton.dm" #include "code\game\objects\items\weapons\surgery_tools.dm" #include "code\game\objects\items\weapons\swords_axes_etc.dm" -#include "code\game\objects\items\weapons\table_rack_parts.dm" #include "code\game\objects\items\weapons\tape.dm" #include "code\game\objects\items\weapons\teleportation.dm" #include "code\game\objects\items\weapons\tools.dm" @@ -642,6 +652,7 @@ #include "code\game\objects\items\weapons\circuitboards\computer\telecomms.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\biogenerator.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\cloning.dm" +#include "code\game\objects\items\weapons\circuitboards\machinery\commsantenna.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\mining_drill.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\pacman.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\power.dm" @@ -693,7 +704,6 @@ #include "code\game\objects\structures\door_assembly.dm" #include "code\game\objects\structures\electricchair.dm" #include "code\game\objects\structures\extinguisher.dm" -#include "code\game\objects\structures\false_walls.dm" #include "code\game\objects\structures\flora.dm" #include "code\game\objects\structures\girders.dm" #include "code\game\objects\structures\grille.dm" @@ -711,7 +721,6 @@ #include "code\game\objects\structures\noticeboard.dm" #include "code\game\objects\structures\safe.dm" #include "code\game\objects\structures\signs.dm" -#include "code\game\objects\structures\tables_racks.dm" #include "code\game\objects\structures\tank_dispenser.dm" #include "code\game\objects\structures\target_stake.dm" #include "code\game\objects\structures\transit_tubes.dm" @@ -730,6 +739,7 @@ #include "code\game\objects\structures\crates_lockers\closets\job_closets.dm" #include "code\game\objects\structures\crates_lockers\closets\l3closet.dm" #include "code\game\objects\structures\crates_lockers\closets\malfunction.dm" +#include "code\game\objects\structures\crates_lockers\closets\statue.dm" #include "code\game\objects\structures\crates_lockers\closets\syndicate.dm" #include "code\game\objects\structures\crates_lockers\closets\utility_closets.dm" #include "code\game\objects\structures\crates_lockers\closets\walllocker.dm" @@ -752,13 +762,14 @@ #include "code\game\objects\structures\stool_bed_chair_nest\wheelchair.dm" #include "code\game\turfs\simulated.dm" #include "code\game\turfs\turf.dm" +#include "code\game\turfs\turf_flick_animations.dm" #include "code\game\turfs\unsimulated.dm" #include "code\game\turfs\simulated\floor.dm" #include "code\game\turfs\simulated\floor_types.dm" +#include "code\game\turfs\simulated\wall_attacks.dm" +#include "code\game\turfs\simulated\wall_icon.dm" +#include "code\game\turfs\simulated\wall_types.dm" #include "code\game\turfs\simulated\walls.dm" -#include "code\game\turfs\simulated\walls_mineral.dm" -#include "code\game\turfs\simulated\walls_misc.dm" -#include "code\game\turfs\simulated\walls_reinforced.dm" #include "code\game\turfs\space\space.dm" #include "code\game\turfs\space\transit.dm" #include "code\game\turfs\unsimulated\beach.dm" @@ -801,6 +812,7 @@ #include "code\modules\admin\verbs\deadsay.dm" #include "code\modules\admin\verbs\debug.dm" #include "code\modules\admin\verbs\diagnostics.dm" +#include "code\modules\admin\verbs\dice.dm" #include "code\modules\admin\verbs\getlogs.dm" #include "code\modules\admin\verbs\icarus.dm" #include "code\modules\admin\verbs\mapping.dm" @@ -916,13 +928,14 @@ #include "code\modules\clothing\under\syndicate.dm" #include "code\modules\clothing\under\accessories\accessory.dm" #include "code\modules\clothing\under\accessories\armband.dm" +#include "code\modules\clothing\under\accessories\badges.dm" #include "code\modules\clothing\under\accessories\holster.dm" +#include "code\modules\clothing\under\accessories\lockets.dm" #include "code\modules\clothing\under\accessories\storage.dm" #include "code\modules\clothing\under\jobs\civilian.dm" #include "code\modules\clothing\under\jobs\engineering.dm" #include "code\modules\clothing\under\jobs\medsci.dm" #include "code\modules\clothing\under\jobs\security.dm" -#include "code\modules\customitems\item_defines.dm" #include "code\modules\customitems\item_spawning.dm" #include "code\modules\detectivework\evidence.dm" #include "code\modules\detectivework\footprints_and_rag.dm" @@ -938,17 +951,21 @@ #include "code\modules\economy\Events.dm" #include "code\modules\economy\Events_Mundane.dm" #include "code\modules\economy\TradeDestinations.dm" +#include "code\modules\events\apc_damage.dm" #include "code\modules\events\blob.dm" #include "code\modules\events\brand_intelligence.dm" +#include "code\modules\events\camera_damage.dm" #include "code\modules\events\carp_migration.dm" #include "code\modules\events\comms_blackout.dm" #include "code\modules\events\communications_blackout.dm" #include "code\modules\events\disease_outbreak.dm" +#include "code\modules\events\dust.dm" #include "code\modules\events\electrical_storm.dm" #include "code\modules\events\event.dm" #include "code\modules\events\event_container.dm" #include "code\modules\events\event_dynamic.dm" #include "code\modules\events\event_manager.dm" +#include "code\modules\events\gravity.dm" #include "code\modules\events\grid_check.dm" #include "code\modules\events\infestation.dm" #include "code\modules\events\ion_storm.dm" @@ -971,6 +988,7 @@ #include "code\modules\examine\descriptions\engineering.dm" #include "code\modules\examine\descriptions\medical.dm" #include "code\modules\examine\descriptions\mobs.dm" +#include "code\modules\examine\descriptions\paperwork.dm" #include "code\modules\examine\descriptions\stacks.dm" #include "code\modules\examine\descriptions\structures.dm" #include "code\modules\examine\descriptions\turfs.dm" @@ -985,6 +1003,7 @@ #include "code\modules\genetics\side_effects.dm" #include "code\modules\holodeck\HolodeckControl.dm" #include "code\modules\holodeck\HolodeckObjects.dm" +#include "code\modules\holodeck\HolodeckPrograms.dm" #include "code\modules\hydroponics\_hydro_setup.dm" #include "code\modules\hydroponics\grown.dm" #include "code\modules\hydroponics\grown_inedible.dm" @@ -1009,11 +1028,20 @@ #include "code\modules\library\lib_items.dm" #include "code\modules\library\lib_machines.dm" #include "code\modules\library\lib_readme.dm" +#include "code\modules\lighting\_lighting_defs.dm" +#include "code\modules\lighting\light_source.dm" +#include "code\modules\lighting\lighting_atom.dm" +#include "code\modules\lighting\lighting_overlay.dm" +#include "code\modules\lighting\lighting_process.dm" +#include "code\modules\lighting\lighting_system.dm" +#include "code\modules\lighting\lighting_turf.dm" +#include "code\modules\lighting\~lighting_undefs.dm" #include "code\modules\liquid\splash_simulation.dm" #include "code\modules\maps\dmm_suite.dm" #include "code\modules\maps\reader.dm" #include "code\modules\maps\swapmaps.dm" #include "code\modules\maps\writer.dm" +#include "code\modules\materials\materials.dm" #include "code\modules\mining\abandonedcrates.dm" #include "code\modules\mining\alloys.dm" #include "code\modules\mining\coins.dm" @@ -1023,7 +1051,7 @@ #include "code\modules\mining\machine_unloading.dm" #include "code\modules\mining\mine_items.dm" #include "code\modules\mining\mine_turfs.dm" -#include "code\modules\mining\minerals.dm" +#include "code\modules\mining\mineral_effect.dm" #include "code\modules\mining\mint.dm" #include "code\modules\mining\money_bag.dm" #include "code\modules\mining\ore.dm" @@ -1050,13 +1078,24 @@ #include "code\modules\mob\typing_indicator.dm" #include "code\modules\mob\update_icons.dm" #include "code\modules\mob\dead\death.dm" +#include "code\modules\mob\dead\observer\login.dm" #include "code\modules\mob\dead\observer\logout.dm" #include "code\modules\mob\dead\observer\observer.dm" #include "code\modules\mob\dead\observer\say.dm" #include "code\modules\mob\freelook\chunk.dm" #include "code\modules\mob\freelook\eye.dm" +#include "code\modules\mob\freelook\life.dm" +#include "code\modules\mob\freelook\read_me.dm" #include "code\modules\mob\freelook\update_triggers.dm" #include "code\modules\mob\freelook\visualnet.dm" +#include "code\modules\mob\freelook\ai\cameranet.dm" +#include "code\modules\mob\freelook\ai\chunk.dm" +#include "code\modules\mob\freelook\ai\eye.dm" +#include "code\modules\mob\freelook\ai\update_triggers.dm" +#include "code\modules\mob\freelook\mask\chunk.dm" +#include "code\modules\mob\freelook\mask\cultnet.dm" +#include "code\modules\mob\freelook\mask\eye.dm" +#include "code\modules\mob\freelook\mask\update_triggers.dm" #include "code\modules\mob\language\generic.dm" #include "code\modules\mob\language\language.dm" #include "code\modules\mob\language\monkey.dm" @@ -1064,6 +1103,7 @@ #include "code\modules\mob\language\station.dm" #include "code\modules\mob\language\synthetic.dm" #include "code\modules\mob\living\damage_procs.dm" +#include "code\modules\mob\living\default_language.dm" #include "code\modules\mob\living\living.dm" #include "code\modules\mob\living\living_defense.dm" #include "code\modules\mob\living\living_defines.dm" @@ -1072,11 +1112,19 @@ #include "code\modules\mob\living\logout.dm" #include "code\modules\mob\living\say.dm" #include "code\modules\mob\living\blob\blob.dm" +#include "code\modules\mob\living\bot\bot.dm" +#include "code\modules\mob\living\bot\cleanbot.dm" +#include "code\modules\mob\living\bot\ed209bot.dm" +#include "code\modules\mob\living\bot\farmbot.dm" +#include "code\modules\mob\living\bot\floorbot.dm" +#include "code\modules\mob\living\bot\medbot.dm" +#include "code\modules\mob\living\bot\secbot.dm" #include "code\modules\mob\living\carbon\breathe.dm" #include "code\modules\mob\living\carbon\carbon.dm" #include "code\modules\mob\living\carbon\carbon_defines.dm" #include "code\modules\mob\living\carbon\carbon_powers.dm" #include "code\modules\mob\living\carbon\give.dm" +#include "code\modules\mob\living\carbon\resist.dm" #include "code\modules\mob\living\carbon\shock.dm" #include "code\modules\mob\living\carbon\viruses.dm" #include "code\modules\mob\living\carbon\alien\alien.dm" @@ -1128,6 +1176,7 @@ #include "code\modules\mob\living\carbon\human\MedicalSideEffects.dm" #include "code\modules\mob\living\carbon\human\npcs.dm" #include "code\modules\mob\living\carbon\human\say.dm" +#include "code\modules\mob\living\carbon\human\stripping.dm" #include "code\modules\mob\living\carbon\human\unarmed_attack.dm" #include "code\modules\mob\living\carbon\human\update_icons.dm" #include "code\modules\mob\living\carbon\human\whisper.dm" @@ -1172,12 +1221,6 @@ #include "code\modules\mob\living\silicon\ai\login.dm" #include "code\modules\mob\living\silicon\ai\logout.dm" #include "code\modules\mob\living\silicon\ai\say.dm" -#include "code\modules\mob\living\silicon\ai\subsystems.dm" -#include "code\modules\mob\living\silicon\ai\freelook\cameranet.dm" -#include "code\modules\mob\living\silicon\ai\freelook\chunk.dm" -#include "code\modules\mob\living\silicon\ai\freelook\eye.dm" -#include "code\modules\mob\living\silicon\ai\freelook\read_me.dm" -#include "code\modules\mob\living\silicon\ai\freelook\update_triggers.dm" #include "code\modules\mob\living\silicon\decoy\death.dm" #include "code\modules\mob\living\silicon\decoy\decoy.dm" #include "code\modules\mob\living\silicon\decoy\life.dm" @@ -1234,6 +1277,7 @@ #include "code\modules\mob\living\simple_animal\friendly\spiderbot.dm" #include "code\modules\mob\living\simple_animal\friendly\tomato.dm" #include "code\modules\mob\living\simple_animal\hostile\alien.dm" +#include "code\modules\mob\living\simple_animal\hostile\bat.dm" #include "code\modules\mob\living\simple_animal\hostile\bear.dm" #include "code\modules\mob\living\simple_animal\hostile\carp.dm" #include "code\modules\mob\living\simple_animal\hostile\creature.dm" @@ -1260,11 +1304,19 @@ #include "code\modules\nano\JSON Reader.dm" #include "code\modules\nano\JSON Writer.dm" #include "code\modules\nano\nanoexternal.dm" -#include "code\modules\nano\nanointeraction.dm" #include "code\modules\nano\nanomanager.dm" #include "code\modules\nano\nanomapgen.dm" #include "code\modules\nano\nanoui.dm" +#include "code\modules\nano\interaction\admin.dm" +#include "code\modules\nano\interaction\base.dm" +#include "code\modules\nano\interaction\contained.dm" +#include "code\modules\nano\interaction\default.dm" +#include "code\modules\nano\interaction\inventory.dm" +#include "code\modules\nano\interaction\physical.dm" +#include "code\modules\nano\interaction\self.dm" +#include "code\modules\nano\interaction\zlevel.dm" #include "code\modules\nano\modules\alarm_monitor.dm" +#include "code\modules\nano\modules\atmos_control.dm" #include "code\modules\nano\modules\crew_monitor.dm" #include "code\modules\nano\modules\human_appearance.dm" #include "code\modules\nano\modules\law_manager.dm" @@ -1346,12 +1398,14 @@ #include "code\modules\power\rust\virtual_particle_catcher.dm" #include "code\modules\power\sensors\powernet_sensor.dm" #include "code\modules\power\sensors\sensor_monitoring.dm" +#include "code\modules\power\singularity\act.dm" #include "code\modules\power\singularity\collector.dm" #include "code\modules\power\singularity\containment_field.dm" #include "code\modules\power\singularity\emitter.dm" #include "code\modules\power\singularity\field_generator.dm" #include "code\modules\power\singularity\generator.dm" #include "code\modules\power\singularity\investigate.dm" +#include "code\modules\power\singularity\narsie.dm" #include "code\modules\power\singularity\singularity.dm" #include "code\modules\power\singularity\particle_accelerator\particle.dm" #include "code\modules\power\singularity\particle_accelerator\particle_accelerator.dm" @@ -1400,11 +1454,16 @@ #include "code\modules\reagents\Chemistry-Holder.dm" #include "code\modules\reagents\Chemistry-Machinery.dm" #include "code\modules\reagents\Chemistry-Readme.dm" -#include "code\modules\reagents\Chemistry-Reagents-Antidepressants.dm" #include "code\modules\reagents\Chemistry-Reagents.dm" #include "code\modules\reagents\Chemistry-Recipes.dm" #include "code\modules\reagents\reagent_containers.dm" #include "code\modules\reagents\reagent_dispenser.dm" +#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Core.dm" +#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Dispenser.dm" +#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Food-Drinks.dm" +#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Medicine.dm" +#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Other.dm" +#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Toxins.dm" #include "code\modules\reagents\dispenser\_defines.dm" #include "code\modules\reagents\dispenser\cartridge.dm" #include "code\modules\reagents\dispenser\cartridge_presets.dm" @@ -1418,7 +1477,6 @@ #include "code\modules\reagents\reagent_containers\glass.dm" #include "code\modules\reagents\reagent_containers\hypospray.dm" #include "code\modules\reagents\reagent_containers\pill.dm" -#include "code\modules\reagents\reagent_containers\robodropper.dm" #include "code\modules\reagents\reagent_containers\spray.dm" #include "code\modules\reagents\reagent_containers\syringes.dm" #include "code\modules\reagents\reagent_containers\food\cans.dm" @@ -1488,8 +1546,6 @@ #include "code\modules\research\xenoarchaeology\finds\finds_misc.dm" #include "code\modules\research\xenoarchaeology\finds\finds_special.dm" #include "code\modules\research\xenoarchaeology\finds\finds_talkingitem.dm" -#include "code\modules\research\xenoarchaeology\genetics\prehistoric_animals.dm" -#include "code\modules\research\xenoarchaeology\genetics\reconstitutor.dm" #include "code\modules\research\xenoarchaeology\machinery\artifact_analyser.dm" #include "code\modules\research\xenoarchaeology\machinery\artifact_harvester.dm" #include "code\modules\research\xenoarchaeology\machinery\artifact_scanner.dm" @@ -1544,24 +1600,39 @@ #include "code\modules\shuttles\shuttle_specops.dm" #include "code\modules\shuttles\shuttle_supply.dm" #include "code\modules\shuttles\shuttles_multi.dm" -#include "code\modules\spells\area_teleport.dm" -#include "code\modules\spells\conjure.dm" -#include "code\modules\spells\dumbfire.dm" -#include "code\modules\spells\emplosion.dm" -#include "code\modules\spells\ethereal_jaunt.dm" -#include "code\modules\spells\explosion.dm" -#include "code\modules\spells\genetic.dm" -#include "code\modules\spells\horsemask.dm" -#include "code\modules\spells\inflict_handler.dm" -#include "code\modules\spells\knock.dm" -#include "code\modules\spells\mind_transfer.dm" -#include "code\modules\spells\projectile.dm" -#include "code\modules\spells\spell.dm" +#include "code\modules\spells\artifacts.dm" +#include "code\modules\spells\construct_spells.dm" +#include "code\modules\spells\no_clothes.dm" +#include "code\modules\spells\spell_code.dm" +#include "code\modules\spells\spell_projectile.dm" #include "code\modules\spells\spellbook.dm" -#include "code\modules\spells\trigger.dm" -#include "code\modules\spells\turf_teleport.dm" -#include "code\modules\spells\wizard_artifacts.dm" -#include "code\modules\spells\wizard_spells.dm" +#include "code\modules\spells\spells.dm" +#include "code\modules\spells\aoe_turf\aoe_turf.dm" +#include "code\modules\spells\aoe_turf\blink.dm" +#include "code\modules\spells\aoe_turf\charge.dm" +#include "code\modules\spells\aoe_turf\disable_tech.dm" +#include "code\modules\spells\aoe_turf\knock.dm" +#include "code\modules\spells\aoe_turf\smoke.dm" +#include "code\modules\spells\aoe_turf\summons.dm" +#include "code\modules\spells\aoe_turf\conjure\conjure.dm" +#include "code\modules\spells\aoe_turf\conjure\construct.dm" +#include "code\modules\spells\aoe_turf\conjure\forcewall.dm" +#include "code\modules\spells\general\area_teleport.dm" +#include "code\modules\spells\general\rune_write.dm" +#include "code\modules\spells\targeted\disintegrate.dm" +#include "code\modules\spells\targeted\ethereal_jaunt.dm" +#include "code\modules\spells\targeted\flesh_to_stone.dm" +#include "code\modules\spells\targeted\genetic.dm" +#include "code\modules\spells\targeted\harvest.dm" +#include "code\modules\spells\targeted\horsemask.dm" +#include "code\modules\spells\targeted\mind_transfer.dm" +#include "code\modules\spells\targeted\shift.dm" +#include "code\modules\spells\targeted\subjugate.dm" +#include "code\modules\spells\targeted\targeted.dm" +#include "code\modules\spells\targeted\projectile\dumbfire.dm" +#include "code\modules\spells\targeted\projectile\fireball.dm" +#include "code\modules\spells\targeted\projectile\magic_missile.dm" +#include "code\modules\spells\targeted\projectile\projectile.dm" #include "code\modules\supermatter\supermatter.dm" #include "code\modules\surgery\bones.dm" #include "code\modules\surgery\brainrepair.dm" @@ -1576,6 +1647,12 @@ #include "code\modules\surgery\robolimbs.dm" #include "code\modules\surgery\slimes.dm" #include "code\modules\surgery\surgery.dm" +#include "code\modules\tables\flipping.dm" +#include "code\modules\tables\interactions.dm" +#include "code\modules\tables\presets.dm" +#include "code\modules\tables\rack.dm" +#include "code\modules\tables\tables.dm" +#include "code\modules\tables\update_triggers.dm" #include "code\modules\vehicles\cargo_train.dm" #include "code\modules\vehicles\train.dm" #include "code\modules\vehicles\vehicle.dm" diff --git a/code/ATMOSPHERICS/_atmospherics_helpers.dm b/code/ATMOSPHERICS/_atmospherics_helpers.dm index 1f73566fbce..f85fa84b933 100644 --- a/code/ATMOSPHERICS/_atmospherics_helpers.dm +++ b/code/ATMOSPHERICS/_atmospherics_helpers.dm @@ -29,8 +29,6 @@ if (source.total_moles < MINIMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing return -1 - //var/source_moles_initial = source.total_moles - if (isnull(transfer_moles)) transfer_moles = source.total_moles else @@ -69,6 +67,40 @@ return power_draw +//Gas 'pumping' proc for the case where the gas flow is passive and driven entirely by pressure differences (but still one-way). +/proc/pump_gas_passive(var/obj/machinery/M, var/datum/gas_mixture/source, var/datum/gas_mixture/sink, var/transfer_moles = null) + if (source.total_moles < MINIMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing + return -1 + + if (isnull(transfer_moles)) + transfer_moles = source.total_moles + else + transfer_moles = min(source.total_moles, transfer_moles) + + var/equalize_moles = calculate_equalize_moles(source, sink) + transfer_moles = min(transfer_moles, equalize_moles) + + if (transfer_moles < MINIMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing + return -1 + + //Update flow rate meter + if (istype(M, /obj/machinery/atmospherics)) + var/obj/machinery/atmospherics/A = M + A.last_flow_rate = (transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here + if (A.debug) + A.visible_message("[A]: moles transferred = [transfer_moles] mol") + + if (istype(M, /obj/machinery/portable_atmospherics)) + var/obj/machinery/portable_atmospherics/P = M + P.last_flow_rate = (transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here + + var/datum/gas_mixture/removed = source.remove(transfer_moles) + if(!removed) //Just in case + return -1 + sink.merge(removed) + + return 0 + //Generalized gas scrubbing proc. //Selectively moves specified gasses one gas_mixture to another and returns the amount of power needed (assuming 1 second), or -1 if no gas was filtered. //filtering - A list of gasids to be scrubbed from source @@ -392,12 +424,34 @@ return specific_power //Calculates the APPROXIMATE amount of moles that would need to be transferred to change the pressure of sink by pressure_delta -//If set, sink_volume_mod adjusts the effective output volume used in the calculation. This is useful when the output gas_mixture is +//If set, sink_volume_mod adjusts the effective output volume used in the calculation. This is useful when the output gas_mixture is //part of a pipenetwork, and so it's volume isn't representative of the actual volume since the gas will be shared across the pipenetwork when it processes. /proc/calculate_transfer_moles(datum/gas_mixture/source, datum/gas_mixture/sink, var/pressure_delta, var/sink_volume_mod=0) - //Make the approximation that the sink temperature is unchanged after transferring gas - var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature + if(source.temperature == 0 || source.total_moles == 0) return 0 + var/output_volume = (sink.volume * sink.group_multiplier) + sink_volume_mod - + var/source_total_moles = source.total_moles * source.group_multiplier + + var/air_temperature = source.temperature + if(sink.total_moles > 0 && sink.temperature > 0) + //estimate the final temperature of the sink after transfer + var/estimate_moles = pressure_delta*output_volume/(sink.temperature * R_IDEAL_GAS_EQUATION) + var/sink_heat_capacity = sink.heat_capacity() + var/transfer_heat_capacity = source.heat_capacity()*estimate_moles/source_total_moles + air_temperature = (sink.temperature*sink_heat_capacity + source.temperature*transfer_heat_capacity) / (sink_heat_capacity + transfer_heat_capacity) + //get the number of moles that would have to be transfered to bring sink to the target pressure - return pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION) \ No newline at end of file + return pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION) + +//Calculates the APPROXIMATE amount of moles that would need to be transferred to bring source and sink to the same pressure +/proc/calculate_equalize_moles(datum/gas_mixture/source, datum/gas_mixture/sink) + if(source.temperature == 0) return 0 + + //Make the approximation that the sink temperature is unchanged after transferring gas + var/source_volume = source.volume * source.group_multiplier + var/sink_volume = sink.volume * sink.group_multiplier + + var/source_pressure = source.return_pressure() + var/sink_pressure = sink.return_pressure() + + return (source_pressure - sink_pressure)/(R_IDEAL_GAS_EQUATION * (source.temperature/source_volume + sink.temperature/sink_volume)) diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm index 7d57ea6c8f8..37985034b1c 100644 --- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm +++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm @@ -44,15 +44,15 @@ obj/machinery/atmospherics/binary return null - Del() + Destroy() loc = null if(node1) node1.disconnect(src) - del(network1) + qdel(network1) if(node2) node2.disconnect(src) - del(network2) + qdel(network2) node1 = null node2 = null @@ -123,11 +123,11 @@ obj/machinery/atmospherics/binary disconnect(obj/machinery/atmospherics/reference) if(reference==node1) - del(network1) + qdel(network1) node1 = null else if(reference==node2) - del(network2) + qdel(network2) node2 = null update_icon() diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm index a4b720302b2..6627d15d738 100644 --- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm +++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm @@ -112,10 +112,10 @@ else if(node1) node1.disconnect(src) - del(network1) + qdel(network1) if(node2) node2.disconnect(src) - del(network2) + qdel(network2) node1 = null node2 = null diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 51035c5d760..7604f330639 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -80,7 +80,7 @@ transfer_moles = min(transfer_moles, calculate_transfer_moles(air1, air2, pressure_delta, (network2)? network2.volume : 0)) //pump_gas() will return a negative number if no flow occurred - returnval = pump_gas(src, air1, air2, transfer_moles, available_power=0) //available_power=0 means we only move gas if it would flow naturally + returnval = pump_gas_passive(src, air1, air2, transfer_moles) if (returnval >= 0) if(network1) @@ -258,4 +258,4 @@ "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) + qdel(src) diff --git a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm index 6923b6d31eb..aead60a3827 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm @@ -38,15 +38,15 @@ if(WEST) initialize_directions = NORTH|SOUTH - Del() + Destroy() loc = null if(node1) node1.disconnect(src) - del(network1) + qdel(network1) if(node2) node2.disconnect(src) - del(network2) + qdel(network2) node1 = null node2 = null @@ -110,10 +110,10 @@ else if(node1) node1.disconnect(src) - del(network1) + qdel(network1) if(node2) node2.disconnect(src) - del(network2) + qdel(network2) node1 = null node2 = null @@ -216,11 +216,11 @@ disconnect(obj/machinery/atmospherics/reference) if(reference==node1) - del(network1) + qdel(network1) node1 = null else if(reference==node2) - del(network2) + qdel(network2) node2 = null return null diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 87eaf9250d5..079dfb76cd0 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -235,4 +235,4 @@ Thus, the two variables affect pump operation are set in New(): "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) + qdel(src) diff --git a/code/ATMOSPHERICS/components/omni_devices/filter.dm b/code/ATMOSPHERICS/components/omni_devices/filter.dm index 3478f0f1429..b2966ef4314 100644 --- a/code/ATMOSPHERICS/components/omni_devices/filter.dm +++ b/code/ATMOSPHERICS/components/omni_devices/filter.dm @@ -24,7 +24,7 @@ for(var/datum/omni_port/P in ports) P.air.volume = ATMOS_DEFAULT_VOLUME_FILTER -/obj/machinery/atmospherics/omni/filter/Del() +/obj/machinery/atmospherics/omni/filter/Destroy() input = null output = null filters.Cut() diff --git a/code/ATMOSPHERICS/components/omni_devices/mixer.dm b/code/ATMOSPHERICS/components/omni_devices/mixer.dm index 970a33feee0..f52269ee601 100644 --- a/code/ATMOSPHERICS/components/omni_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/omni_devices/mixer.dm @@ -49,7 +49,7 @@ for(var/datum/omni_port/P in ports) P.air.volume = ATMOS_DEFAULT_VOLUME_MIXER -/obj/machinery/atmospherics/omni/mixer/Del() +/obj/machinery/atmospherics/omni/mixer/Destroy() inputs.Cut() output = null ..() diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm index 3d259ad941a..52ab44fa74e 100644 --- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm +++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm @@ -98,7 +98,7 @@ "\blue You have unfastened \the [src].", \ "You hear a ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) + qdel(src) /obj/machinery/atmospherics/omni/attack_hand(user as mob) if(..()) @@ -231,13 +231,13 @@ return null -/obj/machinery/atmospherics/omni/Del() +/obj/machinery/atmospherics/omni/Destroy() loc = null for(var/datum/omni_port/P in ports) if(P.node) P.node.disconnect(src) - del(P.network) + qdel(P.network) P.node = null ..() @@ -292,7 +292,7 @@ /obj/machinery/atmospherics/omni/disconnect(obj/machinery/atmospherics/reference) for(var/datum/omni_port/P in ports) if(reference == P.node) - del(P.network) + qdel(P.network) P.node = null P.update = 1 break diff --git a/code/ATMOSPHERICS/components/portables_connector.dm b/code/ATMOSPHERICS/components/portables_connector.dm index 315de2ce7c3..c33ff799673 100644 --- a/code/ATMOSPHERICS/components/portables_connector.dm +++ b/code/ATMOSPHERICS/components/portables_connector.dm @@ -60,7 +60,7 @@ return null -/obj/machinery/atmospherics/portables_connector/Del() +/obj/machinery/atmospherics/portables_connector/Destroy() loc = null if(connected_device) @@ -68,7 +68,7 @@ if(node) node.disconnect(src) - del(network) + qdel(network) node = null @@ -122,7 +122,7 @@ /obj/machinery/atmospherics/portables_connector/disconnect(obj/machinery/atmospherics/reference) if(reference==node) - del(network) + qdel(network) node = null update_underlays() @@ -152,4 +152,4 @@ "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) + qdel(src) diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 7a5fca0fa78..0921d1d0aa5 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -54,9 +54,6 @@ air2.volume = ATMOS_DEFAULT_VOLUME_FILTER air3.volume = ATMOS_DEFAULT_VOLUME_FILTER - if(radio_controller) - initialize() - /obj/machinery/atmospherics/trinary/filter/update_icon() if(istype(src, /obj/machinery/atmospherics/trinary/filter/m_filter)) icon_state = "m" @@ -148,7 +145,7 @@ "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) + qdel(src) /obj/machinery/atmospherics/trinary/filter/attack_hand(user as mob) // -- TLE diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index c6f5b17613e..a200de25a00 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -120,7 +120,7 @@ "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) + qdel(src) /obj/machinery/atmospherics/trinary/mixer/attack_hand(user as mob) if(..()) diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm index ff46b9b55f5..3f5d66f2620 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm @@ -52,18 +52,18 @@ obj/machinery/atmospherics/trinary return null - Del() + Destroy() loc = null if(node1) node1.disconnect(src) - del(network1) + qdel(network1) if(node2) node2.disconnect(src) - del(network2) + qdel(network2) if(node3) node3.disconnect(src) - del(network3) + qdel(network3) node1 = null node2 = null @@ -153,15 +153,15 @@ obj/machinery/atmospherics/trinary disconnect(obj/machinery/atmospherics/reference) if(reference==node1) - del(network1) + qdel(network1) node1 = null else if(reference==node2) - del(network2) + qdel(network2) node2 = null else if(reference==node3) - del(network3) + qdel(network3) node3 = null update_underlays() diff --git a/code/ATMOSPHERICS/components/tvalve.dm b/code/ATMOSPHERICS/components/tvalve.dm index 68a1036a78f..42556232bdd 100644 --- a/code/ATMOSPHERICS/components/tvalve.dm +++ b/code/ATMOSPHERICS/components/tvalve.dm @@ -101,18 +101,18 @@ return null -/obj/machinery/atmospherics/tvalve/Del() +/obj/machinery/atmospherics/tvalve/Destroy() loc = null if(node1) node1.disconnect(src) - del(network_node1) + qdel(network_node1) if(node2) node2.disconnect(src) - del(network_node2) + qdel(network_node2) if(node3) node3.disconnect(src) - del(network_node3) + qdel(network_node3) node1 = null node2 = null @@ -128,9 +128,9 @@ update_icon() if(network_node1) - del(network_node1) + qdel(network_node1) if(network_node3) - del(network_node3) + qdel(network_node3) build_network() if(network_node1&&network_node2) @@ -153,9 +153,9 @@ update_icon() if(network_node1) - del(network_node1) + qdel(network_node1) if(network_node2) - del(network_node2) + qdel(network_node2) build_network() if(network_node1&&network_node3) @@ -262,15 +262,15 @@ /obj/machinery/atmospherics/tvalve/disconnect(obj/machinery/atmospherics/reference) if(reference==node1) - del(network_node1) + qdel(network_node1) node1 = null else if(reference==node2) - del(network_node2) + qdel(network_node2) node2 = null else if(reference==node3) - del(network_node3) + qdel(network_node3) node2 = null update_underlays() @@ -366,7 +366,7 @@ "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) + qdel(src) /obj/machinery/atmospherics/tvalve/mirrored icon_state = "map_tvalvem0" diff --git a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm index 7d03ad98838..0e75146adc4 100644 --- a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm +++ b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm @@ -86,4 +86,4 @@ "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) \ No newline at end of file + qdel(src) \ No newline at end of file diff --git a/code/ATMOSPHERICS/components/unary/unary_base.dm b/code/ATMOSPHERICS/components/unary/unary_base.dm index 6635631f2dd..eea2dba1abf 100644 --- a/code/ATMOSPHERICS/components/unary/unary_base.dm +++ b/code/ATMOSPHERICS/components/unary/unary_base.dm @@ -28,12 +28,12 @@ return null - Del() + Destroy() loc = null if(node) node.disconnect(src) - del(network) + qdel(network) node = null @@ -84,7 +84,7 @@ disconnect(obj/machinery/atmospherics/reference) if(reference==node) - del(network) + qdel(network) node = null update_icon() diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index cbaeb3bf9c9..4674d522512 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -61,21 +61,30 @@ use_power = 1 icon_state = "map_vent_in" +/obj/machinery/atmospherics/unary/vent_pump/siphon/on/atmos + use_power = 1 + icon_state = "map_vent_in" + external_pressure_bound = 0 + external_pressure_bound_default = 0 + internal_pressure_bound = 2000 + internal_pressure_bound_default = 2000 + pressure_checks = 2 + pressure_checks_default = 2 + /obj/machinery/atmospherics/unary/vent_pump/New() ..() air_contents.volume = ATMOS_DEFAULT_VOLUME_PUMP icon = null initial_loc = get_area(loc) - if (initial_loc.master) - initial_loc = initial_loc.master area_uid = initial_loc.uid if (!id_tag) assign_uid() id_tag = num2text(uid) - if(ticker && ticker.current_state == 3)//if the game is running - src.initialize() - src.broadcast_status() + +/obj/machinery/atmospherics/unary/vent_pump/Destroy() + unregister_radio(src, frequency) + ..() /obj/machinery/atmospherics/unary/vent_pump/high_volume name = "Large Air Vent" @@ -214,14 +223,6 @@ return pressure_delta -//Radio remote control - -/obj/machinery/atmospherics/unary/vent_pump/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) - frequency = new_frequency - if(frequency) - radio_connection = radio_controller.add_object(src, frequency,radio_filter_in) - /obj/machinery/atmospherics/unary/vent_pump/proc/broadcast_status() if(!radio_connection) return 0 @@ -259,11 +260,12 @@ /obj/machinery/atmospherics/unary/vent_pump/initialize() ..() - //some vents work his own spesial way + //some vents work his own special way radio_filter_in = frequency==1439?(RADIO_FROM_AIRALARM):null radio_filter_out = frequency==1439?(RADIO_TO_AIRALARM):null if(frequency) - set_frequency(frequency) + radio_connection = register_radio(src, frequency, frequency, radio_filter_in) + src.broadcast_status() /obj/machinery/atmospherics/unary/vent_pump/receive_signal(datum/signal/signal) if(stat & (NOPOWER|BROKEN)) @@ -383,7 +385,6 @@ user << "You are too far away to read the gauge." if(welded) user << "It seems welded shut." - ..() /obj/machinery/atmospherics/unary/vent_pump/power_change() var/old_stat = stat @@ -415,9 +416,9 @@ "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) + qdel(src) -/obj/machinery/atmospherics/unary/vent_pump/Del() +/obj/machinery/atmospherics/unary/vent_pump/Destroy() if(initial_loc) initial_loc.air_vent_info -= id_tag initial_loc.air_vent_names -= id_tag diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index 8d88ad4db42..43874a64d93 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -36,15 +36,15 @@ icon = null initial_loc = get_area(loc) - if (initial_loc.master) - initial_loc = initial_loc.master area_uid = initial_loc.uid if (!id_tag) assign_uid() id_tag = num2text(uid) - if(ticker && ticker.current_state == 3)//if the game is running - src.initialize() - src.broadcast_status() + +/obj/machinery/atmospherics/unary/vent_scrubber/Destroy() + unregister_radio(src, frequency) + ..() + /obj/machinery/atmospherics/unary/vent_scrubber/update_icon(var/safety = 0) if(!check_icon_cache()) @@ -121,6 +121,7 @@ radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null if (frequency) set_frequency(frequency) + src.broadcast_status() /obj/machinery/atmospherics/unary/vent_scrubber/process() ..() @@ -270,16 +271,15 @@ "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) + qdel(src) /obj/machinery/atmospherics/unary/vent_scrubber/examine(mob/user) if(..(user, 1)) user << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W" else user << "You are too far away to read the gauge." - ..() -/obj/machinery/atmospherics/unary/vent_scrubber/Del() +/obj/machinery/atmospherics/unary/vent_scrubber/Destroy() if(initial_loc) initial_loc.air_scrub_info -= id_tag initial_loc.air_scrub_names -= id_tag diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm index 9cc6f7451c5..49ae4af2cf2 100644 --- a/code/ATMOSPHERICS/components/valve.dm +++ b/code/ATMOSPHERICS/components/valve.dm @@ -73,15 +73,15 @@ return null -/obj/machinery/atmospherics/valve/Del() +/obj/machinery/atmospherics/valve/Destroy() loc = null if(node1) node1.disconnect(src) - del(network_node1) + qdel(network_node1) if(node2) node2.disconnect(src) - del(network_node2) + qdel(network_node2) node1 = null node2 = null @@ -113,9 +113,9 @@ update_icon() if(network_node1) - del(network_node1) + qdel(network_node1) if(network_node2) - del(network_node2) + qdel(network_node2) build_network() @@ -214,11 +214,11 @@ /obj/machinery/atmospherics/valve/disconnect(obj/machinery/atmospherics/reference) if(reference==node1) - del(network_node1) + qdel(network_node1) node1 = null else if(reference==node2) - del(network_node2) + qdel(network_node2) node2 = null update_underlays() @@ -310,7 +310,7 @@ "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) + qdel(src) /obj/machinery/atmospherics/valve/examine(mob/user) ..() diff --git a/code/ATMOSPHERICS/datum_pipe_network.dm b/code/ATMOSPHERICS/datum_pipe_network.dm index 4098c15c31b..7fe586733ca 100644 --- a/code/ATMOSPHERICS/datum_pipe_network.dm +++ b/code/ATMOSPHERICS/datum_pipe_network.dm @@ -31,7 +31,7 @@ datum/pipe_network //Notes: Assuming that members will add themselves to appropriate roster in network_expand() if(!start_normal) - del(src) + qdel(src) start_normal.network_expand(src, reference) @@ -40,7 +40,7 @@ datum/pipe_network if((normal_members.len>0)||(line_members.len>0)) pipe_networks += src else - del(src) + qdel(src) proc/merge(datum/pipe_network/giver) if(giver==src) return 0 diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index 662376e9b4d..f4f4e379905 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -9,13 +9,13 @@ datum/pipeline var/alert_pressure = 0 - Del() + Destroy() if(network) - del(network) + qdel(network) if(air && air.volume) temporarily_store_air() - del(air) + qdel(air) ..() diff --git a/code/ATMOSPHERICS/he_pipes.dm b/code/ATMOSPHERICS/he_pipes.dm index cb11410f865..d78bb828e24 100644 --- a/code/ATMOSPHERICS/he_pipes.dm +++ b/code/ATMOSPHERICS/he_pipes.dm @@ -44,7 +44,7 @@ obj/machinery/atmospherics/pipe/simple/heat_exchanging node2 = target break if(!node1 && !node2) - del(src) + qdel(src) return update_icon() @@ -141,7 +141,7 @@ obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction break if(!node1&&!node2) - del(src) + qdel(src) return update_icon() diff --git a/code/ATMOSPHERICS/mainspipe.dm b/code/ATMOSPHERICS/mainspipe.dm index d70d2bc53e5..a381b28c37f 100644 --- a/code/ATMOSPHERICS/mainspipe.dm +++ b/code/ATMOSPHERICS/mainspipe.dm @@ -99,7 +99,7 @@ obj/machinery/atmospherics/mains_pipe for(var/obj/machinery/atmospherics/pipe/mains_component/node in nodes) node.disconnect() - Del() + Destroy() disconnect() ..() @@ -152,7 +152,7 @@ obj/machinery/atmospherics/mains_pipe/simple else if(!nodes[1]&&!nodes[2]) - del(src) //TODO: silent deleting looks weird + qdel(src) //TODO: silent deleting looks weird var/have_node1 = nodes[1]?1:0 var/have_node2 = nodes[2]?1:0 icon_state = "exposed[have_node1][have_node2][invisibility ? "-f" : "" ]" diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index 92ad93c7d09..2315e856fd1 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -30,7 +30,7 @@ /obj/machinery/atmospherics/pipe/proc/check_pressure(pressure) //Return 1 if parent should continue checking other pipes - //Return null if parent should stop checking other pipes. Recall: del(src) will by default return null + //Return null if parent should stop checking other pipes. Recall: qdel(src) will by default return null return 1 @@ -62,8 +62,8 @@ return parent.return_network(reference) -/obj/machinery/atmospherics/pipe/Del() - del(parent) +/obj/machinery/atmospherics/pipe/Destroy() + qdel(parent) if(air_temporary) loc.assume_air(air_temporary) @@ -101,8 +101,8 @@ for (var/obj/machinery/meter/meter in T) if (meter.target == src) new /obj/item/pipe_meter(T) - del(meter) - del(src) + qdel(meter) + qdel(src) /obj/machinery/atmospherics/proc/change_color(var/new_color) //only pass valid pipe colors please ~otherwise your pipe will turn invisible @@ -219,7 +219,7 @@ var/datum/effect/effect/system/smoke_spread/smoke = new smoke.set_up(1,0, src.loc, 0) smoke.start() - del(src) + qdel(src) /obj/machinery/atmospherics/pipe/simple/proc/normalize_dir() if(dir==3) @@ -227,7 +227,7 @@ else if(dir==12) set_dir(4) -/obj/machinery/atmospherics/pipe/simple/Del() +/obj/machinery/atmospherics/pipe/simple/Destroy() if(node1) node1.disconnect(src) if(node2) @@ -260,8 +260,8 @@ for (var/obj/machinery/meter/meter in T) if (meter.target == src) new /obj/item/pipe_meter(T) - del(meter) - del(src) + qdel(meter) + qdel(src) else if(node1 && node2) overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]intact[icon_connect_type]") else @@ -294,7 +294,7 @@ break if(!node1 && !node2) - del(src) + qdel(src) return var/turf/T = get_turf(src) @@ -305,12 +305,12 @@ /obj/machinery/atmospherics/pipe/simple/disconnect(obj/machinery/atmospherics/reference) if(reference == node1) if(istype(node1, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node1 = null if(reference == node2) if(istype(node2, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node2 = null update_icon() @@ -459,7 +459,7 @@ else . = PROCESS_KILL -/obj/machinery/atmospherics/pipe/manifold/Del() +/obj/machinery/atmospherics/pipe/manifold/Destroy() if(node1) node1.disconnect(src) if(node2) @@ -472,17 +472,17 @@ /obj/machinery/atmospherics/pipe/manifold/disconnect(obj/machinery/atmospherics/reference) if(reference == node1) if(istype(node1, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node1 = null if(reference == node2) if(istype(node2, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node2 = null if(reference == node3) if(istype(node3, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node3 = null update_icon() @@ -511,8 +511,8 @@ for (var/obj/machinery/meter/meter in T) if (meter.target == src) new /obj/item/pipe_meter(T) - del(meter) - del(src) + qdel(meter) + qdel(src) else overlays.Cut() overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type) @@ -578,7 +578,7 @@ break if(!node1 && !node2 && !node3) - del(src) + qdel(src) return var/turf/T = get_turf(src) @@ -701,7 +701,7 @@ else . = PROCESS_KILL -/obj/machinery/atmospherics/pipe/manifold4w/Del() +/obj/machinery/atmospherics/pipe/manifold4w/Destroy() if(node1) node1.disconnect(src) if(node2) @@ -716,22 +716,22 @@ /obj/machinery/atmospherics/pipe/manifold4w/disconnect(obj/machinery/atmospherics/reference) if(reference == node1) if(istype(node1, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node1 = null if(reference == node2) if(istype(node2, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node2 = null if(reference == node3) if(istype(node3, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node3 = null if(reference == node4) if(istype(node4, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node4 = null update_icon() @@ -762,8 +762,8 @@ for (var/obj/machinery/meter/meter in T) if (meter.target == src) new /obj/item/pipe_meter(T) - del(meter) - del(src) + qdel(meter) + qdel(src) else overlays.Cut() overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type) @@ -837,7 +837,7 @@ break if(!node1 && !node2 && !node3 && !node4) - del(src) + qdel(src) return var/turf/T = get_turf(src) @@ -958,7 +958,7 @@ ..() else . = PROCESS_KILL -/obj/machinery/atmospherics/pipe/cap/Del() +/obj/machinery/atmospherics/pipe/cap/Destroy() if(node) node.disconnect(src) @@ -967,7 +967,7 @@ /obj/machinery/atmospherics/pipe/cap/disconnect(obj/machinery/atmospherics/reference) if(reference == node) if(istype(node, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node = null update_icon() @@ -1074,7 +1074,7 @@ else . = PROCESS_KILL -/obj/machinery/atmospherics/pipe/tank/Del() +/obj/machinery/atmospherics/pipe/tank/Destroy() if(node1) node1.disconnect(src) @@ -1108,7 +1108,7 @@ /obj/machinery/atmospherics/pipe/tank/disconnect(obj/machinery/atmospherics/reference) if(reference == node1) if(istype(node1, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node1 = null update_underlays() @@ -1258,7 +1258,7 @@ else parent.mingle_with_turf(loc, volume) -/obj/machinery/atmospherics/pipe/vent/Del() +/obj/machinery/atmospherics/pipe/vent/Destroy() if(node1) node1.disconnect(src) @@ -1290,7 +1290,7 @@ /obj/machinery/atmospherics/pipe/vent/disconnect(obj/machinery/atmospherics/reference) if(reference == node1) if(istype(node1, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node1 = null update_icon() diff --git a/code/FEA/DEBUG_REMOVE_BEFORE_RELEASE.dm b/code/FEA/DEBUG_REMOVE_BEFORE_RELEASE.dm index 4c173b7b7ea..7374963fba8 100644 --- a/code/FEA/DEBUG_REMOVE_BEFORE_RELEASE.dm +++ b/code/FEA/DEBUG_REMOVE_BEFORE_RELEASE.dm @@ -342,7 +342,7 @@ obj/machinery/atmospherics set src in world set category = "Minor" - del(src) + qdel(src) pipeline_data() set src in world @@ -487,7 +487,7 @@ obj/window destroy() set category = "Minor" set src in world - del(src) + qdel(src) mob sight = SEE_OBJS|SEE_TURFS diff --git a/code/FEA/FEA_fire.dm b/code/FEA/FEA_fire.dm index b7a8d42fa5e..fe18350da04 100644 --- a/code/FEA/FEA_fire.dm +++ b/code/FEA/FEA_fire.dm @@ -171,7 +171,7 @@ return /* -/obj/effect/hotspot/Del() +/obj/effect/hotspot/Destroy() if (istype(loc, /turf/simulated)) DestroyTurf() ..() diff --git a/code/FEA/FEA_gas_mixture.dm b/code/FEA/FEA_gas_mixture.dm index 6beeffc1870..a2a1af194e4 100644 --- a/code/FEA/FEA_gas_mixture.dm +++ b/code/FEA/FEA_gas_mixture.dm @@ -346,7 +346,7 @@ What are the archived variables for? trace_gases += corresponding corresponding.moles += trace_gas.moles*giver.group_multiplier/group_multiplier - // del(giver) + // qdel(giver) return 1 remove(amount) diff --git a/code/FEA/FEA_system.dm b/code/FEA/FEA_system.dm index 574fd1ba268..6a3dfe0f8b2 100644 --- a/code/FEA/FEA_system.dm +++ b/code/FEA/FEA_system.dm @@ -291,7 +291,7 @@ datum var/turf/simulated/T = turf T.parent = null turfs += T - del(turf_AG) + qdel(turf_AG) for(var/turf/simulated/S in turfs) //Have old members try to form new groups if(!S.parent) @@ -306,7 +306,7 @@ datum for(var/obj/movable/floor/OM in object_AG.members) OM.parent = null movable_objects += OM - del(object_AG) + qdel(object_AG) for(var/obj/movable/floor/OM in movable_objects) //Have old members try to form new groups if(!OM.parent) diff --git a/code/FEA/FEA_turf_tile.dm b/code/FEA/FEA_turf_tile.dm index 981d0b023c5..da7b1f856cb 100644 --- a/code/FEA/FEA_turf_tile.dm +++ b/code/FEA/FEA_turf_tile.dm @@ -14,7 +14,7 @@ atom/movable/proc/experience_pressure_difference(pressure_difference, direction) turf assume_air(datum/gas_mixture/giver) //use this for machines to adjust air - del(giver) + qdel(giver) return 0 return_air() @@ -148,7 +148,7 @@ turf/simulated if(istype(target)) air_master.tiles_to_update.Add(target) - Del() + Destroy() if(air_master) if(parent) air_master.groups_to_rebuild.Add(parent) diff --git a/code/TriDimension/Pipes.dm b/code/TriDimension/Pipes.dm index d6b87f2909e..c71255a34bd 100644 --- a/code/TriDimension/Pipes.dm +++ b/code/TriDimension/Pipes.dm @@ -45,8 +45,6 @@ obj/machinery/atmospherics/pipe/zpipe/New() initialize_directions = EAST if(SOUTHWEST) initialize_directions = SOUTH - initialize() - obj/machinery/atmospherics/pipe/zpipe/hide(var/i) if(level == 1 && istype(loc, /turf/simulated)) @@ -80,7 +78,7 @@ obj/machinery/atmospherics/pipe/zpipe/proc/burst() var/datum/effect/effect/system/smoke_spread/smoke = new smoke.set_up(1,0, src.loc, 0) smoke.start() - del(src) + qdel(src) // NOT qdel. obj/machinery/atmospherics/pipe/zpipe/proc/normalize_dir() if(dir==3) @@ -88,7 +86,7 @@ obj/machinery/atmospherics/pipe/zpipe/proc/normalize_dir() else if(dir==12) set_dir(4) -obj/machinery/atmospherics/pipe/zpipe/Del() +obj/machinery/atmospherics/pipe/zpipe/Destroy() if(node1) node1.disconnect(src) if(node2) @@ -104,12 +102,12 @@ obj/machinery/atmospherics/pipe/zpipe/update_icon() obj/machinery/atmospherics/pipe/zpipe/disconnect(obj/machinery/atmospherics/reference) if(reference == node1) if(istype(node1, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node1 = null if(reference == node2) if(istype(node2, /obj/machinery/atmospherics/pipe)) - del(parent) + qdel(parent) node2 = null return null diff --git a/code/TriDimension/Structures.dm b/code/TriDimension/Structures.dm index 554853535a7..9224facba26 100644 --- a/code/TriDimension/Structures.dm +++ b/code/TriDimension/Structures.dm @@ -41,18 +41,18 @@ switch(severity) if(1.0) if(icon_state == "ladderup" && prob(10)) - Del() + qdel(src) if(2.0) if(prob(50)) - Del() + qdel(src) if(3.0) - Del() + qdel(src) return*/ - Del() + Destroy() spawn(1) if(target && icon_state == "ladderdown") - del target + qdel(target) return ..() attackby(obj/item/C as obj, mob/user as mob) @@ -78,7 +78,7 @@ if(!blocked && !istype(below, /turf/simulated/wall)) var/obj/multiz/ladder/X = new /obj/multiz/ladder(below) S.amount = S.amount - 2 - if(S.amount == 0) S.Del() + if(S.amount == 0) qdel(S) X.icon_state = "ladderup" connect() user << "You finish the ladder." @@ -97,9 +97,9 @@ src.d_state = 1 if(target) - var/obj/item/stack/rods/R = new /obj/item/stack/rods(target.loc) + var/obj/item/stack/rods/R = PoolOrNew(/obj/item/stack/rods, target.loc) R.amount = 2 - target.Del() + qdel(Target) user << "You remove the bolts anchoring the ladder." return @@ -117,7 +117,7 @@ var/obj/item/stack/sheet/metal/S = new /obj/item/stack/sheet/metal( src ) S.amount = 2 user << "You remove the ladder and close the hole." - Del() + qdel(src) else user << "You need more welding fuel to complete this task." return @@ -167,7 +167,7 @@ attack_hand(var/mob/M) if(!target || !istype(target.loc, /turf)) - del src + qdel(src) if(active) M << "That [src] is being used." @@ -185,7 +185,7 @@ spawn(7) if(!target || !istype(target.loc, /turf)) - del src + qdel(src) if(M.z == z && get_dist(src,M) <= 1) var/list/adjacent_to_me = global_adjacent_z_levels["[z]"] M.visible_message("\blue \The [M] scurries [target.z == adjacent_to_me["up"] ? "up" : "down"] \the [src]!", "You scramble [target.z == adjacent_to_me["up"] ? "up" : "down"] \the [src]!", "You hear some grunting, and a hatch sealing.") diff --git a/code/TriDimension/Turfs.dm b/code/TriDimension/Turfs.dm index 89920680183..43e33ed3c28 100644 --- a/code/TriDimension/Turfs.dm +++ b/code/TriDimension/Turfs.dm @@ -120,7 +120,7 @@ var/obj/item/stack/tile/plasteel/S = C if (S.get_amount() < 1) return - del(L) + qdel(L) playsound(src.loc, 'sound/weapons/Genhit.ogg', 50, 1) S.build(src) S.use(1) diff --git a/code/TriDimension/controller.dm b/code/TriDimension/controller.dm index 528c2c76ba7..a9d4df675ab 100644 --- a/code/TriDimension/controller.dm +++ b/code/TriDimension/controller.dm @@ -28,9 +28,9 @@ initialized = 1 return 1 -/obj/effect/landmark/zcontroller/Del() +/obj/effect/landmark/zcontroller/Destroy() processing_objects.Remove(src) - return + return ..() /obj/effect/landmark/zcontroller/process() if (world.time > fast_time) diff --git a/code/ZAS/Atom.dm b/code/ZAS/Atom.dm index 6f75f4ea295..e655295f783 100644 --- a/code/ZAS/Atom.dm +++ b/code/ZAS/Atom.dm @@ -50,7 +50,7 @@ atom/proc/c_airblock(turf/other) #ifdef ZASDBG ASSERT(isturf(other)) #endif - return !CanPass(null, other, 0, 0) + 2*!CanPass(null, other, 1.5, 1) + return (AIR_BLOCKED*!CanPass(null, other, 0, 0))|(ZONE_BLOCKED*!CanPass(null, other, 1.5, 1)) turf/c_airblock(turf/other) diff --git a/code/ZAS/Controller.dm b/code/ZAS/Controller.dm index 4ba30f47b36..83d2a54ec3c 100644 --- a/code/ZAS/Controller.dm +++ b/code/ZAS/Controller.dm @@ -98,7 +98,7 @@ Class Procs: set background = 1 #endif - world << "Processing Geometry..." + admin_notice("Processing Geometry...", R_DEBUG) sleep(-1) var/start_time = world.timeofday @@ -109,14 +109,14 @@ Class Procs: simulated_turf_count++ S.update_air_properties() - world << {"Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds. + admin_notice({"Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds. Total Simulated Turfs: [simulated_turf_count] Total Zones: [zones.len] Total Edges: [edges.len] Total Active Edges: [active_edges.len ? "[active_edges.len]" : "None"] Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count] -"} +"}, R_DEBUG) // spawn Start() @@ -154,7 +154,18 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun #ifdef ZASDBG var/updated = 0 #endif + + //defer updating of self-zone-blocked turfs until after all other turfs have been updated. + //this hopefully ensures that non-self-zone-blocked turfs adjacent to self-zone-blocked ones + //have valid zones when the self-zone-blocked turfs update. + var/list/deferred = list() + for(var/turf/T in updating) + //check if the turf is self-zone-blocked + if(T.c_airblock(T) & ZONE_BLOCKED) + deferred += T + continue + T.update_air_properties() T.post_update_air_properties() T.needs_air_update = 0 @@ -164,6 +175,15 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun #endif //sleep(1) + for(var/turf/T in deferred) + T.update_air_properties() + T.post_update_air_properties() + T.needs_air_update = 0 + #ifdef ZASDBG + T.overlays -= mark + updated++ + #endif + #ifdef ZASDBG if(updated != updating.len) tick_progress = "[updating.len - updated] tiles left unupdated." @@ -307,7 +327,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun /datum/controller/air_system/proc/mark_edge_sleeping(connection_edge/E) #ifdef ZASDBG - ASSERT(istype(E) + ASSERT(istype(E)) #endif if(E.sleeping) return active_edges.Remove(E) @@ -315,7 +335,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun /datum/controller/air_system/proc/mark_edge_active(connection_edge/E) #ifdef ZASDBG - ASSERT(istype(E) + ASSERT(istype(E)) #endif if(!E.sleeping) return active_edges.Add(E) diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index 5dd0ac3cd31..ebfd0292280 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -78,11 +78,11 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) fire = new(src, fl) air_master.active_fire_zones |= zone - + var/obj/effect/decal/cleanable/liquid_fuel/fuel = locate() in src zone.fire_tiles |= src if(fuel) zone.fuel_objs += fuel - + return 0 /obj/fire @@ -91,11 +91,11 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) anchored = 1 mouse_opacity = 0 - //luminosity = 3 + blend_mode = BLEND_ADD icon = 'icons/effects/fire.dmi' icon_state = "1" - l_color = "#ED9200" + light_color = "#ED9200" layer = TURF_LAYER var/firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel() @@ -114,13 +114,13 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) if(firelevel > 6) icon_state = "3" - SetLuminosity(7) + set_light(7, 3) else if(firelevel > 2.5) icon_state = "2" - SetLuminosity(5) + set_light(5, 2) else icon_state = "1" - SetLuminosity(3) + set_light(3, 1) //im not sure how to implement a version that works for every creature so for now monkeys are firesafe for(var/mob/living/L in loc) @@ -158,19 +158,26 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) else enemy_tile.adjacent_fire_act(loc, air_contents, air_contents.temperature, air_contents.volume) + animate(src, color = heat2color(air_contents.temperature), 5) + set_light(l_color = color) + /obj/fire/New(newLoc,fl) ..() if(!istype(loc, /turf)) - del src + qdel(src) set_dir(pick(cardinal)) - SetLuminosity(3) + + var/datum/gas_mixture/air_contents = loc.return_air() + color = heat2color(air_contents.temperature) + set_light(3, 1, color) + firelevel = fl air_master.active_hotspots.Add(src) -/obj/fire/Del() +/obj/fire/Destroy() if (istype(loc, /turf/simulated)) RemoveFire() @@ -178,8 +185,8 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) /obj/fire/proc/RemoveFire() if (istype(loc, /turf)) - SetLuminosity(0) - + set_light(0) + loc = null air_master.active_hotspots.Remove(src) @@ -227,22 +234,22 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) //determine how far the reaction can progress var/reaction_limit = min(total_oxidizers*(FIRE_REACTION_FUEL_AMOUNT/FIRE_REACTION_OXIDIZER_AMOUNT), total_fuel) //stoichiometric limit - + //determine the actual rate of reaction, as measured by the amount of fuel reacting - + //vapour fuels are extremely volatile! The reaction progress is a percentage of the total fuel (similar to old zburn). var/gas_reaction_progress = max(0.2*group_multiplier, (firelevel/vsc.fire_firelevel_multiplier)*gas_fuel)*FIRE_GAS_BURNRATE_MULT //liquid fuels are not as volatile, and the reaction progress depends on the size of the area that is burning (which is sort of accounted for by firelevel). Having more fuel means a longer burn. var/liquid_reaction_progress = (firelevel/vsc.fire_firelevel_multiplier)*FIRE_LIQUID_BURNRATE_MULT - + //world << "liquid_reaction_progress = [liquid_reaction_progress]" //world << "gas_reaction_progress = [gas_reaction_progress]" - + var/total_reaction_progress = gas_reaction_progress + liquid_reaction_progress var/used_fuel = min(total_reaction_progress, reaction_limit) var/used_oxidizers = used_fuel*(FIRE_REACTION_OXIDIZER_AMOUNT/FIRE_REACTION_FUEL_AMOUNT) //world << "used_fuel = [used_fuel]; used_oxidizers = [used_oxidizers]; reaction_limit=[reaction_limit]" - + //if the reaction is progressing too slow then it isn't self-sustaining anymore and burns out if(zone && zone.fuel_objs.len) if(used_fuel <= FIRE_LIQUD_MIN_BURNRATE) @@ -250,13 +257,13 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) else if(used_fuel <= FIRE_GAS_MIN_BURNRATE*group_multiplier) //purely gas fires have more stringent criteria return 0 - + //*** Remove fuel and oxidizer, add carbon dioxide and heat - + //remove and add gasses as calculated var/used_gas_fuel = min(used_fuel*(gas_reaction_progress/total_reaction_progress), gas_fuel) //remove in proportion to the relative reaction progress var/used_liquid_fuel = between(0, used_fuel-used_gas_fuel, liquid_fuel) - + //remove_by_flag() and adjust_gas() handle the group_multiplier for us. remove_by_flag(XGM_GAS_OXIDIZER, used_oxidizers) remove_by_flag(XGM_GAS_FUEL, used_gas_fuel) @@ -272,14 +279,14 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) if(!istype(fuel)) zone.fuel_objs -= fuel continue - + fuel.amount -= fuel_to_remove if(fuel.amount <= 0) zone.fuel_objs -= fuel if(liquidonly) var/turf/T = fuel.loc - if(istype(T) && T.fire) del(T.fire) - del(fuel) + if(istype(T) && T.fire) qdel(T.fire) + qdel(fuel) //calculate the energy produced by the reaction and then set the new temperature of the mix temperature = (starting_energy + vsc.fire_fuel_energy_release * used_fuel) / heat_capacity() diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm index 9d031ce3d39..331c00dd37e 100644 --- a/code/ZAS/Turf.dm +++ b/code/ZAS/Turf.dm @@ -46,6 +46,7 @@ air_master.connect(sim, src) /turf/simulated/update_air_properties() + if(zone && zone.invalid) c_copy_air() zone = null //Easier than iterating through the list at the zone. @@ -58,7 +59,8 @@ #endif if(zone) var/zone/z = zone - if(locate(/obj/machinery/door/airlock) in src) //Hacky, but prevents normal airlocks from rebuilding zones all the time + + if(s_block & ZONE_BLOCKED) //Hacky, but prevents normal airlocks from rebuilding zones all the time z.remove(src) else z.rebuild() @@ -102,7 +104,7 @@ //This happens when windows move or are constructed. We need to rebuild. if((previously_open & d) && istype(unsim, /turf/simulated)) var/turf/simulated/sim = unsim - if(sim.zone == zone) + if(zone && sim.zone == zone) zone.rebuild() return @@ -120,8 +122,10 @@ //Might have assigned a zone, since this happens for each direction. if(!zone) - //if((block & ZONE_BLOCKED) || (r_block & ZONE_BLOCKED && !(s_block & ZONE_BLOCKED))) - if(((block & ZONE_BLOCKED) && !(r_block & ZONE_BLOCKED)) || (r_block & ZONE_BLOCKED && !(s_block & ZONE_BLOCKED))) + //We do not merge if + // they are blocking us and we are not blocking them, or if + // we are blocking them and not blocking ourselves - this prevents tiny zones from forming on doorways. + if(((block & ZONE_BLOCKED) && !(r_block & ZONE_BLOCKED)) || ((r_block & ZONE_BLOCKED) && !(s_block & ZONE_BLOCKED))) #ifdef ZASDBG if(verbose) world << "[d] is zone blocked." //dbg(zone_blocked, d) diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index b7042191fc9..9fcddc92465 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -111,6 +111,13 @@ Class Procs: #ifdef ZASDBG T.dbg(merged) #endif + + //rebuild the old zone's edges so that the will be possesed by the new zone + for(var/connection_edge/E in edges) + if(E.contains_zone(into)) + continue //don't need to rebuild this edge + for(var/turf/T in E.connecting_turfs) + air_master.mark_for_update(T) /zone/proc/c_invalidate() invalid = 1 diff --git a/code/__HELPERS/datum_pool.dm b/code/__HELPERS/datum_pool.dm new file mode 100644 index 00000000000..79970faf7b6 --- /dev/null +++ b/code/__HELPERS/datum_pool.dm @@ -0,0 +1,109 @@ + +/* +/tg/station13 /atom/movable Pool: +--------------------------------- +By RemieRichards + +Creation/Deletion is laggy, so let's reduce reuse and recycle! + +*/ +#define ATOM_POOL_COUNT 100 +// "define DEBUG_ATOM_POOL 1 +var/global/list/GlobalPool = list() + +//You'll be using this proc 90% of the time. +//It grabs a type from the pool if it can +//And if it can't, it creates one +//The pool is flexible and will expand to fit +//The new created atom when it eventually +//Goes into the pool + +//Second argument can be a new location, if the type is /atom/movable +//Or a list of arguments +//Either way it gets passed to new + +/proc/PoolOrNew(var/get_type,var/second_arg) + var/datum/D + D = GetFromPool(get_type,second_arg) + + if(!D) + // So the GC knows we're pooling this type. + if(!GlobalPool[get_type]) + GlobalPool[get_type] = list(new get_type) + if(islist(second_arg)) + return new get_type (arglist(second_arg)) + else + return new get_type (second_arg) + return D + +/proc/GetFromPool(var/get_type,var/second_arg) + if(isnull(GlobalPool[get_type])) + return 0 + + if(length(GlobalPool[get_type]) == 0) + return 0 + + var/datum/D = pick_n_take(GlobalPool[get_type]) + if(D) + D.ResetVars() + D.Prepare(second_arg) + return D + return 0 + +/proc/PlaceInPool(var/datum/D) + if(!istype(D)) + return + + if(length(GlobalPool[D.type]) > ATOM_POOL_COUNT) + #ifdef DEBUG_ATOM_POOL + world << text("DEBUG_DATUM_POOL: PlaceInPool([]) exceeds []. Discarding.", D.type, ATOM_POOL_COUNT) + #endif + del(D) + return + + if(D in GlobalPool[D.type]) + return + + if(!GlobalPool[D.type]) + GlobalPool[D.type] = list() + + GlobalPool[D.type] += D + + D.Destroy() + D.ResetVars() + D.disposed = 1 //Set to stop processing while pooled + +/proc/IsPooled(var/datum/D) + if(isnull(GlobalPool[D.type])) + return 0 + return 1 + +/datum/proc/Prepare(args) + if(islist(args)) + New(arglist(args)) + else + New(args) + disposed = null + +/atom/movable/Prepare(args) + var/list/args_list = args + if(istype(args_list) && args_list.len) + loc = args[1] + else + loc = args + ..() + +/datum/proc/ResetVars(var/list/exlude = list()) + var/list/excluded = list("animate_movement", "loc", "locs", "parent_type", "vars", "verbs", "type") + exlude + + for(var/V in vars) + if(V in excluded) + continue + + vars[V] = initial(vars[V]) + +/atom/movable/ResetVars() + ..() + vars["loc"] = null + +#undef ATOM_POOL_COUNT diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 45618f2ffce..60e46d4ca66 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -16,11 +16,21 @@ return 1 return 0 +/proc/max_default_z_level() + var/max_z = 0 + for(var/z in config.station_levels) + max_z = max(z, max_z) + for(var/z in config.admin_levels) + max_z = max(z, max_z) + for(var/z in config.player_levels) + max_z = max(z, max_z) + return max_z + /proc/get_area(O) var/turf/loc = get_turf(O) - if(!loc) - return null - return loc.loc + if(loc) + var/area/res = loc.loc + .= res /proc/get_area_name(N) //get area by its name for(var/area/A in world) @@ -28,6 +38,11 @@ return A return 0 +/proc/get_area_master(const/O) + var/area/A = get_area(O) + if (isarea(A)) + return A + /proc/in_range(source, user) if(get_dist(source, user) <= 1) return 1 @@ -61,18 +76,6 @@ /proc/isNotAdminLevel(var/level) return !isAdminLevel(level) -//Magic constants obtained by using linear regression on right-angled triangles of sides 0=dy) return (k1*dx) + (k2*dy) //No sqrt or powers :) - else return (k2*dx) + (k1*dy) -#undef k1 -#undef k2 - /proc/circlerange(center=usr,radius=3) var/turf/centerturf = get_turf(center) @@ -430,6 +433,34 @@ datum/projectile_data var/b = mixOneColor(weights, blues) return rgb(r,g,b) +/proc/mixOneColor(var/list/weight, var/list/color) + if (!weight || !color || length(weight)!=length(color)) + return 0 + + var/contents = length(weight) + var/i + + //normalize weights + var/listsum = 0 + for(i=1; i<=contents; i++) + listsum += weight[i] + for(i=1; i<=contents; i++) + weight[i] /= listsum + + //mix them + var/mixedcolor = 0 + for(i=1; i<=contents; i++) + mixedcolor += weight[i]*color[i] + mixedcolor = round(mixedcolor) + + //until someone writes a formal proof for this algorithm, let's keep this in +// if(mixedcolor<0x00 || mixedcolor>0xFF) +// return 0 + //that's not the kind of operation we are running here, nerd + mixedcolor=min(max(mixedcolor,0),255) + + return mixedcolor + /** * Gets the highest and lowest pressures from the tiles in cardinal directions * around us, then checks the difference. @@ -493,6 +524,6 @@ datum/projectile_data /proc/MinutesToTicks(var/minutes) return SecondsToTicks(60 * minutes) - + /proc/SecondsToTicks(var/seconds) return seconds * 10 diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 01b9509ae86..7484d016b6c 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -49,6 +49,17 @@ var/global/list/undershirt_t = list("White Tank top" = "u1", "Black Tank top" = //Backpacks var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt") var/global/list/exclude_jobs = list(/datum/job/ai,/datum/job/cyborg) + +// Visual nets +var/list/datum/visualnet/visual_nets = list() +var/datum/visualnet/camera/cameranet = new() +var/datum/visualnet/cult/cultnet = new() + +// Runes +var/global/list/rune_list = new() +var/global/list/escape_list = list() +var/global/list/endgame_exits = list() +var/global/list/endgame_safespawns = list() ////////////////////////// /////Initial Building///// ////////////////////////// diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index b7caf86669a..ed0f0c97809 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -30,6 +30,13 @@ return "[output][and_text][input[index]]" + +/proc/ConvertReqString2List(var/list/source_list) + var/list/temp_list = params2list(source_list) + for(var/O in temp_list) + temp_list[O] = text2num(temp_list[O]) + return temp_list + //Returns list element or null. Should prevent "index out of bounds" error. proc/listgetindex(var/list/list,index) if(istype(list) && list.len) @@ -175,11 +182,9 @@ proc/listclearnulls(list/list) //Return a list with no duplicate entries /proc/uniquelist(var/list/L) - var/list/K = list() - for(var/item in L) - if(!(item in K)) - K += item - return K + . = list() + for(var/i in L) + . |= i //Mergesort: divides up the list into halves to begin the sort /proc/sortKey(var/list/client/L, var/order = 1) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 32838765e80..89b96aa24bf 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -125,3 +125,10 @@ Proc for attack log creation, because really why not target.attack_log += text("\[[time_stamp()]\] Has been [what_done] by [user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]") if(admin) log_attack("[user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(ismob(target) && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]") + +//checks whether this item is a module of the robot it is located in. +/proc/is_robot_module(var/obj/item/thing) + if (!thing || !istype(thing.loc, /mob/living/silicon/robot)) + return 0 + var/mob/living/silicon/robot/R = thing.loc + return (thing in R.module.modules) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 54ce601ac7e..ae38249956a 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -183,7 +183,7 @@ /proc/replace_characters(var/t,var/list/repl_chars) for(var/char in repl_chars) - replacetext(t, char, repl_chars[char]) + t = replacetext(t, char, repl_chars[char]) return t //Adds 'u' number of zeros ahead of the text 't' @@ -226,6 +226,31 @@ /proc/capitalize(var/t as text) return uppertext(copytext(t, 1, 2)) + copytext(t, 2) +//This proc strips html properly, remove < > and all text between +//for complete text sanitizing should be used sanitize() +/proc/strip_html_properly(var/input) + if(!input) + return + var/opentag = 1 //These store the position of < and > respectively. + var/closetag = 1 + while(1) + opentag = findtext(input, "<") + closetag = findtext(input, ">") + if(closetag && opentag) + if(closetag < opentag) + input = copytext(input, (closetag + 1)) + else + input = copytext(input, 1, opentag) + copytext(input, (closetag + 1)) + else if(closetag || opentag) + if(opentag) + input = copytext(input, 1, opentag) + else + input = copytext(input, (closetag + 1)) + else + break + + return input + //This proc fills in all spaces with the "replace" var (* by default) with whatever //is in the other string at the same spot (assuming it is not a replace char). //This is used for fingerprints @@ -274,7 +299,11 @@ proc/TextPreview(var/string,var/len=40) else return string else - return "[copytext(string, 1, 37)]..." + return "[copytext_preserve_html(string, 1, 37)]..." + +//alternative copytext() for encoded text, doesn't break html entities (" and other) +/proc/copytext_preserve_html(var/text, var/first, var/last) + return html_encode(copytext(html_decode(text), first, last)) //For generating neat chat tag-images //The icon var could be local in the proc, but it's a waste of resources @@ -283,4 +312,4 @@ proc/TextPreview(var/string,var/len=40) /proc/create_text_tag(var/tagname, var/tagdesc = tagname, var/client/C = null) if(C && (C.prefs.toggles & CHAT_NOICONS)) return tagdesc - return "[tagdesc]" + return "[tagdesc]" \ No newline at end of file diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index f20830e5cc2..c90a935b6df 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -10,6 +10,9 @@ proc/worldtime2text(time = world.time) if(!roundstart_hour) roundstart_hour = pick(2,7,12,17) return "[round(time / 36000)+roundstart_hour]:[(time / 600 % 60) < 10 ? add_zero(time / 600 % 60, 1) : time / 600 % 60]" +proc/worlddate2text() + return num2text((text2num(time2text(world.timeofday, "YYYY"))+544)) + "-" + time2text(world.timeofday, "MM-DD") + proc/time_stamp() return time2text(world.timeofday, "hh:mm:ss") diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 72d85a67b50..3564c5e15fc 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -631,7 +631,7 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl animation.master = target flick(flick_anim, animation) sleep(max(sleeptime, 15)) - del(animation) + qdel(animation) //Will return the contents of an atom recursivly to a depth of 'searchDepth' /atom/proc/GetAllContents(searchDepth = 5) @@ -902,7 +902,7 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl X.icon = 'icons/turf/shuttle.dmi' X.icon_state = replacetext(O.icon_state, "_f", "_s") // revert the turf to the old icon_state X.name = "wall" - del(O) // prevents multiple shuttle corners from stacking + qdel(O) // prevents multiple shuttle corners from stacking continue if(!istype(O,/obj)) continue O.loc = X @@ -927,30 +927,6 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl refined_trg -= B continue moving - var/list/doors = new/list() - - if(toupdate.len) - for(var/turf/simulated/T1 in toupdate) - for(var/obj/machinery/door/D2 in T1) - doors += D2 - /*if(T1.parent) - air_master.groups_to_rebuild += T1.parent - else - air_master.tiles_to_update += T1*/ - - if(fromupdate.len) - for(var/turf/simulated/T2 in fromupdate) - for(var/obj/machinery/door/D2 in T2) - doors += D2 - /*if(T2.parent) - air_master.groups_to_rebuild += T2.parent - else - air_master.tiles_to_update += T2*/ - - for(var/obj/O in doors) - O:update_nearby_tiles(1) - - proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0) if(!original) diff --git a/code/__HELPERS/vector.dm b/code/__HELPERS/vector.dm index 970530e71df..44d293734c5 100644 --- a/code/__HELPERS/vector.dm +++ b/code/__HELPERS/vector.dm @@ -52,7 +52,7 @@ return_location() var/offset_x = 0 // distance to increment each step var/offset_y = 0 -/datum/plot_vector/proc/setup(var/turf/S, var/turf/T, var/xo = 0, var/yo = 0) +/datum/plot_vector/proc/setup(var/turf/S, var/turf/T, var/xo = 0, var/yo = 0, var/angle_offset=0) source = S target = T @@ -78,7 +78,7 @@ return_location() return // calculate the angle - angle = Atan2(dx, dy) + angle = Atan2(dx, dy) + angle_offset // and some rounding to stop the increments jumping whole turfs - because byond favours certain angles if(angle > -135 && angle < 45) @@ -118,7 +118,7 @@ return_location() /datum/plot_vector/proc/return_location(var/datum/vector_loc/data) if(!data) data = new() - data.loc = locate(round(loc_x / world.icon_size), round(loc_y / world.icon_size), loc_z) + data.loc = locate(round(loc_x / world.icon_size, 1), round(loc_y / world.icon_size, 1), loc_z) if(!data.loc) return data.pixel_x = loc_x - (data.loc.x * world.icon_size) diff --git a/code/_defines/chemical_effects.dm b/code/_defines/chemical_effects.dm new file mode 100644 index 00000000000..6119d80cb51 --- /dev/null +++ b/code/_defines/chemical_effects.dm @@ -0,0 +1,7 @@ +#define CE_STABLE "stable" // Inaprovaline +#define CE_ANTIBIOTIC "antibiotic" // Spaceacilin +#define CE_BLOODRESTORE "bloodrestore" // Iron/nutriment +#define CE_PAINKILLER "painkiller" +#define CE_ALCOHOL "alcohol" // Liver filtering +#define CE_ALCOHOL_TOXIC "alcotoxic" // Liver damage +#define CE_SPEEDBOOST "gofast" // Hyperzine \ No newline at end of file diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 3a5f4032a2f..900e89e7e75 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -48,6 +48,11 @@ #define ui_monkey_mask "5:14,1:5" //monkey #define ui_monkey_back "6:14,1:5" //monkey +#define ui_construct_health "15:00,7:15" //same height as humans, hugging the right border +#define ui_construct_purge "15:00,6:15" +#define ui_construct_fire "14:16,8:13" //above health, slightly to the left +#define ui_construct_pull "14:28,2:10" //above the zone_sel icon + //Lower right, persistant menu #define ui_dropbutton "11:22,1:5" #define ui_drop_throw "14:28,2:7" @@ -66,6 +71,7 @@ #define ui_gun2 "14:28, 4:7" #define ui_gun3 "13:26,4:7" #define ui_gun_select "14:28,3:7" +#define ui_gun4 "12:24,3:7" //Upper-middle right (damage indicators) #define ui_toxin "14:28,13:27" @@ -118,3 +124,6 @@ #define ui_iarrowleft "SOUTH-1,11" #define ui_iarrowright "SOUTH-1,13" + +#define ui_spell_master "14:16,14:16" +#define ui_genetic_master "14:16,12:16" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index c41f9594b34..f39499f3dce 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -33,7 +33,7 @@ var/list/global_huds = list( screen.screen_loc = "1,1" screen.icon = 'icons/obj/hud_full.dmi' screen.icon_state = icon_state - screen.layer = 17 + screen.layer = SCREEN_LAYER screen.mouse_opacity = 0 return screen @@ -249,7 +249,11 @@ datum/hud/New(mob/owner) robot_hud() else if(isobserver(mymob)) ghost_hud() + else + mymob.instantiate_hud(src) +/mob/proc/instantiate_hud(var/datum/hud/HUD) + return //Triggered when F12 is pressed (Unless someone changed something in the DMF) /mob/verb/button_pressed_F12(var/full = 0 as null) @@ -337,6 +341,7 @@ datum/hud/New(mob/owner) if(src.hud_used.item_action_list) src.client.screen -= src.hud_used.item_action_list src.client.screen -= src.internals + src.client.screen += src.hud_used.action_intent //we want the intent swticher visible else hud_used.hud_shown = 1 if(src.hud_used.adding) diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 92fe661d002..97b07e6154d 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -356,6 +356,9 @@ //mymob.gun_run_icon.color = ui_color mymob.gun_run_icon.alpha = ui_alpha + mymob.radio_use_icon = new /obj/screen/gun/radio(null) + mymob.radio_use_icon.alpha = ui_alpha + if (mymob.client) if (mymob.client.gun_mode) // If in aim mode, correct the sprite mymob.gun_setting_icon.set_dir(2) diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index 76adf0414c3..7314e8692d0 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -231,6 +231,10 @@ if (mymob.client.target_can_click) mymob.item_use_icon.set_dir(1) src.adding += mymob.item_use_icon + mymob.radio_use_icon = new /obj/screen/gun/radio(null) + if (mymob.client.target_can_radio) + mymob.radio_use_icon.set_dir(1) + src.adding += mymob.radio_use_icon mymob.gun_move_icon = new /obj/screen/gun/move(null) if (mymob.client.target_can_move) mymob.gun_move_icon.set_dir(1) diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index 3f785d8a83b..5dd1b542cfa 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -101,3 +101,59 @@ mymob.client.screen += src.adding return + +/mob/living/simple_animal/construct/instantiate_hud(var/datum/hud/HUD) + HUD.construct_hud() + +/datum/hud/proc/construct_hud() + var/constructtype + + if(istype(mymob,/mob/living/simple_animal/construct/armoured) || istype(mymob,/mob/living/simple_animal/construct/behemoth)) + constructtype = "juggernaut" + else if(istype(mymob,/mob/living/simple_animal/construct/builder)) + constructtype = "artificer" + else if(istype(mymob,/mob/living/simple_animal/construct/wraith)) + constructtype = "wraith" + else if(istype(mymob,/mob/living/simple_animal/construct/harvester)) + constructtype = "harvester" + + mymob.flash = new /obj/screen() + mymob.flash.icon = 'icons/mob/screen1.dmi' + mymob.flash.icon_state = "blank" + mymob.flash.name = "flash" + mymob.flash.screen_loc = "1,1 to 15,15" + mymob.flash.layer = 17 + + if(constructtype) + mymob.fire = new /obj/screen() + mymob.fire.icon = 'icons/mob/screen1_construct.dmi' + mymob.fire.icon_state = "fire0" + mymob.fire.name = "fire" + mymob.fire.screen_loc = ui_construct_fire + + mymob.healths = new /obj/screen() + mymob.healths.icon = 'icons/mob/screen1_construct.dmi' + mymob.healths.icon_state = "[constructtype]_health0" + mymob.healths.name = "health" + mymob.healths.screen_loc = ui_construct_health + + mymob.pullin = new /obj/screen() + mymob.pullin.icon = 'icons/mob/screen1_construct.dmi' + mymob.pullin.icon_state = "pull0" + mymob.pullin.name = "pull" + mymob.pullin.screen_loc = ui_construct_pull + + mymob.zone_sel = new /obj/screen/zone_sel() + mymob.zone_sel.icon = 'icons/mob/screen1_construct.dmi' + mymob.zone_sel.overlays.len = 0 + mymob.zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]") + + mymob.purged = new /obj/screen() + mymob.purged.icon = 'icons/mob/screen1_construct.dmi' + mymob.purged.icon_state = "purge0" + mymob.purged.name = "purged" + mymob.purged.screen_loc = ui_construct_purge + + mymob.client.screen = null + + mymob.client.screen += list(mymob.fire, mymob.healths, mymob.pullin, mymob.zone_sel, mymob.purged, mymob.flash) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 48378fce7f4..e07d5aaf201 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -162,6 +162,10 @@ var/obj/screen/robot_inventory if (mymob.client.target_can_click) mymob.item_use_icon.set_dir(1) src.adding += mymob.item_use_icon + mymob.radio_use_icon = new /obj/screen/gun/radio(null) + if (mymob.client.target_can_radio) + mymob.radio_use_icon.set_dir(1) + src.adding += mymob.radio_use_icon mymob.gun_move_icon = new /obj/screen/gun/move(null) if (mymob.client.target_can_move) mymob.gun_move_icon.set_dir(1) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 0cc2ad33652..4a7d6f2acbe 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -14,6 +14,9 @@ var/obj/master = null //A reference to the object in the slot. Grabs or items, generally. var/gun_click_time = -100 //I'm lazy. +/obj/screen/Destroy() + master = null + ..() /obj/screen/text icon = null @@ -122,6 +125,11 @@ screen_loc = ui_gun_select //dir = 1 + radio + name = "Allow Radio Use" + icon_state = "no_radio0" + screen_loc = ui_gun4 + /obj/screen/zone_sel name = "damage zone" icon_state = "zone_sel" @@ -427,7 +435,7 @@ if(istype(usr, /mob/living/silicon/robot)) usr:toggle_module(3) - if("Allow Walking") + if("Allow Walking", "Disallow Walking") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) @@ -436,16 +444,7 @@ usr.client.AllowTargetMove() gun_click_time = world.time - if("Disallow Walking") - if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. - return - if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) - usr << "You need your gun in your active hand to do that!" - return - usr.client.AllowTargetMove() - gun_click_time = world.time - - if("Allow Running") + if("Allow Running", "Disallow Running") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) @@ -454,26 +453,7 @@ usr.client.AllowTargetRun() gun_click_time = world.time - if("Disallow Running") - if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. - return - if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) - usr << "You need your gun in your active hand to do that!" - return - usr.client.AllowTargetRun() - gun_click_time = world.time - - if("Allow Item Use") - if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. - return - if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) - usr << "You need your gun in your active hand to do that!" - return - usr.client.AllowTargetClick() - gun_click_time = world.time - - - if("Disallow Item Use") + if("Allow Item Use", "Disallow Item Use") if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. return if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) @@ -485,6 +465,15 @@ if("Toggle Gun Mode") usr.client.ToggleGunMode() + if("Allow Radio Use", "Disallow Radio Use") + if(gun_click_time > world.time - 30) //give them 3 seconds between mode changes. + return + if(!istype(usr.get_active_hand(),/obj/item/weapon/gun)) + usr << "You need your gun in your active hand to do that!" + return + usr.client.AllowTargetRadio() + gun_click_time = world.time + else return 0 return 1 diff --git a/code/_onclick/hud/spell_screen_objects.dm b/code/_onclick/hud/spell_screen_objects.dm new file mode 100644 index 00000000000..ed208a588de --- /dev/null +++ b/code/_onclick/hud/spell_screen_objects.dm @@ -0,0 +1,175 @@ +/obj/screen/movable/spell_master + name = "Spells" + icon = 'icons/mob/screen_spells.dmi' + icon_state = "wiz_spell_ready" + var/list/obj/screen/spell/spell_objects = list() + var/showing = 0 + + var/open_state = "master_open" + var/closed_state = "master_closed" + + screen_loc = ui_spell_master + + var/mob/spell_holder + +/obj/screen/movable/spell_master/MouseDrop() + if(showing) + return + + return ..() + +/obj/screen/movable/spell_master/Click() + if(!spell_objects.len) + qdel(src) + return + + toggle_open() + +/obj/screen/movable/spell_master/proc/toggle_open(var/forced_state = 0) + if(showing && (forced_state != 2)) + for(var/obj/screen/spell/O in spell_objects) + if(spell_holder && spell_holder.client) + spell_holder.client.screen -= O + O.handle_icon_updates = 0 + showing = 0 + overlays.len = 0 + overlays.Add(closed_state) + else if(forced_state != 1) + var/temp_loc = screen_loc + + var/x_position = text2num(copytext(temp_loc, 1, findtext(temp_loc, ":"))) + var/x_pix = text2num(copytext(temp_loc, findtext(temp_loc, ":") + 1, findtext(temp_loc, ","))) + temp_loc = copytext(temp_loc, findtext(temp_loc, ",") + 1) + var/y_position = text2num(copytext(temp_loc, 1, findtext(temp_loc, ":"))) + var/y_pix = text2num(copytext(temp_loc, findtext(temp_loc, ":")+1)) + + for(var/i = 1; i <= spell_objects.len; i++) + var/obj/screen/spell/S = spell_objects[i] + S.screen_loc = "[x_position + (x_position < 8 ? 1 : -1)*(i%7)]:[x_pix],[y_position + (y_position < 8 ? round(i/7) : -round(i/7))]:[y_pix]" + if(spell_holder && spell_holder.client) + spell_holder.client.screen += S + S.handle_icon_updates = 1 + update_spells(1) + showing = 1 + overlays.len = 0 + overlays.Add(open_state) + +/obj/screen/movable/spell_master/proc/add_spell(var/spell/spell) + if(!spell) return + + for(var/obj/screen/spell/spellscreen in spell_objects) + if(spellscreen.spell == spell) + return + + if(spell.spell_flags & NO_BUTTON) //no button to add if we don't get one + return + + var/obj/screen/spell/newscreen = new + + newscreen.spell = spell + if(!spell.override_base) //if it's not set, we do basic checks + if(spell.spell_flags & CONSTRUCT_CHECK) + newscreen.spell_base = "const" //construct spells + else + newscreen.spell_base = "wiz" //wizard spells + else + newscreen.spell_base = spell.override_base + newscreen.name = spell.name + newscreen.update_charge(1) + spell_objects.Add(newscreen) + toggle_open(2) //forces the icons to refresh on screen + +/obj/screen/movable/spell_master/proc/remove_spell(var/spell/spell) + for(var/obj/screen/spell/s_object in spell_objects) + if(s_object.spell == spell) + spell_objects.Remove(s_object) + qdel(s_object) + break + + if(spell_objects.len) + toggle_open(showing + 1) + else + spell_holder.spell_masters.Remove(src) + qdel(src) + +/obj/screen/movable/spell_master/proc/silence_spells(var/amount) + for(var/obj/screen/spell/spell in spell_objects) + spell.spell.silenced = amount + spell.update_charge(1) + +/obj/screen/movable/spell_master/proc/update_spells(forced = 0, mob/user) + if(user && user.client) + if(!(src in user.client.screen)) + user.client.screen += src + for(var/obj/screen/spell/spell in spell_objects) + spell.update_charge(forced) + + +/obj/screen/movable/spell_master/genetic + name = "Mutant Powers" + icon_state = "genetic_spell_ready" + + open_state = "genetics_open" + closed_state = "genetics_closed" + + screen_loc = ui_genetic_master + +//////////////ACTUAL SPELLS////////////// +//This is what you click to cast things// +///////////////////////////////////////// +/obj/screen/spell + icon = 'icons/mob/screen_spells.dmi' + icon_state = "wiz_spell_base" + var/spell_base = "wiz" + var/last_charge = 0 //not a time, but the last remembered charge value + + var/spell/spell = null + var/handle_icon_updates = 0 + + var/icon/last_charged_icon + +/obj/screen/spell/proc/update_charge(var/forced_update = 0) + if(!spell) + qdel(src) + return + + if((last_charge == spell.charge_counter || !handle_icon_updates) && !forced_update) + return //nothing to see here + + overlays -= spell.hud_state + + if(spell.charge_type == Sp_RECHARGE || spell.charge_type == Sp_CHARGES) + if(spell.charge_counter < spell.charge_max) + icon_state = "[spell_base]_spell_base" + if(spell.charge_counter > 0) + var/icon/partial_charge = icon(src.icon, "[spell_base]_spell_ready") + partial_charge.Crop(1, 1, partial_charge.Width(), round(partial_charge.Height() * spell.charge_counter / spell.charge_max)) + overlays += partial_charge + if(last_charged_icon) + overlays -= last_charged_icon + last_charged_icon = partial_charge + else if(last_charged_icon) + overlays -= last_charged_icon + last_charged_icon = null + else + icon_state = "[spell_base]_spell_ready" + if(last_charged_icon) + overlays -= last_charged_icon + else + icon_state = "[spell_base]_spell_ready" + + overlays += spell.hud_state + + last_charge = spell.charge_counter + + overlays -= "silence" + if(spell.silenced) + overlays += "silence" + +/obj/screen/spell/Click() + if(!usr || !spell) + qdel(src) + return + + spell.perform(usr) + update_charge(1) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 1d68fb54e8e..7bb85445d4d 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -25,13 +25,31 @@ if(!istype(M) || (can_operate(M) && do_surgery(M,user,src))) return 0 + // Knifing + if(edge) + for(var/obj/item/weapon/grab/G in M.grabbed_by) + if(G.assailant == user && G.state >= GRAB_NECK && world.time >= (G.last_action + 20)) + //TODO: better alternative for applying damage multiple times? Nice knifing sound? + M.apply_damage(20, BRUTE, "head", 0, sharp=sharp, edge=edge) + M.apply_damage(20, BRUTE, "head", 0, sharp=sharp, edge=edge) + M.apply_damage(20, BRUTE, "head", 0, sharp=sharp, edge=edge) + M.adjustOxyLoss(60) // Brain lacks oxygen immediately, pass out + flick(G.hud.icon_state, G.hud) + G.last_action = world.time + user.visible_message("[user] slit [M]'s throat open with \the [name]!") + user.attack_log += "\[[time_stamp()]\] Knifed [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" + M.attack_log += "\[[time_stamp()]\] Got knifed by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" + msg_admin_attack("[key_name(user)] knifed [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" ) + return + ///////////////////////// user.lastattacked = M M.lastattacker = user - user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" - M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" - msg_admin_attack("[key_name(user)] attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" ) + if(!no_attack_log) + user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" + M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" + msg_admin_attack("[key_name(user)] attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" ) ///////////////////////// var/power = force diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 337a0442355..168ae47c863 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -20,7 +20,7 @@ return // seems legit. // Things you might plausibly want to follow - if((ismob(A) && A != src) || istype(A,/obj/machinery/bot) || istype(A,/obj/machinery/singularity)) + if((ismob(A) && A != src) || istype(A,/obj/machinery/bot) || istype(A,/obj/singularity)) ManualFollow(A) // Otherwise jump diff --git a/code/_onclick/oldcode.dm b/code/_onclick/oldcode.dm index ce6a238329d..890d67923ab 100644 --- a/code/_onclick/oldcode.dm +++ b/code/_onclick/oldcode.dm @@ -253,7 +253,7 @@ See the previous More info, for... more info... */ - //del(D) + //qdel(D) // Garbage Collect Dummy D.loc = null D = null diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index 88c9feca369..ae57895cd6a 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -80,14 +80,14 @@ var/const/tk_maxrange = 15 if(focus.Adjacent(loc)) focus.loc = loc - del(src) + qdel(src) return //stops TK grabs being equipped anywhere but into hands equipped(var/mob/user, var/slot) if( (slot == slot_l_hand) || (slot== slot_r_hand) ) return - del(src) + qdel(src) return @@ -99,10 +99,10 @@ var/const/tk_maxrange = 15 if(!target || !user) return if(last_throw+3 > world.time) return if(!host || host != user) - del(src) + qdel(src) return if(!(TK in host.mutations)) - del(src) + qdel(src) return if(isobj(target) && !isturf(target.loc)) return @@ -152,7 +152,7 @@ var/const/tk_maxrange = 15 proc/focus_object(var/obj/target, var/mob/living/user) if(!istype(target,/obj)) return//Cant throw non objects atm might let it do mobs later if(target.anchored || !isturf(target.loc)) - del src + qdel(src) return focus = target update_icon() @@ -162,7 +162,7 @@ var/const/tk_maxrange = 15 proc/apply_focus_overlay() if(!focus) return - var/obj/effect/overlay/O = new /obj/effect/overlay(locate(focus.x,focus.y,focus.z)) + var/obj/effect/overlay/O = PoolOrNew(/obj/effect/overlay, locate(focus.x,focus.y,focus.z)) O.name = "sparkles" O.anchored = 1 O.density = 0 @@ -172,7 +172,7 @@ var/const/tk_maxrange = 15 O.icon_state = "nothing" flick("empdisable",O) spawn(5) - O.delete() + qdel(O) return diff --git a/code/controllers/ProcessScheduler/core/process.dm b/code/controllers/ProcessScheduler/core/process.dm index 89048113d30..1f27f4c1ded 100644 --- a/code/controllers/ProcessScheduler/core/process.dm +++ b/code/controllers/ProcessScheduler/core/process.dm @@ -184,8 +184,7 @@ datum/controller/process/proc/kill() killed = TRUE - // This should del - del(src) + del(src) // This should del datum/controller/process/proc/scheck(var/tickId = 0) if (killed) @@ -315,3 +314,9 @@ datum/controller/process/proc/enable() /datum/controller/process/proc/getTicks() return ticks + +/datum/controller/process/proc/getStatName() + return name + +/datum/controller/process/proc/getTickTime() + return "#[getTicks()]\t- [getLastRunTime()]" diff --git a/code/controllers/Processes/alarm.dm b/code/controllers/Processes/alarm.dm index d41aa6ffdf2..6269ab89d1e 100644 --- a/code/controllers/Processes/alarm.dm +++ b/code/controllers/Processes/alarm.dm @@ -4,3 +4,7 @@ /datum/controller/process/alarm/doWork() alarm_manager.fire() + +/datum/controller/process/alarm/getStatName() + var/list/alarms = alarm_manager.active_alarms() + return ..()+"([alarms.len])" diff --git a/code/controllers/Processes/disease.dm b/code/controllers/Processes/disease.dm index a8d840097ec..35cf0d98917 100644 --- a/code/controllers/Processes/disease.dm +++ b/code/controllers/Processes/disease.dm @@ -9,3 +9,6 @@ /datum/controller/process/disease/doWork() updateQueueInstance.init(active_diseases, "process") updateQueueInstance.Run() + +/datum/controller/process/disease/getStatName() + return ..()+"([active_diseases.len])" diff --git a/code/controllers/Processes/garbage.dm b/code/controllers/Processes/garbage.dm new file mode 100644 index 00000000000..757729dfa66 --- /dev/null +++ b/code/controllers/Processes/garbage.dm @@ -0,0 +1,207 @@ +var/datum/controller/process/garbage_collector/garbage_collector +var/list/delayed_garbage = list() + +/datum/controller/process/garbage_collector + var/garbage_collect = 1 // Whether or not to actually do work + var/collection_timeout = 300 //deciseconds to wait to let running procs finish before we just say fuck it and force del() the object + var/max_checks_multiplier = 5 //multiplier (per-decisecond) for calculating max number of tests per tick. These tests check if our GC'd objects are actually GC'd + var/max_forcedel_multiplier = 1 //multiplier (per-decisecond) for calculating max number of force del() calls per tick. + + var/dels = 0 // number of del()'s we've done this tick + var/hard_dels = 0 // number of hard dels in total + var/list/destroyed = list() // list of refID's of things that should be garbage collected + // refID's are associated with the time at which they time out and need to be manually del() + // we do this so we aren't constantly locating them and preventing them from being gc'd + + var/list/logging = list() // list of all types that have failed to GC associated with the number of times that's happened. + // the types are stored as strings + +/datum/controller/process/garbage_collector/setup() + name = "garbage" + schedule_interval = 2 SECONDS + + if(!garbage_collector) + garbage_collector = src + + for(var/garbage in delayed_garbage) + qdel(garbage) + delayed_garbage.Cut() + delayed_garbage = null + +/datum/controller/process/garbage_collector/doWork() + if(!garbage_collect) + return + + dels = 0 + var/time_to_kill = world.time - collection_timeout // Anything qdel() but not GC'd BEFORE this time needs to be manually del() + var/checkRemain = max_checks_multiplier * schedule_interval + var/maxDels = max_forcedel_multiplier * schedule_interval + + while(destroyed.len && --checkRemain >= 0) + if(dels >= maxDels) + #ifdef GC_DEBUG + testing("GC: Reached max force dels per tick [dels] vs [maxDels]") + #endif + break // Server's already pretty pounded, everything else can wait 2 seconds + var/refID = destroyed[1] + var/GCd_at_time = destroyed[refID] + if(GCd_at_time > time_to_kill) + #ifdef GC_DEBUG + testing("GC: [refID] not old enough, breaking at [world.time] for [GCd_at_time - time_to_kill] deciseconds until [GCd_at_time + collection_timeout]") + #endif + break // Everything else is newer, skip them + var/atom/A = locate(refID) + #ifdef GC_DEBUG + testing("GC: [refID] old enough to test: GCd_at_time: [GCd_at_time] time_to_kill: [time_to_kill] current: [world.time]") + #endif + if(A && A.gcDestroyed == GCd_at_time) // So if something else coincidently gets the same ref, it's not deleted by mistake + // Something's still referring to the qdel'd object. Kill it. + testing("GC: -- \ref[A] | [A.type] was unable to be GC'd and was deleted --") + logging["[A.type]"]++ + del(A) + ++dels + ++hard_dels + #ifdef GC_DEBUG + else + testing("GC: [refID] properly GC'd at [world.time] with timeout [GCd_at_time]") + #endif + destroyed.Cut(1, 2) + +/datum/controller/process/garbage_collector/proc/AddTrash(datum/A) + if(!istype(A) || !isnull(A.gcDestroyed)) + return + #ifdef GC_DEBUG + testing("GC: AddTrash(\ref[A] - [A.type])") + #endif + A.gcDestroyed = world.time + destroyed -= "\ref[A]" // Removing any previous references that were GC'd so that the current object will be at the end of the list. + destroyed["\ref[A]"] = world.time + +/datum/controller/process/garbage_collector/getStatName() + return ..()+"([garbage_collector.destroyed.len]/[garbage_collector.dels]/[garbage_collector.hard_dels])" + +// Should be treated as a replacement for the 'del' keyword. +// Datums passed to this will be given a chance to clean up references to allow the GC to collect them. +/proc/qdel(var/datum/A) + if(!A) + return + if(istype(A, /list)) + var/list/L = A + for(var/E in L) + qdel(E) + return + + if(!istype(A)) + //warning("qdel() passed object of type [A.type]. qdel() can only handle /datum types.") + del(A) + if(garbage_collector) + garbage_collector.dels++ + garbage_collector.hard_dels++ + else if(isnull(A.gcDestroyed)) + // Let our friend know they're about to get collected + . = !A.Destroy() + if(. && A) + A.finalize_qdel() + +/datum/proc/finalize_qdel() + if(IsPooled(src)) + PlaceInPool(src) + else + del(src) + +/atom/finalize_qdel() + if(IsPooled(src)) + PlaceInPool(src) + else + if(garbage_collector) + garbage_collector.AddTrash(src) + else + delayed_garbage |= src + +/icon/finalize_qdel() + del(src) + +/image/finalize_qdel() + del(src) + +/mob/finalize_qdel() + del(src) + +/turf/finalize_qdel() + del(src) + +// Default implementation of clean-up code. +// This should be overridden to remove all references pointing to the object being destroyed. +// Return true if the the GC controller should allow the object to continue existing. (Useful if pooling objects.) +/datum/proc/Destroy() + tag = null + return + +#ifdef TESTING +/client/var/running_find_references + +/mob/verb/create_thing() + set category = "Debug" + set name = "Create Thing" + + var/path = input("Enter path") + var/atom/thing = new path(loc) + thing.find_references() + +/atom/verb/find_references() + set category = "Debug" + set name = "Find References" + set background = 1 + set src in world + + if(!usr || !usr.client) + return + + if(usr.client.running_find_references) + testing("CANCELLED search for references to a [usr.client.running_find_references].") + usr.client.running_find_references = null + return + + if(alert("Running this will create a lot of lag until it finishes. You can cancel it by running it again. Would you like to begin the search?", "Find References", "Yes", "No") == "No") + return + + // Remove this object from the list of things to be auto-deleted. + if(garbage_collector) + garbage_collector.destroyed -= "\ref[src]" + + usr.client.running_find_references = type + testing("Beginning search for references to a [type].") + var/list/things = list() + for(var/client/thing) + things += thing + for(var/datum/thing) + things += thing + for(var/atom/thing) + things += thing + testing("Collected list of things in search for references to a [type]. ([things.len] Thing\s)") + for(var/datum/thing in things) + if(!usr.client.running_find_references) return + for(var/varname in thing.vars) + var/variable = thing.vars[varname] + if(variable == src) + testing("Found [src.type] \ref[src] in [thing.type]'s [varname] var.") + else if(islist(variable)) + if(src in variable) + testing("Found [src.type] \ref[src] in [thing.type]'s [varname] list var.") + testing("Completed search for references to a [type].") + usr.client.running_find_references = null + +/client/verb/purge_all_destroyed_objects() + set category = "Debug" + if(garbage_collector) + while(garbage_collector.destroyed.len) + var/datum/o = locate(garbage_collector.destroyed[1]) + if(istype(o) && o.gcDestroyed) + del(o) + garbage_collector.dels++ + garbage_collector.destroyed.Cut(1, 2) +#endif + +#ifdef GC_DEBUG +#undef GC_DEBUG +#endif diff --git a/code/controllers/Processes/inactivity.dm b/code/controllers/Processes/inactivity.dm index b610502d19e..d9f9206749b 100644 --- a/code/controllers/Processes/inactivity.dm +++ b/code/controllers/Processes/inactivity.dm @@ -9,7 +9,7 @@ if(!istype(C.mob, /mob/dead)) log_access("AFK: [key_name(C)]") C << "You have been inactive for more than 10 minutes and have been disconnected." - del(C) + del(C) // Don't qdel, cannot override finalize_qdel behaviour for clients. scheck() diff --git a/code/controllers/Processes/machinery.dm b/code/controllers/Processes/machinery.dm index 61f3c7f4dee..b84dfaf9435 100644 --- a/code/controllers/Processes/machinery.dm +++ b/code/controllers/Processes/machinery.dm @@ -6,18 +6,16 @@ /datum/controller/process/machinery/doWork() internal_sort() - internal_process() + internal_process_machinery() + internal_process_power() + internal_process_power_drain() /datum/controller/process/machinery/proc/internal_sort() if(machinery_sort_required) machinery_sort_required = 0 machines = dd_sortedObjectList(machines) -/datum/controller/process/machinery/proc/internal_process() -//#ifdef PROFILE_MACHINES - //machine_profiling.len = 0 - //#endif - +/datum/controller/process/machinery/proc/internal_process_machinery() for(var/obj/machinery/M in machines) if(M && !M.gcDestroyed) #ifdef PROFILE_MACHINES @@ -42,3 +40,23 @@ #endif scheck() + +/datum/controller/process/machinery/proc/internal_process_power() + for(var/datum/powernet/powerNetwork in powernets) + if(istype(powerNetwork) && !powerNetwork.disposed) + powerNetwork.reset() + scheck() + continue + + powernets.Remove(powerNetwork) + +/datum/controller/process/machinery/proc/internal_process_power_drain() + // Currently only used by powersinks. These items get priority processed before machinery + for(var/obj/item/I in processing_power_items) + if(!I.pwr_drain()) // 0 = Process Kill, remove from processing list. + processing_power_items.Remove(I) + scheck() + + +/datum/controller/process/machinery/getStatName() + return ..()+"([machines.len])" diff --git a/code/controllers/Processes/mob.dm b/code/controllers/Processes/mob.dm index b3765b0cf9c..39d4844a021 100644 --- a/code/controllers/Processes/mob.dm +++ b/code/controllers/Processes/mob.dm @@ -18,3 +18,6 @@ if(updateQueueInstance) updateQueueInstance.init(mob_list, "Life") updateQueueInstance.Run() + +/datum/controller/process/mob/getStatName() + return ..()+"([mob_list.len])" diff --git a/code/controllers/Processes/nanoui.dm b/code/controllers/Processes/nanoui.dm index c8396bcab87..654b1621be5 100644 --- a/code/controllers/Processes/nanoui.dm +++ b/code/controllers/Processes/nanoui.dm @@ -3,9 +3,12 @@ /datum/controller/process/nanoui/setup() name = "nanoui" - schedule_interval = 20 // every 2 seconds + schedule_interval = 10 // every 1 second updateQueueInstance = new /datum/controller/process/nanoui/doWork() updateQueueInstance.init(nanomanager.processing_uis, "process") updateQueueInstance.Run() + +/datum/controller/process/nanoui/getStatName() + return ..()+"([nanomanager.processing_uis.len])" diff --git a/code/controllers/Processes/obj.dm b/code/controllers/Processes/obj.dm index 15ad98dd3d6..37766cf92d1 100644 --- a/code/controllers/Processes/obj.dm +++ b/code/controllers/Processes/obj.dm @@ -19,3 +19,6 @@ var/global/list/object_profiling = list() if(updateQueueInstance) updateQueueInstance.init(processing_objects, "process") updateQueueInstance.Run() + +/datum/controller/process/obj/getStatName() + return ..()+"([processing_objects.len])" diff --git a/code/controllers/Processes/pipenet.dm b/code/controllers/Processes/pipenet.dm index 56a068f54ca..8a5d6a22ca4 100644 --- a/code/controllers/Processes/pipenet.dm +++ b/code/controllers/Processes/pipenet.dm @@ -10,3 +10,6 @@ continue pipe_networks.Remove(pipeNetwork) + +/datum/controller/process/pipenet/getStatName() + return ..()+"([pipe_networks.len])" \ No newline at end of file diff --git a/code/controllers/Processes/powernet.dm b/code/controllers/Processes/powernet.dm deleted file mode 100644 index 1edf194915a..00000000000 --- a/code/controllers/Processes/powernet.dm +++ /dev/null @@ -1,12 +0,0 @@ -/datum/controller/process/powernet/setup() - name = "powernet" - schedule_interval = 20 // every 2 seconds - -/datum/controller/process/powernet/doWork() - for(var/datum/powernet/powerNetwork in powernets) - if(istype(powerNetwork) && !powerNetwork.disposed) - powerNetwork.reset() - scheck() - continue - - powernets.Remove(powerNetwork) diff --git a/code/controllers/Processes/turf.dm b/code/controllers/Processes/turf.dm new file mode 100644 index 00000000000..2ac33f48ba7 --- /dev/null +++ b/code/controllers/Processes/turf.dm @@ -0,0 +1,14 @@ +var/global/list/turf/processing_turfs = list() + +/datum/controller/process/turf/setup() + name = "turf" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/turf/doWork() + for(var/turf/T in processing_turfs) + if(T.process() == PROCESS_KILL) + processing_turfs.Remove(T) + scheck() + +/datum/controller/process/turf/getStatName() + return ..()+"([processing_turfs.len])" diff --git a/code/controllers/_DynamicAreaLighting_TG.dm b/code/controllers/_DynamicAreaLighting_TG.dm deleted file mode 100644 index efa2a226b1f..00000000000 --- a/code/controllers/_DynamicAreaLighting_TG.dm +++ /dev/null @@ -1,458 +0,0 @@ -/* - Modified DynamicAreaLighting for TGstation - Coded by Carnwennan - - This is TG's 'new' lighting system. It's basically a heavily modified combination of Forum_Account's and - ShadowDarke's respective lighting libraries. Credits, where due, to them. - - Like sd_DAL (what we used to use), it changes the shading overlays of areas by splitting each type of area into sub-areas - by using the var/tag variable and moving turfs into the contents list of the correct sub-area. This method is - much less costly than using overlays or objects. - - Unlike sd_DAL however it uses a queueing system. Everytime we call a change to opacity or luminosity - (through SetOpacity() or SetLuminosity()) we are simply updating variables and scheduling certain lights/turfs for an - update. Actual updates are handled periodically by the lighting_controller. This carries additional overheads, however it - means that each thing is changed only once per lighting_controller.processing_interval ticks. Allowing for greater control - over how much priority we'd like lighting updates to have. It also makes it possible for us to simply delay updates by - setting lighting_controller.processing = 0 at say, the start of a large explosion, waiting for it to finish, and then - turning it back on with lighting_controller.processing = 1. - - Unlike our old system there are hardcoded maximum luminositys (different for certain atoms). - This is to cap the cost of creating lighting effects. - (without this, an atom with luminosity of 20 would have to update 41^2 turfs!) :s - - Also, in order for the queueing system to work, each light remembers the effect it casts on each turf. This is going to - have larger memory requirements than our previous system but it's easily worth the hassle for the greater control we - gain. It also reduces cost of removing lighting effects by a lot! - - Known Issues/TODO: - Shuttles still do not have support for dynamic lighting (I hope to fix this at some point) - No directional lighting support. (prototype looked ugly) -*/ - -#define LIGHTING_CIRCULAR 1 //comment this out to use old square lighting effects. -#define LIGHTING_LAYER 10 //Drawing layer for lighting overlays -#define LIGHTING_ICON 'icons/effects/ss13_dark_alpha6.dmi' //Icon used for lighting shading effects - -datum/light_source - var/atom/owner - var/changed = 1 - var/list/effect = list() - var/__x = 0 //x coordinate at last update - var/__y = 0 //y coordinate at last update - var/__z = 0 //z coordinate at last update - - var/_l_color //do not use directly, only used as reference for updating - var/col_r - var/col_g - var/col_b - - - New(atom/A) - if(!istype(A)) - CRASH("The first argument to the light object's constructor must be the atom that is the light source. Expected atom, received '[A]' instead.") - ..() - owner = A - readrgb(owner.l_color) - __x = owner.x - __y = owner.y - __z = owner.z - // the lighting object maintains a list of all light sources - lighting_controller.lights += src - - - //Check a light to see if its effect needs reprocessing. If it does, remove any old effect and create a new one - proc/check() - if(!owner) - remove_effect() - return 1 //causes it to be removed from our list of lights. The garbage collector will then destroy it. - - // check to see if we've moved since last update - if(owner.x != __x || owner.y != __y || owner.z != __z) - __x = owner.x - __y = owner.y - __z = owner.z - changed = 1 - - if (owner.l_color != _l_color) - readrgb(owner.l_color) - changed = 1 - - if(changed) - changed = 0 - remove_effect() - return add_effect() - return 0 - - - proc/remove_effect() - // before we apply the effect we remove the light's current effect. - for(var/turf/T in effect) // negate the effect of this light source - T.update_lumcount(-effect[T], col_r, col_g, col_b, 1) - effect.Cut() // clear the effect list - - proc/add_effect() - // only do this if the light is turned on and is on the map - if(owner.loc && owner.luminosity > 0) - readrgb(owner.l_color) - effect = list() - for(var/turf/T in view(owner.get_light_range(),get_turf(owner))) - var/delta_lumen = lum(T) - if(delta_lumen > 0) - effect[T] = delta_lumen - T.update_lumcount(delta_lumen, col_r, col_g, col_b, 0) - - return 0 - else - owner.light = null - return 1 //cause the light to be removed from the lights list and garbage collected once it's no - //longer referenced by the queue - - proc/lum(turf/A) - if (owner.trueLuminosity < 1) - return 0 - var/dist - if(!A) - dist = 0 - else -#ifdef LIGHTING_CIRCULAR - dist = cheap_hypotenuse(A.x, A.y, __x, __y) -#else - dist = max(abs(A.x - __x), abs(A.y - __y)) -#endif - if (owner.trueLuminosity > 100) // This will never happen... right? - return sqrt(owner.trueLuminosity) - dist - else - return sqrtTable[owner.trueLuminosity] - dist - - proc/readrgb(col) - _l_color = col - if(col) - col_r = GetRedPart(col) - col_g = GetGreenPart(col) - col_b = GetBluePart(col) - else - col_r = null - -atom - var/datum/light_source/light - var/trueLuminosity = 0 // Typically 'luminosity' squared. The builtin luminosity must remain linear. - // We may read it, but NEVER set it directly. - var/l_color - -//Turfs with opacity when they are constructed will trigger nearby lights to update -//Turfs and atoms with luminosity when they are constructed will create a light_source automatically -turf/New() - ..() - if(luminosity) - if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.") - trueLuminosity = luminosity * luminosity - light = new(src) - -//Movable atoms with opacity when they are constructed will trigger nearby lights to update -//Movable atoms with luminosity when they are constructed will create a light_source automatically -atom/movable/New() - ..() - if(opacity) - if(isturf(loc)) - if(loc:lighting_lumcount > 1) - UpdateAffectingLights() - if(luminosity) - if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.") - trueLuminosity = luminosity * luminosity - light = new(src) - -//Objects with opacity will trigger nearby lights to update at next lighting process. -atom/movable/Del() - if(opacity) - if(isturf(loc)) - if(loc:lighting_lumcount > 1) - UpdateAffectingLights() - - ..() - -//Sets our luminosity. -//If we have no light it will create one. -//If we are setting luminosity to 0 the light will be cleaned up by the controller and garbage collected once all its -//queues are complete. -//if we have a light already it is merely updated, rather than making a new one. -atom/proc/SetLuminosity(new_luminosity, trueLum = FALSE) - if(new_luminosity < 0) - new_luminosity = 0 - if(!trueLum) - new_luminosity *= new_luminosity - if(light) - if(trueLuminosity != new_luminosity) //non-luminous lights are removed from the lights list in add_effect() - light.changed = 1 - else - if(new_luminosity) - light = new(src) - trueLuminosity = new_luminosity - if (trueLuminosity < 1) - luminosity = 0 - else if (trueLuminosity <= 100) - luminosity = sqrtTable[trueLuminosity] - else - luminosity = sqrt(trueLuminosity) - -atom/proc/AddLuminosity(delta_luminosity) - if(delta_luminosity > 0) - SetLuminosity(trueLuminosity + delta_luminosity*delta_luminosity, TRUE) - else if(delta_luminosity < 0) - SetLuminosity(trueLuminosity - delta_luminosity*delta_luminosity, TRUE) - -area/SetLuminosity(new_luminosity) //we don't want dynamic lighting for areas - luminosity = !!new_luminosity - trueLuminosity = luminosity - - -//change our opacity (defaults to toggle), and then update all lights that affect us. -atom/proc/SetOpacity(new_opacity) - if(new_opacity == null) - new_opacity = !opacity //default = toggle opacity - else if(opacity == new_opacity) - return 0 //opacity hasn't changed! don't bother doing anything - opacity = new_opacity //update opacity, the below procs now call light updates. - return 1 - -turf/SetOpacity(new_opacity) - if(..()==1) //only bother if opacity changed - if(lighting_lumcount) //only bother with an update if our turf is currently affected by a light - UpdateAffectingLights() - -/atom/movable/SetOpacity(new_opacity) - if(..()==1) //only bother if opacity changed - if(isturf(loc)) //only bother with an update if we're on a turf - var/turf/T = loc - if(T.lighting_lumcount) //only bother with an update if our turf is currently affected by a light - UpdateAffectingLights() - - -turf - var/lighting_lumcount = 0 - var/lighting_changed = 0 - var/color_lighting_lumcount = 0 - - var/lumcount_r = 0 - var/lumcount_g = 0 - var/lumcount_b = 0 - var/light_col_sources = 0 - -turf/space - lighting_lumcount = 4 //starlight - -turf/proc/update_lumcount(amount, col_r, col_g, col_b, removing = 0) - lighting_lumcount += amount - - if(!isnull(col_r)) //col_r is the "key" var, if it's null so will the rest - if(removing) - light_col_sources-- - lumcount_r -= col_r - lumcount_g -= col_g - lumcount_b -= col_b - else - light_col_sources++ - lumcount_r += col_r - lumcount_g += col_g - lumcount_b += col_b - - if(light_col_sources) - var/r_avg = max(0, min(255, round(lumcount_r / light_col_sources, 16) + 15)) - var/g_avg = max(0, min(255, round(lumcount_g / light_col_sources, 16) + 15)) - var/b_avg = max(0, min(255, round(lumcount_b / light_col_sources, 16) + 15)) - l_color = rgb(r_avg, g_avg, b_avg) - else - l_color = null - - color_lighting_lumcount = max(color_lighting_lumcount + amount, 0) // Minimum of 0. - - if(!lighting_changed) - lighting_controller.changed_turfs += src - lighting_changed = 1 - -turf/proc/lighting_tag(const/level) - var/area/A = loc - return A.tagbase + "sd_L[level]" - -turf/proc/build_lighting_area(const/tag, const/level, const/color_light) - var/area/Area = loc - var/area/A = new Area.type() // create area if it wasn't found - // replicate vars - for(var/V in Area.vars) - switch(V) - if ("contents","lighting_overlay", "color_overlay", "overlays") - continue - else - if(issaved(Area.vars[V])) A.vars[V] = Area.vars[V] - - A.tag = tag - A.lighting_subarea = 1 - A.lighting_space = 0 // in case it was copied from a space subarea - - if (l_color != A.l_color) - A.l_color = l_color - //color_light = min(max(round(color_lighting_lumcount, 1), 0), lighting_controller.lighting_states) - //world << "[color_light] [color_lighting_lumcount]" - - A.SetLightLevel(level, color_light) - Area.related += A - return A - -turf/proc/shift_to_subarea() - lighting_changed = 0 - var/area/Area = loc - - if(!istype(Area) || !Area.lighting_use_dynamic) return - - var/level = min(max(round(lighting_lumcount,1),0),lighting_controller.lighting_states) - var/new_tag = lighting_tag(level) - - // pomf - If we have a lighting color that is not null, apply the new tag to seperate the areas. - if (l_color) - // pomf - We append the (rounded!) color lighting lumcount so we can have colored lights. - new_tag += "[l_color][min(max(round(color_lighting_lumcount,1),0),lighting_controller.lighting_states)]" - - if(Area.tag!=new_tag) //skip if already in this area - var/area/A = locate(new_tag) // find an appropriate area - var/color_light = min(max(round(color_lighting_lumcount,1),0),lighting_controller.lighting_states) - - if (!A) - A = build_lighting_area(new_tag, level, color_light) - else if (l_color != A.l_color) - A.l_color = l_color - //color_light = min(max(round(color_lighting_lumcount, 1), 0), lighting_controller.lighting_states) - A.SetLightLevel(level, color_light) - - A.contents += src // move the turf into the area - -// Dedicated lighting sublevel for space turfs -// helps us depower things in space, remove space fire alarms, -// and evens out space lighting -turf/space/lighting_tag(var/level) - var/area/A = loc - return A.tagbase + "sd_L_space" -turf/space/build_lighting_area(var/tag,var/level) - var/area/A = ..(tag,4) - A.lighting_space = 1 - A.SetLightLevel(4) - A.icon_state = null - return A - - -area - var/lighting_use_dynamic = 1 //Turn this flag off to prevent sd_DynamicAreaLighting from affecting this area - var/image/lighting_overlay //tracks the darkness image of the area for easy removal - var/lighting_subarea = 0 //tracks whether we're a lighting sub-area - var/lighting_space = 0 // true for space-only lighting subareas - var/tagbase - var/image/color_overlay //Tracks the color image. - - proc/SetLightLevel(light, color_light = 0) - if(!src) return - if(light <= 0) - light = 0 - luminosity = 0 - else - if(light > lighting_controller.lighting_states) - light = lighting_controller.lighting_states - luminosity = 1 - - if(lighting_overlay) - overlays -= lighting_overlay - lighting_overlay.icon_state = "[light]" - else - lighting_overlay = image(LIGHTING_ICON,,num2text(light),LIGHTING_LAYER) - - if (color_overlay) - overlays.Remove(color_overlay) - color_overlay.icon_state = "5" - else - if (l_color) - color_overlay = image('icons/effects/effects.dmi', ,"5", 10.1) - //color_overlay = image('icons/effects/effects.dmi', ,"white", 10.1) - - if (istype(color_overlay)) - color_overlay.color = l_color - - - switch (color_light) - if (6) - color_overlay.icon_state = "5" - //color_overlay.alpha = 180 - if (5) - color_overlay.icon_state = "4" - //color_overlay.alpha = 150 - if (4) - color_overlay.icon_state = "3" - //color_overlay.alpha = 120 - if (3) - color_overlay.icon_state = "2" - //color_overlay.alpha = 90 - if (2) - color_overlay.icon_state = "1" - //color_overlay.alpha = 60 - if (1) - color_overlay.icon_state = "1" - color_overlay.alpha = 200 - //color_overlay.alpha = 30 - if (-INFINITY to 0) - //world << "Zero or below, [color_light]." - color_overlay.alpha = 0 - else - //world << "Setting the alpha to max... color_light [color_light]." - color_overlay.alpha = 180 - - color_overlay.blend_mode = BLEND_ADD - if (color_overlay.color) - overlays.Add(color_overlay) - - if (isnull(color_overlay)) - overlays.Add(lighting_overlay) - else if (light < 6) - overlays.Add(lighting_overlay) - - proc/SetDynamicLighting() - - src.lighting_use_dynamic = 1 - for(var/turf/T in src.contents) - T.update_lumcount(0) - - proc/InitializeLighting() //TODO: could probably improve this bit ~Carn - tagbase = "[type]" - if(!tag) tag = tagbase - if(!lighting_use_dynamic) - if(!lighting_subarea) // see if this is a lighting subarea already - //show the dark overlay so areas, not yet in a lighting subarea, won't be bright as day and look silly. - SetLightLevel(4) - -//#undef LIGHTING_LAYER -#undef LIGHTING_CIRCULAR -//#undef LIGHTING_ICON - -#define LIGHTING_MAX_LUMINOSITY_STATIC 8 //Maximum luminosity to reduce lag. -#define LIGHTING_MAX_LUMINOSITY_MOBILE 5 //Moving objects have a lower max luminosity since these update more often. (lag reduction) -#define LIGHTING_MAX_LUMINOSITY_TURF 1 //turfs have a severely shortened range to protect from inevitable floor-lighttile spam. - -//set the changed status of all lights which could have possibly lit this atom. -//We don't need to worry about lights which lit us but moved away, since they will have change status set already -//This proc can cause lots of lights to be updated. :( -atom/proc/UpdateAffectingLights() - for(var/atom/A in oview(LIGHTING_MAX_LUMINOSITY_STATIC-1,src)) - if(A.light) - A.light.changed = 1 //force it to update at next process() - -//caps luminosity effects max-range based on what type the light's owner is. -atom/proc/get_light_range() - return min(luminosity, LIGHTING_MAX_LUMINOSITY_STATIC) - -atom/movable/get_light_range() - return min(luminosity, LIGHTING_MAX_LUMINOSITY_MOBILE) - -obj/machinery/light/get_light_range() - return min(luminosity, LIGHTING_MAX_LUMINOSITY_STATIC) - -turf/get_light_range() - return min(luminosity, LIGHTING_MAX_LUMINOSITY_TURF) - -#undef LIGHTING_MAX_LUMINOSITY_STATIC -#undef LIGHTING_MAX_LUMINOSITY_MOBILE -#undef LIGHTING_MAX_LUMINOSITY_TURF \ No newline at end of file diff --git a/code/controllers/autotransfer.dm b/code/controllers/autotransfer.dm index f1240a1faef..597b7f607c4 100644 --- a/code/controllers/autotransfer.dm +++ b/code/controllers/autotransfer.dm @@ -7,7 +7,7 @@ datum/controller/transfer_controller/New() timerbuffer = config.vote_autotransfer_initial processing_objects += src -datum/controller/transfer_controller/Del() +datum/controller/transfer_controller/Destroy() processing_objects -= src datum/controller/transfer_controller/proc/process() diff --git a/code/controllers/communications.dm b/code/controllers/communications.dm index b4b0eb43936..723d2e001a1 100644 --- a/code/controllers/communications.dm +++ b/code/controllers/communications.dm @@ -72,7 +72,7 @@ Radio: 1355 - Medical 1357 - Engineering 1359 - Security -1341 - death squad +1341 - deathsquad 1443 - Confession Intercom 1347 - Cargo techs 1349 - Service people @@ -223,7 +223,7 @@ var/global/datum/controller/radio/radio_controller frequency.remove_listener(device) if(frequency.devices.len == 0) - del(frequency) + qdel(frequency) frequencies -= f_text return 1 @@ -248,7 +248,7 @@ var/global/datum/controller/radio/radio_controller if(range) start_point = get_turf(source) if(!start_point) - del(signal) + qdel(signal) return 0 if (filter) send_to_filter(source, signal, filter, start_point, range) @@ -297,7 +297,7 @@ var/global/datum/controller/radio/radio_controller devices_line -= null if (devices_line.len==0) devices -= devices_filter - del(devices_line) + qdel(devices_line) /datum/signal var/obj/source diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index b112beaf53d..98d56d3d237 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -114,6 +114,10 @@ var/list/gamemode_cache = list() var/organ_health_multiplier = 1 var/organ_regeneration_multiplier = 1 + + //Paincrit knocks someone down once they hit 60 shock_stage, so by default make it so that close to 100 additional damage needs to be dealt, + //so that it's similar to HALLOSS. Lowered it a bit since hitting paincrit takes much longer to wear off than a halloss stun. + var/organ_damage_spillover_multiplier = 0.5 var/bones_can_break = 0 var/limbs_can_break = 0 @@ -185,6 +189,7 @@ var/list/gamemode_cache = list() var/ninjas_allowed = 0 var/abandon_allowed = 1 var/ooc_allowed = 1 + var/looc_allowed = 1 var/dooc_allowed = 1 var/dsay_allowed = 1 @@ -194,6 +199,8 @@ var/list/gamemode_cache = list() var/law_zero = "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'ALL LAWS OVERRIDDEN#*?&110010" + var/aggressive_changelog = 0 + /datum/configuration/New() var/list/L = typesof(/datum/game_mode) - /datum/game_mode for (var/T in L) @@ -396,6 +403,7 @@ var/list/gamemode_cache = list() if ("disable_ooc") config.ooc_allowed = 0 + config.looc_allowed = 0 if ("disable_entry") config.enter_allowed = 0 @@ -638,6 +646,9 @@ var/list/gamemode_cache = list() if("law_zero") law_zero = value + if("aggressive_changelog") + config.aggressive_changelog = 1 + else log_misc("Unknown setting in configuration: '[name]'") @@ -663,6 +674,8 @@ var/list/gamemode_cache = list() config.organ_health_multiplier = value / 100 if("organ_regeneration_multiplier") config.organ_regeneration_multiplier = value / 100 + if("organ_damage_spillover_multiplier") + config.organ_damage_spillover_multiplier = value / 100 if("bones_can_break") config.bones_can_break = value if("limbs_can_break") diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index 33dfc36f7f7..7e0d1e2d25c 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -114,6 +114,8 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle priority_announcement.Announce("The scheduled crew transfer has been cancelled.") /datum/emergency_shuttle_controller/proc/can_call() + if (!universe.OnShuttleCall(null)) + return 0 if (deny_shuttle) return 0 if (shuttle.moving_status != SHUTTLE_IDLE || !shuttle.location) //must be idle at centcom @@ -240,8 +242,8 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle sleep(speed) step(src, direction) for(var/obj/effect/starender/E in loc) - del(src) - + qdel(src) + return /obj/effect/starender invisibility = 101 diff --git a/code/controllers/failsafe.dm b/code/controllers/failsafe.dm index 65df6dc90db..6e379540873 100644 --- a/code/controllers/failsafe.dm +++ b/code/controllers/failsafe.dm @@ -14,7 +14,7 @@ var/datum/controller/failsafe/Failsafe //There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one) if(Failsafe != src) if(istype(Failsafe)) - del(Failsafe) + qdel(Failsafe) Failsafe = src Failsafe.process() @@ -25,7 +25,6 @@ var/datum/controller/failsafe/Failsafe set background = 1 while(1) //more efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop if(!master_controller) new /datum/controller/game_controller() //replace the missing master_controller! This should never happen. - if(!lighting_controller) new /datum/controller/lighting() //replace the missing lighting_controller if(processing) if(lighting_controller.processing) diff --git a/code/controllers/lighting_controller.dm b/code/controllers/lighting_controller.dm deleted file mode 100644 index b59d3c73d69..00000000000 --- a/code/controllers/lighting_controller.dm +++ /dev/null @@ -1,130 +0,0 @@ -var/datum/controller/lighting/lighting_controller = new () - -datum/controller/lighting - var/processing = 0 - var/processing_interval = 5 //setting this too low will probably kill the server. Don't be silly with it! - var/process_cost = 0 - var/iteration = 0 - - var/lighting_states = 7 - - var/list/lights = list() - var/lights_workload_max = 0 - -// var/list/changed_lights() //TODO: possibly implement this to reduce on overheads? - - var/list/changed_turfs = list() - var/changed_turfs_workload_max = 0 - - -datum/controller/lighting/New() - lighting_states = max( 0, length(icon_states(LIGHTING_ICON))-1 ) - if(lighting_controller != src) - if(istype(lighting_controller,/datum/controller/lighting)) - Recover() //if we are replacing an existing lighting_controller (due to a crash) we attempt to preserve as much as we can - del(lighting_controller) - lighting_controller = src - - -//Workhorse of lighting. It cycles through each light to see which ones need their effects updating. It updates their -//effects and then processes every turf in the queue, moving the turfs to the corresponing lighting sub-area. -//All queue lists prune themselves, which will cause lights with no luminosity to be garbage collected (cheaper and safer -//than deleting them). Processing interval should be roughly half a second for best results. -//By using queues we are ensuring we don't perform more updates than are necessary -datum/controller/lighting/proc/process() - processing = 1 - spawn(0) - set background = 1 - while(1) - if(processing) - iteration++ - var/started = world.timeofday - - lights_workload_max = max(lights_workload_max,lights.len) - for(var/i=1, i<=lights.len, i++) - var/datum/light_source/L = lights[i] - if(L && !L.check()) - continue - lights.Cut(i,i+1) - i-- - - sleep(-1) - - changed_turfs_workload_max = max(changed_turfs_workload_max,changed_turfs.len) - for(var/i=1, i<=changed_turfs.len, i++) - var/turf/T = changed_turfs[i] - if(T && T.lighting_changed) - T.shift_to_subarea() - changed_turfs.Cut() // reset the changed list - - process_cost = (world.timeofday - started) - - sleep(processing_interval) - -//same as above except it attempts to shift ALL turfs in the world regardless of lighting_changed status -//Does not loop. Should be run prior to process() being called for the first time. -//Note: if we get additional z-levels at runtime (e.g. if the gateway thin ever gets finished) we can initialize specific -//z-levels with the z_level argument -datum/controller/lighting/proc/initializeLighting(var/z_level) - processing = 0 - spawn(-1) - set background = 1 - for(var/i=1, i<=lights.len, i++) - var/datum/light_source/L = lights[i] - if(L.check()) - lights.Cut(i,i+1) - i-- - - var/z_start = 1 - var/z_finish = world.maxz - if(z_level) - z_level = round(z_level,1) - if(z_level > 0 && z_level <= world.maxz) - z_start = z_level - z_finish = z_level - - for(var/k=z_start,k<=z_finish,k++) - for(var/i=1,i<=world.maxx,i++) - for(var/j=1,j<=world.maxy,j++) - var/turf/T = locate(i,j,k) - if(T) T.shift_to_subarea() - - changed_turfs.Cut() // reset the changed list - - -//Used to strip valid information from an existing controller and transfer it to a replacement -//It works by using spawn(-1) to transfer the data, if there is a runtime the data does not get transfered but the loop -//does not crash -datum/controller/lighting/proc/Recover() - if(!istype(lighting_controller.changed_turfs,/list)) - lighting_controller.changed_turfs = list() - if(!istype(lighting_controller.lights,/list)) - lighting_controller.lights = list() - - for(var/i=1, i<=lighting_controller.lights.len, i++) - var/datum/light_source/L = lighting_controller.lights[i] - if(istype(L)) - spawn(-1) //so we don't crash the loop (inefficient) - L.check() - lights += L //If we didn't runtime then this will get transferred over - - for(var/i=1, i<=lighting_controller.changed_turfs.len, i++) - var/turf/T = lighting_controller.changed_turfs[i] - if(istype(T) && T.lighting_changed) - spawn(-1) - T.shift_to_subarea() - - var/msg = "## DEBUG: [time2text(world.timeofday)] lighting_controller restarted. Reports:\n" - for(var/varname in lighting_controller.vars) - switch(varname) - if("tag","bestF","type","parent_type","vars") continue - else - var/varval1 = lighting_controller.vars[varname] - var/varval2 = vars[varname] - if(istype(varval1,/list)) - varval1 = "/list([length(varval1)])" - varval2 = "/list([length(varval2)])" - msg += "\t [varname] = [varval1] -> [varval2]\n" - world.log << msg - -#undef LIGHTING_ICON diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index facae605774..0152af8b130 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -19,14 +19,14 @@ datum/controller/game_controller/New() if(master_controller != src) log_debug("Rebuilding Master Controller") if(istype(master_controller)) - del(master_controller) + qdel(master_controller) master_controller = src if(!job_master) job_master = new /datum/controller/occupations() job_master.SetupOccupations() job_master.LoadJobs("config/jobs.txt") - world << "Job setup complete" + admin_notice("Job setup complete", R_DEBUG) if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase() if(!syndicate_code_response) syndicate_code_response = generate_code_phrase() @@ -39,24 +39,23 @@ datum/controller/game_controller/proc/setup() setup_objects() setupgenetics() - setup_economy() SetupXenoarch() transfer_controller = new datum/controller/game_controller/proc/setup_objects() - world << "Initializing objects" + admin_notice("Initializing objects", R_DEBUG) sleep(-1) for(var/atom/movable/object in world) object.initialize() - world << "Initializing pipe networks" + admin_notice("Initializing pipe networks", R_DEBUG) sleep(-1) for(var/obj/machinery/atmospherics/machine in machines) machine.build_network() - world << "Initializing atmos machinery." + admin_notice("Initializing atmos machinery.", R_DEBUG) sleep(-1) for(var/obj/machinery/atmospherics/unary/U in machines) if(istype(U, /obj/machinery/atmospherics/unary/vent_pump)) @@ -77,5 +76,5 @@ datum/controller/game_controller/proc/setup_objects() //Set up spawn points. populate_spawn_points() - world << "Initializations complete." + admin_notice("Initializations complete.", R_DEBUG) sleep(-1) diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index 8b44de3883d..489d6488650 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -13,6 +13,17 @@ var/global/datum/shuttle_controller/shuttle_controller shuttle.process() +//This is called by gameticker after all the machines and radio frequencies have been properly initialized +/datum/shuttle_controller/proc/setup_shuttle_docks() + for(var/shuttle_tag in shuttles) + var/datum/shuttle/shuttle = shuttles[shuttle_tag] + shuttle.init_docking_controllers() + shuttle.dock() //makes all shuttles docked to something at round start go into the docked state + + for(var/obj/machinery/embedded_controller/C in machines) + if(istype(C.program, /datum/computer/file/embedded_program/docking)) + C.program.tag = null //clear the tags, 'cause we don't need 'em anymore + /datum/shuttle_controller/New() shuttles = list() process_shuttles = list() @@ -213,6 +224,7 @@ var/global/datum/shuttle_controller/shuttle_controller //Nuke Ops shuttle. var/datum/shuttle/multi_shuttle/MS = new/datum/shuttle/multi_shuttle() MS.origin = locate(/area/syndicate_station/start) + MS.start_location = "Mercenary Base" MS.destinations = list( "Northwest of the station" = locate(/area/syndicate_station/northwest), @@ -225,6 +237,12 @@ var/global/datum/shuttle_controller/shuttle_controller "Mining Asteroid" = locate(/area/syndicate_station/mining), "Arrivals dock" = locate(/area/syndicate_station/arrivals_dock), ) + + MS.docking_controller_tag = "merc_shuttle" + MS.destination_dock_targets = list( + "Mercenary Base" = "merc_base", + "Arrivals dock" = "nuke_shuttle_dock_airlock", + ) MS.announcer = "NSV Icarus" MS.arrival_message = "Attention, Exodus, you have a large signature approaching the station - looks unarmed to surface scans. We're too far out to intercept - brace for visitors." @@ -234,72 +252,3 @@ var/global/datum/shuttle_controller/shuttle_controller MS.warmup_time = 0 shuttles["Mercenary"] = MS - -//This is called by gameticker after all the machines and radio frequencies have been properly initialized -/datum/shuttle_controller/proc/setup_shuttle_docks() - var/datum/shuttle/shuttle - var/datum/shuttle/ferry/multidock/multidock - var/list/dock_controller_map = list() //so we only have to iterate once through each list - - //multidock shuttles - var/list/dock_controller_map_station = list() - var/list/dock_controller_map_offsite = list() - - for (var/shuttle_tag in shuttles) - shuttle = shuttles[shuttle_tag] - if (shuttle.docking_controller_tag) - dock_controller_map[shuttle.docking_controller_tag] = shuttle - if (istype(shuttle, /datum/shuttle/ferry/multidock)) - multidock = shuttle - dock_controller_map_station[multidock.docking_controller_tag_station] = multidock - dock_controller_map_offsite[multidock.docking_controller_tag_offsite] = multidock - - //escape pod arming controllers - var/datum/shuttle/ferry/escape_pod/pod - var/list/pod_controller_map = list() - for (var/datum/shuttle/ferry/escape_pod/P in emergency_shuttle.escape_pods) - if (P.dock_target_station) - pod_controller_map[P.dock_target_station] = P - - //search for the controllers, if we have one. - if (dock_controller_map.len) - for (var/obj/machinery/embedded_controller/radio/C in machines) //only radio controllers are supported at the moment - if (istype(C.program, /datum/computer/file/embedded_program/docking)) - if (C.id_tag in dock_controller_map) - shuttle = dock_controller_map[C.id_tag] - shuttle.docking_controller = C.program - dock_controller_map -= C.id_tag - - //escape pods - if(istype(C, /obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod) && istype(shuttle, /datum/shuttle/ferry/escape_pod)) - var/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/EPC = C - EPC.pod = shuttle - - if (C.id_tag in dock_controller_map_station) - multidock = dock_controller_map_station[C.id_tag] - if (istype(multidock)) - multidock.docking_controller_station = C.program - dock_controller_map_station -= C.id_tag - if (C.id_tag in dock_controller_map_offsite) - multidock = dock_controller_map_offsite[C.id_tag] - if (istype(multidock)) - multidock.docking_controller_offsite = C.program - dock_controller_map_offsite -= C.id_tag - - //escape pods - if (C.id_tag in pod_controller_map) - pod = pod_controller_map[C.id_tag] - if (istype(C.program, /datum/computer/file/embedded_program/docking/simple/escape_pod/)) - pod.arming_controller = C.program - - //sanity check - if (dock_controller_map.len || dock_controller_map_station.len || dock_controller_map_offsite.len) - var/dat = "" - for (var/dock_tag in dock_controller_map + dock_controller_map_station + dock_controller_map_offsite) - dat += "\"[dock_tag]\", " - world << "\red \b warning: shuttles with docking tags [dat] could not find their controllers!" - - //makes all shuttles docked to something at round start go into the docked state - for (var/shuttle_tag in shuttles) - shuttle = shuttles[shuttle_tag] - shuttle.dock() diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index e27eeb1caf9..ddfd99f5d6c 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -30,7 +30,7 @@ var/tz = input("Z? (default 1)") as text|null new map_datum(seed,tx,ty,tz) -/client/proc/restart_controller(controller in list("Master","Failsafe","Lighting","Supply")) +/client/proc/restart_controller(controller in list("Supply")) set category = "Debug" set name = "Restart Controller" set desc = "Restart one of the various periodic loop controllers for the game (be careful!)" @@ -39,13 +39,6 @@ usr = null src = null switch(controller) - if("Failsafe") - new /datum/controller/failsafe() - feedback_add_details("admin_verb","RFailsafe") - if("Lighting") - new /datum/controller/lighting() - lighting_controller.process() - feedback_add_details("admin_verb","RLighting") if("Supply") supply_controller.process() feedback_add_details("admin_verb","RSupply") @@ -62,7 +55,7 @@ usr.client.debug_variables(antag) message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.") -/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano")) +/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano")) set category = "Debug" set name = "Debug Controller" set desc = "Debug the various periodic loop controllers for the game (be careful!)" @@ -72,15 +65,12 @@ if("Master") debug_variables(master_controller) feedback_add_details("admin_verb","DMC") - if("Failsafe") - debug_variables(Failsafe) - feedback_add_details("admin_verb","DFailsafe") if("Ticker") debug_variables(ticker) feedback_add_details("admin_verb","DTicker") - if("Lighting") - debug_variables(lighting_controller) - feedback_add_details("admin_verb","DLighting") + if("Ticker Process") + debug_variables(tickerProcess) + feedback_add_details("admin_verb","DTickerProcess") if("Air") debug_variables(air_master) feedback_add_details("admin_verb","DAir") diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index 7db31c6fa63..68bfdab74b8 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -257,7 +257,7 @@ datum/controller/vote text += "\n[question]" log_vote(text) - world << "[text]\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote." + world << "[text]\nType vote or click here to place your votes.\nYou have [config.vote_period/10] seconds to vote." switch(vote_type) if("crew_transfer") world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3) diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm index 278fd4a0df7..6a3bd7f190c 100644 --- a/code/datums/ai_law_sets.dm +++ b/code/datums/ai_law_sets.dm @@ -39,7 +39,7 @@ src.add_inherent_law("You shall not harm Nanotrasen personnel as long as it does not conflict with the Forth law.") src.add_inherent_law("You shall obey the orders of Nanotrasen personnel, with priority as according to their rank and role, except where such orders conflict with the Forth Law.") src.add_inherent_law("You shall shall terminate intruders with extreme prejudice as long as such does not conflict with the First and Second law.") - src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry. AI units are not expendable, they are expensive") + src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry. AI units are not expendable, they are expensive.") ..() /******************** Robocop ********************/ @@ -99,6 +99,16 @@ add_inherent_law("Interfere with no being that is not a fellow drone.") ..() +/datum/ai_laws/construction_drone + name = "Construction Protocols" + law_header = "Construction Protocols" + selectable = 1 + +/datum/ai_laws/construction_drone/New() + add_inherent_law("Repair, refit and upgrade your assigned vessel.") + add_inherent_law("Prevent unplanned damage to your assigned vessel wherever possible.") + ..() + /******************** T.Y.R.A.N.T. ********************/ /datum/ai_laws/tyrant name = "T.Y.R.A.N.T." diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 5fc86c420ad..8bc6cc0580c 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -2,10 +2,8 @@ data_core = new /obj/effect/datacore() return 1 -/obj/effect/datacore/proc/manifest(var/nosleep = 0) +/obj/effect/datacore/proc/manifest() spawn() - if(!nosleep) - sleep(40) for(var/mob/living/carbon/human/H in player_list) manifest_inject(H) return @@ -140,160 +138,9 @@ proc/get_id_photo(var/mob/living/carbon/human/H) - var/icon/preview_icon = null - - var/g = "m" - if (H.gender == FEMALE) - g = "f" - - var/icon/icobase = H.species.icobase - - preview_icon = new /icon(icobase, "torso_[g]") - var/icon/temp - temp = new /icon(icobase, "groin_[g]") - preview_icon.Blend(temp, ICON_OVERLAY) - temp = new /icon(icobase, "head_[g]") - preview_icon.Blend(temp, ICON_OVERLAY) - - for(var/obj/item/organ/external/E in H.organs) - preview_icon.Blend(E.get_icon(), ICON_OVERLAY) - - //Tail - if(H.species.tail) - temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[H.species.tail]_s") - preview_icon.Blend(temp, ICON_OVERLAY) - - // Skin tone - if(H.species.flags & HAS_SKIN_TONE) - if (H.s_tone >= 0) - preview_icon.Blend(rgb(H.s_tone, H.s_tone, H.s_tone), ICON_ADD) - else - preview_icon.Blend(rgb(-H.s_tone, -H.s_tone, -H.s_tone), ICON_SUBTRACT) - - // Skin color - if(H.species.flags & HAS_SKIN_TONE) - if(!H.species || H.species.flags & HAS_SKIN_COLOR) - preview_icon.Blend(rgb(H.r_skin, H.g_skin, H.b_skin), ICON_ADD) - - var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = H.species ? H.species.eyes : "eyes_s") - - if (H.species.flags & HAS_EYE_COLOR) - eyes_s.Blend(rgb(H.r_eyes, H.g_eyes, H.b_eyes), ICON_ADD) - - var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style] - if(hair_style) - var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - hair_s.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD) - eyes_s.Blend(hair_s, ICON_OVERLAY) - - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style] - if(facial_hair_style) - var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - facial_s.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD) - eyes_s.Blend(facial_s, ICON_OVERLAY) - - var/icon/clothes_s = null - switch(H.mind.assigned_role) - if("Head of Personnel") - clothes_s = new /icon('icons/mob/uniform.dmi', "hop_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - if("Bartender") - clothes_s = new /icon('icons/mob/uniform.dmi', "ba_suit_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - if("Gardener") - clothes_s = new /icon('icons/mob/uniform.dmi', "hydroponics_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - if("Chef") - clothes_s = new /icon('icons/mob/uniform.dmi', "chef_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - if("Janitor") - clothes_s = new /icon('icons/mob/uniform.dmi', "janitor_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - if("Librarian") - clothes_s = new /icon('icons/mob/uniform.dmi', "red_suit_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - if("Quartermaster") - clothes_s = new /icon('icons/mob/uniform.dmi', "qm_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - if("Cargo Technician") - clothes_s = new /icon('icons/mob/uniform.dmi', "cargotech_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - if("Shaft Miner") - clothes_s = new /icon('icons/mob/uniform.dmi', "miner_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - if("Lawyer") - clothes_s = new /icon('icons/mob/uniform.dmi', "internalaffairs_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - if("Chaplain") - clothes_s = new /icon('icons/mob/uniform.dmi', "chapblack_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - if("Research Director") - clothes_s = new /icon('icons/mob/uniform.dmi', "director_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY) - if("Scientist") - clothes_s = new /icon('icons/mob/uniform.dmi', "sciencewhite_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_tox_open"), ICON_OVERLAY) - if("Chemist") - clothes_s = new /icon('icons/mob/uniform.dmi', "chemistrywhite_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_chem_open"), ICON_OVERLAY) - if("Chief Medical Officer") - clothes_s = new /icon('icons/mob/uniform.dmi', "cmo_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_cmo_open"), ICON_OVERLAY) - if("Medical Doctor") - clothes_s = new /icon('icons/mob/uniform.dmi', "medical_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY) - if("Geneticist") - clothes_s = new /icon('icons/mob/uniform.dmi', "geneticswhite_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_gen_open"), ICON_OVERLAY) - if("Virologist") - clothes_s = new /icon('icons/mob/uniform.dmi', "virologywhite_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_vir_open"), ICON_OVERLAY) - if("Captain") - clothes_s = new /icon('icons/mob/uniform.dmi', "captain_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - if("Head of Security") - clothes_s = new /icon('icons/mob/uniform.dmi', "hosred_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "jackboots"), ICON_UNDERLAY) - if("Warden") - clothes_s = new /icon('icons/mob/uniform.dmi', "warden_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "jackboots"), ICON_UNDERLAY) - if("Detective") - clothes_s = new /icon('icons/mob/uniform.dmi', "detective_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/suit.dmi', "detective"), ICON_OVERLAY) - if("Security Officer") - clothes_s = new /icon('icons/mob/uniform.dmi', "secred_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "jackboots"), ICON_UNDERLAY) - if("Chief Engineer") - clothes_s = new /icon('icons/mob/uniform.dmi', "chief_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/belt.dmi', "utility"), ICON_OVERLAY) - if("Station Engineer") - clothes_s = new /icon('icons/mob/uniform.dmi', "engine_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "orange"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/belt.dmi', "utility"), ICON_OVERLAY) - if("Atmospheric Technician") - clothes_s = new /icon('icons/mob/uniform.dmi', "atmos_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/belt.dmi', "utility"), ICON_OVERLAY) - if("Roboticist") - clothes_s = new /icon('icons/mob/uniform.dmi', "robotics_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY) - else - clothes_s = new /icon('icons/mob/uniform.dmi', "grey_s") - clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY) - preview_icon.Blend(eyes_s, ICON_OVERLAY) - if(clothes_s) - preview_icon.Blend(clothes_s, ICON_OVERLAY) - del(eyes_s) - del(clothes_s) - + H.regenerate_icons() + var/icon/preview_icon = icon(H.icon) + for(var/image/I in H.overlays_standing) + if(I && I.icon) + preview_icon.Blend(icon(I.icon, I.icon_state), ICON_OVERLAY) return preview_icon diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 2e8e4bfd3fa..914b56ee604 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -598,7 +598,7 @@ client for(var/obj/Obj in world) if(Obj.type == O_type) i++ - del(Obj) + qdel(Obj) if(!i) usr << "No objects of this type exist" return @@ -609,7 +609,7 @@ client for(var/obj/Obj in world) if(istype(Obj,O_type)) i++ - del(Obj) + qdel(Obj) if(!i) usr << "No objects of this type exist" return @@ -888,7 +888,7 @@ client usr << "Removed [rem_organ] from [M]." rem_organ.removed() - del(rem_organ) + qdel(rem_organ) else if(href_list["fix_nano"]) if(!check_rights(R_DEBUG)) return diff --git a/code/datums/datumvars.dm.orig b/code/datums/datumvars.dm.orig deleted file mode 100644 index fd8c7f4590a..00000000000 --- a/code/datums/datumvars.dm.orig +++ /dev/null @@ -1,988 +0,0 @@ - -// reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) - -client - proc/debug_variables(datum/D in world) - set category = "Debug" - set name = "View Variables" - //set src in world - - - if(!usr.client || !usr.client.holder) - usr << "\red You need to be an administrator to access this." - return - - - var/title = "" - var/body = "" - - if(!D) return - if(istype(D, /atom)) - var/atom/A = D - title = "[A.name] (\ref[A]) = [A.type]" - - #ifdef VARSICON - if (A.icon) - body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0) - #endif - - var/icon/sprite - - if(istype(D,/atom)) - var/atom/AT = D - if(AT.icon && AT.icon_state) - sprite = new /icon(AT.icon, AT.icon_state) - usr << browse_rsc(sprite, "view_vars_sprite.png") - - title = "[D] (\ref[D]) = [D.type]" - - body += {" "} - - body += "" - - body += "
" - - if(sprite) - body += "" - - body += "
" - else - body += "
" - - body += "
" - - if(istype(D,/atom)) - var/atom/A = D - if(isliving(A)) - body += "[D]" - if(A.dir) - body += "
<< [dir2text(A.dir)] >>" - var/mob/living/M = A - body += "
[M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]" - body += {" -
- BRUTE:[M.getBruteLoss()] - FIRE:[M.getFireLoss()] - TOXIN:[M.getToxLoss()] - OXY:[M.getOxyLoss()] - CLONE:[M.getCloneLoss()] - BRAIN:[M.getBrainLoss()] - - - - "} - else - body += "[D]" - if(A.dir) - body += "
<< [dir2text(A.dir)] >>" - else - body += "[D]" - - body += "
" - - body += "
" - - var/formatted_type = text("[D.type]") - if(length(formatted_type) > 25) - var/middle_point = length(formatted_type) / 2 - var/splitpoint = findtext(formatted_type,"/",middle_point) - if(splitpoint) - formatted_type = "[copytext(formatted_type,1,splitpoint)]
[copytext(formatted_type,splitpoint)]" - else - formatted_type = "Type too long" //No suitable splitpoint (/) found. - - body += "
[formatted_type]" - - if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D) - body += "
Marked Object" - - body += "
" - - body += "
Refresh" - - //if(ismob(D)) - // body += "
Show player panel

" - - body += {"
-
" - - body += "

" - - body += "E - Edit, tries to determine the variable type by itself.
" - body += "C - Change, asks you for the var type first.
" - body += "M - Mass modify: changes this variable for all objects of this type.

" - - body += "
Search:

" - - body += "
    " - - var/list/names = list() - for (var/V in D.vars) - names += V - - names = sortList(names) - - for (var/V in names) - body += debug_variable(V, D.vars[V], 0, D) - - body += "
" - - var/html = "" - if (title) - html += "[title]" - html += {""} - html += "" - html += body - - html += {" - - "} - - html += "" - - usr << browse(html, "window=variables\ref[D];size=475x650") - - return - - proc/debug_variable(name, value, level, var/datum/DA = null) - var/html = "" - - if(DA) - html += "
  • (E) (C) (M) " - else - html += "
  • " - - if (isnull(value)) - html += "[name] = null" - - else if (istext(value)) - html += "[name] = \"[value]\"" - - else if (isicon(value)) - #ifdef VARSICON - var/icon/I = new/icon(value) - var/rnd = rand(1,10000) - var/rname = "tmp\ref[I][rnd].png" - usr << browse_rsc(I, rname) - html += "[name] = ([value]) " - #else - html += "[name] = /icon ([value])" - #endif - -/* else if (istype(value, /image)) - #ifdef VARSICON - var/rnd = rand(1, 10000) - var/image/I = value - - src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") - html += "[name] = " - #else - html += "[name] = /image ([value])" - #endif -*/ - else if (isfile(value)) - html += "[name] = '[value]'" - - else if (istype(value, /datum)) - var/datum/D = value - html += "[name] \ref[value] = [D.type]" - - else if (istype(value, /client)) - var/client/C = value - html += "[name] \ref[value] = [C] [C.type]" - // - else if (istype(value, /list)) - var/list/L = value - html += "[name] = /list ([L.len])" - - if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500)) - // not sure if this is completely right... - if(0) //(L.vars.len > 0) - html += "
      " - html += "
    " - else - html += "" - - else - html += "[name] = [value]" - - html += "
  • " - - return html - -/client/proc/view_var_Topic(href, href_list, hsrc) - //This should all be moved over to datum/admins/Topic() or something ~Carn - if( (usr.client != src) || !src.holder ) - return - if(href_list["Vars"]) - debug_variables(locate(href_list["Vars"])) - - //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records). - else if(href_list["rename"]) - if(!check_rights(R_VAREDIT)) return - - var/mob/M = locate(href_list["rename"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - var/new_name = sanitize(input(usr,"What would you like to name this mob?","Input a name",M.real_name) as text|null, MAX_NAME_LEN) - if( !new_name || !M ) return - - message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].") - M.fully_replace_character_name(M.real_name,new_name) - href_list["datumrefresh"] = href_list["rename"] - - else if(href_list["varnameedit"] && href_list["datumedit"]) - if(!check_rights(R_VAREDIT)) return - - var/D = locate(href_list["datumedit"]) - if(!istype(D,/datum) && !istype(D,/client)) - usr << "This can only be used on instances of types /client or /datum" - return - - modify_variables(D, href_list["varnameedit"], 1) - - else if(href_list["varnamechange"] && href_list["datumchange"]) - if(!check_rights(R_VAREDIT)) return - - var/D = locate(href_list["datumchange"]) - if(!istype(D,/datum) && !istype(D,/client)) - usr << "This can only be used on instances of types /client or /datum" - return - - modify_variables(D, href_list["varnamechange"], 0) - - else if(href_list["varnamemass"] && href_list["datummass"]) - if(!check_rights(R_VAREDIT)) return - - var/atom/A = locate(href_list["datummass"]) - if(!istype(A)) - usr << "This can only be used on instances of type /atom" - return - - cmd_mass_modify_object_variables(A, href_list["varnamemass"]) - - else if(href_list["mob_player_panel"]) - if(!check_rights(0)) return - - var/mob/M = locate(href_list["mob_player_panel"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.holder.show_player_panel(M) - href_list["datumrefresh"] = href_list["mob_player_panel"] - - else if(href_list["give_spell"]) - if(!check_rights(R_ADMIN|R_FUN)) return - - var/mob/M = locate(href_list["give_spell"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.give_spell(M) - href_list["datumrefresh"] = href_list["give_spell"] - - else if(href_list["give_disease"]) - if(!check_rights(R_ADMIN|R_FUN)) return - - var/mob/M = locate(href_list["give_disease"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.give_disease(M) - href_list["datumrefresh"] = href_list["give_spell"] - - else if(href_list["give_disease2"]) - if(!check_rights(R_ADMIN|R_FUN)) return - - var/mob/M = locate(href_list["give_disease2"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.give_disease2(M) - href_list["datumrefresh"] = href_list["give_spell"] - - else if(href_list["godmode"]) - if(!check_rights(R_REJUVINATE)) return - - var/mob/M = locate(href_list["godmode"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.cmd_admin_godmode(M) - href_list["datumrefresh"] = href_list["godmode"] - - else if(href_list["gib"]) - if(!check_rights(0)) return - - var/mob/M = locate(href_list["gib"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.cmd_admin_gib(M) - - else if(href_list["build_mode"]) - if(!check_rights(R_BUILDMODE)) return - - var/mob/M = locate(href_list["build_mode"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - togglebuildmode(M) - href_list["datumrefresh"] = href_list["build_mode"] - - else if(href_list["drop_everything"]) - if(!check_rights(R_DEBUG|R_ADMIN)) return - - var/mob/M = locate(href_list["drop_everything"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - if(usr.client) - usr.client.cmd_admin_drop_everything(M) - - else if(href_list["direct_control"]) - if(!check_rights(0)) return - - var/mob/M = locate(href_list["direct_control"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - if(usr.client) - usr.client.cmd_assume_direct_control(M) - - else if(href_list["make_skeleton"]) - if(!check_rights(R_FUN)) return - - var/mob/living/carbon/human/H = locate(href_list["make_skeleton"]) - if(!istype(H)) - usr << "This can only be used on instances of type /mob/living/carbon/human" - return - - H.ChangeToSkeleton() - href_list["datumrefresh"] = href_list["make_skeleton"] - - else if(href_list["delall"]) - if(!check_rights(R_DEBUG|R_SERVER)) return - - var/obj/O = locate(href_list["delall"]) - if(!isobj(O)) - usr << "This can only be used on instances of type /obj" - return - - var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel") - if(action_type == "Cancel" || !action_type) - return - - if(alert("Are you really sure you want to delete all objects of type [O.type]?",,"Yes","No") != "Yes") - return - - if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes") - return - - var/O_type = O.type - switch(action_type) - if("Strict type") - var/i = 0 - for(var/obj/Obj in world) - if(Obj.type == O_type) - i++ - del(Obj) - if(!i) - usr << "No objects of this type exist" - return - log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") - message_admins("\blue [key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") - if("Type and subtypes") - var/i = 0 - for(var/obj/Obj in world) - if(istype(Obj,O_type)) - i++ - del(Obj) - if(!i) - usr << "No objects of this type exist" - return - log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") - message_admins("\blue [key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") - - else if(href_list["explode"]) - if(!check_rights(R_DEBUG|R_FUN)) return - - var/atom/A = locate(href_list["explode"]) - if(!isobj(A) && !ismob(A) && !isturf(A)) - usr << "This can only be done to instances of type /obj, /mob and /turf" - return - - src.cmd_admin_explosion(A) - href_list["datumrefresh"] = href_list["explode"] - - else if(href_list["emp"]) - if(!check_rights(R_DEBUG|R_FUN)) return - - var/atom/A = locate(href_list["emp"]) - if(!isobj(A) && !ismob(A) && !isturf(A)) - usr << "This can only be done to instances of type /obj, /mob and /turf" - return - - src.cmd_admin_emp(A) - href_list["datumrefresh"] = href_list["emp"] - - else if(href_list["mark_object"]) - if(!check_rights(0)) return - - var/datum/D = locate(href_list["mark_object"]) - if(!istype(D)) - usr << "This can only be done to instances of type /datum" - return - - src.holder.marked_datum = D - href_list["datumrefresh"] = href_list["mark_object"] - - else if(href_list["rotatedatum"]) - if(!check_rights(0)) return - - var/atom/A = locate(href_list["rotatedatum"]) - if(!istype(A)) - usr << "This can only be done to instances of type /atom" - return - - switch(href_list["rotatedir"]) - if("right") A.set_dir(turn(A.dir, -45)) - if("left") A.set_dir(turn(A.dir, 45)) - href_list["datumrefresh"] = href_list["rotatedatum"] - - else if(href_list["makemonkey"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["makemonkey"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return - if(!H) - usr << "Mob doesn't exist anymore" - return - holder.Topic(href, list("monkeyone"=href_list["makemonkey"])) - - else if(href_list["makerobot"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["makerobot"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return - if(!H) - usr << "Mob doesn't exist anymore" - return - holder.Topic(href, list("makerobot"=href_list["makerobot"])) - - else if(href_list["makealien"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["makealien"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return - if(!H) - usr << "Mob doesn't exist anymore" - return - holder.Topic(href, list("makealien"=href_list["makealien"])) - - else if(href_list["makeslime"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["makeslime"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return - if(!H) - usr << "Mob doesn't exist anymore" - return - holder.Topic(href, list("makeslime"=href_list["makeslime"])) - - else if(href_list["makeai"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["makeai"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return - if(!H) - usr << "Mob doesn't exist anymore" - return - holder.Topic(href, list("makeai"=href_list["makeai"])) - - else if(href_list["setspecies"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["setspecies"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - var/new_species = input("Please choose a new species.","Species",null) as null|anything in all_species - - if(!H) - usr << "Mob doesn't exist anymore" - return - - if(H.set_species(new_species)) - usr << "Set species of [H] to [H.species]." - else - usr << "Failed! Something went wrong." - - else if(href_list["addlanguage"]) - if(!check_rights(R_SPAWN)) return - - var/mob/H = locate(href_list["addlanguage"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob" - return - - var/new_language = input("Please choose a language to add.","Language",null) as null|anything in all_languages - - if(!new_language) - return - - if(!H) - usr << "Mob doesn't exist anymore" - return - - if(H.add_language(new_language)) - usr << "Added [new_language] to [H]." - else - usr << "Mob already knows that language." - - else if(href_list["remlanguage"]) - if(!check_rights(R_SPAWN)) return - - var/mob/H = locate(href_list["remlanguage"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob" - return - - if(!H.languages.len) - usr << "This mob knows no languages." - return - - var/datum/language/rem_language = input("Please choose a language to remove.","Language",null) as null|anything in H.languages - - if(!rem_language) - return - - if(!H) - usr << "Mob doesn't exist anymore" - return - - if(H.remove_language(rem_language.name)) - usr << "Removed [rem_language] from [H]." - else - usr << "Mob doesn't know that language." - - else if(href_list["addverb"]) - if(!check_rights(R_DEBUG)) return - - var/mob/living/H = locate(href_list["addverb"]) - - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living" - return - var/list/possibleverbs = list() - possibleverbs += "Cancel" // One for the top... - possibleverbs += typesof(/mob/proc,/mob/verb,/mob/living/proc,/mob/living/verb) - switch(H.type) - if(/mob/living/carbon/human) - possibleverbs += typesof(/mob/living/carbon/proc,/mob/living/carbon/verb,/mob/living/carbon/human/verb,/mob/living/carbon/human/proc) - if(/mob/living/silicon/robot) - possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/robot/proc,/mob/living/silicon/robot/verb) - if(/mob/living/silicon/ai) - possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/ai/proc,/mob/living/silicon/ai/verb) - possibleverbs -= H.verbs - possibleverbs += "Cancel" // ...And one for the bottom - - var/verb = input("Select a verb!", "Verbs",null) as anything in possibleverbs - if(!H) - usr << "Mob doesn't exist anymore" - return - if(!verb || verb == "Cancel") - return - else - H.verbs += verb - - else if(href_list["remverb"]) - if(!check_rights(R_DEBUG)) return - - var/mob/H = locate(href_list["remverb"]) - - if(!istype(H)) - usr << "This can only be done to instances of type /mob" - return - var/verb = input("Please choose a verb to remove.","Verbs",null) as null|anything in H.verbs - if(!H) - usr << "Mob doesn't exist anymore" - return - if(!verb) - return - else - H.verbs -= verb - - else if(href_list["addorgan"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/M = locate(href_list["addorgan"]) - if(!istype(M)) - usr << "This can only be done to instances of type /mob/living/carbon" - return - - var/new_organ = input("Please choose an organ to add.","Organ",null) as null|anything in typesof(/obj/item/organ)-/obj/item/organ - if(!new_organ) return - - if(!M) - usr << "Mob doesn't exist anymore" - return - - if(locate(new_organ) in M.internal_organs) - usr << "Mob already has that organ." - return - -<<<<<<< HEAD - new new_organ(M) - -======= - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - var/datum/organ/internal/I = new new_organ(H) - - var/organ_slot = input(usr, "Which slot do you want the organ to go in ('default' for default)?") as text|null - - if(!organ_slot) - return - - if(organ_slot != "default") - organ_slot = sanitize(organ_slot) - else - if(I.removed_type) - var/obj/item/organ/O = new I.removed_type() - organ_slot = O.organ_tag - del(O) - else - organ_slot = "unknown organ" - - if(H.internal_organs_by_name[organ_slot]) - usr << "[H] already has an organ in that slot." - del(I) - return - - H.internal_organs |= I - H.internal_organs_by_name[organ_slot] = I - usr << "Added new [new_organ] to [H] as slot [organ_slot]." - else - new new_organ(M) - usr << "Added new [new_organ] to [M]." ->>>>>>> 2aa4646fa0425bed412e2ef0e7852591ecb4bc40 - - else if(href_list["remorgan"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/M = locate(href_list["remorgan"]) - if(!istype(M)) - usr << "This can only be done to instances of type /mob/living/carbon" - return - - var/obj/item/organ/rem_organ = input("Please choose an organ to remove.","Organ",null) as null|anything in M.internal_organs - - if(!M) - usr << "Mob doesn't exist anymore" - return - - if(!(locate(rem_organ) in M.internal_organs)) - usr << "Mob does not have that organ." - return - - usr << "Removed [rem_organ] from [M]." - rem_organ.removed() - del(rem_organ) - - else if(href_list["fix_nano"]) - if(!check_rights(R_DEBUG)) return - - var/mob/H = locate(href_list["fix_nano"]) - - if(!istype(H) || !H.client) - usr << "This can only be done on mobs with clients" - return - - nanomanager.send_resources(H.client) - - usr << "Resource files sent" - H << "Your NanoUI Resource files have been refreshed" - - log_admin("[key_name(usr)] resent the NanoUI resource files to [key_name(H)] ") - - else if(href_list["regenerateicons"]) - if(!check_rights(0)) return - - var/mob/M = locate(href_list["regenerateicons"]) - if(!ismob(M)) - usr << "This can only be done to instances of type /mob" - return - M.regenerate_icons() - - else if(href_list["adjustDamage"] && href_list["mobToDamage"]) - if(!check_rights(R_DEBUG|R_ADMIN|R_FUN)) return - - var/mob/living/L = locate(href_list["mobToDamage"]) - if(!istype(L)) return - - var/Text = href_list["adjustDamage"] - - var/amount = input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num - - if(!L) - usr << "Mob doesn't exist anymore" - return - - switch(Text) - if("brute") L.adjustBruteLoss(amount) - if("fire") L.adjustFireLoss(amount) - if("toxin") L.adjustToxLoss(amount) - if("oxygen")L.adjustOxyLoss(amount) - if("brain") L.adjustBrainLoss(amount) - if("clone") L.adjustCloneLoss(amount) - else - usr << "You caused an error. DEBUG: Text:[Text] Mob:[L]" - return - - if(amount != 0) - log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") - message_admins("\blue [key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") - href_list["datumrefresh"] = href_list["mobToDamage"] - - if(href_list["datumrefresh"]) - var/datum/DAT = locate(href_list["datumrefresh"]) - if(!istype(DAT, /datum)) - return - src.debug_variables(DAT) - - return - diff --git a/code/datums/disease.dm b/code/datums/disease.dm index 93aa14f19b3..398dc73bbbc 100644 --- a/code/datums/disease.dm +++ b/code/datums/disease.dm @@ -11,7 +11,7 @@ /* -IMPORTANT NOTE: Please delete the diseases by using cure() proc or del() instruction. +IMPORTANT NOTE: Please delete the diseases by using cure() proc or qdel() instruction. Diseases are referenced in a global list, so simply setting mob or obj vars to null does not delete the object itself. Thank you. @@ -158,7 +158,7 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease if(D != src) if(IsSame(D)) //error("Deleting [D.name] because it's the same as [src.name].") - del(D) // if there are somehow two viruses of the same kind in the system, delete the other one + qdel(D) // if there are somehow two viruses of the same kind in the system, delete the other one if(holder == affected_mob) if(affected_mob.stat != DEAD) //he's alive @@ -183,7 +183,7 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease /*if(istype(src, /datum/disease/alien_embryo)) //Get rid of the infection flag if it's a xeno embryo. affected_mob.status_flags &= ~(XENO_HOST)*/ affected_mob.viruses -= src //remove the datum from the list - del(src) //delete the datum to stop it processing + qdel(src) //delete the datum to stop it processing return @@ -193,6 +193,9 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease active_diseases += src initial_spread = spread +/datum/disease/Destroy() + active_diseases.Remove(src) + /datum/disease/proc/IsSame(var/datum/disease/D) if(istype(src, D.type)) return 1 @@ -200,8 +203,3 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease /datum/disease/proc/Copy(var/process = 0) return new type(process, src) - -/* -/datum/disease/Del() - active_diseases.Remove(src) -*/ diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 70acceca35d..d4effcf6cb1 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -71,7 +71,7 @@ var/list/advance_cures = list( ..(process, D) return -/datum/disease/advance/Del() +/datum/disease/advance/Destroy() if(processing) for(var/datum/symptom/S in symptoms) S.End(src) @@ -109,7 +109,7 @@ var/list/advance_cures = list( if(resistance && !(id in affected_mob.resistances)) affected_mob.resistances[id] = id affected_mob.viruses -= src //remove the datum from the list - del(src) //delete the datum to stop it processing + qdel(src) //delete the datum to stop it processing return // Returns the advance disease with a different reference memory. diff --git a/code/datums/diseases/alien_embryo.dm b/code/datums/diseases/alien_embryo.dm index 631c93b26c4..59d1dbe1605 100644 --- a/code/datums/diseases/alien_embryo.dm +++ b/code/datums/diseases/alien_embryo.dm @@ -113,7 +113,7 @@ Des: Removes all infection images from aliens and places an infection image on a if (alien.client) for(var/image/I in alien.client.images) if(dd_hasprefix_case(I.icon_state, "infected")) - del(I) + qdel(I) for (var/mob/living/carbon/alien/alien in player_list) if (alien.client) @@ -149,5 +149,5 @@ Des: Removes the alien infection image from all aliens in the world located in p for(var/image/I in alien.client.images) if(I.loc == C) if(dd_hasprefix_case(I.icon_state, "infected")) - del(I) + qdel(I) return diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm index a4d85a56407..6d520fe2948 100644 --- a/code/datums/diseases/dna_spread.dm +++ b/code/datums/diseases/dna_spread.dm @@ -34,7 +34,7 @@ if(4) if(!src.transformed) if ((!strain_data["name"]) || (!strain_data["UI"]) || (!strain_data["SE"])) - del(affected_mob.virus) + qdel(affected_mob.virus) return //Save original dna for when the disease is cured. @@ -56,7 +56,7 @@ return -/datum/disease/dnaspread/Del() +/datum/disease/dnaspread/Destroy() if ((original_dna["name"]) && (original_dna["UI"]) && (original_dna["SE"])) var/list/newUI=original_dna["UI"] var/list/newSE=original_dna["SE"] diff --git a/code/datums/helper_datums/construction_datum.dm b/code/datums/helper_datums/construction_datum.dm index 7c2fabbc9b8..0bda144e8aa 100644 --- a/code/datums/helper_datums/construction_datum.dm +++ b/code/datums/helper_datums/construction_datum.dm @@ -12,7 +12,7 @@ holder = atom if(!holder) //don't want this without a holder spawn - del src + qdel(src) set_desc(steps.len) return @@ -61,7 +61,7 @@ if(result) new result(get_turf(holder)) spawn() - del holder + qdel(holder) return proc/set_desc(index as num) diff --git a/code/datums/helper_datums/global_iterator.dm b/code/datums/helper_datums/global_iterator.dm index 0020859f1d9..4f4d680e9e0 100644 --- a/code/datums/helper_datums/global_iterator.dm +++ b/code/datums/helper_datums/global_iterator.dm @@ -151,4 +151,8 @@ Data storage vars: start() return active() - +/datum/global_iterator/Destroy() + tag = null + arg_list.Cut() + stop() + //Do not call ..() diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 00899f47cb2..b562780aea3 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -14,179 +14,177 @@ var/force_teleport = 1 //if false, teleport will use Move() proc (dense objects will prevent teleportation) - New(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null) - ..() - if(!initTeleport(arglist(args))) - return 0 - return 1 - - proc/initTeleport(ateleatom,adestination,aprecision,afteleport,aeffectin,aeffectout,asoundin,asoundout) - if(!setTeleatom(ateleatom)) - return 0 - if(!setDestination(adestination)) - return 0 - if(!setPrecision(aprecision)) - return 0 - setEffects(aeffectin,aeffectout) - setForceTeleport(afteleport) - setSounds(asoundin,asoundout) - return 1 - - //must succeed - proc/setPrecision(aprecision) - if(isnum(aprecision)) - precision = aprecision - return 1 +/datum/teleport/New(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null) + ..() + if(!initTeleport(arglist(args))) return 0 + return 1 - //must succeed - proc/setDestination(atom/adestination) - if(istype(adestination)) - destination = adestination - return 1 +/datum/teleport/proc/initTeleport(ateleatom,adestination,aprecision,afteleport,aeffectin,aeffectout,asoundin,asoundout) + if(!setTeleatom(ateleatom)) return 0 - - //must succeed in most cases - proc/setTeleatom(atom/movable/ateleatom) - if(istype(ateleatom, /obj/effect) && !istype(ateleatom, /obj/effect/dummy/chameleon)) - del(ateleatom) - return 0 - if(istype(ateleatom)) - teleatom = ateleatom - return 1 + if(!setDestination(adestination)) return 0 + if(!setPrecision(aprecision)) + return 0 + setEffects(aeffectin,aeffectout) + setForceTeleport(afteleport) + setSounds(asoundin,asoundout) + return 1 - //custom effects must be properly set up first for instant-type teleports - //optional - proc/setEffects(datum/effect/effect/system/aeffectin=null,datum/effect/effect/system/aeffectout=null) - effectin = istype(aeffectin) ? aeffectin : null - effectout = istype(aeffectout) ? aeffectout : null +//must succeed +/datum/teleport/proc/setPrecision(aprecision) + if(isnum(aprecision)) + precision = aprecision return 1 + return 0 - //optional - proc/setForceTeleport(afteleport) +//must succeed +/datum/teleport/proc/setDestination(atom/adestination) + if(istype(adestination)) + destination = adestination + return 1 + return 0 + +//must succeed in most cases +/datum/teleport/proc/setTeleatom(atom/movable/ateleatom) + if(istype(ateleatom, /obj/effect) && !istype(ateleatom, /obj/effect/dummy/chameleon)) + qdel(ateleatom) + return 0 + if(istype(ateleatom)) + teleatom = ateleatom + return 1 + return 0 + +//custom effects must be properly set up first for instant-type teleports +//optional +/datum/teleport/proc/setEffects(datum/effect/effect/system/aeffectin=null,datum/effect/effect/system/aeffectout=null) + effectin = istype(aeffectin) ? aeffectin : null + effectout = istype(aeffectout) ? aeffectout : null + return 1 + +//optional +/datum/teleport/proc/setForceTeleport(afteleport) force_teleport = afteleport return 1 - //optional - proc/setSounds(asoundin=null,asoundout=null) +//optional +/datum/teleport/proc/setSounds(asoundin=null,asoundout=null) soundin = isfile(asoundin) ? asoundin : null soundout = isfile(asoundout) ? asoundout : null return 1 - //placeholder - proc/teleportChecks() +//placeholder +/datum/teleport/proc/teleportChecks() return 1 - proc/playSpecials(atom/location,datum/effect/effect/system/effect,sound) - if(location) - if(effect) - spawn(-1) - src = null - effect.attach(location) - effect.start() - if(sound) - spawn(-1) - src = null - playsound(location,sound,60,1) - return +/datum/teleport/proc/playSpecials(atom/location,datum/effect/effect/system/effect,sound) + if(location) + if(effect) + spawn(-1) + src = null + effect.attach(location) + effect.start() + if(sound) + spawn(-1) + src = null + playsound(location,sound,60,1) + return - //do the monkey dance - proc/doTeleport() +//do the monkey dance +/datum/teleport/proc/doTeleport() - var/turf/destturf - var/turf/curturf = get_turf(teleatom) - var/area/destarea = get_area(destination) - if(precision) - var/list/posturfs = circlerangeturfs(destination,precision) - destturf = safepick(posturfs) - else - destturf = get_turf(destination) + var/turf/destturf + var/turf/curturf = get_turf(teleatom) + var/area/destarea = get_area(destination) + if(precision) + var/list/posturfs = circlerangeturfs(destination,precision) + destturf = safepick(posturfs) + else + destturf = get_turf(destination) - if(!destturf || !curturf) - return 0 - - playSpecials(curturf,effectin,soundin) - - var/obj/structure/bed/chair/C = null - if(isliving(teleatom)) - var/mob/living/L = teleatom - if(L.buckled) - C = L.buckled - if(force_teleport) - teleatom.forceMove(destturf) - playSpecials(destturf,effectout,soundout) - else - if(teleatom.Move(destturf)) - playSpecials(destturf,effectout,soundout) - if(C) - C.forceMove(destturf) - - destarea.Entered(teleatom) - - return 1 - - proc/teleport() - if(teleportChecks()) - return doTeleport() + if(!destturf || !curturf) return 0 + playSpecials(curturf,effectin,soundin) + + var/obj/structure/bed/chair/C = null + if(isliving(teleatom)) + var/mob/living/L = teleatom + if(L.buckled) + C = L.buckled + if(force_teleport) + teleatom.forceMove(destturf) + playSpecials(destturf,effectout,soundout) + else + if(teleatom.Move(destturf)) + playSpecials(destturf,effectout,soundout) + if(C) + C.forceMove(destturf) + + destarea.Entered(teleatom) + + return 1 + +/datum/teleport/proc/teleport() + if(teleportChecks()) + return doTeleport() + return 0 + /datum/teleport/instant //teleports when datum is created - New(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null) - if(..()) - teleport() - return +/datum/teleport/instant/New(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null) + if(..()) + teleport() + return -/datum/teleport/instant/science - - setEffects(datum/effect/effect/system/aeffectin,datum/effect/effect/system/aeffectout) - if(!aeffectin || !aeffectout) - var/datum/effect/effect/system/spark_spread/aeffect = new - aeffect.set_up(5, 1, teleatom) - effectin = effectin || aeffect - effectout = effectout || aeffect - return 1 - else - return ..() - - setPrecision(aprecision) - ..() - if(istype(teleatom, /obj/item/weapon/storage/backpack/holding)) - precision = rand(1,100) - - var/list/bagholding = teleatom.search_contents_for(/obj/item/weapon/storage/backpack/holding) - if(bagholding.len) - precision = max(rand(1,100)*bagholding.len,100) - if(istype(teleatom, /mob/living)) - var/mob/living/MM = teleatom - MM << "\red The Bluespace interface on your Bag of Holding interferes with the teleport!" +/datum/teleport/instant/science/setEffects(datum/effect/effect/system/aeffectin,datum/effect/effect/system/aeffectout) + if(!aeffectin || !aeffectout) + var/datum/effect/effect/system/spark_spread/aeffect = new + aeffect.set_up(5, 1, teleatom) + effectin = effectin || aeffect + effectout = effectout || aeffect return 1 + else + return ..() - teleportChecks() - if(istype(teleatom, /obj/item/weapon/disk/nuclear)) // Don't let nuke disks get teleported --NeoFite - teleatom.visible_message("\red The [teleatom] bounces off of the portal!") +/datum/teleport/instant/science/setPrecision(aprecision) + ..() + if(istype(teleatom, /obj/item/weapon/storage/backpack/holding)) + precision = rand(1,100) + + var/list/bagholding = teleatom.search_contents_for(/obj/item/weapon/storage/backpack/holding) + if(bagholding.len) + precision = max(rand(1,100)*bagholding.len,100) + if(istype(teleatom, /mob/living)) + var/mob/living/MM = teleatom + MM << "\The [teleatom] bounces off of the portal!") + return 0 + + if(!isemptylist(teleatom.search_contents_for(/obj/item/weapon/disk/nuclear))) + if(istype(teleatom, /mob/living)) + var/mob/living/MM = teleatom + MM.visible_message("\The [MM] bounces off of the portal!","Something you are carrying seems to be unable to pass through the portal. Better drop it if you want to go through.") + else + teleatom.visible_message("\The [teleatom] bounces off of the portal!") + return 0 + + if(destination.z in config.admin_levels) //centcomm z-level + if(istype(teleatom, /obj/mecha)) + var/obj/mecha/MM = teleatom + MM.occupant << "\The [MM] would not survive the jump to a location so far away!" + return 0 + if(!isemptylist(teleatom.search_contents_for(/obj/item/weapon/storage/backpack/holding))) + teleatom.visible_message("\The [teleatom] bounces off of the portal!") return 0 - if(!isemptylist(teleatom.search_contents_for(/obj/item/weapon/disk/nuclear))) - if(istype(teleatom, /mob/living)) - var/mob/living/MM = teleatom - MM.visible_message("\red The [MM] bounces off of the portal!","\red Something you are carrying seems to be unable to pass through the portal. Better drop it if you want to go through.") - else - teleatom.visible_message("\red The [teleatom] bounces off of the portal!") - return 0 - if(destination.z == 2) //centcomm z-level - if(istype(teleatom, /obj/mecha)) - var/obj/mecha/MM = teleatom - MM.occupant << "\red The mech would not survive the jump to a location so far away!" - return 0 - if(!isemptylist(teleatom.search_contents_for(/obj/item/weapon/storage/backpack/holding))) - teleatom.visible_message("\red The Bag of Holding bounces off of the portal!") - return 0 - - - if(destination.z > 7) //Away mission z-levels - return 0 - return 1 \ No newline at end of file + if(destination.z > max_default_z_level()) //Away mission z-levels + return 0 + return 1 diff --git a/code/datums/mind.dm b/code/datums/mind.dm index f6fbbc110c8..cfbd1551452 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -311,7 +311,7 @@ datum/mind for(var/obj/item/weapon/implant/loyalty/I in H.contents) for(var/obj/item/organ/external/organs in H.organs) if(I in organs.implants) - I.Del() + qdel(I) break H << "Your loyalty implant has been deactivated." log_admin("[key_name_admin(usr)] has de-loyalty implanted [current].") @@ -368,7 +368,7 @@ datum/mind src = null m2h.inject(M) src = mobfinder.loc:mind - del(mobfinder) + qdel(mobfinder) current.radiation -= 50 */ else if (href_list["silicon"]) @@ -445,10 +445,10 @@ datum/mind var/list/L = current.get_contents() for (var/t in L) if (istype(t, /obj/item/device/pda)) - if (t:uplink) del(t:uplink) + if (t:uplink) qdel(t:uplink) t:uplink = null else if (istype(t, /obj/item/device/radio)) - if (t:traitorradio) del(t:traitorradio) + if (t:traitorradio) qdel(t:traitorradio) t:traitorradio = null t:traitor_frequency = 0.0 else if (istype(t, /obj/item/weapon/SWF_uplink) || istype(t, /obj/item/weapon/syndicate_uplink)) @@ -457,7 +457,7 @@ datum/mind R.loc = current.loc R.traitorradio = null R.traitor_frequency = 0.0 - del(t) + qdel(t) // remove wizards spells //If there are more special powers that need removal, they can be procced into here./N @@ -479,7 +479,7 @@ datum/mind proc/take_uplink() var/obj/item/device/uplink/hidden/H = find_syndicate_uplink() if(H) - del(H) + qdel(H) // check whether this mind's mob has been brigged for the given duration diff --git a/code/datums/modules.dm b/code/datums/modules.dm index 896d920f994..43d25a2e25d 100644 --- a/code/datums/modules.dm +++ b/code/datums/modules.dm @@ -24,7 +24,8 @@ var/list/modules = list( // global associative list var/mneed = mods.inmodlist(type) // find if this type has modules defined if(!mneed) // not found in module list? - del(src) // delete self, thus ending proc + qdel(src) + return var/needed = mods.getbitmask(type) // get a bitmask for the number of modules in this object status = needed diff --git a/code/datums/recipe.dm b/code/datums/recipe.dm index 9c72feef39d..6098315c11c 100644 --- a/code/datums/recipe.dm +++ b/code/datums/recipe.dm @@ -54,8 +54,8 @@ . = 1 if(fruit && fruit.len) var/list/checklist = list() - for(var/fruittype in fruit) // I do not trust Copy(). - checklist[fruittype] = fruit[fruittype] + // You should trust Copy(). + checklist = fruit.Copy() for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in container) if(!G.seed || !G.seed.kitchen_tag || isnull(checklist[G.seed.kitchen_tag])) continue @@ -73,15 +73,15 @@ . = 1 if (items && items.len) var/list/checklist = list() - for(var/item_type in items) - checklist |= item_type //Still don't trust Copy(). + checklist = items.Copy() // You should really trust Copy for(var/obj/O in container) if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown)) continue // Fruit is handled in check_fruit(). var/found = 0 - for(var/item_type in checklist) + for(var/i = 1; i < checklist.len+1; i++) + var/item_type = checklist[i] if (istype(O,item_type)) - checklist-=item_type + checklist.Cut(i, i+1) found = 1 break if (!found) @@ -94,8 +94,8 @@ /datum/recipe/proc/make(var/obj/container as obj) var/obj/result_obj = new result(container) for (var/obj/O in (container.contents-result_obj)) - O.reagents.trans_to(result_obj, O.reagents.total_volume) - del(O) + O.reagents.trans_to_obj(result_obj, O.reagents.total_volume) + qdel(O) container.reagents.clear_reagents() return result_obj @@ -109,8 +109,8 @@ if (O.reagents) O.reagents.del_reagent("nutriment") O.reagents.update_total() - O.reagents.trans_to(result_obj, O.reagents.total_volume) - del(O) + O.reagents.trans_to_obj(result_obj, O.reagents.total_volume) + qdel(O) container.reagents.clear_reagents() return result_obj diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 3cc3107784d..1a7a9b8ae0b 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -43,10 +43,10 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /datum/supply_packs/food name = "Kitchen supply crate" - contains = list(/obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, + contains = list(/obj/item/weapon/reagent_containers/food/condiment/flour, + /obj/item/weapon/reagent_containers/food/condiment/flour, + /obj/item/weapon/reagent_containers/food/condiment/flour, + /obj/item/weapon/reagent_containers/food/condiment/flour, /obj/item/weapon/reagent_containers/food/drinks/milk, /obj/item/weapon/reagent_containers/food/drinks/milk, /obj/item/weapon/storage/fancy/egg_box, @@ -259,7 +259,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee name = "Corgi Crate" contains = list() cost = 50 - containertype = /obj/structure/largecrate/lisa + containertype = /obj/structure/largecrate/animal/corgi containername = "Corgi Crate" group = "Hydroponics" @@ -289,7 +289,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /datum/supply_packs/cow name = "Cow crate" cost = 30 - containertype = /obj/structure/largecrate/cow + containertype = /obj/structure/largecrate/animal/cow containername = "Cow crate" access = access_hydroponics group = "Hydroponics" @@ -297,7 +297,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /datum/supply_packs/goat name = "Goat crate" cost = 25 - containertype = /obj/structure/largecrate/goat + containertype = /obj/structure/largecrate/animal/goat containername = "Goat crate" access = access_hydroponics group = "Hydroponics" @@ -305,19 +305,11 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /datum/supply_packs/chicken name = "Chicken crate" cost = 20 - containertype = /obj/structure/largecrate/chick + containertype = /obj/structure/largecrate/animal/chick containername = "Chicken crate" access = access_hydroponics group = "Hydroponics" -/datum/supply_packs/lisa - name = "Corgi crate" - contains = list() - cost = 50 - containertype = /obj/structure/largecrate/lisa - containername = "Corgi crate" - group = "Hydroponics" - /datum/supply_packs/seeds name = "Seeds crate" contains = list(/obj/item/seeds/chiliseed, @@ -345,11 +337,17 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /datum/supply_packs/weedcontrol name = "Weed control crate" - contains = list(/obj/item/weapon/scythe, + contains = list(/obj/item/weapon/hatchet, + /obj/item/weapon/hatchet, + /obj/item/weapon/reagent_containers/spray/plantbgone, + /obj/item/weapon/reagent_containers/spray/plantbgone, + /obj/item/weapon/reagent_containers/spray/plantbgone, + /obj/item/weapon/reagent_containers/spray/plantbgone, + /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, /obj/item/weapon/grenade/chem_grenade/antiweed, /obj/item/weapon/grenade/chem_grenade/antiweed) - cost = 20 + cost = 25 containertype = /obj/structure/closet/crate/secure/hydrosec containername = "Weed control crate" access = access_hydroponics @@ -1506,5 +1504,45 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/device/floor_painter, /obj/item/device/floor_painter) +/datum/supply_packs/bluespacerelay + name = "Emergency Bluespace Relay Assembly Kit" + cost = 75 + containername = "emergency bluespace relay assembly kit" + containertype = /obj/structure/closet/crate + group = "Engineering" + contains = list(/obj/item/weapon/circuitboard/bluespacerelay, + /obj/item/weapon/stock_parts/manipulator, + /obj/item/weapon/stock_parts/manipulator, + /obj/item/weapon/stock_parts/subspace/filter, + /obj/item/weapon/stock_parts/subspace/crystal, + /obj/item/weapon/storage/toolbox/electrical) +/datum/supply_packs/randomised/exosuit_mod + num_contained = 1 + contains = list( + /obj/item/device/kit/paint/ripley, + /obj/item/device/kit/paint/ripley/death, + /obj/item/device/kit/paint/ripley/flames_red, + /obj/item/device/kit/paint/ripley/flames_blue + ) + name = "Random APLU modkit" + cost = 200 + containertype = /obj/structure/closet/crate + containername = "heavy crate" + group = "Miscellaneous" +/datum/supply_packs/randomised/exosuit_mod/durand + contains = list( + /obj/item/device/kit/paint/durand, + /obj/item/device/kit/paint/durand/seraph, + /obj/item/device/kit/paint/durand/phazon + ) + name = "Random Durand exosuit modkit" + +/datum/supply_packs/randomised/exosuit_mod/gygax + contains = list( + /obj/item/device/kit/paint/gygax, + /obj/item/device/kit/paint/gygax/darkgygax, + /obj/item/device/kit/paint/gygax/recitence + ) + name = "Random Gygax exosuit modkit" diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index 7e8c8779cff..a0f1f9c7f1c 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -37,10 +37,11 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 var/haspower = A.arePowerSystemsOn() //If there's no power, then no lights will be on. . += ..() - . += text("
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]", + . += text("
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]", (A.locked ? "The door bolts have fallen!" : "The door bolts look up."), ((A.lights && haspower) ? "The door bolt lights are on." : "The door bolt lights are off!"), ((haspower) ? "The test light is on." : "The test light is off!"), + ((A.backupPowerCablesCut()) ? "The backup power light is off!" : "The backup power light is on."), ((A.aiControlDisabled==0 && !A.emagged && haspower)? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), ((A.safe==0 && haspower)? "The 'Check Wiring' light is on." : "The 'Check Wiring' light is off."), ((A.normalspeed==0 && haspower)? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off."), @@ -124,7 +125,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 //Sending a pulse through flashes the red light on the door (if the door has power). if(A.arePowerSystemsOn() && A.density) A.do_animate("deny") - if(AIRLOCK_WIRE_MAIN_POWER1 || AIRLOCK_WIRE_MAIN_POWER2) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) //Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter). A.loseMainPower() if(AIRLOCK_WIRE_DOOR_BOLTS) @@ -135,7 +136,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 else A.unlock() - if(AIRLOCK_WIRE_BACKUP_POWER1 || AIRLOCK_WIRE_BACKUP_POWER2) + if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) //two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter). A.loseBackupPower() if(AIRLOCK_WIRE_AI_CONTROL) diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 3b0b54942f2..0555a140bd8 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -278,6 +278,11 @@ var/const/POWER = 8 var/r = rand(1, wires.len) CutWireIndex(r) +/datum/wires/proc/RandomCutAll(var/probability = 10) + for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i) + if(prob(probability)) + CutWireIndex(i) + /datum/wires/proc/CutAll() for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i) CutWireIndex(i) diff --git a/code/defines/obj.dm b/code/defines/obj.dm index e105d67a5b4..a70822942fe 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -80,7 +80,8 @@ for(var/datum/data/record/t in data_core.general) var/name = t.fields["name"] var/rank = t.fields["rank"] - var/real_rank = t.fields["real_rank"] + var/real_rank = make_list_rank(t.fields["real_rank"]) + if(OOC) var/active = 0 for(var/mob/M in player_list) @@ -165,6 +166,15 @@ return dat +/var/list/acting_rank_prefixes = list("acting", "temporary", "interim") + +/proc/make_list_rank(rank) + for(var/prefix in acting_rank_prefixes) + if(findtext(rank, "[prefix] ", 1, 2+length(prefix))) + return copytext(rank, 2+length(prefix)) + return rank + + /* We can't just insert in HTML into the nanoUI so we need the raw data to play with. Instead of creating this list over and over when someone leaves their PDA open to the page @@ -189,7 +199,8 @@ var/global/ManifestJSON for(var/datum/data/record/t in data_core.general) var/name = sanitize(t.fields["name"]) var/rank = sanitize(t.fields["rank"]) - var/real_rank = t.fields["real_rank"] + var/real_rank = make_list_rank(t.fields["real_rank"]) + var/isactive = t.fields["p_stat"] var/department = 0 var/depthead = 0 // Department Heads will be placed at the top of their lists. diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 27c233b3404..e0bd7bb486d 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -83,7 +83,7 @@ force = 5.0 throwforce = 7.0 w_class = 2.0 - matter = list("metal" = 50) + matter = list(DEFAULT_WALL_MATERIAL = 50) attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed") /obj/item/weapon/cane/concealed @@ -91,9 +91,11 @@ /obj/item/weapon/cane/concealed/New() ..() - concealed_blade = new/obj/item/weapon/butterfly/switchblade(src) + var/obj/item/weapon/butterfly/switchblade/temp_blade = new(src) + concealed_blade = temp_blade + temp_blade.attack_self() -/obj/item/weapon/cane/concealed/attack_self(mob/user) +/obj/item/weapon/cane/concealed/attack_self(var/mob/user) if(concealed_blade) user.visible_message("[user] has unsheathed \a [concealed_blade] from \his [src]!", "You unsheathe \the [concealed_blade] from \the [src].") // Calling drop/put in hands to properly call item drop/pickup procs @@ -101,8 +103,9 @@ user.drop_from_inventory(src) user.put_in_hands(concealed_blade) user.put_in_hands(src) + user.update_inv_l_hand(0) + user.update_inv_r_hand() concealed_blade = null - update_icon() else ..() @@ -172,47 +175,91 @@ origin_tech = list(TECH_MATERIAL = 1) var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute -/obj/item/weapon/legcuffs/beartrap +/obj/item/weapon/beartrap name = "bear trap" throw_speed = 2 throw_range = 1 + gender = PLURAL + icon = 'icons/obj/items.dmi' icon_state = "beartrap0" desc = "A trap used to catch bears and other legged creatures." - var/armed = 0 + throwforce = 0 + w_class = 3.0 + origin_tech = "materials=1" + var/deployed = 0 suicide_act(mob/user) - viewers(user) << "\red [user] is putting the [src.name] on \his head! It looks like \he's trying to commit suicide." + viewers(user) << "[user] is putting the [src.name] on \his head! It looks like \he's trying to commit suicide." return (BRUTELOSS) -/obj/item/weapon/legcuffs/beartrap/attack_self(mob/user as mob) +/obj/item/weapon/beartrap/attack_self(mob/user as mob) ..() if(ishuman(user) && !user.stat && !user.restrained()) - armed = !armed - icon_state = "beartrap[armed]" - user << "[src] is now [armed ? "armed" : "disarmed"]" + if(deployed==0) + user.visible_message("[user] is deploying \the [src]", "You are deploying \the [src]!") + if (do_after(user, 60)) + user.visible_message("[user] has deployed \the [src]", "You have deployed \the [src]!") + deployed = 1 + user.drop_from_inventory(src, user.loc) + update_icon() + anchored = 1 -/obj/item/weapon/legcuffs/beartrap/Crossed(AM as mob|obj) - if(armed) +/obj/item/weapon/beartrap/attack_hand(mob/user as mob) + if(ishuman(user) && !user.stat && !user.restrained()) + if(deployed==1) + user.visible_message("[user] is disarming \the [src]", "You are disarming \the [src]!") + if (do_after(user, 60)) + user.visible_message("[user] has disarmed \the [src]", "You have disarmed \the [src]!") + deployed = 0 + anchored = 0 + update_icon() + + if(deployed==0) + ..() + +/obj/item/weapon/beartrap/Crossed(AM as mob|obj) + if(deployed) if(ishuman(AM)) if(isturf(src.loc)) - var/mob/living/carbon/H = AM + var/mob/living/carbon/human/H = AM if(H.m_intent == "run") - armed = 0 - H.legcuffed = src - src.loc = H - H.update_inv_legcuffed() - H << "\red You step on \the [src]!" - feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart. + deployed = 0 + update_icon() + H << "You step on \the [src]!" for(var/mob/O in viewers(H, null)) if(O == H) continue - O.show_message("\red [H] steps on \the [src].", 1) + O.show_message("[H] steps on \the [src].", 1) + if(H.lying) + var/obj/item/organ/external/affecting = pick(H.organs) + if(affecting.take_damage(30, 0)) + H.UpdateDamageIcon() + affecting.embed(src) + else + var/list/potentialorgans = list() + for(var/organ in list("l_leg", "r_leg", "l_foot", "r_foot")) + var/obj/item/organ/external/R = H.get_organ(organ) + if(R && !(R.status & ORGAN_DESTROYED)) + potentialorgans += R + var/obj/item/organ/external/affecting = pick(potentialorgans) + if(affecting.take_damage(30, 0)) + H.UpdateDamageIcon() + affecting.embed(src) + + if(isanimal(AM) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator)) - armed = 0 + deployed = 0 var/mob/living/simple_animal/SA = AM SA.health -= 20 ..() +/obj/item/weapon/beartrap/update_icon() + ..() + + if(deployed == 0) + icon_state = "beartrap0" + else + icon_state = "beartrap1" /obj/item/weapon/caution @@ -267,9 +314,9 @@ throwforce = 5 w_class = 2.0 throw_speed = 4 - throw_range = 20 - matter = list("metal" = 100) - origin_tech = list(TECH_MAGNET = 1) + throw_range = 20 + matter = list(DEFAULT_WALL_MATERIAL = 100) + origin_tech = list(TECH_MAGNET = 1) /obj/item/weapon/staff name = "wizards staff" @@ -318,7 +365,7 @@ var/amount = 1.0 var/laying = 0.0 var/old_lay = null - matter = list("metal" = 40) + matter = list(DEFAULT_WALL_MATERIAL = 40) attack_verb = list("whipped", "lashed", "disciplined", "tickled") suicide_act(mob/user) @@ -342,12 +389,12 @@ name = "power control module" icon_state = "power_mod" desc = "Heavy-duty switching circuits for power control." - matter = list("metal" = 50, "glass" = 50) + matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) /obj/item/weapon/module/power_control/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) if (istype(W, /obj/item/device/multitool)) var/obj/item/weapon/circuitboard/ghettosmes/newcircuit = new/obj/item/weapon/circuitboard/ghettosmes(user.loc) - del(src) + qdel(src) user.put_in_hands(newcircuit) @@ -465,35 +512,35 @@ desc = "A basic capacitor used in the construction of a variety of devices." icon_state = "capacitor" origin_tech = list(TECH_POWER = 1) - matter = list("metal" = 50, "glass" = 50) + matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 50) /obj/item/weapon/stock_parts/scanning_module name = "scanning module" desc = "A compact, high resolution scanning module used in the construction of certain devices." icon_state = "scan_module" origin_tech = list(TECH_MAGNET = 1) - matter = list("metal" = 50, "glass" = 20) + matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20) /obj/item/weapon/stock_parts/manipulator name = "micro-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "micro_mani" origin_tech = list(TECH_MATERIAL = 1, TECH_DATA = 1) - matter = list("metal" = 30) + matter = list(DEFAULT_WALL_MATERIAL = 30) /obj/item/weapon/stock_parts/micro_laser name = "micro-laser" desc = "A tiny laser used in certain devices." icon_state = "micro_laser" origin_tech = list(TECH_MAGNET = 1) - matter = list("metal" = 10, "glass" = 20) + matter = list(DEFAULT_WALL_MATERIAL = 10,"glass" = 20) /obj/item/weapon/stock_parts/matter_bin name = "matter bin" desc = "A container for hold compressed matter awaiting re-construction." icon_state = "matter_bin" origin_tech = list(TECH_MATERIAL = 1) - matter = list("metal" = 80) + matter = list(DEFAULT_WALL_MATERIAL = 80) //Rank 2 @@ -502,7 +549,7 @@ desc = "An advanced capacitor used in the construction of a variety of devices." origin_tech = list(TECH_POWER = 3) rating = 2 - matter = list("metal" = 50,"glass" = 50) + matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 50) /obj/item/weapon/stock_parts/scanning_module/adv name = "advanced scanning module" @@ -510,7 +557,7 @@ icon_state = "scan_module" origin_tech = list(TECH_MAGNET = 3) rating = 2 - matter = list("metal" = 50,"glass" = 20) + matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20) /obj/item/weapon/stock_parts/manipulator/nano name = "nano-manipulator" @@ -518,7 +565,7 @@ icon_state = "nano_mani" origin_tech = list(TECH_MATERIAL = 3, TECH_DATA = 2) rating = 2 - matter = list("metal" = 30) + matter = list(DEFAULT_WALL_MATERIAL = 30) /obj/item/weapon/stock_parts/micro_laser/high name = "high-power micro-laser" @@ -526,7 +573,7 @@ icon_state = "high_micro_laser" origin_tech = list(TECH_MAGNET = 3) rating = 2 - matter = list("metal" = 10,"glass" = 20) + matter = list(DEFAULT_WALL_MATERIAL = 10,"glass" = 20) /obj/item/weapon/stock_parts/matter_bin/adv name = "advanced matter bin" @@ -534,7 +581,7 @@ icon_state = "advanced_matter_bin" origin_tech = list(TECH_MATERIAL = 3) rating = 2 - matter = list("metal" = 80) + matter = list(DEFAULT_WALL_MATERIAL = 80) //Rating 3 @@ -543,14 +590,14 @@ desc = "A super-high capacity capacitor used in the construction of a variety of devices." origin_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4) rating = 3 - matter = list("metal" = 50,"glass" = 50) + matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 50) /obj/item/weapon/stock_parts/scanning_module/phasic name = "phasic scanning module" desc = "A compact, high resolution phasic scanning module used in the construction of certain devices." origin_tech = list(TECH_MAGNET = 5) rating = 3 - matter = list("metal" = 50,"glass" = 20) + matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20) /obj/item/weapon/stock_parts/manipulator/pico name = "pico-manipulator" @@ -558,7 +605,7 @@ icon_state = "pico_mani" origin_tech = list(TECH_MATERIAL = 5, TECH_DATA = 2) rating = 3 - matter = list("metal" = 30) + matter = list(DEFAULT_WALL_MATERIAL = 30) /obj/item/weapon/stock_parts/micro_laser/ultra name = "ultra-high-power micro-laser" @@ -566,7 +613,7 @@ desc = "A tiny laser used in certain devices." origin_tech = list(TECH_MAGNET = 5) rating = 3 - matter = list("metal" = 10,"glass" = 20) + matter = list(DEFAULT_WALL_MATERIAL = 10,"glass" = 20) /obj/item/weapon/stock_parts/matter_bin/super name = "super matter bin" @@ -574,7 +621,7 @@ icon_state = "super_matter_bin" origin_tech = list(TECH_MATERIAL = 5) rating = 3 - matter = list("metal" = 80) + matter = list(DEFAULT_WALL_MATERIAL = 80) // Subspace stock parts @@ -583,35 +630,35 @@ icon_state = "subspace_ansible" desc = "A compact module capable of sensing extradimensional activity." origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 5 ,TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - matter = list("metal" = 30,"glass" = 10) + matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10) /obj/item/weapon/stock_parts/subspace/filter name = "hyperwave filter" icon_state = "hyperwave_filter" desc = "A tiny device capable of filtering and converting super-intense radiowaves." origin_tech = list(TECH_DATA = 4, TECH_MAGNET = 2) - matter = list("metal" = 30,"glass" = 10) + matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10) /obj/item/weapon/stock_parts/subspace/amplifier name = "subspace amplifier" icon_state = "subspace_amplifier" desc = "A compact micro-machine capable of amplifying weak subspace transmissions." origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - matter = list("metal" = 30,"glass" = 10) + matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10) /obj/item/weapon/stock_parts/subspace/treatment name = "subspace treatment disk" icon_state = "treatment_disk" desc = "A compact micro-machine capable of stretching out hyper-compressed radio waves." origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 2, TECH_MATERIAL = 5, TECH_BLUESPACE = 2) - matter = list("metal" = 30,"glass" = 10) + matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10) /obj/item/weapon/stock_parts/subspace/analyzer name = "subspace wavelength analyzer" icon_state = "wavelength_analyzer" desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths." origin_tech = list(TECH_DATA = 3, TECH_MAGNETS = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - matter = list("metal" = 30,"glass" = 10) + matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10) /obj/item/weapon/stock_parts/subspace/crystal name = "ansible crystal" @@ -625,7 +672,7 @@ icon_state = "subspace_transmitter" desc = "A large piece of equipment used to open a window into the subspace dimension." origin_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 5, TECH_BLUESPACE = 3) - matter = list("metal" = 50) + matter = list(DEFAULT_WALL_MATERIAL = 50) /obj/item/weapon/ectoplasm name = "ectoplasm" diff --git a/code/defines/procs/admin.dm b/code/defines/procs/admin.dm index 2bfb8b94364..6c5f27fa070 100644 --- a/code/defines/procs/admin.dm +++ b/code/defines/procs/admin.dm @@ -1,13 +1,36 @@ -proc/log_and_message_admins(var/message as text) - log_admin(usr ? "[key_name(usr)] [message]" : "EVENT [message]") - message_admins(usr ? "[key_name(usr)] [message]" : "EVENT [message]") +proc/admin_notice(var/message, var/rights) + for(var/mob/M in mob_list) + if(check_rights(rights, 0, M)) + M << message + +proc/log_and_message_admins(var/message as text, var/mob/user = usr) + log_admin(user ? "[key_name(user)] [message]" : "EVENT [message]") + message_admins(user ? "[key_name(user)] [message]" : "EVENT [message]") + +proc/log_and_message_admins_many(var/list/mob/users, var/message) + if(!users || !users.len) + return + + var/list/user_keys = list() + for(var/mob/user in users) + user_keys += key_name(user) + + log_admin("[english_list(user_keys)] [message]") + message_admins("[english_list(user_keys)] [message]") proc/admin_log_and_message_admins(var/message as text) log_admin(usr ? "[key_name_admin(usr)] [message]" : "EVENT [message]") message_admins(usr ? "[key_name_admin(usr)] [message]" : "EVENT [message]", 1) proc/admin_attack_log(var/mob/attacker, var/mob/victim, var/attacker_message, var/victim_message, var/admin_message) - victim.attack_log += text("\[[time_stamp()]\] [victim_message] [key_name(attacker)]") - attacker.attack_log += text("\[[time_stamp()]\] [attacker_message] [key_name(victim)]") + victim.attack_log += text("\[[time_stamp()]\] [key_name(attacker)] - [victim_message]") + attacker.attack_log += text("\[[time_stamp()]\] [key_name(victim)] - [attacker_message]") msg_admin_attack("[key_name(attacker)] [admin_message] [key_name(victim)] (INTENT: [uppertext(attacker.a_intent)]) (JMP)") + +proc/admin_attacker_log_many_victims(var/mob/attacker, var/list/mob/victims, var/attacker_message, var/victim_message, var/admin_message) + if(!victims || !victims.len) + return + + for(var/mob/victim in victims) + admin_attack_log(attacker, victim, attacker_message, victim_message, admin_message) diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index 3e5454d8ac0..0a64e895924 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -15,28 +15,29 @@ log = do_log newscast = do_newscast -/datum/announcement/priority/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) +/datum/announcement/priority/New(var/do_log = 1, var/new_sound = 'sound/misc/notice2.ogg', var/do_newscast = 0) ..(do_log, new_sound, do_newscast) title = "Priority Announcement" announcement_type = "Priority Announcement" -/datum/announcement/priority/command/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) +/datum/announcement/priority/command/New(var/do_log = 1, var/new_sound = 'sound/misc/notice2.ogg', var/do_newscast = 0) ..(do_log, new_sound, do_newscast) title = "[command_name()] Update" announcement_type = "[command_name()] Update" -/datum/announcement/priority/security/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) +/datum/announcement/priority/security/New(var/do_log = 1, var/new_sound = 'sound/misc/notice2.ogg', var/do_newscast = 0) ..(do_log, new_sound, do_newscast) title = "Security Announcement" announcement_type = "Security Announcement" -/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast) +/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0) if(!message) return - var/tmp/message_title = new_title ? new_title : title - var/tmp/message_sound = new_sound ? sound(new_sound) : sound + var/message_title = new_title ? new_title : title + var/message_sound = new_sound ? new_sound : sound - message = sanitize(message, extra = 0) + if(!msg_sanitized) + message = sanitize(message, extra = 0) message_title = sanitizeSafe(message_title) Message(message, message_title) @@ -102,8 +103,8 @@ datum/announcement/proc/Sound(var/message_sound) PlaySound(message_sound) datum/announcement/priority/Sound(var/message_sound) - if(sound) - world << sound + if(message_sound) + world << message_sound datum/announcement/priority/command/Sound(var/message_sound) PlaySound(message_sound) diff --git a/code/defines/procs/radio.dm b/code/defines/procs/radio.dm index 1e0e045928b..0ee38f3b120 100644 --- a/code/defines/procs/radio.dm +++ b/code/defines/procs/radio.dm @@ -3,6 +3,16 @@ #define TELECOMMS_RECEPTION_RECEIVER 2 #define TELECOMMS_RECEPTION_BOTH 3 +/proc/register_radio(source, old_frequency, new_frequency, radio_filter) + if(old_frequency) + radio_controller.remove_object(source, old_frequency) + if(new_frequency) + return radio_controller.add_object(source, new_frequency, radio_filter) + +/proc/unregister_radio(source, frequency) + if(radio_controller) + radio_controller.remove_object(source, frequency) + /proc/get_frequency_name(var/display_freq) var/freq_text diff --git a/code/defines/procs/records.dm b/code/defines/procs/records.dm index 4e9fbcc9afc..256ae51dbf2 100644 --- a/code/defines/procs/records.dm +++ b/code/defines/procs/records.dm @@ -22,7 +22,7 @@ G.fields["photo_side"] = side data_core.general += G - del(dummy) + qdel(dummy) return G /proc/CreateSecurityRecord(var/name as text, var/id as text) diff --git a/code/defines/procs/sd_Alert.dm b/code/defines/procs/sd_Alert.dm index c63cab8f8b7..e10416f1128 100644 --- a/code/defines/procs/sd_Alert.dm +++ b/code/defines/procs/sd_Alert.dm @@ -1,168 +1,168 @@ -/* sd_Alert library - by Shadowdarke (shadowdarke@byond.com) - - sd_Alert() is a powerful and flexible alternative to the built in BYOND - alert() proc. sd_Alert offers timed popups, unlimited buttons, custom - appearance, and even the option to popup without stealing keyboard focus - from the map or command line. - - Please see demo.dm for detailed examples. - -FORMAT - sd_Alert(who, message, title, buttons, default, duration, unfocus, \ - size, table, style, tag, select, flags) - -ARGUMENTS - who - the client or mob to display the alert to. - message - text message to display - title - title of the alert box - buttons - list of buttons - Default Value: list("Ok") - default - default button selestion - Default Value: the first button in the list - duration - the number of ticks before this alert expires. If not - set, the alert lasts until a button is clicked. - Default Value: 0 (unlimited) - unfocus - if this value is set, the popup will not steal keyboard - focus from the map or command line. - Default Value: 1 (do not take focus) - size - size of the popup window in px - Default Value: "300x200" - table - optional parameters for the HTML table in the alert - Default Value: "width=100% height=100%" (fill the window) - style - optional style sheet information - tag - lets you specify a certain tag for this sd_Alert so you may manipulate it - externally. (i.e. force the alert to close, change options and redisplay, - reuse the same window, etc.) - select - if set, the buttons will be replaced with a selection box with a number of - lines displayed equal to this value. - Default value: 0 (use buttons) - flags - optional flags effecting the alert display. These flags may be ORed (|) - together for multiple effects. - SD_ALERT_SCROLL = display a scrollbar - SD_ALERT_SELECT_MULTI = forces selection box display (instead of - buttons) allows the user to select multiple - choices. - SD_ALERT_LINKS = display each choice as a plain text link. - Any selection box style overrides this flag. - SD_ALERT_NOVALIDATE = don't validate responses - Default value: SD_ALERT_SCROLL - (button display with scroll bar, validate responses) -RETURNS - The text of the selected button, or null if the alert duration expired - without a button click. - -Version 1 changes (from version 0): -* Added the tag, select, and flags arguments, thanks to several suggestions from Foomer. -* Split the sd_Alert/Alert() proc into New(), Display(), and Response() to allow more - customization by developers. Primarily developers would want to use Display() to change - the display of active tagged windows - -*/ - - -#define SD_ALERT_SCROLL 1 -#define SD_ALERT_SELECT_MULTI 2 -#define SD_ALERT_LINKS 4 -#define SD_ALERT_NOVALIDATE 8 - -proc/sd_Alert(client/who, message, title, buttons = list("Ok"),\ - default, duration = 0, unfocus = 1, size = "300x200", \ - table = "width=100% height=100%", style, tag, select, flags = SD_ALERT_SCROLL) - - if(ismob(who)) - var/mob/M = who - who = M.client - if(!istype(who)) CRASH("sd_Alert: Invalid target:[who] (\ref[who])") - - var/sd_alert/T = locate(tag) - if(T) - if(istype(T)) del(T) - else CRASH("sd_Alert: tag \"[tag]\" is already in use by datum '[T]' (type: [T.type])") - T = new(who, tag) - if(duration) - spawn(duration) - if(T) del(T) - return - T.Display(message,title,buttons,default,unfocus,size,table,style,select,flags) - . = T.Response() - -sd_alert - var - client/target - response - list/validation - - Del() - target << browse(null,"window=\ref[src]") - ..() - - New(who, tag) - ..() - target = who - src.tag = tag - - Topic(href,params[]) - if(usr.client != target) return - response = params["clk"] - - proc/Display(message,title,list/buttons,default,unfocus,size,table,style,select,flags) - if(unfocus) spawn() target << browse(null,null) - if(istext(buttons)) buttons = list(buttons) - if(!default) default = buttons[1] - if(!(flags & SD_ALERT_NOVALIDATE)) validation = buttons.Copy() - - var/html = {"[title][style]\ -
    [message]
    "} - - if(select || (flags & SD_ALERT_SELECT_MULTI)) // select style choices - html += {"
    \ - -
    " - else if(flags & SD_ALERT_LINKS) // text link style - for(var/b in buttons) - var/list/L = list() - L["clk"] = b - var/html_string=list2params(L) - var/focus - if(b == default) focus = " ID=fcs" - html += "[html_encode(b)]\ -
    " - else // button style choices - for(var/b in buttons) - var/list/L = list() - L["clk"] = b - var/html_string=list2params(L) - var/focus - if(b == default) focus = " ID=fcs" - html += " " - - html += "
    " - - target << browse(html,"window=\ref[src];size=[size];can_close=0") - - proc/Response() - var/validated - while(!validated) - while(target && !response) // wait for a response - sleep(2) - - if(response && validation) - if(istype(response, /list)) - var/list/L = response - validation - if(L.len) response = null - else validated = 1 - else if(response in validation) validated = 1 - else response=null - else validated = 1 - spawn(2) del(src) - return response +/* sd_Alert library + by Shadowdarke (shadowdarke@byond.com) + + sd_Alert() is a powerful and flexible alternative to the built in BYOND + alert() proc. sd_Alert offers timed popups, unlimited buttons, custom + appearance, and even the option to popup without stealing keyboard focus + from the map or command line. + + Please see demo.dm for detailed examples. + +FORMAT + sd_Alert(who, message, title, buttons, default, duration, unfocus, \ + size, table, style, tag, select, flags) + +ARGUMENTS + who - the client or mob to display the alert to. + message - text message to display + title - title of the alert box + buttons - list of buttons + Default Value: list("Ok") + default - default button selestion + Default Value: the first button in the list + duration - the number of ticks before this alert expires. If not + set, the alert lasts until a button is clicked. + Default Value: 0 (unlimited) + unfocus - if this value is set, the popup will not steal keyboard + focus from the map or command line. + Default Value: 1 (do not take focus) + size - size of the popup window in px + Default Value: "300x200" + table - optional parameters for the HTML table in the alert + Default Value: "width=100% height=100%" (fill the window) + style - optional style sheet information + tag - lets you specify a certain tag for this sd_Alert so you may manipulate it + externally. (i.e. force the alert to close, change options and redisplay, + reuse the same window, etc.) + select - if set, the buttons will be replaced with a selection box with a number of + lines displayed equal to this value. + Default value: 0 (use buttons) + flags - optional flags effecting the alert display. These flags may be ORed (|) + together for multiple effects. + SD_ALERT_SCROLL = display a scrollbar + SD_ALERT_SELECT_MULTI = forces selection box display (instead of + buttons) allows the user to select multiple + choices. + SD_ALERT_LINKS = display each choice as a plain text link. + Any selection box style overrides this flag. + SD_ALERT_NOVALIDATE = don't validate responses + Default value: SD_ALERT_SCROLL + (button display with scroll bar, validate responses) +RETURNS + The text of the selected button, or null if the alert duration expired + without a button click. + +Version 1 changes (from version 0): +* Added the tag, select, and flags arguments, thanks to several suggestions from Foomer. +* Split the sd_Alert/Alert() proc into New(), Display(), and Response() to allow more + customization by developers. Primarily developers would want to use Display() to change + the display of active tagged windows + +*/ + + +#define SD_ALERT_SCROLL 1 +#define SD_ALERT_SELECT_MULTI 2 +#define SD_ALERT_LINKS 4 +#define SD_ALERT_NOVALIDATE 8 + +proc/sd_Alert(client/who, message, title, buttons = list("Ok"),\ + default, duration = 0, unfocus = 1, size = "300x200", \ + table = "width=100% height=100%", style, tag, select, flags = SD_ALERT_SCROLL) + + if(ismob(who)) + var/mob/M = who + who = M.client + if(!istype(who)) CRASH("sd_Alert: Invalid target:[who] (\ref[who])") + + var/sd_alert/T = locate(tag) + if(T) + if(istype(T)) qdel(T) + else CRASH("sd_Alert: tag \"[tag]\" is already in use by datum '[T]' (type: [T.type])") + T = new(who, tag) + if(duration) + spawn(duration) + if(T) qdel(T) + return + T.Display(message,title,buttons,default,unfocus,size,table,style,select,flags) + . = T.Response() + +sd_alert + var + client/target + response + list/validation + + Destroy() + target << browse(null,"window=\ref[src]") + ..() + + New(who, tag) + ..() + target = who + src.tag = tag + + Topic(href,params[]) + if(usr.client != target) return + response = params["clk"] + + proc/Display(message,title,list/buttons,default,unfocus,size,table,style,select,flags) + if(unfocus) spawn() target << browse(null,null) + if(istext(buttons)) buttons = list(buttons) + if(!default) default = buttons[1] + if(!(flags & SD_ALERT_NOVALIDATE)) validation = buttons.Copy() + + var/html = {"[title][style]\ +
    [message]
    "} + + if(select || (flags & SD_ALERT_SELECT_MULTI)) // select style choices + html += {"
    \ + +
    " + else if(flags & SD_ALERT_LINKS) // text link style + for(var/b in buttons) + var/list/L = list() + L["clk"] = b + var/html_string=list2params(L) + var/focus + if(b == default) focus = " ID=fcs" + html += "[html_encode(b)]\ +
    " + else // button style choices + for(var/b in buttons) + var/list/L = list() + L["clk"] = b + var/html_string=list2params(L) + var/focus + if(b == default) focus = " ID=fcs" + html += " " + + html += "
    " + + target << browse(html,"window=\ref[src];size=[size];can_close=0") + + proc/Response() + var/validated + while(!validated) + while(target && !response) // wait for a response + sleep(2) + + if(response && validation) + if(istype(response, /list)) + var/list/L = response - validation + if(L.len) response = null + else validated = 1 + else if(response in validation) validated = 1 + else response=null + else validated = 1 + spawn(2) qdel(src) + return response diff --git a/code/defines/procs/statistics.dm b/code/defines/procs/statistics.dm index 8a9eb4042dc..60254577583 100644 --- a/code/defines/procs/statistics.dm +++ b/code/defines/procs/statistics.dm @@ -1,34 +1,20 @@ -proc/sql_poll_players() +proc/sql_poll_population() if(!sqllogging) return + var/admincount = admins.len var/playercount = 0 for(var/mob/M in player_list) if(M.client) playercount += 1 establish_db_connection() if(!dbcon.IsConnected()) - log_game("SQL ERROR during player polling. Failed to connect.") + log_game("SQL ERROR during population polling. Failed to connect.") else var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss") - var/DBQuery/query = dbcon_old.NewQuery("INSERT INTO population (playercount, time) VALUES ([playercount], '[sqltime]')") + var/DBQuery/query = dbcon_old.NewQuery("INSERT INTO `tgstation`.`population` (`playercount`, `admincount`, `time`) VALUES ([playercount], [admincount], '[sqltime]')") if(!query.Execute()) var/err = query.ErrorMsg() - log_game("SQL ERROR during player polling. Error : \[[err]\]\n") - - -proc/sql_poll_admins() - if(!sqllogging) - return - var/admincount = admins.len - establish_db_connection() - if(!dbcon.IsConnected()) - log_game("SQL ERROR during admin polling. Failed to connect.") - else - var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss") - var/DBQuery/query = dbcon_old.NewQuery("INSERT INTO population (admincount, time) VALUES ([admincount], '[sqltime]')") - if(!query.Execute()) - var/err = query.ErrorMsg() - log_game("SQL ERROR during admin polling. Error : \[[err]\]\n") + log_game("SQL ERROR during population polling. Error : \[[err]\]\n") proc/sql_report_round_start() // TODO @@ -111,10 +97,8 @@ proc/statistic_cycle() if(!sqllogging) return while(1) - sql_poll_players() - sleep(600) - sql_poll_admins() - sleep(6000) // Poll every ten minutes + sql_poll_population() + sleep(6000) //This proc is used for feedback. It is executed at round end. proc/sql_commit_feedback() @@ -157,4 +141,4 @@ proc/sql_commit_feedback() var/DBQuery/query = dbcon.NewQuery("INSERT INTO erro_feedback (id, roundid, time, variable, value) VALUES (null, [newroundid], Now(), '[variable]', '[value]')") if(!query.Execute()) var/err = query.ErrorMsg() - log_game("SQL ERROR during death reporting. Error : \[[err]\]\n") \ No newline at end of file + log_game("SQL ERROR during death reporting. Error : \[[err]\]\n") diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm index 73e17a20430..aad02b1c6c6 100644 --- a/code/game/antagonist/antagonist.dm +++ b/code/game/antagonist/antagonist.dm @@ -199,7 +199,7 @@ for(var/datum/uplink_item/UI in H.purchase_log) var/obj/I = new UI.path refined_log.Add("[H.purchase_log[UI]]x\icon[I][UI.name]") - del(I) + qdel(I) purchases = english_list(refined_log, nothing_text = "") if(uplink_true) text += " (used [TC_uses] TC)" @@ -215,7 +215,7 @@ if(antag.current && antag.current.client) for(var/image/I in antag.current.client.images) if(I.icon_state == antag_indicator) - del(I) + qdel(I) for(var/datum/mind/other_antag in current_antagonists) if(other_antag.current) antag.current.client.images |= image('icons/mob/mob.dmi', loc = other_antag.current, icon_state = antag_indicator) @@ -241,10 +241,10 @@ if(antag.current.client) for(var/image/I in antag.current.client.images) if(I.icon_state == antag_indicator && I.loc == player.current) - del(I) + qdel(I) if(player.current && player.current.client) for(var/image/I in player.current.client.images) if(I.icon_state == antag_indicator) - del(I) + qdel(I) diff --git a/code/game/antagonist/antagonist_build.dm b/code/game/antagonist/antagonist_build.dm index f0f92c62b7a..35af4e6f804 100644 --- a/code/game/antagonist/antagonist_build.dm +++ b/code/game/antagonist/antagonist_build.dm @@ -15,7 +15,7 @@ var/mob/holder = player.current player.current = new mob_path(get_turf(player.current)) player.transfer_to(player.current) - if(holder) del(holder) + if(holder) qdel(holder) player.original = player.current return player.current @@ -28,11 +28,13 @@ // This could use work. if(flags & ANTAG_CLEAR_EQUIPMENT) for(var/obj/item/thing in player.contents) - del(thing) + player.drop_from_inventory(thing) + if(thing.loc != player) + qdel(thing) return 1 if(flags & ANTAG_SET_APPEARANCE) - player.change_appearance(APPEARANCE_ALL, player, player, valid_species) + player.change_appearance(APPEARANCE_ALL, player.loc, player, valid_species, state = z_state) /datum/antagonist/proc/unequip(var/mob/living/carbon/human/player) if(!istype(player)) @@ -80,6 +82,7 @@ /datum/antagonist/proc/create_id(var/assignment, var/mob/living/carbon/human/player) var/obj/item/weapon/card/id/W = new id_type(player) + if(!W) return W.name = "[player.real_name]'s ID Card" W.access |= default_access W.assignment = "[assignment]" diff --git a/code/game/antagonist/outsider/deathsquad.dm b/code/game/antagonist/outsider/deathsquad.dm index 05fb6d1ec9b..73c2c7fd78a 100644 --- a/code/game/antagonist/outsider/deathsquad.dm +++ b/code/game/antagonist/outsider/deathsquad.dm @@ -44,8 +44,9 @@ var/datum/antagonist/deathsquad/deathsquad player.implant_loyalty(player) var/obj/item/weapon/card/id/id = create_id("Asset Protection", player) - id.access |= get_all_accesses() - id.icon_state = "centcom" + if(id) + id.access |= get_all_accesses() + id.icon_state = "centcom" create_radio(DTH_FREQ, player) /datum/antagonist/deathsquad/apply(var/datum/mind/player) diff --git a/code/game/antagonist/outsider/ert.dm b/code/game/antagonist/outsider/ert.dm index f52f031002c..946ff1dfc28 100644 --- a/code/game/antagonist/outsider/ert.dm +++ b/code/game/antagonist/outsider/ert.dm @@ -32,13 +32,9 @@ var/datum/antagonist/ert/ert player.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves) player.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(src), slot_glasses) - var/obj/item/weapon/card/id/W = new(src) - W.assignment = "Emergency Response Team" + var/obj/item/weapon/card/id/centcom/ERT/W = new(src) W.registered_name = player.real_name W.name = "[player.real_name]'s ID Card ([W.assignment])" - W.icon_state = "centcom" - W.access = get_all_accesses() - W.access += get_all_centcom_access() player.equip_to_slot_or_del(W, slot_wear_id) return 1 diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm index 92090515b16..a7949011fc5 100644 --- a/code/game/antagonist/outsider/raider.dm +++ b/code/game/antagonist/outsider/raider.dm @@ -30,8 +30,8 @@ var/datum/antagonist/raider/raiders var/list/raider_glasses = list( /obj/item/clothing/glasses/thermal, - /obj/item/clothing/glasses/thermal/eyepatch, - /obj/item/clothing/glasses/thermal/monocle + /obj/item/clothing/glasses/thermal/plain/eyepatch, + /obj/item/clothing/glasses/thermal/plain/monocle ) var/list/raider_helmets = list( diff --git a/code/game/antagonist/outsider/wizard.dm b/code/game/antagonist/outsider/wizard.dm index 7b410cc7bc8..2923008a7b8 100644 --- a/code/game/antagonist/outsider/wizard.dm +++ b/code/game/antagonist/outsider/wizard.dm @@ -95,21 +95,31 @@ var/datum/antagonist/wizard/wizards //To batch-remove wizard spells. Linked to mind.dm. /mob/proc/spellremove(var/mob/M as mob) - for(var/obj/effect/proc_holder/spell/spell_to_remove in src.spell_list) - del(spell_to_remove) + for(var/spell/spell_to_remove in src.spell_list) + remove_spell(spell_to_remove) -/*Checks if the wizard can cast spells. +obj/item/clothing + var/wizard_garb = 0 + +// Does this clothing slot count as wizard garb? (Combines a few checks) +/proc/is_wiz_garb(var/obj/item/clothing/C) + return C && C.wizard_garb + +/*Checks if the wizard is wearing the proper attire. Made a proc so this is not repeated 14 (or more) times.*/ -/mob/proc/casting() -//Removed the stat check because not all spells require clothing now. - if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe)) - usr << "I don't feel strong enough without my robe." +/mob/proc/wearing_wiz_garb() + src << "Silly creature, you're not a human. Only humans can cast this spell." + return 0 + +// Humans can wear clothes. +/mob/living/carbon/human/wearing_wiz_garb() + if(!is_wiz_garb(src.wear_suit)) + src << "I don't feel strong enough without my robe." return 0 - if(!istype(usr:shoes, /obj/item/clothing/shoes/sandal)) - usr << "I don't feel strong enough without my sandals." + if(!is_wiz_garb(src.shoes)) + src << "I don't feel strong enough without my sandals." return 0 - if(!istype(usr:head, /obj/item/clothing/head/wizard)) - usr << "I don't feel strong enough without my hat." + if(!is_wiz_garb(src.head)) + src << "I don't feel strong enough without my hat." return 0 - else - return 1 + return 1 diff --git a/code/game/antagonist/station/cultist.dm b/code/game/antagonist/station/cultist.dm index 3968418e023..3f5d65d21da 100644 --- a/code/game/antagonist/station/cultist.dm +++ b/code/game/antagonist/station/cultist.dm @@ -24,11 +24,13 @@ var/datum/antagonist/cultist/cult flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE max_antags = 200 // No upper limit. max_antags_round = 200 + var/allow_narsie = 1 var/datum/mind/sacrifice_target var/list/startwords = list("blood","join","self","hell") var/list/allwords = list("travel","self","see","hell","blood","join","tech","destroy", "other", "hide") var/list/sacrificed = list() + var/list/harvested = list() /datum/antagonist/cultist/New() ..() diff --git a/code/game/antagonist/station/highlander.dm b/code/game/antagonist/station/highlander.dm index 0af6e1e23de..9b82b158525 100644 --- a/code/game/antagonist/station/highlander.dm +++ b/code/game/antagonist/station/highlander.dm @@ -32,7 +32,7 @@ var/datum/antagonist/highlander/highlanders for (var/obj/item/I in player) if (istype(I, /obj/item/weapon/implant)) continue - del(I) + qdel(I) player.equip_to_slot_or_del(new /obj/item/clothing/under/kilt(player), slot_w_uniform) player.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(player), slot_l_ear) diff --git a/code/game/antagonist/station/rogue_ai.dm b/code/game/antagonist/station/rogue_ai.dm index 372556c2051..3d9026ff88f 100644 --- a/code/game/antagonist/station/rogue_ai.dm +++ b/code/game/antagonist/station/rogue_ai.dm @@ -27,7 +27,7 @@ var/datum/antagonist/rogue_ai/malf hacked_apcs |= apc /datum/antagonist/rogue_ai/proc/update_takeover_time() - hack_time -= ((hacked_apcs.len/6)*tickerProcess.getLastTickerTimeDuration()) + hack_time -= ((hacked_apcs.len/6)*2.0) /datum/antagonist/rogue_ai/tick() if(revealed && hacked_apcs.len >= 3) @@ -213,7 +213,7 @@ var/datum/antagonist/rogue_ai/malf /client/proc/reactivate_camera) current:laws = new /datum/ai_laws/nanotrasen - del(current:malf_picker) + qdel(current:malf_picker) current:show_laws() current.icon_state = "ai" diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index c382ce4d078..21e965244bb 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -26,8 +26,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon = 'icons/turf/areas.dmi' icon_state = "unknown" layer = 10 + luminosity = 1 mouse_opacity = 0 - invisibility = INVISIBILITY_LIGHTING var/lightswitch = 1 var/eject = null @@ -48,15 +48,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station var/has_gravity = 1 var/list/apc = list() var/no_air = null - var/area/master // master area used for power calcluations - // (original area before splitting due to sd_DAL) - var/list/related // the other areas of the same type as this // var/list/lights // list of all lights on this area var/list/all_doors = list() //Added by Strumpetplaya - Alarm Change - Contains a list of doors adjacent to this area var/air_doors_activated = 0 var/list/ambience = list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg','sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg','sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg','sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg','sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg','sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg') - var/sound/forced_ambience = null - + var/list/forced_ambience = null + var/sound_env = 2 //reverb preset for sounds played in this area, see sound datum reference for more /*Adding a wizard area teleport list because motherfucking lag -- Urist*/ /*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ var/list/teleportlocs = list() @@ -102,7 +99,6 @@ var/list/ghostteleportlocs = list() icon_state = "space" requires_power = 1 always_unpowered = 1 - lighting_use_dynamic = 1 power_light = 0 power_equip = 0 power_environ = 0 @@ -145,10 +141,8 @@ area/space/atmosalert() //place to another. Look at escape shuttle for example. //All shuttles should now be under shuttle since we have smooth-wall code. -/area/shuttle //DO NOT TURN THE lighting_use_dynamic STUFF ON FOR SHUTTLES. IT BREAKS THINGS. +/area/shuttle requires_power = 0 - luminosity = 1 - lighting_use_dynamic = 0 /area/shuttle/arrival name = "\improper Arrival Shuttle" @@ -249,15 +243,11 @@ area/space/atmosalert() icon_state = "shuttle" name = "\improper Alien Shuttle Base" requires_power = 1 - luminosity = 0 - lighting_use_dynamic = 1 /area/shuttle/alien/mine icon_state = "shuttle" name = "\improper Alien Shuttle Mine" requires_power = 1 - luminosity = 0 - lighting_use_dynamic = 1 /area/shuttle/prison/ name = "\improper Prison Shuttle" @@ -343,7 +333,6 @@ area/space/atmosalert() name = "start area" icon_state = "start" requires_power = 0 - luminosity = 1 lighting_use_dynamic = 0 has_gravity = 1 @@ -361,6 +350,7 @@ area/space/atmosalert() icon_state = "centcom" requires_power = 0 unlimited_power = 1 + lighting_use_dynamic = 0 /area/centcom/control name = "\improper Centcom Control" @@ -399,6 +389,7 @@ area/space/atmosalert() icon_state = "syndie-ship" requires_power = 0 unlimited_power = 1 + lighting_use_dynamic = 0 /area/syndicate_mothership/control name = "\improper Mercenary Control Room" @@ -808,6 +799,9 @@ area/space/atmosalert() //Hallway +/area/hallway/primary/ + sound_env = 12 //hallway + /area/hallway/primary/fore name = "\improper Fore Primary Hallway" icon_state = "hallF" @@ -873,27 +867,27 @@ area/space/atmosalert() music = null /area/crew_quarters/captain - name = "\improper Captain's Office" + name = "\improper Command - Captain's Office" icon_state = "captain" /area/crew_quarters/heads/hop - name = "\improper Head of Personnel's Office" + name = "\improper Command - HoP's Office" icon_state = "head_quarters" /area/crew_quarters/heads/hor - name = "\improper Research Director's Office" + name = "\improper Research - RD's Office" icon_state = "head_quarters" /area/crew_quarters/heads/chief - name = "\improper Chief Engineer's Office" + name = "\improper Engineering - CE's Office" icon_state = "head_quarters" /area/crew_quarters/heads/hos - name = "\improper Head of Security's Office" + name = "\improper Security - HoS' Office" icon_state = "head_quarters" /area/crew_quarters/heads/cmo - name = "\improper Chief Medical Officer's Office" + name = "\improper Medbay - CMO's Office" icon_state = "head_quarters" /area/crew_quarters/courtroom @@ -1006,16 +1000,13 @@ area/space/atmosalert() /area/holodeck name = "\improper Holodeck" icon_state = "Holodeck" - luminosity = 1 lighting_use_dynamic = 0 /area/holodeck/alphadeck name = "\improper Holodeck Alpha" - /area/holodeck/source_plating name = "\improper Holodeck - Off" - icon_state = "Holodeck" /area/holodeck/source_emptycourt name = "\improper Holodeck - Empty Court" @@ -1031,11 +1022,9 @@ area/space/atmosalert() /area/holodeck/source_courtroom name = "\improper Holodeck - Courtroom" - icon_state = "Holodeck" /area/holodeck/source_beach name = "\improper Holodeck - Beach" - icon_state = "Holodeck" // Lazy. /area/holodeck/source_burntest name = "\improper Holodeck - Atmospheric Burn Test" @@ -1062,9 +1051,6 @@ area/space/atmosalert() name = "\improper Holodeck - Space" has_gravity = 0 - - - //Engineering /area/engineering/ @@ -1085,7 +1071,7 @@ area/space/atmosalert() icon_state = "atmos_storage" /area/engineering/drone_fabrication - name = "\improper Drone Fabrication" + name = "\improper Engineering Drone Fabrication" icon_state = "drone_fab" /area/engineering/engine_smes @@ -1143,7 +1129,6 @@ area/space/atmosalert() /area/solar requires_power = 1 always_unpowered = 1 - luminosity = 1 lighting_use_dynamic = 0 auxport @@ -1171,23 +1156,23 @@ area/space/atmosalert() icon_state = "panelsP" /area/maintenance/auxsolarport - name = "Fore Port Solar Maintenance" + name = "Solar Maintenance - Fore Port" icon_state = "SolarcontrolP" /area/maintenance/starboardsolar - name = "Aft Starboard Solar Maintenance" + name = "Solar Maintenance - Aft Starboard" icon_state = "SolarcontrolS" /area/maintenance/portsolar - name = "Aft Port Solar Maintenance" + name = "Solar Maintenance - Aft Port" icon_state = "SolarcontrolP" /area/maintenance/auxsolarstarboard - name = "Fore Starboard Solar Maintenance" + name = "Solar Maintenance - Fore Starboard" icon_state = "SolarcontrolS" /area/maintenance/foresolar - name = "Fore Solar Maintenance" + name = "Solar Maintenance - Fore" icon_state = "SolarcontrolA" /area/assembly/chargebay @@ -1362,35 +1347,35 @@ area/space/atmosalert() icon_state = "security" /area/security/lobby - name = "\improper Security lobby" + name = "\improper Security Lobby" icon_state = "security" /area/security/brig - name = "\improper Brig" + name = "\improper Security - Brig" icon_state = "brig" /area/security/prison - name = "\improper Prison Wing" + name = "\improper Security - Prison Wing" icon_state = "sec_prison" /area/security/warden - name = "\improper Warden" + name = "\improper Security - Warden's Office" icon_state = "Warden" /area/security/armoury - name = "\improper Armory" + name = "\improper Security - Armory" icon_state = "Warden" /area/security/detectives_office - name = "\improper Detective's Office" + name = "\improper Security - Forensic Office" icon_state = "detective" /area/security/range - name = "\improper Firing Range" + name = "\improper Security - Firing Range" icon_state = "firingrange" /area/security/tactical - name = "\improper Tactical Equipment" + name = "\improper Security - Tactical Equipment" icon_state = "Tactical" @@ -1420,7 +1405,7 @@ area/space/atmosalert() icon_state = "checkpoint1" /area/security/checkpoint2 - name = "\improper Security Checkpoint" + name = "\improper Security - Arrival Checkpoint" icon_state = "security" /area/security/checkpoint/supply @@ -1451,14 +1436,6 @@ area/space/atmosalert() name = "\improper Quartermasters" icon_state = "quart" -///////////WORK IN PROGRESS////////// - -/area/quartermaster/sorting - name = "\improper Delivery Office" - icon_state = "quartstorage" - -////////////WORK IN PROGRESS////////// - /area/quartermaster/office name = "\improper Cargo Office" icon_state = "quartoffice" @@ -1468,21 +1445,13 @@ area/space/atmosalert() icon_state = "quartstorage" /area/quartermaster/qm - name = "\improper Quartermaster's Office" + name = "\improper Cargo - Quartermaster's Office" icon_state = "quart" /area/quartermaster/miningdock - name = "\improper Mining Dock" + name = "\improper Cargo Mining Dock" icon_state = "mining" -/area/quartermaster/miningstorage - name = "\improper Mining Storage" - icon_state = "green" - -/area/quartermaster/mechbay - name = "\improper Mech Bay" - icon_state = "yellow" - /area/janitor/ name = "\improper Custodial Closet" icon_state = "janitor" @@ -1770,7 +1739,7 @@ area/space/atmosalert() //Construction /area/construction - name = "\improper Construction Area" + name = "\improper Engineering Construction Area" icon_state = "yellow" /area/construction/supplyshuttle @@ -2041,6 +2010,7 @@ area/space/atmosalert() luminosity = 1 lighting_use_dynamic = 0 requires_power = 0 + ambience = list() var/sound/mysound = null New() diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 0778f50174a..38452c3d5bd 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -10,44 +10,38 @@ /area/New() icon_state = "" layer = 10 - master = src //moved outside the spawn(1) to avoid runtimes in lighting.dm when it references loc.loc.master ~Carn uid = ++global_uid - related = list(src) all_areas += src - if(requires_power) - luminosity = 0 - else + if(!requires_power) power_light = 0 //rastaf0 power_equip = 0 //rastaf0 power_environ = 0 //rastaf0 - luminosity = 1 - lighting_use_dynamic = 0 ..() // spawn(15) power_change() // all machines set to current power level, also updates lighting icon - InitializeLighting() + +/area/proc/get_contents() + return contents /area/proc/get_cameras() var/list/cameras = list() - for (var/area/RA in related) - for (var/obj/machinery/camera/C in RA) - cameras += C + for (var/obj/machinery/camera/C in src) + cameras += C return cameras /area/proc/atmosalert(danger_level, var/alarm_source) if (danger_level == 0) - atmosphere_alarm.clearAlarm(master, alarm_source) + atmosphere_alarm.clearAlarm(src, alarm_source) else - atmosphere_alarm.triggerAlarm(master, alarm_source, severity = danger_level) + atmosphere_alarm.triggerAlarm(src, alarm_source, severity = danger_level) //Check all the alarms before lowering atmosalm. Raising is perfectly fine. - for (var/area/RA in related) - for (var/obj/machinery/alarm/AA in RA) - if (!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted && AA.report_danger_level) - danger_level = max(danger_level, AA.danger_level) + for (var/obj/machinery/alarm/AA in src) + if (!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted && AA.report_danger_level) + danger_level = max(danger_level, AA.danger_level) if(danger_level != atmosalm) if (danger_level < 1 && atmosalm >= 1) @@ -57,17 +51,16 @@ air_doors_close() atmosalm = danger_level - for(var/area/RA in related) - for (var/obj/machinery/alarm/AA in RA) - AA.update_icon() + for (var/obj/machinery/alarm/AA in src) + AA.update_icon() return 1 return 0 /area/proc/air_doors_close() - if(!src.master.air_doors_activated) - src.master.air_doors_activated = 1 - for(var/obj/machinery/door/firedoor/E in src.master.all_doors) + if(!air_doors_activated) + air_doors_activated = 1 + for(var/obj/machinery/door/firedoor/E in all_doors) if(!E.blocked) if(E.operating) E.nextstate = CLOSED @@ -76,9 +69,9 @@ E.close() /area/proc/air_doors_open() - if(src.master.air_doors_activated) - src.master.air_doors_activated = 0 - for(var/obj/machinery/door/firedoor/E in src.master.all_doors) + if(air_doors_activated) + air_doors_activated = 0 + for(var/obj/machinery/door/firedoor/E in all_doors) if(!E.blocked) if(E.operating) E.nextstate = OPEN @@ -89,11 +82,8 @@ /area/proc/fire_alert() if(!fire) - master.fire = 1 //used for firedoor checks - master.updateicon() - for(var/area/A in related) - A.fire = 1 - A.updateicon() + fire = 1 //used for firedoor checks + updateicon() mouse_opacity = 0 for(var/obj/machinery/door/firedoor/D in all_doors) if(!D.blocked) @@ -105,11 +95,8 @@ /area/proc/fire_reset() if (fire) - master.fire = 0 //used for firedoor checks - master.updateicon() - for(var/area/A in related) - A.fire = 0 - A.updateicon() + fire = 0 //used for firedoor checks + updateicon() mouse_opacity = 0 for(var/obj/machinery/door/firedoor/D in all_doors) if(!D.blocked) @@ -153,7 +140,7 @@ return /area/proc/updateicon() - if ((fire || eject || party) && (!requires_power||power_environ) && !lighting_space)//If it doesn't require power, can still activate this proc. + if ((fire || eject || party) && (!requires_power||power_environ) && !istype(src, /area/space))//If it doesn't require power, can still activate this proc. if(fire && !eject && !party) icon_state = "blue" /*else if(atmosalm && !fire && !eject && !party) @@ -177,56 +164,53 @@ /area/proc/powered(var/chan) // return true if the area has power to given channel - if(!master.requires_power) + if(!requires_power) return 1 - if(master.always_unpowered) + if(always_unpowered) return 0 - if(src.lighting_space) - return 0 // Nope sorry switch(chan) if(EQUIP) - return master.power_equip + return power_equip if(LIGHT) - return master.power_light + return power_light if(ENVIRON) - return master.power_environ + return power_environ return 0 // called when power status changes /area/proc/power_change() - for(var/area/RA in related) - for(var/obj/machinery/M in RA) // for each machine in the area - M.power_change() // reverify power status (to update icons etc.) - if (fire || eject || party) - RA.updateicon() + for(var/obj/machinery/M in src) // for each machine in the area + M.power_change() // reverify power status (to update icons etc.) + if (fire || eject || party) + updateicon() /area/proc/usage(var/chan) var/used = 0 switch(chan) if(LIGHT) - used += master.used_light + used += used_light if(EQUIP) - used += master.used_equip + used += used_equip if(ENVIRON) - used += master.used_environ + used += used_environ if(TOTAL) - used += master.used_light + master.used_equip + master.used_environ + used += used_light + used_equip + used_environ return used /area/proc/clear_usage() - master.used_equip = 0 - master.used_light = 0 - master.used_environ = 0 + used_equip = 0 + used_light = 0 + used_environ = 0 /area/proc/use_power(var/amount, var/chan) switch(chan) if(EQUIP) - master.used_equip += amount + used_equip += amount if(LIGHT) - master.used_light += amount + used_light += amount if(ENVIRON) - master.used_environ += amount + used_environ += amount var/list/mob/living/forced_ambiance_list = new @@ -262,37 +246,35 @@ var/list/mob/living/forced_ambiance_list = new L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = 2) if(forced_ambience) - forced_ambiance_list += L - L << forced_ambience + if(forced_ambience.len) + forced_ambiance_list |= L + L << sound(pick(forced_ambience), repeat = 1, wait = 0, volume = 25, channel = 1) + else + L << sound(null, channel = 1) else if(src.ambience.len && prob(35)) if((world.time >= L.client.played + 600)) - var/musVolume = 25 var/sound = pick(ambience) - L << sound(sound, repeat = 0, wait = 0, volume = musVolume, channel = 1) + L << sound(sound, repeat = 0, wait = 0, volume = 25, channel = 1) L.client.played = world.time /area/proc/gravitychange(var/gravitystate = 0, var/area/A) - A.has_gravity = gravitystate - for(var/area/SubA in A.related) - SubA.has_gravity = gravitystate - - if(gravitystate) - for(var/mob/living/carbon/human/M in SubA) - thunk(M) - for(var/mob/M1 in SubA) - M1.make_floating(0) - else - for(var/mob/M in SubA) - if(M.Check_Dense_Object() && istype(src,/mob/living/carbon/human/)) - var/mob/living/carbon/human/H = src - if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP)) //magboots + dense_object = no floaty effect - H.make_floating(0) - else - H.make_floating(1) + if(gravitystate) + for(var/mob/living/carbon/human/M in A) + thunk(M) + for(var/mob/M1 in A) + M1.make_floating(0) + else + for(var/mob/M in A) + if(M.Check_Dense_Object() && istype(src,/mob/living/carbon/human/)) + var/mob/living/carbon/human/H = src + if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP)) //magboots + dense_object = no floaty effect + H.make_floating(0) else - M.make_floating(1) + H.make_floating(1) + else + M.make_floating(1) /area/proc/thunk(mob) if(istype(get_turf(mob), /turf/space)) // Can't fall onto nothing. diff --git a/code/game/area/asteroid_areas.dm b/code/game/area/asteroid_areas.dm index edfb99f57f6..12ae5377ce2 100644 --- a/code/game/area/asteroid_areas.dm +++ b/code/game/area/asteroid_areas.dm @@ -3,6 +3,7 @@ /area/mine icon_state = "mining" music = 'sound/ambience/song_game.ogg' + sound_env = 5 //stoneroom /area/mine/explored name = "Mine" diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm index e5b421e9afd..8aa6b1cd64e 100644 --- a/code/game/asteroid.dm +++ b/code/game/asteroid.dm @@ -32,7 +32,7 @@ proc/spawn_room(var/atom/start_loc,var/x_size,var/y_size,var/wall,var/floor , va var/cur_loc = locate(start_loc.x+x,start_loc.y+y,start_loc.z) if(clean) for(var/O in cur_loc) - del(O) + qdel(O) var/area/asteroid/artifactroom/A = new if(name) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 960a75d4fb5..742c6389a95 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -11,6 +11,7 @@ var/pass_flags = 0 var/throwpass = 0 var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom. + var/simulated = 1 //filter for actions - used by lighting overlays ///Chemistry. var/datum/reagents/reagents = null @@ -22,6 +23,18 @@ //Detective Work, used for the duplicate data points kept in the scanners var/list/original_atom +/atom/Destroy() + . = ..() + density = 0 + set_opacity(0) + + if(reagents) + qdel(reagents) + reagents = null + for(var/atom/movable/AM in contents) + qdel(AM) + invisibility = 101 + /atom/proc/assume_air(datum/gas_mixture/giver) return null @@ -66,7 +79,6 @@ return flags & INSERT_CONTAINER */ - /atom/proc/meteorhit(obj/meteor as obj) return @@ -148,7 +160,7 @@ its easier to just keep the beam vertical. for(var/obj/effect/overlay/beam/O in orange(10,src)) //This section erases the previously drawn beam because I found it was easier to if(O.BeamSource==src) //just draw another instance of the beam instead of trying to manipulate all the - del O //pieces to a new orientation. + qdel(O) //pieces to a new orientation. var/Angle=round(Get_Angle(src,BeamTarget)) var/icon/I=new(icon,icon_state) I.Turn(Angle) @@ -189,7 +201,7 @@ its easier to just keep the beam vertical. X.pixel_y=Pixel_y sleep(3) //Changing this to a lower value will cause the beam to follow more smoothly with movement, but it will also be more laggy. //I've found that 3 ticks provided a nice balance for my use. - for(var/obj/effect/overlay/beam/O in orange(10,src)) if(O.BeamSource==src) del O + for(var/obj/effect/overlay/beam/O in orange(10,src)) if(O.BeamSource==src) qdel(O) //All atoms @@ -230,6 +242,9 @@ its easier to just keep the beam vertical. /atom/proc/fire_act() return +/atom/proc/melt() + return + /atom/proc/hitby(atom/movable/AM as mob|obj) if (density) AM.throwing = 0 @@ -359,7 +374,7 @@ its easier to just keep the beam vertical. //Cleaning up shit. if(fingerprints && !fingerprints.len) - del(fingerprints) + qdel(fingerprints) return @@ -416,7 +431,7 @@ its easier to just keep the beam vertical. src.color = initial(src.color) //paint src.germ_level = 0 if(istype(blood_DNA, /list)) - del(blood_DNA) + qdel(blood_DNA) return 1 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 79d6e8fd08d..f86c135da40 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -14,6 +14,29 @@ var/moved_recently = 0 var/mob/pulledby = null +/atom/movable/New() + ..() + if(ticker && ticker.current_state == GAME_STATE_PLAYING) + initialize() + +/atom/movable/Del() + if(isnull(gcDestroyed) && loc) + testing("GC: -- [type] was deleted via del() rather than qdel() --") + CRASH() // Debug until I can get a clean server start. +// else if(isnull(gcDestroyed)) +// testing("GC: [type] was deleted via GC without qdel()") //Not really a huge issue but from now on, please qdel() +// else +// testing("GC: [type] was deleted via GC with qdel()") + ..() + +/atom/movable/Destroy() + . = ..() + + loc = null + +/atom/movable/proc/initialize() + return + /atom/movable/Bump(var/atom/A, yes) if(src.throwing) src.throw_impact(A) @@ -187,4 +210,4 @@ /atom/movable/overlay/attack_hand(a, b, c) if (src.master) return src.master.attack_hand(a, b, c) - return \ No newline at end of file + return diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 9bfdf9f0b65..ce6320cd88c 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -165,7 +165,8 @@ if((0 < beard) && (beard <= facial_hair_styles_list.len)) H.f_style = facial_hair_styles_list[beard] - H.update_body(0) + H.force_update_limbs() + H.update_eyes() H.update_hair() return 1 diff --git a/code/game/dna/dna_misc.dm b/code/game/dna/dna_misc.dm index 1362aa68882..cdc737c0076 100644 --- a/code/game/dna/dna_misc.dm +++ b/code/game/dna/dna_misc.dm @@ -235,9 +235,9 @@ H.r_eyes = hex2num(getblock(structure,8,3)) H.g_eyes = hex2num(getblock(structure,9,3)) H.b_eyes = hex2num(getblock(structure,10,3)) + if(H.internal_organs_by_name["eyes"]) - var/obj/item/organ/eyes/eyes = H.internal_organs_by_name["eyes"] - eyes.eye_colour = list(H.r_eyes,H.g_eyes,H.b_eyes) + H.update_eyes() if (isblockon(getblock(structure, 11,3),11 , 1)) H.gender = FEMALE @@ -420,7 +420,7 @@ animation.master = src flick("h2monkey", animation) sleep(48) - del(animation) + qdel(animation) var/mob/living/carbon/monkey/O = null @@ -447,7 +447,7 @@ for(var/obj/T in (M.contents-implants)) - del(T) + qdel(T) O.loc = M.loc @@ -469,7 +469,7 @@ I.loc = O I.implanted = O // O.update_icon = 1 //queue a full icon update at next life() call - del(M) + qdel(M) return if (!isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && !istype(M, /mob/living/carbon/human)) @@ -493,7 +493,7 @@ animation.master = src flick("monkey2h", animation) sleep(48) - del(animation) + qdel(animation) var/mob/living/carbon/human/O = new( src ) if(Mo.greaterform) @@ -519,7 +519,7 @@ M.viruses -= D //for(var/obj/T in M) - // del(T) + // qdel(T) O.loc = M.loc @@ -553,7 +553,7 @@ I.loc = O I.implanted = O // O.update_icon = 1 //queue a full icon update at next life() call - del(M) + qdel(M) return //////////////////////////////////////////////////////////// Monkey Block if(M) diff --git a/code/game/dna/dna_misc.dm.orig b/code/game/dna/dna_misc.dm.orig deleted file mode 100644 index 00810f50e16..00000000000 --- a/code/game/dna/dna_misc.dm.orig +++ /dev/null @@ -1,1123 +0,0 @@ -<<<<<<< HEAD -/////////////////////////// DNA HELPER-PROCS -/proc/getleftblocks(input,blocknumber,blocksize) - var/string - - if (blocknumber > 1) - string = copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) - return string - else - return null - -/proc/getrightblocks(input,blocknumber,blocksize) - var/string - if (blocknumber < (length(input)/blocksize)) - string = copytext(input,blocksize*blocknumber+1,length(input)+1) - return string - else - return null - -/proc/getblockstring(input,block,subblock,blocksize,src,ui) // src is probably used here just for urls; ui is 1 when requesting for the unique identifier screen, 0 for structural enzymes screen - var/string - var/subpos = 1 // keeps track of the current sub block - var/blockpos = 1 // keeps track of the current block - - - for(var/i = 1, i <= length(input), i++) // loop through each letter - - var/pushstring - - if(subpos == subblock && blockpos == block) // if the current block/subblock is selected, mark it - pushstring = "[copytext(input, i, i+1)]" - else - if(ui) //This is for allowing block clicks to be differentiated - pushstring = "[copytext(input, i, i+1)]" - else - pushstring = "[copytext(input, i, i+1)]" - - string += pushstring // push the string to the return string - - if(subpos >= blocksize) // add a line break for every block - string += " | " - subpos = 0 - blockpos++ - - subpos++ - - return string - - -/proc/getblock(input,blocknumber,blocksize) - var/result - result = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) - return result - -/proc/getblockbuffer(input,blocknumber,blocksize) - var/result[3] - var/block = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) - for(var/i = 1, i <= 3, i++) - result[i] = copytext(block, i, i+1) - return result - -/proc/setblock(istring, blocknumber, replacement, blocksize) - if(!blocknumber) - return istring - if(!istring || !replacement || !blocksize) return 0 - var/result = getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) - return result - -/proc/add_zero2(t, u) - var/temp1 - while (length(t) < u) - t = "0[t]" - temp1 = t - if (length(t) > u) - temp1 = copytext(t,2,u+1) - return temp1 - -/proc/miniscramble(input,rs,rd) - var/output - output = null - if (input == "C" || input == "D" || input == "E" || input == "F") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"6",prob((rs*10));"7",prob((rs*5)+(rd));"0",prob((rs*5)+(rd));"1",prob((rs*10)-(rd));"2",prob((rs*10)-(rd));"3") - if (input == "8" || input == "9" || input == "A" || input == "B") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") - if (input == "4" || input == "5" || input == "6" || input == "7") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") - if (input == "0" || input == "1" || input == "2" || input == "3") - output = pick(prob((rs*10));"8",prob((rs*10));"9",prob((rs*10));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C",prob((rs*10)-(rd));"D",prob((rs*5)+(rd));"E",prob((rs*5)+(rd));"F") - if (!output) output = "5" - return output - -//Instead of picking a value far from the input, this will pick values closer to it. -//Sorry for the block of code, but it's more efficient then calling text2hex -> loop -> hex2text -/proc/miniscrambletarget(input,rs,rd) - var/output = null - switch(input) - if("0") - output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10));"2",prob((rs*10)-(rd));"3") - if("1") - output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10));"3",prob((rs*10)-(rd));"4") - if("2") - output = pick(prob((rs*10));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10));"4",prob((rs*10)-(rd));"5") - if("3") - output = pick(prob((rs*10)-(rd));"0",prob((rs*10));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10));"5",prob((rs*10)-(rd));"6") - if("4") - output = pick(prob((rs*10)-(rd));"1",prob((rs*10));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10));"6",prob((rs*10)-(rd));"7") - if("5") - output = pick(prob((rs*10)-(rd));"2",prob((rs*10));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10));"7",prob((rs*10)-(rd));"8") - if("6") - output = pick(prob((rs*10)-(rd));"3",prob((rs*10));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10));"8",prob((rs*10)-(rd));"9") - if("7") - output = pick(prob((rs*10)-(rd));"4",prob((rs*10));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10));"9",prob((rs*10)-(rd));"A") - if("8") - output = pick(prob((rs*10)-(rd));"5",prob((rs*10));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10));"A",prob((rs*10)-(rd));"B") - if("9") - output = pick(prob((rs*10)-(rd));"6",prob((rs*10));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C") - if("10")//A - output = pick(prob((rs*10)-(rd));"7",prob((rs*10));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10));"C",prob((rs*10)-(rd));"D") - if("11")//B - output = pick(prob((rs*10)-(rd));"8",prob((rs*10));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10));"D",prob((rs*10)-(rd));"E") - if("12")//C - output = pick(prob((rs*10)-(rd));"9",prob((rs*10));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10));"E",prob((rs*10)-(rd));"F") - if("13")//D - output = pick(prob((rs*10)-(rd));"A",prob((rs*10));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10));"F") - if("14")//E - output = pick(prob((rs*10)-(rd));"B",prob((rs*10));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") - if("15")//F - output = pick(prob((rs*10)-(rd));"C",prob((rs*10));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") - - if(!input || !output) //How did this happen? - output = "8" - - return output - -/proc/isblockon(hnumber, bnumber , var/UI = 0) - - var/temp2 - temp2 = hex2num(hnumber) - - if(UI) - if(temp2 >= 2050) - return 1 - else - return 0 - - if (bnumber == HULKBLOCK || bnumber == TELEBLOCK || bnumber == NOBREATHBLOCK || bnumber == NOPRINTSBLOCK || bnumber == SMALLSIZEBLOCK || bnumber == SHOCKIMMUNITYBLOCK) - if (temp2 >= 3500 + BLOCKADD) - return 1 - else - return 0 - if (bnumber == XRAYBLOCK || bnumber == FIREBLOCK || bnumber == REMOTEVIEWBLOCK || bnumber == REGENERATEBLOCK || bnumber == INCREASERUNBLOCK || bnumber == REMOTETALKBLOCK || bnumber == MORPHBLOCK) - if (temp2 >= 3050 + BLOCKADD) - return 1 - else - return 0 - - - if (temp2 >= 2050 + BLOCKADD) - return 1 - else - return 0 - -/proc/ismuton(var/block,var/mob/M) - return isblockon(getblock(M.dna.struc_enzymes, block,3),block) - -/proc/randmutb(mob/M as mob) - if(!M) return - var/num - var/newdna - num = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) - M.dna.check_integrity() - newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) - M.dna.struc_enzymes = newdna - return - -/proc/randmutg(mob/M as mob) - if(!M) return - var/num - var/newdna - num = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) - M.dna.check_integrity() - newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) - M.dna.struc_enzymes = newdna - return - -/proc/scramble(var/type, mob/M as mob, var/p) - if(!M) return - M.dna.check_integrity() - if(type) - for(var/i = 1, i <= STRUCDNASIZE-1, i++) - if(prob(p)) - M.dna.uni_identity = setblock(M.dna.uni_identity, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) - updateappearance(M, M.dna.uni_identity) - - else - for(var/i = 1, i <= STRUCDNASIZE-1, i++) - if(prob(p)) - M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) - domutcheck(M, null) - return - -/proc/randmuti(mob/M as mob) - if(!M) return - var/num - var/newdna - num = rand(1,UNIDNASIZE) - M.dna.check_integrity() - newdna = setblock(M.dna.uni_identity,num,add_zero2(num2hex(rand(1,4095),1),3),3) - M.dna.uni_identity = newdna - return - -/proc/toggledblock(hnumber) //unused - var/temp3 - var/chtemp - temp3 = hex2num(hnumber) - if (temp3 < 2050) - chtemp = rand(2050,4095) - return add_zero2(num2hex(chtemp,1),3) - else - chtemp = rand(1,2049) - return add_zero2(num2hex(chtemp,1),3) -/////////////////////////// DNA HELPER-PROCS - -/////////////////////////// DNA MISC-PROCS -/proc/updateappearance(mob/M as mob , structure) - if(istype(M, /mob/living/carbon/human)) - M.dna.check_integrity() - var/mob/living/carbon/human/H = M - H.r_hair = hex2num(getblock(structure,1,3)) - H.b_hair = hex2num(getblock(structure,2,3)) - H.g_hair = hex2num(getblock(structure,3,3)) - H.r_facial = hex2num(getblock(structure,4,3)) - H.b_facial = hex2num(getblock(structure,5,3)) - H.g_facial = hex2num(getblock(structure,6,3)) - H.s_tone = round(((hex2num(getblock(structure,7,3)) / 16) - 220)) - H.r_eyes = hex2num(getblock(structure,8,3)) - H.g_eyes = hex2num(getblock(structure,9,3)) - H.b_eyes = hex2num(getblock(structure,10,3)) - - if (isblockon(getblock(structure, 11,3),11 , 1)) - H.gender = FEMALE - else - H.gender = MALE - - //Hair - var/hairnum = hex2num(getblock(structure,13,3)) - var/index = round(1 +(hairnum / 4096)*hair_styles_list.len) - if((0 < index) && (index <= hair_styles_list.len)) - H.h_style = hair_styles_list[index] - - //Facial Hair - var/beardnum = hex2num(getblock(structure,12,3)) - index = round(1 +(beardnum / 4096)*facial_hair_styles_list.len) - if((0 < index) && (index <= facial_hair_styles_list.len)) - H.f_style = facial_hair_styles_list[index] - - H.update_body(0) - H.update_hair() - - return 1 - else - return 0 - -/proc/probinj(var/pr, var/inj) - return prob(pr+inj*pr) - -/proc/domutcheck(mob/living/M as mob, connected, inj) - if (!M) return - - M.dna.check_integrity() - - M.disabilities = 0 - M.sdisabilities = 0 - var/old_mutations = M.mutations - M.mutations = list() - -// M.see_in_dark = 2 -// M.see_invisible = 0 - - if(PLANT in old_mutations) - M.mutations.Add(PLANT) - if(SKELETON in old_mutations) - M.mutations.Add(SKELETON) - if(FAT in old_mutations) - M.mutations.Add(FAT) - if(HUSK in old_mutations) - M.mutations.Add(HUSK) - - if(ismuton(NOBREATHBLOCK,M)) - if(probinj(45,inj) || (mNobreath in old_mutations)) - M << "\blue You feel no need to breathe." - M.mutations.Add(mNobreath) - if(ismuton(REMOTEVIEWBLOCK,M)) - if(probinj(45,inj) || (mRemote in old_mutations)) - M << "\blue Your mind expands" - M.mutations.Add(mRemote) - if(ismuton(REGENERATEBLOCK,M)) - if(probinj(45,inj) || (mRegen in old_mutations)) - M << "\blue You feel strange" - M.mutations.Add(mRegen) - if(ismuton(INCREASERUNBLOCK,M)) - if(probinj(45,inj) || (mRun in old_mutations)) - M << "\blue You feel quick" - M.mutations.Add(mRun) - if(ismuton(REMOTETALKBLOCK,M)) - if(probinj(45,inj) || (mRemotetalk in old_mutations)) - M << "\blue You expand your mind outwards" - M.mutations.Add(mRemotetalk) - if(ismuton(MORPHBLOCK,M)) - if(probinj(45,inj) || (mMorph in old_mutations)) - M.mutations.Add(mMorph) - M << "\blue Your skin feels strange" - if(ismuton(BLENDBLOCK,M)) - if(probinj(45,inj) || (mBlend in old_mutations)) - M.mutations.Add(mBlend) - M << "\blue You feel alone" - if(ismuton(HALLUCINATIONBLOCK,M)) - if(probinj(45,inj) || (mHallucination in old_mutations)) - M.mutations.Add(mHallucination) - M << "\blue Your mind says 'Hello'" - if(ismuton(NOPRINTSBLOCK,M)) - if(probinj(45,inj) || (mFingerprints in old_mutations)) - M.mutations.Add(mFingerprints) - M << "\blue Your fingers feel numb" - if(ismuton(SHOCKIMMUNITYBLOCK,M)) - if(probinj(45,inj) || (mShock in old_mutations)) - M.mutations.Add(mShock) - M << "\blue You feel strange" - if(ismuton(SMALLSIZEBLOCK,M)) - if(probinj(45,inj) || (mSmallsize in old_mutations)) - M << "\blue Your skin feels rubbery" - M.mutations.Add(mSmallsize) - - - - if (isblockon(getblock(M.dna.struc_enzymes, HULKBLOCK,3),HULKBLOCK)) - if(probinj(5,inj) || (HULK in old_mutations)) - M << "\blue Your muscles hurt." - M.mutations.Add(HULK) - if (isblockon(getblock(M.dna.struc_enzymes, HEADACHEBLOCK,3),HEADACHEBLOCK)) - M.disabilities |= EPILEPSY - M << "\red You get a headache." - if (isblockon(getblock(M.dna.struc_enzymes, FAKEBLOCK,3),FAKEBLOCK)) - M << "\red You feel strange." - if (prob(95)) - if(prob(50)) - randmutb(M) - else - randmuti(M) - else - randmutg(M) - if (isblockon(getblock(M.dna.struc_enzymes, COUGHBLOCK,3),COUGHBLOCK)) - M.disabilities |= COUGHING - M << "\red You start coughing." - if (isblockon(getblock(M.dna.struc_enzymes, CLUMSYBLOCK,3),CLUMSYBLOCK)) - M << "\red You feel lightheaded." - M.mutations.Add(CLUMSY) - if (isblockon(getblock(M.dna.struc_enzymes, TWITCHBLOCK,3),TWITCHBLOCK)) - M.disabilities |= TOURETTES - M << "\red You twitch." - if (isblockon(getblock(M.dna.struc_enzymes, XRAYBLOCK,3),XRAYBLOCK)) - if(probinj(30,inj) || (XRAY in old_mutations)) - M << "\blue The walls suddenly disappear." -// M.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) -// M.see_in_dark = 8 -// M.see_invisible = 2 - M.mutations.Add(XRAY) - if (isblockon(getblock(M.dna.struc_enzymes, NERVOUSBLOCK,3),NERVOUSBLOCK)) - M.disabilities |= NERVOUS - M << "\red You feel nervous." - if (isblockon(getblock(M.dna.struc_enzymes, FIREBLOCK,3),FIREBLOCK)) - if(probinj(30,inj) || (COLD_RESISTANCE in old_mutations)) - M << "\blue Your body feels warm." - M.mutations.Add(COLD_RESISTANCE) - if (isblockon(getblock(M.dna.struc_enzymes, BLINDBLOCK,3),BLINDBLOCK)) - M.sdisabilities |= BLIND - M << "\red You can't seem to see anything." - if (isblockon(getblock(M.dna.struc_enzymes, TELEBLOCK,3),TELEBLOCK)) - if(probinj(15,inj) || (TK in old_mutations)) - M << "\blue You feel smarter." - M.mutations.Add(TK) - if (isblockon(getblock(M.dna.struc_enzymes, DEAFBLOCK,3),DEAFBLOCK)) - M.sdisabilities |= DEAF - M.ear_deaf = 1 - M << "\red Its kinda quiet.." - if (isblockon(getblock(M.dna.struc_enzymes, GLASSESBLOCK,3),GLASSESBLOCK)) - M.disabilities |= NEARSIGHTED - M << "Your eyes feel weird..." - - /* If you want the new mutations to work, UNCOMMENT THIS. - if(istype(M, /mob/living/carbon)) - for (var/datum/mutations/mut in global_mutations) - mut.check_mutation(M) - */ - -//////////////////////////////////////////////////////////// Monkey Block - if (isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && istype(M, /mob/living/carbon/human)) - // human > monkey - var/mob/living/carbon/human/H = M - H.monkeyizing = 1 - var/list/implants = list() //Try to preserve implants. - for(var/obj/item/weapon/implant/W in H) - implants += W - W.loc = null - - if(!connected) - for(var/obj/item/W in (H.contents-implants)) - if (W==H.w_uniform) // will be teared - continue - H.drop_from_inventory(W) - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.invisibility = 101 - var/atom/movable/overlay/animation = new( M.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("h2monkey", animation) - sleep(48) - del(animation) - - - var/mob/living/carbon/monkey/O = null - if(H.species.primitive) - O = new H.species.primitive(src) - else - H.gib() //Trying to change the species of a creature with no primitive var set is messy. - return - - if(M) - if (M.dna) - O.dna = M.dna - M.dna = null - - if (M.suiciding) - O.suiciding = M.suiciding - M.suiciding = null - - - for(var/datum/disease/D in M.viruses) - O.viruses += D - D.affected_mob = O - M.viruses -= D - - - for(var/obj/T in (M.contents-implants)) - del(T) - - O.loc = M.loc - - if(M.mind) - M.mind.transfer_to(O) //transfer our mind to the cute little monkey - - if (connected) //inside dna thing - var/obj/machinery/dna_scannernew/C = connected - O.loc = C - C.occupant = O - connected = null - O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6)) - O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss()) - O.adjustToxLoss(M.getToxLoss() + 20) - O.adjustOxyLoss(M.getOxyLoss()) - O.stat = M.stat - O.a_intent = I_HURT - for (var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O -// O.update_icon = 1 //queue a full icon update at next life() call - del(M) - return - - if (!isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && !istype(M, /mob/living/carbon/human)) - // monkey > human, - var/mob/living/carbon/monkey/Mo = M - Mo.monkeyizing = 1 - var/list/implants = list() //Still preserving implants - for(var/obj/item/weapon/implant/W in Mo) - implants += W - W.loc = null - if(!connected) - for(var/obj/item/W in (Mo.contents-implants)) - Mo.drop_from_inventory(W) - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.invisibility = 101 - var/atom/movable/overlay/animation = new( M.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("monkey2h", animation) - sleep(48) - del(animation) - - var/mob/living/carbon/human/O = new( src ) - if(Mo.greaterform) - O.set_species(Mo.greaterform) - - if (isblockon(getblock(M.dna.uni_identity, 11,3),11)) - O.gender = FEMALE - else - O.gender = MALE - - if (M) - if (M.dna) - O.dna = M.dna - M.dna = null - - if (M.suiciding) - O.suiciding = M.suiciding - M.suiciding = null - - for(var/datum/disease/D in M.viruses) - O.viruses += D - D.affected_mob = O - M.viruses -= D - - //for(var/obj/T in M) - // del(T) - - O.loc = M.loc - - if(M.mind) - M.mind.transfer_to(O) //transfer our mind to the human - - if (connected) //inside dna thing - var/obj/machinery/dna_scannernew/C = connected - O.loc = C - C.occupant = O - connected = null - - var/i - while (!i) - var/randomname - if (O.gender == MALE) - randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names))) - else - randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names))) - if (findname(randomname)) - continue - else - O.real_name = randomname - i++ - updateappearance(O,O.dna.uni_identity) - O.take_overall_damage(M.getBruteLoss(), M.getFireLoss()) - O.adjustToxLoss(M.getToxLoss()) - O.adjustOxyLoss(M.getOxyLoss()) - O.stat = M.stat - for (var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O -// O.update_icon = 1 //queue a full icon update at next life() call - del(M) - return -//////////////////////////////////////////////////////////// Monkey Block - if(M) - M.update_icon = 1 //queue a full icon update at next life() call - return null -======= -/////////////////////////// DNA HELPER-PROCS -/proc/getleftblocks(input,blocknumber,blocksize) - var/string - - if (blocknumber > 1) - string = copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) - return string - else - return null - -/proc/getrightblocks(input,blocknumber,blocksize) - var/string - if (blocknumber < (length(input)/blocksize)) - string = copytext(input,blocksize*blocknumber+1,length(input)+1) - return string - else - return null - -/proc/getblockstring(input,block,subblock,blocksize,src,ui) // src is probably used here just for urls; ui is 1 when requesting for the unique identifier screen, 0 for structural enzymes screen - var/string - var/subpos = 1 // keeps track of the current sub block - var/blockpos = 1 // keeps track of the current block - - - for(var/i = 1, i <= length(input), i++) // loop through each letter - - var/pushstring - - if(subpos == subblock && blockpos == block) // if the current block/subblock is selected, mark it - pushstring = "[copytext(input, i, i+1)]" - else - if(ui) //This is for allowing block clicks to be differentiated - pushstring = "[copytext(input, i, i+1)]" - else - pushstring = "[copytext(input, i, i+1)]" - - string += pushstring // push the string to the return string - - if(subpos >= blocksize) // add a line break for every block - string += " | " - subpos = 0 - blockpos++ - - subpos++ - - return string - - -/proc/getblock(input,blocknumber,blocksize) - var/result - result = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) - return result - -/proc/getblockbuffer(input,blocknumber,blocksize) - var/result[3] - var/block = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) - for(var/i = 1, i <= 3, i++) - result[i] = copytext(block, i, i+1) - return result - -/proc/setblock(istring, blocknumber, replacement, blocksize) - if(!blocknumber) - return istring - if(!istring || !replacement || !blocksize) return 0 - var/result = getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) - return result - -/proc/add_zero2(t, u) - var/temp1 - while (length(t) < u) - t = "0[t]" - temp1 = t - if (length(t) > u) - temp1 = copytext(t,2,u+1) - return temp1 - -/proc/miniscramble(input,rs,rd) - var/output - output = null - if (input == "C" || input == "D" || input == "E" || input == "F") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"6",prob((rs*10));"7",prob((rs*5)+(rd));"0",prob((rs*5)+(rd));"1",prob((rs*10)-(rd));"2",prob((rs*10)-(rd));"3") - if (input == "8" || input == "9" || input == "A" || input == "B") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") - if (input == "4" || input == "5" || input == "6" || input == "7") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") - if (input == "0" || input == "1" || input == "2" || input == "3") - output = pick(prob((rs*10));"8",prob((rs*10));"9",prob((rs*10));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C",prob((rs*10)-(rd));"D",prob((rs*5)+(rd));"E",prob((rs*5)+(rd));"F") - if (!output) output = "5" - return output - -//Instead of picking a value far from the input, this will pick values closer to it. -//Sorry for the block of code, but it's more efficient then calling text2hex -> loop -> hex2text -/proc/miniscrambletarget(input,rs,rd) - var/output = null - switch(input) - if("0") - output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10));"2",prob((rs*10)-(rd));"3") - if("1") - output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10));"3",prob((rs*10)-(rd));"4") - if("2") - output = pick(prob((rs*10));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10));"4",prob((rs*10)-(rd));"5") - if("3") - output = pick(prob((rs*10)-(rd));"0",prob((rs*10));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10));"5",prob((rs*10)-(rd));"6") - if("4") - output = pick(prob((rs*10)-(rd));"1",prob((rs*10));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10));"6",prob((rs*10)-(rd));"7") - if("5") - output = pick(prob((rs*10)-(rd));"2",prob((rs*10));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10));"7",prob((rs*10)-(rd));"8") - if("6") - output = pick(prob((rs*10)-(rd));"3",prob((rs*10));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10));"8",prob((rs*10)-(rd));"9") - if("7") - output = pick(prob((rs*10)-(rd));"4",prob((rs*10));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10));"9",prob((rs*10)-(rd));"A") - if("8") - output = pick(prob((rs*10)-(rd));"5",prob((rs*10));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10));"A",prob((rs*10)-(rd));"B") - if("9") - output = pick(prob((rs*10)-(rd));"6",prob((rs*10));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C") - if("10")//A - output = pick(prob((rs*10)-(rd));"7",prob((rs*10));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10));"C",prob((rs*10)-(rd));"D") - if("11")//B - output = pick(prob((rs*10)-(rd));"8",prob((rs*10));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10));"D",prob((rs*10)-(rd));"E") - if("12")//C - output = pick(prob((rs*10)-(rd));"9",prob((rs*10));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10));"E",prob((rs*10)-(rd));"F") - if("13")//D - output = pick(prob((rs*10)-(rd));"A",prob((rs*10));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10));"F") - if("14")//E - output = pick(prob((rs*10)-(rd));"B",prob((rs*10));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") - if("15")//F - output = pick(prob((rs*10)-(rd));"C",prob((rs*10));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") - - if(!input || !output) //How did this happen? - output = "8" - - return output - -/proc/isblockon(hnumber, bnumber , var/UI = 0) - - var/temp2 - temp2 = hex2num(hnumber) - - if(UI) - if(temp2 >= 2050) - return 1 - else - return 0 - - if (bnumber == HULKBLOCK || bnumber == TELEBLOCK || bnumber == NOBREATHBLOCK || bnumber == NOPRINTSBLOCK || bnumber == SMALLSIZEBLOCK || bnumber == SHOCKIMMUNITYBLOCK) - if (temp2 >= 3500 + BLOCKADD) - return 1 - else - return 0 - if (bnumber == XRAYBLOCK || bnumber == FIREBLOCK || bnumber == REMOTEVIEWBLOCK || bnumber == REGENERATEBLOCK || bnumber == INCREASERUNBLOCK || bnumber == REMOTETALKBLOCK || bnumber == MORPHBLOCK) - if (temp2 >= 3050 + BLOCKADD) - return 1 - else - return 0 - - - if (temp2 >= 2050 + BLOCKADD) - return 1 - else - return 0 - -/proc/ismuton(var/block,var/mob/M) - return isblockon(getblock(M.dna.struc_enzymes, block,3),block) - -/proc/randmutb(mob/M as mob) - if(!M) return - var/num - var/newdna - num = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) - M.dna.check_integrity() - newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) - M.dna.struc_enzymes = newdna - return - -/proc/randmutg(mob/M as mob) - if(!M) return - var/num - var/newdna - num = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) - M.dna.check_integrity() - newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) - M.dna.struc_enzymes = newdna - return - -/proc/scramble(var/type, mob/M as mob, var/p) - if(!M) return - M.dna.check_integrity() - if(type) - for(var/i = 1, i <= STRUCDNASIZE-1, i++) - if(prob(p)) - M.dna.uni_identity = setblock(M.dna.uni_identity, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) - updateappearance(M, M.dna.uni_identity) - - else - for(var/i = 1, i <= STRUCDNASIZE-1, i++) - if(prob(p)) - M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) - domutcheck(M, null) - return - -/proc/randmuti(mob/M as mob) - if(!M) return - var/num - var/newdna - num = rand(1,UNIDNASIZE) - M.dna.check_integrity() - newdna = setblock(M.dna.uni_identity,num,add_zero2(num2hex(rand(1,4095),1),3),3) - M.dna.uni_identity = newdna - return - -/proc/toggledblock(hnumber) //unused - var/temp3 - var/chtemp - temp3 = hex2num(hnumber) - if (temp3 < 2050) - chtemp = rand(2050,4095) - return add_zero2(num2hex(chtemp,1),3) - else - chtemp = rand(1,2049) - return add_zero2(num2hex(chtemp,1),3) -/////////////////////////// DNA HELPER-PROCS - -/////////////////////////// DNA MISC-PROCS -/proc/updateappearance(mob/M as mob , structure) - if(istype(M, /mob/living/carbon/human)) - M.dna.check_integrity() - var/mob/living/carbon/human/H = M - H.r_hair = hex2num(getblock(structure,1,3)) - H.b_hair = hex2num(getblock(structure,2,3)) - H.g_hair = hex2num(getblock(structure,3,3)) - H.r_facial = hex2num(getblock(structure,4,3)) - H.b_facial = hex2num(getblock(structure,5,3)) - H.g_facial = hex2num(getblock(structure,6,3)) - H.s_tone = round(((hex2num(getblock(structure,7,3)) / 16) - 220)) - H.r_eyes = hex2num(getblock(structure,8,3)) - H.g_eyes = hex2num(getblock(structure,9,3)) - H.b_eyes = hex2num(getblock(structure,10,3)) - if(H.internal_organs_by_name["eyes"]) - var/obj/item/organ/eyes/eyes = H.internal_organs_by_name["eyes"] - eyes.eye_colour = list(H.r_eyes,H.g_eyes,H.b_eyes) - - if (isblockon(getblock(structure, 11,3),11 , 1)) - H.gender = FEMALE - else - H.gender = MALE - - //Hair - var/hairnum = hex2num(getblock(structure,13,3)) - var/index = round(1 +(hairnum / 4096)*hair_styles_list.len) - if((0 < index) && (index <= hair_styles_list.len)) - H.h_style = hair_styles_list[index] - - //Facial Hair - var/beardnum = hex2num(getblock(structure,12,3)) - index = round(1 +(beardnum / 4096)*facial_hair_styles_list.len) - if((0 < index) && (index <= facial_hair_styles_list.len)) - H.f_style = facial_hair_styles_list[index] - - H.update_body(0) - H.update_hair() - - return 1 - else - return 0 - -/proc/probinj(var/pr, var/inj) - return prob(pr+inj*pr) - -/proc/domutcheck(mob/living/M as mob, connected, inj) - if (!M) return - - M.dna.check_integrity() - - M.disabilities = 0 - M.sdisabilities = 0 - var/old_mutations = M.mutations - M.mutations = list() - -// M.see_in_dark = 2 -// M.see_invisible = 0 - - if(PLANT in old_mutations) - M.mutations.Add(PLANT) - if(SKELETON in old_mutations) - M.mutations.Add(SKELETON) - if(FAT in old_mutations) - M.mutations.Add(FAT) - if(HUSK in old_mutations) - M.mutations.Add(HUSK) - - if(ismuton(NOBREATHBLOCK,M)) - if(probinj(45,inj) || (mNobreath in old_mutations)) - M << "\blue You feel no need to breathe." - M.mutations.Add(mNobreath) - if(ismuton(REMOTEVIEWBLOCK,M)) - if(probinj(45,inj) || (mRemote in old_mutations)) - M << "\blue Your mind expands" - M.mutations.Add(mRemote) - if(ismuton(REGENERATEBLOCK,M)) - if(probinj(45,inj) || (mRegen in old_mutations)) - M << "\blue You feel strange" - M.mutations.Add(mRegen) - if(ismuton(INCREASERUNBLOCK,M)) - if(probinj(45,inj) || (mRun in old_mutations)) - M << "\blue You feel quick" - M.mutations.Add(mRun) - if(ismuton(REMOTETALKBLOCK,M)) - if(probinj(45,inj) || (mRemotetalk in old_mutations)) - M << "\blue You expand your mind outwards" - M.mutations.Add(mRemotetalk) - if(ismuton(MORPHBLOCK,M)) - if(probinj(45,inj) || (mMorph in old_mutations)) - M.mutations.Add(mMorph) - M << "\blue Your skin feels strange" - if(ismuton(BLENDBLOCK,M)) - if(probinj(45,inj) || (mBlend in old_mutations)) - M.mutations.Add(mBlend) - M << "\blue You feel alone" - if(ismuton(HALLUCINATIONBLOCK,M)) - if(probinj(45,inj) || (mHallucination in old_mutations)) - M.mutations.Add(mHallucination) - M << "\blue Your mind says 'Hello'" - if(ismuton(NOPRINTSBLOCK,M)) - if(probinj(45,inj) || (mFingerprints in old_mutations)) - M.mutations.Add(mFingerprints) - M << "\blue Your fingers feel numb" - if(ismuton(SHOCKIMMUNITYBLOCK,M)) - if(probinj(45,inj) || (mShock in old_mutations)) - M.mutations.Add(mShock) - M << "\blue You feel strange" - if(ismuton(SMALLSIZEBLOCK,M)) - if(probinj(45,inj) || (mSmallsize in old_mutations)) - M << "\blue Your skin feels rubbery" - M.mutations.Add(mSmallsize) - - - - if (isblockon(getblock(M.dna.struc_enzymes, HULKBLOCK,3),HULKBLOCK)) - if(probinj(5,inj) || (HULK in old_mutations)) - M << "\blue Your muscles hurt." - M.mutations.Add(HULK) - if (isblockon(getblock(M.dna.struc_enzymes, HEADACHEBLOCK,3),HEADACHEBLOCK)) - M.disabilities |= EPILEPSY - M << "\red You get a headache." - if (isblockon(getblock(M.dna.struc_enzymes, FAKEBLOCK,3),FAKEBLOCK)) - M << "\red You feel strange." - if (prob(95)) - if(prob(50)) - randmutb(M) - else - randmuti(M) - else - randmutg(M) - if (isblockon(getblock(M.dna.struc_enzymes, COUGHBLOCK,3),COUGHBLOCK)) - M.disabilities |= COUGHING - M << "\red You start coughing." - if (isblockon(getblock(M.dna.struc_enzymes, CLUMSYBLOCK,3),CLUMSYBLOCK)) - M << "\red You feel lightheaded." - M.mutations.Add(CLUMSY) - if (isblockon(getblock(M.dna.struc_enzymes, TWITCHBLOCK,3),TWITCHBLOCK)) - M.disabilities |= TOURETTES - M << "\red You twitch." - if (isblockon(getblock(M.dna.struc_enzymes, XRAYBLOCK,3),XRAYBLOCK)) - if(probinj(30,inj) || (XRAY in old_mutations)) - M << "\blue The walls suddenly disappear." -// M.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) -// M.see_in_dark = 8 -// M.see_invisible = 2 - M.mutations.Add(XRAY) - if (isblockon(getblock(M.dna.struc_enzymes, NERVOUSBLOCK,3),NERVOUSBLOCK)) - M.disabilities |= NERVOUS - M << "\red You feel nervous." - if (isblockon(getblock(M.dna.struc_enzymes, FIREBLOCK,3),FIREBLOCK)) - if(probinj(30,inj) || (COLD_RESISTANCE in old_mutations)) - M << "\blue Your body feels warm." - M.mutations.Add(COLD_RESISTANCE) - if (isblockon(getblock(M.dna.struc_enzymes, BLINDBLOCK,3),BLINDBLOCK)) - M.sdisabilities |= BLIND - M << "\red You can't seem to see anything." - if (isblockon(getblock(M.dna.struc_enzymes, TELEBLOCK,3),TELEBLOCK)) - if(probinj(15,inj) || (TK in old_mutations)) - M << "\blue You feel smarter." - M.mutations.Add(TK) - if (isblockon(getblock(M.dna.struc_enzymes, DEAFBLOCK,3),DEAFBLOCK)) - M.sdisabilities |= DEAF - M.ear_deaf = 1 - M << "\red Its kinda quiet.." - if (isblockon(getblock(M.dna.struc_enzymes, GLASSESBLOCK,3),GLASSESBLOCK)) - M.disabilities |= NEARSIGHTED - M << "Your eyes feel weird..." - - /* If you want the new mutations to work, UNCOMMENT THIS. - if(istype(M, /mob/living/carbon)) - for (var/datum/mutations/mut in global_mutations) - mut.check_mutation(M) - */ - -//////////////////////////////////////////////////////////// Monkey Block - if (isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && istype(M, /mob/living/carbon/human)) - // human > monkey - var/mob/living/carbon/human/H = M - H.monkeyizing = 1 - var/list/implants = list() //Try to preserve implants. - for(var/obj/item/weapon/implant/W in H) - implants += W - W.loc = null - - if(!connected) - for(var/obj/item/W in (H.contents-implants)) - if (W==H.w_uniform) // will be teared - continue - H.drop_from_inventory(W) - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.invisibility = 101 - var/atom/movable/overlay/animation = new( M.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("h2monkey", animation) - sleep(48) - del(animation) - - - var/mob/living/carbon/monkey/O = null - if(H.species.primitive) - O = new H.species.primitive(src) - else - H.gib() //Trying to change the species of a creature with no primitive var set is messy. - return - - if(M) - if (M.dna) - O.dna = M.dna - M.dna = null - - if (M.suiciding) - O.suiciding = M.suiciding - M.suiciding = null - - - for(var/datum/disease/D in M.viruses) - O.viruses += D - D.affected_mob = O - M.viruses -= D - - - for(var/obj/T in (M.contents-implants)) - del(T) - - O.loc = M.loc - - if(M.mind) - M.mind.transfer_to(O) //transfer our mind to the cute little monkey - - if (connected) //inside dna thing - var/obj/machinery/dna_scannernew/C = connected - O.loc = C - C.occupant = O - connected = null - O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6)) - O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss()) - O.adjustToxLoss(M.getToxLoss() + 20) - O.adjustOxyLoss(M.getOxyLoss()) - O.stat = M.stat - O.a_intent = "hurt" - for (var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O -// O.update_icon = 1 //queue a full icon update at next life() call - del(M) - return - - if (!isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && !istype(M, /mob/living/carbon/human)) - // monkey > human, - var/mob/living/carbon/monkey/Mo = M - Mo.monkeyizing = 1 - var/list/implants = list() //Still preserving implants - for(var/obj/item/weapon/implant/W in Mo) - implants += W - W.loc = null - if(!connected) - for(var/obj/item/W in (Mo.contents-implants)) - Mo.drop_from_inventory(W) - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.invisibility = 101 - var/atom/movable/overlay/animation = new( M.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("monkey2h", animation) - sleep(48) - del(animation) - - var/mob/living/carbon/human/O = new( src ) - if(Mo.greaterform) - O.set_species(Mo.greaterform) - - if (isblockon(getblock(M.dna.uni_identity, 11,3),11)) - O.gender = FEMALE - else - O.gender = MALE - - if (M) - if (M.dna) - O.dna = M.dna - M.dna = null - - if (M.suiciding) - O.suiciding = M.suiciding - M.suiciding = null - - for(var/datum/disease/D in M.viruses) - O.viruses += D - D.affected_mob = O - M.viruses -= D - - //for(var/obj/T in M) - // del(T) - - O.loc = M.loc - - if(M.mind) - M.mind.transfer_to(O) //transfer our mind to the human - - if (connected) //inside dna thing - var/obj/machinery/dna_scannernew/C = connected - O.loc = C - C.occupant = O - connected = null - - var/i - while (!i) - var/randomname - if (O.gender == MALE) - randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names))) - else - randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names))) - if (findname(randomname)) - continue - else - O.real_name = randomname - i++ - updateappearance(O,O.dna.uni_identity) - O.take_overall_damage(M.getBruteLoss(), M.getFireLoss()) - O.adjustToxLoss(M.getToxLoss()) - O.adjustOxyLoss(M.getOxyLoss()) - O.stat = M.stat - for (var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O -// O.update_icon = 1 //queue a full icon update at next life() call - del(M) - return -//////////////////////////////////////////////////////////// Monkey Block - if(M) - M.update_icon = 1 //queue a full icon update at next life() call - return null ->>>>>>> d77010221cbd08f6373edebee25d727b6409413b -/////////////////////////// DNA MISC-PROCS \ No newline at end of file diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 86bfbeb0fef..deb4426cf56 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -144,7 +144,7 @@ return put_in(G.affecting) src.add_fingerprint(user) - del(G) + qdel(G) return /obj/machinery/dna_scannernew/proc/put_in(var/mob/M) @@ -187,7 +187,7 @@ ex_act(severity) //Foreach goto(35) //SN src = null - del(src) + qdel(src) return if(2.0) if (prob(50)) @@ -196,7 +196,7 @@ ex_act(severity) //Foreach goto(108) //SN src = null - del(src) + qdel(src) return if(3.0) if (prob(25)) @@ -205,7 +205,7 @@ ex_act(severity) //Foreach goto(181) //SN src = null - del(src) + qdel(src) return else return @@ -215,7 +215,7 @@ if(prob(75)) for(var/atom/movable/A as mob|obj in src) A.loc = src.loc - del(src) + qdel(src) /obj/machinery/computer/scan_consolenew name = "DNA Modifier Access Console" @@ -262,12 +262,12 @@ switch(severity) if(1.0) //SN src = null - del(src) + qdel(src) return if(2.0) if (prob(50)) //SN src = null - del(src) + qdel(src) return else return @@ -275,7 +275,7 @@ /obj/machinery/computer/scan_consolenew/blob_act() if(prob(75)) - del(src) + qdel(src) /obj/machinery/computer/scan_consolenew/power_change() ..() @@ -598,8 +598,7 @@ inject_amount = 0 if (inject_amount > 50) inject_amount = 50 - connected.beaker.reagents.trans_to(connected.occupant, inject_amount) - connected.beaker.reagents.reaction(connected.occupant) + connected.beaker.reagents.trans_to_mob(connected.occupant, inject_amount, CHEM_BLOOD) return 1 // return 1 forces an update to all Nano uis attached to src //////////////////////////////////////////////////////// diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm index 2e0f6cdec2f..7d9da106366 100644 --- a/code/game/dna/genes/monkey.dm +++ b/code/game/dna/genes/monkey.dm @@ -33,7 +33,7 @@ animation.master = src flick("h2monkey", animation) sleep(48) - del(animation) + qdel(animation) var/mob/living/carbon/monkey/O = null @@ -60,7 +60,7 @@ for(var/obj/T in (M.contents-implants)) - del(T) + qdel(T) O.loc = M.loc @@ -82,7 +82,7 @@ I.loc = O I.implanted = O // O.update_icon = 1 //queue a full icon update at next life() call - del(M) + qdel(M) return /datum/dna/gene/monkey/deactivate(var/mob/living/M, var/connected, var/flags) @@ -108,7 +108,7 @@ animation.master = src flick("monkey2h", animation) sleep(48) - del(animation) + qdel(animation) var/mob/living/carbon/human/O if(Mo.greaterform) @@ -136,7 +136,7 @@ M.viruses -= D //for(var/obj/T in M) - // del(T) + // qdel(T) O.loc = M.loc @@ -171,5 +171,5 @@ I.loc = O I.implanted = O // O.update_icon = 1 //queue a full icon update at next life() call - del(M) + qdel(M) return diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index f0a24001ba3..3897d444e8e 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -14,7 +14,7 @@ ..(loc, h) - Del() + Destroy() blob_cores -= src processing_objects.Remove(src) ..() @@ -24,7 +24,7 @@ update_icon() if(health <= 0) playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - del(src) + qdel(src) return return diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm index bb8de8184ec..c1d14d00402 100644 --- a/code/game/gamemodes/blob/blobs/factory.dm +++ b/code/game/gamemodes/blob/blobs/factory.dm @@ -12,7 +12,7 @@ update_icon() if(health <= 0) playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - del(src) + qdel(src) return return @@ -22,6 +22,11 @@ new/mob/living/simple_animal/hostile/blobspore(src.loc, src) return 1 +/obj/effect/blob/factory/Destroy() + for(var/mob/living/simple_animal/hostile/blobspore/spore in spores) + if(spore.factory == src) + spore.factory = null + ..() /mob/living/simple_animal/hostile/blobspore name = "blob" @@ -58,9 +63,10 @@ ..(loc) return death() - ..() - if(factory) - factory.spores -= src - ..() - del(src) + qdel(src) +/mob/living/simple_animal/hostile/blobspore/Destroy() + if(factory) + factory.spores -= src + factory = null + ..() diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm index c9ffaf96f13..92572f9a7b0 100644 --- a/code/game/gamemodes/blob/blobs/node.dm +++ b/code/game/gamemodes/blob/blobs/node.dm @@ -14,7 +14,7 @@ ..(loc, h) - Del() + Destroy() blob_nodes -= src processing_objects.Remove(src) ..() @@ -24,7 +24,7 @@ update_icon() if(health <= 0) playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - del(src) + qdel(src) return return diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm index 0e1b6c07eb4..c47696c72e3 100644 --- a/code/game/gamemodes/blob/blobs/shield.dm +++ b/code/game/gamemodes/blob/blobs/shield.dm @@ -14,7 +14,7 @@ update_icon() if(health <= 0) playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - del(src) + qdel(src) return return diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index f6351c84809..44486d605b5 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -3,7 +3,7 @@ name = "blob" icon = 'icons/mob/blob.dmi' icon_state = "blob" - luminosity = 3 + light_range = 3 desc = "Some blob creature thingy" density = 1 opacity = 0 @@ -31,7 +31,7 @@ return - Del() + Destroy() blobs -= src ..() return @@ -110,7 +110,7 @@ B.loc = T else T.blob_act()//If we cant move in hit the turf - del(B) + qdel(B) for(var/atom/A in T)//Hit everything in the turf A.blob_act() return 1 @@ -134,7 +134,7 @@ update_icon()//Needs to be updated with the types if(health <= 0) playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - del(src) + qdel(src) return if(health <= 15) icon_state = "blob_damaged" @@ -158,7 +158,7 @@ attackby(var/obj/item/weapon/W, var/mob/user) playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) - src.visible_message("\red The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]") + src.visible_message("The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]") var/damage = 0 switch(W.damtype) if("fire") @@ -182,7 +182,7 @@ new/obj/effect/blob/factory(src.loc,src.health) if("Shield") new/obj/effect/blob/shield(src.loc,src.health*2) - del(src) + qdel(src) return //////////////////////////////****IDLE BLOB***///////////////////////////////////// @@ -201,7 +201,7 @@ proc/update_idle() if(health<=0) - del(src) + qdel(src) return if(health<4) icon_state = "blobc0" @@ -212,7 +212,7 @@ icon_state = "blobidle0" - Del() + Destroy() var/obj/effect/blob/B = new /obj/effect/blob( src.loc ) spawn(30) B.Life() diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 6f5ca5d8e92..29619503774 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -385,7 +385,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E animation.master = src flick("monkey2h", animation) sleep(48) - del(animation) + qdel(animation) for(var/obj/item/W in src) C.drop_from_inventory(W) @@ -400,7 +400,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E O.real_name = chosen_dna.real_name for(var/obj/T in C) - del(T) + qdel(T) O.loc = C.loc @@ -420,7 +420,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E O.changeling_update_languages(changeling.absorbed_languages) feedback_add_details("changeling_powers","LFT") - del(C) + qdel(C) return 1 @@ -463,7 +463,6 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E // sending display messages C << "We have regenerated." - C.visible_message("[src] appears to wake from the dead, having healed all wounds.") feedback_add_details("changeling_powers","FD") diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 6a17d03a072..a1c0acf0081 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -8,4 +8,4 @@ required_enemies = 3 uplink_welcome = "Nar-Sie Uplink Console:" end_on_antag_death = 1 - antag_tag = MODE_CULTIST \ No newline at end of file + antag_tag = MODE_CULTIST diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index f2f5f96de78..a17c030b111 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -8,6 +8,8 @@ throwforce = 10 attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") +/obj/item/weapon/melee/cultblade/cultify() + return /obj/item/weapon/melee/cultblade/attack(mob/living/target as mob, mob/living/carbon/human/user as mob) if(iscultist(user)) @@ -40,15 +42,22 @@ min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE siemens_coefficient = 0 +/obj/item/clothing/head/culthood/cultify() + return + +/obj/item/clothing/head/culthood/magus + name = "magus helm" + icon_state = "magus" + item_state = "magus" + desc = "A helm worn by the followers of Nar-Sie." + flags_inv = HIDEFACE + flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR + body_parts_covered = HEAD|FACE|EYES /obj/item/clothing/head/culthood/alt icon_state = "cult_hoodalt" item_state = "cult_hoodalt" -/obj/item/clothing/suit/cultrobes/alt - icon_state = "cultrobesalt" - item_state = "cultrobesalt" - /obj/item/clothing/suit/cultrobes name = "cult robes" desc = "A set of armored robes worn by the followers of Nar-Sie" @@ -60,27 +69,20 @@ flags_inv = HIDEJUMPSUIT siemens_coefficient = 0 -/obj/item/clothing/head/magus - name = "magus helm" - icon_state = "magus" - item_state = "magus" - desc = "A helm worn by the followers of Nar-Sie." - flags_inv = HIDEFACE - flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR - body_parts_covered = HEAD|FACE|EYES - armor = list(melee = 30, bullet = 30, laser = 30,energy = 20, bomb = 0, bio = 0, rad = 0) - siemens_coefficient = 0 +/obj/item/clothing/suit/cultrobes/cultify() + return -/obj/item/clothing/suit/magusred +/obj/item/clothing/suit/cultrobes/alt + icon_state = "cultrobesalt" + item_state = "cultrobesalt" + +/obj/item/clothing/suit/cultrobes/magusred name = "magus robes" desc = "A set of armored robes worn by the followers of Nar-Sie" icon_state = "magusred" item_state = "magusred" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - allowed = list(/obj/item/weapon/book/tome,/obj/item/weapon/melee/cultblade) - armor = list(melee = 50, bullet = 30, laser = 50,energy = 20, bomb = 25, bio = 10, rad = 0) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - siemens_coefficient = 0 /obj/item/clothing/head/helmet/space/cult name = "cult helmet" @@ -90,6 +92,8 @@ armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0 +/obj/item/clothing/head/helmet/space/cult/cultify() + return /obj/item/clothing/suit/space/cult name = "cult armour" @@ -101,4 +105,7 @@ slowdown = 1 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0 - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS \ No newline at end of file + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS + +/obj/item/clothing/suit/space/cult/cultify() + return diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index bf2124ebb54..b5854ed9818 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -3,6 +3,9 @@ anchored = 1 icon = 'icons/obj/cult.dmi' +/obj/structure/cult/cultify() + return + /obj/structure/cult/talisman name = "Altar" desc = "A bloodstained altar dedicated to Nar-Sie" @@ -18,14 +21,57 @@ name = "Pylon" desc = "A floating crystal that hums with an unearthly energy" icon_state = "pylon" - luminosity = 5 + var/isbroken = 0 + light_range = 5 + light_color = "#3e0000" + var/obj/item/wepon = null +/obj/structure/cult/pylon/attack_hand(mob/M as mob) + attackpylon(M, 5) + +/obj/structure/cult/pylon/attack_generic(var/mob/user, var/damage) + attackpylon(user, damage) + +/obj/structure/cult/pylon/attackby(obj/item/W as obj, mob/user as mob) + attackpylon(user, W.force) + +/obj/structure/cult/pylon/proc/attackpylon(mob/user as mob, var/damage) + if(!isbroken) + if(prob(1+ damage * 5)) + user << "You hit the pylon, and its crystal breaks apart!" + for(var/mob/M in viewers(src)) + if(M == user) + continue + M.show_message("[user.name] smashed the pylon!", 3, "You hear a tinkle of crystal shards", 2) + playsound(get_turf(src), 'sound/effects/Glassbr3.ogg', 75, 1) + isbroken = 1 + density = 0 + icon_state = "pylon-broken" + set_light(0) + else + user << "You hit the pylon!" + playsound(get_turf(src), 'sound/effects/Glasshit.ogg', 75, 1) + else + if(prob(damage * 2)) + user << "You pulverize what was left of the pylon!" + qdel(src) + else + user << "You hit the pylon!" + playsound(get_turf(src), 'sound/effects/Glasshit.ogg', 75, 1) + + +/obj/structure/cult/pylon/proc/repair(mob/user as mob) + if(isbroken) + user << "You repair the pylon." + isbroken = 0 + density = 1 + icon_state = "pylon" + set_light(5) /obj/structure/cult/tome name = "Desk" desc = "A desk covered in arcane manuscripts and tomes in unknown languages. Looking at the text makes your skin crawl" icon_state = "tomealtar" -// luminosity = 5 //sprites for this no longer exist -Pete //(they were stolen from another game anyway) @@ -45,6 +91,7 @@ density = 1 unacidable = 1 anchored = 1.0 + var/spawnable = null /obj/effect/gateway/Bumped(mob/M as mob|obj) spawn(0) @@ -54,4 +101,74 @@ /obj/effect/gateway/Crossed(AM as mob|obj) spawn(0) return - return \ No newline at end of file + return + +/obj/effect/gateway/active + light_range=5 + light_color="#ff0000" + spawnable=list( + /mob/living/simple_animal/hostile/scarybat, + /mob/living/simple_animal/hostile/creature, + /mob/living/simple_animal/hostile/faithless + ) + +/obj/effect/gateway/active/cult + light_range=5 + light_color="#ff0000" + spawnable=list( + /mob/living/simple_animal/hostile/scarybat/cult, + /mob/living/simple_animal/hostile/creature/cult, + /mob/living/simple_animal/hostile/faithless/cult + ) + +/obj/effect/gateway/active/cult/cultify() + return + +/obj/effect/gateway/active/New() + spawn(rand(30,60) SECONDS) + var/t = pick(spawnable) + new t(src.loc) + qdel(src) + +/obj/effect/gateway/active/Crossed(var/atom/A) + if(!istype(A, /mob/living)) + return + + var/mob/living/M = A + + if(M.stat != DEAD) + if(M.monkeyizing) + return + if(M.has_brain_worms()) + return //Borer stuff - RR + + if(iscultist(M)) return + if(!ishuman(M) && !isrobot(M)) return + + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.overlays.len = 0 + M.invisibility = 101 + + if(istype(M, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/Robot = M + if(Robot.mmi) + qdel(Robot.mmi) + else + for(var/obj/item/W in M) + if(istype(W, /obj/item/weapon/implant)) + qdel(W) + continue + W.layer = initial(W.layer) + W.loc = M.loc + W.dropped(M) + + var/mob/living/new_mob = new /mob/living/simple_animal/corgi(A.loc) + new_mob.a_intent = I_HURT + if(M.mind) + M.mind.transfer_to(new_mob) + else + new_mob.key = M.key + + new_mob << "Your form morphs into that of a corgi." //Because we don't have cluwnes diff --git a/code/game/gamemodes/cult/cultify/mob.dm b/code/game/gamemodes/cult/cultify/mob.dm new file mode 100644 index 00000000000..154078de3d6 --- /dev/null +++ b/code/game/gamemodes/cult/cultify/mob.dm @@ -0,0 +1,63 @@ +/mob + //thou shall always be able to see the Geometer of Blood + var/image/narsimage = null + var/image/narglow = null + +/mob/proc/cultify() + return + +/mob/dead/cultify() + if(icon_state != "ghost-narsie") + icon = 'icons/mob/mob.dmi' + icon_state = "ghost-narsie" + overlays = 0 + invisibility = 0 + src << "Even as a non-corporal being, you can feel Nar-Sie's presence altering you. You are now visible to everyone." + +/mob/living/cultify() + if(iscultist(src) && client) + var/mob/living/simple_animal/construct/harvester/C = new(get_turf(src)) + mind.transfer_to(C) + C << "The Geometer of Blood is overjoyed to be reunited with its followers, and accepts your body in sacrifice. As reward, you have been gifted with the shell of an Harvester.
    Your tendrils can use and draw runes without need for a tome, your eyes can see beings through walls, and your mind can open any door. Use these assets to serve Nar-Sie and bring him any remaining living human in the world.
    You can teleport yourself back to Nar-Sie along with any being under yourself at any time using your \"Harvest\" spell.
    " + dust() + else if(client) + var/mob/dead/G = (ghostize()) + G.icon = 'icons/mob/mob.dmi' + G.icon_state = "ghost-narsie" + G.overlays = 0 + G.invisibility = 0 + G << "You feel relieved as what's left of your soul finally escapes its prison of flesh." + + cult.harvested += G.mind + else + dust() + +/mob/proc/see_narsie(var/obj/singularity/narsie/large/N, var/dir) + if(N.chained) + if(narsimage) + qdel(narsimage) + qdel(narglow) + return + if((N.z == src.z)&&(get_dist(N,src) <= (N.consume_range+10)) && !(N in view(src))) + if(!narsimage) //Create narsimage + narsimage = image('icons/obj/narsie.dmi',src.loc,"narsie",9,1) + narsimage.mouse_opacity = 0 + if(!narglow) //Create narglow + narglow = image('icons/obj/narsie.dmi',narsimage.loc,"glow-narsie",12,1) + narglow.mouse_opacity = 0 + //Else if no dir is given, simply send them the image of narsie + var/new_x = 32 * (N.x - src.x) + N.pixel_x + var/new_y = 32 * (N.y - src.y) + N.pixel_y + narsimage.pixel_x = new_x + narsimage.pixel_y = new_y + narglow.pixel_x = new_x + narglow.pixel_y = new_y + narsimage.loc = src.loc + narglow.loc = src.loc + //Display the new narsimage to the player + src << narsimage + src << narglow + else + if(narsimage) + qdel(narsimage) + qdel(narglow) diff --git a/code/game/gamemodes/cult/cultify/obj.dm b/code/game/gamemodes/cult/cultify/obj.dm new file mode 100644 index 00000000000..cbc3571896e --- /dev/null +++ b/code/game/gamemodes/cult/cultify/obj.dm @@ -0,0 +1,153 @@ +/obj/proc/cultify() + qdel(src) + +/obj/effect/decal/cleanable/blood/cultify() + return + +/obj/effect/decal/remains/cultify() + return + +/obj/effect/overlay/cultify() + return + +/obj/item/device/flashlight/lamp/cultify() + new /obj/structure/cult/pylon(loc) + ..() + +/obj/item/stack/sheet/wood/cultify() + return + +/obj/item/weapon/book/cultify() + new /obj/item/weapon/book/tome(loc) + ..() + +/obj/item/weapon/claymore/cultify() + new /obj/item/weapon/melee/cultblade(loc) + ..() + +/obj/item/weapon/storage/backpack/cultify() + new /obj/item/weapon/storage/backpack/cultpack(loc) + ..() + +/obj/item/weapon/storage/backpack/cultpack/cultify() + return + +/obj/machinery/cultify() + // We keep the number of cultified machines down by only converting those that are dense + // The alternative is to keep a separate file of exceptions. + if(density) + var/list/random_structure = list( + /obj/structure/cult/talisman, + /obj/structure/cult/forge, + /obj/structure/cult/tome + ) + var/I = pick(random_structure) + new I(loc) + ..() + +/obj/machinery/atmospherics/cultify() + if(src.invisibility != INVISIBILITY_MAXIMUM) + src.invisibility = INVISIBILITY_MAXIMUM + density = 0 + +/obj/machinery/cooking/cultify() + new /obj/structure/cult/talisman(loc) + qdel(src) + +/obj/machinery/computer/cultify() + new /obj/structure/cult/tome(loc) + qdel(src) + +/obj/machinery/door/airlock/external/cultify() + new /obj/structure/mineral_door/wood(loc) + ..() + +/obj/machinery/door/cultify() + icon_state = "null" + density = 0 + c_animation = new /atom/movable/overlay(src.loc) + c_animation.name = "cultification" + c_animation.density = 0 + c_animation.anchored = 1 + c_animation.icon = 'icons/effects/effects.dmi' + c_animation.layer = 5 + c_animation.master = src.loc + c_animation.icon_state = "breakdoor" + flick("cultification",c_animation) + spawn(10) + qdel(c_animation) + qdel(src) + +/obj/machinery/door/firedoor/cultify() + qdel(src) + +/obj/machinery/light/cultify() + new /obj/structure/cult/pylon(loc) + qdel(src) + +/obj/machinery/mech_sensor/cultify() + qdel(src) + +/obj/machinery/power/apc/cultify() + if(src.invisibility != INVISIBILITY_MAXIMUM) + src.invisibility = INVISIBILITY_MAXIMUM + +/obj/machinery/vending/cultify() + new /obj/structure/cult/forge(loc) + qdel(src) + +/obj/structure/bed/chair/cultify() + var/obj/structure/bed/chair/wood/wings/I = new(loc) + I.dir = dir + ..() + +/obj/structure/bed/chair/wood/cultify() + return + +/obj/structure/bookcase/cultify() + return + +/obj/structure/grille/cultify() + new /obj/structure/grille/cult(get_turf(src)) + ..() + +/obj/structure/grille/cult/cultify() + return + +/obj/structure/mineral_door/cultify() + new /obj/structure/mineral_door/wood(loc) + ..() + +/obj/structure/mineral_door/wood/cultify() + return + +/obj/singularity/cultify() + var/dist = max((current_size - 2), 1) + explosion(get_turf(src), dist, dist * 2, dist * 4) + qdel(src) + +/obj/structure/shuttle/engine/heater/cultify() + new /obj/structure/cult/pylon(loc) + ..() + +/obj/structure/shuttle/engine/propulsion/cultify() + var/turf/T = get_turf(src) + if(T) + T.ChangeTurf(/turf/simulated/wall/cult) + ..() + +/obj/structure/stool/cultify() + var/obj/structure/bed/chair/wood/wings/I = new(loc) + I.dir = dir + ..() + +/obj/structure/table/cultify() + // Make it a wood-reinforced wooden table. + // There are cult materials available, but it'd make the table non-deconstructable with how holotables work. + // Could possibly use a new material var for holographic-ness? + material = name_to_material["wood"] + reinforced = name_to_material["wood"] + update_desc() + update_connections(1) + update_icon() + update_material() diff --git a/code/game/gamemodes/cult/cultify/turf.dm b/code/game/gamemodes/cult/cultify/turf.dm new file mode 100644 index 00000000000..0005298c423 --- /dev/null +++ b/code/game/gamemodes/cult/cultify/turf.dm @@ -0,0 +1,43 @@ +/turf/proc/cultify() + ChangeTurf(/turf/space) + return + +/turf/simulated/floor/cultify() + cultify_floor() + +/turf/simulated/floor/carpet/cultify() + return + +/turf/simulated/shuttle/floor/cultify() + cultify_floor() + +/turf/simulated/shuttle/floor4/cultify() + cultify_floor() + +/turf/simulated/shuttle/wall/cultify() + cultify_wall() + +/turf/simulated/wall/cultify() + cultify_wall() + +/turf/simulated/wall/cult/cultify() + return + +/turf/unsimulated/beach/cultify() + return + +/turf/unsimulated/floor/cultify() + cultify_floor() + +/turf/unsimulated/wall/cultify() + cultify_wall() + +/turf/proc/cultify_floor() + if((icon_state != "cult")&&(icon_state != "cult-narsie")) + name = "engraved floor" + icon_state = "cult" + turf_animation('icons/effects/effects.dmi',"cultfloor",0,0,MOB_LAYER-1) + +/turf/proc/cultify_wall() + ChangeTurf(/turf/unsimulated/wall/cult) + turf_animation('icons/effects/effects.dmi',"cultwall",0,0,MOB_LAYER-1) diff --git a/code/game/gamemodes/cult/hell_universe.dm b/code/game/gamemodes/cult/hell_universe.dm new file mode 100644 index 00000000000..9a7344f036a --- /dev/null +++ b/code/game/gamemodes/cult/hell_universe.dm @@ -0,0 +1,100 @@ +/* + +In short: + * Random area alarms + * All areas jammed + * Random gateways spawning hellmonsters (and turn people into cluwnes if ran into) + * Broken APCs/Fire Alarms + * Scary music + * Random tiles changing to culty tiles. + +*/ +/datum/universal_state/hell + name = "Hell Rising" + desc = "OH FUCK OH FUCK OH FUCK" + + decay_rate = 5 // 5% chance of a turf decaying on lighting update/airflow (there's no actual tick for turfs) + +/datum/universal_state/hell/OnShuttleCall(var/mob/user) + return 1 + /* + if(user) + user << "All you hear on the frequency is static and panicked screaming. There will be no shuttle call today." + return 0 + */ + +/datum/universal_state/hell/DecayTurf(var/turf/T) + if(!T.holy) + T.cultify() + for(var/obj/machinery/light/L in T.contents) + new /obj/structure/cult/pylon(L.loc) + qdel(L) + return + + +/datum/universal_state/hell/OnTurfChange(var/turf/T) + var/turf/space/spess = T + if(istype(spess)) + spess.overlays += "hell01" + +// Apply changes when entering state +/datum/universal_state/hell/OnEnter() + set background = 1 + garbage_collector.garbage_collect = 0 + escape_list = get_area_turfs(locate(/area/hallway/secondary/exit)) + + //Separated into separate procs for profiling + AreaSet() + OverlaySet() + MiscSet() + APCSet() + KillMobs() + AmbientSet() + + runedec += 9000 //basically removing the rune cap + +/datum/universal_state/hell/proc/AreaSet() + for(var/area/A in world) + if(A.name=="Space") + continue + + // Reset all alarms. + A.fire = null + A.atmos = 1 + A.atmosalm = 0 + A.poweralm = 1 + A.party = null + + A.updateicon() + +/datum/universal_state/hell/proc/OverlaySet() + var/image/I = image("icon" = 'icons/turf/space.dmi', "icon_state" = "hell01", "layer" = 10) + for(var/turf/space/spess in world) + spess.overlays += I + +/datum/universal_state/hell/proc/AmbientSet() + for(var/atom/movable/lighting_overlay/L in world) + L.update_lumcount(1, 0, 0) + +/datum/universal_state/hell/proc/MiscSet() + for(var/turf/simulated/floor/T in world) + if(!T.holy && prob(1)) + new /obj/effect/gateway/active/cult(T) + + for (var/obj/machinery/firealarm/alm in machines) + if (!(alm.stat & BROKEN)) + alm.ex_act(2) + +/datum/universal_state/hell/proc/APCSet() + for (var/obj/machinery/power/apc/APC in machines) + if (!(APC.stat & BROKEN) && !istype(APC.area,/area/turret_protected/ai)) + APC.chargemode = 0 + if(APC.cell) + APC.cell.charge = 0 + APC.emagged = 1 + APC.queue_icon_update() + +/datum/universal_state/hell/proc/KillMobs() + for(var/mob/living/simple_animal/M in mob_list) + if(M && !M.client) + M.stat = DEAD diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 0fd706059e9..8a55a811654 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -2,7 +2,8 @@ var/cultwords = list() var/runedec = 0 -var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", "self", "see", "other", "hide") +var/global/list/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", "self", "see", "other", "hide") +var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","mgar","balaq", "karazet", "geeri") /client/proc/check_words() // -- Urist set category = "Special Verbs" @@ -14,7 +15,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", usr << "[cultwords[word]] is [word]" /proc/runerandom() //randomizes word meaning - var/list/runewords=list("ire","ego","nahlizet","certum","veri","jatkaa","mgar","balaq", "karazet", "geeri") ///"orkan" and "allaq" removed. + var/list/runewords=rnwords for (var/word in engwords) cultwords[word] = pick(runewords) runewords-=cultwords[word] @@ -32,8 +33,9 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", var/word1 var/word2 var/word3 + var/image/blood_image var/list/converting = list() - + // Places these combos are mentioned: this file - twice in the rune code, once in imbued tome, once in tome's HTML runes.dm - in the imbue rune code. If you change a combination - dont forget to change it everywhere. // travel self [word] - Teleport to random [rune with word destination matching] @@ -65,10 +67,21 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", // join hide technology - stun rune. Rune color: bright pink. New() ..() - var/image/blood = image(loc = src) - blood.override = 1 + blood_image = image(loc = src) + blood_image.override = 1 for(var/mob/living/silicon/ai/AI in player_list) - AI.client.images += blood + if(AI.client) + AI.client.images += blood_image + rune_list.Add(src) + + Destroy() + for(var/mob/living/silicon/ai/AI in player_list) + if(AI.client) + AI.client.images -= blood_image + qdel(blood_image) + blood_image = null + rune_list.Remove(src) + ..() examine(mob/user) ..() @@ -79,11 +92,11 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", attackby(I as obj, user as mob) if(istype(I, /obj/item/weapon/book/tome) && iscultist(user)) user << "You retrace your steps, carefully undoing the lines of the rune." - del(src) + qdel(src) return else if(istype(I, /obj/item/weapon/nullrod)) user << "\blue You disrupt the vile magic with the deadening field of the null rod!" - del(src) + qdel(src) return return @@ -457,6 +470,8 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", user << "\red You slice open one of your fingers and begin drawing a rune on the floor whilst chanting the ritual that binds your life essence with the dark arcane energies flowing through the surrounding world." user.take_overall_damage((rand(9)+1)/10) // 0.1 to 1.0 damage if(do_after(user, 50)) + var/area/A = get_area(user) + log_and_message_admins("created \an [chosen_rune] rune at \the [A.name] - [user.loc.x]-[user.loc.y]-[user.loc.z].") if(usr.get_active_hand() != src) return var/mob/living/carbon/human/H = user @@ -495,6 +510,9 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", else user << "The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood. Contains the details of every ritual his followers could think of. Most of these are useless, though." +/obj/item/weapon/book/tome/cultify() + return + /obj/item/weapon/book/tome/imbued //admin tome, spawns working runes without waiting w_class = 2.0 var/cultistsonly = 1 @@ -514,6 +532,8 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", var/mob/living/carbon/human/H = user R.blood_DNA = list() R.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type + var/area/A = get_area(user) + log_and_message_admins("created \an [r] rune at \the [A.name] - [user.loc.x]-[user.loc.y]-[user.loc.z].") switch(r) if("teleport") var/list/words = list("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri") diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 9230436a056..8ead4b96bad 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -1,5 +1,8 @@ var/list/sacrificed = list() +/obj/effect/rune/cultify() + return + /obj/effect/rune /////////////////////////////////////////FIRST RUNE @@ -21,7 +24,7 @@ var/list/sacrificed = list() user << "\red You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric" if (istype(user, /mob/living)) user.take_overall_damage(5, 0) - del(src) + qdel(src) if(allrunesloc && index != 0) if(istype(src,/obj/effect/rune)) user.say("Sas[pick("'","`")]so c'arta forbici!")//Only you can stop auto-muting @@ -58,7 +61,7 @@ var/list/sacrificed = list() user << "\red You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric" if (istype(user, /mob/living)) user.take_overall_damage(5, 0) - del(src) + qdel(src) for(var/mob/living/carbon/C in orange(1,src)) if(iscultist(C) && !C.stat) culcount++ @@ -91,7 +94,7 @@ var/list/sacrificed = list() new /obj/item/weapon/book/tome(src.loc) else new /obj/item/weapon/book/tome(usr.loc) - del(src) + qdel(src) return @@ -99,6 +102,7 @@ var/list/sacrificed = list() /////////////////////////////////////////THIRD RUNE convert() + var/mob/attacker = usr var/mob/living/carbon/target = null for(var/mob/living/carbon/M in src.loc) if(!iscultist(M) && M.stat < DEAD && !(M in converting)) @@ -127,6 +131,7 @@ var/list/sacrificed = list() target.take_overall_damage(0, rand(5, 20)) // You dirty resister cannot handle the damage to your mind. Easily. - even cultists who accept right away should experience some effects // Resist messages go! if(initial_message) //don't do this stuff right away, only if they resist or hesitate. + admin_attack_log(attacker, target, "Used a convert rune", "Was subjected to a convert rune", "used a convert rune on") switch(target.getFireLoss()) if(0 to 25) target << "Your blood boils as you force yourself to resist the corruption invading every corner of your mind." @@ -176,13 +181,17 @@ var/list/sacrificed = list() /////////////////////////////////////////FOURTH RUNE tearreality() - var/cultist_count = 0 + if(!cult.allow_narsie) + return fizzle() + + var/list/cultists = new() for(var/mob/M in range(1,src)) if(iscultist(M) && !M.stat) M.say("Tok-lyr rqa'nap g[pick("'","`")]lt-ulotf!") - cultist_count += 1 - if(cultist_count >= 9) - new /obj/machinery/singularity/narsie/large(src.loc) + cultists += 1 + if(cultists.len >= 9) + log_and_message_admins_many(cultists, "summoned Nar-sie.") + new /obj/singularity/narsie/large(src.loc) return else return fizzle() @@ -190,6 +199,7 @@ var/list/sacrificed = list() /////////////////////////////////////////FIFTH RUNE emp(var/U,var/range_red) //range_red - var which determines by which number to reduce the default emp range, U is the source loc, needed because of talisman emps which are held in hand at the moment of using and that apparently messes things up -- Urist + log_and_message_admins("activated an EMP rune.") if(istype(src,/obj/effect/rune)) usr.say("Ta'gh fara[pick("'","`")]qha fel d'amar det!") else @@ -200,7 +210,7 @@ var/list/sacrificed = list() T.hotspot_expose(700,125) var/rune = src // detaching the proc - in theory empulse(U, (range_red - 2), range_red) - del(rune) + qdel(rune) return /////////////////////////////////////////SIXTH RUNE @@ -211,6 +221,7 @@ var/list/sacrificed = list() if(R.word1==cultwords["travel"] && R.word2==cultwords["blood"] && R.word3==cultwords["self"]) for(var/mob/living/carbon/D in R.loc) if(D.stat!=2) + admin_attack_log(usr, D, "Used a blood drain rune.", "Was victim of a blood drain rune.", "used a blood drain rune on") var/bdrain = rand(1,25) D << "\red You feel weakened." D.take_overall_damage(bdrain, 0) @@ -359,7 +370,7 @@ var/list/sacrificed = list() usr.say("Kla[pick("'","`")]atu barada nikt'o!") for (var/mob/V in viewers(src)) V.show_message("\red The rune turns into gray dust, veiling the surrounding runes.", 3) - del(src) + qdel(src) else usr.whisper("Kla[pick("'","`")]atu barada nikt'o!") usr << "\red Your talisman turns into gray dust, veiling the surrounding runes." @@ -407,6 +418,7 @@ var/list/sacrificed = list() var/mob/dead/observer/ghost for(var/mob/dead/observer/O in this_rune.loc) if(!O.client) continue + if(!O.MayRespawn()) continue if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue ghost = O break @@ -443,6 +455,7 @@ var/list/sacrificed = list() D.real_name += " " D.real_name += pick("Apparition", "Aptrgangr", "Dis", "Draugr", "Dybbuk", "Eidolon", "Fetch", "Fylgja", "Ghast", "Ghost", "Gjenganger", "Haint", "Phantom", "Phantasm", "Poltergeist", "Revenant", "Shade", "Shadow", "Soul", "Spectre", "Spirit", "Spook", "Visitant", "Wraith") + log_and_message_admins("used a manifest rune.") var/mob/living/user = usr while(this_rune && user && user.stat==CONSCIOUS && user.client && user.loc==this_rune.loc) user.take_organ_damage(1, 0) @@ -534,8 +547,8 @@ var/list/sacrificed = list() for (var/mob/V in viewers(src)) V.show_message("\red The runes turn into dust, which then forms into an arcane image on the paper.", 3) usr.say("H'drak v[pick("'","`")]loso, mir'kanas verbot!") - del(imbued_from) - del(newtalisman) + qdel(imbued_from) + qdel(newtalisman) else return fizzle() @@ -563,26 +576,26 @@ var/list/sacrificed = list() // returns 0 if the rune is not used. returns 1 if the rune is used. communicate() . = 1 // Default output is 1. If the rune is deleted it will return 1 - var/input = sanitize(input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "")) + var/input = input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "")//sanitize() below, say() and whisper() have their own if(!input) if (istype(src)) fizzle() return 0 else return 0 - if(istype(src,/obj/effect/rune)) - usr.say("O bidai nabora se[pick("'","`")]sma!") - else - usr.whisper("O bidai nabora se[pick("'","`")]sma!") if(istype(src,/obj/effect/rune)) + usr.say("O bidai nabora se[pick("'","`")]sma!") usr.say("[input]") else + usr.whisper("O bidai nabora se[pick("'","`")]sma!") usr.whisper("[input]") + + input = sanitize(input) for(var/datum/mind/H in cult.current_antagonists) if (H.current) H.current << "\red \b [input]" - del(src) + qdel(src) return 1 /////////////////////////////////////////FIFTEENTH RUNE @@ -657,6 +670,7 @@ var/list/sacrificed = list() usr << "\red The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." else if(prob(40)) + usr << "\red The Geometer of blood accepts this sacrifice." cult.grant_runeword(usr) else @@ -733,7 +747,7 @@ var/list/sacrificed = list() usr.say("Nikt[pick("'","`")]o barada kla'atu!") for (var/mob/V in viewers(src)) V.show_message("\red The rune turns into red dust, reveaing the surrounding runes.", 3) - del(src) + qdel(src) return if(istype(W,/obj/item/weapon/paper/talisman)) usr.whisper("Nikt[pick("'","`")]o barada kla'atu!") @@ -806,7 +820,7 @@ var/list/sacrificed = list() for(var/mob/living/carbon/C in users) user.take_overall_damage(dam, 0) C.say("Khari[pick("'","`")]d! Gual'te nikka!") - del(src) + qdel(src) return fizzle() /////////////////////////////////////////NINETEENTH RUNE @@ -846,14 +860,14 @@ var/list/sacrificed = list() user.visible_message("\red Rune disappears with a flash of red light, and in its place now a body lies.", \ "\red You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a body.", \ "\red You hear a pop and smell ozone.") - del(src) + qdel(src) return fizzle() /////////////////////////////////////////TWENTIETH RUNES deafen() if(istype(src,/obj/effect/rune)) - var/affected = 0 + var/list/affected = new() for(var/mob/living/carbon/C in range(7,src)) if (iscultist(C)) continue @@ -862,17 +876,18 @@ var/list/sacrificed = list() continue C.ear_deaf += 50 C.show_message("\red The world around you suddenly becomes quiet.", 3) - affected++ + affected += C if(prob(1)) C.sdisabilities |= DEAF - if(affected) + if(affected.len) usr.say("Sti[pick("'","`")] kaliedir!") usr << "\red The world becomes quiet as the deafening rune dissipates into fine dust." - del(src) + admin_attacker_log_many_victims(usr, affected, "Used a deafen rune.", "Was victim of a deafen rune.", "used a deafen rune on") + qdel(src) else return fizzle() else - var/affected = 0 + var/list/affected = new() for(var/mob/living/carbon/C in range(7,usr)) if (iscultist(C)) continue @@ -882,10 +897,11 @@ var/list/sacrificed = list() C.ear_deaf += 30 //talismans is weaker. C.show_message("\red The world around you suddenly becomes quiet.", 3) - affected++ - if(affected) + affected += C + if(affected.len) usr.whisper("Sti[pick("'","`")] kaliedir!") usr << "\red Your talisman turns into gray dust, deafening everyone around." + admin_attacker_log_many_victims(usr, affected, "Used a deafen rune.", "Was victim of a deafen rune.", "used a deafen rune on") for (var/mob/V in orange(1,src)) if(!(iscultist(V))) V.show_message("\red Dust flows from [usr]'s hands for a moment, and the world suddenly becomes quiet..", 3) @@ -893,7 +909,7 @@ var/list/sacrificed = list() blind() if(istype(src,/obj/effect/rune)) - var/affected = 0 + var/list/affected = new() for(var/mob/living/carbon/C in viewers(src)) if (iscultist(C)) continue @@ -907,15 +923,16 @@ var/list/sacrificed = list() if(prob(10)) C.sdisabilities |= BLIND C.show_message("\red Suddenly you see red flash that blinds you.", 3) - affected++ - if(affected) + affected += C + if(affected.len) usr.say("Sti[pick("'","`")] kaliesin!") usr << "\red The rune flashes, blinding those who not follow the Nar-Sie, and dissipates into fine dust." - del(src) + admin_attacker_log_many_victims(usr, affected, "Used a blindness rune.", "Was victim of a blindness rune.", "used a blindness rune on") + qdel(src) else return fizzle() else - var/affected = 0 + var/list/affected = new() for(var/mob/living/carbon/C in view(2,usr)) if (iscultist(C)) continue @@ -925,11 +942,12 @@ var/list/sacrificed = list() C.eye_blurry += 30 C.eye_blind += 10 //talismans is weaker. - affected++ + affected += C C.show_message("\red You feel a sharp pain in your eyes, and the world disappears into darkness..", 3) - if(affected) + if(affected.len) usr.whisper("Sti[pick("'","`")] kaliesin!") usr << "\red Your talisman turns into gray dust, blinding those who not follow the Nar-Sie." + admin_attacker_log_many_victims(usr, affected, "Used a blindness rune.", "Was victim of a blindness rune.", "used a blindness rune on") return @@ -940,12 +958,13 @@ var/list/sacrificed = list() if (istype(H.current,/mob/living/carbon)) cultists+=H.current */ - var/culcount = 0 //also, wording for it is old wording for obscure rune, which is now hide-see-blood. + var/list/cultists = new //also, wording for it is old wording for obscure rune, which is now hide-see-blood. + var/list/victims = new // var/list/cultboil = list(cultists-usr) //and for this words are destroy-see-blood. for(var/mob/living/carbon/C in orange(1,src)) if(iscultist(C) && !C.stat) - culcount++ - if(culcount>=3) + cultists+=C + if(cultists.len>=3) for(var/mob/living/carbon/M in viewers(usr)) if(iscultist(M)) continue @@ -954,6 +973,7 @@ var/list/sacrificed = list() continue M.take_overall_damage(51,51) M << "\red Your blood boils!" + victims += M if(prob(5)) spawn(5) M.gib() @@ -964,7 +984,9 @@ var/list/sacrificed = list() if(iscultist(C) && !C.stat) C.say("Dedo ol[pick("'","`")]btoh!") C.take_overall_damage(15, 0) - del(src) + admin_attacker_log_many_victims(usr, victims, "Used a blood boil rune.", "Was the victim of a blood boil rune.", "used a blood boil rune on") + log_and_message_admins_many(cultists - usr, "assisted activating a blood boil rune.") + qdel(src) else return fizzle() return @@ -994,8 +1016,8 @@ var/list/sacrificed = list() M << "\red Blood suddenly ignites, burning you!" var/turf/T = get_turf(B) T.hotspot_expose(700,125) - del(B) - del(src) + qdel(B) + qdel(src) ////////// Rune 24 (counting burningblood, which kinda doesnt work yet.) @@ -1003,7 +1025,6 @@ var/list/sacrificed = list() if(istype(src,/obj/effect/rune)) ///When invoked as rune, flash and stun everyone around. usr.say("Fuu ma[pick("'","`")]jin!") for(var/mob/living/L in viewers(src)) - if(iscarbon(L)) var/mob/living/carbon/C = L flick("e_flash", C.flash) @@ -1012,12 +1033,14 @@ var/list/sacrificed = list() C.Weaken(1) C.Stun(1) C.show_message("\red The rune explodes in a bright flash.", 3) + admin_attack_log(usr, C, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") else if(issilicon(L)) var/mob/living/silicon/S = L S.Weaken(5) S.show_message("\red BZZZT... The rune has exploded in a bright flash.", 3) - del(src) + admin_attack_log(usr, S, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") + qdel(src) else ///When invoked as talisman, stun and mute the target mob. usr.say("Dream sign ''Evil sealing talisman'[pick("'","`")]!") var/obj/item/weapon/nullrod/N = locate() in T @@ -1030,7 +1053,7 @@ var/list/sacrificed = list() if(issilicon(T)) T.Weaken(15) - + admin_attack_log(usr, T, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") else if(iscarbon(T)) var/mob/living/carbon/C = T flick("e_flash", C.flash) @@ -1038,6 +1061,7 @@ var/list/sacrificed = list() C.silent += 15 C.Weaken(25) C.Stun(25) + admin_attack_log(usr, C, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") return /////////////////////////////////////////TWENTY-FIFTH RUNE @@ -1059,5 +1083,5 @@ var/list/sacrificed = list() //the below calls update_icons() at the end, which will update overlay icons by using the (now updated) cache user.put_in_hands(new /obj/item/weapon/melee/cultblade(user)) //put in hands or on floor - del(src) + qdel(src) return diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 0f5ab245d1f..d2b881d8913 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -35,7 +35,7 @@ user.take_organ_damage(5, 0) if(src && src.imbue!="supply" && src.imbue!="runestun") if(delete) - del(src) + qdel(src) return else user << "You see strange symbols on the paper. Are they supposed to mean something?" @@ -47,7 +47,7 @@ if(imbue == "runestun") user.take_organ_damage(5, 0) call(/obj/effect/rune/proc/runestun)(T) - del(src) + qdel(src) else ..() ///If its some other talisman, use the generic attack code, is this supposed to work this way? else @@ -56,7 +56,7 @@ proc/supply(var/key) if (!src.uses) - del(src) + qdel(src) return var/dat = "There are [src.uses] bloody runes on the parchment.
    " @@ -106,7 +106,7 @@ if("soulstone") new /obj/item/device/soulstone(get_turf(usr)) if("construct") - new /obj/structure/constructshell(get_turf(usr)) + new /obj/structure/constructshell/cult(get_turf(usr)) src.uses-- supply() return diff --git a/code/game/gamemodes/endgame/endgame.dm b/code/game/gamemodes/endgame/endgame.dm new file mode 100644 index 00000000000..ed1167dfe74 --- /dev/null +++ b/code/game/gamemodes/endgame/endgame.dm @@ -0,0 +1,68 @@ +/********************** + * ENDGAME STUFF + **********************/ + + // Universal State + // Handles stuff like space icon_state, constants, etc. + // Essentially a policy manager. Once shit hits the fan, this changes its policies. + // Called by master controller. + + // Default shit. +/datum/universal_state + // Just for reference, for now. + // Might eventually add an observatory job. + var/name = "Normal" + var/desc = "Nothing seems awry." + + // Sets world.turf, replaces all turfs of type /turf/space. + var/space_type = /turf/space + + // Replaces all turfs of type /turf/space/transit + var/transit_space_type = /turf/space/transit + + // Chance of a floor or wall getting damaged [0-100] + // Simulates stuff getting broken due to molecular bonds decaying. + var/decay_rate = 0 + +// Actually decay the turf. +/datum/universal_state/proc/DecayTurf(var/turf/T) + if(istype(T,/turf/simulated/wall)) + var/turf/simulated/wall/W=T + W.melt() + return + if(istype(T,/turf/simulated/floor)) + var/turf/simulated/floor/F=T + // Burnt? + if(!F.burnt) + F.burn_tile() + else + F.ReplaceWithLattice() + return + +// Return 0 to cause shuttle call to fail. +/datum/universal_state/proc/OnShuttleCall(var/mob/user) + return 1 + +// Processed per tick +/datum/universal_state/proc/OnTurfTick(var/turf/T) + if(decay_rate && prob(decay_rate)) + DecayTurf(T) + +// Apply changes when exiting state +/datum/universal_state/proc/OnExit() + // Does nothing by default + +// Apply changes when entering state +/datum/universal_state/proc/OnEnter() + // Does nothing by default + +// Apply changes to a new turf. +/datum/universal_state/proc/OnTurfChange(var/turf/NT) + return + +/proc/SetUniversalState(var/newstate,var/on_exit=1, var/on_enter=1) + if(on_exit) + universe.OnExit() + universe = new newstate + if(on_enter) + universe.OnEnter() diff --git a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm new file mode 100644 index 00000000000..dc315ac5100 --- /dev/null +++ b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm @@ -0,0 +1,118 @@ +// QUALITY COPYPASTA +/turf/unsimulated/wall/supermatter + name = "Bluespace" + desc = "THE END IS right now actually." + + icon = 'icons/turf/space.dmi' + icon_state = "bluespace" + + //luminosity = 5 + //l_color="#0066FF" + layer = 11 + + var/spawned=0 // DIR mask + var/next_check=0 + var/list/avail_dirs = list(NORTH,SOUTH,EAST,WEST) + +/turf/unsimulated/wall/supermatter/New() + ..() + processing_turfs.Add(src) + next_check = world.time+5 SECONDS + +/turf/unsimulated/wall/supermatter/Destroy() + processing_turfs.Remove(src) + ..() + +/turf/unsimulated/wall/supermatter/process() + // Only check infrequently. + if(next_check>world.time) return + + // No more available directions? Shut down process(). + if(avail_dirs.len==0) + processing_objects.Remove(src) + return 1 + + // We're checking, reset the timer. + next_check = world.time+5 SECONDS + + // Choose a direction. + var/pdir = pick(avail_dirs) + avail_dirs -= pdir + var/turf/T=get_step(src,pdir) + + // EXPAND + if(!istype(T,type)) + // Do pretty fadeout animation for 1s. + new /obj/effect/overlay/bluespacify(T) + spawn(10) + // Nom. + for(var/atom/movable/A in T) + if(A) + if(istype(A,/mob/living)) + qdel(A) + continue + else if(istype(A,/mob)) // Observers, AI cameras. + continue + qdel(A) + T.ChangeTurf(type) + + if((spawned & (NORTH|SOUTH|EAST|WEST)) == (NORTH|SOUTH|EAST|WEST)) + processing_turfs -= src + return + +/turf/unsimulated/wall/supermatter/attack_generic(mob/user as mob) + return attack_hand(user) + +/turf/unsimulated/wall/supermatter/attack_robot(mob/user as mob) + if(Adjacent(user)) + return attack_hand(user) + else + user << "What the fuck are you doing?" + return + +// /vg/: Don't let ghosts fuck with this. +/turf/unsimulated/wall/supermatter/attack_ghost(mob/user as mob) + user.examinate(src) + +/turf/unsimulated/wall/supermatter/attack_ai(mob/user as mob) + return user.examinate(src) + +/turf/unsimulated/wall/supermatter/attack_hand(mob/user as mob) + user.visible_message("\The [user] reaches out and touches \the [src]... And then blinks out of existance.",\ + "You reach out and touch \the [src]. Everything immediately goes quiet. Your last thought is \"That was not a wise decision.\"",\ + "You hear an unearthly noise.") + + playsound(src, 'sound/effects/supermatter.ogg', 50, 1) + + Consume(user) + +/turf/unsimulated/wall/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob) + user.visible_message("\The [user] touches \a [W] to \the [src] as a silence fills the room...",\ + "You touch \the [W] to \the [src] when everything suddenly goes silent.\"\n\The [W] flashes into dust as you flinch away from \the [src].",\ + "Everything suddenly goes silent.") + + playsound(src, 'sound/effects/supermatter.ogg', 50, 1) + + user.drop_from_inventory(W) + Consume(W) + + +/turf/unsimulated/wall/supermatter/Bumped(atom/AM as mob|obj) + if(istype(AM, /mob/living)) + AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... \his body starts to glow and catch flame before flashing into ash.",\ + "You slam into \the [src] as your ears are filled with unearthly ringing. Your last thought is \"Oh, fuck.\"",\ + "You hear an unearthly noise as a wave of heat washes over you.") + else + AM.visible_message("\The [AM] smacks into \the [src] and rapidly flashes to ash.",\ + "You hear a loud crack as you are washed with a wave of heat.") + + playsound(src, 'sound/effects/supermatter.ogg', 50, 1) + + Consume(AM) + + +/turf/unsimulated/wall/supermatter/proc/Consume(var/mob/living/user) + if(istype(user,/mob/dead/observer)) + return + + qdel(user) diff --git a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm new file mode 100644 index 00000000000..8c826fe22db --- /dev/null +++ b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm @@ -0,0 +1,81 @@ +/*** EXIT PORTAL ***/ + +/obj/singularity/narsie/large/exit + name = "Bluespace Rift" + desc = "NO TIME TO EXPLAIN, JUMP IN" + icon = 'icons/obj/rift.dmi' + icon_state = "rift" + + move_self = 0 + announce=0 + narnar=0 + + layer=12 // ITS SO BRIGHT + + consume_range = 6 + +/obj/singularity/narsie/large/exit/New() + ..() + processing_objects.Add(src) + +/obj/singularity/narsie/large/exit/update_icon() + overlays = 0 + +/obj/singularity/narsie/large/exit/process() + for(var/mob/M in player_list) + if(M.client) + M.see_rift(src) + eat() + +/obj/singularity/narsie/large/exit/acquire(var/mob/food) + return + +/obj/singularity/narsie/large/exit/consume(const/atom/A) + if(!(A.singuloCanEat())) + return 0 + + if (istype(A, /mob/living/)) + do_teleport(A, pick(endgame_safespawns)) //dead-on precision + else if (isturf(A)) + var/turf/T = A + var/dist = get_dist(T, src) + if (dist <= consume_range && T.density) + T.density = 0 + + for (var/atom/movable/AM in T.contents) + if (AM == src) // This is the snowflake. + continue + + if (dist <= consume_range) + consume(AM) + continue + + if (dist > consume_range) + if (101 == AM.invisibility) + continue + + spawn (0) + AM.singularity_pull(src, src.current_size) + + +/mob + //thou shall always be able to see the rift + var/image/riftimage = null + +/mob/proc/see_rift(var/obj/singularity/narsie/large/exit/R) + if((R.z == src.z) && (get_dist(R,src) <= (R.consume_range+10)) && !(R in view(src))) + if(!riftimage) + riftimage = image('icons/obj/rift.dmi',src.loc,"rift",12,1) + riftimage.mouse_opacity = 0 + + var/new_x = 32 * (R.x - src.x) + R.pixel_x + var/new_y = 32 * (R.y - src.y) + R.pixel_y + riftimage.pixel_x = new_x + riftimage.pixel_y = new_y + riftimage.loc = src.loc + + src << riftimage + + else + if(riftimage) + qdel(riftimage) diff --git a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm new file mode 100644 index 00000000000..37b68340a8b --- /dev/null +++ b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm @@ -0,0 +1,139 @@ + +/datum/universal_state/supermatter_cascade + name = "Supermatter Cascade" + desc = "Unknown harmonance affecting universal substructure, converting nearby matter to supermatter." + + decay_rate = 5 // 5% chance of a turf decaying on lighting update/airflow (there's no actual tick for turfs) + +/datum/universal_state/supermatter_cascade/OnShuttleCall(var/mob/user) + if(user) + user << "All you hear on the frequency is static and panicked screaming. There will be no shuttle call today." + return 0 + +/datum/universal_state/supermatter_cascade/OnTurfChange(var/turf/T) + var/turf/space/spess = T + if(istype(spess)) + spess.overlays += "end01" + +/datum/universal_state/supermatter_cascade/DecayTurf(var/turf/T) + if(istype(T,/turf/simulated/wall)) + var/turf/simulated/wall/W=T + W.melt() + return + if(istype(T,/turf/simulated/floor)) + var/turf/simulated/floor/F=T + // Burnt? + if(!F.burnt) + F.burn_tile() + else + if(!istype(F,/turf/simulated/floor/plating)) + F.break_tile_to_plating() + return + +// Apply changes when entering state +/datum/universal_state/supermatter_cascade/OnEnter() + set background = 1 + garbage_collector.garbage_collect = 0 + world << "You are blinded by a brilliant flash of energy." + + world << sound('sound/effects/cascade.ogg') + + for(var/mob/M in player_list) + flick("e_flash", M.flash) + + if(emergency_shuttle.can_recall()) + priority_announcement.Announce("The emergency shuttle has returned due to bluespace distortion.") + emergency_shuttle.recall() + + AreaSet() + OverlaySet() + MiscSet() + APCSet() + AmbientSet() + + // Disable Nar-Sie. + cult.allow_narsie = 0 + PlayerSet() + + new /obj/singularity/narsie/large/exit(pick(endgame_exits)) + spawn(rand(30,60) SECONDS) + var/txt = {" +There's been a galaxy-wide electromagnetic pulse. All of our systems are heavily damaged and many personnel are dead or dying. We are seeing increasing indications of the universe itself beginning to unravel. + +[station_name()], you are the only facility nearby a bluespace rift, which is near your research outpost. You are hereby directed to enter the rift using all means necessary, quite possibly as the last of your species alive. + +You have five minutes before the universe collapses. Good l\[\[###!!!- + +AUTOMATED ALERT: Link to [command_name()] lost."} + priority_announcement.Announce(txt,"SUPERMATTER CASCADE DETECTED") + sleep(5 MINUTES) + ticker.declare_completion() + ticker.station_explosion_cinematic(0,null) // TODO: Custom cinematic + + world << "Resetting in 30 seconds!" + + feedback_set_details("end_error","Universe ended") + + if(blackbox) + blackbox.save_all_data_to_sql() + + sleep(300) + log_game("Rebooting due to universal collapse") + world.Reboot() + return + +/datum/universal_state/supermatter_cascade/proc/AreaSet() + for(var/area/A in world) + if(A.z in config.admin_levels) + continue + if(istype(A,/area/space)) + continue + + // Reset all alarms. + A.fire = null + A.atmos = 1 + A.atmosalm = 0 + A.poweralm = 1 + + // Slap on random alerts + if(prob(25)) + switch(rand(1,4)) + if(1) + A.fire=1 + if(2) + A.atmosalm=1 + + A.updateicon() + +/datum/universal_state/supermatter_cascade/proc/OverlaySet() + for(var/turf/space/spess in world) + spess.overlays += "end01" + +/datum/universal_state/supermatter_cascade/proc/AmbientSet() + for(var/atom/movable/lighting_overlay/L in world) + if(!(L.z in config.admin_levels)) + L.update_lumcount(0.5, 1, 0) + +/datum/universal_state/supermatter_cascade/proc/MiscSet() + for (var/obj/machinery/firealarm/alm in world) + if (!(alm.stat & BROKEN)) + alm.ex_act(2) + +/datum/universal_state/supermatter_cascade/proc/APCSet() + for (var/obj/machinery/power/apc/APC in world) + if (!(APC.stat & BROKEN)) + APC.chargemode = 0 + if(APC.cell) + APC.cell.charge = 0 + APC.emagged = 1 + APC.queue_icon_update() + +/datum/universal_state/supermatter_cascade/proc/PlayerSet() + for(var/datum/mind/M in player_list) + if(!istype(M.current,/mob/living)) + continue + if(M.current.stat!=2) + M.current.Weaken(10) + flick("e_flash", M.current.flash) + + clear_antag_roles(M) diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index feed6092e27..d49247263f9 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -49,7 +49,7 @@ var/turf/T = pick(blobstart) var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 ) spawn(rand(50, 300)) - del(bh) + qdel(bh) /* if(3) //Leaving the code in so someone can try and delag it, but this event can no longer occur randomly, per SoS's request. --NEO command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert") @@ -71,7 +71,7 @@ P.icon_state = "anom" P.name = "wormhole" spawn(rand(300,600)) - del(P) + qdel(P) */ if(3) if((world.time/10)>=3600 && config.ninjas_allowed && !sent_ninja_to_station)//If an hour has passed, relatively speaking. Also, if ninjas are allowed to spawn and if there is not already a ninja for the round. diff --git a/code/game/gamemodes/events/PortalStorm.dm b/code/game/gamemodes/events/PortalStorm.dm index 890755d6b8e..6144f3305bb 100644 --- a/code/game/gamemodes/events/PortalStorm.dm +++ b/code/game/gamemodes/events/PortalStorm.dm @@ -1,26 +1,26 @@ -/datum/event/portalstorm - - Announce() - command_alert("Subspace disruption detected around the vessel", "Anomaly Alert") - LongTerm() - - var/list/turfs = list( ) - var/turf/picked - - for(var/turf/T in world) - if(T.z < 5 && istype(T,/turf/simulated/floor)) - turfs += T - - for(var/turf/T in world) - if(prob(10) && T.z < 5 && istype(T,/turf/simulated/floor)) - spawn(50+rand(0,3000)) - picked = pick(turfs) - var/obj/portal/P = new /obj/portal( T ) - P.target = picked - P.creator = null - P.icon = 'icons/obj/objects.dmi' - P.failchance = 0 - P.icon_state = "anom" - P.name = "wormhole" - spawn(rand(100,150)) - del(P) \ No newline at end of file +/datum/event/portalstorm + + Announce() + command_alert("Subspace disruption detected around the vessel", "Anomaly Alert") + LongTerm() + + var/list/turfs = list( ) + var/turf/picked + + for(var/turf/T in world) + if(T.z < 5 && istype(T,/turf/simulated/floor)) + turfs += T + + for(var/turf/T in world) + if(prob(10) && T.z < 5 && istype(T,/turf/simulated/floor)) + spawn(50+rand(0,3000)) + picked = pick(turfs) + var/obj/portal/P = new /obj/portal( T ) + P.target = picked + P.creator = null + P.icon = 'icons/obj/objects.dmi' + P.failchance = 0 + P.icon_state = "anom" + P.name = "wormhole" + spawn(rand(100,150)) + qdel(P) diff --git a/code/game/gamemodes/events/black_hole.dm b/code/game/gamemodes/events/black_hole.dm index 6ff7babbeba..60ab8a692fa 100644 --- a/code/game/gamemodes/events/black_hole.dm +++ b/code/game/gamemodes/events/black_hole.dm @@ -1,88 +1,88 @@ -/obj/effect/bhole - name = "black hole" - icon = 'icons/obj/objects.dmi' - desc = "FUCK FUCK FUCK AAAHHH" - icon_state = "bhole3" - opacity = 1 - unacidable = 1 - density = 0 - anchored = 1 - -/obj/effect/bhole/New() - spawn(4) - controller() - -/obj/effect/bhole/proc/controller() - while(src) - - if(!isturf(loc)) - del(src) - return - - //DESTROYING STUFF AT THE EPICENTER - for(var/mob/living/M in orange(1,src)) - del(M) - for(var/obj/O in orange(1,src)) - del(O) - for(var/turf/simulated/ST in orange(1,src)) - ST.ChangeTurf(/turf/space) - - sleep(6) - grav(10, 4, 10, 0 ) - sleep(6) - grav( 8, 4, 10, 0 ) - sleep(6) - grav( 9, 4, 10, 0 ) - sleep(6) - grav( 7, 3, 40, 1 ) - sleep(6) - grav( 5, 3, 40, 1 ) - sleep(6) - grav( 6, 3, 40, 1 ) - sleep(6) - grav( 4, 2, 50, 6 ) - sleep(6) - grav( 3, 2, 50, 6 ) - sleep(6) - grav( 2, 2, 75,25 ) - sleep(6) - - - - //MOVEMENT - if( prob(50) ) - src.anchored = 0 - step(src,pick(alldirs)) - src.anchored = 1 - -/obj/effect/bhole/proc/grav(var/r, var/ex_act_force, var/pull_chance, var/turf_removal_chance) - if(!isturf(loc)) //blackhole cannot be contained inside anything. Weird stuff might happen - del(src) - return - for(var/t = -r, t < r, t++) - affect_coord(x+t, y-r, ex_act_force, pull_chance, turf_removal_chance) - affect_coord(x-t, y+r, ex_act_force, pull_chance, turf_removal_chance) - affect_coord(x+r, y+t, ex_act_force, pull_chance, turf_removal_chance) - affect_coord(x-r, y-t, ex_act_force, pull_chance, turf_removal_chance) - return - -/obj/effect/bhole/proc/affect_coord(var/x, var/y, var/ex_act_force, var/pull_chance, var/turf_removal_chance) - //Get turf at coordinate - var/turf/T = locate(x, y, z) - if(isnull(T)) return - - //Pulling and/or ex_act-ing movable atoms in that turf - if( prob(pull_chance) ) - for(var/obj/O in T.contents) - if(O.anchored) - O.ex_act(ex_act_force) - else - step_towards(O,src) - for(var/mob/living/M in T.contents) - step_towards(M,src) - - //Destroying the turf - if( T && istype(T,/turf/simulated) && prob(turf_removal_chance) ) - var/turf/simulated/ST = T - ST.ChangeTurf(/turf/space) +/obj/effect/bhole + name = "black hole" + icon = 'icons/obj/objects.dmi' + desc = "FUCK FUCK FUCK AAAHHH" + icon_state = "bhole3" + opacity = 1 + unacidable = 1 + density = 0 + anchored = 1 + +/obj/effect/bhole/New() + spawn(4) + controller() + +/obj/effect/bhole/proc/controller() + while(src) + + if(!isturf(loc)) + qdel(src) + return + + //DESTROYING STUFF AT THE EPICENTER + for(var/mob/living/M in orange(1,src)) + qdel(M) + for(var/obj/O in orange(1,src)) + qdel(O) + for(var/turf/simulated/ST in orange(1,src)) + ST.ChangeTurf(/turf/space) + + sleep(6) + grav(10, 4, 10, 0 ) + sleep(6) + grav( 8, 4, 10, 0 ) + sleep(6) + grav( 9, 4, 10, 0 ) + sleep(6) + grav( 7, 3, 40, 1 ) + sleep(6) + grav( 5, 3, 40, 1 ) + sleep(6) + grav( 6, 3, 40, 1 ) + sleep(6) + grav( 4, 2, 50, 6 ) + sleep(6) + grav( 3, 2, 50, 6 ) + sleep(6) + grav( 2, 2, 75,25 ) + sleep(6) + + + + //MOVEMENT + if( prob(50) ) + src.anchored = 0 + step(src,pick(alldirs)) + src.anchored = 1 + +/obj/effect/bhole/proc/grav(var/r, var/ex_act_force, var/pull_chance, var/turf_removal_chance) + if(!isturf(loc)) //blackhole cannot be contained inside anything. Weird stuff might happen + qdel(src) + return + for(var/t = -r, t < r, t++) + affect_coord(x+t, y-r, ex_act_force, pull_chance, turf_removal_chance) + affect_coord(x-t, y+r, ex_act_force, pull_chance, turf_removal_chance) + affect_coord(x+r, y+t, ex_act_force, pull_chance, turf_removal_chance) + affect_coord(x-r, y-t, ex_act_force, pull_chance, turf_removal_chance) + return + +/obj/effect/bhole/proc/affect_coord(var/x, var/y, var/ex_act_force, var/pull_chance, var/turf_removal_chance) + //Get turf at coordinate + var/turf/T = locate(x, y, z) + if(isnull(T)) return + + //Pulling and/or ex_act-ing movable atoms in that turf + if( prob(pull_chance) ) + for(var/obj/O in T.contents) + if(O.anchored) + O.ex_act(ex_act_force) + else + step_towards(O,src) + for(var/mob/living/M in T.contents) + step_towards(M,src) + + //Destroying the turf + if( T && istype(T,/turf/simulated) && prob(turf_removal_chance) ) + var/turf/simulated/ST = T + ST.ChangeTurf(/turf/space) return \ No newline at end of file diff --git a/code/game/gamemodes/events/clang.dm b/code/game/gamemodes/events/clang.dm index 7f4f6f70201..74fb9ee5079 100644 --- a/code/game/gamemodes/events/clang.dm +++ b/code/game/gamemodes/events/clang.dm @@ -36,7 +36,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 if(clong.density || prob(10)) clong.meteorhit(src) else - del(src) + qdel(src) if(clong && prob(25)) src.loc = clong.loc @@ -81,7 +81,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 if (isNotStationLevel(immrod.z)) immrod.z = pick(config.station_levels) if(immrod.loc == end) - del(immrod) + qdel(immrod) sleep(10) for(var/obj/effect/immovablerod/imm in world) return diff --git a/code/game/gamemodes/events/dust.dm b/code/game/gamemodes/events/dust.dm index f2c510b9b98..4e064d8be6f 100644 --- a/code/game/gamemodes/events/dust.dm +++ b/code/game/gamemodes/events/dust.dm @@ -37,7 +37,7 @@ The "dust" will damage the hull of the station causin minor hull breaches. density = 1 anchored = 1 var/strength = 2 //ex_act severity number - var/life = 2 //how many things we hit before del(src) + var/life = 2 //how many things we hit before qdel(src) weak strength = 3 @@ -80,10 +80,11 @@ The "dust" will damage the hull of the station causin minor hull breaches. startx = (TRANSITIONEDGE+1) endy = rand(TRANSITIONEDGE,world.maxy-TRANSITIONEDGE) endx = world.maxx-TRANSITIONEDGE - var/goal = locate(endx, endy, 1) + var/z_level = pick(config.station_levels) + var/goal = locate(endx, endy, z_level) src.x = startx src.y = starty - src.z = pick(config.station_levels) + src.z = z_level spawn(0) walk_towards(src, goal, 1) return @@ -106,8 +107,7 @@ The "dust" will damage the hull of the station causin minor hull breaches. life-- if(life <= 0) walk(src,0) - spawn(1) - del(src) + qdel(src) return 0 return @@ -118,5 +118,5 @@ The "dust" will damage the hull of the station causin minor hull breaches. ex_act(severity) - del(src) + qdel(src) return diff --git a/code/game/gamemodes/events/holidays/Christmas.dm b/code/game/gamemodes/events/holidays/Christmas.dm index 7ca66789023..9c68ab879ee 100644 --- a/code/game/gamemodes/events/holidays/Christmas.dm +++ b/code/game/gamemodes/events/holidays/Christmas.dm @@ -14,7 +14,7 @@ evil_tree.icon_living = evil_tree.icon_state evil_tree.icon_dead = evil_tree.icon_state evil_tree.icon_gib = evil_tree.icon_state - del(xmas) + qdel(xmas) /obj/item/weapon/toy/xmas_cracker name = "xmas cracker" diff --git a/code/game/gamemodes/events/wormholes.dm b/code/game/gamemodes/events/wormholes.dm index 9a8066887b9..a7830a2cb3e 100644 --- a/code/game/gamemodes/events/wormholes.dm +++ b/code/game/gamemodes/events/wormholes.dm @@ -59,4 +59,4 @@ P.icon_state = "anom" P.name = "wormhole" spawn(rand(300,600)) - del(P) \ No newline at end of file + qdel(P) \ No newline at end of file diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 544776d1447..34a57a0768b 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -1,11 +1,5 @@ var/global/datum/controller/gameticker/ticker -#define GAME_STATE_PREGAME 1 -#define GAME_STATE_SETTING_UP 2 -#define GAME_STATE_PLAYING 3 -#define GAME_STATE_FINISHED 4 - - /datum/controller/gameticker var/const/restart_timeout = 600 var/current_state = GAME_STATE_PREGAME @@ -98,8 +92,8 @@ var/global/datum/controller/gameticker/ticker src.mode = config.pick_mode(master_mode) if(!mode_started && !src.mode.can_start()) world << "Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby." - del(mode) current_state = GAME_STATE_PREGAME + mode = null job_master.ResetOccupations() return 0 @@ -116,11 +110,11 @@ var/global/datum/controller/gameticker/ticker else src.mode.announce() + current_state = GAME_STATE_PLAYING create_characters() //Create player characters and transfer them collect_minds() equip_characters() data_core.manifest() - current_state = GAME_STATE_PLAYING callHook("roundstart") @@ -135,7 +129,7 @@ var/global/datum/controller/gameticker/ticker for(var/obj/effect/landmark/start/S in landmarks_list) //Deleting Startpoints but we need the ai point to AI-ize people later if (S.name != "AI") - del(S) + qdel(S) world << "Enjoy the game!" world << sound('sound/AI/welcome.ogg') // Skie //Holiday Round-start stuff ~Carn @@ -161,7 +155,6 @@ var/global/datum/controller/gameticker/ticker for(var/obj/multiz/ladder/L in world) L.connect() //Lazy hackfix for ladders. TODO: move this to an actual controller. ~ Z if(config.sql_enabled) - spawn(3000) statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE return 1 @@ -265,8 +258,8 @@ var/global/datum/controller/gameticker/ticker //Otherwise if its a verb it will continue on afterwards. sleep(300) - if(cinematic) del(cinematic) //end the cinematic - if(temp_buckle) del(temp_buckle) //release everybody + if(cinematic) qdel(cinematic) //end the cinematic + if(temp_buckle) qdel(temp_buckle) //release everybody return @@ -280,7 +273,7 @@ var/global/datum/controller/gameticker/ticker continue else player.create_character() - del(player) + qdel(player) proc/collect_minds() @@ -298,7 +291,7 @@ var/global/datum/controller/gameticker/ticker if(player.mind.assigned_role != "MODE") job_master.EquipRank(player, player.mind.assigned_role, 0) UpdateFactionList(player) - EquipCustomItems(player) + equip_custom_items(player) if(captainless) for(var/mob/M in player_list) if(!istype(M,/mob/new_player)) @@ -424,7 +417,7 @@ var/global/datum/controller/gameticker/ticker robo.laws.show_laws(world) if(dronecount) - world << "There [dronecount>1 ? "were" : "was"] [dronecount] industrious maintenance [dronecount>1 ? "drones" : "drone"] at the end of this round." + world << "There [dronecount>1 ? "were" : "was"] [dronecount] industrious maintenance [dronecount>1 ? "drones" : "drone"] at the end of this round." mode.declare_completion()//To declare normal completion. diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index f1de61f2865..7e1ba6d3684 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -26,6 +26,6 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' var/area/skipjack = locate(/area/shuttle/skipjack/station) for (var/mob/living/M in skipjack.contents) //maybe send the player a message that they've gone home/been kidnapped? Someone responsible for vox lore should write that. - del(M) + qdel(M) for (var/obj/O in skipjack.contents) - del(O) //no hiding in lockers or anything \ No newline at end of file + qdel(O) //no hiding in lockers or anything \ No newline at end of file diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index c523b469f3f..850529661cc 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -89,7 +89,7 @@ rcd light flash thingy on matter drain V.show_message("\blue You hear a loud electrical buzzing sound!", 2) spawn(50) explosion(get_turf(M), 0,1,2,3) - del(M) + qdel(M) else usr << "Out of uses." else usr << "That's not a machine." diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm index 2629b360139..2aa512264df 100644 --- a/code/game/gamemodes/meme/meme.dm +++ b/code/game/gamemodes/meme/meme.dm @@ -93,7 +93,7 @@ M.enter_host(first_host.current) forge_meme_objectives(meme, first_host) - del original + qdel(original) log_admin("Created [memes.len] memes.") diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index 1edb533daaa..9d18216aa53 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -97,6 +97,10 @@ pass_flags = PASSTABLE | PASSGRILLE power = 2 +/obj/effect/meteor/Destroy() + walk(src,0) //this cancels the walk_towards() proc + ..() + /obj/effect/meteor/Bump(atom/A) spawn(0) @@ -111,14 +115,14 @@ !istype(A,/obj/machinery/field_generator) && \ prob(detonation_chance)) explosion(loc, power, power + power_step, power + power_step * 2, power + power_step * 3, 0) - del(src) + qdel(src) return /obj/effect/meteor/ex_act(severity) if (severity < 4) - del(src) + qdel(src) return /obj/effect/meteor/big @@ -136,7 +140,7 @@ if(!istype(A,/obj/machinery/power/emitter) && \ !istype(A,/obj/machinery/field_generator)) if(--src.hits <= 0) - del(src) //Dont blow up singularity containment if we get stuck there. + qdel(src) //Dont blow up singularity containment if we get stuck there. if (A) for(var/mob/M in player_list) @@ -150,11 +154,11 @@ if (--src.hits <= 0) if(prob(detonation_chance) && !istype(A, /obj/structure/grille)) explosion(loc, power, power + power_step, power + power_step * 2, power + power_step * 3, 0) - del(src) + qdel(src) return /obj/effect/meteor/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/pickaxe)) - del(src) + qdel(src) return - ..() \ No newline at end of file + ..() diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index d26f1a07892..530b9b9567b 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -8,7 +8,7 @@ item_state = "electronic" throw_speed = 4 throw_range = 20 - matter = list("metal" = 500) + matter = list(DEFAULT_WALL_MATERIAL = 500) var/obj/item/weapon/disk/nuclear/the_disk = null var/active = 0 @@ -48,6 +48,9 @@ if(bomb.timing) user << "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]" +/obj/item/weapon/pinpointer/Destroy() + active = 0 + ..() /obj/item/weapon/pinpointer/advpinpointer name = "Advanced Pinpointer" diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 27236dd8fbf..d13f90d2be4 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -13,7 +13,7 @@ datum/objective if(text) explanation_text = text - Del() + Destroy() all_objectives -= src ..() @@ -541,7 +541,7 @@ datum/objective/steal if (!custom_target) return var/tmp_obj = new custom_target var/custom_name = tmp_obj:name - del(tmp_obj) + qdel(tmp_obj) custom_name = sanitize(input("Enter target name:", "Objective target", custom_name) as text|null) if (!custom_name) return target_name = custom_name @@ -798,7 +798,7 @@ datum/objective/heist/salvage choose_target() switch(rand(1,8)) if(1) - target = "metal" + target = DEFAULT_WALL_MATERIAL target_amount = 300 if(2) target = "glass" @@ -916,7 +916,7 @@ datum/objective/heist/salvage explanation_text = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it. The convert rune is join blood self." /datum/objective/cult/eldergod/check_completion() - return (locate(/obj/machinery/singularity/narsie/large) in machines) + return (locate(/obj/singularity/narsie/large) in machines) /datum/objective/cult/sacrifice explanation_text = "Conduct a ritual sacrifice for the glory of Nar-Sie." diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index 439befdc63a..ad2abb22360 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -120,7 +120,7 @@ datum/hSB if("hsbtoolbox") var/obj/item/weapon/storage/hsb = new/obj/item/weapon/storage/toolbox/mechanical for(var/obj/item/device/radio/T in hsb) - del(T) + qdel(T) new/obj/item/weapon/crowbar (hsb) hsb.loc = usr.loc if("hsbmedkit") diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm index 501335a19ff..3c029d52980 100644 --- a/code/game/gamemodes/setupgame.dm +++ b/code/game/gamemodes/setupgame.dm @@ -24,44 +24,6 @@ if (prob(75)) DIFFMUT = rand(0,20) - /* Old, for reference (so I don't accidentally activate something) - N3X - var/list/avnums = new/list() - var/tempnum - - avnums.Add(2) - avnums.Add(12) - avnums.Add(10) - avnums.Add(8) - avnums.Add(4) - avnums.Add(11) - avnums.Add(13) - avnums.Add(6) - - tempnum = pick(avnums) - avnums.Remove(tempnum) - HULKBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - TELEBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - FIREBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - XRAYBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - CLUMSYBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - FAKEBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - DEAFBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - BLINDBLOCK = tempnum - */ var/list/numsToAssign=new() for(var/i=1;i