mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-17 02:47:58 +01:00
Merge pull request #1874 from Lohikar/asteroid-gen-2
Development merge + Asteroid gen speed-up
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
# baystation12
|
||||
# Aurorastation
|
||||
|
||||
[Website](http://baystation12.net/) - [Code](http://github.com/Baystation12/Baystation12/) - [IRC](http://baystation12.net/forums/viewtopic.php?f=12&t=5088)
|
||||
[Website](https://aurorastation.org/) - [Code](https://github.com/Aurorastation/Aurora.3)
|
||||
|
||||
---
|
||||
|
||||
### LICENSE
|
||||
Baystation12 is licensed under the GNU Affero General Public License version 3, which can be found in full in LICENSE-AGPL3.txt.
|
||||
Aurorastation is licensed under the GNU Affero General Public License version 3, which can be found in full in LICENSE-AGPL3.txt.
|
||||
|
||||
Commits with a git authorship date prior to `1420675200 +0000` (2015/01/08 00:00) are licensed under the GNU General Public License version 3, which can be found in full in LICENSE-GPL3.txt.
|
||||
|
||||
@@ -18,11 +18,11 @@ See [here](https://www.gnu.org/licenses/why-affero-gpl.html) for more informatio
|
||||
### GETTING THE CODE
|
||||
The simplest way to obtain the code is using the github .zip feature.
|
||||
|
||||
Click [here](https://github.com/Baystation12/Baystation12/archive/master.zip) to get the latest code as a .zip file, then unzip it to wherever you want.
|
||||
Click [here](https://github.com/Aurorastation/Aurora.3/archive/master.zip) to get the latest stable code as a .zip file, then unzip it to wherever you want.
|
||||
|
||||
The more complicated and easier to update method is using git. You'll need to download git or some client from [here](http://git-scm.com/). When that's installed, right click in any folder and click on "Git Bash". When that opens, type in:
|
||||
|
||||
git clone https://github.com/Baystation12/Baystation12.git
|
||||
git clone https://github.com/Aurorastation/Aurora.3.git
|
||||
|
||||
(hint: hold down ctrl and press insert to paste into git bash)
|
||||
|
||||
@@ -30,7 +30,7 @@ This will take a while to download, but it provides an easier method for updatin
|
||||
|
||||
Once the repository is in place, run this command:
|
||||
```bash
|
||||
cd Baystation12
|
||||
cd Aurora.3
|
||||
git update-index --assume-unchanged baystation12.int
|
||||
```
|
||||
Now git will ignore changes to the file baystation12.int.
|
||||
@@ -45,7 +45,7 @@ This is a sourcecode-only release, so the next step is to compile the server fil
|
||||
|
||||
baystation12.dmb - 0 errors, 0 warnings
|
||||
|
||||
If you see any errors or warnings, something has gone wrong - possibly a corrupt download or the files extracted wrong, or a code issue on the main repo. Ask on IRC.
|
||||
If you see any errors or warnings, something has gone wrong - possibly a corrupt download or the files extracted wrong, or a code issue on the main repo. Ask on the server Discord if you're completely lost.
|
||||
|
||||
Once that's done, open up the config folder. You'll want to edit config.txt to set the probabilities for different gamemodes in Secret and to set your server location so that all your players don't get disconnected at the end of each round. It's recommended you don't turn on the gamemodes with probability 0, as they have various issues and aren't currently being tested, so they may have unknown and bizarre bugs.
|
||||
|
||||
@@ -78,16 +78,12 @@ When you have done this, you'll need to recompile the code, but then it should w
|
||||
|
||||
### Configuration
|
||||
|
||||
For a basic setup, simply copy every file from config/example to config.
|
||||
For a basic setup, simply copy every file from config/example to config.
|
||||
|
||||
For more advanced setups, setting the server `tick_lag` in the config as well as configuring SQL are good first steps.
|
||||
|
||||
---
|
||||
|
||||
### SQL Setup
|
||||
|
||||
The SQL backend for the library and stats tracking requires a MySQL server. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql. More detailed setup instructions arecoming soon, for now ask in our IRC channel.
|
||||
|
||||
---
|
||||
|
||||
### IRC Bot Setup
|
||||
|
||||
Included in the repo is an IRC bot capable of relaying adminhelps to a specified IRC channel/server (thanks to Skibiliano). Instructions for bot setup are included in the /bot/ folder along with the bot/relay script itself.
|
||||
The SQL backend for the library and stats tracking requires a MySQL server, as does the optional SQL saves system. Your server details go in config/dbconfig.txt, and initial database setup is done with [flyway](https://flywaydb.org/). Detailed instructions can be found [here](https://github.com/Aurorastation/Aurora.3/tree/master/SQL).
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
-- They are not needed for normal server operation.
|
||||
|
||||
CREATE TABLE `ss13dbg_lighting` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`time` INT(11) NULL DEFAULT NULL COMMENT 'World time (in ticks)',
|
||||
`type` VARCHAR(32) NULL DEFAULT NULL COMMENT 'The type of the update.',
|
||||
`name` VARCHAR(50) NULL DEFAULT NULL COMMENT 'The callee\'s name.',
|
||||
`loc_name` VARCHAR(50) NULL DEFAULT NULL COMMENT 'The callee\'s location.',
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`time` INT(11) UNSIGNED NULL DEFAULT NULL COMMENT 'World time (in ticks)',
|
||||
`tick_usage` DOUBLE UNSIGNED NULL DEFAULT NULL,
|
||||
`type` VARCHAR(32) NULL DEFAULT NULL COMMENT 'The type of the update.' COLLATE 'latin1_bin',
|
||||
`name` VARCHAR(50) NULL DEFAULT NULL COMMENT 'The callee\'s name.' COLLATE 'latin1_bin',
|
||||
`loc_name` VARCHAR(50) NULL DEFAULT NULL COMMENT 'The callee\'s location.' COLLATE 'latin1_bin',
|
||||
`x` SMALLINT(6) NULL DEFAULT NULL,
|
||||
`y` SMALLINT(6) NULL DEFAULT NULL,
|
||||
`z` SMALLINT(6) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
COLLATE='utf8_general_ci'
|
||||
COLLATE='latin1_bin'
|
||||
ENGINE=MEMORY
|
||||
ROW_FORMAT=FIXED;
|
||||
|
||||
+50
-3
@@ -29,6 +29,7 @@
|
||||
#include "code\__defines\lighting.dm"
|
||||
#include "code\__defines\machinery.dm"
|
||||
#include "code\__defines\math_physics.dm"
|
||||
#include "code\__defines\mining.dm"
|
||||
#include "code\__defines\misc.dm"
|
||||
#include "code\__defines\mobs.dm"
|
||||
#include "code\__defines\process_scheduler.dm"
|
||||
@@ -124,6 +125,7 @@
|
||||
#include "code\controllers\emergency_shuttle_controller.dm"
|
||||
#include "code\controllers\hooks-defs.dm"
|
||||
#include "code\controllers\hooks.dm"
|
||||
#include "code\controllers\law.dm"
|
||||
#include "code\controllers\master_controller.dm"
|
||||
#include "code\controllers\shuttle_controller.dm"
|
||||
#include "code\controllers\subsystems.dm"
|
||||
@@ -134,12 +136,12 @@
|
||||
#include "code\controllers\Processes\arrivalShuttle.dm"
|
||||
#include "code\controllers\Processes\chemistry.dm"
|
||||
#include "code\controllers\Processes\disease.dm"
|
||||
#include "code\controllers\Processes\effects.dm"
|
||||
#include "code\controllers\Processes\emergencyShuttle.dm"
|
||||
#include "code\controllers\Processes\event.dm"
|
||||
#include "code\controllers\Processes\explosives.dm"
|
||||
#include "code\controllers\Processes\garbage.dm"
|
||||
#include "code\controllers\Processes\inactivity.dm"
|
||||
#include "code\controllers\Processes\law.dm"
|
||||
#include "code\controllers\Processes\lighting.dm"
|
||||
#include "code\controllers\Processes\machinery.dm"
|
||||
#include "code\controllers\Processes\mob.dm"
|
||||
@@ -170,7 +172,6 @@
|
||||
#include "code\datums\mind.dm"
|
||||
#include "code\datums\mixed.dm"
|
||||
#include "code\datums\modules.dm"
|
||||
#include "code\datums\recipe.dm"
|
||||
#include "code\datums\server_greeting.dm"
|
||||
#include "code\datums\sun.dm"
|
||||
#include "code\datums\supplypacks.dm"
|
||||
@@ -534,10 +535,13 @@
|
||||
#include "code\game\machinery\kitchen\icecream.dm"
|
||||
#include "code\game\machinery\kitchen\microwave.dm"
|
||||
#include "code\game\machinery\kitchen\smartfridge.dm"
|
||||
#include "code\game\machinery\kitchen\cooking_machines\_appliance.dm"
|
||||
#include "code\game\machinery\kitchen\cooking_machines\_cooker.dm"
|
||||
#include "code\game\machinery\kitchen\cooking_machines\_cooker_output.dm"
|
||||
#include "code\game\machinery\kitchen\cooking_machines\_mixer.dm"
|
||||
#include "code\game\machinery\kitchen\cooking_machines\candy.dm"
|
||||
#include "code\game\machinery\kitchen\cooking_machines\cereal.dm"
|
||||
#include "code\game\machinery\kitchen\cooking_machines\container.dm"
|
||||
#include "code\game\machinery\kitchen\cooking_machines\fryer.dm"
|
||||
#include "code\game\machinery\kitchen\cooking_machines\grill.dm"
|
||||
#include "code\game\machinery\kitchen\cooking_machines\oven.dm"
|
||||
@@ -1172,6 +1176,11 @@
|
||||
#include "code\modules\economy\Events.dm"
|
||||
#include "code\modules\economy\Events_Mundane.dm"
|
||||
#include "code\modules\economy\TradeDestinations.dm"
|
||||
#include "code\modules\effects\effect_system.dm"
|
||||
#include "code\modules\effects\visual_effect.dm"
|
||||
#include "code\modules\effects\sparks\procs.dm"
|
||||
#include "code\modules\effects\sparks\spawner.dm"
|
||||
#include "code\modules\effects\sparks\visuals.dm"
|
||||
#include "code\modules\events\apc_damage.dm"
|
||||
#include "code\modules\events\bear_attack.dm"
|
||||
#include "code\modules\events\blob.dm"
|
||||
@@ -1223,7 +1232,10 @@
|
||||
#include "code\modules\flufftext\Dreaming.dm"
|
||||
#include "code\modules\flufftext\Hallucination.dm"
|
||||
#include "code\modules\flufftext\TextFilters.dm"
|
||||
#include "code\modules\food\recipe.dm"
|
||||
#include "code\modules\food\recipes_fryer.dm"
|
||||
#include "code\modules\food\recipes_microwave.dm"
|
||||
#include "code\modules\food\recipes_oven.dm"
|
||||
#include "code\modules\games\boardgame.dm"
|
||||
#include "code\modules\games\cardemon.dm"
|
||||
#include "code\modules\games\cards.dm"
|
||||
@@ -1276,6 +1288,7 @@
|
||||
#include "code\modules\lighting\lighting_setup.dm"
|
||||
#include "code\modules\lighting\lighting_source.dm"
|
||||
#include "code\modules\lighting\lighting_turf.dm"
|
||||
#include "code\modules\lighting\lighting_verbs.dm"
|
||||
#include "code\modules\lighting\~lighting_undefs.dm"
|
||||
#include "code\modules\liquid\splash_simulation.dm"
|
||||
#include "code\modules\maps\dmm_suite.dm"
|
||||
@@ -1535,6 +1548,7 @@
|
||||
#include "code\modules\mob\living\simple_animal\borer\say.dm"
|
||||
#include "code\modules\mob\living\simple_animal\constructs\constructs.dm"
|
||||
#include "code\modules\mob\living\simple_animal\constructs\soulstone.dm"
|
||||
#include "code\modules\mob\living\simple_animal\familiars\familiars.dm"
|
||||
#include "code\modules\mob\living\simple_animal\friendly\cat.dm"
|
||||
#include "code\modules\mob\living\simple_animal\friendly\corgi.dm"
|
||||
#include "code\modules\mob\living\simple_animal\friendly\crab.dm"
|
||||
@@ -1562,6 +1576,9 @@
|
||||
#include "code\modules\mob\living\simple_animal\hostile\syndicate.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\tree.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\retaliate\cavern.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\commanded\_command_defines.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\commanded\bear_companion.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\commanded\commanded.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\retaliate\drone.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm"
|
||||
@@ -1755,6 +1772,7 @@
|
||||
#include "code\modules\projectiles\guns\projectile.dm"
|
||||
#include "code\modules\projectiles\guns\energy\laser.dm"
|
||||
#include "code\modules\projectiles\guns\energy\lawgiver.dm"
|
||||
#include "code\modules\projectiles\guns\energy\magic.dm"
|
||||
#include "code\modules\projectiles\guns\energy\nuclear.dm"
|
||||
#include "code\modules\projectiles\guns\energy\pulse.dm"
|
||||
#include "code\modules\projectiles\guns\energy\rifle.dm"
|
||||
@@ -1963,11 +1981,15 @@
|
||||
#include "code\modules\shuttles\shuttles_multi.dm"
|
||||
#include "code\modules\spells\artifacts.dm"
|
||||
#include "code\modules\spells\construct_spells.dm"
|
||||
#include "code\modules\spells\contracts.dm"
|
||||
#include "code\modules\spells\monster_manual.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\spell_verb.dm"
|
||||
#include "code\modules\spells\spellbook.dm"
|
||||
#include "code\modules\spells\spells.dm"
|
||||
#include "code\modules\spells\storage.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"
|
||||
@@ -1977,23 +1999,48 @@
|
||||
#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\druidic_spells.dm"
|
||||
#include "code\modules\spells\aoe_turf\conjure\forcewall.dm"
|
||||
#include "code\modules\spells\aoe_turf\conjure\grove.dm"
|
||||
#include "code\modules\spells\general\area_teleport.dm"
|
||||
#include "code\modules\spells\general\contract_spells.dm"
|
||||
#include "code\modules\spells\general\mark_recall.dm"
|
||||
#include "code\modules\spells\general\return_master.dm"
|
||||
#include "code\modules\spells\general\rune_write.dm"
|
||||
#include "code\modules\spells\hand\hand.dm"
|
||||
#include "code\modules\spells\hand\hand_item.dm"
|
||||
#include "code\modules\spells\spellbook\battlemage.dm"
|
||||
#include "code\modules\spells\spellbook\cleric.dm"
|
||||
#include "code\modules\spells\spellbook\druid.dm"
|
||||
#include "code\modules\spells\spellbook\necromancer.dm"
|
||||
#include "code\modules\spells\spellbook\spatial.dm"
|
||||
#include "code\modules\spells\spellbook\standard.dm"
|
||||
#include "code\modules\spells\spellbook\student.dm"
|
||||
#include "code\modules\spells\targeted\cleric_spells.dm"
|
||||
#include "code\modules\spells\targeted\entangle.dm"
|
||||
#include "code\modules\spells\targeted\ethereal_jaunt.dm"
|
||||
#include "code\modules\spells\targeted\genetic.dm"
|
||||
#include "code\modules\spells\targeted\harvest.dm"
|
||||
#include "code\modules\spells\targeted\mind_transfer.dm"
|
||||
#include "code\modules\spells\targeted\necromancer_spells.dm"
|
||||
#include "code\modules\spells\targeted\shapeshift.dm"
|
||||
#include "code\modules\spells\targeted\shift.dm"
|
||||
#include "code\modules\spells\targeted\subjugate.dm"
|
||||
#include "code\modules\spells\targeted\swap.dm"
|
||||
#include "code\modules\spells\targeted\targeted.dm"
|
||||
#include "code\modules\spells\targeted\torment.dm"
|
||||
#include "code\modules\spells\targeted\equip\equip.dm"
|
||||
#include "code\modules\spells\targeted\equip\holy_relic.dm"
|
||||
#include "code\modules\spells\targeted\equip\horsemask.dm"
|
||||
#include "code\modules\spells\targeted\equip\remove_horsemask.dm"
|
||||
#include "code\modules\spells\targeted\equip\party_hardy.dm"
|
||||
#include "code\modules\spells\targeted\equip\seed.dm"
|
||||
#include "code\modules\spells\targeted\equip\shield.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\passage.dm"
|
||||
#include "code\modules\spells\targeted\projectile\projectile.dm"
|
||||
#include "code\modules\spells\targeted\projectile\stuncuff.dm"
|
||||
#include "code\modules\supermatter\setup_supermatter.dm"
|
||||
#include "code\modules\supermatter\supermatter.dm"
|
||||
#include "code\modules\surgery\_defines.dm"
|
||||
|
||||
+3
-3
@@ -137,13 +137,13 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
|
||||
if(firelevel > 6)
|
||||
icon_state = "3"
|
||||
set_light(7, FIRE_LIGHT_3, update_type = UPDATE_NONE) // We set color later in the proc, that should trigger an update.
|
||||
set_light(7, FIRE_LIGHT_3, no_update = TRUE) // We set color later in the proc, that should trigger an update.
|
||||
else if(firelevel > 2.5)
|
||||
icon_state = "2"
|
||||
set_light(5, FIRE_LIGHT_2, update_type = UPDATE_NONE)
|
||||
set_light(5, FIRE_LIGHT_2, no_update = TRUE)
|
||||
else
|
||||
icon_state = "1"
|
||||
set_light(3, FIRE_LIGHT_1, update_type = UPDATE_NONE)
|
||||
set_light(3, FIRE_LIGHT_1, no_update = TRUE)
|
||||
|
||||
for(var/mob/living/L in loc)
|
||||
L.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure()) //Burn the mobs!
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#define LIGHTING_INTERVAL 1 // Frequency, in 1/10ths of a second, of the lighting process.
|
||||
#define LIGHTING_INTERVAL 2 // Frequency, in 1/10ths of a second, of the lighting process.
|
||||
|
||||
#define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone
|
||||
#define LIGHTING_ROUND_VALUE 1 / 128 //Value used to round lumcounts, values smaller than 1/255 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY.
|
||||
|
||||
#define LIGHTING_ICON 'icons/effects/lighting_overlay.png' // icon used for lighting shading effects
|
||||
#define DARKNESS_ICON 'icons/effects/darkness.png'
|
||||
|
||||
#define LIGHTING_SOFT_THRESHOLD 0.001 // If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting overlays.
|
||||
|
||||
@@ -52,6 +51,7 @@
|
||||
#define LIGHT_COLOR_YELLOW "#E1E17D" //Dimmed yellow, leaning kaki. rgb(225, 225, 125)
|
||||
#define LIGHT_COLOR_BROWN "#966432" //Clear brown, mostly dim. rgb(150, 100, 50)
|
||||
#define LIGHT_COLOR_ORANGE "#FA9632" //Mostly pure orange. rgb(250, 150, 50)
|
||||
#define LIGHT_COLOR_PURPLE "#A97FAA" //Soft purple. rgb(169, 127, 170)
|
||||
|
||||
//These ones aren't a direct colour like the ones above, because nothing would fit
|
||||
#define LIGHT_COLOR_FIRE "#FAA019" //Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25)
|
||||
@@ -66,18 +66,22 @@
|
||||
#define LIGHT_BROKEN 2
|
||||
#define LIGHT_BURNED 3
|
||||
|
||||
// Some angle presets for directional lighting.
|
||||
#define LIGHT_OMNI null
|
||||
#define LIGHT_SEMI 180
|
||||
#define LIGHT_WIDE 90
|
||||
#define LIGHT_NARROW 45
|
||||
|
||||
// Night lighting controller times
|
||||
// The time (in ticks based on worldtime2ticks()) that various actions trigger
|
||||
#define MORNING_LIGHT_RESET 252000 // 7am or 07:00 - lighting restores to normal in morning
|
||||
#define NIGHT_LIGHT_ACTIVE 648000 // 6pm or 18:00 - night lighting mode activates
|
||||
|
||||
// Update type flags.
|
||||
#define UPDATE_SCHEDULE 0 // Default behavior. Schedule an update with lighting process.
|
||||
#define UPDATE_NOW 1 // Update right now, fuck the scheduler. May cause lag.
|
||||
#define UPDATE_NONE 2 // Don't trigger an update at all. Useful if you're triggering the update manually.
|
||||
|
||||
// Some brightness/range defines for objects.
|
||||
#define L_WALLMOUNT_POWER 0.4
|
||||
#define L_WALLMOUNT_RANGE 2
|
||||
#define L_WALLMOUNT_HI_POWER 2 // For red/delta alert on fire alarms.
|
||||
#define L_WALLMOUNT_HI_RANGE 4
|
||||
|
||||
// Just so we can avoid unneeded proc calls when profiling is disabled.
|
||||
#define L_PROF(O,T) if (lighting_profiling) {lprof_write(O,T);}
|
||||
|
||||
@@ -96,3 +96,12 @@ var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret
|
||||
#define ATMOS_DEFAULT_VOLUME_FILTER 200 // L.
|
||||
#define ATMOS_DEFAULT_VOLUME_MIXER 200 // L.
|
||||
#define ATMOS_DEFAULT_VOLUME_PIPE 70 // L.
|
||||
|
||||
|
||||
// Misc process flags.
|
||||
#define M_PROCESSES 0x1
|
||||
#define M_USES_POWER 0x2
|
||||
|
||||
// If this is returned from a machine's process() proc, the machine will stop processing but
|
||||
// will continue to have power calculations done.
|
||||
#define M_NO_PROCESS 27
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#define ORE_URANIUM "uranium"
|
||||
#define ORE_IRON "iron"
|
||||
#define ORE_COAL "coal"
|
||||
#define ORE_SAND "sand"
|
||||
#define ORE_PHORON "phoron"
|
||||
#define ORE_SILVER "silver"
|
||||
#define ORE_GOLD "gold"
|
||||
#define ORE_DIAMOND "diamond"
|
||||
#define ORE_PLATINUM "platinum"
|
||||
#define ORE_HYDROGEN "mhydrogen"
|
||||
@@ -269,3 +269,27 @@
|
||||
#define TICK_LIMIT 80
|
||||
#define TICK_CHECK ( world.tick_usage > TICK_LIMIT ? stoplag() : 0 )
|
||||
#define CHECK_TICK if (world.tick_usage > TICK_LIMIT) stoplag()
|
||||
|
||||
// Effect Systems.
|
||||
#define EFFECT_CONTINUE 0 // Keep processing.
|
||||
#define EFFECT_HALT 1 // Stop processing, but don't qdel.
|
||||
#define EFFECT_DESTROY 2 // qdel.
|
||||
|
||||
// Performance bullshit.
|
||||
|
||||
//supposedly the fastest way to do this according to https://gist.github.com/Giacom/be635398926bb463b42a
|
||||
#define RANGE_TURFS(RADIUS, CENTER) \
|
||||
block( \
|
||||
locate(max(CENTER.x-(RADIUS),1), max(CENTER.y-(RADIUS),1), CENTER.z), \
|
||||
locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \
|
||||
)
|
||||
|
||||
#define get_turf(A) (get_step(A, 0))
|
||||
#define QDELETED(TARGET) (!TARGET || TARGET.gcDestroyed)
|
||||
|
||||
//Recipe type defines. Used to determine what machine makes them
|
||||
#define MICROWAVE 0x1
|
||||
#define FRYER 0x2
|
||||
#define OVEN 0x4
|
||||
#define CANDYMAKER 0x8
|
||||
#define CEREALMAKER 0x10
|
||||
|
||||
@@ -133,6 +133,9 @@
|
||||
set name = "Debug Pooling Type"
|
||||
set category = "Debug"
|
||||
|
||||
if (!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/type = input("What is the typepath for the pooled object variables you wish to view?", "Pooled Variables") in pooledvariables|null
|
||||
|
||||
if(!type)
|
||||
@@ -149,4 +152,4 @@
|
||||
|
||||
// Shim - this method doesn't natively exist in this implementation.
|
||||
/proc/IsPooled(var/datum/D)
|
||||
return "[D.type]" in masterdatumPool
|
||||
return "[D.type]" in masterdatumPool
|
||||
|
||||
@@ -631,7 +631,6 @@ proc/ColorTone(rgb, tone)
|
||||
/*
|
||||
Get flat icon by DarkCampainger. As it says on the tin, will return an icon with all the overlays
|
||||
as a single icon. Useful for when you want to manipulate an icon via the above as overlays are not normally included.
|
||||
The _flatIcons list is a cache for generated icon files.
|
||||
*/
|
||||
|
||||
proc // Creates a single icon from a given /atom or /image. Only the first argument is required.
|
||||
|
||||
@@ -127,4 +127,12 @@
|
||||
return (val & (val-1)) == 0
|
||||
|
||||
/proc/RoundUpToPowerOfTwo(var/val)
|
||||
return 2 ** -round(-log(2,val))
|
||||
return 2 ** -round(-log(2,val))
|
||||
|
||||
|
||||
//Written by Lohikar
|
||||
//Returns the cube root of the input number
|
||||
/proc/cubert(var/num, var/iterations = 10)
|
||||
. = num
|
||||
for (var/i = 0, i < iterations, i++)
|
||||
. = (1/3) * (num/(.**2)+2*.)
|
||||
|
||||
@@ -180,6 +180,28 @@
|
||||
if(start)
|
||||
return findtextEx(text, suffix, start, null)
|
||||
|
||||
|
||||
//Parses a string into a list
|
||||
/proc/dd_text2List(text, separator)
|
||||
var/textlength = lentext(text)
|
||||
var/separatorlength = lentext(separator)
|
||||
var/list/textList = new /list()
|
||||
var/searchPosition = 1
|
||||
var/findPosition = 1
|
||||
var/buggyText
|
||||
while (1) // Loop forever.
|
||||
findPosition = findtextEx(text, separator, searchPosition, 0)
|
||||
buggyText = copytext(text, searchPosition, findPosition) // Everything from searchPosition to findPosition goes into a list element.
|
||||
textList += "[buggyText]" // Working around weird problem where "text" != "text" after this copytext().
|
||||
|
||||
searchPosition = findPosition + separatorlength // Skip over separator.
|
||||
if (findPosition == 0) // Didn't find anything at end of string so stop here.
|
||||
return textList
|
||||
else
|
||||
if (searchPosition > textlength) // Found separator at very end of string.
|
||||
textList += "" // So add empty element
|
||||
|
||||
|
||||
/*
|
||||
* Text modification
|
||||
*/
|
||||
|
||||
@@ -1065,13 +1065,6 @@ proc/get_mob_with_client_list()
|
||||
else if (zone == "r_foot") return "right foot"
|
||||
else return zone
|
||||
|
||||
//gets the turf the atom is located in (or itself, if it is a turf).
|
||||
//returns null if the atom is not in a turf.
|
||||
/proc/get_turf(atom/A)
|
||||
if(!istype(A)) return
|
||||
for(A, A && !isturf(A), A=A.loc);
|
||||
return A
|
||||
|
||||
/proc/get(atom/loc, type)
|
||||
while(loc)
|
||||
if(istype(loc, type))
|
||||
|
||||
@@ -125,6 +125,7 @@
|
||||
/obj/screen/movable/spell_master/proc/silence_spells(var/amount)
|
||||
for(var/obj/screen/spell/spell in spell_objects)
|
||||
spell.spell.silenced = amount
|
||||
spell.spell.process()
|
||||
spell.update_charge(1)
|
||||
|
||||
/obj/screen/movable/spell_master/proc/update_spells(forced = 0, mob/user)
|
||||
|
||||
@@ -110,9 +110,7 @@
|
||||
M.Stun(power)
|
||||
M.stuttering = max(M.stuttering, power)
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, M)
|
||||
s.start()
|
||||
spark(M, 5, alldirs)
|
||||
|
||||
if(prob(stunprob) && powerlevel >= 8)
|
||||
M.adjustFireLoss(powerlevel * rand(6,10))
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#define STAGE_IDLE 0
|
||||
#define STAGE_EFFECT 1
|
||||
#define STAGE_SUBEFFECT 2
|
||||
|
||||
var/datum/controller/process/effects/effect_master
|
||||
|
||||
/var/list/datum/effect_system/effects_objects = list() // The effect-spawning objects. Shouldn't be many of these.
|
||||
/var/list/obj/visual_effect/effects_visuals = list() // The visible component of an effect. May be created without an effect object.
|
||||
|
||||
/datum/controller/process/effects
|
||||
var/tmp/list/processing_effects = list()
|
||||
var/tmp/list/processing_visuals = list()
|
||||
var/tmp/stage = STAGE_IDLE
|
||||
|
||||
/datum/controller/process/effects/setup()
|
||||
effect_master = src
|
||||
name = "effects"
|
||||
schedule_interval = 2
|
||||
tick_allowance = 15
|
||||
|
||||
/datum/controller/process/effects/doWork()
|
||||
if (stage == STAGE_IDLE)
|
||||
// Start a new work cycle.
|
||||
processing_effects = effects_objects
|
||||
effects_objects = list()
|
||||
stage = STAGE_EFFECT
|
||||
|
||||
while (processing_effects.len)
|
||||
var/datum/effect_system/E = processing_effects[processing_effects.len]
|
||||
processing_effects.len--
|
||||
|
||||
if (!E || E.gcDestroyed)
|
||||
continue
|
||||
|
||||
switch (E.process())
|
||||
if (EFFECT_CONTINUE)
|
||||
effects_objects += E
|
||||
|
||||
if (EFFECT_DESTROY)
|
||||
qdel(E)
|
||||
|
||||
F_SCHECK
|
||||
|
||||
if (stage == STAGE_EFFECT)
|
||||
processing_visuals = effects_visuals
|
||||
effects_visuals = list()
|
||||
stage = STAGE_SUBEFFECT
|
||||
|
||||
while (processing_visuals.len)
|
||||
var/obj/visual_effect/V = processing_visuals[processing_visuals.len]
|
||||
processing_visuals.len--
|
||||
|
||||
if (!V || V.gcDestroyed)
|
||||
effects_visuals -= V
|
||||
continue
|
||||
|
||||
switch (V.tick())
|
||||
if (EFFECT_CONTINUE)
|
||||
effects_visuals += V
|
||||
|
||||
if (EFFECT_DESTROY)
|
||||
effects_visuals -= V
|
||||
V.end()
|
||||
qdel(V)
|
||||
|
||||
F_SCHECK
|
||||
|
||||
stage = STAGE_IDLE
|
||||
|
||||
// We're done.
|
||||
if (!processing_effects.len && !processing_visuals.len && !effects_objects.len && !effects_visuals.len)
|
||||
disable()
|
||||
|
||||
/datum/controller/process/effects/proc/queue(var/datum/effect_system/E)
|
||||
if (!E || E.gcDestroyed)
|
||||
return
|
||||
|
||||
effects_objects += E
|
||||
enable()
|
||||
|
||||
/datum/controller/process/effects/proc/queue_simple(var/obj/visual_effect/V)
|
||||
if (!V || V.gcDestroyed)
|
||||
return
|
||||
|
||||
effects_visuals += V
|
||||
enable()
|
||||
|
||||
/datum/controller/process/effects/statProcess()
|
||||
..()
|
||||
stat(null, "Effect process is [disabled ? "sleeping" : "processing"].")
|
||||
stat(null, "[effects_objects.len] effects queued, [processing_effects.len] processing")
|
||||
stat(null, "[effects_visuals.len] visuals queued, [processing_visuals.len] processing")
|
||||
@@ -127,11 +127,6 @@ world/loop_checks = 0
|
||||
stat(null, "[garbage_collect ? "On" : "Off"], [destroyed.len] queued")
|
||||
stat(null, "Dels: [total_dels], [soft_dels] soft, [hard_dels] hard, [tick_dels] last run")
|
||||
|
||||
|
||||
// Tests if an atom has been deleted.
|
||||
/proc/deleted(atom/A)
|
||||
return !A || !isnull(A.gcDestroyed)
|
||||
|
||||
// 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)
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/var/global/datum/controller/process/law/corp_regs
|
||||
|
||||
/datum/controller/process/law
|
||||
var/list/laws = list() // All laws
|
||||
|
||||
var/list/low_severity = list()
|
||||
var/list/med_severity = list()
|
||||
var/list/high_severity = list()
|
||||
|
||||
disabled = 1
|
||||
|
||||
/datum/controller/process/law/New()
|
||||
corp_regs = src
|
||||
|
||||
..()
|
||||
|
||||
/datum/controller/process/law/setup()
|
||||
name = "Law"
|
||||
schedule_interval = 100
|
||||
|
||||
for( var/L in subtypesof( /datum/law/low_severity ))
|
||||
low_severity += new L
|
||||
|
||||
for( var/L in subtypesof( /datum/law/med_severity ))
|
||||
med_severity += new L
|
||||
|
||||
for( var/L in subtypesof( /datum/law/high_severity ))
|
||||
high_severity += new L
|
||||
|
||||
laws = low_severity + med_severity + high_severity
|
||||
@@ -14,36 +14,29 @@
|
||||
|
||||
/datum/controller/process/lighting
|
||||
schedule_interval = LIGHTING_INTERVAL
|
||||
var/list/curr_lights = list()
|
||||
var/list/curr_corners = list()
|
||||
var/list/curr_overlays = list()
|
||||
var/list/resume_pos = 0
|
||||
|
||||
/datum/controller/process/lighting/setup()
|
||||
name = "lighting"
|
||||
|
||||
lighting_process = src
|
||||
|
||||
/datum/controller/process/lighting/statProcess()
|
||||
..()
|
||||
stat(null, "Server tick usage is [world.tick_usage].")
|
||||
stat(null, "[all_lighting_overlays.len] overlays ([all_lighting_corners.len] corners)")
|
||||
stat(null, "Lights: [lighting_update_lights.len] queued, [curr_lights.len] processing")
|
||||
stat(null, "Corners: [lighting_update_corners.len] queued, [curr_corners.len] processing")
|
||||
stat(null, "Overlays: [lighting_update_overlays.len] queued, [curr_overlays.len] processing")
|
||||
stat(null, "Lights: [lighting_update_lights.len] queued")
|
||||
stat(null, "Corners: [lighting_update_corners.len] queued")
|
||||
stat(null, "Overlays: [lighting_update_overlays.len] queued")
|
||||
|
||||
/datum/controller/process/lighting/doWork()
|
||||
// -- SOURCES --
|
||||
if (resume_pos == STAGE_NONE)
|
||||
curr_lights = lighting_update_lights
|
||||
lighting_update_lights = list()
|
||||
|
||||
resume_pos = STAGE_SOURCE
|
||||
var/list/curr_lights = lighting_update_lights
|
||||
var/list/curr_corners = lighting_update_corners
|
||||
var/list/curr_overlays = lighting_update_overlays
|
||||
|
||||
while (curr_lights.len)
|
||||
var/datum/light_source/L = curr_lights[curr_lights.len]
|
||||
curr_lights.len--
|
||||
|
||||
if(L.check() || L.destroyed || L.force_update)
|
||||
if(L.destroyed || L.check() || L.force_update)
|
||||
L.remove_lum()
|
||||
if(!L.destroyed)
|
||||
L.apply_lum()
|
||||
@@ -57,13 +50,6 @@
|
||||
|
||||
F_SCHECK
|
||||
|
||||
// -- CORNERS --
|
||||
if (resume_pos == STAGE_SOURCE)
|
||||
curr_corners = lighting_update_corners
|
||||
lighting_update_corners = list()
|
||||
|
||||
resume_pos = STAGE_CORNER
|
||||
|
||||
while (curr_corners.len)
|
||||
var/datum/lighting_corner/C = curr_corners[curr_corners.len]
|
||||
curr_corners.len--
|
||||
@@ -74,12 +60,6 @@
|
||||
|
||||
F_SCHECK
|
||||
|
||||
if (resume_pos == STAGE_CORNER)
|
||||
curr_overlays = lighting_update_overlays
|
||||
lighting_update_overlays = list()
|
||||
|
||||
resume_pos = STAGE_OVERLAY
|
||||
|
||||
while (curr_overlays.len)
|
||||
var/atom/movable/lighting_overlay/O = curr_overlays[curr_overlays.len]
|
||||
curr_overlays.len--
|
||||
@@ -89,8 +69,6 @@
|
||||
|
||||
F_SCHECK
|
||||
|
||||
resume_pos = 0
|
||||
|
||||
#undef STAGE_NONE
|
||||
#undef STAGE_SOURCE
|
||||
#undef STAGE_CORNER
|
||||
|
||||
@@ -1,16 +1,39 @@
|
||||
/var/global/machinery_sort_required = 0
|
||||
/var/global/machinery_sort_required = 0
|
||||
var/global/list/power_using_machines = list()
|
||||
var/global/list/ticking_machines = list()
|
||||
|
||||
#define STAGE_NONE 0
|
||||
#define STAGE_MACHINERY 1
|
||||
#define STAGE_POWERNET 2
|
||||
#define STAGE_POWERSINK 3
|
||||
#define STAGE_PIPENET 4
|
||||
#define STAGE_MACHINERY_PROCESS 1
|
||||
#define STAGE_MACHINERY_POWER 2
|
||||
#define STAGE_POWERNET 3
|
||||
#define STAGE_POWERSINK 4
|
||||
#define STAGE_PIPENET 5
|
||||
|
||||
/proc/add_machine(var/obj/machinery/M)
|
||||
if (QDELETED(M))
|
||||
return
|
||||
|
||||
var/type = M.get_process_type()
|
||||
if (type)
|
||||
machines += M
|
||||
|
||||
if (type & M_PROCESSES)
|
||||
ticking_machines += M
|
||||
|
||||
if (type & M_USES_POWER)
|
||||
power_using_machines += M
|
||||
|
||||
/proc/remove_machine(var/obj/machinery/M)
|
||||
machines -= M
|
||||
power_using_machines -= M
|
||||
ticking_machines -= M
|
||||
|
||||
/datum/controller/process/machinery
|
||||
var/tmp/list/processing_machinery = list()
|
||||
var/tmp/list/processing_powernets = list()
|
||||
var/tmp/list/processing_powersinks = list()
|
||||
var/tmp/list/processing_pipenets = list()
|
||||
var/tmp/list/processing_machinery = list()
|
||||
var/tmp/list/processing_power_users = list()
|
||||
var/tmp/list/processing_powernets = list()
|
||||
var/tmp/list/processing_powersinks = list()
|
||||
var/tmp/list/processing_pipenets = list()
|
||||
var/stage = STAGE_NONE
|
||||
|
||||
/datum/controller/process/machinery/setup()
|
||||
@@ -21,20 +44,37 @@
|
||||
/datum/controller/process/machinery/doWork()
|
||||
// If we're starting a new tick, setup.
|
||||
if (stage == STAGE_NONE)
|
||||
processing_machinery = machines.Copy()
|
||||
stage = STAGE_MACHINERY
|
||||
processing_machinery = ticking_machines.Copy()
|
||||
stage = STAGE_MACHINERY_PROCESS
|
||||
|
||||
// Process machinery.
|
||||
while (processing_machinery.len)
|
||||
var/obj/machinery/M = processing_machinery[processing_machinery.len]
|
||||
processing_machinery.len--
|
||||
|
||||
if (!M || M.gcDestroyed)
|
||||
machines -= M
|
||||
if (QDELETED(M))
|
||||
remove_machine(M)
|
||||
continue
|
||||
|
||||
if (M.process() == PROCESS_KILL)
|
||||
machines -= M
|
||||
switch (M.process())
|
||||
if (PROCESS_KILL)
|
||||
remove_machine(M)
|
||||
|
||||
if (M_NO_PROCESS)
|
||||
ticking_machines -= M
|
||||
|
||||
F_SCHECK
|
||||
|
||||
if (stage == STAGE_MACHINERY_PROCESS)
|
||||
processing_power_users = power_using_machines.Copy()
|
||||
stage = STAGE_MACHINERY_POWER
|
||||
|
||||
while (processing_power_users.len)
|
||||
var/obj/machinery/M = processing_power_users[processing_power_users.len]
|
||||
processing_power_users.len--
|
||||
|
||||
if (QDELETED(M))
|
||||
remove_machine(M)
|
||||
continue
|
||||
|
||||
if (M.use_power)
|
||||
@@ -42,7 +82,7 @@
|
||||
|
||||
F_SCHECK
|
||||
|
||||
if (stage == STAGE_MACHINERY)
|
||||
if (stage == STAGE_MACHINERY_POWER)
|
||||
processing_powernets = powernets.Copy()
|
||||
stage = STAGE_POWERNET
|
||||
|
||||
@@ -50,7 +90,7 @@
|
||||
var/datum/powernet/PN = processing_powernets[processing_powernets.len]
|
||||
processing_powernets.len--
|
||||
|
||||
if (!PN || PN.gcDestroyed)
|
||||
if (QDELETED(PN))
|
||||
powernets -= PN
|
||||
continue
|
||||
|
||||
@@ -65,7 +105,7 @@
|
||||
var/obj/item/I = processing_powersinks[processing_powersinks.len]
|
||||
processing_powersinks.len--
|
||||
|
||||
if (!I || !I.pwr_drain())
|
||||
if (QDELETED(I) || !I.pwr_drain())
|
||||
processing_power_items -= I
|
||||
|
||||
F_SCHECK
|
||||
@@ -78,7 +118,8 @@
|
||||
var/datum/pipe_network/PN = processing_pipenets[processing_pipenets.len]
|
||||
processing_pipenets.len--
|
||||
|
||||
if (!PN || PN.gcDestroyed)
|
||||
if (QDELETED(PN))
|
||||
pipe_networks -= PN
|
||||
continue
|
||||
|
||||
PN.process()
|
||||
@@ -93,13 +134,16 @@
|
||||
|
||||
/datum/controller/process/machinery/statProcess()
|
||||
..()
|
||||
stat(null, "[machines.len] machines, [processing_machinery.len] queued")
|
||||
stat(null, "[machines.len] total machines")
|
||||
stat(null, "[ticking_machines.len] ticking machines, [processing_machinery.len] queued")
|
||||
stat(null, "[power_using_machines.len] power-using machines, [processing_power_users.len] queued")
|
||||
stat(null, "[powernets.len] powernets, [processing_powernets.len] queued")
|
||||
stat(null, "[processing_power_items.len] power items, [processing_powersinks.len] queued")
|
||||
stat(null, "[pipe_networks.len] pipenets, [processing_pipenets.len] queued")
|
||||
|
||||
#undef STAGE_NONE
|
||||
#undef STAGE_MACHINERY
|
||||
#undef STAGE_MACHINERY_PROCESS
|
||||
#undef STAGE_MACHINERY_POWER
|
||||
#undef STAGE_POWERNET
|
||||
#undef STAGE_POWERSINK
|
||||
#undef STAGE_PIPENET
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
/datum/controller/process/scheduler/setup()
|
||||
name = "scheduler"
|
||||
schedule_interval = 3 SECONDS
|
||||
schedule_interval = 2 SECONDS
|
||||
scheduled_tasks = list()
|
||||
scheduler = src
|
||||
|
||||
@@ -23,13 +23,14 @@
|
||||
var/datum/scheduled_task/task = queued_tasks[queued_tasks.len]
|
||||
queued_tasks.len--
|
||||
|
||||
if (QDELETED(task))
|
||||
scheduled_tasks -= task
|
||||
continue
|
||||
|
||||
if (world.time > task.trigger_time)
|
||||
unschedule(task)
|
||||
// why are these separated.
|
||||
task.pre_process()
|
||||
F_SCHECK // fuck it, it's a cheap call.
|
||||
task.process()
|
||||
F_SCHECK
|
||||
task.post_process()
|
||||
F_SCHECK
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ var/list/gamemode_cache = list()
|
||||
var/banappeals
|
||||
var/wikiurl
|
||||
var/forumurl
|
||||
var/forum_passphrase
|
||||
var/githuburl
|
||||
|
||||
//Alert level description
|
||||
@@ -458,6 +459,9 @@ var/list/gamemode_cache = list()
|
||||
if ("forumurl")
|
||||
config.forumurl = value
|
||||
|
||||
if ("forum_passphrase")
|
||||
config.forum_passphrase = value
|
||||
|
||||
if ("githuburl")
|
||||
config.githuburl = value
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/var/global/datum/controller/law/corp_regs
|
||||
|
||||
/datum/controller/law
|
||||
var/list/laws = list() // All laws
|
||||
|
||||
var/list/low_severity = list()
|
||||
var/list/med_severity = list()
|
||||
var/list/high_severity = list()
|
||||
|
||||
/datum/controller/law/New()
|
||||
corp_regs = src
|
||||
|
||||
for (var/L in subtypesof(/datum/law/low_severity))
|
||||
low_severity += new L
|
||||
|
||||
for (var/L in subtypesof(/datum/law/med_severity))
|
||||
med_severity += new L
|
||||
|
||||
for (var/L in subtypesof(/datum/law/high_severity))
|
||||
high_severity += new L
|
||||
|
||||
laws = low_severity + med_severity + high_severity
|
||||
|
||||
..()
|
||||
@@ -81,6 +81,7 @@ datum/controller/game_controller/proc/setup_objects()
|
||||
admin_notice(span("danger", "Done."))
|
||||
|
||||
if(config.generate_asteroid)
|
||||
var/time = world.time
|
||||
// These values determine the specific area that the map is applied to.
|
||||
// If you do not use the official Baycode moonbase map, you will need to change them.
|
||||
//Create the mining Z-level.
|
||||
@@ -92,12 +93,9 @@ datum/controller/game_controller/proc/setup_objects()
|
||||
new /datum/random_map/noise/ore(null, 0, 0, 5, 64, 64)
|
||||
new /datum/random_map/noise/ore(null, 0, 0, 4, 64, 64)
|
||||
new /datum/random_map/noise/ore(null, 0, 0, 3, 64, 64)
|
||||
// Update all turfs to ensure everything looks good post-generation. Yes,
|
||||
// it's brute-forcey, but frankly the alternative is a mine turf rewrite.
|
||||
for(var/turf/simulated/mineral/M in world) // Ugh.
|
||||
M.updateMineralOverlays()
|
||||
for(var/turf/simulated/floor/asteroid/M in world) // Uuuuuugh.
|
||||
M.updateMineralOverlays()
|
||||
var/msg = "Asteroid generation completed in [(world.time - time) / 10] seconds."
|
||||
admin_notice(span("danger", msg))
|
||||
game_log("ASGEN", msg)
|
||||
|
||||
admin_notice(span("danger", "Setting up lighting."))
|
||||
initialize_lighting()
|
||||
@@ -113,5 +111,8 @@ datum/controller/game_controller/proc/setup_objects()
|
||||
//Set up spawn points.
|
||||
populate_spawn_points()
|
||||
|
||||
// Setup laws.
|
||||
global.corp_regs = new
|
||||
|
||||
admin_notice("<span class='danger'>Initializations complete.</span>", R_DEBUG)
|
||||
sleep(-1)
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
var/atom/movable/teleatom //atom to teleport
|
||||
var/atom/destination //destination to teleport to
|
||||
var/precision = 0 //teleport precision
|
||||
var/datum/effect/effect/system/effectin //effect to show right before teleportation
|
||||
var/datum/effect/effect/system/effectout //effect to show right after teleportation
|
||||
var/datum/effect_system/effectin //effect to show right before teleportation
|
||||
var/datum/effect_system/effectout //effect to show right after teleportation
|
||||
var/soundin //soundfile to play before teleportation
|
||||
var/soundout //soundfile to play after teleportation
|
||||
var/force_teleport = 1 //if false, teleport will use Move() proc (dense objects will prevent teleportation)
|
||||
@@ -78,13 +78,13 @@
|
||||
/datum/teleport/proc/teleportChecks()
|
||||
return 1
|
||||
|
||||
/datum/teleport/proc/playSpecials(atom/location,datum/effect/effect/system/effect,sound)
|
||||
/datum/teleport/proc/playSpecials(atom/location,datum/effect_system/effect,sound)
|
||||
if(location)
|
||||
if(effect)
|
||||
spawn(-1)
|
||||
src = null
|
||||
effect.attach(location)
|
||||
effect.start()
|
||||
effect.location = location
|
||||
effect.queue()
|
||||
if(sound)
|
||||
spawn(-1)
|
||||
src = null
|
||||
@@ -141,8 +141,7 @@
|
||||
|
||||
/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)
|
||||
var/datum/effect_system/sparks/aeffect = getFromPool(/datum/effect_system/sparks, null, FALSE, 5, alldirs)
|
||||
effectin = effectin || aeffect
|
||||
effectout = effectout || aeffect
|
||||
return 1
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* /datum/recipe by rastaf0 13 apr 2011 *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* This is powerful and flexible recipe system.
|
||||
* It exists not only for food.
|
||||
* supports both reagents and objects as prerequisites.
|
||||
* In order to use this system you have to define a deriative from /datum/recipe
|
||||
* * reagents are reagents. Acid, milc, booze, etc.
|
||||
* * items are objects. Fruits, tools, circuit boards.
|
||||
* * result is type to create as new object
|
||||
* * time is optional parameter, you shall use in in your machine,
|
||||
default /datum/recipe/ procs does not rely on this parameter.
|
||||
*
|
||||
* Functions you need:
|
||||
* /datum/recipe/proc/make(var/obj/container as obj)
|
||||
* Creates result inside container,
|
||||
* deletes prerequisite reagents,
|
||||
* transfers reagents from prerequisite objects,
|
||||
* deletes all prerequisite objects (even not needed for recipe at the moment).
|
||||
*
|
||||
* /proc/select_recipe(list/datum/recipe/avaiable_recipes, obj/obj as obj, exact = 1)
|
||||
* Wonderful function that select suitable recipe for you.
|
||||
* obj is a machine (or magik hat) with prerequisites,
|
||||
* exact = 0 forces algorithm to ignore superfluous stuff.
|
||||
*
|
||||
*
|
||||
* Functions you do not need to call directly but could:
|
||||
* /datum/recipe/proc/check_reagents(var/datum/reagents/avail_reagents)
|
||||
* /datum/recipe/proc/check_items(var/obj/container as obj)
|
||||
*
|
||||
* */
|
||||
|
||||
/datum/recipe
|
||||
var/list/reagents // example: = list("berryjuice" = 5) // do not list same reagent twice
|
||||
var/list/items // example: = list(/obj/item/weapon/crowbar, /obj/item/weapon/welder) // place /foo/bar before /foo
|
||||
var/list/fruit // example: = list("fruit" = 3)
|
||||
var/result // example: = /obj/item/weapon/reagent_containers/food/snacks/donut/normal
|
||||
var/time = 100 // 1/10 part of second
|
||||
|
||||
/datum/recipe/proc/check_reagents(var/datum/reagents/avail_reagents)
|
||||
. = 1
|
||||
for (var/r_r in reagents)
|
||||
var/aval_r_amnt = avail_reagents.get_reagent_amount(r_r)
|
||||
if (!(abs(aval_r_amnt - reagents[r_r])<0.5)) //if NOT equals
|
||||
if (aval_r_amnt>reagents[r_r])
|
||||
. = 0
|
||||
else
|
||||
return -1
|
||||
if ((reagents?(reagents.len):(0)) < avail_reagents.reagent_list.len)
|
||||
return 0
|
||||
return .
|
||||
|
||||
/datum/recipe/proc/check_fruit(var/obj/container)
|
||||
. = 1
|
||||
if(fruit && fruit.len)
|
||||
var/list/checklist = list()
|
||||
// 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
|
||||
checklist[G.seed.kitchen_tag]--
|
||||
for(var/ktag in checklist)
|
||||
if(!isnull(checklist[ktag]))
|
||||
if(checklist[ktag] < 0)
|
||||
. = 0
|
||||
else if(checklist[ktag] > 0)
|
||||
. = -1
|
||||
break
|
||||
return .
|
||||
|
||||
/datum/recipe/proc/check_items(var/obj/container as obj)
|
||||
. = 1
|
||||
if (items && items.len)
|
||||
var/list/checklist = list()
|
||||
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/i = 1; i < checklist.len+1; i++)
|
||||
var/item_type = checklist[i]
|
||||
if (istype(O,item_type))
|
||||
checklist.Cut(i, i+1)
|
||||
found = 1
|
||||
break
|
||||
if (!found)
|
||||
. = 0
|
||||
if (checklist.len)
|
||||
. = -1
|
||||
return .
|
||||
|
||||
//general version
|
||||
/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_obj(result_obj, O.reagents.total_volume)
|
||||
qdel(O)
|
||||
container.reagents.clear_reagents()
|
||||
return result_obj
|
||||
|
||||
// food-related
|
||||
/datum/recipe/proc/make_food(var/obj/container as obj)
|
||||
if(!result)
|
||||
world << "<span class='danger'>Recipe [type] is defined without a result, please bug this.</span>"
|
||||
return
|
||||
var/obj/result_obj = new result(container)
|
||||
for (var/obj/O in (container.contents-result_obj))
|
||||
if (O.reagents)
|
||||
O.reagents.del_reagent("nutriment")
|
||||
O.reagents.update_total()
|
||||
O.reagents.trans_to_obj(result_obj, O.reagents.total_volume)
|
||||
qdel(O)
|
||||
container.reagents.clear_reagents()
|
||||
return result_obj
|
||||
|
||||
/proc/select_recipe(var/list/datum/recipe/avaiable_recipes, var/obj/obj as obj, var/exact)
|
||||
var/list/datum/recipe/possible_recipes = new
|
||||
var/target = exact ? 0 : 1
|
||||
for (var/datum/recipe/recipe in avaiable_recipes)
|
||||
if((recipe.check_reagents(obj.reagents) < target) || (recipe.check_items(obj) < target) || (recipe.check_fruit(obj) < target))
|
||||
continue
|
||||
possible_recipes |= recipe
|
||||
if (possible_recipes.len==0)
|
||||
return null
|
||||
else if (possible_recipes.len==1)
|
||||
return possible_recipes[1]
|
||||
else //okay, let's select the most complicated recipe
|
||||
var/highest_count = 0
|
||||
. = possible_recipes[1]
|
||||
for (var/datum/recipe/recipe in possible_recipes)
|
||||
var/count = ((recipe.items)?(recipe.items.len):0) + ((recipe.reagents)?(recipe.reagents.len):0) + ((recipe.fruit)?(recipe.fruit.len):0)
|
||||
if (count >= highest_count)
|
||||
highest_count = count
|
||||
. = recipe
|
||||
return .
|
||||
@@ -15,8 +15,17 @@
|
||||
item_cost = round(DEFAULT_TELECRYSTAL_AMOUNT / 2)
|
||||
desc = "Causes a falsified [command_name()] Update. Triggers immediately after supplying additional data."
|
||||
|
||||
/datum/uplink_item/abstract/announcements/fake_centcom/extra_args(var/mob/user)
|
||||
var/title = sanitize(input("Enter your announcement title.", "Announcement Title") as null|text)
|
||||
if(!title)
|
||||
return
|
||||
var/message = sanitize(input("Enter your announcement message.", "Announcement Title") as null|text)
|
||||
if(!message)
|
||||
return
|
||||
return list("title" = title, "message" = message)
|
||||
|
||||
/datum/uplink_item/abstract/announcements/fake_centcom/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user, var/list/args)
|
||||
command_announcement.Announce(args.["message"], args.["title"])
|
||||
command_announcement.Announce(args["message"], args["title"])
|
||||
return 1
|
||||
|
||||
/datum/uplink_item/abstract/announcements/fake_crew_arrival
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
item_cost = 2
|
||||
path = /obj/item/weapon/storage/toolbox/syndicate
|
||||
|
||||
/datum/uplink_item/item/tools/advancedpinpointer
|
||||
name = "Advanced pinpointer"
|
||||
item_cost = 15
|
||||
path = /obj/item/weapon/pinpointer/advpinpointer
|
||||
desc = "An advanced pinpointer that can find any target with DNA along with various other items."
|
||||
|
||||
/datum/uplink_item/item/tools/money
|
||||
name = "Operations Funding"
|
||||
item_cost = 2
|
||||
|
||||
@@ -47,6 +47,9 @@ var/datum/uplink/uplink = new()
|
||||
if(!can_buy(U))
|
||||
return
|
||||
|
||||
if(U.CanUseTopic(user, inventory_state) != STATUS_INTERACTIVE)
|
||||
return
|
||||
|
||||
var/cost = cost(U.uses)
|
||||
|
||||
var/goods = get_goods(U, get_turf(user), user, extra_args)
|
||||
@@ -143,7 +146,9 @@ datum/uplink_item/dd_SortValue()
|
||||
* Abstract Uplink Entries *
|
||||
* *
|
||||
********************************/
|
||||
var/image/default_abstract_uplink_icon
|
||||
/datum/uplink_item/abstract
|
||||
var/static/image/default_abstract_uplink_icon
|
||||
|
||||
/datum/uplink_item/abstract/log_icon()
|
||||
if(!default_abstract_uplink_icon)
|
||||
default_abstract_uplink_icon = image('icons/obj/pda.dmi', "pda-syn")
|
||||
|
||||
+12
-11
@@ -173,7 +173,7 @@
|
||||
throw_range = 5
|
||||
w_class = 2.0
|
||||
attack_verb = list("warned", "cautioned", "smashed")
|
||||
|
||||
|
||||
/obj/item/weapon/caution/attack_self(mob/user as mob)
|
||||
if(src.icon_state == "caution")
|
||||
src.icon_state = "caution_blinking"
|
||||
@@ -181,14 +181,15 @@
|
||||
else
|
||||
src.icon_state = "caution"
|
||||
user << "You turn the sign off."
|
||||
|
||||
|
||||
/obj/item/weapon/caution/AltClick()
|
||||
if(src.icon_state == "caution")
|
||||
src.icon_state = "caution_blinking"
|
||||
usr << "You turn the sign on."
|
||||
else
|
||||
src.icon_state = "caution"
|
||||
usr << "You turn the sign off."
|
||||
if(!usr || usr.stat || usr.lying || usr.restrained() || !Adjacent(usr)) return
|
||||
if(src.icon_state == "caution")
|
||||
src.icon_state = "caution_blinking"
|
||||
usr << "You turn the sign on."
|
||||
else
|
||||
src.icon_state = "caution"
|
||||
usr << "You turn the sign off."
|
||||
|
||||
/obj/item/weapon/caution/cone
|
||||
desc = "This cone is trying to warn you of something!"
|
||||
@@ -197,10 +198,10 @@
|
||||
item_state = "cone"
|
||||
contained_sprite = 1
|
||||
slot_flags = SLOT_HEAD
|
||||
|
||||
|
||||
/obj/item/weapon/caution/cone/attack_self(mob/user as mob)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/caution/cone/AltClick()
|
||||
return
|
||||
|
||||
@@ -427,7 +428,7 @@
|
||||
icon = 'icons/obj/stock_parts.dmi'
|
||||
w_class = 2.0
|
||||
var/rating = 1
|
||||
|
||||
|
||||
/obj/item/weapon/stock_parts/New()
|
||||
src.pixel_x = rand(-5.0, 5)
|
||||
src.pixel_y = rand(-5.0, 5)
|
||||
|
||||
@@ -14,6 +14,7 @@ var/datum/antagonist/xenos/xenomorphs
|
||||
faction_descriptor = "Hive"
|
||||
faction_welcome = "Your will is ripped away as your humanity merges with the xenomorph overmind. You are now \
|
||||
a thrall to the queen and her brood. Obey their instructions without question. Serve the hive."
|
||||
faction = "xenomorph"
|
||||
|
||||
hard_cap = 5
|
||||
hard_cap_round = 8
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
var/faction_descriptor // Description of the cause. Mandatory for faction role.
|
||||
var/faction_verb // Verb added when becoming a member of the faction, if any.
|
||||
var/faction_welcome // Message shown to faction members.
|
||||
var/faction = "neutral" // Faction name, mostly used for simple animals.
|
||||
|
||||
// Spawn values (autotraitor and game mode)
|
||||
var/hard_cap = 3 // Autotraitor var. Won't spawn more than this many antags.
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
create_antagonist(player, move_to_spawn, do_not_announce, preserve_appearance)
|
||||
if(!do_not_equip)
|
||||
equip(player.current)
|
||||
|
||||
player.current.faction = faction
|
||||
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/add_antagonist_mind(var/datum/mind/player, var/ignore_role, var/nonstandard_role_type, var/nonstandard_role_msg)
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
player.drop_from_inventory(thing)
|
||||
if(thing.loc != player)
|
||||
qdel(thing)
|
||||
player.species.equip_survival_gear(player)
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/unequip(var/mob/living/carbon/human/player)
|
||||
if(!istype(player))
|
||||
return 0
|
||||
return 1
|
||||
return 1
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
set category = "Abilities"
|
||||
if(!M.mind)
|
||||
return
|
||||
for (var/obj/item/weapon/implant/loyalty/I in M)
|
||||
if (I.implanted)
|
||||
src << "<span class='warning'>[M] is too loyal to the company!</span>"
|
||||
return
|
||||
convert_to_faction(M.mind, revs)
|
||||
|
||||
/mob/living/proc/convert_to_faction(var/datum/mind/player, var/datum/antagonist/faction)
|
||||
|
||||
@@ -30,7 +30,7 @@ var/datum/antagonist/ert/ert
|
||||
/datum/antagonist/ert/greet(var/datum/mind/player)
|
||||
if(!..())
|
||||
return
|
||||
player.current << "The Emergency Response Team works for Asset Protection; your job is to protect NanoTrasen's assets. There is a code red alert on [station_name()], you are tasked to go and fix the problem."
|
||||
player.current << "The Emergency Response Team works for Asset Protection; your job is to protect [company_name]'s assets. There is a code red alert on [station_name()], you are tasked to go and fix the problem."
|
||||
player.current << "You should first gear up and discuss a plan with your team. More members may be joining, don't move out before you're ready."
|
||||
|
||||
/datum/antagonist/ert/equip(var/mob/living/carbon/human/player)
|
||||
|
||||
@@ -14,7 +14,8 @@ var/datum/antagonist/wizard/wizards
|
||||
hard_cap_round = 3
|
||||
initial_spawn_req = 1
|
||||
initial_spawn_target = 1
|
||||
|
||||
|
||||
faction = "Space Wizard"
|
||||
|
||||
/datum/antagonist/wizard/New()
|
||||
..()
|
||||
@@ -85,7 +86,8 @@ var/datum/antagonist/wizard/wizards
|
||||
if(wizard_mob.backbag == 5) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/duffel/wizard(wizard_mob), slot_back)
|
||||
wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box(wizard_mob), slot_in_backpack)
|
||||
wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(wizard_mob), slot_r_store)
|
||||
wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/spellbook(wizard_mob), slot_r_hand)
|
||||
var/obj/item/I = new /obj/item/weapon/spellbook(get_turf(wizard_mob))
|
||||
wizard_mob.put_in_hands(I)
|
||||
wizard_mob.update_icons()
|
||||
return 1
|
||||
|
||||
@@ -100,6 +102,22 @@ var/datum/antagonist/wizard/wizards
|
||||
feedback_set_details("round_end_result","loss - wizard killed")
|
||||
world << "<span class='danger'><font size = 3>The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!</font></span>"
|
||||
|
||||
/datum/antagonist/wizard/print_player_summary()
|
||||
..()
|
||||
for(var/p in current_antagonists)
|
||||
var/datum/mind/player = p
|
||||
var/text = "<b>[player.name]'s spells were:</b>"
|
||||
if(!player.learned_spells || !player.learned_spells.len)
|
||||
text += "<br>None!"
|
||||
else
|
||||
for(var/s in player.learned_spells)
|
||||
var/spell/spell = s
|
||||
text += "<br><b>[spell.name]</b> - "
|
||||
text += "Speed: [spell.spell_levels["speed"]] Power: [spell.spell_levels["power"]]"
|
||||
text += "<br>"
|
||||
world << text
|
||||
|
||||
|
||||
//To batch-remove wizard spells. Linked to mind.dm.
|
||||
/mob/proc/spellremove()
|
||||
for(var/spell/spell_to_remove in src.spell_list)
|
||||
@@ -120,13 +138,13 @@ Made a proc so this is not repeated 14 (or more) times.*/
|
||||
|
||||
// Humans can wear clothes.
|
||||
/mob/living/carbon/human/wearing_wiz_garb()
|
||||
if(!is_wiz_garb(src.wear_suit))
|
||||
if(!is_wiz_garb(src.wear_suit) && (!src.species.hud || (slot_wear_suit in src.species.hud.equip_slots)))
|
||||
src << "<span class='warning'>I don't feel strong enough without my robe.</span>"
|
||||
return 0
|
||||
if(!is_wiz_garb(src.shoes))
|
||||
if(!is_wiz_garb(src.shoes) && (!species.hud || (slot_shoes in src.species.hud.equip_slots)))
|
||||
src << "<span class='warning'>I don't feel strong enough without my sandals.</span>"
|
||||
return 0
|
||||
if(!is_wiz_garb(src.head))
|
||||
if(!is_wiz_garb(src.head) && (!species.hud || (slot_head in src.species.hud.equip_slots)))
|
||||
src << "<span class='warning'>I don't feel strong enough without my hat.</span>"
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -104,12 +104,16 @@ var/datum/antagonist/cultist/cult
|
||||
player.memory = ""
|
||||
if(show_message)
|
||||
player.current.visible_message("<FONT size = 3>[player.current] looks like they just reverted to their old faith!</FONT>")
|
||||
if(. && player.current && !istype(player.current, /mob/living/simple_animal/construct))
|
||||
player.current.remove_language(LANGUAGE_CULT)
|
||||
|
||||
/datum/antagonist/cultist/add_antagonist(var/datum/mind/player)
|
||||
. = ..()
|
||||
if(.)
|
||||
player << "You catch a glimpse of the Realm of Nar-Sie, the Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of That Which Waits. Assist your new compatriots in their dark dealings. Their goals are yours, and yours are theirs. You serve the Dark One above all else. Bring It back."
|
||||
|
||||
if(player.current && !istype(player.current, /mob/living/simple_animal/construct))
|
||||
player.current.add_language(LANGUAGE_CULT)
|
||||
|
||||
/datum/antagonist/cultist/can_become_antag(var/datum/mind/player, ignore_role = 1)
|
||||
if(!..())
|
||||
return 0
|
||||
|
||||
@@ -28,8 +28,8 @@ var/datum/antagonist/revolutionary/revs
|
||||
faction_indicator = "rev"
|
||||
faction_invisible = 1
|
||||
|
||||
restricted_jobs = list("Internal Affairs Agent", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective")
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Personnel", "Chief Engineer", "Research Director", "Chief Medical Officer", "Captain", "Head of Security", "Internal Affairs Agent")
|
||||
|
||||
/datum/antagonist/revolutionary/New()
|
||||
..()
|
||||
@@ -46,3 +46,11 @@ var/datum/antagonist/revolutionary/revs
|
||||
rev_obj.target = player.mind
|
||||
rev_obj.explanation_text = "Assassinate, capture or convert [player.real_name], the [player.mind.assigned_role]."
|
||||
global_objectives += rev_obj
|
||||
|
||||
/datum/antagonist/revolutionary/can_become_antag(var/datum/mind/player)
|
||||
if(!..())
|
||||
return 0
|
||||
for(var/obj/item/weapon/implant/loyalty/L in player.current)
|
||||
if(L && (L.imp_in == player.current))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -2,8 +2,8 @@ var/datum/antagonist/thrall/vampire_thrall = null
|
||||
|
||||
/datum/antagonist/thrall
|
||||
id = MODE_THRALL
|
||||
role_text = "thrall"
|
||||
role_text_plural = "thralls"
|
||||
role_text = "Thrall"
|
||||
role_text_plural = "Thralls"
|
||||
bantype = "vampires"
|
||||
feedback_tag = "thrall_objective"
|
||||
restricted_jobs = list("AI", "Cyborg", "Chaplain")
|
||||
|
||||
@@ -256,7 +256,6 @@ area/space/atmosalert()
|
||||
|
||||
/area/shuttle/mining/outpost
|
||||
icon_state = "shuttle"
|
||||
base_turf = /turf/simulated/floor/asteroid
|
||||
|
||||
/area/shuttle/transport1/centcom
|
||||
icon_state = "shuttle"
|
||||
@@ -556,6 +555,7 @@ area/space/atmosalert()
|
||||
/area/syndicate_station/mining
|
||||
name = "\improper northeast of the mining station"
|
||||
icon_state = "north"
|
||||
base_turf = /turf/space
|
||||
|
||||
/area/syndicate_station/arrivals_dock
|
||||
name = "\improper docked with station"
|
||||
@@ -609,6 +609,7 @@ area/space/atmosalert()
|
||||
/area/skipjack_station/mining
|
||||
name = "\improper south of mining station"
|
||||
icon_state = "north"
|
||||
base_turf = /turf/space
|
||||
|
||||
//PRISON
|
||||
/area/prison
|
||||
@@ -1304,6 +1305,7 @@ area/space/atmosalert()
|
||||
requires_power = 1
|
||||
always_unpowered = 1
|
||||
dynamic_lighting = 0
|
||||
base_turf = /turf/space
|
||||
|
||||
auxport
|
||||
name = "\improper Roof Solar Array"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
/area
|
||||
var/global/global_uid = 0
|
||||
var/uid
|
||||
blend_mode = BLEND_MULTIPLY
|
||||
|
||||
/area/New()
|
||||
icon_state = ""
|
||||
@@ -353,4 +354,4 @@ var/list/mob/living/forced_ambiance_list = new
|
||||
turfs += F
|
||||
if (turfs.len)
|
||||
return pick(turfs)
|
||||
else return null
|
||||
else return null
|
||||
|
||||
@@ -59,9 +59,7 @@
|
||||
C.prefs.be_special_role ^= MODE_MERCENARY
|
||||
|
||||
obj/item/weapon/antag_spawner/borg_tele/spawn_antag(client/C, turf/T)
|
||||
var/datum/effect/effect/system/spark_spread/S = new /datum/effect/effect/system/spark_spread
|
||||
S.set_up(4, 1, src)
|
||||
S.start()
|
||||
spark(T, 4, alldirs)
|
||||
var/mob/living/silicon/robot/H = new /mob/living/silicon/robot/syndicate(T)
|
||||
H.key = C.key
|
||||
var/newname = sanitizeSafe(input(H,"Enter a name, or leave blank for the default name.", "Name change","") as text, MAX_NAME_LEN)
|
||||
|
||||
@@ -107,7 +107,7 @@ The access requirements on the Asteroid Shuttles' consoles have now been revoked
|
||||
continue
|
||||
|
||||
if (!(C.z in config.admin_levels))
|
||||
C.update_lumcount(0.15, 0.5, 0)
|
||||
C.update_lumcount(0.15, 0.15, 0.5)
|
||||
CHECK_TICK
|
||||
|
||||
/datum/universal_state/supermatter_cascade/proc/MiscSet()
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
visible_message("A red light flashes on \the [src].")
|
||||
return
|
||||
cable.use(amount)
|
||||
if(deleted(cable))
|
||||
if(QDELETED(cable))
|
||||
cable = null
|
||||
return 1
|
||||
|
||||
|
||||
@@ -134,6 +134,35 @@
|
||||
else
|
||||
user << "<span class='warning'>\The [src] has a beaker already.</span>"
|
||||
return
|
||||
else if(istype(I, /obj/item/weapon/grab))
|
||||
|
||||
var/obj/item/weapon/grab/G = I
|
||||
var/mob/living/L = G.affecting
|
||||
|
||||
if(!istype(L))
|
||||
user << "<span class='warning'>\The machine won't accept that.</span>"
|
||||
return
|
||||
|
||||
visible_message("[user] starts putting [G.affecting] into the [src].", 3)
|
||||
|
||||
if (do_mob(user, G.affecting, 20, needhand = 0))
|
||||
if(occupant)
|
||||
user << "<span class='warning'>\The [src] is already occupied.</span>"
|
||||
return
|
||||
var/bucklestatus = L.bucklecheck(user)
|
||||
|
||||
if (!bucklestatus)//incase the patient got buckled during the delay
|
||||
return
|
||||
if(L != G.affecting)//incase it isn't the same mob we started with
|
||||
return
|
||||
|
||||
var/mob/M = G.affecting
|
||||
M.forceMove(src)
|
||||
update_use_power(2)
|
||||
occupant = M
|
||||
update_icon()
|
||||
qdel(G)
|
||||
return
|
||||
|
||||
/obj/machinery/sleeper/MouseDrop_T(var/mob/target, var/mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user)|| !ishuman(target))
|
||||
|
||||
@@ -100,8 +100,8 @@ obj/machinery/computer/general_air_control/Destroy()
|
||||
onclose(user, "computer")
|
||||
|
||||
/obj/machinery/computer/general_air_control/process()
|
||||
..()
|
||||
src.updateUsrDialog()
|
||||
if (operable())
|
||||
src.updateUsrDialog()
|
||||
|
||||
/obj/machinery/computer/general_air_control/receive_signal(datum/signal/signal)
|
||||
if(!signal || signal.encryption) return
|
||||
|
||||
@@ -878,9 +878,7 @@
|
||||
cell.update_icon()
|
||||
cell = null
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
spark(Tsec, 3, alldirs)
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(src.loc)
|
||||
unload(0)
|
||||
|
||||
@@ -258,9 +258,7 @@
|
||||
update_coverage()
|
||||
|
||||
//sparks
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
|
||||
spark_system.set_up(5, 0, loc)
|
||||
spark_system.start()
|
||||
spark(loc, 5)
|
||||
playsound(loc, "sparks", 50, 1)
|
||||
|
||||
/obj/machinery/camera/proc/set_status(var/newstatus)
|
||||
|
||||
@@ -174,11 +174,7 @@ var/global/list/engineering_networks = list(
|
||||
assembly.upgrades.Add(new /obj/item/device/assembly/prox_sensor(assembly))
|
||||
setPowerUsage()
|
||||
if(!(src in machines))
|
||||
if(!machinery_sort_required && ticker)
|
||||
dd_insertObjectList(machines, src)
|
||||
else
|
||||
machines += src
|
||||
machinery_sort_required = 1
|
||||
add_machine(src)
|
||||
update_coverage()
|
||||
|
||||
/obj/machinery/camera/proc/setPowerUsage()
|
||||
|
||||
@@ -80,5 +80,5 @@
|
||||
|
||||
|
||||
/obj/machinery/computer/operating/process()
|
||||
if(..())
|
||||
if(operable())
|
||||
src.updateDialog()
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
crew_announcement.newscast = 1
|
||||
|
||||
/obj/machinery/computer/communications/process()
|
||||
if(..())
|
||||
if(operable())
|
||||
if(state != STATE_STATUSDISPLAY)
|
||||
src.updateDialog()
|
||||
|
||||
|
||||
@@ -23,11 +23,6 @@
|
||||
power_change()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/emp_act(severity)
|
||||
if(prob(20/severity)) set_broken()
|
||||
..()
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
set name = "Eject ID Card"
|
||||
set src in oview(1)
|
||||
|
||||
if(!usr || usr.stat || usr.lying) return
|
||||
if(!usr || usr.stat || usr.lying || usr.restrained() || !Adjacent(usr)) return
|
||||
|
||||
if(scan)
|
||||
usr << "You remove \the [scan] from \the [src]."
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
//Server linked to.
|
||||
var/obj/machinery/message_server/linkedServer = null
|
||||
//Sparks effect - For emag
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread
|
||||
var/datum/effect_system/sparks/spark_system
|
||||
//Messages - Saves me time if I want to change something.
|
||||
var/noserver = "<span class='alert'>ALERT: No server detected.</span>"
|
||||
var/incorrectkey = "<span class='warning'>ALERT: Incorrect decryption key!</span>"
|
||||
@@ -29,6 +29,9 @@
|
||||
var/customjob = "Admin"
|
||||
var/custommessage = "This is a test, please ignore."
|
||||
|
||||
/obj/machinery/computer/message_monitor/New()
|
||||
..()
|
||||
spark_system = bind_spark(src, 5)
|
||||
|
||||
/obj/machinery/computer/message_monitor/attackby(obj/item/weapon/O as obj, mob/living/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
@@ -51,8 +54,7 @@
|
||||
if(!isnull(src.linkedServer))
|
||||
emag = 1
|
||||
screen = 2
|
||||
spark_system.set_up(5, 0, src)
|
||||
src.spark_system.start()
|
||||
src.spark_system.queue()
|
||||
var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey
|
||||
MK.loc = src.loc
|
||||
// Will help make emagging the console not so easy to get away with.
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
|
||||
|
||||
/obj/machinery/computer/pod/process()
|
||||
if(!..())
|
||||
if(inoperable())
|
||||
return
|
||||
if(timing)
|
||||
if(time > 0)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
set name = "Eject ID Card"
|
||||
set src in oview(1)
|
||||
|
||||
if(!usr || usr.stat || usr.lying) return
|
||||
if(!usr || usr.stat || usr.lying || usr.restrained() || !Adjacent(usr)) return
|
||||
|
||||
if(scan)
|
||||
usr << "You remove \the [scan] from \the [src]."
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
set name = "Eject ID Card"
|
||||
set src in oview(1)
|
||||
|
||||
if(!usr || usr.stat || usr.lying) return
|
||||
if(!usr || usr.stat || usr.lying || usr.restrained() || !Adjacent(usr)) return
|
||||
|
||||
if(scan)
|
||||
usr << "You remove \the [scan] from \the [src]."
|
||||
|
||||
@@ -155,3 +155,17 @@
|
||||
user << desc
|
||||
if(P && P.loc != src && !istype(P, /obj/item/stack/cable_coil))
|
||||
user << "<span class='warning'>You cannot add that component to the machine!</span>"
|
||||
|
||||
|
||||
/obj/machinery/constructable_frame/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if (!mover)
|
||||
return 1
|
||||
if(istype(mover,/obj/item/projectile) && density)
|
||||
if (prob(50))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
else if(mover.checkpass(PASSTABLE))
|
||||
//Animals can run under them, lots of empty space
|
||||
return 1
|
||||
return ..()
|
||||
@@ -177,26 +177,27 @@ for reference:
|
||||
user << "Barrier lock toggled off."
|
||||
return
|
||||
else
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(2, 1, src)
|
||||
s.start()
|
||||
spark(src, 2, src)
|
||||
visible_message("<span class='warning'>BZZzZZzZZzZT</span>")
|
||||
return
|
||||
return
|
||||
else if (istype(W, /obj/item/weapon/wrench))
|
||||
if (src.health < src.maxhealth)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
src.health = src.maxhealth
|
||||
src.emagged = 0
|
||||
src.req_access = list(access_security)
|
||||
visible_message("<span class='warning'>[user] repairs \the [src]!</span>")
|
||||
return
|
||||
else if (src.emagged > 0)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
src.emagged = 0
|
||||
src.req_access = list(access_security)
|
||||
visible_message("<span class='warning'>[user] repairs \the [src]!</span>")
|
||||
return
|
||||
return
|
||||
else
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
switch(W.damtype)
|
||||
if("fire")
|
||||
src.health -= W.force * 0.75
|
||||
@@ -241,9 +242,7 @@ for reference:
|
||||
/* var/obj/item/stack/rods/ =*/
|
||||
getFromPool(/obj/item/stack/rods, Tsec)
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
spark(src, 3, alldirs)
|
||||
|
||||
explosion(src.loc,-1,-1,0)
|
||||
if(src)
|
||||
@@ -256,16 +255,12 @@ for reference:
|
||||
src.req_access.Cut()
|
||||
src.req_one_access.Cut()
|
||||
user << "You break the ID authentication lock on \the [src]."
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(2, 1, src)
|
||||
s.start()
|
||||
spark(src, 2, alldirs)
|
||||
visible_message("<span class='warning'>BZZzZZzZZzZT</span>")
|
||||
return 1
|
||||
else if (src.emagged == 1)
|
||||
src.emagged = 2
|
||||
user << "You short out the anchoring mechanism on \the [src]."
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(2, 1, src)
|
||||
s.start()
|
||||
spark(src, 2, 1)
|
||||
visible_message("<span class='warning'>BZZzZZzZZzZT</span>")
|
||||
return 1
|
||||
|
||||
@@ -577,12 +577,12 @@ About the new airlock wires panel:
|
||||
if(locked && lights && src.arePowerSystemsOn())
|
||||
icon_state = "door_locked"
|
||||
if (!has_set_boltlight)
|
||||
set_light(2, 0.75, COLOR_RED_LIGHT, update_type = UPDATE_NONE)
|
||||
set_light(2, 0.75, COLOR_RED_LIGHT)
|
||||
has_set_boltlight = TRUE
|
||||
else
|
||||
icon_state = "door_closed"
|
||||
if (has_set_boltlight)
|
||||
set_light(0, update_type = UPDATE_NONE)
|
||||
set_light(0)
|
||||
has_set_boltlight = FALSE
|
||||
if(p_open || welded)
|
||||
overlays = list()
|
||||
@@ -609,13 +609,9 @@ About the new airlock wires panel:
|
||||
if((stat & BROKEN) && !(stat & NOPOWER))
|
||||
overlays += image(icon, "sparks_open")
|
||||
if (has_set_boltlight)
|
||||
set_light(0, update_type = UPDATE_NONE)
|
||||
set_light(0)
|
||||
has_set_boltlight = FALSE
|
||||
|
||||
if (src)
|
||||
var/turf/T = get_turf(src)
|
||||
if (T)
|
||||
T.update_lights_now()
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/do_animate(animation)
|
||||
@@ -733,9 +729,7 @@ About the new airlock wires panel:
|
||||
if (istype(mover, /obj/item))
|
||||
var/obj/item/i = mover
|
||||
if (i.matter && (DEFAULT_WALL_MATERIAL in i.matter) && i.matter[DEFAULT_WALL_MATERIAL] > 0)
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
spark(src, 5, alldirs)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/door/airlock/attack_hand(mob/user as mob)
|
||||
@@ -971,9 +965,8 @@ About the new airlock wires panel:
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message("[src.name]'s control panel bursts open, sparks spewing out!")
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
spark(src, 5, alldirs)
|
||||
|
||||
update_icon()
|
||||
return
|
||||
|
||||
@@ -1092,7 +1085,7 @@ About the new airlock wires panel:
|
||||
|
||||
// playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
// next_beep_at = world.time + SecondsToTicks(10)
|
||||
close_door_at = world.time + 6
|
||||
close_door_in(6)
|
||||
return
|
||||
for(var/turf/turf in locs)
|
||||
for(var/atom/movable/AM in turf)
|
||||
|
||||
@@ -29,8 +29,9 @@
|
||||
var/hitsound_light = 'sound/effects/Glasshit.ogg'//Sound door makes when hit very gently
|
||||
var/obj/item/stack/material/steel/repairing
|
||||
var/block_air_zones = 1 //If set, air zones cannot merge across the door even when it is opened.
|
||||
var/close_door_at = 0 //When to automatically close the door, if possible
|
||||
var/open_duration = 150//How long it stays open
|
||||
var/datum/scheduled_task/close_task
|
||||
var/datum/scheduled_task/hatch_task
|
||||
|
||||
var/hashatch = 0//If 1, this door has hatches, and certain small creatures can move through them without opening the door
|
||||
var/hatchstate = 0//0: closed, 1: open
|
||||
@@ -41,8 +42,6 @@
|
||||
var/hatch_open_sound = 'sound/machines/hatch_open.ogg'
|
||||
var/hatch_close_sound = 'sound/machines/hatch_close.ogg'
|
||||
|
||||
var/hatchclosetime //A world.time value to tell us when the hatch should close
|
||||
|
||||
var/image/hatch_image
|
||||
|
||||
//Multi-tile doors
|
||||
@@ -107,7 +106,7 @@
|
||||
hatchstate = 1
|
||||
update_icon()
|
||||
playsound(src.loc, hatch_open_sound, 40, 1, -1)
|
||||
hatchclosetime = world.time + 29
|
||||
close_hatch_in(29)
|
||||
|
||||
if (istype(mover, /mob/living))
|
||||
var/mob/living/S = mover
|
||||
@@ -125,16 +124,18 @@
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/machinery/door/process()
|
||||
if(close_door_at && world.time >= close_door_at)
|
||||
if(autoclose)
|
||||
close_door_at = next_close_time()
|
||||
close()
|
||||
else
|
||||
close_door_at = 0
|
||||
if (hatchstate && world.time > hatchclosetime)
|
||||
/obj/machinery/door/proc/close_door_in(var/time = 5 SECONDS)
|
||||
spawn(time)
|
||||
src.close()
|
||||
|
||||
/obj/machinery/door/proc/close_hatch_in(var/time = 5 SECONDS)
|
||||
spawn(time)
|
||||
close_hatch()
|
||||
|
||||
/obj/machinery/door/proc/auto_close()
|
||||
if (!QDELETED(src) && can_close(FALSE) && autoclose)
|
||||
close()
|
||||
|
||||
/obj/machinery/door/proc/can_open()
|
||||
if(!density || operating || !ticker)
|
||||
return 0
|
||||
@@ -429,9 +430,7 @@
|
||||
take_damage(damage)
|
||||
if(3.0)
|
||||
if(prob(80))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(2, 1, src)
|
||||
s.start()
|
||||
spark(src, 2, alldirs)
|
||||
var/damage = rand(100,150)
|
||||
if (bolted)
|
||||
damage *= 0.8
|
||||
@@ -491,19 +490,23 @@
|
||||
operating = 0
|
||||
|
||||
if(autoclose)
|
||||
close_door_at = next_close_time()
|
||||
close_door_in(next_close_time())
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/door/proc/next_close_time()
|
||||
return world.time + (normalspeed ? open_duration : 5)
|
||||
return (normalspeed ? open_duration : 5)
|
||||
|
||||
/obj/machinery/door/proc/close(var/forced = 0)
|
||||
if(!can_close(forced))
|
||||
if (autoclose)
|
||||
for (var/atom/movable/AM in get_turf(src))
|
||||
if (AM.density && AM != src)
|
||||
spawn(60)
|
||||
src.auto_close()
|
||||
return
|
||||
operating = 1
|
||||
|
||||
close_door_at = 0
|
||||
do_animate("closing")
|
||||
sleep(3)
|
||||
src.density = 1
|
||||
@@ -540,8 +543,6 @@
|
||||
update_heat_protection(turf)
|
||||
air_master.mark_for_update(turf)
|
||||
|
||||
T.update_lights_now()
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/door/proc/update_heat_protection(var/turf/simulated/source)
|
||||
|
||||
@@ -179,9 +179,7 @@
|
||||
//Emags and ninja swords? You may pass.
|
||||
if (istype(I, /obj/item/weapon/melee/energy/blade))
|
||||
if(emag_act(10, user))
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
|
||||
spark_system.set_up(5, 0, src.loc)
|
||||
spark_system.start()
|
||||
spark(src.loc, 5)
|
||||
playsound(src.loc, "sparks", 50, 1)
|
||||
playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
|
||||
visible_message("<span class='warning'>The glass door was sliced open by [user]!</span>")
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
var/unlocked = 0
|
||||
var/open = 0
|
||||
var/brightness_on = 8 //can't remember what the maxed out value is
|
||||
light_color = LIGHT_COLOR_TUNGSTEN
|
||||
light_wedge = LIGHT_WIDE
|
||||
|
||||
/obj/machinery/floodlight/New()
|
||||
src.cell = new(src)
|
||||
|
||||
@@ -126,9 +126,7 @@
|
||||
|
||||
|
||||
flick("migniter-spark", src)
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(2, 1, src)
|
||||
s.start()
|
||||
spark(src, 2, 1)
|
||||
src.last_spark = world.time
|
||||
use_power(1000)
|
||||
var/turf/location = src.loc
|
||||
|
||||
@@ -158,9 +158,7 @@ datum/track/New(var/title_name, var/audio)
|
||||
|
||||
explosion(src.loc, 0, 0, 1, rand(1,2), 1)
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
spark(src, 3, alldirs)
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(src.loc)
|
||||
qdel(src)
|
||||
|
||||
@@ -0,0 +1,670 @@
|
||||
// This folder contains code that was originally ported from Apollo Station and then refactored/optimized/changed.
|
||||
|
||||
// Tracks precooked food to stop deep fried baked grilled grilled grilled diona nymph cereal.
|
||||
/obj/item/weapon/reagent_containers/food/snacks/var/list/cooked = list()
|
||||
|
||||
// Root type for cooking machines. See following files for specific implementations.
|
||||
/obj/machinery/appliance
|
||||
name = "cooker"
|
||||
desc = "You shouldn't be seeing this!"
|
||||
icon = 'icons/obj/cooking_machines.dmi'
|
||||
var/appliancetype = 0
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
use_power = 0
|
||||
idle_power_usage = 5 // Power used when turned on, but not processing anything
|
||||
active_power_usage = 1000 // Power used when turned on and actively cooking something
|
||||
|
||||
|
||||
var/cooking_power = 1
|
||||
var/max_contents = 1 // Maximum number of things this appliance can simultaneously cook
|
||||
var/on_icon // Icon state used when cooking.
|
||||
var/off_icon // Icon state used when not cooking.
|
||||
var/cooking // Whether or not the machine is currently operating.
|
||||
var/cook_type // A string value used to track what kind of food this machine makes.
|
||||
var/can_cook_mobs // Whether or not this machine accepts grabbed mobs.
|
||||
var/mobdamagetype = BRUTE // Burn damage for cooking appliances, brute for cereal/candy
|
||||
var/food_color // Colour of resulting food item.
|
||||
var/cooked_sound // Sound played when cooking completes.
|
||||
var/can_burn_food // Can the object burn food that is left inside?
|
||||
var/burn_chance = 10 // How likely is the food to burn?
|
||||
var/list/cooking_objs = list() // List of things being cooked
|
||||
|
||||
// If the machine has multiple output modes, define them here.
|
||||
var/selected_option
|
||||
var/list/output_options = list()
|
||||
var/list/datum/recipe/available_recipes // List of the recipes this appliance could possibly make
|
||||
|
||||
var/container_type = null
|
||||
|
||||
var/combine_first = 0//If 1, this appliance will do combinaiton cooking before checking recipes
|
||||
|
||||
/obj/machinery/appliance/initialize()
|
||||
..()
|
||||
if(output_options.len)
|
||||
verbs += /obj/machinery/appliance/proc/choose_output
|
||||
|
||||
if (!available_recipes)
|
||||
available_recipes = new
|
||||
|
||||
for (var/type in subtypesof(/datum/recipe))
|
||||
var/datum/recipe/test = new type
|
||||
if ((appliancetype & test.appliance))
|
||||
available_recipes += test
|
||||
else
|
||||
qdel(test)
|
||||
|
||||
/obj/machinery/appliance/Destroy()
|
||||
for (var/a in cooking_objs)
|
||||
var/datum/cooking_item/CI = a
|
||||
qdel(CI.container)//Food is fragile, it probably doesnt survive the destruction of the machine
|
||||
cooking_objs -= CI
|
||||
qdel(CI)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/appliance/examine(var/mob/user)
|
||||
..()
|
||||
if(Adjacent(usr))
|
||||
list_contents(user)
|
||||
return 1
|
||||
|
||||
/obj/machinery/appliance/proc/list_contents(var/mob/user)
|
||||
if (cooking_objs.len)
|
||||
var/string = "Contains..."
|
||||
for (var/a in cooking_objs)
|
||||
var/datum/cooking_item/CI = a
|
||||
string += "-\a [CI.container.label(null, CI.combine_target)], [report_progress(CI)]</br>"
|
||||
usr << string
|
||||
else
|
||||
usr << span("notice","It is empty.")
|
||||
|
||||
/obj/machinery/appliance/proc/report_progress(var/datum/cooking_item/CI)
|
||||
if (!CI || !CI.max_cookwork)
|
||||
return null
|
||||
|
||||
if (!CI.cookwork)
|
||||
return "It is cold."
|
||||
var/progress = CI.cookwork / CI.max_cookwork
|
||||
|
||||
if (progress < 0.25)
|
||||
return "It's barely started cooking."
|
||||
if (progress < 0.75)
|
||||
return span("notice","It's cooking away nicely.")
|
||||
if (progress < 1)
|
||||
return span("notice", "<b>It's almost ready!</b>")
|
||||
|
||||
var/half_overcook = (CI.overcook_mult - 1)*0.5
|
||||
if (progress < 1+half_overcook)
|
||||
return span("soghun","<b>It is done !</b>")
|
||||
if (progress < CI.overcook_mult)
|
||||
return span("warning","It looks overcooked, get it out!")
|
||||
else
|
||||
return span("danger","It is burning!!")
|
||||
|
||||
/obj/machinery/appliance/update_icon()
|
||||
if (!stat && cooking_objs.len)
|
||||
icon_state = on_icon
|
||||
|
||||
else
|
||||
icon_state = off_icon
|
||||
|
||||
/obj/machinery/appliance/verb/toggle_power()
|
||||
set src in view()
|
||||
set name = "Toggle Power"
|
||||
set category = "Object"
|
||||
|
||||
if (!isliving(usr))
|
||||
usr << "Ghosts aren't allowed to toggle power switches"
|
||||
return
|
||||
|
||||
if (usr.stat || usr.restrained() || usr.incapacitated())
|
||||
return
|
||||
|
||||
if (!Adjacent(usr))
|
||||
if (!issilicon(usr))
|
||||
usr << "You can't reach the power switch from there, get closer!"
|
||||
return
|
||||
|
||||
if (stat & POWEROFF)//Its turned off
|
||||
stat &= ~POWEROFF
|
||||
use_power = 1
|
||||
if (usr)
|
||||
usr.visible_message("[usr] turns the [src] on", "You turn on the [src]")
|
||||
else //Its on, turn it off
|
||||
stat |= POWEROFF
|
||||
use_power = 0
|
||||
if (usr)
|
||||
usr.visible_message("[usr] turns the [src] off", "You turn off the [src]")
|
||||
|
||||
playsound(src, 'sound/machines/click.ogg', 40, 1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/appliance/proc/choose_output()
|
||||
set src in view()
|
||||
set name = "Choose output"
|
||||
set category = "Object"
|
||||
|
||||
if (!isliving(usr))
|
||||
usr << "Ghosts aren't allowed to mess with cooking machines!"
|
||||
return
|
||||
|
||||
if (usr.stat || usr.restrained() || usr.incapacitated())
|
||||
return
|
||||
|
||||
if (!Adjacent(usr))
|
||||
if (!issilicon(usr))
|
||||
usr << "You can't adjust the [src] from this distance, get closer!"
|
||||
return
|
||||
|
||||
if(output_options.len)
|
||||
|
||||
var/choice = input("What specific food do you wish to make with \the [src]?") as null|anything in output_options+"Default"
|
||||
if(!choice)
|
||||
return
|
||||
if(choice == "Default")
|
||||
selected_option = null
|
||||
usr << "<span class='notice'>You decide not to make anything specific with \the [src].</span>"
|
||||
else
|
||||
selected_option = choice
|
||||
usr << "<span class='notice'>You prepare \the [src] to make \a [selected_option] with the next thing you put in. Try putting several ingredients in a container!</span>"
|
||||
|
||||
//Handles all validity checking and error messages for inserting things
|
||||
/obj/machinery/appliance/proc/can_insert(var/obj/item/I, var/mob/user)
|
||||
if(!dropsafety(I))
|
||||
return 0
|
||||
|
||||
// We are trying to cook a grabbed mob.
|
||||
var/obj/item/weapon/grab/G = I
|
||||
if(istype(G))
|
||||
|
||||
if(!can_cook_mobs)
|
||||
user << "<span class='warning'>That's not going to fit.</span>"
|
||||
return 0
|
||||
|
||||
if(!isliving(G.affecting))
|
||||
user << "<span class='warning'>You can't cook that.</span>"
|
||||
return 0
|
||||
|
||||
return 2
|
||||
|
||||
|
||||
if (!has_space(I))
|
||||
user << "<span class='warning'>There's no room in [src] for that!</span>"
|
||||
return 0
|
||||
|
||||
|
||||
if (container_type && istype(I, container_type))
|
||||
return 1
|
||||
|
||||
// We're trying to cook something else. Check if it's valid.
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/check = I
|
||||
if(istype(check) && islist(check.cooked) && (cook_type in check.cooked))
|
||||
user << "<span class='warning'>\The [check] has already been [cook_type].</span>"
|
||||
return 0
|
||||
else if(istype(check, /obj/item/weapon/reagent_containers/glass))
|
||||
user << "<span class='warning'>That would probably break [src].</span>"
|
||||
return 0
|
||||
else if(istype(check, /obj/item/weapon/disk/nuclear))
|
||||
user << "Central Command would kill you if you [cook_type] that."
|
||||
return 0
|
||||
else if(!istype(check) && !istype(check, /obj/item/weapon/holder))
|
||||
user << "<span class='warning'>That's not edible.</span>"
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
//This function is overridden by cookers that do stuff with containers
|
||||
/obj/machinery/appliance/proc/has_space(var/obj/item/I)
|
||||
if (cooking_objs.len >= max_contents)
|
||||
return 0
|
||||
|
||||
else return 1
|
||||
|
||||
/obj/machinery/appliance/attackby(var/obj/item/I, var/mob/user)
|
||||
if(!cook_type || (stat & (BROKEN)))
|
||||
user << "<span class='warning'>\The [src] is not working.</span>"
|
||||
return
|
||||
|
||||
|
||||
|
||||
var/result = can_insert(I, user)
|
||||
if (!result)
|
||||
return
|
||||
|
||||
if (result == 2)
|
||||
var/obj/item/weapon/grab/G = I
|
||||
if (G && istype(G) && G.affecting)
|
||||
cook_mob(G.affecting, user)
|
||||
return
|
||||
|
||||
|
||||
//From here we can start cooking food
|
||||
add_content(I, user)
|
||||
|
||||
|
||||
update_icon()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Override for container mechanics
|
||||
/obj/machinery/appliance/proc/add_content(var/obj/item/I, var/mob/user)
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
|
||||
var/datum/cooking_item/CI = has_space(I)
|
||||
if (istype(I, /obj/item/weapon/reagent_containers/cooking_container) && CI == 1)
|
||||
var/obj/item/weapon/reagent_containers/cooking_container/CC = I
|
||||
CI = new /datum/cooking_item/(CC)
|
||||
I.forceMove(src)
|
||||
cooking_objs.Add(CI)
|
||||
user.visible_message("<span class='notice'>\The [user] puts \the [I] into \the [src].</span>")
|
||||
if (CC.check_contents() == 0)//If we're just putting an empty container in, then dont start any processing.
|
||||
return
|
||||
else
|
||||
if (CI && istype(CI))
|
||||
I.forceMove(CI.container)
|
||||
|
||||
else //Something went wrong
|
||||
return
|
||||
|
||||
if (selected_option)
|
||||
CI.combine_target = selected_option
|
||||
|
||||
|
||||
// We can actually start cooking now.
|
||||
user.visible_message("<span class='notice'>\The [user] puts \the [I] into \the [src].</span>")
|
||||
|
||||
get_cooking_work(CI)
|
||||
cooking = 1
|
||||
return CI
|
||||
|
||||
/obj/machinery/appliance/proc/get_cooking_work(var/datum/cooking_item/CI)
|
||||
for (var/obj/item/J in CI.container)
|
||||
oilwork(J, CI)
|
||||
|
||||
for (var/r in CI.container.reagents.reagent_list)
|
||||
var/datum/reagent/R = r
|
||||
if (istype(R, /datum/reagent/nutriment))
|
||||
CI.max_cookwork += R.volume *2//Added reagents contribute less than those in food items due to granular form
|
||||
|
||||
//Nonfat reagents will soak oil
|
||||
if (!istype(R, /datum/reagent/nutriment/triglyceride))
|
||||
CI.max_oil += R.volume * 0.25
|
||||
else
|
||||
CI.max_cookwork += R.volume
|
||||
CI.max_oil += R.volume * 0.10
|
||||
|
||||
//Rescaling cooking work to avoid insanely long times for large things
|
||||
var/buffer = CI.max_cookwork
|
||||
CI.max_cookwork = 0
|
||||
var/multiplier = 1
|
||||
var/step = 4
|
||||
while (buffer > step)
|
||||
buffer -= step
|
||||
CI.max_cookwork += step*multiplier
|
||||
multiplier *= 0.95
|
||||
|
||||
CI.max_cookwork += buffer*multiplier
|
||||
|
||||
//Just a helper to save code duplication in the above
|
||||
/obj/machinery/appliance/proc/oilwork(var/obj/item/I, var/datum/cooking_item/CI)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/S = I
|
||||
var/work = 0
|
||||
if (istype(S))
|
||||
if (S.reagents)
|
||||
for (var/r in S.reagents.reagent_list)
|
||||
var/datum/reagent/R = r
|
||||
if (istype(R, /datum/reagent/nutriment))
|
||||
work += R.volume *3//Core nutrients contribute much more than peripheral chemicals
|
||||
|
||||
//Nonfat reagents will soak oil
|
||||
if (!istype(R, /datum/reagent/nutriment/triglyceride))
|
||||
CI.max_oil += R.volume * 0.35
|
||||
else
|
||||
work += R.volume
|
||||
CI.max_oil += R.volume * 0.15
|
||||
|
||||
|
||||
else if(istype(I, /obj/item/weapon/holder))
|
||||
var/obj/item/weapon/holder/H = I
|
||||
if (H.contained)
|
||||
work += (H.contained.mob_size * H.contained.mob_size * 2)+2
|
||||
|
||||
CI.max_cookwork += work
|
||||
|
||||
|
||||
//Called every tick while we're cooking something
|
||||
/obj/machinery/appliance/proc/do_cooking_tick(var/datum/cooking_item/CI)
|
||||
if (!CI.max_cookwork)
|
||||
return 0
|
||||
|
||||
var/was_done = 0
|
||||
if (CI.cookwork >= CI.max_cookwork)
|
||||
was_done = 1
|
||||
|
||||
CI.cookwork += cooking_power
|
||||
|
||||
if (!was_done && CI.cookwork >= CI.max_cookwork)
|
||||
//If cookwork has gone from above to below 0, then this item finished cooking
|
||||
finish_cooking(CI)
|
||||
|
||||
else if (!CI.burned && CI.cookwork > CI.max_cookwork * CI.overcook_mult)
|
||||
burn_food(CI)
|
||||
|
||||
// Gotta hurt.
|
||||
for(var/obj/item/weapon/holder/H in CI.container.contents)
|
||||
var/mob/living/M = H.contained
|
||||
if (M)
|
||||
M.apply_damage(rand(1,3), mobdamagetype, "chest")
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/appliance/process()
|
||||
if (cooking_power > 0 && cooking)
|
||||
for (var/i in cooking_objs)
|
||||
do_cooking_tick(i)
|
||||
|
||||
|
||||
|
||||
/obj/machinery/appliance/proc/finish_cooking(var/datum/cooking_item/CI)
|
||||
|
||||
src.visible_message("<span class='notice'>\The [src] pings!</span>")
|
||||
if(cooked_sound)
|
||||
playsound(get_turf(src), cooked_sound, 50, 1)
|
||||
//Check recipes first, a valid recipe overrides other options
|
||||
var/datum/recipe/recipe = null
|
||||
var/atom/C = null
|
||||
if (CI.container)
|
||||
C = CI.container
|
||||
else
|
||||
C = src
|
||||
recipe = select_recipe(available_recipes,C)
|
||||
|
||||
if (recipe)
|
||||
CI.result_type = 4//Recipe type, a specific recipe will transform the ingredients into a new food
|
||||
var/list/results = recipe.make_food(C)
|
||||
|
||||
var/atom/temp = new /atom //To prevent infinite loops, all results will be moved into a temporary location so they're not considered as inputs for other recipes
|
||||
|
||||
for (var/atom/movable/AM in results)
|
||||
AM.loc = temp
|
||||
|
||||
//making multiple copies of a recipe from one container. For example, tons of fries
|
||||
while (select_recipe(available_recipes,C) == recipe)
|
||||
var/list/TR = recipe.make_food(C)
|
||||
for (var/atom/movable/AM in TR) //Move results to buffer
|
||||
AM.loc = temp
|
||||
results.Add(TR)
|
||||
|
||||
|
||||
for (var/r in results)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/R = r
|
||||
R.loc = C //Move everything from the buffer back to the container
|
||||
R.cooked |= cook_type.
|
||||
|
||||
qdel(temp) //delete buffer object
|
||||
temp = null
|
||||
.=1 //None of the rest of this function is relevant for recipe cooking
|
||||
|
||||
else if(CI.combine_target)
|
||||
CI.result_type = 3//Combination type. We're making something out of our ingredients
|
||||
.=combination_cook(CI)
|
||||
|
||||
|
||||
else
|
||||
//Otherwise, we're just doing standard modification cooking. change a color + name
|
||||
for (var/obj/item/i in CI.container)
|
||||
modify_cook(i, CI)
|
||||
|
||||
//Final step. Cook function just cooks batter for now.
|
||||
for (var/obj/item/weapon/reagent_containers/food/snacks/S in CI.container)
|
||||
S.cook()
|
||||
|
||||
|
||||
//Combination cooking involves combining the names and reagents of ingredients into a predefined output object
|
||||
//The ingredients represent flavours or fillings. EG: donut pizza, cheese bread
|
||||
/obj/machinery/appliance/proc/combination_cook(var/datum/cooking_item/CI)
|
||||
var/cook_path = output_options[CI.combine_target]
|
||||
|
||||
var/list/words = list()
|
||||
var/list/cooktypes = list()
|
||||
var/datum/reagents/buffer = new /datum/reagents(1000)
|
||||
var/totalcolour
|
||||
|
||||
for (var/obj/item/I in CI.container)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/S
|
||||
if (istype(I, /obj/item/weapon/holder))
|
||||
S = create_mob_food(I, CI)
|
||||
else if (istype(I, /obj/item/weapon/reagent_containers/food/snacks))
|
||||
S = I
|
||||
|
||||
if (!S)
|
||||
continue
|
||||
|
||||
words |= dd_text2List(S.name," ")
|
||||
cooktypes |= S.cooked
|
||||
|
||||
|
||||
|
||||
if (S.reagents && S.reagents.total_volume > 0)
|
||||
if (S.filling_color)
|
||||
if (!totalcolour || !buffer.total_volume)
|
||||
totalcolour = S.filling_color
|
||||
else
|
||||
var/t = buffer.total_volume + S.reagents.total_volume
|
||||
t = buffer.total_volume / y
|
||||
totalcolour = BlendRGB(totalcolour, S.filling_color, t)
|
||||
//Blend colours in order to find a good filling color
|
||||
|
||||
|
||||
S.reagents.trans_to_holder(buffer, S.reagents.total_volume)
|
||||
//Cleanup these empty husk ingredients now
|
||||
if (I)
|
||||
qdel(I)
|
||||
if (S)
|
||||
qdel(S)
|
||||
|
||||
CI.container.reagents.trans_to_holder(buffer, CI.container.reagents.total_volume)
|
||||
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/result = new cook_path(CI.container)
|
||||
buffer.trans_to(result, buffer.total_volume)
|
||||
|
||||
//Filling overlay
|
||||
var/image/I = image(result.icon, "[result.icon_state]_filling")
|
||||
I.color = totalcolour
|
||||
result.overlays += I
|
||||
result.filling_color = totalcolour
|
||||
|
||||
//Set the name.
|
||||
words.Remove(list("and", "the", "in", "is", "bar", "raw", "sticks", "boiled", "fried", "deep", "-o-", "warm", "two", "flavored"))
|
||||
//Remove common connecting words and unsuitable ones from the list. Unsuitable words include those describing
|
||||
//the shape, cooked-ness/temperature or other state of an ingredient which doesn't apply to the finished product
|
||||
words.Remove(result.name)
|
||||
shuffle(words)
|
||||
var/num = 6 //Maximum number of words
|
||||
while (num > 0)
|
||||
num--
|
||||
if (!words.len)
|
||||
break
|
||||
//Add prefixes from the ingredients in a random order until we run out or hit limit
|
||||
result.name = "[pop(words)] [result.name]"
|
||||
|
||||
//This proc sets the size of the output result
|
||||
result.update_icon()
|
||||
return result
|
||||
|
||||
//Helper proc for standard modification cooking
|
||||
/obj/machinery/appliance/proc/modify_cook(var/obj/item/input, var/datum/cooking_item/CI)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/result
|
||||
if (istype(input, /obj/item/weapon/holder))
|
||||
result = create_mob_food(input, CI)
|
||||
else if (istype(input, /obj/item/weapon/reagent_containers/food/snacks))
|
||||
result = input
|
||||
else
|
||||
//Nonviable item
|
||||
return
|
||||
|
||||
if (!result)
|
||||
return
|
||||
|
||||
result.cooked |= cook_type.
|
||||
|
||||
// Set icon and appearance.
|
||||
change_product_appearance(result, CI)
|
||||
|
||||
// Update strings.
|
||||
change_product_strings(result, CI)
|
||||
|
||||
/obj/machinery/appliance/proc/burn_food(var/datum/cooking_item/CI)
|
||||
// You dun goofed.
|
||||
CI.burned = 1
|
||||
CI.container.clear()
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/badrecipe(CI.container)
|
||||
|
||||
// Produce nasty smoke.
|
||||
visible_message("<span class='danger'>\The [src] vomits a gout of rancid smoke!</span>")
|
||||
var/datum/effect/effect/system/smoke_spread/bad/smoke = getFromPool(/datum/effect/effect/system/smoke_spread/bad)
|
||||
smoke.attach(src)
|
||||
smoke.set_up(10, 0, get_turf(src), 300)
|
||||
smoke.start()
|
||||
|
||||
/obj/machinery/appliance/attack_hand(var/mob/user)
|
||||
if (cooking_objs.len)
|
||||
if (removal_menu(user))
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/appliance/proc/removal_menu(var/mob/user)
|
||||
if (can_remove_items(user))
|
||||
var/list/menuoptions = list()
|
||||
for (var/a in cooking_objs)
|
||||
var/datum/cooking_item/CI = a
|
||||
if (CI.container)
|
||||
menuoptions[CI.container.label(menuoptions.len)] = CI
|
||||
|
||||
var/selection = input(user, "Which item would you like to remove?", "Remove ingredients") as null|anything in menuoptions
|
||||
if (selection)
|
||||
var/datum/cooking_item/CI = menuoptions[selection]
|
||||
eject(CI, user)
|
||||
update_icon()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/appliance/proc/can_remove_items(var/mob/user)
|
||||
return 1
|
||||
|
||||
/obj/machinery/appliance/proc/eject(var/datum/cooking_item/CI, var/mob/user = null)
|
||||
var/obj/item/thing
|
||||
var/delete = 1
|
||||
var/status = CI.container.check_contents()
|
||||
if (status == 1)//If theres only one object in a container then we extract that
|
||||
thing = locate(/obj/item) in CI.container
|
||||
delete = 0
|
||||
else//If the container is empty OR contains more than one thing, then we must extract the container
|
||||
thing = CI.container
|
||||
if (!user || !user.put_in_hands(thing))
|
||||
thing.forceMove(get_turf(src))
|
||||
|
||||
if (delete)
|
||||
cooking_objs -= CI
|
||||
qdel(CI)
|
||||
else
|
||||
CI.reset()//reset instead of deleting if the container is left inside
|
||||
|
||||
/obj/machinery/appliance/proc/cook_mob(var/mob/living/victim, var/mob/user)
|
||||
return
|
||||
|
||||
/obj/machinery/appliance/proc/change_product_strings(var/obj/item/weapon/reagent_containers/food/snacks/product, var/datum/cooking_item/CI)
|
||||
product.name = "[cook_type] [product.name]"
|
||||
product.desc = "[product.desc] It has been [cook_type]."
|
||||
|
||||
|
||||
/obj/machinery/appliance/proc/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/product, var/datum/cooking_item/CI)
|
||||
if (!product.coating) //Coatings change colour through a new sprite
|
||||
product.color = food_color
|
||||
product.filling_color = food_color
|
||||
|
||||
|
||||
|
||||
|
||||
//This function creates a food item which represents a dead mob
|
||||
/obj/machinery/appliance/proc/create_mob_food(var/obj/item/weapon/holder/H, var/datum/cooking_item/CI)
|
||||
if (!istype(H) || !H.contained)
|
||||
qdel(H)
|
||||
return null
|
||||
var/mob/living/victim = H.contained
|
||||
if (victim.stat != DEAD)
|
||||
return null //Victim somehow survived the cooking, they do not become food
|
||||
|
||||
victim.calculate_composition()
|
||||
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/variable/mob/result = new /obj/item/weapon/reagent_containers/food/snacks/variable/mob(CI.container)
|
||||
result.w_class = victim.mob_size
|
||||
result.reagents.add_reagent(victim.composition_reagent, victim.composition_reagent_quantity)
|
||||
|
||||
if (victim.reagents)
|
||||
victim.reagents.trans_to_holder(result.reagents, victim.reagents.total_volume)
|
||||
|
||||
if (isanimal(victim))
|
||||
var/mob/living/simple_animal/SA = victim
|
||||
result.kitchen_tag = SA.kitchen_tag
|
||||
|
||||
result.appearance = victim
|
||||
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(45)
|
||||
M.Translate(1,-2)
|
||||
result.transform = M
|
||||
|
||||
// all done, now delete the old objects
|
||||
H.contained = null
|
||||
qdel(victim)
|
||||
victim = null
|
||||
qdel(H)
|
||||
H = null
|
||||
|
||||
return result
|
||||
|
||||
|
||||
/datum/cooking_item
|
||||
//var/obj/object
|
||||
var/max_cookwork
|
||||
var/cookwork
|
||||
var/overcook_mult = 2
|
||||
var/result_type = 0
|
||||
var/obj/item/weapon/reagent_containers/cooking_container/container = null
|
||||
var/combine_target = null
|
||||
|
||||
//Result type is one of the following:
|
||||
//0 unfinished, no result yet
|
||||
//1 Standard modification cooking. eg Fried Donk Pocket, Baked wheat, etc
|
||||
//2 Modification but with a new object that's an inert copy of the old. Generally used for deepfried mice
|
||||
//3 Combination cooking, EG Donut Bread, Donk pocket pizza, etc
|
||||
//4:Specific recipe cooking. EG: Turning raw potato sticks into fries
|
||||
|
||||
var/burned = 0
|
||||
|
||||
var/oil = 0
|
||||
var/max_oil = 0//Used for fryers.
|
||||
|
||||
/datum/cooking_item/New(var/obj/item/I)
|
||||
container = I
|
||||
|
||||
|
||||
//This is called for containers whose contents are ejected without removing the container
|
||||
/datum/cooking_item/proc/reset()
|
||||
//object = null
|
||||
max_cookwork = 0
|
||||
cookwork = 0
|
||||
result_type = 0
|
||||
burned = 0
|
||||
max_oil = 0
|
||||
oil = 0
|
||||
combine_target = null
|
||||
//Container is not reset
|
||||
@@ -1,236 +1,142 @@
|
||||
// This folder contains code that was originally ported from Apollo Station and then refactored/optimized/changed.
|
||||
/obj/machinery/appliance/cooker
|
||||
var/temperature = T20C
|
||||
var/min_temp = 353//Minimum temperature to do any cooking
|
||||
var/optimal_temp = 472//Temperature at which we have 100% efficiency. efficiency is lowered on either side of this
|
||||
var/optimal_power = 0.1//cooking power at 100%
|
||||
|
||||
// Tracks precooked food to stop deep fried baked grilled grilled grilled diona nymph cereal.
|
||||
/obj/item/weapon/reagent_containers/food/snacks/var/list/cooked
|
||||
var/loss = 1//Temp lost per proc when equalising
|
||||
var/resistance = 320000//Resistance to heating. combines with active power usage to determine how long heating takes
|
||||
|
||||
// Root type for cooking machines. See following files for specific implementations.
|
||||
/obj/machinery/cooker
|
||||
name = "cooker"
|
||||
desc = "You shouldn't be seeing this!"
|
||||
icon = 'icons/obj/cooking_machines.dmi'
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 5
|
||||
var/light_x = 0
|
||||
var/light_y = 0
|
||||
cooking_power = 0
|
||||
|
||||
var/on_icon // Icon state used when cooking.
|
||||
var/off_icon // Icon state used when not cooking.
|
||||
var/cooking // Whether or not the machine is currently operating.
|
||||
var/cook_type // A string value used to track what kind of food this machine makes.
|
||||
var/cook_time = 200 // How many ticks the cooking will take.
|
||||
var/can_cook_mobs // Whether or not this machine accepts grabbed mobs.
|
||||
var/food_color // Colour of resulting food item.
|
||||
var/cooked_sound // Sound played when cooking completes.
|
||||
var/can_burn_food // Can the object burn food that is left inside?
|
||||
var/burn_chance = 10 // How likely is the food to burn?
|
||||
var/obj/item/cooking_obj // Holder for the currently cooking object.
|
||||
|
||||
// If the machine has multiple output modes, define them here.
|
||||
var/selected_option
|
||||
var/list/output_options = list()
|
||||
|
||||
/obj/machinery/cooker/Destroy()
|
||||
if(cooking_obj)
|
||||
qdel(cooking_obj)
|
||||
cooking_obj = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/cooker/examine()
|
||||
..()
|
||||
if(cooking_obj && Adjacent(usr))
|
||||
usr << "You can see \a [cooking_obj] inside."
|
||||
|
||||
/obj/machinery/cooker/attackby(var/obj/item/I, var/mob/user)
|
||||
if(!cook_type || (stat & (NOPOWER|BROKEN)))
|
||||
user << "<span class='warning'>\The [src] is not working.</span>"
|
||||
return
|
||||
|
||||
if(cooking)
|
||||
user << "<span class='warning'>\The [src] is running!</span>"
|
||||
return
|
||||
|
||||
if(!dropsafety(I))
|
||||
return
|
||||
|
||||
// We are trying to cook a grabbed mob.
|
||||
var/obj/item/weapon/grab/G = I
|
||||
if(istype(G))
|
||||
|
||||
if(!can_cook_mobs)
|
||||
user << "<span class='warning'>That's not going to fit.</span>"
|
||||
return
|
||||
|
||||
if(!isliving(G.affecting))
|
||||
user << "<span class='warning'>You can't cook that.</span>"
|
||||
return
|
||||
|
||||
cook_mob(G.affecting, user)
|
||||
return
|
||||
|
||||
// We're trying to cook something else. Check if it's valid.
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/check = I
|
||||
if(istype(check) && islist(check.cooked) && (cook_type in check.cooked))
|
||||
user << "<span class='warning'>\The [check] has already been [cook_type].</span>"
|
||||
return 0
|
||||
else if(istype(check, /obj/item/weapon/reagent_containers/glass))
|
||||
user << "<span class='warning'>That would probably break [src].</span>"
|
||||
return 0
|
||||
else if(istype(check, /obj/item/weapon/disk/nuclear))
|
||||
user << "Central Command would kill you if you [cook_type] that."
|
||||
return 0
|
||||
else if(!istype(check) && !istype(check, /obj/item/weapon/holder))
|
||||
user << "<span class='warning'>That's not edible.</span>"
|
||||
return 0
|
||||
|
||||
// Gotta hurt.
|
||||
if(istype(cooking_obj, /obj/item/weapon/holder))
|
||||
for(var/mob/living/M in cooking_obj.contents)
|
||||
M.apply_damage(rand(30,40), BURN, "chest")
|
||||
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
|
||||
// We can actually start cooking now.
|
||||
user.visible_message("<span class='notice'>\The [user] puts \the [I] into \the [src].</span>")
|
||||
cooking_obj = I
|
||||
cooking_obj.forceMove(src)
|
||||
cooking = 1
|
||||
icon_state = on_icon
|
||||
|
||||
sleep(cook_time)
|
||||
|
||||
// Sanity checks.
|
||||
if (!check_cooking_obj())
|
||||
return
|
||||
|
||||
if(istype(cooking_obj, /obj/item/weapon/holder))
|
||||
for(var/mob/living/M in cooking_obj.contents)
|
||||
M.death()
|
||||
|
||||
// Cook the food.
|
||||
var/cook_path
|
||||
if(selected_option && output_options.len)
|
||||
cook_path = output_options[selected_option]
|
||||
if(!cook_path)
|
||||
cook_path = /obj/item/weapon/reagent_containers/food/snacks/variable
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/result = new cook_path(src) //Holy typepaths, Batman.
|
||||
|
||||
if(cooking_obj && cooking_obj.reagents && cooking_obj.reagents.total_volume)
|
||||
cooking_obj.reagents.trans_to(result, cooking_obj.reagents.total_volume)
|
||||
|
||||
// Set icon and appearance.
|
||||
change_product_appearance(result)
|
||||
|
||||
// Update strings.
|
||||
change_product_strings(result)
|
||||
|
||||
// Set cooked data.
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/food_item = cooking_obj
|
||||
if(istype(food_item) && islist(food_item.cooked))
|
||||
result.cooked = food_item.cooked.Copy()
|
||||
else
|
||||
result.cooked = list()
|
||||
result.cooked |= cook_type
|
||||
|
||||
// Reset relevant variables.
|
||||
qdel(cooking_obj)
|
||||
src.visible_message("<span class='notice'>\The [src] pings!</span>")
|
||||
if(cooked_sound)
|
||||
playsound(get_turf(src), cooked_sound, 50, 1)
|
||||
|
||||
if(!can_burn_food)
|
||||
icon_state = off_icon
|
||||
cooking = 0
|
||||
result.forceMove(get_turf(src))
|
||||
cooking_obj = null
|
||||
else
|
||||
var/failed
|
||||
var/overcook_period = max(Floor(cook_time/5),1)
|
||||
cooking_obj = result
|
||||
while(1)
|
||||
sleep(overcook_period)
|
||||
if(!cooking || !result || result.loc != src)
|
||||
failed = 1
|
||||
else if(prob(burn_chance))
|
||||
// You dun goofed.
|
||||
qdel(cooking_obj)
|
||||
cooking_obj = new /obj/item/weapon/reagent_containers/food/snacks/badrecipe(src)
|
||||
// Produce nasty smoke.
|
||||
visible_message("<span class='danger'>\The [src] vomits a gout of rancid smoke!</span>")
|
||||
var/datum/effect/effect/system/smoke_spread/bad/smoke = getFromPool(/datum/effect/effect/system/smoke_spread/bad)
|
||||
smoke.attach(src)
|
||||
smoke.set_up(10, 0, usr.loc)
|
||||
smoke.start()
|
||||
failed = 1
|
||||
|
||||
if(failed)
|
||||
cooking = 0
|
||||
icon_state = off_icon
|
||||
break
|
||||
|
||||
/obj/machinery/cooker/proc/check_cooking_obj()
|
||||
if(!cooking_obj || cooking_obj.loc != src)
|
||||
cooking_obj = null
|
||||
icon_state = off_icon
|
||||
cooking = 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/cooker/attack_hand(var/mob/user)
|
||||
|
||||
if(cooking_obj)
|
||||
user << "<span class='notice'>You grab \the [cooking_obj] from \the [src].</span>"
|
||||
user.put_in_hands(cooking_obj)
|
||||
cooking = 0
|
||||
cooking_obj = null
|
||||
icon_state = off_icon
|
||||
return
|
||||
|
||||
if(output_options.len)
|
||||
|
||||
if(cooking)
|
||||
user << "<span class='warning'>\The [src] is in use!</span>"
|
||||
return
|
||||
|
||||
var/choice = input("What specific food do you wish to make with \the [src]?") as null|anything in output_options+"Default"
|
||||
if(!choice)
|
||||
return
|
||||
if(choice == "Default")
|
||||
selected_option = null
|
||||
user << "<span class='notice'>You decide not to make anything specific with \the [src].</span>"
|
||||
/obj/machinery/appliance/cooker/examine(var/mob/user)
|
||||
.=..()
|
||||
if (.)//no need to duplicate adjacency check
|
||||
if (!stat)
|
||||
if (temperature < min_temp)
|
||||
user << span("warning", "It is heating up.")
|
||||
else
|
||||
user << span("notice", "It is running at [round(get_efficiency(), 0.1)]% efficiency!")
|
||||
user << "Temperature: [round(temperature - T0C, 0.1)]C / [round(optimal_temp - T0C, 0.1)]C"
|
||||
else
|
||||
selected_option = choice
|
||||
user << "<span class='notice'>You prepare \the [src] to make \a [selected_option].</span>"
|
||||
user << span("warning", "It is switched off.")
|
||||
|
||||
/obj/machinery/appliance/cooker/list_contents(var/mob/user)
|
||||
if (cooking_objs.len)
|
||||
var/string = "Contains...</br>"
|
||||
var/num = 0
|
||||
for (var/a in cooking_objs)
|
||||
num++
|
||||
var/datum/cooking_item/CI = a
|
||||
if (CI && CI.container)
|
||||
string += "- [CI.container.label(num)], [report_progress(CI)]</br>"
|
||||
usr << string
|
||||
else
|
||||
usr << span("notice","It is empty.")
|
||||
|
||||
/obj/machinery/appliance/cooker/proc/get_efficiency()
|
||||
. = cooking_power / optimal_power
|
||||
. *= 100
|
||||
|
||||
/obj/machinery/appliance/cooker/New()
|
||||
..()
|
||||
loss = (active_power_usage / resistance)*0.5
|
||||
cooking_objs = list()
|
||||
for (var/i = 0, i < max_contents, i++)
|
||||
cooking_objs.Add(new /datum/cooking_item/(new container_type(src)))
|
||||
cooking = 0
|
||||
|
||||
/obj/machinery/appliance/cooker/update_icon()
|
||||
overlays.Cut()
|
||||
var/image/light
|
||||
if (use_power == 2 && !stat)
|
||||
light = image(icon, "light_on")
|
||||
else
|
||||
light = image(icon, "light_off")
|
||||
light.pixel_x = light_x
|
||||
light.pixel_y = light_y
|
||||
overlays += light
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/machinery/appliance/cooker/process()
|
||||
if (!stat)
|
||||
heat_up()
|
||||
|
||||
else
|
||||
var/turf/T = get_turf(src)
|
||||
if (temperature > T.temperature)
|
||||
equalize_temperature()
|
||||
..()
|
||||
|
||||
/obj/machinery/cooker/proc/cook_mob(var/mob/living/victim, var/mob/user)
|
||||
return
|
||||
/obj/machinery/appliance/cooker/power_change()
|
||||
.=..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/cooker/proc/change_product_strings(var/obj/item/weapon/reagent_containers/food/snacks/product)
|
||||
if(product.type == /obj/item/weapon/reagent_containers/food/snacks/variable) // Base type, generic.
|
||||
product.name = "[cook_type] [cooking_obj.name]"
|
||||
product.desc = "[cooking_obj.desc] It has been [cook_type]."
|
||||
/obj/machinery/appliance/cooker/proc/update_cooking_power()
|
||||
var/temp_scale = 0
|
||||
if(temperature > min_temp)
|
||||
|
||||
temp_scale = (temperature - min_temp) / (optimal_temp - min_temp)
|
||||
//If we're between min and optimal this will yield a value in the range 0-1
|
||||
|
||||
if (temp_scale > 1)
|
||||
//We're above optimal, efficiency goes down as we pass too much over it
|
||||
if (temp_scale >= 2)
|
||||
temp_scale = 0
|
||||
else
|
||||
temp_scale = 1 - (temp_scale - 1)
|
||||
|
||||
|
||||
cooking_power = optimal_power * temp_scale
|
||||
|
||||
/obj/machinery/appliance/cooker/proc/heat_up()
|
||||
if (temperature < optimal_temp)
|
||||
if (use_power == 1 && ((optimal_temp - temperature) > 5))
|
||||
playsound(src, 'sound/machines/click.ogg', 20, 1)
|
||||
use_power = 2.//If we're heating we use the active power
|
||||
update_icon()
|
||||
temperature += active_power_usage / resistance
|
||||
update_cooking_power()
|
||||
return 1
|
||||
else
|
||||
product.name = "[cooking_obj.name] [product.name]"
|
||||
if (use_power == 2)
|
||||
use_power = 1
|
||||
playsound(src, 'sound/machines/click.ogg', 20, 1)
|
||||
update_icon()
|
||||
//We're holding steady. temperature falls more slowly
|
||||
if (prob(25))
|
||||
equalize_temperature()
|
||||
return -1
|
||||
|
||||
/obj/machinery/cooker/proc/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/product)
|
||||
if(product.type == /obj/item/weapon/reagent_containers/food/snacks/variable) // Base type, generic.
|
||||
product.appearance = cooking_obj
|
||||
product.color = food_color
|
||||
product.filling_color = food_color
|
||||
|
||||
if(istype(cooking_obj, /obj/item/weapon/holder))
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(90)
|
||||
M.Translate(1,-6)
|
||||
product.transform = M
|
||||
/obj/machinery/appliance/cooker/proc/equalize_temperature()
|
||||
temperature -= loss//Temperature will fall somewhat slowly
|
||||
update_cooking_power()
|
||||
|
||||
|
||||
//Cookers do differently, they use containers
|
||||
/obj/machinery/appliance/cooker/has_space(var/obj/item/I)
|
||||
|
||||
if (istype(I, /obj/item/weapon/reagent_containers/cooking_container) && cooking_objs.len < max_contents)
|
||||
//Containers can go into an empty slot
|
||||
return 1
|
||||
|
||||
else
|
||||
var/image/I = image(product.icon, "[product.icon_state]_filling")
|
||||
if(istype(cooking_obj, /obj/item/weapon/reagent_containers/food/snacks))
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/S = cooking_obj
|
||||
I.color = S.filling_color
|
||||
if(!I.color)
|
||||
I.color = food_color
|
||||
product.overlays += I
|
||||
|
||||
//Any food items directly added need an empty container. A slot without a container cant hold food
|
||||
for (var/datum/cooking_item/CI in cooking_objs)
|
||||
if (CI.container.check_contents() == 0)
|
||||
return CI
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/appliance/cooker/add_content(var/obj/item/I, var/mob/user)
|
||||
var/datum/cooking_item/CI = ..()
|
||||
if (CI.combine_target)
|
||||
user << "The [I] will be used to make a [selected_option]. Output selection is returned to default for future items."
|
||||
selected_option = null
|
||||
@@ -5,67 +5,158 @@
|
||||
desc = "If you can see this description then something is wrong. Please report the bug on the tracker."
|
||||
bitesize = 2
|
||||
|
||||
var/size = 5 //The quantity of reagents which is considered "normal" for this kind of food
|
||||
//These objects will change size depending on the ratio of reagents to this value
|
||||
var/min_scale = 0.5
|
||||
var/max_scale = 2
|
||||
var/scale = 1
|
||||
|
||||
w_class = 2
|
||||
var/prefix
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/New()
|
||||
..()
|
||||
if (reagents)
|
||||
reagents.maximum_volume = size*8 + 10
|
||||
else
|
||||
create_reagents(size*8 + 10)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/update_icon()
|
||||
if (reagents && reagents.total_volume)
|
||||
var/ratio = reagents.total_volume / size
|
||||
|
||||
scale = cubert(ratio) //Scaling factor is square root of desired area
|
||||
scale = Clamp(scale, min_scale, max_scale)
|
||||
else
|
||||
scale = min_scale
|
||||
|
||||
var/matrix/M = matrix()
|
||||
M.Scale(scale)
|
||||
src.transform = M
|
||||
|
||||
w_class *= scale
|
||||
if (!prefix)
|
||||
if (scale == min_scale)
|
||||
prefix = "tiny"
|
||||
else if (scale <= 0.8)
|
||||
prefix = "small"
|
||||
|
||||
else
|
||||
if (scale >= 1.2)
|
||||
prefix = "large"
|
||||
if (scale >= 1.4)
|
||||
prefix = "extra large"
|
||||
if (scale >= 1.6)
|
||||
prefix = "huge"
|
||||
if (scale >= max_scale)
|
||||
prefix = "massive"
|
||||
|
||||
name = "[prefix] [name]"
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/pizza
|
||||
name = "personal pizza"
|
||||
desc = "A personalized pan pizza meant for only one person."
|
||||
icon_state = "personal_pizza"
|
||||
size = 20
|
||||
w_class = 3
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/bread
|
||||
name = "bread"
|
||||
desc = "Tasty bread."
|
||||
icon_state = "breadcustom"
|
||||
size = 40
|
||||
w_class = 3
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/pie
|
||||
name = "pie"
|
||||
desc = "Tasty pie."
|
||||
icon_state = "piecustom"
|
||||
size = 25
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/cake
|
||||
name = "cake"
|
||||
desc = "A popular band."
|
||||
icon_state = "cakecustom"
|
||||
size = 40
|
||||
w_class = 3
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/pocket
|
||||
name = "hot pocket"
|
||||
desc = "You wanna put a bangin- oh, nevermind."
|
||||
icon_state = "donk"
|
||||
size = 8
|
||||
w_class = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/kebab
|
||||
name = "kebab"
|
||||
desc = "Remove this!"
|
||||
icon_state = "kabob"
|
||||
size = 10
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/waffles
|
||||
name = "waffles"
|
||||
desc = "Made with love."
|
||||
icon_state = "waffles"
|
||||
size = 12
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/cookie
|
||||
name = "cookie"
|
||||
desc = "Sugar snap!"
|
||||
icon_state = "cookie"
|
||||
size = 6
|
||||
w_class = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/donut
|
||||
name = "filled donut"
|
||||
desc = "Donut eat this!" // kill me
|
||||
icon_state = "donut"
|
||||
size = 8
|
||||
w_class = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/jawbreaker
|
||||
name = "flavored jawbreaker"
|
||||
desc = "It's like cracking a molar on a rainbow."
|
||||
icon_state = "jawbreaker"
|
||||
size = 4
|
||||
w_class = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/candybar
|
||||
name = "flavored chocolate bar"
|
||||
desc = "Made in a factory downtown."
|
||||
icon_state = "bar"
|
||||
size = 6
|
||||
w_class = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/sucker
|
||||
name = "flavored sucker"
|
||||
desc = "Suck, suck, suck."
|
||||
icon_state = "sucker"
|
||||
size = 4
|
||||
w_class = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/jelly
|
||||
name = "jelly"
|
||||
desc = "All your friends will be jelly."
|
||||
icon_state = "jellycustom"
|
||||
size = 8
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/cereal
|
||||
name = "cereal"
|
||||
desc = "Crispy and flaky"
|
||||
icon_state = "cereal_box"
|
||||
size = 30
|
||||
w_class = 3
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/cereal/New()
|
||||
..()
|
||||
name = pick(list("flakes", "krispies", "crunch", "pops", "O's", "crisp", "loops", "jacks", "clusters"))
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/variable/mob
|
||||
desc = "Poor little thing"
|
||||
size = 5
|
||||
w_class = 1
|
||||
var/kitchen_tag = "animal"
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
The mixer subtype is used for the candymaker and cereal maker. They are similar to cookers but with a few
|
||||
fundamental differences
|
||||
|
||||
|
||||
1. They have a single container which cant be removed. it will eject multiple contents
|
||||
2. Items can't be added or removed once the process starts
|
||||
3. Items are all placed in the same container when added directly
|
||||
4. They do combining mode only. And will always combine the entire contents of the container into an output
|
||||
*/
|
||||
|
||||
/obj/machinery/appliance/mixer
|
||||
max_contents = 1
|
||||
stat = POWEROFF
|
||||
cooking_power = 0.4
|
||||
active_power_usage = 3000
|
||||
idle_power_usage = 50
|
||||
|
||||
/obj/machinery/appliance/mixer/examine(var/mob/user)
|
||||
..()
|
||||
user << span("notice", "It is currently set to make a [selected_option]")
|
||||
|
||||
/obj/machinery/appliance/mixer/New()
|
||||
..()
|
||||
cooking_objs.Add(new /datum/cooking_item/(new /obj/item/weapon/reagent_containers/cooking_container(src)))
|
||||
cooking = 0
|
||||
selected_option = pick(output_options)
|
||||
|
||||
//Mixers cannot-not do combining mode. So the default option is removed from this. A combine target must be chosen
|
||||
/obj/machinery/appliance/mixer/choose_output()
|
||||
set src in view()
|
||||
set name = "Choose output"
|
||||
set category = "Object"
|
||||
|
||||
if(output_options.len)
|
||||
|
||||
var/choice = input("What specific food do you wish to make with \the [src]?") as null|anything in output_options
|
||||
if(!choice)
|
||||
return
|
||||
else
|
||||
selected_option = choice
|
||||
user << "<span class='notice'>You prepare \the [src] to make \a [selected_option].</span>"
|
||||
var/datum/cooking_item/CI = cooking_objs[1]
|
||||
CI.combine_target = selected_option
|
||||
|
||||
|
||||
/obj/machinery/appliance/mixer/has_space(var/obj/item/I)
|
||||
var/datum/cooking_item/CI = cooking_objs[1]
|
||||
if (!CI || !CI.container)
|
||||
return 0
|
||||
|
||||
if (CI.container.can_fit(I))
|
||||
return CI
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/appliance/mixer/can_remove_items(var/mob/user)
|
||||
if (stat)
|
||||
return 1
|
||||
else
|
||||
user << span("warning", "You can't remove ingredients while its turned on! Turn it off first or wait for it to finish.")
|
||||
|
||||
//Container is not removable
|
||||
/obj/machinery/appliance/mixer/removal_menu(var/mob/user)
|
||||
if (can_remove_items(user))
|
||||
var/list/menuoptions = list()
|
||||
for (var/a in cooking_objs)
|
||||
var/datum/cooking_item/CI = a
|
||||
if (CI.container)
|
||||
if (!CI.container.check_contents())
|
||||
user << "There's nothing in the [src] you can remove!"
|
||||
return
|
||||
|
||||
for (var/obj/item/I in CI.container)
|
||||
menuoptions[I.name] = I
|
||||
|
||||
var/selection = input(user, "Which item would you like to remove? If you want to remove chemicals, use an empty beaker.", "Remove ingredients") as null|anything in menuoptions
|
||||
if (selection)
|
||||
var/obj/item/I = menuoptions[selection]
|
||||
if (!user || !user.put_in_hands(I))
|
||||
I.forceMove(get_turf(src))
|
||||
update_icon()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/appliance/mixer/toggle_power()
|
||||
set src in view()
|
||||
set name = "Toggle Power"
|
||||
set category = "Object"
|
||||
|
||||
var/datum/cooking_item/CI = cooking_objs[1]
|
||||
if (!CI.container.check_contents())
|
||||
usr << "There's nothing in it! Add ingredients before turning [src] on!"
|
||||
return
|
||||
|
||||
if (stat & POWEROFF)//Its turned off
|
||||
stat &= ~POWEROFF
|
||||
if (usr)
|
||||
usr.visible_message("[usr] turns the [src] on", "You turn on the [src]")
|
||||
get_cooking_work(CI)
|
||||
use_power = 2
|
||||
else //Its on, turn it off
|
||||
stat |= POWEROFF
|
||||
use_power = 0
|
||||
if (usr)
|
||||
usr.visible_message("[usr] turns the [src] off", "You turn off the [src]")
|
||||
playsound(src, 'sound/machines/click.ogg', 40, 1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/appliance/mixer/can_insert(var/obj/item/I, var/mob/user)
|
||||
if (!stat)
|
||||
user << span("warning","You can't add items while \the [src] is running. Wait for it to finish or turn the power off to abort")
|
||||
return 0
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/appliance/mixer/finish_cooking(var/datum/cooking_item/CI)
|
||||
..()
|
||||
stat |= POWEROFF
|
||||
playsound(src, 'sound/machines/click.ogg', 40, 1)
|
||||
use_power = 0
|
||||
CI.reset()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/appliance/mixer/update_icon()
|
||||
if (!stat)
|
||||
icon_state = on_icon
|
||||
else
|
||||
icon_state = off_icon
|
||||
|
||||
|
||||
/obj/machinery/appliance/mixer/process()
|
||||
if (!stat)
|
||||
for (var/i in cooking_objs)
|
||||
do_cooking_tick(i)
|
||||
@@ -1,10 +1,12 @@
|
||||
/obj/machinery/cooker/candy
|
||||
/obj/machinery/appliance/mixer/candy
|
||||
name = "candy machine"
|
||||
desc = "Get yer candied cheese wheels here!"
|
||||
icon_state = "mixer_off"
|
||||
off_icon = "mixer_off"
|
||||
on_icon = "mixer_on"
|
||||
cook_type = "candied"
|
||||
appliancetype = CANDYMAKER
|
||||
cooking_power = 0.6
|
||||
|
||||
output_options = list(
|
||||
"Jawbreaker" = /obj/item/weapon/reagent_containers/food/snacks/variable/jawbreaker,
|
||||
@@ -13,6 +15,6 @@
|
||||
"Jelly" = /obj/item/weapon/reagent_containers/food/snacks/variable/jelly
|
||||
)
|
||||
|
||||
/obj/machinery/cooker/candy/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/cooked/product)
|
||||
/obj/machinery/appliance/mixer/candy/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/cooked/product)
|
||||
food_color = get_random_colour(1)
|
||||
. = ..()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/machinery/cooker/cereal
|
||||
/obj/machinery/appliance/mixer/cereal
|
||||
name = "cereal maker"
|
||||
desc = "Now with Dann O's available!"
|
||||
icon = 'icons/obj/cooking_machines.dmi'
|
||||
@@ -6,20 +6,57 @@
|
||||
cook_type = "cerealized"
|
||||
on_icon = "cereal_on"
|
||||
off_icon = "cereal_off"
|
||||
appliancetype = CEREALMAKER
|
||||
|
||||
/obj/machinery/cooker/cereal/change_product_strings(var/obj/item/weapon/reagent_containers/food/snacks/product)
|
||||
output_options = list(
|
||||
"Cereal" = /obj/item/weapon/reagent_containers/food/snacks/variable/cereal
|
||||
)
|
||||
|
||||
/*
|
||||
/obj/machinery/appliance/cereal/change_product_strings(var/obj/item/weapon/reagent_containers/food/snacks/product, var/datum/cooking_item/CI)
|
||||
. = ..()
|
||||
product.name = "box of [cooking_obj.name] cereal"
|
||||
product.name = "box of [CI.object.name] cereal"
|
||||
|
||||
/obj/machinery/cooker/cereal/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/product)
|
||||
/obj/machinery/appliance/cereal/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/product, var/datum/cooking_item/CI)
|
||||
product.icon = 'icons/obj/food.dmi'
|
||||
product.icon_state = "cereal_box"
|
||||
product.filling_color = cooking_obj.color
|
||||
product.filling_color = CI.object.color
|
||||
|
||||
var/image/food_image = image(cooking_obj.icon, cooking_obj.icon_state)
|
||||
food_image.color = cooking_obj.color
|
||||
food_image.overlays += cooking_obj.overlays
|
||||
var/image/food_image = image(CI.object.icon, CI.object.icon_state)
|
||||
food_image.color = CI.object.color
|
||||
food_image.overlays += CI.object.overlays
|
||||
food_image.transform *= 0.7
|
||||
|
||||
product.overlays += food_image
|
||||
*/
|
||||
|
||||
/obj/machinery/appliance/mixer/cereal/combination_cook(var/datum/cooking_item/CI)
|
||||
|
||||
var/list/images = list()
|
||||
var/num = 0
|
||||
for (var/obj/item/I in CI.container).
|
||||
if (istype(I, /obj/item/weapon/reagent_containers/food/snacks/variable/cereal))
|
||||
//Images of cereal boxes on cereal boxes is dumb
|
||||
continue
|
||||
|
||||
var/image/food_image = image(I.icon, I.icon_state)
|
||||
food_image.color = I.color
|
||||
food_image.overlays += I.overlays
|
||||
food_image.transform *= 0.7 - (num * 0.05)
|
||||
food_image.pixel_x = rand(-2,2)
|
||||
food_image.pixel_y = rand(-3,5)
|
||||
|
||||
|
||||
if (!images[I.icon_state])
|
||||
images[I.icon_state] = food_image
|
||||
num++
|
||||
|
||||
if (num > 3)
|
||||
continue
|
||||
|
||||
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/result = ..()
|
||||
|
||||
result.color = result.filling_color
|
||||
for (var/i in images)
|
||||
result.overlays += images[i]
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
//Cooking containers are used in ovens and fryers, to hold multiple ingredients for a recipe.
|
||||
//They work fairly similar to the microwave - acting as a container for objects and reagents,
|
||||
//which can be checked against recipe requirements in order to cook recipes that require several things
|
||||
|
||||
/obj/item/weapon/reagent_containers/cooking_container
|
||||
icon = 'icons/obj/cooking_machines.dmi'
|
||||
var/shortname
|
||||
var/max_space = 20//Maximum sum of w-classes of foods in this container at once
|
||||
var/max_reagents = 80//Maximum units of reagents
|
||||
|
||||
/obj/item/weapon/reagent_containers/cooking_container/New()
|
||||
..()
|
||||
create_reagents(max_reagents)
|
||||
flags |= OPENCONTAINER
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/cooking_container/examine(var/mob/user)
|
||||
..()
|
||||
if (contents.len)
|
||||
var/string = "It contains....</br>"
|
||||
for (var/atom/movable/A in contents)
|
||||
string += "[A.name] </br>"
|
||||
user << span("notice", string)
|
||||
if (reagents.total_volume)
|
||||
user << span("notice", "It contains [reagents.total_volume]u of reagents.")
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/cooking_container/attackby(var/obj/item/I as obj, var/mob/user as mob)
|
||||
if (istype(I, /obj/item/weapon/reagent_containers/food/snacks))
|
||||
if (!can_fit(I))
|
||||
user << span("warning","There's no more space in the [src] for that!")
|
||||
return 0
|
||||
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
I.forceMove(src)
|
||||
user << span("notice", "You put the [I] into the [src]")
|
||||
|
||||
/obj/item/weapon/reagent_containers/cooking_container/verb/empty()
|
||||
set src in view()
|
||||
set name = "Empty Container"
|
||||
set category = "Object"
|
||||
set desc = "Removes items from the container. does not remove reagents."
|
||||
|
||||
if (!Adjacent(usr))
|
||||
usr << "You can't reach the [src] from there, get closer!"
|
||||
return
|
||||
|
||||
for (var/atom/movable/A in contents)
|
||||
A.forceMove(get_turf(src))
|
||||
|
||||
/obj/item/weapon/reagent_containers/cooking_container/proc/check_contents()
|
||||
if (contents.len == 0)
|
||||
if (!reagents || reagents.total_volume == 0)
|
||||
return 0//Completely empty
|
||||
else if (contents.len == 1)
|
||||
if (!reagents || reagents.total_volume == 0)
|
||||
return 1//Contains only a single object which can be extracted alone
|
||||
return 2//Contains multiple objects and/or reagents
|
||||
|
||||
|
||||
|
||||
//Deletes contents of container.
|
||||
//Used when food is burned, before replacing it with a burned mess
|
||||
/obj/item/weapon/reagent_containers/cooking_container/proc/clear()
|
||||
for (var/atom/a in contents)
|
||||
qdel(a)
|
||||
|
||||
if (reagents)
|
||||
reagents.clear_reagents()
|
||||
|
||||
/obj/item/weapon/reagent_containers/cooking_container/proc/label(var/number, var/CT = null)
|
||||
//This returns something like "Fryer basket 1 - empty"
|
||||
//The latter part is a brief reminder of contents
|
||||
//This is used in the removal menu
|
||||
. = shortname
|
||||
if (!isnull(number))
|
||||
.+= " [number]"
|
||||
.+= " - "
|
||||
if (CT)
|
||||
.+=CT
|
||||
else if (contents.len)
|
||||
for (var/obj/O in contents)
|
||||
.+=O.name//Just append the name of the first object
|
||||
return
|
||||
else if (reagents && reagents.total_volume > 0)
|
||||
var/datum/reagent/R = reagents.get_master_reagent()
|
||||
.+=R.name//Append name of most voluminous reagent
|
||||
return
|
||||
else
|
||||
. += "empty"
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/cooking_container/proc/can_fit(var/obj/item/I)
|
||||
var/total = 0
|
||||
for (var/obj/item/J in contents)
|
||||
total += J.w_class
|
||||
|
||||
if((max_space - total) >= I.w_class)
|
||||
return 1
|
||||
|
||||
|
||||
//Takes a reagent holder as input and distributes its contents among the items in the container
|
||||
//Distribution is weighted based on the volume already present in each item
|
||||
/obj/item/weapon/reagent_containers/cooking_container/proc/soak_reagent(var/datum/reagents/holder)
|
||||
var/total = 0
|
||||
var/list/weights = list()
|
||||
for (var/obj/item/I in contents)
|
||||
if (I.reagents && I.reagents.total_volume)
|
||||
total += I.reagents.total_volume
|
||||
weights[I] = I.reagents.total_volume
|
||||
|
||||
if (total > 0)
|
||||
for (var/obj/item/I in contents)
|
||||
if (weights[I])
|
||||
holder.trans_to(I, weights[I] / total)
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/cooking_container/oven
|
||||
name = "Oven Dish"
|
||||
shortname = "shelf"
|
||||
desc = "Put ingredients in this for cooking to a recipe,in an oven."
|
||||
icon_state = "ovendish"
|
||||
max_space = 30
|
||||
max_reagents = 120
|
||||
|
||||
/obj/item/weapon/reagent_containers/cooking_container/fryer
|
||||
name = "Fryer basket"
|
||||
shortname = "basket"
|
||||
desc = "Belongs in a deep fryer, put ingredients in it for cooking to a recipe"
|
||||
icon_state = "basket"
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/machinery/cooker/fryer
|
||||
/obj/machinery/appliance/cooker/fryer
|
||||
name = "deep fryer"
|
||||
desc = "Deep fried <i>everything</i>."
|
||||
icon_state = "fryer_off"
|
||||
@@ -8,27 +8,164 @@
|
||||
off_icon = "fryer_off"
|
||||
food_color = "#FFAD33"
|
||||
cooked_sound = 'sound/machines/ding.ogg'
|
||||
appliancetype = FRYER
|
||||
active_power_usage = 24000
|
||||
//24 KW, based on real world values for a large commercial fryer.
|
||||
|
||||
/obj/machinery/cooker/fryer/cook_mob(var/mob/living/victim, var/mob/user)
|
||||
optimal_power = 0.35
|
||||
|
||||
idle_power_usage = 6000
|
||||
//Power used to maintain temperature once it's heated.
|
||||
//Going with 25% of the active power. This is a somewhat arbitrary value
|
||||
|
||||
resistance = 90000
|
||||
//By default, about 15 mins to heat up.
|
||||
|
||||
max_contents = 2
|
||||
container_type = /obj/item/weapon/reagent_containers/cooking_container/fryer
|
||||
|
||||
stat = POWEROFF//Starts turned off
|
||||
|
||||
var/datum/reagents/oil
|
||||
var/optimal_oil = 9000//90 litres of cooking oil
|
||||
|
||||
|
||||
/obj/machinery/appliance/cooker/fryer/examine(var/mob/user)
|
||||
if (..())//no need to duplicate adjacency check
|
||||
user << "Oil Level: [oil.total_volume]/[optimal_oil]"
|
||||
|
||||
|
||||
/obj/machinery/appliance/cooker/fryer/New()
|
||||
..()
|
||||
oil = new/datum/reagents(optimal_oil * 1.25, src)
|
||||
var/variance = rand()*0.15
|
||||
//Fryer is always a little below full, but its usually negligible
|
||||
|
||||
if (prob(20))
|
||||
//Sometimes the fryer will start with much less than full oil, significantly impacting efficiency until filled
|
||||
variance = rand()*0.5
|
||||
oil.add_reagent("cornoil", optimal_oil*(1 - variance))
|
||||
|
||||
/obj/machinery/appliance/cooker/fryer/heat_up()
|
||||
if (..())
|
||||
//Set temperature of oil reagent
|
||||
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
|
||||
if (OL && istype(OL))
|
||||
OL.data["temperature"] = temperature
|
||||
|
||||
/obj/machinery/appliance/cooker/fryer/equalize_temperature()
|
||||
if (..())
|
||||
//Set temperature of oil reagent
|
||||
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
|
||||
if (OL && istype(OL))
|
||||
OL.data["temperature"] = temperature
|
||||
|
||||
|
||||
/obj/machinery/appliance/cooker/fryer/update_cooking_power()
|
||||
..()//In addition to parent temperature calculation
|
||||
//Fryer efficiency also drops when oil levels arent optimal
|
||||
var/oil_level = 0
|
||||
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
|
||||
if (OL && istype(OL))
|
||||
oil_level = OL.volume
|
||||
|
||||
var/oil_efficiency = 0
|
||||
if (oil_level)
|
||||
oil_efficiency = oil_level / optimal_oil
|
||||
|
||||
if (oil_efficiency > 1)
|
||||
//We're above optimal, efficiency goes down as we pass too much over it
|
||||
oil_efficiency = 1 - (oil_efficiency - 1)
|
||||
|
||||
|
||||
cooking_power *= oil_efficiency
|
||||
|
||||
|
||||
/obj/machinery/appliance/cooker/fryer/update_icon()
|
||||
if (cooking)
|
||||
icon_state = on_icon
|
||||
else
|
||||
icon_state = off_icon
|
||||
..()
|
||||
|
||||
|
||||
//Fryer gradually infuses any cooked food with oil. Moar calories
|
||||
//This causes a slow drop in oil levels, encouraging refill after extended use
|
||||
/obj/machinery/appliance/cooker/fryer/do_cooking_tick(var/datum/cooking_item/CI)
|
||||
if(..() && (CI.oil < CI.max_oil) && prob(20))
|
||||
var/datum/reagents/buffer = new /datum/reagents(2)
|
||||
oil.trans_to_holder(buffer, min(0.5, CI.max_oil - CI.oil))
|
||||
CI.oil += buffer.total_volume
|
||||
CI.container.soak_reagent(buffer)
|
||||
|
||||
|
||||
//To solve any odd logic problems with results having oil as part of their compiletime ingredients.
|
||||
//Upon finishing a recipe the fryer will analyse any oils in the result, and replace them with our oil
|
||||
//As well as capping the total to the max oil
|
||||
/obj/machinery/appliance/cooker/fryer/finish_cooking(var/datum/cooking_item/CI)
|
||||
..()
|
||||
var/total_oil = 0
|
||||
var/total_our_oil = 0
|
||||
var/total_removed = 0
|
||||
var/datum/reagent/our_oil = oil.get_master_reagent()
|
||||
|
||||
for (var/obj/item/I in CI.container)
|
||||
if (I.reagents && I.reagents.total_volume)
|
||||
for (var/datum/reagent/R in I.reagents.reagent_list)
|
||||
if (istype(R, /datum/reagent/nutriment/triglyceride/oil))
|
||||
total_oil += R.volume
|
||||
if (R.id != our_oil.id)
|
||||
total_removed += R.volume
|
||||
I.reagents.remove_reagent(R.id, R.volume)
|
||||
else
|
||||
total_our_oil += R.volume
|
||||
|
||||
|
||||
if (total_removed > 0 || total_oil != CI.max_oil)
|
||||
total_oil = min(total_oil, CI.max_oil)
|
||||
|
||||
if (total_our_oil < total_oil)
|
||||
//If we have less than the combined total, then top up from our reservoir
|
||||
var/datum/reagents/buffer = new /datum/reagents(INFINITY)
|
||||
oil.trans_to_holder(buffer, total_oil - total_our_oil)
|
||||
CI.container.soak_reagent(buffer)
|
||||
else if (total_our_oil > total_oil)
|
||||
|
||||
//If we have more than the maximum allowed then we delete some.
|
||||
//This could only happen if one of the objects spawns with the same type of oil as ours
|
||||
var/portion = 1 - (total_oil / total_our_oil) //find the percentage to remove
|
||||
for (var/obj/item/I in CI.container)
|
||||
if (I.reagents && I.reagents.total_volume)
|
||||
for (var/datum/reagent/R in I.reagents.reagent_list)
|
||||
if (R.id == our_oil.id)
|
||||
I.reagents.remove_reagent(R.id, R.volume*portion)
|
||||
|
||||
|
||||
|
||||
/obj/machinery/appliance/cooker/fryer/cook_mob(var/mob/living/victim, var/mob/user)
|
||||
|
||||
if(!istype(victim))
|
||||
return
|
||||
|
||||
user.visible_message("<span class='danger'>\The [user] starts pushing \the [victim] into \the [src]!</span>")
|
||||
icon_state = on_icon
|
||||
cooking = 1
|
||||
//user.visible_message("<span class='danger'>\The [user] starts pushing \the [victim] into \the [src]!</span>")
|
||||
|
||||
if(!do_mob(user, victim, 20))
|
||||
cooking = 0
|
||||
icon_state = off_icon
|
||||
return
|
||||
|
||||
//Removed delay on this action in favour of a cooldown after it
|
||||
//If you can lure someone close to the fryer and grab them then you deserve success.
|
||||
//And a delay on this kind of niche action just ensures it never happens
|
||||
//Cooldown ensures it can't be spammed to instakill someone
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN*3)
|
||||
|
||||
if(!victim || !victim.Adjacent(user))
|
||||
user << "<span class='danger'>Your victim slipped free!</span>"
|
||||
cooking = 0
|
||||
icon_state = off_icon
|
||||
return
|
||||
|
||||
var/damage = rand(7,13)
|
||||
//Though this damage seems reduced, some hot oil is transferred to the victim and will burn them for a while after
|
||||
|
||||
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
|
||||
damage *= OL.heatdamage(victim)
|
||||
|
||||
var/obj/item/organ/external/E
|
||||
var/nopain
|
||||
if(ishuman(victim) && user.zone_sel.selecting != "groin" && user.zone_sel.selecting != "chest")
|
||||
@@ -40,28 +177,62 @@
|
||||
nopain = 1
|
||||
|
||||
user.visible_message("<span class='danger'>\The [user] shoves \the [victim][E ? "'s [E.name]" : ""] into \the [src]!</span>")
|
||||
if (damage > 0)
|
||||
if(E)
|
||||
|
||||
if(E)
|
||||
E.take_damage(0, rand(20,30))
|
||||
if(E.children && E.children.len)
|
||||
for(var/obj/item/organ/external/child in E.children)
|
||||
if(nopain && nopain < 2 && !(child.robotic >= ORGAN_ROBOT))
|
||||
nopain = 0
|
||||
child.take_damage(0, rand(20,30))
|
||||
else
|
||||
victim.apply_damage(rand(30,40), BURN, user.zone_sel.selecting)
|
||||
if(E.children && E.children.len)
|
||||
for(var/obj/item/organ/external/child in E.children)
|
||||
if(nopain && nopain < 2 && !(child.robotic >= ORGAN_ROBOT))
|
||||
nopain = 0
|
||||
child.take_damage(0, damage)
|
||||
damage -= (damage*0.5)//IF someone's arm is plunged in, the hand should take most of it
|
||||
|
||||
E.take_damage(0, damage)
|
||||
else
|
||||
victim.apply_damage(damage, BURN, user.zone_sel.selecting)
|
||||
|
||||
|
||||
if(!nopain)
|
||||
victim << "<span class='danger'>Agony consumes you as searing hot oil scorches your [E ? E.name : "flesh"] horribly!</span>"
|
||||
victim.emote("scream")
|
||||
else
|
||||
victim << "<span class='danger'>Searing hot oil scorches your [E ? E.name : "flesh"]!</span>"
|
||||
|
||||
if(!nopain)
|
||||
victim << "<span class='danger'>Agony consumes you as searing hot oil scorches your [E ? E.name : "flesh"] horribly!</span>"
|
||||
victim.emote("scream")
|
||||
else
|
||||
victim << "<span class='danger'>Searing hot oil scorches your [E ? E.name : "flesh"]!</span>"
|
||||
|
||||
if(victim.client)
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Has [cook_type] \the [victim] ([victim.ckey]) in \a [src]</font>")
|
||||
victim.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been [cook_type] in \a [src] by [user.name] ([user.ckey])</font>")
|
||||
msg_admin_attack("[user] ([user.ckey]) [cook_type] \the [victim] ([victim.ckey]) in \a [src]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
icon_state = off_icon
|
||||
cooking = 0
|
||||
//Coat the victim in some oil
|
||||
oil.trans_to(victim, 40)
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/machinery/appliance/cooker/fryer/attackby(var/obj/item/I, var/mob/user)
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass) && I.reagents)
|
||||
if (I.reagents.total_volume <= 0 && oil)
|
||||
//Its empty, handle scooping some hot oil out of the fryer
|
||||
oil.trans_to(I, I.reagents.maximum_volume)
|
||||
user.visible_message("[user] scoops some oil out of \the [src]", span("notice","You scoop some oil out of \the [src]"))
|
||||
return 1
|
||||
else
|
||||
//It contains stuff, handle pouring any oil into the fryer
|
||||
//Possibly in future allow pouring non-oil reagents in, in order to sabotage it and poison food.
|
||||
//That would really require coding some sort of filter or better replacement mechanism first
|
||||
//So for now, restrict to oil only
|
||||
var/amount = 0
|
||||
for (var/datum/reagent/R in I.reagents.reagent_list)
|
||||
if (istype(R, /datum/reagent/nutriment/triglyceride/oil))
|
||||
var/delta = oil.get_free_space()
|
||||
delta = min(delta, R.volume)
|
||||
oil.add_reagent(R.id, delta)
|
||||
I.reagents.remove_reagent(R.id, delta)
|
||||
amount += delta
|
||||
if (amount > 0)
|
||||
user.visible_message("[user] pours some oil into \the [src]", span("notice","You pour [amount]u of oil into \the [src]"))
|
||||
return 1
|
||||
//If neither of the above returned, then call parent as normal
|
||||
..()
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/obj/machinery/cooker/grill
|
||||
/obj/machinery/appliance/cooker/grill
|
||||
name = "grill"
|
||||
desc = "Backyard grilling, IN SPACE."
|
||||
icon_state = "grill_off"
|
||||
cook_type = "grilled"
|
||||
cook_time = 100
|
||||
food_color = "#A34719"
|
||||
on_icon = "grill_on"
|
||||
off_icon = "grill_off"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/machinery/cooker/oven
|
||||
/obj/machinery/appliance/cooker/oven
|
||||
name = "oven"
|
||||
desc = "Cookies are ready, dear."
|
||||
icon = 'icons/obj/cooking_machines.dmi'
|
||||
@@ -6,18 +6,107 @@
|
||||
on_icon = "oven_on"
|
||||
off_icon = "oven_off"
|
||||
cook_type = "baked"
|
||||
cook_time = 300
|
||||
appliancetype = OVEN
|
||||
food_color = "#A34719"
|
||||
can_burn_food = 1
|
||||
active_power_usage = 19000
|
||||
//Based on a double deck electric convection oven
|
||||
|
||||
resistance = 72000
|
||||
idle_power_usage = 6000
|
||||
//uses 30% power to stay warm
|
||||
optimal_power = 0.2
|
||||
|
||||
light_x = 2
|
||||
max_contents = 5
|
||||
container_type = /obj/item/weapon/reagent_containers/cooking_container/oven
|
||||
|
||||
stat = POWEROFF//Starts turned off
|
||||
|
||||
var/open = 1
|
||||
|
||||
output_options = list(
|
||||
"Personal Pizza" = /obj/item/weapon/reagent_containers/food/snacks/variable/pizza,
|
||||
"Pizza" = /obj/item/weapon/reagent_containers/food/snacks/variable/pizza,
|
||||
"Bread" = /obj/item/weapon/reagent_containers/food/snacks/variable/bread,
|
||||
"Pie" = /obj/item/weapon/reagent_containers/food/snacks/variable/pie,
|
||||
"Small Cake" = /obj/item/weapon/reagent_containers/food/snacks/variable/cake,
|
||||
"Cake" = /obj/item/weapon/reagent_containers/food/snacks/variable/cake,
|
||||
"Hot Pocket" = /obj/item/weapon/reagent_containers/food/snacks/variable/pocket,
|
||||
"Kebab" = /obj/item/weapon/reagent_containers/food/snacks/variable/kebab,
|
||||
"Waffles" = /obj/item/weapon/reagent_containers/food/snacks/variable/waffles,
|
||||
"Cookie" = /obj/item/weapon/reagent_containers/food/snacks/variable/cookie,
|
||||
"Donut" = /obj/item/weapon/reagent_containers/food/snacks/variable/donut
|
||||
)
|
||||
|
||||
|
||||
/obj/machinery/appliance/cooker/oven/update_icon()
|
||||
if (!open)
|
||||
if (!stat)
|
||||
icon_state = "ovenclosed_on"
|
||||
else
|
||||
icon_state = "ovenclosed_off"
|
||||
else
|
||||
icon_state = "ovenopen"
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/appliance/cooker/oven/AltClick(var/mob/user)
|
||||
if(user.stat || user.restrained()) return
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)//No spamming the door, it makes a sound
|
||||
toggle_door()
|
||||
|
||||
/obj/machinery/appliance/cooker/oven/verb/toggle_door()
|
||||
set src in view()
|
||||
set name = "Open/close oven door"
|
||||
set category = "Object"
|
||||
if (!Adjacent(usr))
|
||||
usr << "You can't reach the [src] from there, get closer!"
|
||||
return
|
||||
|
||||
if (open)
|
||||
open = 0
|
||||
loss = (active_power_usage / resistance)*0.5
|
||||
else
|
||||
open = 1
|
||||
loss = (active_power_usage / resistance)*10
|
||||
//When the oven door is opened, heat is lost MUCH faster
|
||||
|
||||
playsound(src, 'sound/machines/hatch_open.ogg', 20, 1)
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/appliance/cooker/oven/can_insert(var/obj/item/I, var/mob/user)
|
||||
if (!open)
|
||||
user << "<span class='warning'>You can't put anything in while the door is closed!</span>"
|
||||
return 0
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
//If an oven's door is open it will lose heat every proc, even if it also gained it
|
||||
//But dont call equalize twice in one stack. A return value of -1 from the parent indicates equalize was already called
|
||||
/obj/machinery/appliance/cooker/oven/heat_up()
|
||||
.=..()
|
||||
if (open && . != -1)
|
||||
var/turf/T = get_turf(src)
|
||||
if (temperature > T.temperature)
|
||||
equalize_temperature()
|
||||
|
||||
/obj/machinery/appliance/cooker/oven/can_remove_items(var/mob/user)
|
||||
if (!open)
|
||||
user << "<span class='warning'>You can't take anything out while the door is closed!</span>"
|
||||
return 0
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
//Oven has lots of recipes and combine options. The chance for interference is high, so
|
||||
//If a combine target is set the oven will do it instead of checking recipes
|
||||
/obj/machinery/appliance/cooker/oven/finish_cooking(var/datum/cooking_item/CI)
|
||||
if(CI.combine_target)
|
||||
CI.result_type = 3//Combination type. We're making something out of our ingredients
|
||||
combination_cook(CI)
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 100
|
||||
active_power_usage = 2000
|
||||
flags = OPENCONTAINER | NOREACT
|
||||
var/operating = 0 // Is it on?
|
||||
var/dirty = 0 // = {0..100} Does it need cleaning?
|
||||
@@ -17,7 +17,7 @@
|
||||
var/global/list/acceptable_items // List of the items you can put in
|
||||
var/global/list/acceptable_reagents // List of the reagents you can put in
|
||||
var/global/max_n_of_items = 0
|
||||
|
||||
var/appliancetype = MICROWAVE
|
||||
|
||||
// see code/modules/food/recipes_microwave.dm for recipes
|
||||
|
||||
@@ -32,7 +32,11 @@
|
||||
if (!available_recipes)
|
||||
available_recipes = new
|
||||
for (var/type in (typesof(/datum/recipe)-/datum/recipe))
|
||||
available_recipes+= new type
|
||||
var/datum/recipe/test = new type
|
||||
if ((test.appliance & appliancetype))
|
||||
available_recipes += test
|
||||
else
|
||||
qdel(test)
|
||||
acceptable_items = new
|
||||
acceptable_reagents = new
|
||||
for (var/datum/recipe/recipe in available_recipes)
|
||||
@@ -137,13 +141,13 @@
|
||||
return 1
|
||||
else if(istype(O,/obj/item/weapon/crowbar))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] begins [src.anchored ? "securing" : "unsecuring"] the microwave.</span>", \
|
||||
"<span class='notice'>You attempt to [src.anchored ? "secure" : "unsecure"] the microwave.</span>"
|
||||
"<span class='notice'>\The [user] begins [src.anchored ? "unsecuring" : "securing"] the microwave.</span>", \
|
||||
"<span class='notice'>You attempt to [src.anchored ? "unsecure" : "secure"] the microwave.</span>"
|
||||
)
|
||||
if (do_after(user,20))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] [src.anchored ? "secures" : "unsecures"] the microwave.</span>", \
|
||||
"<span class='notice'>You [src.anchored ? "secure" : "unsecure"] the microwave.</span>"
|
||||
"<span class='notice'>\The [user] [src.anchored ? "unsecures" : "secures"] the microwave.</span>", \
|
||||
"<span class='notice'>You [src.anchored ? "unsecure" : "secure"] the microwave.</span>"
|
||||
)
|
||||
src.anchored = !src.anchored
|
||||
else
|
||||
@@ -239,7 +243,7 @@
|
||||
return
|
||||
start()
|
||||
if (reagents.total_volume==0 && !(locate(/obj) in contents)) //dry run
|
||||
if (!wzhzhzh(10))
|
||||
if (!wzhzhzh(16))
|
||||
abort()
|
||||
return
|
||||
stop()
|
||||
@@ -250,17 +254,17 @@
|
||||
if (!recipe)
|
||||
dirty += 1
|
||||
if (prob(max(10,dirty*5)))
|
||||
if (!wzhzhzh(4))
|
||||
if (!wzhzhzh(16))
|
||||
abort()
|
||||
return
|
||||
muck_start()
|
||||
wzhzhzh(4)
|
||||
wzhzhzh(16)
|
||||
muck_finish()
|
||||
cooked = fail()
|
||||
cooked.loc = src.loc
|
||||
return
|
||||
else if (has_extra_item())
|
||||
if (!wzhzhzh(4))
|
||||
if (!wzhzhzh(16))
|
||||
abort()
|
||||
return
|
||||
broke()
|
||||
@@ -268,7 +272,7 @@
|
||||
cooked.loc = src.loc
|
||||
return
|
||||
else
|
||||
if (!wzhzhzh(10))
|
||||
if (!wzhzhzh(40))
|
||||
abort()
|
||||
return
|
||||
stop()
|
||||
@@ -276,7 +280,7 @@
|
||||
cooked.loc = src.loc
|
||||
return
|
||||
else
|
||||
var/halftime = round(recipe.time/10/2)
|
||||
var/halftime = round((recipe.time*4)/10/2)
|
||||
if (!wzhzhzh(halftime))
|
||||
abort()
|
||||
return
|
||||
@@ -285,17 +289,36 @@
|
||||
cooked = fail()
|
||||
cooked.loc = src.loc
|
||||
return
|
||||
cooked = recipe.make_food(src)
|
||||
|
||||
|
||||
//Making multiple copies of a recipe
|
||||
var/result = recipe.result
|
||||
var/valid = 1
|
||||
var/list/cooked_items = list()
|
||||
while(valid)
|
||||
cooked_items += recipe.make_food(src)
|
||||
valid = 0
|
||||
recipe = select_recipe(available_recipes,src)
|
||||
if (recipe && recipe.result == result)
|
||||
valid = 1
|
||||
|
||||
//Any leftover reagents are divided amongst the foods
|
||||
var/total = reagents.total_volume
|
||||
for (var/obj/item/weapon/reagent_containers/food/snacks/S in cooked_items)
|
||||
reagents.trans_to_holder(S.reagents, total/cooked_items.len)
|
||||
|
||||
for (var/obj/item/weapon/reagent_containers/food/snacks/S in contents)
|
||||
S.cook()
|
||||
|
||||
dispose(0) //clear out anything left
|
||||
stop()
|
||||
if(cooked)
|
||||
cooked.loc = src.loc
|
||||
return
|
||||
|
||||
/obj/machinery/microwave/proc/wzhzhzh(var/seconds as num) // Whoever named this proc is fucking literally Satan. ~ Z
|
||||
for (var/i=1 to seconds)
|
||||
if (stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
use_power(500)
|
||||
use_power(active_power_usage)
|
||||
sleep(10)
|
||||
return 1
|
||||
|
||||
@@ -325,13 +348,14 @@
|
||||
src.icon_state = "mw"
|
||||
src.updateUsrDialog()
|
||||
|
||||
/obj/machinery/microwave/proc/dispose()
|
||||
for (var/obj/O in contents)
|
||||
O.loc = src.loc
|
||||
/obj/machinery/microwave/proc/dispose(var/message = 1)
|
||||
for (var/atom/movable/A in contents)
|
||||
A.forceMove(loc)
|
||||
if (src.reagents.total_volume)
|
||||
src.dirty++
|
||||
src.reagents.clear_reagents()
|
||||
usr << "<span class='notice'>You dispose of the microwave contents.</span>"
|
||||
if (message)
|
||||
usr << "<span class='notice'>You dispose of the microwave contents.</span>"
|
||||
src.updateUsrDialog()
|
||||
|
||||
/obj/machinery/microwave/proc/muck_start()
|
||||
@@ -348,9 +372,7 @@
|
||||
src.updateUsrDialog()
|
||||
|
||||
/obj/machinery/microwave/proc/broke()
|
||||
var/datum/effect/effect/system/spark_spread/s = new
|
||||
s.set_up(2, 1, src)
|
||||
s.start()
|
||||
spark(src, 2, alldirs)
|
||||
src.icon_state = "mwb" // Make it look all busted up and shit
|
||||
src.visible_message("<span class='warning'>The microwave breaks!</span>") //Let them know they're stupid
|
||||
src.broken = 2 // Make it broken so it can't be used util fixed
|
||||
@@ -389,3 +411,12 @@
|
||||
if ("dispose")
|
||||
dispose()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/microwave/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if (!mover)
|
||||
return 1
|
||||
if(mover.checkpass(PASSTABLE))
|
||||
//Animals can run under them, lots of empty space
|
||||
return 1
|
||||
return ..()
|
||||
@@ -118,14 +118,11 @@ Class Procs:
|
||||
..(l)
|
||||
if(d)
|
||||
set_dir(d)
|
||||
if(!machinery_sort_required && ticker)
|
||||
dd_insertObjectList(machines, src)
|
||||
else
|
||||
machines += src
|
||||
machinery_sort_required = 1
|
||||
|
||||
add_machine(src)
|
||||
|
||||
/obj/machinery/Destroy()
|
||||
machines -= src
|
||||
remove_machine(src)
|
||||
if(component_parts)
|
||||
for(var/atom/A in component_parts)
|
||||
if(A.loc == src) // If the components are inside the machine, delete them.
|
||||
@@ -141,7 +138,12 @@ Class Procs:
|
||||
if(!(use_power || idle_power_usage || active_power_usage))
|
||||
return PROCESS_KILL
|
||||
|
||||
return
|
||||
return M_NO_PROCESS
|
||||
|
||||
/obj/machinery/proc/get_process_type()
|
||||
. |= M_PROCESSES
|
||||
if (use_power || idle_power_usage || active_power_usage)
|
||||
. |= M_USES_POWER
|
||||
|
||||
/obj/machinery/emp_act(severity)
|
||||
if(use_power && stat == 0)
|
||||
@@ -280,9 +282,7 @@ Class Procs:
|
||||
return 0
|
||||
if(!prob(prb))
|
||||
return 0
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
spark(src, 5, alldirs)
|
||||
if (electrocute_mob(user, get_area(src), src, 0.7))
|
||||
var/area/temp_area = get_area(src)
|
||||
if(temp_area)
|
||||
|
||||
@@ -11,6 +11,7 @@ var/bomb_set
|
||||
var/lighthack = 0
|
||||
var/timeleft = 120
|
||||
var/timing = 0
|
||||
var/alerted = 0
|
||||
var/r_code = "ADMIN"
|
||||
var/code = ""
|
||||
var/yes_code = 0
|
||||
@@ -290,6 +291,10 @@ var/bomb_set
|
||||
update_icon()
|
||||
else
|
||||
secure_device()
|
||||
|
||||
if(alerted == 0)
|
||||
set_security_level(SEC_LEVEL_DELTA)
|
||||
alerted = 1
|
||||
if (href_list["safety"])
|
||||
if (wires.IsIndexCut(NUCLEARBOMB_WIRE_SAFETY))
|
||||
usr << "<span class='warning'>Nothing happens, something might be wrong with the wiring.</span>"
|
||||
|
||||
@@ -463,7 +463,7 @@ Buildable meters
|
||||
var/turf/T = P.loc
|
||||
P.level = !T.is_plating() ? 2 : 1
|
||||
P.initialize()
|
||||
if (deleted(P))
|
||||
if (QDELETED(P))
|
||||
usr << pipefailtext
|
||||
return 1
|
||||
P.build_network()
|
||||
@@ -482,7 +482,7 @@ Buildable meters
|
||||
var/turf/T = P.loc
|
||||
P.level = !T.is_plating() ? 2 : 1
|
||||
P.initialize()
|
||||
if (deleted(P))
|
||||
if (QDELETED(P))
|
||||
usr << pipefailtext
|
||||
return 1
|
||||
P.build_network()
|
||||
@@ -501,7 +501,7 @@ Buildable meters
|
||||
var/turf/T = P.loc
|
||||
P.level = !T.is_plating() ? 2 : 1
|
||||
P.initialize()
|
||||
if (deleted(P))
|
||||
if (QDELETED(P))
|
||||
usr << pipefailtext
|
||||
return 1
|
||||
P.build_network()
|
||||
@@ -520,7 +520,7 @@ Buildable meters
|
||||
var/turf/T = P.loc
|
||||
P.level = !T.is_plating() ? 2 : 1
|
||||
P.initialize()
|
||||
if (deleted(P))
|
||||
if (QDELETED(P))
|
||||
usr << pipefailtext
|
||||
return 1
|
||||
P.build_network()
|
||||
@@ -537,7 +537,7 @@ Buildable meters
|
||||
P.initialize_directions = pipe_dir //this var it's used to know if the pipe is bent or not
|
||||
P.initialize_directions_he = pipe_dir
|
||||
P.initialize()
|
||||
if (deleted(P))
|
||||
if (QDELETED(P))
|
||||
usr << pipefailtext
|
||||
return 1
|
||||
P.build_network()
|
||||
@@ -572,7 +572,7 @@ Buildable meters
|
||||
var/turf/T = M.loc
|
||||
M.level = !T.is_plating() ? 2 : 1
|
||||
M.initialize()
|
||||
if (deleted(M))
|
||||
if (QDELETED(M))
|
||||
usr << pipefailtext
|
||||
return 1
|
||||
M.build_network()
|
||||
@@ -641,7 +641,7 @@ Buildable meters
|
||||
var/turf/T = M.loc
|
||||
M.level = !T.is_plating() ? 2 : 1
|
||||
M.initialize()
|
||||
if (deleted(M))
|
||||
if (QDELETED(M))
|
||||
usr << pipefailtext
|
||||
return 1
|
||||
M.build_network()
|
||||
@@ -718,7 +718,7 @@ Buildable meters
|
||||
P.initialize_directions = src.get_pdir()
|
||||
P.initialize_directions_he = src.get_hdir()
|
||||
P.initialize()
|
||||
if (deleted(P))
|
||||
if (QDELETED(P))
|
||||
usr << pipefailtext //"There's nothing to connect this pipe to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)"
|
||||
return 1
|
||||
P.build_network()
|
||||
@@ -901,7 +901,7 @@ Buildable meters
|
||||
var/turf/T = P.loc
|
||||
P.level = !T.is_plating() ? 2 : 1
|
||||
P.initialize()
|
||||
if (deleted(P))
|
||||
if (QDELETED(P))
|
||||
usr << pipefailtext
|
||||
return 1
|
||||
P.build_network()
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
var/shot_sound //what sound should play when the turret fires
|
||||
var/eshot_sound //what sound should play when the emagged turret fires
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/spark_system //the spark system, used for generating... sparks?
|
||||
var/datum/effect_system/sparks/spark_system //the spark system, used for generating... sparks?
|
||||
|
||||
var/wrenching = 0
|
||||
var/last_target //last target fired at, prevents turrets from erratically firing at all valid targets in range
|
||||
@@ -81,9 +81,7 @@
|
||||
req_one_access = list(access_security, access_heads)
|
||||
|
||||
//Sets up a spark system
|
||||
spark_system = new /datum/effect/effect/system/spark_spread
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
spark_system = bind_spark(src, 5)
|
||||
|
||||
setup()
|
||||
|
||||
@@ -370,7 +368,7 @@ var/list/turret_icons
|
||||
|
||||
health -= force
|
||||
if (force > 5 && prob(45))
|
||||
spark_system.start()
|
||||
spark_system.queue()
|
||||
if(health <= 0)
|
||||
die() //the death process :(
|
||||
|
||||
@@ -425,7 +423,7 @@ var/list/turret_icons
|
||||
/obj/machinery/porta_turret/proc/die() //called when the turret dies, ie, health <= 0
|
||||
health = 0
|
||||
stat |= BROKEN //enables the BROKEN bit
|
||||
spark_system.start() //creates some sparks because they look cool
|
||||
spark_system.queue() //creates some sparks because they look cool
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/porta_turret/process()
|
||||
|
||||
@@ -60,6 +60,8 @@ obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob)
|
||||
return
|
||||
if (istype(G, /obj/item/weapon/gun/energy/staff))
|
||||
return
|
||||
if (istype(G, /obj/item/weapon/gun/energy/wand))
|
||||
return
|
||||
if(istype(G, /obj/item/modular_computer))
|
||||
var/obj/item/modular_computer/C = G
|
||||
if(!C.battery_module)
|
||||
|
||||
@@ -37,8 +37,7 @@ var/list/ai_status_emotions = list(
|
||||
return emotions
|
||||
|
||||
/proc/set_ai_status_displays(mob/user as mob)
|
||||
var/list/ai_emotions = get_ai_emotions(user.ckey)
|
||||
var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions
|
||||
var/emote = get_ai_emotion(user)
|
||||
for (var/obj/machinery/M in machines) //change status
|
||||
if(istype(M, /obj/machinery/ai_status_display))
|
||||
var/obj/machinery/ai_status_display/AISD = M
|
||||
@@ -69,26 +68,24 @@ var/list/ai_status_emotions = list(
|
||||
var/emotion = "Neutral"
|
||||
|
||||
/obj/machinery/ai_status_display/attack_ai/(mob/user as mob)
|
||||
var/list/ai_emotions = get_ai_emotions(user.ckey)
|
||||
var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions
|
||||
var/emote = get_ai_emotion(user)
|
||||
src.emotion = emote
|
||||
src.update()
|
||||
|
||||
/obj/machinery/ai_status_display/process()
|
||||
return
|
||||
/proc/get_ai_emotion(mob/user as mob)
|
||||
return input(user, "Please, select a status!", "AI Status", null, null) in get_ai_emotions(user.ckey)
|
||||
|
||||
/obj/machinery/ai_status_display/proc/update()
|
||||
if(mode==0) //Blank
|
||||
overlays.Cut()
|
||||
return
|
||||
switch (mode)
|
||||
if (0) // Blank
|
||||
overlays.Cut()
|
||||
|
||||
if(mode==1) // AI emoticon
|
||||
var/datum/ai_emotion/ai_emotion = ai_status_emotions[emotion]
|
||||
set_picture(ai_emotion.overlay)
|
||||
return
|
||||
if (1) // AI emoticon
|
||||
var/datum/ai_emotion/ai_emotion = ai_status_emotions[emotion]
|
||||
set_picture(ai_emotion.overlay)
|
||||
|
||||
if(mode==2) // BSOD
|
||||
set_picture("ai_bsod")
|
||||
return
|
||||
if (2) // BSOD
|
||||
set_picture("ai_bsod")
|
||||
|
||||
/obj/machinery/ai_status_display/proc/set_picture(var/state)
|
||||
picture_state = state
|
||||
|
||||
@@ -170,12 +170,14 @@
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 2000
|
||||
var/obj/machinery/computer/teleporter/com
|
||||
var/datum/effect_system/sparks/spark_system
|
||||
|
||||
|
||||
/obj/machinery/teleport/hub/New()
|
||||
..()
|
||||
underlays.Cut()
|
||||
underlays += image('icons/obj/stationobjs.dmi', icon_state = "tele-wires")
|
||||
spark_system = bind_spark(src, 5, alldirs)
|
||||
|
||||
/obj/machinery/teleport/hub/Bumped(M as mob|obj)
|
||||
spawn()
|
||||
@@ -201,9 +203,7 @@
|
||||
com.one_time_use = 0
|
||||
com.locked = null
|
||||
else
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
spark_system.queue()
|
||||
accurate = 1
|
||||
spawn(3000) accurate = 0 //Accurate teleporting for 5 minutes
|
||||
for(var/mob/B in hearers(src, null))
|
||||
|
||||
@@ -914,7 +914,7 @@
|
||||
desc = "A kitchen and restaurant equipment vendor."
|
||||
product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils.;You don't really need these..."
|
||||
icon_state = "dinnerware"
|
||||
products = list(/obj/item/weapon/tray = 8,/obj/item/weapon/material/kitchen/utensil/fork = 6, /obj/item/weapon/material/kitchen/utensil/knife = 6, /obj/item/weapon/material/kitchen/utensil/spoon = 6, /obj/item/weapon/material/knife = 3,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 8,/obj/item/clothing/suit/chef/classic = 2)
|
||||
products = list(/obj/item/weapon/tray = 8,/obj/item/weapon/material/kitchen/utensil/fork = 6, /obj/item/weapon/material/kitchen/utensil/knife = 6, /obj/item/weapon/material/kitchen/utensil/spoon = 6, /obj/item/weapon/material/knife = 3,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 8,/obj/item/clothing/suit/chef/classic = 2, /obj/item/weapon/reagent_containers/cooking_container/oven = 5, /obj/item/weapon/reagent_containers/cooking_container/fryer = 4)
|
||||
contraband = list(/obj/item/weapon/material/kitchen/rollingpin = 2, /obj/item/weapon/material/knife/butch = 2)
|
||||
|
||||
/obj/machinery/vending/sovietsoda
|
||||
|
||||
@@ -274,7 +274,7 @@
|
||||
set_ready_state(0)
|
||||
if(do_after_cooldown(target))
|
||||
if(disabled) return
|
||||
chassis.spark_system.start()
|
||||
chassis.spark_system.queue()
|
||||
target:ChangeTurf(/turf/simulated/floor/plating)
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
chassis.use_power(energy_drain)
|
||||
@@ -283,7 +283,7 @@
|
||||
set_ready_state(0)
|
||||
if(do_after_cooldown(target))
|
||||
if(disabled) return
|
||||
chassis.spark_system.start()
|
||||
chassis.spark_system.queue()
|
||||
target:ChangeTurf(get_base_turf_by_area(target))
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
chassis.use_power(energy_drain)
|
||||
@@ -292,7 +292,7 @@
|
||||
set_ready_state(0)
|
||||
if(do_after_cooldown(target))
|
||||
if(disabled) return
|
||||
chassis.spark_system.start()
|
||||
chassis.spark_system.queue()
|
||||
qdel(target)
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
chassis.use_power(energy_drain)
|
||||
@@ -304,7 +304,7 @@
|
||||
if(disabled) return
|
||||
target:ChangeTurf(/turf/simulated/floor/plating)
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
chassis.spark_system.start()
|
||||
chassis.spark_system.queue()
|
||||
chassis.use_power(energy_drain*2)
|
||||
else if(istype(target, /turf/simulated/floor))
|
||||
occupant_message("Building Wall...")
|
||||
@@ -313,7 +313,7 @@
|
||||
if(disabled) return
|
||||
target:ChangeTurf(/turf/simulated/wall)
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
chassis.spark_system.start()
|
||||
chassis.spark_system.queue()
|
||||
chassis.use_power(energy_drain*2)
|
||||
if(2)
|
||||
if(istype(target, /turf/simulated/floor))
|
||||
@@ -321,7 +321,7 @@
|
||||
set_ready_state(0)
|
||||
if(do_after_cooldown(target))
|
||||
if(disabled) return
|
||||
chassis.spark_system.start()
|
||||
chassis.spark_system.queue()
|
||||
var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target)
|
||||
T.autoclose = 1
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
var/add_req_access = 1
|
||||
var/maint_access = 1
|
||||
var/dna //dna-locking the mech
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new
|
||||
var/datum/effect_system/sparks/spark_system
|
||||
var/lights = 0
|
||||
var/lights_power = 6
|
||||
|
||||
@@ -108,8 +108,6 @@
|
||||
add_radio()
|
||||
add_cabin()
|
||||
add_airtank() //All mecha currently have airtanks. No need to check unless changes are made.
|
||||
spark_system.set_up(2, 0, src)
|
||||
spark_system.attach(src)
|
||||
add_cell()
|
||||
add_iterators()
|
||||
removeVerb(/obj/mecha/verb/disconnect_from_port)
|
||||
@@ -117,7 +115,8 @@
|
||||
loc.Entered(src)
|
||||
mechas_list += src //global mech list
|
||||
narrator_message(FIRSTRUN)
|
||||
return
|
||||
|
||||
spark_system = bind_spark(src, 2)
|
||||
|
||||
/obj/mecha/Destroy()
|
||||
src.go_out()
|
||||
@@ -595,12 +594,13 @@
|
||||
|
||||
/obj/mecha/proc/update_health()
|
||||
if(src.health > 0)
|
||||
src.spark_system.start()
|
||||
src.spark_system.queue()
|
||||
else
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/mecha/attack_hand(mob/user as mob)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
src.log_message("Attack by hand/paw. Attacker - [user].",1)
|
||||
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
@@ -668,7 +668,8 @@
|
||||
if(istype(Proj, /obj/item/projectile/beam/pulse))
|
||||
ignore_threshold = 1
|
||||
src.hit_damage(Proj.damage, Proj.check_armour, is_melee=0)
|
||||
if(prob(25)) spark_system.start()
|
||||
if(prob(25))
|
||||
spark_system.queue()
|
||||
src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),ignore_threshold)
|
||||
|
||||
//AP projectiles have a chance to cause additional damage
|
||||
@@ -758,7 +759,7 @@
|
||||
//////////////////////
|
||||
|
||||
/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
|
||||
if(istype(W, /obj/item/mecha_parts/mecha_equipment))
|
||||
var/obj/item/mecha_parts/mecha_equipment/E = W
|
||||
spawn()
|
||||
@@ -872,6 +873,7 @@
|
||||
else
|
||||
src.log_message("Attacked by [W]. Attacker - [user]")
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
if(deflect_hit(is_melee=1))
|
||||
user << "<span class='danger'>\The [W] bounces off [src.name].</span>"
|
||||
src.log_append_to_last("Armor saved.")
|
||||
@@ -1928,7 +1930,9 @@
|
||||
return icon_state
|
||||
|
||||
/obj/mecha/attack_generic(var/mob/user, var/damage, var/attack_message)
|
||||
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
|
||||
if(!damage)
|
||||
return 0
|
||||
|
||||
@@ -2248,7 +2252,7 @@
|
||||
qdel(leaked_gas)
|
||||
if(mecha.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT))
|
||||
if(mecha.get_charge())
|
||||
mecha.spark_system.start()
|
||||
mecha.spark_system.queue()
|
||||
mecha.cell.charge -= min(20,mecha.cell.charge)
|
||||
mecha.cell.maxcharge -= min(20,mecha.cell.maxcharge)
|
||||
return
|
||||
|
||||
@@ -71,6 +71,9 @@ var/global/list/image/splatter_cache=list()
|
||||
if(amount < 1)
|
||||
return
|
||||
|
||||
if (!blood_DNA || !islist(blood_DNA))
|
||||
blood_DNA = list()
|
||||
|
||||
var/obj/item/organ/external/l_foot = perp.get_organ("l_foot")
|
||||
var/obj/item/organ/external/r_foot = perp.get_organ("r_foot")
|
||||
var/hasfeet = 1
|
||||
|
||||
@@ -22,9 +22,7 @@
|
||||
var/obj/effect/decal/cleanable/blood/oil/streak = new(src.loc)
|
||||
streak.update_icon()
|
||||
else if (prob(10))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
spark(src, 3, alldirs)
|
||||
if (step_to(src, get_step(src, direction), 0))
|
||||
break
|
||||
|
||||
@@ -47,4 +45,4 @@
|
||||
|
||||
/obj/effect/decal/cleanable/blood/oil/streak
|
||||
random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5")
|
||||
amount = 2
|
||||
amount = 2
|
||||
|
||||
@@ -87,82 +87,6 @@ steam.start() -- spawns the effect
|
||||
spawn(20)
|
||||
qdel(steam)
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//SPARK SYSTEM (like steam system)
|
||||
// The attach(atom/atom) proc is optional, and can be called to attach the effect
|
||||
// to something, like the RCD, so then you can just call start() and the sparks
|
||||
// will always spawn at the items location.
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/obj/effect/sparks
|
||||
name = "sparks"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "sparks"
|
||||
var/amount = 6.0
|
||||
anchored = 1.0
|
||||
mouse_opacity = 0
|
||||
|
||||
/obj/effect/sparks/New()
|
||||
..()
|
||||
playsound(src.loc, "sparks", 100, 1)
|
||||
var/turf/T = src.loc
|
||||
if (istype(T, /turf))
|
||||
T.hotspot_expose(1000,100)
|
||||
|
||||
/obj/effect/sparks/initialize()
|
||||
..()
|
||||
schedule_task_in(10 SECONDS, /proc/qdel, list(src))
|
||||
|
||||
/obj/effect/sparks/Destroy()
|
||||
var/turf/T = src.loc
|
||||
if (istype(T, /turf))
|
||||
T.hotspot_expose(1000,100)
|
||||
return ..()
|
||||
|
||||
/obj/effect/sparks/Move()
|
||||
..()
|
||||
var/turf/T = src.loc
|
||||
if (istype(T, /turf))
|
||||
T.hotspot_expose(1000,100)
|
||||
|
||||
/datum/effect/effect/system/spark_spread
|
||||
var/total_sparks = 0 // To stop it being spammed and lagging!
|
||||
|
||||
set_up(n = 3, c = 0, loca)
|
||||
if(n > 10)
|
||||
n = 10
|
||||
number = n
|
||||
cardinals = c
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
|
||||
start()
|
||||
var/i = 0
|
||||
for(i=0, i<src.number, i++)
|
||||
if(src.total_sparks > 20)
|
||||
return
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/sparks/sparks = getFromPool(/obj/effect/sparks, src.location)
|
||||
src.total_sparks++
|
||||
var/direction
|
||||
if(src.cardinals)
|
||||
direction = pick(cardinal)
|
||||
else
|
||||
direction = pick(alldirs)
|
||||
for(i=0, i<pick(1,2,3), i++)
|
||||
sleep(5)
|
||||
step(sparks,direction)
|
||||
spawn(20)
|
||||
if(sparks)
|
||||
qdel(sparks)
|
||||
src.total_sparks--
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//// SMOKE SYSTEMS
|
||||
// direct can be optinally added when set_up, to make the smoke always travel in one direction
|
||||
@@ -184,8 +108,10 @@ steam.start() -- spawns the effect
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
|
||||
/obj/effect/effect/smoke/New()
|
||||
/obj/effect/effect/smoke/New(var/loc, var/duration = 0)
|
||||
..()
|
||||
if (duration)
|
||||
time_to_live = duration
|
||||
spawn (time_to_live)
|
||||
qdel(src)
|
||||
|
||||
@@ -310,8 +236,10 @@ steam.start() -- spawns the effect
|
||||
var/total_smoke = 0 // To stop it being spammed and lagging!
|
||||
var/direction
|
||||
var/smoke_type = /obj/effect/effect/smoke
|
||||
var/smoke_duration
|
||||
|
||||
/datum/effect/effect/system/smoke_spread/set_up(n = 5, c = 0, loca, direct)
|
||||
/datum/effect/effect/system/smoke_spread/set_up(n = 5, c = 0, loca, direct, duration = 0)
|
||||
smoke_duration = duration
|
||||
if(n > 10)
|
||||
n = 10
|
||||
number = n
|
||||
@@ -475,9 +403,7 @@ steam.start() -- spawns the effect
|
||||
|
||||
start()
|
||||
if (amount <= 2)
|
||||
var/datum/effect/effect/system/spark_spread/s = getFromPool(/datum/effect/effect/system/spark_spread)
|
||||
s.set_up(2, 1, location)
|
||||
s.start()
|
||||
spark(location, 2)
|
||||
|
||||
for(var/mob/M in viewers(5, location))
|
||||
M << "<span class='warning'>The solution violently explodes.</span>"
|
||||
|
||||
@@ -28,9 +28,7 @@
|
||||
qdel(D)
|
||||
|
||||
if(sparks)
|
||||
var/datum/effect/effect/system/spark_spread/s = getFromPool(/datum/effect/effect/system/spark_spread)
|
||||
s.set_up(2, 1, get_turf(location)) // Not sure if it's safe to pass an arbitrary object to set_up, todo
|
||||
s.start()
|
||||
spark(location, 2, alldirs)
|
||||
|
||||
for(var/i = 1, i<= gibtypes.len, i++)
|
||||
if(gibamounts[i])
|
||||
|
||||
@@ -25,13 +25,11 @@
|
||||
triggered = 1
|
||||
call(src,triggerproc)(M)
|
||||
|
||||
/obj/effect/mine/proc/triggerrad(obj)
|
||||
var/datum/effect/effect/system/spark_spread/s = getFromPool(/datum/effect/effect/system/spark_spread)
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
obj:radiation += 50
|
||||
randmutb(obj)
|
||||
domutcheck(obj,null)
|
||||
/obj/effect/mine/proc/triggerrad(var/mob/living/M)
|
||||
spark(src, 3, alldirs)
|
||||
if (istype(M))
|
||||
M.apply_radiation(50)
|
||||
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
|
||||
@@ -39,9 +37,7 @@
|
||||
if(ismob(obj))
|
||||
var/mob/M = obj
|
||||
M.Stun(30)
|
||||
var/datum/effect/effect/system/spark_spread/s = getFromPool(/datum/effect/effect/system/spark_spread)
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
spark(src, 3, alldirs)
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
|
||||
@@ -66,11 +62,11 @@
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/mine/proc/triggerkick(obj)
|
||||
var/datum/effect/effect/system/spark_spread/s = getFromPool(/datum/effect/effect/system/spark_spread)
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
qdel(obj:client)
|
||||
/obj/effect/mine/proc/triggerkick(var/mob/M)
|
||||
spark(src, 3, alldirs)
|
||||
if (istype(M))
|
||||
qdel(M.client)
|
||||
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -129,16 +129,20 @@
|
||||
/obj/item/examine(mob/user, var/distance = -1)
|
||||
var/size
|
||||
switch(src.w_class)
|
||||
if(1.0)
|
||||
size = "tiny"
|
||||
if(2.0)
|
||||
size = "small"
|
||||
if(3.0)
|
||||
size = "normal-sized"
|
||||
if(4.0)
|
||||
size = "bulky"
|
||||
if(5.0)
|
||||
if (5.0 to INFINITY)
|
||||
size = "huge"
|
||||
if (4.0 to 5.0)
|
||||
size = "bulky"
|
||||
if (3.0 to 4.0)
|
||||
size = "normal-sized"
|
||||
if (2.0 to 3.0)
|
||||
size = "small"
|
||||
if (0 to 2.0)
|
||||
size = "tiny"
|
||||
//Changed this switch to ranges instead of tiered values, to cope with granularity and also
|
||||
//things outside its range ~Nanako
|
||||
|
||||
|
||||
return ..(user, distance, "", "It is a [size] item.")
|
||||
|
||||
/obj/item/attack_hand(mob/user as mob)
|
||||
|
||||
@@ -12,8 +12,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
w_class = 2.0
|
||||
slot_flags = SLOT_ID | SLOT_BELT
|
||||
sprite_sheets = list("Resomi" = 'icons/mob/species/resomi/id.dmi')
|
||||
//offset_light = 1
|
||||
//diona_restricted_light = 1//Light emitted by this object or creature has limited interaction with diona
|
||||
uv_intensity = 15
|
||||
|
||||
//Main variables
|
||||
var/owner = null
|
||||
@@ -344,6 +343,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
return id
|
||||
|
||||
/obj/item/device/pda/AltClick(var/mob/user)
|
||||
if(!user || user.stat || user.lying || user.restrained() || !Adjacent(user)) return
|
||||
if (ismob(src.loc))
|
||||
verb_remove_id()
|
||||
|
||||
@@ -467,7 +467,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0")))
|
||||
if(8) //medical
|
||||
if(P.icon_state == "pda-cmo"||P.icon_state == "pda-v"||P.icon_state == "pda-m"||P.icon_state == "pda-chem")
|
||||
pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0")))
|
||||
pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0")))
|
||||
count++
|
||||
|
||||
data["convopdas"] = convopdas
|
||||
@@ -730,12 +730,12 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
active_conversation = null
|
||||
if(mode==21)
|
||||
mode=2
|
||||
|
||||
|
||||
|
||||
|
||||
if("Filter") // Filters through available pdas
|
||||
if (href_list["option"])
|
||||
pdafilter = sanitize_integer(text2num(href_list["option"]), 0, 8, pdafilter)
|
||||
|
||||
|
||||
if("Ringtone")
|
||||
var/t = input(U, "Please enter new ringtone", name, ttone) as text|null
|
||||
if (in_range(src, U) && loc == U)
|
||||
@@ -957,9 +957,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
M.apply_effects(1,0,0,0,1)
|
||||
message += "Your [P] flashes with a blinding white light! You feel weaker."
|
||||
if(i>=85) //Sparks
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(2, 1, P.loc)
|
||||
s.start()
|
||||
spark(P.loc, 2)
|
||||
message += "Your [P] begins to spark violently!"
|
||||
if(i>45 && i<65 && prob(50)) //Nothing happens
|
||||
message += "Your [P] bleeps loudly."
|
||||
|
||||
@@ -65,10 +65,7 @@
|
||||
|
||||
/obj/item/device/chameleon/proc/disrupt(var/delete_dummy = 1)
|
||||
if(active_dummy)
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
spark_system.start()
|
||||
spark(src, 5)
|
||||
eject_all()
|
||||
if(delete_dummy)
|
||||
qdel(active_dummy)
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
light_color = LIGHT_COLOR_HALOGEN
|
||||
//offset_light = 1
|
||||
//diona_restricted_light = 1//Light emitted by this object or creature has limited interaction with diona
|
||||
uv_intensity = 50
|
||||
light_wedge = LIGHT_WIDE
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20)
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
/obj/item/device/flashlight/update_icon()
|
||||
if(on)
|
||||
icon_state = "[initial(icon_state)]-on"
|
||||
set_light(brightness_on, update_type = UPDATE_NOW)
|
||||
set_light(brightness_on)
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
set_light(0, update_type = UPDATE_NOW)
|
||||
set_light(0)
|
||||
|
||||
/obj/item/device/flashlight/attack_self(mob/user)
|
||||
if(!isturf(user.loc))
|
||||
@@ -96,6 +96,7 @@
|
||||
slot_flags = SLOT_EARS
|
||||
brightness_on = 2
|
||||
w_class = 1
|
||||
light_wedge = LIGHT_OMNI
|
||||
|
||||
/obj/item/device/flashlight/drone
|
||||
name = "low-power flashlight"
|
||||
@@ -113,8 +114,10 @@
|
||||
item_state = "heavyflashlight"
|
||||
brightness_on = 4
|
||||
w_class = 3
|
||||
uv_intensity = 60
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 100,"glass" = 70)
|
||||
contained_sprite = 1
|
||||
light_wedge = LIGHT_SEMI
|
||||
|
||||
/obj/item/device/flashlight/maglight
|
||||
name = "maglight"
|
||||
@@ -124,10 +127,12 @@
|
||||
force = 10
|
||||
brightness_on = 5
|
||||
w_class = 3
|
||||
uv_intensity = 70
|
||||
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 200,"glass" = 100)
|
||||
hitsound = 'sound/weapons/smash.ogg'
|
||||
contained_sprite = 1
|
||||
light_wedge = LIGHT_NARROW
|
||||
|
||||
|
||||
// the desk lamps are a bit special
|
||||
@@ -137,10 +142,12 @@
|
||||
icon_state = "lamp"
|
||||
item_state = "lamp"
|
||||
brightness_on = 5
|
||||
w_class = 4
|
||||
w_class = 5
|
||||
flags = CONDUCT
|
||||
|
||||
uv_intensity = 100
|
||||
on = 1
|
||||
slot_flags = 0 //No wearing desklamps
|
||||
light_wedge = LIGHT_OMNI
|
||||
|
||||
|
||||
// green-shaded desk lamp
|
||||
@@ -165,17 +172,17 @@
|
||||
name = "flare"
|
||||
desc = "A red standard-issue flare. There are instructions on the side reading 'pull cord, make light'."
|
||||
w_class = 2.0
|
||||
brightness_on = 8 // Pretty bright.
|
||||
light_power = 3
|
||||
brightness_on = 4 // Pretty bright.
|
||||
light_power = 4
|
||||
light_color = LIGHT_COLOR_FLARE
|
||||
icon_state = "flare"
|
||||
item_state = "flare"
|
||||
action_button_name = null //just pull it manually, neckbeard.
|
||||
var/fuel = 0
|
||||
uv_intensity = 100
|
||||
var/on_damage = 7
|
||||
var/produce_heat = 1500
|
||||
//offset_light = 0//Emits light all around, not directional
|
||||
//diona_restricted_light = 0
|
||||
light_wedge = LIGHT_OMNI
|
||||
|
||||
/obj/item/device/flashlight/flare/New()
|
||||
fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds.
|
||||
@@ -224,14 +231,14 @@
|
||||
item_state = "slime"
|
||||
w_class = 1
|
||||
brightness_on = 6
|
||||
uv_intensity = 200
|
||||
on = 1 //Bio-luminesence has one setting, on.
|
||||
light_color = LIGHT_COLOR_SLIME_LAMP
|
||||
//offset_light = 0//Emits light all around, not directional
|
||||
//diona_restricted_light = 0
|
||||
light_wedge = LIGHT_OMNI
|
||||
|
||||
/obj/item/device/flashlight/slime/New()
|
||||
..()
|
||||
set_light(brightness_on, update_type = UPDATE_NOW)
|
||||
set_light(brightness_on)
|
||||
|
||||
/obj/item/device/flashlight/slime/update_icon()
|
||||
return
|
||||
@@ -252,9 +259,9 @@
|
||||
icon_state = "glowstick"
|
||||
item_state = "glowstick"
|
||||
contained_sprite = 1
|
||||
//offset_light = 0
|
||||
//diona_restricted_light = 0
|
||||
uv_intensity = 255
|
||||
var/fuel = 0
|
||||
light_wedge = LIGHT_OMNI
|
||||
|
||||
/obj/item/device/flashlight/glowstick/New()
|
||||
fuel = rand(900, 1200)
|
||||
@@ -271,7 +278,7 @@
|
||||
/obj/item/device/flashlight/glowstick/proc/turn_off()
|
||||
on = 0
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/device/flashlight/glowstick/attack_self(var/mob/living/user)
|
||||
|
||||
if(((CLUMSY in user.mutations)) && prob(50))
|
||||
|
||||
@@ -422,16 +422,7 @@
|
||||
spark()
|
||||
|
||||
/obj/item/device/magnetic_lock/proc/spark()
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
|
||||
if (target)
|
||||
s.set_up(5, 1, target)
|
||||
else
|
||||
s.set_up(5, 1, src)
|
||||
|
||||
s.start()
|
||||
spawn(5)
|
||||
qdel(s)
|
||||
spark(target ? target : src, 5, alldirs)
|
||||
|
||||
#undef STATUS_INACTIVE
|
||||
#undef STATUS_ACTIVE
|
||||
|
||||
@@ -93,9 +93,7 @@
|
||||
if(M)
|
||||
M.moved_recently = 0
|
||||
M << "<span class='danger'>You feel a sharp shock!</span>"
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, M)
|
||||
s.start()
|
||||
spark(M, 3)
|
||||
|
||||
M.Weaken(10)
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
|
||||
valve_open = 0
|
||||
|
||||
if(deleted(tank_one) || deleted(tank_two) || !tank_one.air_contents || !tank_two.air_contents)
|
||||
if(QDELETED(tank_one) || QDELETED(tank_two) || !tank_one.air_contents || !tank_two.air_contents)
|
||||
return
|
||||
|
||||
var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume
|
||||
|
||||
@@ -104,6 +104,11 @@ A list of items and costs is stored under the datum of every game mode, alongsid
|
||||
// Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button.
|
||||
/obj/item/device/uplink/hidden/interact(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/device/uplink/hidden/CanUseTopic()
|
||||
if(!active)
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
// The purchasing code.
|
||||
/obj/item/device/uplink/hidden/Topic(href, href_list)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user