@@ -1,49 +0,0 @@
|
||||
#define MC_TICK_CHECK ( world.tick_usage > CURRENT_TICKLIMIT ? pause() : 0 )
|
||||
// Used to smooth out costs to try and avoid oscillation.
|
||||
#define MC_AVERAGE_FAST(average, current) (0.7 * (average) + 0.3 * (current))
|
||||
#define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current))
|
||||
#define MC_AVERAGE_SLOW(average, current) (0.9 * (average) + 0.1 * (current))
|
||||
#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
|
||||
|
||||
#define START_PROCESSING(Processor, Datum) if (!Datum.isprocessing) Datum.isprocessing = 1;Processor.processing += Datum
|
||||
#define STOP_PROCESSING(Processor, Datum) if (Datum.isprocessing) Datum.isprocessing = 0;Processor.processing -= Datum
|
||||
|
||||
//SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
|
||||
|
||||
//subsystem should fire during pre-game lobby.
|
||||
#define SS_FIRE_IN_LOBBY 1
|
||||
|
||||
//subsystem does not initialize.
|
||||
#define SS_NO_INIT 2
|
||||
|
||||
//subsystem does not fire.
|
||||
// (like can_fire = 0, but keeps it from getting added to the processing subsystems list)
|
||||
// (Requires a MC restart to change)
|
||||
#define SS_NO_FIRE 4
|
||||
|
||||
//subsystem only runs on spare cpu (after all non-background subsystems have ran that tick)
|
||||
// SS_BACKGROUND has its own priority bracket
|
||||
#define SS_BACKGROUND 8
|
||||
|
||||
//subsystem does not tick check, and should not run unless there is enough time (or its running behind (unless background))
|
||||
#define SS_NO_TICK_CHECK 16
|
||||
|
||||
//Treat wait as a tick count, not DS, run every wait ticks.
|
||||
// (also forces it to run first in the tick, above even SS_NO_TICK_CHECK subsystems)
|
||||
// (implies SS_FIRE_IN_LOBBY because of how it works)
|
||||
// (overrides SS_BACKGROUND)
|
||||
// This is designed for basically anything that works as a mini-mc (like SStimer)
|
||||
#define SS_TICKER 32
|
||||
|
||||
//keep the subsystem's timing on point by firing early if it fired late last fire because of lag
|
||||
// ie: if a 20ds subsystem fires say 5 ds late due to lag or what not, its next fire would be in 15ds, not 20ds.
|
||||
#define SS_KEEP_TIMING 64
|
||||
|
||||
//Calculate its next fire after its fired.
|
||||
// (IE: if a 5ds wait SS takes 2ds to run, its next fire should be 5ds away, not 3ds like it normally would be)
|
||||
// This flag overrides SS_KEEP_TIMING
|
||||
#define SS_POST_FIRE_TIMING 128
|
||||
|
||||
|
||||
//Timing subsystem
|
||||
#define GLOBAL_PROC "some_magic_bullshit"
|
||||
@@ -1,26 +0,0 @@
|
||||
//Bot defines, placed here so they can be read by other things!
|
||||
|
||||
#define BOT_STEP_DELAY 4 //Delay between movemements
|
||||
#define BOT_STEP_MAX_RETRIES 5 //Maximum times a bot will retry to step from its position
|
||||
|
||||
#define DEFAULT_SCAN_RANGE 7 //default view range for finding targets.
|
||||
|
||||
//Mode defines
|
||||
#define BOT_IDLE 0 // idle
|
||||
#define BOT_HUNT 1 // found target, hunting
|
||||
#define BOT_PREP_ARREST 2 // at target, preparing to arrest
|
||||
#define BOT_ARREST 3 // arresting target
|
||||
#define BOT_START_PATROL 4 // start patrol
|
||||
#define BOT_PATROL 5 // patrolling
|
||||
#define BOT_SUMMON 6 // summoned by PDA
|
||||
#define BOT_CLEANING 7 // cleaning (cleanbots)
|
||||
#define BOT_REPAIRING 8 // repairing hull breaches (floorbots)
|
||||
#define BOT_MOVING 9 // for clean/floor/med bots, when moving.
|
||||
#define BOT_HEALING 10 // healing people (medbots)
|
||||
#define BOT_RESPONDING 11 // responding to a call from the AI
|
||||
#define BOT_DELIVER 12 // moving to deliver
|
||||
#define BOT_GO_HOME 13 // returning to home
|
||||
#define BOT_BLOCKED 14 // blocked
|
||||
#define BOT_NAV 15 // computing navigation
|
||||
#define BOT_WAIT_FOR_NAV 16 // waiting for nav computation
|
||||
#define BOT_NO_ROUTE 17 // no destination beacon found (or no route)
|
||||
@@ -1,134 +0,0 @@
|
||||
//ITEM INVENTORY SLOT BITMASKS
|
||||
#define SLOT_OCLOTHING 1
|
||||
#define SLOT_ICLOTHING 2
|
||||
#define SLOT_GLOVES 4
|
||||
#define SLOT_EYES 8
|
||||
#define SLOT_EARS 16
|
||||
#define SLOT_MASK 32
|
||||
#define SLOT_HEAD 64
|
||||
#define SLOT_FEET 128
|
||||
#define SLOT_ID 256
|
||||
#define SLOT_BELT 512
|
||||
#define SLOT_BACK 1024
|
||||
#define SLOT_POCKET 2048 //this is to allow items with a w_class of 3 or 4 to fit in pockets.
|
||||
#define SLOT_DENYPOCKET 4096 //this is to deny items with a w_class of 2 or 1 to fit in pockets.
|
||||
|
||||
//SLOTS
|
||||
#define slot_back 1
|
||||
#define slot_wear_mask 2
|
||||
#define slot_handcuffed 3
|
||||
#define slot_l_hand 4
|
||||
#define slot_r_hand 5
|
||||
#define slot_belt 6
|
||||
#define slot_wear_id 7
|
||||
#define slot_ears 8
|
||||
#define slot_glasses 9
|
||||
#define slot_gloves 10
|
||||
#define slot_head 11
|
||||
#define slot_shoes 12
|
||||
#define slot_wear_suit 13
|
||||
#define slot_w_uniform 14
|
||||
#define slot_l_store 15
|
||||
#define slot_r_store 16
|
||||
#define slot_s_store 17
|
||||
#define slot_in_backpack 18
|
||||
#define slot_legcuffed 19
|
||||
#define slot_drone_storage 20
|
||||
|
||||
#define slots_amt 20 // Keep this up to date!
|
||||
|
||||
//I hate that this has to exist
|
||||
/proc/slotdefine2slotbit(slotdefine) //Keep this up to date with the value of SLOT BITMASKS and SLOTS (the two define sections above)
|
||||
. = 0
|
||||
switch(slotdefine)
|
||||
if(slot_back)
|
||||
. = SLOT_BACK
|
||||
if(slot_wear_mask)
|
||||
. = SLOT_MASK
|
||||
if(slot_belt)
|
||||
. = SLOT_BELT
|
||||
if(slot_wear_id)
|
||||
. = SLOT_ID
|
||||
if(slot_ears)
|
||||
. = SLOT_EARS
|
||||
if(slot_glasses)
|
||||
. = SLOT_EYES
|
||||
if(slot_gloves)
|
||||
. = SLOT_GLOVES
|
||||
if(slot_head)
|
||||
. = SLOT_HEAD
|
||||
if(slot_shoes)
|
||||
. = SLOT_FEET
|
||||
if(slot_wear_suit)
|
||||
. = SLOT_OCLOTHING
|
||||
if(slot_w_uniform)
|
||||
. = SLOT_ICLOTHING
|
||||
if(slot_l_store, slot_r_store)
|
||||
. = SLOT_POCKET
|
||||
|
||||
|
||||
//Bit flags for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses.
|
||||
#define HIDEGLOVES 1
|
||||
#define HIDESUITSTORAGE 2
|
||||
#define HIDEJUMPSUIT 4 //these first four are only used in exterior suits
|
||||
#define HIDESHOES 8
|
||||
#define HIDEMASK 16 //these last six are only used in masks and headgear.
|
||||
#define HIDEEARS 32 // (ears means headsets and such)
|
||||
#define HIDEEYES 64 // Whether eyes and glasses are hidden
|
||||
#define HIDEFACE 128 // Whether we appear as unknown.
|
||||
#define HIDEHAIR 256
|
||||
#define HIDEFACIALHAIR 512
|
||||
|
||||
|
||||
//Cant seem to find a mob bitflags area other than the powers one
|
||||
|
||||
// bitflags for clothing parts - also used for limbs
|
||||
#define HEAD 1
|
||||
#define CHEST 2
|
||||
#define GROIN 4
|
||||
#define LEG_LEFT 8
|
||||
#define LEG_RIGHT 16
|
||||
#define LEGS 24
|
||||
#define FOOT_LEFT 32
|
||||
#define FOOT_RIGHT 64
|
||||
#define FEET 96
|
||||
#define ARM_LEFT 128
|
||||
#define ARM_RIGHT 256
|
||||
#define ARMS 384
|
||||
#define HAND_LEFT 512
|
||||
#define HAND_RIGHT 1024
|
||||
#define HANDS 1536
|
||||
#define FULL_BODY 2047
|
||||
|
||||
// bitflags for the percentual amount of protection a piece of clothing which covers the body part offers.
|
||||
// Used with human/proc/get_heat_protection() and human/proc/get_cold_protection()
|
||||
// The values here should add up to 1.
|
||||
// Hands and feet have 2.5%, arms and legs 7.5%, each of the torso parts has 15% and the head has 30%
|
||||
#define THERMAL_PROTECTION_HEAD 0.3
|
||||
#define THERMAL_PROTECTION_CHEST 0.15
|
||||
#define THERMAL_PROTECTION_GROIN 0.15
|
||||
#define THERMAL_PROTECTION_LEG_LEFT 0.075
|
||||
#define THERMAL_PROTECTION_LEG_RIGHT 0.075
|
||||
#define THERMAL_PROTECTION_FOOT_LEFT 0.025
|
||||
#define THERMAL_PROTECTION_FOOT_RIGHT 0.025
|
||||
#define THERMAL_PROTECTION_ARM_LEFT 0.075
|
||||
#define THERMAL_PROTECTION_ARM_RIGHT 0.075
|
||||
#define THERMAL_PROTECTION_HAND_LEFT 0.025
|
||||
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
|
||||
|
||||
//flags for female outfits: How much the game can safely "take off" the uniform without it looking weird
|
||||
|
||||
#define NO_FEMALE_UNIFORM 0
|
||||
#define FEMALE_UNIFORM_FULL 1
|
||||
#define FEMALE_UNIFORM_TOP 2
|
||||
|
||||
|
||||
//flags for covering body parts
|
||||
#define GLASSESCOVERSEYES 1
|
||||
#define MASKCOVERSEYES 2 // get rid of some of the other retardation in these flags
|
||||
#define HEADCOVERSEYES 4 // feel free to realloc these numbers for other purposes
|
||||
#define MASKCOVERSMOUTH 8 // on other items, these are just for mask/head
|
||||
#define HEADCOVERSMOUTH 16
|
||||
|
||||
#define TINT_DARKENED 2 //Threshold of tint level to apply weld mask overlay
|
||||
#define TINT_BLIND 3 //Threshold of tint level to obscure vision fully
|
||||
@@ -1,118 +0,0 @@
|
||||
|
||||
//Defines copying names of mutations in all cases, make sure to change this if you change mutation's name
|
||||
#define HULK "Hulk"
|
||||
#define XRAY "X Ray Vision"
|
||||
#define COLDRES "Cold Resistance"
|
||||
#define TK "Telekinesis"
|
||||
#define NERVOUS "Nervousness"
|
||||
#define EPILEPSY "Epilepsy"
|
||||
#define MUTATE "Unstable DNA"
|
||||
#define COUGH "Cough"
|
||||
#define DWARFISM "Dwarfism"
|
||||
#define CLOWNMUT "Clumsiness"
|
||||
#define TOURETTES "Tourettes Syndrome"
|
||||
#define DEAFMUT "Deafness"
|
||||
#define BLINDMUT "Blindness"
|
||||
#define RACEMUT "Monkified"
|
||||
#define BADSIGHT "Near Sightness"
|
||||
#define LASEREYES "Laser Eyes"
|
||||
#define CHAMELEON "Chameleon"
|
||||
#define WACKY "Wacky"
|
||||
#define MUT_MUTE "Mute"
|
||||
#define SMILE "Smile"
|
||||
#define UNINTELLIGABLE "Unintelligable"
|
||||
#define SWEDISH "Swedish"
|
||||
#define CHAV "Chav"
|
||||
#define ELVIS "Elvis"
|
||||
|
||||
#define UI_CHANGED "ui changed"
|
||||
#define UE_CHANGED "ue changed"
|
||||
|
||||
#define CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY 204
|
||||
|
||||
// String identifiers for associative list lookup
|
||||
|
||||
//Types of usual mutations
|
||||
#define POSITIVE 1
|
||||
#define NEGATIVE 2
|
||||
#define MINOR_NEGATIVE 3
|
||||
|
||||
//Mutations that cant be taken from genetics and are not in SE
|
||||
#define NON_SCANNABLE -1
|
||||
|
||||
// Extra powers:
|
||||
#define LASER 9 // harm intent - click anywhere to shoot lasers from eyes
|
||||
#define HEAL 10 // healing people with hands
|
||||
#define SHADOW 11 // shadow teleportation (create in/out portals anywhere) (25%)
|
||||
#define SCREAM 12 // supersonic screaming (25%)
|
||||
#define EXPLOSIVE 13 // exploding on-demand (15%)
|
||||
#define REGENERATION 14 // superhuman regeneration (30%)
|
||||
#define REPROCESSOR 15 // eat anything (50%)
|
||||
#define SHAPESHIFTING 16 // take on the appearance of anything (40%)
|
||||
#define PHASING 17 // ability to phase through walls (40%)
|
||||
#define SHIELD 18 // shielding from all projectile attacks (30%)
|
||||
#define SHOCKWAVE 19 // attack a nearby tile and cause a massive shockwave, knocking most people on their asses (25%)
|
||||
#define ELECTRICITY 20 // ability to shoot electric attacks (15%)
|
||||
|
||||
//DNA - Because fuck you and your magic numbers being all over the codebase.
|
||||
#define DNA_BLOCK_SIZE 3
|
||||
|
||||
#define DNA_UNI_IDENTITY_BLOCKS 19
|
||||
#define DNA_HAIR_COLOR_BLOCK 1
|
||||
#define DNA_FACIAL_HAIR_COLOR_BLOCK 2
|
||||
#define DNA_SKIN_TONE_BLOCK 3
|
||||
#define DNA_EYE_COLOR_TWO_BLOCK 4
|
||||
#define DNA_EYE_COLOR_SWITCH_BLOCK 5
|
||||
#define DNA_EYE_COLOR_BLOCK 6
|
||||
#define DNA_GENDER_BLOCK 7
|
||||
#define DNA_FACIAL_HAIR_STYLE_BLOCK 8
|
||||
#define DNA_HAIR_STYLE_BLOCK 9
|
||||
#define DNA_COLOR_ONE_BLOCK 10
|
||||
#define DNA_COLOR_TWO_BLOCK 11
|
||||
#define DNA_COLOR_THR_BLOCK 12
|
||||
#define DNA_COLOR_SWITCH_BLOCK 13
|
||||
#define DNA_COLOR_SWITCH_MAX 7 //must be (2^(n+1))-1
|
||||
#define DNA_COCK_BLOCK 14
|
||||
#define DNA_MUTANTRACE_BLOCK 15
|
||||
#define DNA_MUTANTTAIL_BLOCK 16
|
||||
#define DNA_MUTANTWING_BLOCK 17
|
||||
#define DNA_WINGCOLOR_BLOCK 18
|
||||
#define DNA_TAUR_BLOCK 19
|
||||
|
||||
#define DNA_STRUC_ENZYMES_BLOCKS 19
|
||||
#define DNA_UNIQUE_ENZYMES_LEN 32
|
||||
|
||||
//Transformation proc stuff
|
||||
#define TR_KEEPITEMS 1
|
||||
#define TR_KEEPVIRUS 2
|
||||
#define TR_KEEPDAMAGE 4
|
||||
#define TR_HASHNAME 8 // hashing names (e.g. monkey(e34f)) (only in monkeyize)
|
||||
#define TR_KEEPIMPLANTS 16
|
||||
#define TR_KEEPSE 32 // changelings shouldn't edit the DNA's SE when turning into a monkey
|
||||
#define TR_DEFAULTMSG 64
|
||||
#define TR_KEEPSRC 128
|
||||
#define TR_KEEPORGANS 256
|
||||
|
||||
//Organ stuff, It's here because "Genetics" is the most relevant file for organs and bodyparts
|
||||
#define ORGAN_ORGANIC 1
|
||||
#define ORGAN_ROBOTIC 2
|
||||
|
||||
//Nutrition levels for humans. No idea where else to put it
|
||||
#define NUTRITION_LEVEL_FAT 600
|
||||
#define NUTRITION_LEVEL_FULL 550
|
||||
#define NUTRITION_LEVEL_WELL_FED 450
|
||||
#define NUTRITION_LEVEL_FED 350
|
||||
#define NUTRITION_LEVEL_HUNGRY 250
|
||||
#define NUTRITION_LEVEL_STARVING 150
|
||||
|
||||
#define CLONER_FRESH_CLONE "fresh"
|
||||
#define CLONER_MATURE_CLONE "mature"
|
||||
|
||||
//Blood levels
|
||||
#define BLOOD_VOLUME_MAXIMUM 2000
|
||||
#define BLOOD_VOLUME_SLIME_SPLIT 1120
|
||||
#define BLOOD_VOLUME_NORMAL 560
|
||||
#define BLOOD_VOLUME_SAFE 501
|
||||
#define BLOOD_VOLUME_OKAY 336
|
||||
#define BLOOD_VOLUME_BAD 224
|
||||
#define BLOOD_VOLUME_SURVIVE 122
|
||||
@@ -1,18 +0,0 @@
|
||||
//List of all preclaimed planes
|
||||
//Generally 'arbitrary' planes should be given a constant number
|
||||
//Planes that are dependent upon another plane value should be defined with that plane
|
||||
#define PLANE_SPACE_BACKGROUND -10
|
||||
#define PLANE_SPACE_PARALLAX (PLANE_SPACE_BACKGROUND + 1)
|
||||
#define PLANE_SPACE_DUST (PLANE_SPACE_PARALLAX + 1)
|
||||
|
||||
#define PLANE_TURF -6
|
||||
#define PLANE_NOIR_BLOOD -5
|
||||
#define PLANE_OBJ -4
|
||||
#define PLANE_MOB -3
|
||||
#define PLANE_EFFECTS -2
|
||||
#define PLANE_LIGHTING -1
|
||||
|
||||
#define PLANE_BASE 0
|
||||
|
||||
#define PLANE_STATIC 1
|
||||
#define PLANE_HUD 2
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
#define CAT_NONE ""
|
||||
#define CAT_WEAPON "Weaponry"
|
||||
#define CAT_AMMO "Ammunition"
|
||||
#define CAT_ROBOT "Robots"
|
||||
#define CAT_FOOD "Food"
|
||||
#define CAT_MISC "Misc"
|
||||
#define CAT_PRIMAL "Tribal"
|
||||
@@ -1 +0,0 @@
|
||||
#define CLICKCATCHER_PLANE -99
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* Additional variables that must be defined on /mob/living/carbon/human
|
||||
* for use in code that is part of the vore modules.
|
||||
*
|
||||
* These variables are declared here (separately from the normal human_defines.dm)
|
||||
* in order to isolate VOREStation changes and ease merging of other codebases.
|
||||
*/
|
||||
|
||||
// Additional vars
|
||||
/mob/living/carbon/human
|
||||
|
||||
// Horray Furries!
|
||||
var/datum/sprite_accessory/ears/ear_style = null
|
||||
var/datum/sprite_accessory/tail/tail_style = null
|
||||
var/r_tail = 30
|
||||
var/g_tail = 30
|
||||
var/b_tail = 30
|
||||
|
||||
// Custom Species Name
|
||||
var/custom_species
|
||||
@@ -1,44 +0,0 @@
|
||||
// ---------------------------------------------
|
||||
// -!-!-!-!-!-!-!-!- READ ME -!-!-!-!-!-!-!-!-!-
|
||||
// ---------------------------------------------
|
||||
|
||||
//Beep beep hello
|
||||
//
|
||||
//Use this file to define the exclusive abilities of the spidertaur folk
|
||||
//
|
||||
//ahuhuhuhu
|
||||
//-Antsnap
|
||||
|
||||
obj/item/clothing/suit/web_bindings
|
||||
icon = 'icons/obj/clothing/suits.dmi'
|
||||
name = "web bindings"
|
||||
desc = "A webbed cocoon that completely restrains the wearer."
|
||||
icon_state = "web_bindings"
|
||||
item_state = "web_bindings"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
|
||||
|
||||
/* //Commenting all this out, as people keep abusing it. Sorry!
|
||||
mob/proc/weaveWeb()
|
||||
set name = "Weave Web"
|
||||
set category = "Species Powers"
|
||||
if(nutrition >= 500) //People decided to abuse it. Sorry. It was asked to be made so it couldn't be spammed, and what do ya know, people are spamming it everywhere.
|
||||
src.visible_message("<span class='notice'>\the [src] weaves a web from their spinneret silk.</span>")
|
||||
nutrition -= 500
|
||||
spawn(30) //3 seconds to form
|
||||
new /obj/effect/spider/stickyweb(src.loc)
|
||||
else
|
||||
src << "You do not have enough nutrition to create webbing!"
|
||||
*/
|
||||
|
||||
mob/proc/weaveWebBindings()
|
||||
set name = "Weave Web Bindings"
|
||||
set category = "Species Powers"
|
||||
if(nutrition >= 30) //This isn't a huge problem. This is so you can bind people up.
|
||||
src.visible_message("<span class='notice'>\the [src] pulls silk from their spinneret and delicately weaves it into bindings.</span>")
|
||||
nutrition -= 30
|
||||
spawn(30) //5 seconds to weave the bindings~
|
||||
var/obj/item/clothing/suit/web_bindings/bindings = new() //This sprite is amazing, I must say.
|
||||
src.put_in_hands(bindings)
|
||||
else
|
||||
src << "You do not have enough nutrition to create webbing!" //CK~
|
||||
@@ -1,645 +0,0 @@
|
||||
/*
|
||||
Hello and welcome to VOREStation sprite_accessories: For a more general overview
|
||||
please read sprite_accessories.dm. This file is for ears, tails, and taur bodies!
|
||||
|
||||
This is intended to be friendly for people with little to no actual coding experience.
|
||||
|
||||
!!WARNING!!: changing existing accessory information can be VERY hazardous to savefiles,
|
||||
to the point where you may completely corrupt a server's savefiles. Please refrain
|
||||
from doing this unless you absolutely know what you are doing, and have defined a
|
||||
conversion in savefile.dm
|
||||
*/
|
||||
|
||||
// Add Additional variable onto sprite_accessory
|
||||
/datum/sprite_accessory
|
||||
// Ckey of person allowed to use this, if defined.
|
||||
var/list/ckeys_allowed = null
|
||||
|
||||
/*
|
||||
////////////////////////////
|
||||
/ =--------------------= /
|
||||
/ == Ear Definitions == /
|
||||
/ =--------------------= /
|
||||
////////////////////////////
|
||||
*/
|
||||
/datum/sprite_accessory/ears
|
||||
name = "You should not see this..."
|
||||
icon = 'icons/mob/vore/ears_vr.dmi'
|
||||
do_colouration = 0 // Set to 1 to blend (ICON_ADD) hair color
|
||||
|
||||
var/color_blend_mode = ICON_ADD // Only appliciable if do_coloration = 1
|
||||
var/extra_overlay // Icon state of an additional overlay to blend in.
|
||||
var/desc = "You should not see this..."
|
||||
|
||||
// Ears avaliable to anyone
|
||||
|
||||
/datum/sprite_accessory/ears/squirrel_orange
|
||||
name = "squirel, orange"
|
||||
desc = ""
|
||||
icon_state = "squirrel-orange"
|
||||
|
||||
/datum/sprite_accessory/ears/squirrel_red
|
||||
name = "squirrel, red"
|
||||
desc = ""
|
||||
icon_state = "squirrel-red"
|
||||
|
||||
/datum/sprite_accessory/ears/bunny_white
|
||||
name = "bunny, white"
|
||||
desc = ""
|
||||
icon_state = "bunny"
|
||||
|
||||
/datum/sprite_accessory/ears/bear_brown
|
||||
name = "bear, brown"
|
||||
desc = ""
|
||||
icon_state = "bear-brown"
|
||||
|
||||
/datum/sprite_accessory/ears/wolf_grey
|
||||
name = "wolf, grey"
|
||||
desc = ""
|
||||
icon_state = "wolf-grey"
|
||||
|
||||
/datum/sprite_accessory/ears/wolf_green
|
||||
name = "wolf, green"
|
||||
desc = ""
|
||||
icon_state = "wolf-green"
|
||||
|
||||
/datum/sprite_accessory/ears/wisewolf
|
||||
name = "wolf, wise"
|
||||
desc = ""
|
||||
icon_state = "wolf-wise"
|
||||
|
||||
/datum/sprite_accessory/ears/mouse_grey
|
||||
name = "mouse, grey"
|
||||
desc = ""
|
||||
icon_state = "mouse-grey"
|
||||
|
||||
/datum/sprite_accessory/ears/bee
|
||||
name = "bee antennae"
|
||||
desc = ""
|
||||
icon_state = "bee"
|
||||
|
||||
/datum/sprite_accessory/ears/oni_h1
|
||||
name = "oni horns"
|
||||
desc = ""
|
||||
icon_state = "oni-h1"
|
||||
|
||||
/datum/sprite_accessory/ears/demon_horns1
|
||||
name = "demon horns"
|
||||
desc = ""
|
||||
icon_state = "demon-horns1"
|
||||
|
||||
/datum/sprite_accessory/ears/foxears
|
||||
name = "highlander zorren ears"
|
||||
desc = ""
|
||||
icon_state = "foxears"
|
||||
|
||||
/datum/sprite_accessory/ears/fenears
|
||||
name = "flatland zorren ears"
|
||||
desc = ""
|
||||
icon_state = "fenears"
|
||||
|
||||
/datum/sprite_accessory/ears/sergal
|
||||
name = "Sergal ears"
|
||||
icon_state = "serg_plain_s"
|
||||
|
||||
/datum/sprite_accessory/ears/foxearshc
|
||||
name = "highlander zorren ears, colorable"
|
||||
desc = ""
|
||||
icon_state = "foxearshc"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/ears/fenearshc
|
||||
name = "flatland zorren ears, colorable"
|
||||
desc = ""
|
||||
icon_state = "fenearshc"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/ears/sergalhc
|
||||
name = "Sergal ears, colorable"
|
||||
icon_state = "serg_plain_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/ears/mousehc
|
||||
name = "mouse, colorable"
|
||||
desc = ""
|
||||
icon_state = "mouse"
|
||||
do_colouration = 1
|
||||
extra_overlay = "mouseinner"
|
||||
|
||||
/datum/sprite_accessory/ears/wolfhc
|
||||
name = "wolf, colorable"
|
||||
desc = ""
|
||||
icon_state = "wolf"
|
||||
do_colouration = 1
|
||||
extra_overlay = "wolfinner"
|
||||
|
||||
/datum/sprite_accessory/ears/bearhc
|
||||
name = "bear, colorable"
|
||||
desc = ""
|
||||
icon_state = "bear"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/ears/squirrelhc
|
||||
name = "squirrel, colorable"
|
||||
desc = ""
|
||||
icon_state = "squirrel"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/ears/kittyhc
|
||||
name = "kitty, colorable"
|
||||
desc = ""
|
||||
icon_state = "kitty"
|
||||
do_colouration = 1
|
||||
extra_overlay = "kittyinner"
|
||||
|
||||
/datum/sprite_accessory/ears/bunnyhc
|
||||
name = "bunny, colorable"
|
||||
desc = ""
|
||||
icon_state = "bunny"
|
||||
do_colouration = 1
|
||||
|
||||
// Special snowflake ears go below here.
|
||||
|
||||
/datum/sprite_accessory/ears/molenar_kitsune
|
||||
name = "quintail kitsune ears (Molenar)"
|
||||
desc = ""
|
||||
icon_state = "molenar-kitsune"
|
||||
ckeys_allowed = list("molenar")
|
||||
|
||||
/datum/sprite_accessory/ears/molenar_deathclaw
|
||||
name = "deathclaw ears (Molenar)"
|
||||
desc = ""
|
||||
icon_state = "molenar-deathclaw"
|
||||
ckeys_allowed = list("molenar")
|
||||
|
||||
/datum/sprite_accessory/ears/runac
|
||||
name = "fennecsune ears (Runac)"
|
||||
desc = ""
|
||||
icon_state = "runac"
|
||||
ckeys_allowed = list("rebcom1807")
|
||||
|
||||
/datum/sprite_accessory/ears/kerena
|
||||
name = "wingwolf ears (Kerena)"
|
||||
desc = ""
|
||||
icon_state = "kerena"
|
||||
ckeys_allowed = list("somekindofpony")
|
||||
|
||||
/datum/sprite_accessory/ears/rosey
|
||||
name = "tritail kitsune ears (Rosey)"
|
||||
desc = ""
|
||||
icon_state = "rosey"
|
||||
ckeys_allowed = list("joey4298")
|
||||
|
||||
/datum/sprite_accessory/ears/aronai
|
||||
name = "aronai ears/head (Aronai)"
|
||||
desc = ""
|
||||
icon_state = "aronai"
|
||||
ckeys_allowed = list("arokha")
|
||||
|
||||
/*
|
||||
////////////////////////////
|
||||
/ =--------------------= /
|
||||
/ == Tail Definitions == /
|
||||
/ =--------------------= /
|
||||
////////////////////////////
|
||||
*/
|
||||
/datum/sprite_accessory/tail
|
||||
name = "You should not see this..."
|
||||
icon = 'icons/mob/vore/tails_vr.dmi'
|
||||
do_colouration = 0 //Set to 1 to enable coloration using the tail color.
|
||||
|
||||
var/color_blend_mode = ICON_ADD // Only appliciable if do_coloration = 1
|
||||
var/extra_overlay // Icon state of an additional overlay to blend in.
|
||||
var/show_species_tail = 0 // If false, do not render species' tail.
|
||||
var/clothing_can_hide = 1 // If true, clothing with HIDETAIL hides it
|
||||
var/desc = "You should not see this..."
|
||||
|
||||
/datum/sprite_accessory/tail/invisible
|
||||
name = "hide species-sprite tail"
|
||||
icon = null
|
||||
icon_state = null
|
||||
|
||||
/datum/sprite_accessory/tail/squirrel_orange
|
||||
name = "squirel, orange"
|
||||
desc = ""
|
||||
icon_state = "squirrel-orange"
|
||||
|
||||
/datum/sprite_accessory/tail/squirrel_red
|
||||
name = "squirrel, red"
|
||||
desc = ""
|
||||
icon_state = "squirrel-red"
|
||||
|
||||
/datum/sprite_accessory/tail/squirrel
|
||||
name = "squirrel, colorable"
|
||||
desc = ""
|
||||
icon_state = "squirrel"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/kitty
|
||||
name = "kitty, colorable, downwards"
|
||||
desc = ""
|
||||
icon_state = "kittydown"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/kittyup
|
||||
name = "kitty, colorable, upwards"
|
||||
desc = ""
|
||||
icon_state = "kittyup"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/tiger_white
|
||||
name = "tiger, colorable, white stripes"
|
||||
desc = ""
|
||||
icon_state = "tiger"
|
||||
do_colouration = 1
|
||||
extra_overlay = "tigerinnerwhite"
|
||||
|
||||
/datum/sprite_accessory/tail/tiger_black
|
||||
name = "tiger, colorable, black stripes"
|
||||
desc = ""
|
||||
icon_state = "tiger"
|
||||
do_colouration = 1
|
||||
extra_overlay = "tigerinnerblack"
|
||||
|
||||
/datum/sprite_accessory/tail/stripey
|
||||
name = "stripey taj, colorable"
|
||||
desc = ""
|
||||
icon_state = "stripeytail"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/stripeytail_brown
|
||||
name = "stripey taj, brown"
|
||||
desc = ""
|
||||
icon_state = "stripeytail-brown"
|
||||
|
||||
/datum/sprite_accessory/tail/bunny
|
||||
name = "bunny, colorable"
|
||||
desc = ""
|
||||
icon_state = "bunny"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/mothc
|
||||
name = "moth wings, colorable"
|
||||
desc = ""
|
||||
icon_state = "moth"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/moth
|
||||
name = "moth wings"
|
||||
desc = ""
|
||||
icon_state = "moth"
|
||||
|
||||
/datum/sprite_accessory/tail/bear_brown
|
||||
name = "bear, brown"
|
||||
desc = ""
|
||||
icon_state = "bear-brown"
|
||||
|
||||
/datum/sprite_accessory/tail/bear
|
||||
name = "bear, colorable"
|
||||
desc = ""
|
||||
icon_state = "bear"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/wolf_grey
|
||||
name = "wolf, grey"
|
||||
desc = ""
|
||||
icon_state = "wolf-grey"
|
||||
|
||||
/datum/sprite_accessory/tail/wolf_green
|
||||
name = "wolf, green"
|
||||
desc = ""
|
||||
icon_state = "wolf-green"
|
||||
|
||||
/datum/sprite_accessory/tail/wisewolf
|
||||
name = "wolf, wise"
|
||||
desc = ""
|
||||
icon_state = "wolf-wise"
|
||||
|
||||
/datum/sprite_accessory/tail/blackwolf
|
||||
name = "wolf, black"
|
||||
desc = ""
|
||||
icon_state = "wolf"
|
||||
|
||||
/datum/sprite_accessory/tail/wolf
|
||||
name = "wolf, colorable"
|
||||
desc = ""
|
||||
icon_state = "wolf"
|
||||
do_colouration = 1
|
||||
extra_overlay = "wolfinner"
|
||||
|
||||
/datum/sprite_accessory/tail/mouse_grey
|
||||
name = "mouse, grey"
|
||||
desc = ""
|
||||
icon_state = "mouse-grey"
|
||||
|
||||
/datum/sprite_accessory/tail/crossfox
|
||||
name = "cross fox"
|
||||
desc = ""
|
||||
icon_state = "crossfox"
|
||||
|
||||
/datum/sprite_accessory/tail/mouse
|
||||
name = "mouse, colorable"
|
||||
desc = ""
|
||||
icon_state = "mouse"
|
||||
do_colouration = 1
|
||||
extra_overlay = "mouseinner"
|
||||
|
||||
/datum/sprite_accessory/tail/bee
|
||||
name = "bee thorax (+wings)"
|
||||
desc = ""
|
||||
icon_state = "bee"
|
||||
|
||||
/datum/sprite_accessory/tail/moth_full
|
||||
name = "moth antenna and wings"
|
||||
desc = ""
|
||||
icon_state = "moth_full"
|
||||
|
||||
/datum/sprite_accessory/tail/succubus_purple
|
||||
name = "succubus, purple (+wings)"
|
||||
desc = ""
|
||||
icon_state = "succubus-purple"
|
||||
|
||||
/datum/sprite_accessory/tail/succubus_red
|
||||
name = "succubus, red (+wings)"
|
||||
desc = ""
|
||||
icon_state = "succubus-red"
|
||||
|
||||
/datum/sprite_accessory/tail/succubus_black
|
||||
name = "succubus, black (+wings)"
|
||||
desc = ""
|
||||
icon_state = "succubus-black"
|
||||
|
||||
/datum/sprite_accessory/tail/bat_black
|
||||
name = "bat wings, black"
|
||||
desc = ""
|
||||
icon_state = "bat-black"
|
||||
show_species_tail = 1
|
||||
|
||||
/datum/sprite_accessory/tail/bat_red
|
||||
name = "bat wings, red"
|
||||
desc = ""
|
||||
icon_state = "bat-red"
|
||||
show_species_tail = 1
|
||||
|
||||
/datum/sprite_accessory/tail/snag
|
||||
name = "xenomorph tail w/ backplate"
|
||||
desc = ""
|
||||
icon_state = "snag"
|
||||
|
||||
/datum/sprite_accessory/tail/xenotail
|
||||
name = "xenomorph tail"
|
||||
desc = ""
|
||||
icon_state = "xenotail"
|
||||
|
||||
/datum/sprite_accessory/tail/molenar_kitsune
|
||||
name = "quintail kitsune tails (Molenar)"
|
||||
desc = ""
|
||||
icon_state = "molenar-kitsune"
|
||||
ckeys_allowed = list("molenar")
|
||||
|
||||
/datum/sprite_accessory/tail/molenar_deathclaw
|
||||
name = "deathclaw bits (Molenar)"
|
||||
desc = ""
|
||||
icon_state = "molenar-deathclaw"
|
||||
ckeys_allowed = list("molenar","jertheace")
|
||||
|
||||
/datum/sprite_accessory/tail/runac
|
||||
name = "fennecsune tails (Runac)"
|
||||
desc = ""
|
||||
icon_state = "runac"
|
||||
ckeys_allowed = list("rebcom1807")
|
||||
|
||||
/datum/sprite_accessory/tail/kerena
|
||||
name = "wingwolf tail (+wings) (Kerena)"
|
||||
desc = ""
|
||||
icon_state = "kerena"
|
||||
ckeys_allowed = list("somekindofpony")
|
||||
|
||||
/datum/sprite_accessory/tail/rosey
|
||||
name = "tritail kitsune tails (Rosey)"
|
||||
desc = ""
|
||||
icon_state = "rosey"
|
||||
ckeys_allowed = list("joey4298")
|
||||
|
||||
/datum/sprite_accessory/tail/scree
|
||||
name = "green taj tail (+wings) (Scree)"
|
||||
desc = ""
|
||||
icon_state = "scree"
|
||||
ckeys_allowed = list("scree")
|
||||
|
||||
/datum/sprite_accessory/tail/aronai
|
||||
name = "aronai tail (Aronai)"
|
||||
desc = ""
|
||||
icon_state = "aronai"
|
||||
ckeys_allowed = list("arokha")
|
||||
|
||||
/datum/sprite_accessory/tail/feathered
|
||||
name = "feathered wings"
|
||||
desc = ""
|
||||
icon_state = "feathered"
|
||||
|
||||
//For all species tails. Includes haircolored tails.
|
||||
/datum/sprite_accessory/tail/special
|
||||
name = "Blank tail. Do not select."
|
||||
icon = 'icons/effects/species_tails_vr.dmi'
|
||||
|
||||
/datum/sprite_accessory/tail/special/unathi
|
||||
name = "unathi tail"
|
||||
desc = ""
|
||||
icon_state = "sogtail_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/tajaran
|
||||
name = "tajaran tail"
|
||||
desc = ""
|
||||
icon_state = "tajtail_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/sergal
|
||||
name = "sergal tail"
|
||||
desc = ""
|
||||
icon_state = "sergtail_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/akula
|
||||
name = "akula tail"
|
||||
desc = ""
|
||||
icon_state = "sharktail_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/nevrean
|
||||
name = "nevrean tail"
|
||||
desc = ""
|
||||
icon_state = "nevreantail_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/armalis
|
||||
name = "armalis tail"
|
||||
desc = ""
|
||||
icon_state = "armalis_tail_humanoid_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/xenodrone
|
||||
name = "xenomorph drone tail"
|
||||
desc = ""
|
||||
icon_state = "xenos_drone_tail_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/xenosentinel
|
||||
name = "xenomorph sentinel tail"
|
||||
desc = ""
|
||||
icon_state = "xenos_sentinel_tail_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/xenohunter
|
||||
name = "xenomorph hunter tail"
|
||||
desc = ""
|
||||
icon_state = "xenos_hunter_tail_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/xenoqueen
|
||||
name = "xenomorph queen tail"
|
||||
desc = ""
|
||||
icon_state = "xenos_queen_tail_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/monkey
|
||||
name = "monkey tail"
|
||||
desc = ""
|
||||
icon_state = "chimptail_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/seromitail
|
||||
name = "seromi tail"
|
||||
desc = ""
|
||||
icon_state = "seromitail_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/seromitailfeathered
|
||||
name = "seromi tail w/ feathers"
|
||||
desc = ""
|
||||
icon_state = "seromitail_feathers_s"
|
||||
|
||||
/datum/sprite_accessory/tail/special/unathihc
|
||||
name = "unathi tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "sogtail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/tajaranhc
|
||||
name = "tajaran tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "tajtail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/sergalhc
|
||||
name = "sergal tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "sergtail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/akulahc
|
||||
name = "akula tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "sharktail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/nevreanhc
|
||||
name = "nevrean tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "nevreantail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/foxhc
|
||||
name = "highlander zorren tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "foxtail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/fennechc
|
||||
name = "flatland zorren tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "fentail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/armalishc
|
||||
name = "armalis tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "armalis_tail_humanoid_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/xenodronehc
|
||||
name = "xenomorph drone tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "xenos_drone_tail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/xenosentinelhc
|
||||
name = "xenomorph sentinel tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "xenos_sentinel_tail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/xenohunterhc
|
||||
name = "xenomorph hunter tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "xenos_hunter_tail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/xenoqueenhc
|
||||
name = "xenomorph queen tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "xenos_queen_tail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/monkeyhc
|
||||
name = "monkey tail, colorable, colorable"
|
||||
desc = ""
|
||||
icon_state = "chimptail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/seromitailhc
|
||||
name = "seromi tail, colorable"
|
||||
desc = ""
|
||||
icon_state = "seromitail_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/datum/sprite_accessory/tail/special/seromitailfeatheredhc
|
||||
name = "seromi tail w/ feathers, colorable"
|
||||
desc = ""
|
||||
icon_state = "seromitail_feathers_hc_s"
|
||||
do_colouration = 1
|
||||
|
||||
/*
|
||||
////////////////////////////
|
||||
/ =--------------------= /
|
||||
/ == Taur Definitions == /
|
||||
/ =--------------------= /
|
||||
////////////////////////////
|
||||
*/
|
||||
|
||||
// Taur sprites are now a subtype of tail since they are mutually exclusive anyway.
|
||||
|
||||
/datum/sprite_accessory/tail/taur
|
||||
name = "You should not see this..."
|
||||
icon = 'icons/mob/vore/taurs_vr.dmi'
|
||||
do_colouration = 1 // Yes color, using tail color
|
||||
color_blend_mode = ICON_MULTIPLY // The sprites for taurs are designed for ICON_MULTIPLY
|
||||
|
||||
/datum/sprite_accessory/tail/taur/wolf
|
||||
name = "Wolf"
|
||||
icon_state = "wolf_s"
|
||||
|
||||
/datum/sprite_accessory/tail/taur/naga
|
||||
name = "Naga"
|
||||
icon_state = "naga_s"
|
||||
|
||||
/datum/sprite_accessory/tail/taur/horse
|
||||
name = "Horse"
|
||||
icon_state = "horse_s"
|
||||
|
||||
/datum/sprite_accessory/tail/taur/cow
|
||||
name = "Cow"
|
||||
icon_state = "cow_s"
|
||||
|
||||
/datum/sprite_accessory/tail/taur/lizard
|
||||
name = "Lizard"
|
||||
icon_state = "lizard_s"
|
||||
|
||||
/datum/sprite_accessory/tail/taur/spider
|
||||
name = "Spider"
|
||||
icon_state = "spider_s"
|
||||
|
||||
/datum/sprite_accessory/tail/taur/tents
|
||||
name = "Tentacles"
|
||||
icon_state = "tent_s"
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
|
||||
#define isTaurTail(A) istype(A, /datum/sprite_accessory/tail/taur)
|
||||
|
||||
/mob/living/carbon/human/proc/get_ears_overlay()
|
||||
if(ear_style && !(head && (head.flags_inv & BLOCKHEADHAIR)))
|
||||
var/icon/ears_s = new/icon("icon" = ear_style.icon, "icon_state" = ear_style.icon_state)
|
||||
if(ear_style.do_colouration)
|
||||
ears_s.Blend(rgb(src.r_hair, src.g_hair, src.b_hair), ear_style.color_blend_mode)
|
||||
if(ear_style.extra_overlay)
|
||||
var/icon/overlay = new/icon("icon" = ear_style.icon, "icon_state" = ear_style.extra_overlay)
|
||||
ears_s.Blend(overlay, ICON_OVERLAY)
|
||||
return ears_s
|
||||
return null
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/get_tail_image()
|
||||
//If you are FBP with tail style
|
||||
if(synthetic && synthetic.includes_tail)
|
||||
var/icon/tail_s = new/icon("icon" = synthetic.icon, "icon_state" = "tail")
|
||||
return image(tail_s)
|
||||
|
||||
//If you have a custom tail selected
|
||||
if(tail_style && !(wear_suit && wear_suit.flags_inv & HIDETAIL && !isTaurTail(tail_style)))
|
||||
var/icon/tail_s = new/icon("icon" = tail_style.icon, "icon_state" = tail_style.icon_state)
|
||||
if(tail_style.do_colouration)
|
||||
tail_s.Blend(rgb(src.r_tail, src.g_tail, src.b_tail), tail_style.color_blend_mode)
|
||||
if(tail_style.extra_overlay)
|
||||
var/icon/overlay = new/icon("icon" = tail_style.icon, "icon_state" = tail_style.extra_overlay)
|
||||
tail_s.Blend(overlay, ICON_OVERLAY)
|
||||
qdel(overlay)
|
||||
|
||||
if(isTaurTail(tail_style))
|
||||
return image(tail_s, "pixel_x" = -16)
|
||||
else
|
||||
return image(tail_s)
|
||||
return null
|
||||
@@ -1,419 +0,0 @@
|
||||
//
|
||||
// The belly object is what holds onto a mob while they're inside a predator.
|
||||
// It takes care of altering the pred's decription, digesting the prey, relaying struggles etc.
|
||||
//
|
||||
|
||||
// If you change what variables are on this, then you need to update the copy() proc.
|
||||
|
||||
//
|
||||
// Parent type of all the various "belly" varieties.
|
||||
//
|
||||
/datum/belly
|
||||
var/name // Name of this location
|
||||
var/inside_flavor // Flavor text description of inside sight/sound/smells/feels.
|
||||
var/vore_sound = 'sound/vore/gulp.ogg' // Sound when ingesting someone
|
||||
var/vore_verb = "ingest" // Verb for eating with this in messages
|
||||
var/human_prey_swallow_time = 100 // Time in deciseconds to swallow /mob/living/carbon/human
|
||||
var/nonhuman_prey_swallow_time = 100 // Time in deciseconds to swallow anything else
|
||||
var/emoteTime = 600 // How long between stomach emotes at prey
|
||||
var/digest_brute = 1 // Brute damage per tick in digestion mode
|
||||
var/digest_burn = 1 // Burn damage per tick in digestion mode
|
||||
var/digest_tickrate = 3 // Modulus this of air controller tick number to iterate gurgles on
|
||||
var/immutable = 0 // Prevents this belly from being deleted
|
||||
var/integrity = 100 // Gut 'health' weakened by non help intent stuggles
|
||||
var/escapable = 0 // Belly can be resisted out of at any time
|
||||
var/escapetime = 600 // Deciseconds, how long to escape this belly
|
||||
|
||||
var/tmp/digest_mode = DM_HOLD // Whether or not to digest. Default to not digest.
|
||||
var/tmp/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_HEAL,DM_DIGESTF) // Possible digest modes
|
||||
var/tmp/mob/living/owner // The mob whose belly this is.
|
||||
var/tmp/list/internal_contents = list() // People/Things you've eaten into this belly!
|
||||
var/tmp/is_full // Flag for if digested remeans are present. (for disposal messages)
|
||||
var/tmp/emotePend = 0 // If there's already a spawned thing counting for the next emote
|
||||
var/tmp/recent_struggle = 0 // Flag to prevent struggle emote spam
|
||||
// Don't forget to watch your commas at the end of each line if you change these.
|
||||
var/datum/gas_mixture/air_contents = new() // Belly Air stuff
|
||||
|
||||
var/list/struggle_messages_outside = list(
|
||||
"%pred's %belly wobbles with a squirming meal.",
|
||||
"%pred's %belly jostles with movement.",
|
||||
"%pred's %belly briefly swells outward as someone pushes from inside.",
|
||||
"%pred's %belly fidgets with a trapped victim.",
|
||||
"%pred's %belly jiggles with motion from inside.",
|
||||
"%pred's %belly sloshes around.",
|
||||
"%pred's %belly gushes softly.",
|
||||
"%pred's %belly lets out a wet squelch.")
|
||||
|
||||
var/list/struggle_messages_inside = list(
|
||||
"Your useless squirming only causes %pred's slimy %belly to squelch over your body.",
|
||||
"Your struggles only cause %pred's %belly to gush softly around you.",
|
||||
"Your movement only causes %pred's %belly to slosh around you.",
|
||||
"Your motion causes %pred's %belly to jiggle.",
|
||||
"You fidget around inside of %pred's %belly.",
|
||||
"You shove against the walls of %pred's %belly, making it briefly swell outward.",
|
||||
"You jostle %pred's %belly with movement.",
|
||||
"You squirm inside of %pred's %belly, making it wobble around.")
|
||||
|
||||
var/list/digest_messages_owner = list(
|
||||
"You feel %prey's body succumb to your digestive system, which breaks it apart into soft slurry.",
|
||||
"You hear a lewd glorp as your %belly muscles grind %prey into a warm pulp.",
|
||||
"Your %belly lets out a rumble as it melts %prey into sludge.",
|
||||
"You feel a soft gurgle as %prey's body loses form in your %belly. They're nothing but a soft mass of churning slop now.",
|
||||
"Your %belly begins gushing %prey's remains through your system, adding some extra weight to your thighs.",
|
||||
"Your %belly begins gushing %prey's remains through your system, adding some extra weight to your rump.",
|
||||
"Your %belly begins gushing %prey's remains through your system, adding some extra weight to your belly.",
|
||||
"Your %belly groans as %prey falls apart into a thick soup. You can feel their remains soon flowing deeper into your body to be absorbed.",
|
||||
"Your %belly kneads on every fiber of %prey, softening them down into mush to fuel your next hunt.",
|
||||
"Your %belly churns %prey down into a hot slush. You can feel the nutrients coursing through your digestive track with a series of long, wet glorps.")
|
||||
|
||||
var/list/digest_messages_prey = list(
|
||||
"Your body succumbs to %pred's digestive system, which breaks you apart into soft slurry.",
|
||||
"%pred's %belly lets out a lewd glorp as their muscles grind you into a warm pulp.",
|
||||
"%pred's %belly lets out a rumble as it melts you into sludge.",
|
||||
"%pred feels a soft gurgle as your body loses form in their %belly. You're nothing but a soft mass of churning slop now.",
|
||||
"%pred's %belly begins gushing your remains through their system, adding some extra weight to %pred's thighs.",
|
||||
"%pred's %belly begins gushing your remains through their system, adding some extra weight to %pred's rump.",
|
||||
"%pred's %belly begins gushing your remains through their system, adding some extra weight to %pred's belly.",
|
||||
"%pred's %belly groans as you fall apart into a thick soup. Your remains soon flow deeper into %pred's body to be absorbed.",
|
||||
"%pred's %belly kneads on every fiber of your body, softening you down into mush to fuel their next hunt.",
|
||||
"%pred's %belly churns you down into a hot slush. Your nutrient-rich remains course through their digestive track with a series of long, wet glorps.")
|
||||
|
||||
var/list/examine_messages = list(
|
||||
"They have something solid in their %belly!",
|
||||
"It looks like they have something in their %belly!")
|
||||
|
||||
//Mostly for being overridden on precreated bellies on mobs. Could be VV'd into
|
||||
//a carbon's belly if someone really wanted. No UI for carbons to adjust this.
|
||||
//List has indexes that are the digestion mode strings, and keys that are lists of strings.
|
||||
var/list/emote_lists = list()
|
||||
|
||||
// Constructor that sets the owning mob
|
||||
/datum/belly/New(var/mob/living/owning_mob)
|
||||
owner = owning_mob
|
||||
|
||||
// Toggle digestion on/off and notify user of the new setting.
|
||||
// If multiple digestion modes are avaliable (i.e. unbirth) then user should be prompted.
|
||||
/datum/belly/proc/toggle_digestion()
|
||||
return
|
||||
|
||||
// Checks if any mobs are present inside the belly
|
||||
// return True if the belly is empty.
|
||||
/datum/belly/proc/is_empty()
|
||||
return internal_contents.len == 0
|
||||
|
||||
// Release all contents of this belly into the owning mob's location.
|
||||
// If that location is another mob, contents are transferred into whichever of its bellies the owning mob is in.
|
||||
// Returns the number of mobs so released.
|
||||
/datum/belly/proc/release_all_contents()
|
||||
for (var/atom/movable/M in internal_contents)
|
||||
M.forceMove(owner.loc) // Move the belly contents into the same location as belly's owner.
|
||||
internal_contents -= M // Remove from the belly contents
|
||||
|
||||
var/datum/belly/B = check_belly(owner) // This makes sure that the mob behaves properly if released into another mob
|
||||
if(B)
|
||||
B.internal_contents += M
|
||||
|
||||
owner.visible_message("<font color='green'><b>[owner] expels everything from their [lowertext(name)]!</b></font>")
|
||||
return 1
|
||||
|
||||
// Release a specific atom from the contents of this belly into the owning mob's location.
|
||||
// If that location is another mob, the atom is transferred into whichever of its bellies the owning mob is in.
|
||||
// Returns the number of atoms so released.
|
||||
/datum/belly/proc/release_specific_contents(var/atom/movable/M)
|
||||
if (!(M in internal_contents))
|
||||
return 0 // They weren't in this belly anyway
|
||||
|
||||
M.forceMove(owner.loc) // Move the belly contents into the same location as belly's owner.
|
||||
src.internal_contents -= M // Remove from the belly contents
|
||||
|
||||
var/datum/belly/B = check_belly(owner)
|
||||
if(B)
|
||||
B.internal_contents += M
|
||||
|
||||
owner.visible_message("<font color='green'><b>[owner] expels [M] from their [lowertext(name)]!</b></font>")
|
||||
owner.update_icons()
|
||||
return 1
|
||||
|
||||
// Actually perform the mechanics of devouring the tasty prey.
|
||||
// The purpose of this method is to avoid duplicate code, and ensure that all necessary
|
||||
// steps are taken.
|
||||
/datum/belly/proc/nom_mob(var/mob/prey, var/mob/user)
|
||||
// if (prey.buckled)
|
||||
// prey.buckled.unbuckle_mob()
|
||||
|
||||
// Super super messy. prey.forceMove.owner doesn't work if there's no prey.
|
||||
prey.loc = user
|
||||
internal_contents |= prey
|
||||
|
||||
if(inside_flavor)
|
||||
prey << "<span class='notice'><B>[inside_flavor]</B></span>"
|
||||
|
||||
// Get the line that should show up in Examine message if the owner of this belly
|
||||
// is examined. By making this a proc, we not only take advantage of polymorphism,
|
||||
// but can easily make the message vary based on how many people are inside, etc.
|
||||
// Returns a string which shoul be appended to the Examine output.
|
||||
/datum/belly/proc/get_examine_msg()
|
||||
if(internal_contents.len && examine_messages.len)
|
||||
var/formatted_message
|
||||
var/raw_message = pick(examine_messages)
|
||||
|
||||
formatted_message = replacetext(raw_message,"%belly",lowertext(name))
|
||||
|
||||
return("<span class='warning'>[formatted_message]</span><BR>")
|
||||
|
||||
// The next function gets the messages set on the belly, in human-readable format.
|
||||
// This is useful in customization boxes and such. The delimiter right now is \n\n so
|
||||
// in message boxes, this looks nice and is easily delimited.
|
||||
/datum/belly/proc/get_messages(var/type, var/delim = "\n\n")
|
||||
ASSERT(type == "smo" || type == "smi" || type == "dmo" || type == "dmp" || type == "em")
|
||||
var/list/raw_messages
|
||||
|
||||
switch(type)
|
||||
if("smo")
|
||||
raw_messages = struggle_messages_outside
|
||||
if("smi")
|
||||
raw_messages = struggle_messages_inside
|
||||
if("dmo")
|
||||
raw_messages = digest_messages_owner
|
||||
if("dmp")
|
||||
raw_messages = digest_messages_prey
|
||||
if("em")
|
||||
raw_messages = examine_messages
|
||||
|
||||
var/messages = list2text(raw_messages,delim)
|
||||
return messages
|
||||
|
||||
// The next function sets the messages on the belly, from human-readable var
|
||||
// replacement strings and linebreaks as delimiters (two \n\n by default).
|
||||
// They also sanitize the messages.
|
||||
/datum/belly/proc/set_messages(var/raw_text, var/type, var/delim = "\n\n")
|
||||
ASSERT(type == "smo" || type == "smi" || type == "dmo" || type == "dmp" || type == "em")
|
||||
|
||||
var/list/raw_list = text2list(html_encode(raw_text),delim)
|
||||
if(raw_list.len > 10)
|
||||
raw_list.Cut(11)
|
||||
log_attack("[owner] tried to set [name] with 11+ messages")
|
||||
|
||||
for(var/i = 1, i <= raw_list.len, i++)
|
||||
if(length(raw_list[i]) > 160 || length(raw_list[i]) < 10) //160 is fudged value due to htmlencoding increasing the size
|
||||
raw_list.Cut(i,i)
|
||||
log_attack("[owner] tried to set [name] with >121 or <10 char message")
|
||||
else
|
||||
raw_list[i] = readd_quotes(raw_list[i])
|
||||
//Also fix % sign for var replacement
|
||||
raw_list[i] = replacetext(raw_list[i],"%","%")
|
||||
|
||||
ASSERT(raw_list.len <= 10) //Sanity
|
||||
|
||||
switch(type)
|
||||
if("smo")
|
||||
struggle_messages_outside = raw_list
|
||||
if("smi")
|
||||
struggle_messages_inside = raw_list
|
||||
if("dmo")
|
||||
digest_messages_owner = raw_list
|
||||
if("dmp")
|
||||
digest_messages_prey = raw_list
|
||||
if("em")
|
||||
examine_messages = raw_list
|
||||
|
||||
return
|
||||
|
||||
// Handle the death of a mob via digestion.
|
||||
// Called from the process_Life() methods of bellies that digest prey.
|
||||
// Default implementation calls M.death() and removes from internal contents.
|
||||
// Indigestable items are removed, and M is deleted.
|
||||
/datum/belly/proc/digestion_death(var/mob/living/M, var/mob/prey, var/mob/pred)
|
||||
is_full = 1
|
||||
M.death(1)
|
||||
internal_contents -= M
|
||||
|
||||
// If digested prey is also a pred... anyone inside their bellies gets moved up.
|
||||
if (is_vore_predator(M))
|
||||
for (var/bellytype in M.vore_organs)
|
||||
var/datum/belly/belly = M.vore_organs[bellytype]
|
||||
for (var/obj/SubPrey in belly.internal_contents)
|
||||
SubPrey.forceMove(owner)
|
||||
internal_contents += SubPrey
|
||||
SubPrey << "As [M] melts away around you, you find yourself in [owner]'s [name]"
|
||||
|
||||
//Drop all items into the belly.
|
||||
if (config.items_survive_digestion)
|
||||
for (var/obj/item/W in M)
|
||||
_handle_digested_item(W)
|
||||
|
||||
//Reagent transfer
|
||||
if(M.reagents && istype(M.reagents,/datum/reagents))
|
||||
var/datum/reagents/RL = M.reagents
|
||||
RL.trans_to(owner,RL.total_volume*0.5)
|
||||
|
||||
// Delete the digested mob
|
||||
message_admins("[key_name(pred)] digested [key_name(prey)].")
|
||||
log_attack("[key_name(pred)] digested [key_name(prey)].")
|
||||
qdel(M)
|
||||
|
||||
// Recursive method - To recursively scan thru someone's inventory for digestable/indigestable.
|
||||
/datum/belly/proc/_handle_digested_item(var/obj/item/W)
|
||||
W.forceMove(owner)
|
||||
internal_contents += W
|
||||
|
||||
/datum/belly/proc/_is_digestable(var/obj/item/I)
|
||||
return 1
|
||||
|
||||
//Handle a mob struggling
|
||||
// Called from /mob/living/carbon/relaymove()
|
||||
/datum/belly/proc/relay_resist(var/mob/living/R)
|
||||
var/struggle_outer_message = pick(struggle_messages_outside)
|
||||
var/struggle_user_message = pick(struggle_messages_inside)
|
||||
if (!(R in internal_contents))
|
||||
return // User is not in this belly, or struggle too soon.
|
||||
|
||||
// R.setClickCooldown(50)
|
||||
|
||||
if(owner.stat || escapable) //If owner is stat (dead, KO) we can actually escape, or if belly is set to escapable (non-default)
|
||||
R << "<span class='warning'>You attempt to climb out of \the [name]. (This will take around [escapetime/10] seconds.)</span>"
|
||||
owner << "<span class='warning'>Someone is attempting to climb out of your [name]!</span>"
|
||||
|
||||
if(do_after(R, escapetime, owner))
|
||||
if((owner.stat || escapable) && (R in internal_contents)) //Can still escape?
|
||||
release_specific_contents(R)
|
||||
return
|
||||
else if(!(R in internal_contents)) //Aren't even in the belly. Quietly fail.
|
||||
return
|
||||
else //Belly became inescapable or mob revived
|
||||
R << "<span class='warning'>Your attempt to escape [name] has failed!</span>"
|
||||
owner << "<span class='notice'>The attempt to escape from your [name] has failed!</span>"
|
||||
return
|
||||
return
|
||||
|
||||
struggle_outer_message = replacetext(struggle_outer_message,"%pred",owner)
|
||||
struggle_outer_message = replacetext(struggle_outer_message,"%prey",R)
|
||||
struggle_outer_message = replacetext(struggle_outer_message,"%belly",lowertext(name))
|
||||
|
||||
struggle_user_message = replacetext(struggle_user_message,"%pred",owner)
|
||||
struggle_user_message = replacetext(struggle_user_message,"%prey",R)
|
||||
struggle_user_message = replacetext(struggle_user_message,"%belly",lowertext(name))
|
||||
|
||||
struggle_outer_message = "<span class='alert'>" + struggle_outer_message + "</span>"
|
||||
struggle_user_message = "<span class='alert'>" + struggle_user_message + "</span>"
|
||||
|
||||
for(var/mob/M in hearers(4, owner))
|
||||
M.show_message(struggle_outer_message, 2) // hearable
|
||||
R << struggle_user_message
|
||||
var/strpick = pick(struggle_sounds)
|
||||
var/strsound = struggle_sounds[strpick]
|
||||
playsound(R.loc, strsound, 50, 1)
|
||||
|
||||
/datum/belly/proc/relaymove(var/mob/living/R)
|
||||
var/struggle_outer_message = pick(struggle_messages_outside)
|
||||
var/struggle_user_message = pick(struggle_messages_inside)
|
||||
var/strpick = pick(struggle_sounds)
|
||||
var/strsound = struggle_sounds[strpick]
|
||||
|
||||
if(!(R in internal_contents) || recent_struggle)
|
||||
return // User is not in this belly, or struggle too soon.
|
||||
|
||||
if(R in internal_contents && R.a_intent == "help")
|
||||
recent_struggle = 1
|
||||
spawn(30)
|
||||
recent_struggle = 0
|
||||
|
||||
struggle_outer_message = replacetext(struggle_outer_message,"%pred",owner)
|
||||
struggle_outer_message = replacetext(struggle_outer_message,"%prey",R)
|
||||
struggle_outer_message = replacetext(struggle_outer_message,"%belly",lowertext(name))
|
||||
|
||||
struggle_user_message = replacetext(struggle_user_message,"%pred",owner)
|
||||
struggle_user_message = replacetext(struggle_user_message,"%prey",R)
|
||||
struggle_user_message = replacetext(struggle_user_message,"%belly",lowertext(name))
|
||||
|
||||
struggle_outer_message = "<span class='alert'>" + struggle_outer_message + "</span>"
|
||||
struggle_user_message = "<span class='alert'>" + struggle_user_message + "</span>"
|
||||
|
||||
for(var/mob/M in hearers(4, owner))
|
||||
M.show_message(struggle_outer_message, 2) // hearable
|
||||
R << struggle_user_message
|
||||
|
||||
playsound(R.loc, strsound, 50, 1)
|
||||
|
||||
else if(!(R in internal_contents && R.a_intent == "help"))
|
||||
integrity -= 15
|
||||
recent_struggle = 1
|
||||
spawn(15) // there's a want to get out, so faster
|
||||
recent_struggle = 0
|
||||
|
||||
struggle_outer_message = replacetext(struggle_outer_message,"%pred",owner)
|
||||
struggle_outer_message = replacetext(struggle_outer_message,"%prey",R)
|
||||
struggle_outer_message = replacetext(struggle_outer_message,"%belly",lowertext(name))
|
||||
|
||||
struggle_user_message = replacetext(struggle_user_message,"%pred",owner)
|
||||
struggle_user_message = replacetext(struggle_user_message,"%prey",R)
|
||||
struggle_user_message = replacetext(struggle_user_message,"%belly",lowertext(name))
|
||||
|
||||
struggle_outer_message = "<span class='alert'>" + struggle_outer_message + "</span>"
|
||||
struggle_user_message = "<span class='alert'>" + struggle_user_message + "</span>"
|
||||
|
||||
for(var/mob/M in hearers(4, owner))
|
||||
M.show_message(struggle_outer_message, 2) // hearable
|
||||
R << struggle_user_message
|
||||
playsound(R.loc, strsound, 50, 1)
|
||||
|
||||
if(integrity<=0)
|
||||
release_specific_contents(R)
|
||||
integrity=0
|
||||
owner.Stun(rand(2,4))
|
||||
playsound(R.loc, 'sound/vore/StomachTransfer.ogg', 50, 1)
|
||||
|
||||
// Belly copies and then returns the copy
|
||||
// Needs to be updated for any var changes
|
||||
/datum/belly/proc/copy(mob/new_owner)
|
||||
var/datum/belly/dupe = new /datum/belly(new_owner)
|
||||
|
||||
//// Non-object variables
|
||||
dupe.name = name
|
||||
dupe.inside_flavor = inside_flavor
|
||||
dupe.vore_sound = vore_sound
|
||||
dupe.vore_verb = vore_verb
|
||||
dupe.human_prey_swallow_time = human_prey_swallow_time
|
||||
dupe.nonhuman_prey_swallow_time = nonhuman_prey_swallow_time
|
||||
dupe.emoteTime = emoteTime
|
||||
dupe.digest_brute = digest_brute
|
||||
dupe.digest_burn = digest_burn
|
||||
dupe.digest_tickrate = digest_tickrate
|
||||
dupe.immutable = immutable
|
||||
dupe.escapable = escapable
|
||||
dupe.escapetime = escapetime
|
||||
|
||||
//// Object-holding variables
|
||||
//struggle_messages_outside - strings
|
||||
dupe.struggle_messages_outside.Cut()
|
||||
for(var/I in struggle_messages_outside)
|
||||
dupe.struggle_messages_outside += I
|
||||
|
||||
//struggle_messages_inside - strings
|
||||
dupe.struggle_messages_inside.Cut()
|
||||
for(var/I in struggle_messages_inside)
|
||||
dupe.struggle_messages_inside += I
|
||||
|
||||
//digest_messages_owner - strings
|
||||
dupe.digest_messages_owner.Cut()
|
||||
for(var/I in digest_messages_owner)
|
||||
dupe.digest_messages_owner += I
|
||||
|
||||
//digest_messages_prey - strings
|
||||
dupe.digest_messages_prey.Cut()
|
||||
for(var/I in digest_messages_prey)
|
||||
dupe.digest_messages_prey += I
|
||||
|
||||
//examine_messages - strings
|
||||
dupe.examine_messages.Cut()
|
||||
for(var/I in examine_messages)
|
||||
dupe.examine_messages += I
|
||||
|
||||
//emote_lists - index: digest mode, key: list of strings
|
||||
dupe.emote_lists.Cut()
|
||||
for(var/K in emote_lists)
|
||||
dupe.emote_lists[K] = list()
|
||||
for(var/I in emote_lists[K])
|
||||
dupe.emote_lists[K] += I
|
||||
|
||||
return dupe
|
||||
@@ -1,127 +0,0 @@
|
||||
// Process the predator's effects upon the contents of its belly (i.e digestion/transformation etc)
|
||||
// Called from /mob/living/Life() proc.
|
||||
/datum/belly/proc/process_Life()
|
||||
|
||||
/////////////////////////// Auto-Emotes ///////////////////////////
|
||||
if((digest_mode in emote_lists) && !emotePend)
|
||||
emotePend = 1
|
||||
|
||||
spawn(emoteTime)
|
||||
var/list/EL = emote_lists[digest_mode]
|
||||
for(var/mob/living/M in internal_contents)
|
||||
M << "<span class='notice'>[pick(EL)]</span>"
|
||||
src.emotePend = 0
|
||||
|
||||
//////////////////////////////Integrity regeneration ////////////////
|
||||
integrity=min(integrity+8,100)
|
||||
|
||||
///////////////////////////// DM_HOLD /////////////////////////////
|
||||
if(digest_mode == DM_HOLD)
|
||||
return //Pretty boring, huh
|
||||
|
||||
//////////////////////////// DM_DIGEST ////////////////////////////
|
||||
if(digest_mode == DM_DIGEST)
|
||||
|
||||
if(prob(50))
|
||||
var/churnsound = pick(digestion_sounds)
|
||||
for(var/mob/hearer in range(1,owner))
|
||||
hearer << sound(churnsound,volume=60)
|
||||
|
||||
for (var/mob/living/M in internal_contents)
|
||||
//Pref protection!
|
||||
if (!M.digestable)
|
||||
continue
|
||||
|
||||
//Person just died in guts!
|
||||
if(M.stat == DEAD && M.getFireLoss() >= 150)
|
||||
var/digest_alert_owner = pick(digest_messages_owner)
|
||||
var/digest_alert_prey = pick(digest_messages_prey)
|
||||
|
||||
//Replace placeholder vars
|
||||
digest_alert_owner = replacetext(digest_alert_owner,"%pred",owner)
|
||||
digest_alert_owner = replacetext(digest_alert_owner,"%prey",M)
|
||||
digest_alert_owner = replacetext(digest_alert_owner,"%belly",lowertext(name))
|
||||
|
||||
digest_alert_prey = replacetext(digest_alert_prey,"%pred",owner)
|
||||
digest_alert_prey = replacetext(digest_alert_prey,"%prey",M)
|
||||
digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name))
|
||||
|
||||
//Send messages
|
||||
owner << "<span class='notice'>" + digest_alert_owner + "</span>"
|
||||
M << "<span class='notice'>" + digest_alert_prey + "</span>"
|
||||
|
||||
owner.nutrition += 400 // so eating dead mobs gives you *something*.
|
||||
var/deathsound = pick(death_sounds)
|
||||
for(var/mob/hearer in range(1,owner))
|
||||
hearer << deathsound
|
||||
digestion_death(M)
|
||||
continue
|
||||
|
||||
// Deal digestion damage (and feed the pred)
|
||||
if(!(M.status_flags & GODMODE))
|
||||
M.adjustBruteLoss(1)
|
||||
M.adjustFireLoss(1)
|
||||
owner.nutrition += 10
|
||||
return
|
||||
|
||||
//////////////////////////// DM_DIGESTF ////////////////////////////
|
||||
if(digest_mode == DM_DIGESTF)
|
||||
|
||||
if(prob(50))
|
||||
var/churnsound = pick(digestion_sounds)
|
||||
for(var/mob/hearer in range(1,owner))
|
||||
hearer << sound(churnsound,volume=80)
|
||||
|
||||
for (var/mob/living/M in internal_contents)
|
||||
//Pref protection!
|
||||
if (!M.digestable)
|
||||
continue
|
||||
|
||||
//Person just died in guts!
|
||||
if(M.stat == DEAD && M.getFireLoss() >= 150)
|
||||
var/digest_alert_owner = pick(digest_messages_owner)
|
||||
var/digest_alert_prey = pick(digest_messages_prey)
|
||||
|
||||
//Replace placeholder vars
|
||||
digest_alert_owner = replacetext(digest_alert_owner,"%pred",owner)
|
||||
digest_alert_owner = replacetext(digest_alert_owner,"%prey",M)
|
||||
digest_alert_owner = replacetext(digest_alert_owner,"%belly",lowertext(name))
|
||||
|
||||
digest_alert_prey = replacetext(digest_alert_prey,"%pred",owner)
|
||||
digest_alert_prey = replacetext(digest_alert_prey,"%prey",M)
|
||||
digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name))
|
||||
|
||||
//Send messages
|
||||
owner << "<span class='notice'>" + digest_alert_owner + "</span>"
|
||||
M << "<span class='notice'>" + digest_alert_prey + "</span>"
|
||||
|
||||
owner.nutrition += 400 // so eating dead mobs gives you *something*.
|
||||
var/deathsound = pick(death_sounds)
|
||||
for(var/mob/hearer in range(1,owner))
|
||||
hearer << deathsound
|
||||
digestion_death(M)
|
||||
continue
|
||||
|
||||
// Deal digestion damage (and feed the pred)
|
||||
if(!(M.status_flags & GODMODE))
|
||||
M.adjustBruteLoss(2)
|
||||
M.adjustFireLoss(3)
|
||||
owner.nutrition += 10
|
||||
return
|
||||
|
||||
///////////////////////////// DM_HEAL /////////////////////////////
|
||||
if(digest_mode == DM_HEAL)
|
||||
if(prob(50)) //Wet heals!
|
||||
var/healsound = pick(digestion_sounds)
|
||||
for(var/mob/hearer in range(1,owner))
|
||||
hearer << sound(healsound,volume=80)
|
||||
|
||||
for (var/mob/living/M in internal_contents)
|
||||
if(M.stat != DEAD)
|
||||
if(owner.nutrition > 90 && (M.health < M.maxHealth))
|
||||
M.adjustBruteLoss(-2)
|
||||
M.adjustFireLoss(-2)
|
||||
owner.nutrition -= 2
|
||||
if(M.nutrition <= 400)
|
||||
M.nutrition += 1
|
||||
return
|
||||
@@ -1,341 +0,0 @@
|
||||
///////////////////// Mob Living /////////////////////
|
||||
/mob/living
|
||||
var/digestable = 1 // Can the mob be digested inside a belly?
|
||||
var/datum/belly/vore_selected // Default to no vore capability.
|
||||
var/list/vore_organs = list() // List of vore containers inside a mob
|
||||
var/recent_struggle = 0
|
||||
//
|
||||
// Hook for generic creation of stuff on new creatures
|
||||
//
|
||||
/hook/living_new/proc/vore_setup(mob/living/M)
|
||||
M.verbs += /mob/living/proc/insidePanel
|
||||
M.verbs += /mob/living/proc/escapeOOC
|
||||
|
||||
//Tries to load prefs if a client is present otherwise gives freebie stomach
|
||||
if(!M.vore_organs || !M.vore_organs.len)
|
||||
spawn(20) //Wait a couple of seconds to make sure copy_to or whatever has gone
|
||||
if(!M) return
|
||||
|
||||
/* if(M.client && M.client.prefs)
|
||||
if(!M.load_vore_preferences)
|
||||
M << "<span class='warning'>ERROR: You seem to have saved prefs, but they couldn't be loaded.</span>"
|
||||
return 0
|
||||
if(M.vore_organs && M.vore_organs.len)
|
||||
M.vore_selected = M.vore_organs[1] */
|
||||
|
||||
if(!M.vore_organs || !M.vore_organs.len)
|
||||
if(!M.vore_organs)
|
||||
M.vore_organs = list()
|
||||
var/datum/belly/B = new /datum/belly(M)
|
||||
B.immutable = 1
|
||||
B.name = "Stomach"
|
||||
B.inside_flavor = "It appears to be rather warm and wet. Makes sense, considering it's inside \the [M.name]."
|
||||
M.vore_organs[B.name] = B
|
||||
M.vore_selected = B.name
|
||||
|
||||
//Simple_animal gets emotes. move this to that hook instead?
|
||||
if(istype(src,/mob/living/simple_animal))
|
||||
B.emote_lists[DM_HOLD] = list(
|
||||
"The insides knead at you gently for a moment.",
|
||||
"The guts glorp wetly around you as some air shifts.",
|
||||
"Your predator takes a deep breath and sighs, shifting you somewhat.",
|
||||
"The stomach squeezes you tight for a moment, then relaxes.",
|
||||
"During a moment of quiet, breathing becomes the most audible thing.",
|
||||
"The warm slickness surrounds and kneads on you.")
|
||||
|
||||
B.emote_lists[DM_DIGEST] = list(
|
||||
"The caustic acids eat away at your form.",
|
||||
"The acrid air burns at your lungs.",
|
||||
"Without a thought for you, the stomach grinds inwards painfully.",
|
||||
"The guts treat you like food, squeezing to press more acids against you.",
|
||||
"The onslaught against your body doesn't seem to be letting up; you're food now.",
|
||||
"The insides work on you like they would any other food.")
|
||||
|
||||
//Return 1 to hook-caller
|
||||
return 1
|
||||
|
||||
//
|
||||
// Handle being clicked, perhaps with something to devour
|
||||
//
|
||||
|
||||
// Refactored to use centralized vore code system - Leshana
|
||||
|
||||
// Critical adjustments due to TG grab changes - Poojawa
|
||||
|
||||
/mob/living/proc/vore_attack(var/mob/living/user, var/mob/living/prey)
|
||||
if(!user)
|
||||
return
|
||||
if(!prey)
|
||||
return
|
||||
if(prey==user)
|
||||
return
|
||||
if(prey == src && user.zone_selected == "mouth") //you click your target
|
||||
if(!is_vore_predator(prey))
|
||||
user << "<span class='notice'>They aren't voracious enough.</span>"
|
||||
feed_self_to_grabbed(user)
|
||||
|
||||
if( user == src ) //you click yourself
|
||||
if(!is_vore_predator(src))
|
||||
user << "<span class='notice'>You aren't voracious enough.</span>"
|
||||
feed_grabbed_to_self(prey, user)
|
||||
|
||||
else // click someone other than you/prey
|
||||
if(!is_vore_predator(src))
|
||||
user << "<span class='notice'>They aren't voracious enough.</span>"
|
||||
return
|
||||
feed_grabbed_to_other(user)
|
||||
//
|
||||
// Eating procs depending on who clicked what
|
||||
//
|
||||
/mob/living/proc/feed_grabbed_to_self(var/mob/living/user, var/mob/living/prey)
|
||||
var/belly = user.vore_selected
|
||||
return perform_the_nom(prey, user, prey, belly)
|
||||
/*
|
||||
/mob/living/proc/eat_held_mob(var/mob/living/user, var/mob/living/prey, var/mob/living/pred)
|
||||
var/belly
|
||||
if(user != pred)
|
||||
belly = input("Choose Belly") in pred.vore_organs
|
||||
else
|
||||
belly = pred.vore_selected
|
||||
return perform_the_nom(user, prey, pred, belly)*/
|
||||
|
||||
/mob/living/proc/feed_self_to_grabbed(var/mob/living/user, var/mob/living/pred)
|
||||
var/belly = input("Choose Belly") in pred.vore_organs
|
||||
return perform_the_nom(user, user, pred, belly)
|
||||
|
||||
/mob/living/proc/feed_grabbed_to_other(var/mob/living/user, var/mob/living/prey, var/mob/living/pred)
|
||||
return//disabled until further notice
|
||||
var/belly = input("Choose Belly") in pred.vore_organs
|
||||
return perform_the_nom(user, prey, pred, belly)
|
||||
|
||||
//
|
||||
// Master vore proc that actually does vore procedures
|
||||
//
|
||||
|
||||
/mob/living/proc/perform_the_nom(var/mob/living/user, var/mob/living/prey, var/mob/living/pred, var/belly, swallow_time = 100)
|
||||
//Sanity
|
||||
if(!user || !prey || !pred || !belly || !(belly in pred.vore_organs))
|
||||
log_attack("[user] attempted to feed [prey] to [pred], via [belly] but it went wrong.")
|
||||
return
|
||||
// The belly selected at the time of noms
|
||||
var/datum/belly/belly_target = pred.vore_organs[belly]
|
||||
var/attempt_msg = "ERROR: Vore message couldn't be created. Notify a dev. (at)"
|
||||
var/success_msg = "ERROR: Vore message couldn't be created. Notify a dev. (sc)"
|
||||
|
||||
// Prepare messages
|
||||
if(user == pred) //Feeding someone to yourself
|
||||
attempt_msg = text("<span class='warning'>[] is attemping to [] [] into their []!</span>",pred,lowertext(belly_target.vore_verb),prey,lowertext(belly_target.name))
|
||||
success_msg = text("<span class='warning'>[] manages to [] [] into their []!</span>",pred,lowertext(belly_target.vore_verb),prey,lowertext(belly_target.name))
|
||||
else //Feeding someone to another person
|
||||
attempt_msg = text("<span class='warning'>[] is attempting to make [] [] [] into their []!</span>",user,pred,lowertext(belly_target.vore_verb),prey,lowertext(belly_target.name))
|
||||
success_msg = text("<span class='warning'>[] manages to make [] [] [] into their []!</span>",user,pred,lowertext(belly_target.vore_verb),prey,lowertext(belly_target.name))
|
||||
|
||||
// Announce that we start the attempt!
|
||||
user.visible_message(attempt_msg)
|
||||
|
||||
// Now give the prey time to escape... return if they did
|
||||
|
||||
if(!do_mob(src, user, swallow_time))
|
||||
return 0 // Prey escpaed (or user disabled) before timer expired.
|
||||
|
||||
// If we got this far, nom successful! Announce it!
|
||||
user.visible_message(success_msg)
|
||||
playsound(user, belly_target.vore_sound, 100, 1)
|
||||
|
||||
// Actually shove prey into the belly.
|
||||
belly_target.nom_mob(prey, user)
|
||||
// user.update_icons()
|
||||
stop_pulling()
|
||||
|
||||
// Inform Admins
|
||||
if (pred == user)
|
||||
message_admins("[key_name(pred)] ate [key_name(prey)]. ([pred ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[pred.x];Y=[pred.y];Z=[pred.z]'>JMP</a>" : "null"])")
|
||||
log_attack("[key_name(pred)] ate [key_name(prey)]")
|
||||
else if (prey == !client && stat != DEAD)
|
||||
message_admins("[key_name(pred)] ate [key_name(prey)] (braindead) ([pred ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[pred.x];Y=[pred.y];Z=[pred.z]'>JMP</a>" : "null"])")
|
||||
log_attack("[key_name(pred)] ate [key_name(prey)] (braindead)")
|
||||
else
|
||||
message_admins("[key_name(user)] forced [key_name(pred)] to eat [key_name(prey)]. ([pred ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[pred.x];Y=[pred.y];Z=[pred.z]'>JMP</a>" : "null"])")
|
||||
log_attack("[key_name(user)] forced [key_name(pred)] to eat [key_name(prey)].")
|
||||
return 1
|
||||
|
||||
//
|
||||
//End vore code.
|
||||
/*
|
||||
//Handle case: /obj/item/weapon/holder
|
||||
if(/obj/item/weapon/holder/micro)
|
||||
var/obj/item/weapon/holder/H = I
|
||||
|
||||
if(!isliving(user)) return 0 // Return 0 to continue upper procs
|
||||
var/mob/living/attacker = user // Typecast to living
|
||||
|
||||
if (is_vore_predator(src))
|
||||
for (var/mob/living/M in H.contents)
|
||||
attacker.eat_held_mob(attacker, M, src)
|
||||
return 1 //Return 1 to exit upper procs
|
||||
else
|
||||
log_attack("[attacker] attempted to feed [H.contents] to [src] ([src.type]) but it failed.")
|
||||
|
||||
// I just can't imagine this not being complained about
|
||||
//Handle case: /obj/item/device/radio/beacon
|
||||
if(/obj/item/device/radio/beacon)
|
||||
var/confirm = alert(user, "[src == user ? "Eat the beacon?" : "Feed the beacon to [src]?"]", "Confirmation", "Yes!", "Cancel")
|
||||
if(confirm == "Yes!")
|
||||
var/bellychoice = input("Which belly?","Select A Belly") in src.vore_organs
|
||||
var/datum/belly/B = src.vore_organs[bellychoice]
|
||||
src.visible_message("<span class='warning'>[user] is trying to stuff a beacon into [src]'s [bellychoice]!</span>","<span class='warning'>[user] is trying to stuff a beacon into you!</span>")
|
||||
if(do_after(user,30,src))
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
B.internal_contents += I
|
||||
src.visible_message("<span class='warning'>[src] is fed the beacon!</span>","You're fed the beacon!")
|
||||
playsound(src, B.vore_sound, 100, 1)
|
||||
return 1
|
||||
else
|
||||
return 1 //You don't get to hit someone 'later'
|
||||
|
||||
return 0
|
||||
*/
|
||||
//
|
||||
// Custom resist catches for /mob/living
|
||||
//
|
||||
/mob/living/proc/vore_process_resist()
|
||||
|
||||
//Are we resisting from inside a belly?
|
||||
var/datum/belly/B = check_belly(src)
|
||||
if(B)
|
||||
spawn() B.relay_resist(src)
|
||||
return TRUE //resist() on living does this TRUE thing.
|
||||
|
||||
//Other overridden resists go here
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
//
|
||||
// Proc for updating vore organs and digestion/healing/absorbing
|
||||
//
|
||||
/mob/living/proc/handle_internal_contents()
|
||||
if(SSair.times_fired%3 != 1)
|
||||
return //The accursed timer
|
||||
|
||||
for (var/I in vore_organs)
|
||||
var/datum/belly/B = vore_organs[I]
|
||||
if(B.internal_contents.len)
|
||||
B.process_Life() //AKA 'do bellymodes_vr.dm'
|
||||
|
||||
if(SSair.times_fired%3 != 1) return //Occasionally do supercleanups.
|
||||
for (var/I in vore_organs)
|
||||
var/datum/belly/B = vore_organs[I]
|
||||
if(B.internal_contents.len)
|
||||
for(var/atom/movable/M in B.internal_contents)
|
||||
if(M.loc != src)
|
||||
B.internal_contents -= M
|
||||
log_attack("Had to remove [M] from belly [B] in [src]")
|
||||
/*
|
||||
//
|
||||
// Verb for saving vore preferences to save file
|
||||
//
|
||||
/mob/living/proc/save_vore_prefs()
|
||||
if(!(client || client.prefs_vr))
|
||||
return 0
|
||||
if(!copy_to_prefs_vr())
|
||||
return 0
|
||||
if(!client.prefs_vr.save_vore())
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/proc/apply_vore_prefs()
|
||||
if(!(client || client.prefs_vr))
|
||||
return 0
|
||||
if(!client.prefs_vr.load_vore())
|
||||
return 0
|
||||
if(!copy_from_prefs_vr())
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/proc/copy_to_prefs_vr()
|
||||
if(!client || !client.prefs_vr)
|
||||
src << "<span class='warning'>You attempted to save your vore prefs but somehow you're in this character without a client.prefs_vr variable. Tell a dev.</span>"
|
||||
return 0
|
||||
|
||||
var/datum/vore_preferences/P = client.prefs_vr
|
||||
|
||||
P.digestable = src.digestable
|
||||
P.belly_prefs = src.vore_organs
|
||||
|
||||
return 1
|
||||
|
||||
//
|
||||
// Proc for applying vore preferences, given bellies
|
||||
//
|
||||
/mob/living/proc/copy_from_prefs_vr()
|
||||
if(!client || !client.prefs_vr)
|
||||
src << "<span class='warning'>You attempted to apply your vore prefs but somehow you're in this character without a client.prefs_vr variable. Tell a dev.</span>"
|
||||
return 0
|
||||
|
||||
var/datum/vore_preferences/P = client.prefs_vr
|
||||
|
||||
src.digestable = P.digestable
|
||||
src.vore_organs = list()
|
||||
|
||||
for(var/I in P.belly_prefs)
|
||||
var/datum/belly/Bp = P.belly_prefs[I]
|
||||
src.vore_organs[Bp.name] = Bp.copy(src)
|
||||
|
||||
return 1
|
||||
*/
|
||||
//
|
||||
// Verb for saving vore preferences to save file
|
||||
//
|
||||
/mob/living/proc/save_vore_prefs()
|
||||
set name = "Save Vore Prefs"
|
||||
set category = "Vore"
|
||||
|
||||
var/result = 0
|
||||
|
||||
if(client.prefs)
|
||||
result = client.prefs.save_vore_preferences()
|
||||
else
|
||||
src << "<span class='warning'>You attempted to save your vore prefs but somehow you're in this character without a client.prefs variable. Tell a dev.</span>"
|
||||
log_admin("[src] tried to save vore prefs but lacks a client.prefs var.")
|
||||
|
||||
return result
|
||||
|
||||
//
|
||||
// Proc for applying vore preferences, given bellies
|
||||
//
|
||||
/mob/living/proc/apply_vore_prefs(var/list/bellies)
|
||||
if(!bellies || bellies.len == 0)
|
||||
log_admin("Tried to apply bellies to [src] and failed.")
|
||||
|
||||
|
||||
//
|
||||
// OOC Escape code for pref-breaking or AFK preds
|
||||
//
|
||||
/mob/living/proc/escapeOOC()
|
||||
set name = "Animal Escape"
|
||||
set category = "Vore"
|
||||
|
||||
//You're in an animal!
|
||||
if(istype(src.loc,/mob/living/simple_animal))
|
||||
var/mob/living/simple_animal/pred = src.loc
|
||||
var/confirm = alert(src, "You're in a mob. Use this as a trick to get out of hostile animals. If you are in more than one pred, use this more than once.", "Confirmation", "Okay", "Cancel")
|
||||
if(confirm == "Okay")
|
||||
for(var/I in pred.vore_organs)
|
||||
var/datum/belly/B = pred.vore_organs[I]
|
||||
B.release_specific_contents(src)
|
||||
|
||||
for(var/mob/living/simple_animal/SA in range(10))
|
||||
SA.prey_excludes += src
|
||||
spawn(18000)
|
||||
if(src && SA)
|
||||
SA.prey_excludes -= src
|
||||
|
||||
pred.update_icons()
|
||||
|
||||
else
|
||||
src << "<span class='alert'>You aren't inside anything, you clod.</span>"
|
||||
@@ -1,39 +0,0 @@
|
||||
///////////////////// Simple Animal /////////////////////
|
||||
/mob/living/simple_animal
|
||||
var/isPredator = 0 //Are they capable of performing and pre-defined vore actions for their species?
|
||||
var/swallowTime = 30 //How long it takes to eat its prey in 1/10 of a second. The default is 3 seconds.
|
||||
var/list/prey_excludes = list() //For excluding people from being eaten.
|
||||
|
||||
//
|
||||
// Simple nom proc for if you get ckey'd into a simple_animal mob! Avoids grabs.
|
||||
/*
|
||||
/mob/living/proc/animal_nom(var/mob/living/T in oview(1))
|
||||
set name = "Animal Nom"
|
||||
set category = "Vore"
|
||||
set desc = "Since you can't grab, you get a verb!"
|
||||
|
||||
feed_grabbed_to_self(src,T)
|
||||
*/
|
||||
//
|
||||
// Simple proc for animals to have their digestion toggled on/off externally
|
||||
//
|
||||
/mob/living/simple_animal/verb/toggle_digestion()
|
||||
set name = "Toggle Animal's Digestion"
|
||||
set desc = "Enables digestion on this mob for 20 minutes."
|
||||
set category = "Vore"
|
||||
set src in oview(1)
|
||||
|
||||
var/datum/belly/B = vore_organs[vore_selected]
|
||||
if(faction != usr.faction)
|
||||
usr << "<span class='warning'>This predator isn't friendly, and doesn't give a shit about your opinions of it digesting you.</span>"
|
||||
return
|
||||
if(B.digest_mode == "Hold")
|
||||
var/confirm = alert(usr, "Enabling digestion on [name] will cause it to digest all stomach contents. Using this to break OOC prefs is against the rules. Digestion will disable itself after 20 minutes.", "Enabling [name]'s Digestion", "Enable", "Cancel")
|
||||
if(confirm == "Enable")
|
||||
B.digest_mode = "Digest"
|
||||
spawn(12000) //12000=20 minutes
|
||||
if(src) B.digest_mode = "Hold"
|
||||
else
|
||||
var/confirm = alert(usr, "This mob is currently set to digest all stomach contents. Do you want to disable this?", "Disabling [name]'s Digestion", "Disable", "Cancel")
|
||||
if(confirm == "Disable")
|
||||
B.digest_mode = "Hold"
|
||||
@@ -1,123 +0,0 @@
|
||||
|
||||
/*
|
||||
VVVVVVVV VVVVVVVV OOOOOOOOO RRRRRRRRRRRRRRRRR EEEEEEEEEEEEEEEEEEEEEE
|
||||
V::::::V V::::::V OO:::::::::OO R::::::::::::::::R E::::::::::::::::::::E
|
||||
V::::::V V::::::V OO:::::::::::::OO R::::::RRRRRR:::::R E::::::::::::::::::::E
|
||||
V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEEEEE::::E
|
||||
V:::::V V:::::V O::::::O O::::::O R::::R R:::::R E:::::E EEEEEE
|
||||
V:::::V V:::::V O:::::O O:::::O R::::R R:::::R E:::::E
|
||||
V:::::V V:::::V O:::::O O:::::O R::::RRRRRR:::::R E::::::EEEEEEEEEE
|
||||
V:::::V V:::::V O:::::O O:::::O R:::::::::::::RR E:::::::::::::::E
|
||||
V:::::V V:::::V O:::::O O:::::O R::::RRRRRR:::::R E:::::::::::::::E
|
||||
V:::::V V:::::V O:::::O O:::::O R::::R R:::::R E::::::EEEEEEEEEE
|
||||
V:::::V:::::V O:::::O O:::::O R::::R R:::::R E:::::E
|
||||
V:::::::::V O::::::O O::::::O R::::R R:::::R E:::::E EEEEEE
|
||||
V:::::::V O:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEEEE:::::E
|
||||
V:::::V OO:::::::::::::OO R::::::R R:::::RE::::::::::::::::::::E
|
||||
V:::V OO:::::::::OO R::::::R R:::::RE::::::::::::::::::::E
|
||||
VVV OOOOOOOOO RRRRRRRR RRRRRRREEEEEEEEEEEEEEEEEEEEEE
|
||||
|
||||
-Aro <3 */
|
||||
|
||||
//
|
||||
// Overrides/additions to stock defines go here, as well as hooks. Sort them by
|
||||
// the object they are overriding. So all /mob/living together, etc.
|
||||
//
|
||||
/datum/configuration
|
||||
var/items_survive_digestion = 1 //For configuring if the important_items survive digestion
|
||||
/*
|
||||
//
|
||||
// The datum type bolted onto normal preferences datums for storing Virgo stuff
|
||||
//
|
||||
/client
|
||||
var/datum/vore_preferences/prefs_vr
|
||||
|
||||
/hook/client_new/proc/add_prefs_vr(client/C)
|
||||
C.prefs_vr = new/datum/vore_preferences(C)
|
||||
if(C.prefs_vr)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/datum/vore_preferences
|
||||
//Actual preferences
|
||||
var/digestable = 1
|
||||
var/list/belly_prefs = list()
|
||||
|
||||
//Mechanically required
|
||||
var/path
|
||||
var/slot
|
||||
var/client/client
|
||||
var/client_ckey
|
||||
|
||||
/datum/vore_preferences/New(client/C)
|
||||
if(istype(C))
|
||||
client = C
|
||||
client_ckey = C.ckey
|
||||
load_vore_preferences(C)
|
||||
*/
|
||||
//
|
||||
// Check if an object is capable of eating things, based on vore_organs
|
||||
//
|
||||
/proc/is_vore_predator(var/mob/living/O)
|
||||
if(istype(O,/mob/living))
|
||||
if(O.vore_organs.len > 0)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
//
|
||||
// Belly searching for simplifying other procs
|
||||
//
|
||||
/proc/check_belly(atom/movable/A)
|
||||
if(istype(A.loc,/mob/living))
|
||||
var/mob/living/M = A.loc
|
||||
for(var/I in M.vore_organs)
|
||||
var/datum/belly/B = M.vore_organs[I]
|
||||
if(A in B.internal_contents)
|
||||
return(B)
|
||||
|
||||
return 0
|
||||
|
||||
/*
|
||||
// Save/Load Vore Preferences
|
||||
//
|
||||
/datum/preferences/proc/load_vore()
|
||||
if(!client || !client_ckey) return 0 //No client, how can we save?
|
||||
|
||||
slot = client.prefs.default_slot
|
||||
|
||||
path = client.prefs.path
|
||||
|
||||
if(!path) return 0 //Path couldn't be set?
|
||||
if(!fexists(path)) //Never saved before
|
||||
save_vore() //Make the file first
|
||||
return 1
|
||||
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(!S) return 0 //Savefile object couldn't be created?
|
||||
|
||||
S.cd = "/character[slot]"
|
||||
|
||||
S["digestable"] >> digestable
|
||||
S["belly_prefs"] >> belly_prefs
|
||||
|
||||
if(isnull(digestable))
|
||||
digestable = 1
|
||||
if(isnull(belly_prefs))
|
||||
belly_prefs = list()
|
||||
|
||||
return 1
|
||||
|
||||
/datum/preferences/proc/save_vore()
|
||||
if(!path) return 0
|
||||
if(!slot) return 0
|
||||
var/savefile/S = new /savefile(path)
|
||||
if(!S) return 0
|
||||
S.cd = "/character[slot]"
|
||||
|
||||
S["digestable"] << digestable
|
||||
S["belly_prefs"] << belly_prefs
|
||||
|
||||
return 1
|
||||
*/
|
||||
@@ -1,457 +0,0 @@
|
||||
//
|
||||
// Vore management panel for players
|
||||
//
|
||||
|
||||
/mob/living/proc/insidePanel()
|
||||
set name = "Vore Panel"
|
||||
set category = "Vore"
|
||||
|
||||
var/datum/vore_look/picker_holder = new()
|
||||
picker_holder.loop = picker_holder
|
||||
picker_holder.selected = vore_organs[vore_selected]
|
||||
|
||||
var/dat = picker_holder.gen_vui(src)
|
||||
|
||||
picker_holder.popup = new(src, "insidePanel","Inside!", 400, 600, picker_holder)
|
||||
picker_holder.popup.set_content(dat)
|
||||
picker_holder.popup.open()
|
||||
|
||||
//
|
||||
// Callback Handler for the Inside form
|
||||
//
|
||||
/datum/vore_look
|
||||
var/datum/belly/selected
|
||||
var/datum/browser/popup
|
||||
var/loop = null; // Magic self-reference to stop the handler from being GC'd before user takes action.
|
||||
|
||||
/datum/vore_look/Topic(href,href_list[])
|
||||
if (vp_interact(href, href_list))
|
||||
popup.set_content(gen_vui(usr))
|
||||
usr << output(popup.get_content(), "insidePanel.browser")
|
||||
|
||||
/datum/vore_look/proc/gen_vui(var/mob/living/user)
|
||||
var/dat
|
||||
|
||||
if (is_vore_predator(user.loc))
|
||||
var/mob/living/eater = user.loc
|
||||
var/datum/belly/inside_belly
|
||||
|
||||
//This big block here figures out where the prey is
|
||||
inside_belly = check_belly(user)
|
||||
|
||||
if(inside_belly)
|
||||
dat += "<font color = 'green'>You are currently inside</font> <font color = 'yellow'>[eater]'s</font> <font color = 'red'>[inside_belly]</font>!<br><br>"
|
||||
|
||||
if(inside_belly.inside_flavor)
|
||||
dat += "[inside_belly.inside_flavor]<br><br>"
|
||||
|
||||
if (inside_belly.internal_contents.len > 1)
|
||||
dat += "You can see the following around you:<br>"
|
||||
for (var/atom/movable/O in inside_belly.internal_contents)
|
||||
if(istype(O,/mob/living))
|
||||
var/mob/living/M = O
|
||||
//That's just you
|
||||
if(M == user)
|
||||
continue
|
||||
//Anything else
|
||||
dat += "<a href='?src=\ref[src];outsidepick=\ref[O];outsidebelly=\ref[inside_belly]'>[O]</a>"
|
||||
else
|
||||
dat += "You aren't inside anyone."
|
||||
|
||||
dat += "<HR>"
|
||||
|
||||
dat += "<ol style='list-style: none; padding: 0; overflow: auto;'>"
|
||||
for(var/K in user.vore_organs) //Fuggin can't iterate over values
|
||||
var/datum/belly/B = user.vore_organs[K]
|
||||
if(B == selected)
|
||||
dat += "<li style='float: left'><a href='?src=\ref[src];bellypick=\ref[B]'><b>[B.name]</b>"
|
||||
else
|
||||
dat += "<li style='float: left'><a href='?src=\ref[src];bellypick=\ref[B]'>[B.name]"
|
||||
|
||||
var/spanstyle
|
||||
switch(B.digest_mode)
|
||||
if(DM_HOLD)
|
||||
spanstyle = ""
|
||||
if(DM_DIGEST)
|
||||
spanstyle = "color:red;"
|
||||
if(DM_DIGESTF)
|
||||
spanstyle = "color:red;"
|
||||
if(DM_HEAL)
|
||||
spanstyle = "color:green;"
|
||||
|
||||
dat += "<span style='[spanstyle]'> ([B.internal_contents.len])</span></a></li>"
|
||||
|
||||
if(user.vore_organs.len < 10)
|
||||
dat += "<li style='float: left'><a href='?src=\ref[src];newbelly=1'>New+</a></li>"
|
||||
dat += "</ol>"
|
||||
dat += "<HR>"
|
||||
|
||||
// Selected Belly (contents, configuration)
|
||||
if(!selected)
|
||||
dat += "No belly selected. Click one to select it."
|
||||
else
|
||||
if(selected.internal_contents.len > 0)
|
||||
dat += "<b>Contents:</b> "
|
||||
for(var/O in selected.internal_contents)
|
||||
dat += "<a href='?src=\ref[src];insidepick=\ref[O]'>[O]</a>"
|
||||
|
||||
//If there's more than one thing, add an [All] button
|
||||
if(selected.internal_contents.len > 1)
|
||||
dat += "<a href='?src=\ref[src];insidepick=1;pickall=1'>\[All\]</a>"
|
||||
|
||||
dat += "<HR>"
|
||||
|
||||
//Belly Name Button
|
||||
dat += "<a href='?src=\ref[src];b_name=\ref[selected]'>Name:</a>"
|
||||
dat += " '[selected.name]'"
|
||||
|
||||
//Digest Mode Button
|
||||
dat += "<br><a href='?src=\ref[src];b_mode=\ref[selected]'>Belly Mode:</a>"
|
||||
dat += " [selected.digest_mode]"
|
||||
|
||||
//Belly verb
|
||||
dat += "<br><a href='?src=\ref[src];b_verb=\ref[selected]'>Vore Verb:</a>"
|
||||
dat += " '[selected.vore_verb]'"
|
||||
|
||||
//Inside flavortext
|
||||
dat += "<br><a href='?src=\ref[src];b_desc=\ref[selected]'>Flavor Text:</a>"
|
||||
dat += " '[selected.inside_flavor]'"
|
||||
|
||||
//Belly sound
|
||||
dat += "<br><a href='?src=\ref[src];b_sound=\ref[selected]'>Set Vore Sound</a>"
|
||||
dat += "<a href='?src=\ref[src];b_soundtest=\ref[selected]'>Test</a>"
|
||||
|
||||
//Belly messages
|
||||
dat += "<br><a href='?src=\ref[src];b_msgs=\ref[selected]'>Belly Messages</a>"
|
||||
|
||||
//Delete button
|
||||
dat += "<br><a style='background:#990000;' href='?src=\ref[src];b_del=\ref[selected]'>Delete Belly</a>"
|
||||
|
||||
dat += "<HR>"
|
||||
|
||||
//Under the last HR, save and stuff.
|
||||
dat += "<a href='?src=\ref[src];saveprefs=1'>Save Prefs</a>"
|
||||
dat += "<a href='?src=\ref[src];refresh=1'>Refresh</a>"
|
||||
|
||||
switch(user.digestable)
|
||||
if(1)
|
||||
dat += "<a href='?src=\ref[src];toggledg=1'>Toggle Digestable</a>"
|
||||
if(0)
|
||||
dat += "<a href='?src=\ref[src];toggledg=1'><span style='color:green;'>Toggle Digestable</span></a>"
|
||||
|
||||
//Returns the dat html to the vore_look
|
||||
return dat
|
||||
|
||||
/datum/vore_look/proc/vp_interact(href, href_list)
|
||||
var/mob/living/user = usr
|
||||
for(var/H in href_list)
|
||||
|
||||
if(href_list["close"])
|
||||
del(src) // Cleanup
|
||||
return
|
||||
|
||||
if(href_list["outsidepick"])
|
||||
var/tgt = locate(href_list["outsidepick"])
|
||||
var/datum/belly/OB = locate(href_list["outsidebelly"])
|
||||
var/intent = "Examine"
|
||||
|
||||
if(istype(tgt,/mob/living))
|
||||
var/mob/living/M = tgt
|
||||
intent = alert("What do you want to do to them?","Query","Examine","Help Out","Devour")
|
||||
switch(intent)
|
||||
if("Examine") //Examine a mob inside another mob
|
||||
M.examine(user)
|
||||
|
||||
if("Help Out") //Help the inside-mob out
|
||||
user << "<font color='green'>You begin to push [M] to freedom!</font>"
|
||||
M << "[usr] begins to push you to freedom!"
|
||||
M.loc << "<span class='warning'>Someone is trying to escape from inside you!</span>"
|
||||
sleep(50)
|
||||
if(prob(33))
|
||||
OB.release_specific_contents(M)
|
||||
usr << "<font color='green'>You manage to help [M] to safety!</font>"
|
||||
M << "<font color='green'>[user] pushes you free!</font>"
|
||||
M.loc << "<span class='alert'>[M] forces free of the confines of your body!</span>"
|
||||
else
|
||||
user << "<span class='alert'>[M] slips back down inside despite your efforts.</span>"
|
||||
M << "<span class='alert'> Even with [user]'s help, you slip back inside again.</span>"
|
||||
M.loc << "<font color='green'>Your body efficiently shoves [M] back where they belong.</font>"
|
||||
|
||||
if("Devour") //Eat the inside mob
|
||||
if(!user.vore_selected)
|
||||
user << "<span class='warning'>Pick a belly on yourself first!</span>"
|
||||
return 1
|
||||
|
||||
var/datum/belly/TB = user.vore_organs[user.vore_selected]
|
||||
user << "<span class='warning'>You begin to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!</span>"
|
||||
M << "<span class='warning'>[user] begins to [lowertext(TB.vore_verb)] you into their [lowertext(TB.name)]!</span>"
|
||||
M.loc << "<span class='warning'>Someone inside you is eating someone else!</span>"
|
||||
|
||||
sleep(TB.nonhuman_prey_swallow_time)
|
||||
if((user in OB.internal_contents) && (M in OB.internal_contents))
|
||||
user << "<span class='warning'>You manage to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!</span>"
|
||||
M << "<span class='warning'>[user] manages to [lowertext(TB.vore_verb)] you into their [lowertext(TB.name)]!</span>"
|
||||
M.loc << "<span class='warning'>Someone inside you has eaten someone else!</span>"
|
||||
M.loc = user
|
||||
TB.nom_mob(M)
|
||||
OB.internal_contents -= M
|
||||
|
||||
else if(istype(tgt,/obj/item))
|
||||
var/obj/item/T = tgt
|
||||
intent = alert("What do you want to do to that?","Query","Examine","Use Hand")
|
||||
switch(intent)
|
||||
if("Examine")
|
||||
T.examine(user)
|
||||
|
||||
if("Use Hand")
|
||||
if(user.stat)
|
||||
user << "<span class='warning'>You can't do that in your state!</span>"
|
||||
return 1
|
||||
|
||||
user.ClickOn(T)
|
||||
sleep(5) //Seems to exit too fast for the panel to update
|
||||
|
||||
if(href_list["insidepick"])
|
||||
var/intent
|
||||
|
||||
//Handle the [All] choice. Ugh inelegant. Someone make this pretty.
|
||||
if(href_list["pickall"])
|
||||
intent = alert("Eject all, Move all?","Query","Eject all","Cancel","Move all")
|
||||
switch(intent)
|
||||
if("Cancel")
|
||||
return 1
|
||||
|
||||
if("Eject all")
|
||||
if(user.stat)
|
||||
user << "<span class='warning'>You can't do that in your state!</span>"
|
||||
return 1
|
||||
|
||||
selected.release_all_contents()
|
||||
playsound(user, 'sound/effects/splat.ogg', 50, 1)
|
||||
|
||||
if("Move all")
|
||||
if(user.stat)
|
||||
user << "<span class='warning'>You can't do that in your state!</span>"
|
||||
return 1
|
||||
|
||||
var/choice = input("Move all where?","Select Belly") in user.vore_organs + "Cancel - Don't Move"
|
||||
|
||||
if(choice == "Cancel - Don't Move")
|
||||
return 1
|
||||
else
|
||||
var/datum/belly/B = user.vore_organs[choice]
|
||||
for(var/atom/movable/tgt in selected.internal_contents)
|
||||
selected.internal_contents -= tgt
|
||||
B.internal_contents += tgt
|
||||
|
||||
tgt << "<span class='warning'>You're squished from [user]'s [selected] to their [B]!</span>"
|
||||
|
||||
for(var/mob/hearer in range(1,user))
|
||||
hearer << sound('sound/vore/squish2.ogg',volume=80)
|
||||
return 1
|
||||
|
||||
|
||||
var/atom/movable/tgt = locate(href_list["insidepick"])
|
||||
intent = "Examine"
|
||||
intent = alert("Examine, Eject, Move? Examine if you want to leave this box.","Query","Examine","Eject","Move")
|
||||
switch(intent)
|
||||
if("Examine")
|
||||
tgt.examine(user)
|
||||
|
||||
if("Eject")
|
||||
if(user.stat)
|
||||
user << "<span class='warning'>You can't do that in your state!</span>"
|
||||
return 1
|
||||
|
||||
selected.release_specific_contents(tgt)
|
||||
playsound(user, 'sound/effects/splat.ogg', 50, 1)
|
||||
|
||||
if("Move")
|
||||
if(user.stat)
|
||||
user << "<span class='warning'>You can't do that in your state!</span>"
|
||||
return 1
|
||||
|
||||
var/choice = input("Move [tgt] where?","Select Belly") in user.vore_organs + "Cancel - Don't Move"
|
||||
|
||||
if(choice == "Cancel - Don't Move")
|
||||
return 1
|
||||
else
|
||||
var/datum/belly/B = user.vore_organs[choice]
|
||||
selected.internal_contents -= tgt
|
||||
B.internal_contents += tgt
|
||||
|
||||
tgt << "<span class='warning'>You're squished from [user]'s [lowertext(selected.name)] to their [lowertext(B.name)]!</span>"
|
||||
for(var/mob/hearer in range(1,user))
|
||||
hearer << sound('sound/vore/squish2.ogg',volume=80)
|
||||
|
||||
if(href_list["newbelly"])
|
||||
if(user.vore_organs.len >= 10)
|
||||
return 1
|
||||
|
||||
var/new_name = html_encode(input(usr,"New belly's name:","New Belly") as text|null)
|
||||
|
||||
if(length(new_name) > 12 || length(new_name) < 2)
|
||||
usr << "<span class='warning'>Entered belly name is too long.</span>"
|
||||
return 0
|
||||
if(new_name in user.vore_organs)
|
||||
usr << "<span class='warning'>No duplicate belly names, please.</span>"
|
||||
return 0
|
||||
|
||||
var/datum/belly/NB = new(user)
|
||||
NB.name = new_name
|
||||
user.vore_organs[new_name] = NB
|
||||
selected = NB
|
||||
|
||||
if(href_list["bellypick"])
|
||||
selected = locate(href_list["bellypick"])
|
||||
user.vore_selected = selected.name
|
||||
|
||||
if(href_list["b_name"])
|
||||
var/new_name = html_encode(input(usr,"Belly's new name:","New Name") as text|null)
|
||||
|
||||
if(length(new_name) > 12 || length(new_name) < 2)
|
||||
usr << "<span class='warning'>Entered belly name length invalid (must be longer than 2, shorter than 12).</span>"
|
||||
return 0
|
||||
if(new_name in user.vore_organs)
|
||||
usr << "<span class='warning'>No duplicate belly names, please.</span>"
|
||||
return 0
|
||||
|
||||
user.vore_organs[new_name] = selected
|
||||
user.vore_organs -= selected.name
|
||||
selected.name = new_name
|
||||
|
||||
if(href_list["b_mode"])
|
||||
var/list/menu_list = selected.digest_modes
|
||||
|
||||
if(selected.digest_modes.len == 1) // Don't do anything
|
||||
return 1
|
||||
if(selected.digest_modes.len == 2) // Just toggle... there's probably a more elegant way to do this...
|
||||
var/index = selected.digest_modes.Find(selected.digest_mode)
|
||||
switch(index)
|
||||
if(1)
|
||||
selected.digest_mode = selected.digest_modes[2]
|
||||
if(2)
|
||||
selected.digest_mode = selected.digest_modes[1]
|
||||
else
|
||||
selected.digest_mode = input("Choose Mode (currently [selected.digest_mode])") in menu_list
|
||||
|
||||
if(href_list["b_desc"])
|
||||
var/new_desc = html_encode(input(usr,"Belly Description (1024 char limit):","New Description",selected.inside_flavor) as message|null)
|
||||
new_desc = readd_quotes(new_desc)
|
||||
|
||||
if(length(new_desc) > 1024)
|
||||
usr << "<span class='warning'>Entered belly desc too long. 1024 character limit.</span>"
|
||||
return 0
|
||||
|
||||
selected.inside_flavor = new_desc
|
||||
|
||||
if(href_list["b_msgs"])
|
||||
var/list/messages = list(
|
||||
"Digest Message (to prey)",
|
||||
"Digest Message (to you)",
|
||||
"Struggle Message (outside)",
|
||||
"Struggle Message (inside)",
|
||||
"Examine Message (when full)",
|
||||
"Reset All To Default",
|
||||
"Cancel - No Changes"
|
||||
)
|
||||
|
||||
alert(user,"Setting abusive or deceptive messages will result in a ban. Consider this your warning. Max 150 characters per message, max 10 messages per topic.","Really, don't.")
|
||||
var/choice = input(user,"Select a type to modify. Messages from each topic are pulled at random when needed.","Pick Type") in messages
|
||||
var/help = " Press enter twice to separate messages. '%pred' will be replaced with your name. '%prey' will be replaced with the prey's name. '%belly' will be replaced with your belly's name."
|
||||
|
||||
switch(choice)
|
||||
if("Digest Message (to prey)")
|
||||
var/new_message = input(user,"These are sent to prey when they expire. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Digest Message (to prey)",selected.get_messages("dmp")) as message
|
||||
if(new_message)
|
||||
selected.set_messages(new_message,"dmp")
|
||||
|
||||
if("Digest Message (to you)")
|
||||
var/new_message = input(user,"These are sent to you when prey expires in you. Write them in 2nd person ('you feel X'). Avoid using %pred in this type."+help,"Digest Message (to you)",selected.get_messages("dmo")) as message
|
||||
if(new_message)
|
||||
selected.set_messages(new_message,"dmo")
|
||||
|
||||
if("Struggle Message (outside)")
|
||||
var/new_message = input(user,"These are sent to those nearby when prey struggles. Write them in 3rd person ('X's Y bulges')."+help,"Struggle Message (outside)",selected.get_messages("smo")) as message
|
||||
if(new_message)
|
||||
selected.set_messages(new_message,"smo")
|
||||
|
||||
if("Struggle Message (inside)")
|
||||
var/new_message = input(user,"These are sent to prey when they struggle. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Struggle Message (inside)",selected.get_messages("smi")) as message
|
||||
if(new_message)
|
||||
selected.set_messages(new_message,"smi")
|
||||
|
||||
if("Examine Message (when full)")
|
||||
var/new_message = input(user,"These are sent to people who examine you when this belly has contents. Write them in 3rd person ('Their %belly is bulging'). Do not use %pred or %prey in this type."+help,"Examine Message (when full)",selected.get_messages("em")) as message
|
||||
if(new_message)
|
||||
selected.set_messages(new_message,"em")
|
||||
|
||||
if("Reset All To Default")
|
||||
var/confirm = alert(user,"This will delete any custom messages. Are you sure?","Confirmation","DELETE","Cancel")
|
||||
if(confirm == "DELETE")
|
||||
selected.digest_messages_prey = initial(selected.digest_messages_prey)
|
||||
selected.digest_messages_owner = initial(selected.digest_messages_owner)
|
||||
selected.struggle_messages_outside = initial(selected.struggle_messages_outside)
|
||||
selected.struggle_messages_inside = initial(selected.struggle_messages_inside)
|
||||
|
||||
if("Cancel - No Changes")
|
||||
return 1
|
||||
|
||||
if(href_list["b_verb"])
|
||||
var/new_verb = html_encode(input(usr,"New verb when eating (infinitive tense, e.g. nom or swallow):","New Verb") as text|null)
|
||||
|
||||
if(length(new_verb) > 12 || length(new_verb) < 2)
|
||||
usr << "<span class='warning'>Entered verb length invalid (must be longer than 2, shorter than 12).</span>"
|
||||
return 0
|
||||
|
||||
selected.vore_verb = new_verb
|
||||
|
||||
if(href_list["b_sound"])
|
||||
var/choice = input(user,"Currently set to [selected.vore_sound]","Select Sound") in vore_sounds + "Cancel - No Changes"
|
||||
|
||||
if(choice == "Cancel")
|
||||
return 1
|
||||
|
||||
selected.vore_sound = vore_sounds[choice]
|
||||
|
||||
if(href_list["b_soundtest"])
|
||||
user << selected.vore_sound
|
||||
|
||||
if(href_list["b_del"])
|
||||
if(selected.internal_contents.len)
|
||||
usr << "<span class='warning'>Can't delete bellies with contents!</span>"
|
||||
else if(selected.immutable)
|
||||
usr << "<span class='warning'>This belly is marked as undeletable.</span>"
|
||||
else if(user.vore_organs.len == 1)
|
||||
usr << "<span class='warning'>You must have at least one belly.</span>"
|
||||
else
|
||||
var/alert = alert("Are you sure you want to delete [selected]?","Confirmation","Delete","Cancel")
|
||||
if(alert == "Delete" && !selected.internal_contents.len)
|
||||
user.vore_organs -= selected.name
|
||||
user.vore_organs.Remove(selected)
|
||||
selected = user.vore_organs[1]
|
||||
user.vore_selected = user.vore_organs[1]
|
||||
|
||||
if(href_list["saveprefs"])
|
||||
if(!user.save_vore_prefs())
|
||||
user << "<span class='warning'>ERROR: Preferences failed to save!</span>"
|
||||
else
|
||||
user << "<span class='notice'>Preferences saved!</span>"
|
||||
|
||||
if(href_list["toggledg"])
|
||||
var/choice = alert(user, "This button is for those who don't like being digested. It can make you undigestable. Don't abuse this button by toggling it back and forth to extend a scene or whatever, or you'll make the admins cry. Digesting you is currently: [user.digestable ? "Allowed" : "Prevented"]", "", "Allow Digestion", "Cancel", "Prevent Digestion")
|
||||
switch(choice)
|
||||
if("Cancel")
|
||||
return 1
|
||||
if("Allow Digestion")
|
||||
user.digestable = 1
|
||||
if("Prevent Digestion")
|
||||
user.digestable = 0
|
||||
|
||||
// message_admins("[key_name(user)] toggled their digestability to [user.digestable] ([user ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[user.loc.];Y=[user.loc.y];Z=[user.loc.z]'>JMP</a>" : "null"])")
|
||||
|
||||
if(user.client.prefs)
|
||||
user.client.prefs.digestable = user.digestable
|
||||
|
||||
//Refresh when interacted with, returning 1 makes vore_look.Topic update
|
||||
return 1
|
||||
@@ -1,124 +0,0 @@
|
||||
// BEGIN - DO NOT EDIT PROTOTYPE
|
||||
/obj/item/weapon/storage/box/fluff
|
||||
name = "Undefined Fluff Box"
|
||||
desc = "This should have a description. Tell an admin."
|
||||
storage_slots = 7
|
||||
var/list/has_items = list()
|
||||
|
||||
/obj/item/weapon/storage/box/fluff/New()
|
||||
storage_slots = has_items.len
|
||||
allowed = list()
|
||||
for(var/P in has_items)
|
||||
allowed += P
|
||||
new P(src)
|
||||
..()
|
||||
return
|
||||
// END - DO NOT EDIT PROTOTYPE
|
||||
|
||||
|
||||
/* TEMPLATE
|
||||
// ckey:Character Name
|
||||
/obj/item/weapon/storage/box/fluff/charactername
|
||||
name = ""
|
||||
desc = ""
|
||||
has_items = list(
|
||||
/obj/item/clothing/head/thing1,
|
||||
/obj/item/clothing/shoes/thing2,
|
||||
/obj/item/clothing/suit/thing3,
|
||||
/obj/item/clothing/under/thing4)
|
||||
*/
|
||||
|
||||
//POLARISTODO - These fail to compile since not all items are ported yet
|
||||
// bwoincognito:Tasald Corlethian
|
||||
/obj/item/weapon/storage/box/fluff/tasald
|
||||
name = "Tasald's Kit"
|
||||
desc = "A kit containing Talsald's equipment."
|
||||
has_items = list(
|
||||
/obj/item/clothing/suit/storage/det_suit/fluff/tasald,
|
||||
/obj/item/clothing/suit/storage/det_suit/fluff/tas_coat,
|
||||
/obj/item/clothing/under/det/fluff/tasald,
|
||||
/obj/item/fluff/permit/tasald_corlethian,
|
||||
/obj/item/weapon/gun/projectile/revolver/detective/fluff/tasald_corlethian,
|
||||
/obj/item/weapon/implanter/loyalty)
|
||||
|
||||
// jemli:Cirra Mayhem
|
||||
/obj/item/weapon/storage/box/fluff/cirra
|
||||
name = "Instant Pirate Kit"
|
||||
desc = "Just add Akula!"
|
||||
has_items = list(
|
||||
/obj/item/clothing/head/pirate,
|
||||
/obj/item/clothing/glasses/eyepatch,
|
||||
/obj/item/clothing/suit/pirate,
|
||||
/obj/item/clothing/under/pirate)
|
||||
|
||||
// joey4298:Emoticon
|
||||
/obj/item/weapon/storage/box/fluff/emoticon
|
||||
name = "Emoticon's Mime Kit"
|
||||
desc = "Specially packaged for the hungry catgirl mime with a taste for clown."
|
||||
has_items = list(
|
||||
/obj/item/device/fluff/id_kit_mime,
|
||||
/obj/item/clothing/gloves/white,
|
||||
/obj/item/clothing/head/beret,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing,
|
||||
/obj/item/clothing/shoes/black,
|
||||
/*/obj/item/toy/crayon/mime*/) //Need to track down the code for crayons before adding this back in
|
||||
|
||||
//joanrisu:Joan Risu
|
||||
/obj/item/weapon/storage/backpack/dufflebag/sec/fluff/joanrisu
|
||||
name = "Joan's Workbag"
|
||||
desc = "A duffle bag Joan uses to carry her work equipment."
|
||||
slowdown = 0
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/clothing/accessory/holster/hip(src)
|
||||
new /obj/item/clothing/suit/storage/fluff/fedcoat/fedcapt(src)
|
||||
new /obj/item/weapon/card/id/centcom/fluff/joanbadge(src)
|
||||
new /obj/item/weapon/gun/energy/gun/fluff/dominator(src)
|
||||
new /obj/item/clothing/suit/armor/det_suit(src)
|
||||
new /obj/item/fluff/permit/joanrisu(src)
|
||||
new /obj/item/clothing/accessory/storage/black_vest(src)
|
||||
new /obj/item/weapon/sword/fluff/joanaria(src)
|
||||
new /obj/item/weapon/flame/lighter/zippo/fluff/joan(src)
|
||||
new /obj/item/clothing/under/rank/internalaffairs/fluff/joan(src)
|
||||
|
||||
//joanrisu:Katarina Eine
|
||||
/obj/item/weapon/storage/backpack/dufflebag/sec/fluff/Katarina
|
||||
name = "Katarina's Workbag"
|
||||
desc = "A duffle bag Katarina uses to carry her tools."
|
||||
slowdown = 0
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/clothing/accessory/holster/hip(src)
|
||||
new /obj/item/clothing/suit/storage/fluff/fedcoat(src)
|
||||
new /obj/item/weapon/gun/energy/gun/fluff/dominator(src)
|
||||
new /obj/item/clothing/suit/armor/det_suit(src)
|
||||
new /obj/item/clothing/accessory/storage/black_vest(src)
|
||||
new /obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina(src)
|
||||
new /obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina(src)
|
||||
new /obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina(src)
|
||||
new /obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina(src)
|
||||
new /obj/item/clothing/under/rank/internalaffairs/fluff/joan(src)
|
||||
|
||||
//Razerwing:Archer Maximus
|
||||
/obj/item/weapon/storage/box/fluff/archermaximus
|
||||
desc = "Personal Effects"
|
||||
has_items = list(
|
||||
/obj/item/fluff/permit/archermaximus,
|
||||
/obj/item/weapon/gun/projectile/colt/fluff/archercolt)
|
||||
|
||||
// arokha:Aronai Kadigan
|
||||
/obj/item/weapon/storage/backpack/dufflebag/emt/fluff/aro
|
||||
name = "Aronai's Equipment"
|
||||
desc = "A big dufflebag, containing the stuff Aronai likes to carry with him."
|
||||
slowdown = 0 //HAX!
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/clothing/head/helmet/space/fluff/aronai(src)
|
||||
new /obj/item/clothing/suit/space/fluff/aronai(src)
|
||||
new /obj/item/device/suit_cooling_unit(src)
|
||||
new /obj/item/weapon/material/hatchet/tacknife/combatknife(src)
|
||||
new /obj/item/weapon/card/id/centcom/fluff/aro(src)
|
||||
new /obj/item/weapon/reagent_containers/hypospray/fluff/aronai(src)
|
||||
@@ -1,684 +0,0 @@
|
||||
/* TUTORIAL
|
||||
"icon" is the file with the HUD/ground icon for the item
|
||||
"icon_state" is the iconstate in this file for the item
|
||||
"icon_override" is the file with the on-mob icons, can be the same file
|
||||
"item_state" is the iconstate for the on-mob icons:
|
||||
item_state_s is used for worn uniforms on mobs
|
||||
item_state_r and item_state_l are for being held in each hand
|
||||
some do not have a suffix, like gloves. plan accordingly, maybe add _mob?
|
||||
"overlay_state" is the iconstate for ties/accessories, for some reason they don't
|
||||
just use the item_state variable
|
||||
|
||||
If you don't have a special HUD/ground sprite, don't worry about it.
|
||||
Just set both the icon_state and item_state to the same thing,
|
||||
and it will use the top direction sprite (facing the viewer)
|
||||
for your HUD/item sprite. This usually looks fine!
|
||||
|
||||
Advanced:
|
||||
"item_state_slots" can replace "item_state", it is a list:
|
||||
item_state_slots["slotname1"] = "item state for that slot"
|
||||
item_state_slots["slotname2"] = "item state for that slot"
|
||||
*/
|
||||
|
||||
/* TEMPLATE
|
||||
//ckey:Character Name
|
||||
/obj/item/clothing/type/fluff/charactername
|
||||
name = ""
|
||||
desc = ""
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "myicon"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "myicon"
|
||||
|
||||
*/
|
||||
|
||||
//benemuel:Yuuko Shimmerpond
|
||||
/obj/item/clothing/under/fluff/sakura_hokkaido_kimono
|
||||
name = "Sakura Kimono"
|
||||
desc = "A pale-pink, nearly white, kimono with a red and gold obi. There is a embroidered design of cherry blossom flowers covering the kimono."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "sh_kimono"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "sh_kimono_mob"
|
||||
|
||||
//BeyondMyLife:Kilano Soryu
|
||||
/obj/item/clothing/under/dress/fluff/kilano
|
||||
name = "Bleached Dress"
|
||||
desc = "It appears that this was once a captain's dress, it's blueish color has been turned white by bleach, only the gold markings remain to slightly signify what it once was."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "kilanodress"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "kilanodress_mob"
|
||||
|
||||
species_restricted = null
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
|
||||
|
||||
//BeyondMyLife:Kilano Soryu
|
||||
/obj/item/clothing/gloves/fluff/kilano
|
||||
name = "Bleached Gloves"
|
||||
desc = "Some old captain's gloves, bleached white, almost unrecognizable from the color change besides the gold trim."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "kilanogloves"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "kilanogloves_mob"
|
||||
species_restricted = null
|
||||
|
||||
//JoanRisu:Joan Risu
|
||||
/obj/item/clothing/under/suit_jacket/female/fluff/asuna
|
||||
name = "Joan's Historia Uniform"
|
||||
desc = "A red and white outfit used by Joan during her explorer days. Looks almost like a red school uniform."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "joanasuna"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "joanasuna"
|
||||
|
||||
//Unknown. Please check records from the forums.
|
||||
/obj/item/clothing/under/suit_jacket/female/fluff/miqote
|
||||
name = "Miqo'te Seperates"
|
||||
desc = "This two-part set of clothing is very popular on the planet Hydaelyn. While made of very robust materials, its usefulness as armor is negated by the exposed midriff."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "miqote"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "miqote"
|
||||
|
||||
//JoanRisu:Joan Risu
|
||||
/obj/item/clothing/under/fluff/nightgown
|
||||
name = "nightgown"
|
||||
desc = "A seethrough nightgown. For those intimate nights with your significant other."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "joannightgown"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "joannightgown"
|
||||
|
||||
//Vorrarkul:Lucina Dakarim
|
||||
/obj/item/clothing/under/dress/fluff/lucinadress
|
||||
name = "Elegant Purple Dress"
|
||||
desc = "An expertly tailored dress, made out of fine fabrics. The interwoven necklace appears to be made out of gold, with three complicated symbols engraved in the front."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "solara_dress"
|
||||
|
||||
icon_override = 'icons/mob/uniform.dmi'
|
||||
item_state = "solara_dress"
|
||||
|
||||
//For general use
|
||||
/obj/item/clothing/suit/armor/hos/fluff/brittrenchcoat
|
||||
name = "Britania Trench Coat"
|
||||
desc = "An armored trench coat from the Brittanian Empire. It looks so British."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "brittrenchcoat"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "brittrenchcoat"
|
||||
|
||||
//For general use
|
||||
/obj/item/clothing/suit/armor/hos/nazi_greatcoat
|
||||
name = "Greatcoat"
|
||||
desc = "Perfect attire for kicking down the doors of suspected dissidents; this coat gives off an imposing look, while offering a luxuriously plush fur liner."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "greatcoat"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "greatcoat_mob"
|
||||
|
||||
//For general use
|
||||
/obj/item/clothing/suit/storage/fluff/fedcoat
|
||||
name = "Federation Uniform Jacket"
|
||||
desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it. Set phasers to awesome."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "fedcoat"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "fedcoat"
|
||||
|
||||
blood_overlay_type = "coat"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
|
||||
allowed = list(
|
||||
/obj/item/weapon/tank/emergency_oxygen,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/weapon/gun/energy,
|
||||
/obj/item/weapon/gun/projectile,
|
||||
/obj/item/ammo_magazine,
|
||||
/obj/item/ammo_casing,
|
||||
// /obj/item/weapon/storage/fancy/shotgun_ammo,
|
||||
/obj/item/weapon/melee/baton,
|
||||
/obj/item/weapon/handcuffs,
|
||||
// /obj/item/device/detective_scanner,
|
||||
/obj/item/device/taperecorder)
|
||||
armor = list(melee = 50, bullet = 15, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0)
|
||||
var/unbuttoned = 0
|
||||
|
||||
verb/toggle()
|
||||
set name = "Toggle coat buttons"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
if(!usr.canmove || usr.stat || usr.restrained())
|
||||
return 0
|
||||
|
||||
switch(unbuttoned)
|
||||
if(0)
|
||||
icon_state = "[initial(icon_state)]_open"
|
||||
item_state = "[initial(item_state)]_open"
|
||||
unbuttoned = 1
|
||||
usr << "You unbutton the coat."
|
||||
if(1)
|
||||
icon_state = "[initial(icon_state)]"
|
||||
item_state = "[initial(item_state)]"
|
||||
unbuttoned = 0
|
||||
usr << "You button up the coat."
|
||||
usr.update_inv_wear_suit()
|
||||
|
||||
//Variants
|
||||
fedblue
|
||||
name = "Federation Uniform Jacket"
|
||||
desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it. Wearing this may make you feel all scientific."
|
||||
icon_state = "fedblue"
|
||||
item_state = "fedblue"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0)
|
||||
|
||||
fedeng
|
||||
name = "Federation Uniform Jacket"
|
||||
desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it.Wearing it may make you feel like checking a warp core, whatever that is."
|
||||
icon_state = "fedeng"
|
||||
item_state = "fedeng"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 10, bomb = 0, bio = 30, rad = 35)
|
||||
|
||||
fedcapt
|
||||
name = "Federation Uniform Jacket"
|
||||
desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it. You feel like a commanding officer of Starfleet."
|
||||
icon_state = "fedcapt"
|
||||
item_state = "fedcapt"
|
||||
armor = list(melee = 50, bullet = 5, laser = 15,energy = 10, bomb = 0, bio = 0, rad = 0)
|
||||
|
||||
/*POLARISTODO - Needs rework in update_icons as it doesn't use item_state
|
||||
//For general use
|
||||
/obj/item/clothing/glasses/welding/fluff/yellow
|
||||
name = "Yellow Goggles"
|
||||
desc = "A neat looking pair of goggles"
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "gogyellow"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "gogyellow"
|
||||
|
||||
/obj/item/clothing/glasses/welding/fluff/blue
|
||||
name = "Blue Goggles"
|
||||
desc = "A neat looking pair of goggles"
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "gogblue"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "gogblue"
|
||||
*/
|
||||
|
||||
//wickedtemp:chakat tempest
|
||||
/obj/item/clothing/glasses/hud/health/fluff/wickedtemphud
|
||||
name = "Purple MedHUD"
|
||||
desc = "A standard Medical HUD, only this one is colored purple with a violet lens."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "healthhud"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "healthhud"
|
||||
|
||||
//For general use
|
||||
/obj/item/clothing/accessory/fluff/smilepin
|
||||
name = "Smiley Pin"
|
||||
desc = "A pin with a stupid grin on its face"
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "smilepin"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
overlay_state = "" //They don't have one
|
||||
|
||||
//For general use
|
||||
/obj/item/clothing/accessory/fluff/heartpin
|
||||
name = "Love Pin"
|
||||
desc = "A cute heart pin."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "heartpin"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
overlay_state = "" //They don't have one
|
||||
|
||||
//john.wayne9392:Harmony Prechtl
|
||||
/obj/item/clothing/suit/armor/captain/fluff/harmsuit
|
||||
name = "Harmony's Captain Armor"
|
||||
desc = "A modified Captain Armor suit for Harmony Prechtl."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "harmarmor"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "harmarmor"
|
||||
|
||||
//john.wayne9392:Harmony Prechtl
|
||||
/obj/item/clothing/head/helmet/space/capspace/fluff/harmhelm
|
||||
name = "Harmony's Captain Helmet"
|
||||
desc = "A modified Captain helmet for Harmony Prechtl."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "harmspace"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "harmspace_mob"
|
||||
|
||||
//john.wayne9392:Harmony Prechtl
|
||||
/obj/item/clothing/under/rank/captain/fluff/harmuniform
|
||||
name = "Harmony's Captain uniform"
|
||||
desc = "A customized Captain uniform for Harmony Prechtl, given to her as a gift by Central Command for her service."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "harmcaptain"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "harmcaptain"
|
||||
//Variant
|
||||
centcom
|
||||
name = "\improper CentCom administrator's uniform"
|
||||
desc = "It's a green jumpsuit with some gold markings denoting the rank of \"Administrator\"."
|
||||
|
||||
//john.wayne9392:Harmony Prechtl
|
||||
/obj/item/clothing/head/centhat/fluff/harmhat
|
||||
name = "Harmony's CentCom hat"
|
||||
desc = "It's good to be queen."
|
||||
|
||||
// bwoincognito:Tasald Corlethian
|
||||
/obj/item/clothing/under/det/fluff/tasald
|
||||
name = "Tasald's outfit"
|
||||
desc = "Tasald's outfit. Very green."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "tasaldsuit"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "tasaldsuit"
|
||||
|
||||
// bwoincognito:Tasald Corlethian
|
||||
/obj/item/clothing/suit/storage/det_suit/fluff/tasald
|
||||
name = "Tasald's Vest"
|
||||
desc = "A fancy looking vest. You look like a smooth operating officer in this."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "tasvest"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "tasvest"
|
||||
|
||||
blood_overlay_type = "coat"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
|
||||
// bwoincognito:Tasald Corlethian
|
||||
/obj/item/clothing/suit/storage/det_suit/fluff/tas_coat
|
||||
name = "Armored Colony coat"
|
||||
desc = "Dark green and grey colored sleeveless long coat with two thick metal shoulder pads. has seen some wear and tear, with noticeable patches in the fabric, scratches on the shoulder pads, but with a clean patch on the left upper chest. It has a red NT marked on the right shoulder pad and red Security on the left. "
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "tasaldcoat"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "tasaldcoat_mob"
|
||||
|
||||
blood_overlay_type = "coat"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
|
||||
//Event Costumes Below
|
||||
/obj/item/clothing/head/helmet/fluff/freddy
|
||||
name = "Animatronic Suit Helmet"
|
||||
desc = "Votre toast, je peux vous le rendre."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "freddyhead"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "freddyhead_mob"
|
||||
permeability_coefficient = 0.01
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
flags_inv = HIDEMASK|HIDEEARS
|
||||
cold_protection = HEAD
|
||||
siemens_coefficient = 0.9
|
||||
|
||||
//Bonnie Head
|
||||
bonnie
|
||||
desc = "Children's entertainer."
|
||||
icon_state = "bonniehead"
|
||||
item_state = "bonniehead_mob"
|
||||
|
||||
//Foxy Head
|
||||
foxy
|
||||
desc = "I guess he doesn't like being watched."
|
||||
icon_state = "foxyhead"
|
||||
item_state = "foxyhead_mob"
|
||||
|
||||
//Chica Head
|
||||
chica
|
||||
desc = "<b><font color=red>LET'S EAT!</font></b>"
|
||||
icon_state = "chicahead"
|
||||
item_state = "chicahead_mob"
|
||||
|
||||
//Anamatronic Suits
|
||||
/obj/item/clothing/suit/fluff/freddy
|
||||
name = "Animatronic Suit"
|
||||
desc = "Votre toast, je peux vous le rendre."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "freddysuit"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "freddysuit_mob"
|
||||
|
||||
gas_transfer_coefficient = 0.01
|
||||
permeability_coefficient = 0.02
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
|
||||
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
|
||||
siemens_coefficient = 0.9
|
||||
|
||||
//Bonnie Suit
|
||||
bonnie
|
||||
desc = "Children's entertainer."
|
||||
icon_state = "bonniesuit"
|
||||
item_state = "bonniesuit_mob"
|
||||
|
||||
//Foxy Suit
|
||||
foxy
|
||||
desc = "I guess he doesn't like being watched."
|
||||
icon_state = "foxysuit"
|
||||
item_state = "foxysuit_mob"
|
||||
|
||||
|
||||
//Chica Suit
|
||||
chica
|
||||
desc = "<b><font color=red>LET'S EAT!</font></b>"
|
||||
icon_state = "chicasuit"
|
||||
item_state = "chicasuit_mob"
|
||||
|
||||
//End event costumes
|
||||
|
||||
//scree:Scree
|
||||
/obj/item/clothing/head/helmet/space/void/engineering/fluff/screehelm
|
||||
name = "Modified Tajara Helmet"
|
||||
desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding. This one doesn't look like it was made for humans. Its been modified to include headlights."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "scree-helm"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "scree-helm_mob"
|
||||
|
||||
light_overlay = "helmet_light_dual"
|
||||
|
||||
species_restricted = null
|
||||
|
||||
mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
|
||||
..()
|
||||
if(H.ckey != "scree")
|
||||
H << "<span class='warning'>Your face and whoever is meant for this helmet are too different.</span>"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
//scree:Scree
|
||||
/obj/item/clothing/suit/space/void/engineering/fluff/screespess
|
||||
name = "Modified Winged Suit"
|
||||
desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding. This one doesn't look like it was made for humans. This one was made with a special personal shielding for someone's wings."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "scree-spess"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "scree-spess_mob"
|
||||
|
||||
species_restricted = null
|
||||
|
||||
mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
|
||||
..()
|
||||
if(H.ckey != "scree")
|
||||
H << "<span class='warning'>The gloves only have three fingers, not to mention the accomidation for extra limbs.</span>"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
//scree:Scree
|
||||
/obj/item/clothing/under/fluff/screesuit
|
||||
name = "Scree's feathers"
|
||||
desc = "A mop of fluffy blue feathers, the honkmother only knows what kind of bird they originally came from."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "screesuit"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "screesuit"
|
||||
|
||||
mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
|
||||
..()
|
||||
if(H.ckey != "scree")
|
||||
H << "<span class='warning'>Are you just going to tape them on or what? This isn't gonna work.</span>"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
//HOS Hardsuit
|
||||
/obj/item/clothing/suit/space/void/security/fluff/hos // ToDo: Rig version.
|
||||
name = "\improper prototype voidsuit"
|
||||
desc = "A customized security voidsuit made to match the Head of Security's obession with black. Has additional composite armor."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "rig-hos"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "rig-hos_mob"
|
||||
|
||||
//HOS Hardsuit Helmet
|
||||
/obj/item/clothing/head/helmet/space/void/security/fluff/hos // ToDo: Rig version.
|
||||
name = "\improper prototype voidsuit helmet"
|
||||
desc = "A customized security voidsuit helmet customized to include the Head of Security's signature hat. Has additional composite armor."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "rig0-hos"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "rig0-hos_mob"
|
||||
|
||||
//adk09:Lethe
|
||||
/obj/item/clothing/head/helmet/hos/fluff/lethe
|
||||
name = "Lethe's Hat"
|
||||
desc = " This is Lethe's Hat! A little tag attached inside reads: 'If found please return to Lethe! Or else!' It looks rather worn in. It also lacks armor."
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
|
||||
icon = 'icons/obj/clothing/hats.dmi'
|
||||
icon_state = "hoscap"
|
||||
|
||||
icon_override = 'icons/mob/head.dmi'
|
||||
item_state = "hoscap"
|
||||
|
||||
/obj/item/weapon/storage/belt/utility/fluff/vulpine
|
||||
name = "vulpine belt"
|
||||
desc = "A tool-belt in Atmos colours."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "vulpine_belt"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "vulpine_belt_mob"
|
||||
|
||||
storage_slots = 9
|
||||
New()
|
||||
..()
|
||||
new /obj/item/weapon/screwdriver(src)
|
||||
new /obj/item/weapon/wrench(src)
|
||||
new /obj/item/weapon/weldingtool(src)
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
new /obj/item/weapon/wirecutters(src)
|
||||
new /obj/item/device/multitool(src)
|
||||
new /obj/item/stack/cable_coil(src, 30, "red")
|
||||
new /obj/item/stack/cable_coil(src, 30, "green")
|
||||
|
||||
// molenar:Giliana Gamish
|
||||
/obj/item/clothing/suit/storage/toggle/labcoat/fluff/molenar
|
||||
name = "Gili Custom Labcoat"
|
||||
desc = " Custom made, lengthened labcoat with water resistant, durable material. And a custom set of holes inserted for Deathclaw anatomy. A tag inside has 'G.G.' monogram on it"
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "molenar"
|
||||
icon_open = "molenar_open"
|
||||
icon_closed = "molenar"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "molenar"
|
||||
|
||||
//scree:Scree
|
||||
/obj/item/clothing/head/fluff/pompom
|
||||
name = "Pom-Pom"
|
||||
desc = "A fluffy little thingus on a thin stalk, ideal for impersonating moogles and anglerfish. Kupomnomnom."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "pom"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "pom_mob"
|
||||
|
||||
w_class = 2.0
|
||||
on = 0
|
||||
brightness_on = 5
|
||||
light_overlay = null
|
||||
|
||||
attack_self(mob/user)
|
||||
if(!isturf(user.loc))
|
||||
user << "You cannot turn the light on while in this [user.loc]"
|
||||
return
|
||||
|
||||
switch(on)
|
||||
if(0)
|
||||
on = 1
|
||||
user << "You light up your pom-pom."
|
||||
icon_state = "pom-on"
|
||||
item_state = "pom-on_mob"
|
||||
if(1)
|
||||
on = 0
|
||||
user << "You dim your pom-pom."
|
||||
icon_state = "pom"
|
||||
item_state = "pom_mob"
|
||||
|
||||
update_light(user)
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.head == src)
|
||||
H.update_inv_head()
|
||||
|
||||
// arokha : Aronai Kadigan
|
||||
/obj/item/clothing/head/helmet/space/fluff/aronai
|
||||
name = "Aronai's Helmet"
|
||||
desc = "This spacesuit helmet appears to be custom-made for someone with pointed ears and a muzzle. \
|
||||
It is form-fitting enough that it's unlikely to fit anyone but the person it was intended for. \
|
||||
'Aronai' is printed on the back of the helmet."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "arohelm"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "arohelm_mob"
|
||||
|
||||
light_overlay = "helmet_light_dual"
|
||||
camera_networks = list(NETWORK_MEDICAL)
|
||||
|
||||
mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
|
||||
..()
|
||||
if(H.ckey != "arokha")
|
||||
H << "<span class='warning'>You try to wear the helmet, but it doesn't fit.</span>"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/suit/space/fluff/aronai
|
||||
name = "Aronai's Spacesuit"
|
||||
desc = "This spacesuit appears to be custom-made for someone with digitigrade legs and a tail. \
|
||||
It is form-fitting enough that it's unlikely to fit anyone but the person it was intended for. \
|
||||
'Aronai' is printed just above the spine on the back of the neckpiece. It has no space for an O2 tank. \
|
||||
In fact, it's practically paper-thin. It doesn't seem to retain body heat at all."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "arosuit"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "arosuit_mob"
|
||||
w_class = 4 //Oh but I can.
|
||||
allowed = list(/obj/item/device/suit_cooling_unit) //Can't fit O2 tanks
|
||||
|
||||
mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
|
||||
..()
|
||||
if(H.ckey != "arokha")
|
||||
H << "<span class='warning'>You try to fit into the suit, to no avail.</span>"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
//Viveret:Keturah
|
||||
/obj/item/clothing/under/dress/maid/
|
||||
name = "Maid Outfit"
|
||||
desc = "A french maid outfit made ironically in Gaia's version of the far east."
|
||||
|
||||
//JoanRisu:Joan Risu
|
||||
/obj/item/clothing/head/helmet/space/fluff/joan
|
||||
name = "Joan's Combat Space Helmet"
|
||||
desc = "A customized combat space helmet made for a certain squirrely Commissioned Officer. \
|
||||
The top has the signature ears that are held up with a harder back covering. 'Joan' is engraved on the back.\
|
||||
There are some indications that the helmet has seen combat."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "joanhelm"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "joanhelm_mob"
|
||||
|
||||
light_overlay = "helmet_light"
|
||||
|
||||
|
||||
//JoanRisu:Joan Risu
|
||||
/obj/item/clothing/suit/space/fluff/joan
|
||||
name = "Joan's Combat Spacesuit"
|
||||
desc = "A customized combat spacesuit made for a certain squirrely Commissioned Officer, tail slot included. \
|
||||
On the right shoulder, the United Federation's Emblem sits proudly. On the left, there are faded indications \
|
||||
that there were different ranks painted on and off. On the collar where the suit is softer is a rectangular \
|
||||
name-tag with the name 'Joan' on it. There are indications that the suit has seen combat."
|
||||
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "joansuit"
|
||||
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "joansuit_mob"
|
||||
|
||||
/obj/item/clothing/under/rank/internalaffairs/fluff/joan
|
||||
desc = "The plain, professional attire of a Federation Law Enforcement Detective. The collar is <i>immaculately</i> starched."
|
||||
name = "Federation Dress Shirt"
|
||||
icon_state = "internalaffairs"
|
||||
item_state = "ba_suit"
|
||||
worn_state = "internalaffairs"
|
||||
rolled_sleeves = 0
|
||||
starting_accessories = list(/obj/item/clothing/accessory/black)
|
||||
@@ -1,472 +0,0 @@
|
||||
/* TUTORIAL
|
||||
"icon" is the file with the HUD/ground icon for the item
|
||||
"icon_state" is the iconstate in this file for the item
|
||||
"icon_override" is the file with the on-mob icons, can be the same file
|
||||
"item_state" is the iconstate for the on-mob icons:
|
||||
item_state_s is used for worn uniforms on mobs
|
||||
item_state_r and item_state_l are for being held in each hand
|
||||
|
||||
"item_state_slots" can replace "item_state", it is a list:
|
||||
item_state_slots["slotname1"] = "item state for that slot"
|
||||
item_state_slots["slotname2"] = "item state for that slot"
|
||||
|
||||
on guns, in particular:
|
||||
item_state being null makes it look for exactly the icon_state in the on-mob file,
|
||||
including any 0,75,etc appended from the energy bar setting
|
||||
item_state being present prevents different mode sprites, sadly, but you may
|
||||
be able to override this on the gun itself with a proc
|
||||
*/
|
||||
|
||||
/* TEMPLATE
|
||||
//ckey:Character Name
|
||||
/obj/item/weapon/gun/type/fluff/charactername
|
||||
name = ""
|
||||
desc = ""
|
||||
|
||||
icon = 'icons/vore/custom_guns_vr.dmi'
|
||||
icon_state = "myicon"
|
||||
|
||||
icon_override = 'icons/vore/custom_guns_vr.dmi'
|
||||
item_state = "myicon"
|
||||
|
||||
*/
|
||||
|
||||
//////////////////// Projectile Weapons ////////////////////
|
||||
// For general use
|
||||
/obj/item/weapon/gun/projectile/automatic/battlerifle
|
||||
name = "\improper BR55 Service Rifle"
|
||||
desc = "You had your chance to be afraid before you joined my beloved Corps! But, to guide you back to the true path, I brought this motivational device! Uses unique 9.5x40mm rounds."
|
||||
icon = 'icons/obj/gun_vr.dmi'
|
||||
icon_state = "battlerifle"
|
||||
icon_override = 'icons/obj/gun_vr.dmi'
|
||||
item_state = "battlerifle"
|
||||
item_icons = null
|
||||
w_class = 4
|
||||
recoil = 2 // The battlerifle was known for its nasty recoil.
|
||||
max_shells = 36
|
||||
caliber = "9.5x40mm"
|
||||
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2)
|
||||
ammo_type = /obj/item/ammo_casing/a95mm
|
||||
magazine_type = /obj/item/ammo_magazine/battlerifle
|
||||
allowed_magazines = list(/obj/item/ammo_magazine/battlerifle)
|
||||
fire_sound = 'sound/weapons/battlerifle.ogg'
|
||||
load_method = MAGAZINE
|
||||
slot_flags = SLOT_BACK
|
||||
//requires_two_hands = 1
|
||||
one_handed_penalty = 4 // The weapon itself is heavy
|
||||
|
||||
// For general use
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/unsc
|
||||
name = "\improper M45E Tactical Shotgun"
|
||||
desc = "All you greenhorns who wanted to see Xenomorphs up close... this is your lucky day."
|
||||
|
||||
icon = 'icons/obj/gun_vr.dmi'
|
||||
icon_state = "haloshotgun"
|
||||
|
||||
icon_override = 'icons/obj/gun_vr.dmi'
|
||||
item_state = "haloshotgun"
|
||||
item_icons = null
|
||||
|
||||
ammo_type = /obj/item/ammo_casing/shotgun
|
||||
max_shells = 12
|
||||
|
||||
// jertheace : Jeremiah 'Ace' Acacius
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/unsc/fluff/ace
|
||||
name = "Ace's M45D Tactical Shotgun" // D-model holds half as many shells as the normal version so as not to be OP as shit. Better than shotgun, worse than combat shotgun.
|
||||
desc = "Owned by the respected (or feared?) veteran Captain of VORE Station. Inscribed on the barrel are the words \"Speak softly, and carry a big stick.\" It has a folding stock so it can fit into bags."
|
||||
w_class = 3 // Because collapsable stock so it fits in backpacks.
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/stunshell
|
||||
max_shells = 6
|
||||
|
||||
// bwoincognito:Tasald Corlethian
|
||||
/obj/item/weapon/gun/projectile/revolver/detective/fluff/tasald_corlethian
|
||||
name = "Big Iron revolver"
|
||||
desc = "A .38 revolver for veteran rangers on the planet Orta. The right side of the handle has a logo for Quarion industries, and the left is the Rangers. The primary ammo for this gun is .38 rubber. According to the CentCom Chief of Security, this revolver was more controversial than it needed to be."
|
||||
|
||||
icon = 'icons/vore/custom_guns_vr.dmi'
|
||||
icon_state = "tasaldrevolver"
|
||||
|
||||
item_state = "revolver"
|
||||
|
||||
fire_sound = 'sound/weapons/pistol.ogg'
|
||||
ammo_type = /obj/item/ammo_casing/c38r
|
||||
var/recentpump = 0
|
||||
var/cocksound = 'sound/weapons/revolvercock.ogg'
|
||||
|
||||
consume_next_projectile()
|
||||
if(chambered)
|
||||
return chambered.BB
|
||||
usr << "<span class='warning'>It's a single action revolver, pull the hammer back!</span>"
|
||||
return null
|
||||
|
||||
attack_self(mob/living/user as mob)
|
||||
if(world.time >= recentpump + 10)
|
||||
pump(user)
|
||||
recentpump = world.time
|
||||
|
||||
proc/pump(mob/M as mob)
|
||||
playsound(M, cocksound, 60, 1)
|
||||
|
||||
if(chambered)//We have a shell in the chamber
|
||||
chambered.loc = get_turf(src)//Eject casing
|
||||
chambered = null
|
||||
|
||||
if(loaded.len)
|
||||
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
|
||||
loaded -= AC //Remove casing from loaded list.
|
||||
chambered = AC
|
||||
|
||||
update_icon()
|
||||
|
||||
// wankersonofjerkin : Ryan Winz
|
||||
/obj/item/weapon/gun/projectile/revolver/fluff/ryan_winz_revolver
|
||||
name = "Ryan's 'Devilgun'"
|
||||
desc = "You notice the serial number on the revolver is 666. The word 'Sin' is engraved on the blood-red rosewood grip. Uses .357 rounds."
|
||||
|
||||
icon = 'icons/vore/custom_guns_vr.dmi'
|
||||
icon_state = "ryan_winz"
|
||||
|
||||
item_state = "revolver"
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/fluff/ryan_winz_revolver/redemption
|
||||
name = "Ryan's 'Redeemer'"
|
||||
desc = "You notice the serial number on the revolver is 667. The word 'Redemption' is engraved on dark rosewood grip. Uses .357 rounds."
|
||||
|
||||
// sasoperative : Joseph Skinner
|
||||
/obj/item/weapon/gun/projectile/revolver/shotgun/fluff/sasoperative
|
||||
name = "\"The Jury\""
|
||||
desc = "A customized variant of the \"The Judge\" revolver sold by Cybersun Industries, built specifically for Joseph Skinner. Uses 12g shells."
|
||||
|
||||
icon = 'icons/vore/custom_guns_vr.dmi'
|
||||
icon_state = "jury"
|
||||
|
||||
item_state = "gun"
|
||||
|
||||
accuracy = 0 // Because I know you're not an idiot who needs to be nerfed. -Ace
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/beanbag
|
||||
|
||||
// For general use
|
||||
/obj/item/weapon/gun/projectile/automatic/stg
|
||||
name = "\improper Sturmgewehr"
|
||||
desc = "An STG-560 built by RauMauser. Experience the terror of the Siegfried line, redone for the 26th century! The Kaiser would be proud. Uses unique 7.92x33mm Kurz rounds."
|
||||
icon = 'icons/obj/gun_vr.dmi'
|
||||
icon_state = "stg60"
|
||||
item_state = "arifle"
|
||||
w_class = 4
|
||||
max_shells = 30
|
||||
caliber = "kurz"
|
||||
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2, TECH_ILLEGAL = 6)
|
||||
magazine_type = /obj/item/ammo_magazine/stg
|
||||
allowed_magazines = list(/obj/item/ammo_magazine/stg)
|
||||
load_method = MAGAZINE
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/stg/update_icon(var/ignore_inhands)
|
||||
..()
|
||||
icon_state = (ammo_magazine)? "stg60" : "stg60-empty"
|
||||
item_state = (ammo_magazine)? "arifle" : "arifle-empty"
|
||||
if(!ignore_inhands) update_held_icon()
|
||||
|
||||
// For general use
|
||||
/obj/item/weapon/gun/projectile/automatic/m14/fluff/gallian
|
||||
name = "\improper Gallian 4 Rifle"
|
||||
desc = "The ever reliable Gallian 4 Rifle. Produced by the National Armory on the Planet of Gaia located in Gallia, the Gallian 4 Rifle offers high accuracy and is widely used in the United Federation's Military. Uses 7.62mm rounds."
|
||||
|
||||
// For general use
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/rifle/zmkar
|
||||
name = "\improper ZM Kar 1"
|
||||
desc = "A reproduction of an old ZM Kar 1 Rifle from the Autocratic East Europan Imperial Alliance of Gaia. Popular among imperials and collectors within the Federation and its allies. Uses 7.62mm rounds."
|
||||
|
||||
// For general use
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/rifle/wicked
|
||||
name = "Wicked Butterfly ZM Kar S1"
|
||||
desc = "A customized bolt-action sniper rifle that was carried by some of the most revered snipers in the Federation. The stock has a small butterfly engraved on it. Uses 7.62mm rounds."
|
||||
|
||||
icon = 'icons/vore/custom_guns_vr.dmi'
|
||||
icon_state = "wickedbutterfly"
|
||||
|
||||
icon_override = 'icons/obj/gun_vr.dmi'
|
||||
item_state = "SVD"
|
||||
item_icons = null
|
||||
|
||||
recoil = 2 //extra kickback
|
||||
accuracy = -1
|
||||
scoped_accuracy = 2
|
||||
load_method = SINGLE_CASING
|
||||
|
||||
verb/scope()
|
||||
set category = "Object"
|
||||
set name = "Use Scope"
|
||||
set popup_menu = 1
|
||||
|
||||
toggle_scope(2.0)
|
||||
|
||||
// For general use
|
||||
/obj/item/weapon/gun/projectile/automatic/pdw // Vorestation SMG because the WT550 is ugly and bad.
|
||||
name = "personal defense weapon"
|
||||
desc = "The X-9MM is a select-fire personal defense weapon designed in-house by Xing Private Security. It was made to compete with the WT550 Saber, but hasn't yet caught on in popularity outside of the Virgo-Erigone system. Uses 9mm rounds."
|
||||
icon = 'icons/obj/gun_vr.dmi'
|
||||
icon_state = "pdw"
|
||||
item_state = "c20r" // Placeholder
|
||||
w_class = 3
|
||||
caliber = "9mm"
|
||||
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2)
|
||||
slot_flags = SLOT_BELT
|
||||
load_method = MAGAZINE
|
||||
magazine_type = /obj/item/ammo_magazine/mc9mml
|
||||
allowed_magazines = list(/obj/item/ammo_magazine/mc9mm, /obj/item/ammo_magazine/mc9mml)
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
|
||||
list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=6, burst_accuracy=list(0,-1,-2), dispersion=list(0.0, 0.6, 0.6))
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/pdw/update_icon(var/ignore_inhands)
|
||||
..()
|
||||
if(istype(ammo_magazine,/obj/item/ammo_magazine/mc9mm))
|
||||
icon_state = "pdw-short"
|
||||
else
|
||||
icon_state = (ammo_magazine)? "pdw" : "pdw-empty"
|
||||
if(!ignore_inhands) update_held_icon()
|
||||
|
||||
|
||||
//Currently, the only problem I have now is that this weapon's item_state isn't working.
|
||||
/obj/item/weapon/gun/projectile/automatic/fluff/crestrose
|
||||
name = "Crescent Rose"
|
||||
desc = "Can you match my resolve? If so then you will succeed. I believe that the human spirit is indomitable. Keep Moving Forward. Uses 5.56mm rounds."
|
||||
icon = 'icons/vore/custom_guns_vr.dmi'
|
||||
icon_state = "crestrose_fold"
|
||||
|
||||
icon_override = 'icons/vore/custom_guns_vr.dmi'
|
||||
item_state = "crestrose_fold_mob"
|
||||
|
||||
w_class = 4
|
||||
origin_tech = list(TECH_COMBAT = 7, TECH_MATERIAL = 4)
|
||||
slot_flags = null
|
||||
fire_sound = 'sound/weapons/Gunshot_light.ogg'
|
||||
load_method = MAGAZINE
|
||||
force = 3
|
||||
recoil = 2
|
||||
var/on = 0
|
||||
auto_eject = 1
|
||||
auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg'
|
||||
hitsound = null
|
||||
caliber = "a556"
|
||||
magazine_type = /obj/item/ammo_magazine/a556
|
||||
allowed_magazines = list(/obj/item/ammo_magazine/a556)
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/fluff/crestrose/attack_self(mob/user as mob)
|
||||
on = !on
|
||||
if(on)
|
||||
user.visible_message("<span class='warning'>With a press of a button, [user]'s gun turns into a deadly scythe.</span>",\
|
||||
"<span class='warning'>You extend The Rose's thorns.</span>",\
|
||||
"You hear an ominous click.")
|
||||
icon = 'icons/vore/custom_guns_vr.dmi'
|
||||
icon_state = "crestrose"
|
||||
icon_override = 'icons/vore/custom_guns_vr.dmi'
|
||||
item_state = "crestrose_mob"
|
||||
w_class = 4
|
||||
force = 15//Obscenely robust
|
||||
attack_verb = list("slashed", "cut", "drives")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
else
|
||||
user.visible_message("<span class='notice'>\The [user] folds the weapon back up into a gun.</span>",\
|
||||
"<span class='notice'>You fold up the weapon.</span>",\
|
||||
"You hear a click.")
|
||||
icon = 'icons/vore/custom_guns_vr.dmi'
|
||||
icon_state = "crestrose_fold"
|
||||
icon_override = 'icons/vore/custom_guns_vr.dmi'
|
||||
item_state = "crestrose_fold_mob"
|
||||
w_class = 3
|
||||
force = 3//Not so obscenely robust
|
||||
attack_verb = list("hit", "melee'd")
|
||||
hitsound = null
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/fluff/crestrose/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
|
||||
if(default_parry_check(user, attacker, damage_source) && prob(50))
|
||||
user.visible_message("<span class='danger'>\The [user] parries [attack_text] with \the [src]!</span>")
|
||||
playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// molenar:Kari Akiren
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/rifle/fluff/kari_akiren
|
||||
name = "clockwork rifle"
|
||||
desc = "Brass, copper, and lots of gears. Well lubricated for fluid movement as each round is loaded, locked, and fired. Just like clockwork."
|
||||
|
||||
icon = 'icons/vore/custom_guns_vr.dmi'
|
||||
icon_state = "clockworkrifle"
|
||||
|
||||
icon_override = 'icons/vore/custom_guns_vr.dmi'
|
||||
item_state = "clockworkrifle"
|
||||
item_icons = null
|
||||
|
||||
//Razerwing:Archer Maximus
|
||||
/obj/item/weapon/gun/projectile/colt/fluff/archercolt
|
||||
name = "\improper MEUSOC .45"
|
||||
desc = "Some serious drywall work, coming up!"
|
||||
|
||||
//////////////////// Energy Weapons ////////////////////
|
||||
//arokha:Aronai Kadigan
|
||||
/obj/item/weapon/gun/energy/gun/fluff/aro
|
||||
name = "\improper KIN-H21"
|
||||
desc = "The Kitsuhana Heavy Industries standard Imperial Navy energy sidearm, commonly called the KIN21. This one appears to have been modified to have additional features at the cost of battery life."
|
||||
|
||||
icon = 'icons/vore/custom_guns_vr.dmi'
|
||||
icon_state = "kinh21stun100"
|
||||
|
||||
item_state = "laser"
|
||||
|
||||
modifystate = "kinh21stun"
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/stun/kin21
|
||||
|
||||
max_shots = 8
|
||||
charge_cost = 125
|
||||
charge_meter = 1
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/kin21, modifystate="kinh21stun", fire_sound='sound/weapons/Taser.ogg'),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="kinh21kill", fire_sound='sound/weapons/blaster_pistol.ogg'),
|
||||
list(mode_name="shrink", projectile_type=/obj/item/projectile/beam/shrinklaser, modifystate="kinh21shrink", fire_sound='sound/weapons/wave.ogg'),
|
||||
list(mode_name="grow", projectile_type=/obj/item/projectile/beam/growlaser, modifystate="kinh21grow", fire_sound='sound/weapons/pulse3.ogg'),
|
||||
)
|
||||
|
||||
// -------------- Dominator -------------
|
||||
/obj/item/weapon/gun/energy/gun/fluff/dominator
|
||||
name = "\improper MWPSB Dominator"
|
||||
desc = "A MWPSB's Dominator from the Federation. Like the basic Energy Gun, this gun has two settings. It is used by the United Federation Public Safety Bureau's Criminal Investigation Division."
|
||||
|
||||
icon = 'icons/vore/custom_guns_vr.dmi'
|
||||
icon_state = "dominatorstun100"
|
||||
|
||||
icon_override = 'icons/vore/custom_guns_vr.dmi'
|
||||
item_state = null
|
||||
item_icons = null
|
||||
|
||||
fire_sound = 'sound/weapons/Taser.ogg'
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
|
||||
modifystate = "dominatorstun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", charge_cost=100,projectile_type=/obj/item/projectile/beam/stun, modifystate="dominatorstun", fire_sound='sound/weapons/Taser.ogg'),
|
||||
list(mode_name="lethal", charge_cost=125,projectile_type=/obj/item/projectile/beam/dominator, modifystate="dominatorkill", fire_sound='sound/weapons/gauss_shoot.ogg'),
|
||||
)
|
||||
|
||||
// ------------ Energy Luger ------------
|
||||
/obj/item/weapon/gun/energy/gun/eluger
|
||||
name = "energy Luger"
|
||||
desc = "The finest sidearm produced by RauMauser, this pistol can punch a hole through inch thick steel plating. This ain't your great-grand-daddy's Luger! Can switch between stun and kill."
|
||||
|
||||
icon = 'icons/obj/gun_vr.dmi'
|
||||
icon_state = "elugerstun100"
|
||||
|
||||
item_state = "gun"
|
||||
|
||||
charge_cost = 100 //How much energy is needed to fire.
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
|
||||
modifystate = "elugerstun"
|
||||
fire_sound = 'sound/weapons/Taser.ogg'
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", charge_cost=100,projectile_type=/obj/item/projectile/beam/stun, modifystate="elugerstun", fire_sound='sound/weapons/Taser.ogg'),
|
||||
list(mode_name="lethal", charge_cost=200,projectile_type=/obj/item/projectile/beam/eluger, modifystate="elugerkill", fire_sound='sound/weapons/eluger.ogg'),
|
||||
)
|
||||
|
||||
//////////////////// Custom Ammo ////////////////////
|
||||
//---------------- Beams ----------------
|
||||
/obj/item/projectile/beam/eluger
|
||||
name = "laser beam"
|
||||
icon_state = "emitter"
|
||||
|
||||
/obj/item/projectile/beam/dominator
|
||||
name = "dominator lethal beam"
|
||||
icon_state = "xray"
|
||||
muzzle_type = /obj/effect/projectile/xray/muzzle
|
||||
tracer_type = /obj/effect/projectile/xray/tracer
|
||||
impact_type = /obj/effect/projectile/xray/impact
|
||||
|
||||
/obj/item/projectile/beam/stun/kin21
|
||||
name = "kinh21 stun beam"
|
||||
icon_state = "omnilaser"
|
||||
muzzle_type = /obj/effect/projectile/laser_omni/muzzle
|
||||
tracer_type = /obj/effect/projectile/laser_omni/tracer
|
||||
impact_type = /obj/effect/projectile/laser_omni/impact
|
||||
|
||||
//--------------- StG-60 ----------------
|
||||
/obj/item/ammo_magazine/stg
|
||||
name = "box mag (7.92x33mm Kurz)"
|
||||
icon = 'icons/obj/ammo_vr.dmi'
|
||||
icon_state = "stg_30rnd"
|
||||
caliber = "kurz"
|
||||
ammo_type = /obj/item/ammo_casing/stg
|
||||
max_ammo = 30
|
||||
mag_type = MAGAZINE
|
||||
|
||||
/obj/item/ammo_casing/stg
|
||||
desc = "A 7.92×33mm Kurz casing."
|
||||
icon_state = "rifle-casing"
|
||||
caliber = "kurz"
|
||||
projectile_type = /obj/item/projectile/bullet/rifle/a762
|
||||
|
||||
/obj/item/ammo_magazine/stg/empty
|
||||
initial_ammo = 0
|
||||
|
||||
//------------- Battlerifle -------------
|
||||
/obj/item/ammo_magazine/battlerifle
|
||||
name = "box mag (9.5x40mm)"
|
||||
icon = 'icons/obj/ammo_vr.dmi'
|
||||
icon_state = "battlerifle"
|
||||
caliber = "9.5x40mm"
|
||||
ammo_type = /obj/item/ammo_casing/a95mm
|
||||
max_ammo = 36
|
||||
mag_type = MAGAZINE
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_casing/a95mm
|
||||
desc = "A 9.5x40mm bullet casing."
|
||||
icon_state = "rifle-casing"
|
||||
caliber = "9.5x40mm"
|
||||
projectile_type = /obj/item/projectile/bullet/rifle/a95mm
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a95mm
|
||||
damage = 40
|
||||
penetrating = 2 // Better penetration than the 7.62mm
|
||||
|
||||
/obj/item/ammo_magazine/battlerifle/empty
|
||||
initial_ammo = 0
|
||||
|
||||
//---------------- PDW ------------------
|
||||
/obj/item/ammo_magazine/mc9mml
|
||||
name = "\improper SMG magazine (9mm)"
|
||||
icon = 'icons/obj/ammo_vr.dmi'
|
||||
icon_state = "smg"
|
||||
origin_tech = list(TECH_COMBAT = 2)
|
||||
mag_type = MAGAZINE
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 1800)
|
||||
caliber = "9mm"
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
max_ammo = 30
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/mc9mml/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/mc9mml/ap
|
||||
name = "\improper SMG magazine (9mm armor-piercing)"
|
||||
ammo_type = /obj/item/ammo_casing/c9mm/ap
|
||||
|
||||
/obj/item/ammo_magazine/mc9mml/flash
|
||||
name = "\improper SMG magazine (9mm flash)"
|
||||
ammo_type = /obj/item/ammo_casing/c9mmf
|
||||
|
||||
/obj/item/ammo_magazine/mc9mml/rubber
|
||||
name = "\improper SMG magazine (9mm rubber)"
|
||||
ammo_type = /obj/item/ammo_casing/c9mmr
|
||||
|
||||
/obj/item/ammo_magazine/mc9mml/practice
|
||||
name = "\improper SMG magazine (9mm practice)"
|
||||
ammo_type = /obj/item/ammo_casing/c9mmp
|
||||
@@ -1,345 +0,0 @@
|
||||
/* TUTORIAL
|
||||
"icon" is the file with the HUD/ground icon for the item
|
||||
"icon_state" is the iconstate in this file for the item
|
||||
"icon_override" is the file with the on-mob icons, can be the same file
|
||||
"item_state" is the iconstate for the on-mob icons:
|
||||
item_state_s is used for worn uniforms on mobs
|
||||
item_state_r and item_state_l are for being held in each hand
|
||||
|
||||
"item_state_slots" can replace "item_state", it is a list:
|
||||
item_state_slots["slotname1"] = "item state for that slot"
|
||||
item_state_slots["slotname2"] = "item state for that slot"
|
||||
*/
|
||||
|
||||
/* TEMPLATE
|
||||
//ckey:Character Name
|
||||
/obj/item/weapon/fluff/charactername
|
||||
name = ""
|
||||
desc = ""
|
||||
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "myicon"
|
||||
|
||||
icon_override = 'icons/vore/custom_items_vr.dmi'
|
||||
item_state = "myicon"
|
||||
|
||||
*/
|
||||
|
||||
//For general use
|
||||
/obj/item/device/modkit_conversion
|
||||
name = "modification kit"
|
||||
desc = "A kit containing all the needed tools and parts to modify a suit and helmet."
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "modkit"
|
||||
var/parts = 3
|
||||
var/from_helmet = /obj/item/clothing/head/helmet/space/void
|
||||
var/from_suit = /obj/item/clothing/suit/space/void
|
||||
var/to_helmet = /obj/item/clothing/head/cardborg
|
||||
var/to_suit = /obj/item/clothing/suit/cardborg
|
||||
|
||||
//Conversion proc
|
||||
afterattack(obj/O, mob/user as mob)
|
||||
var/flag
|
||||
var/to_type
|
||||
if(istype(O,from_helmet))
|
||||
flag = 1
|
||||
to_type = to_helmet
|
||||
else if(istype(O,from_suit))
|
||||
flag = 2
|
||||
to_type = to_suit
|
||||
else
|
||||
return
|
||||
if(!(parts & flag))
|
||||
user << "<span class='warning'>This kit has no parts for this modification left.</span>"
|
||||
return
|
||||
if(istype(O,to_type))
|
||||
user << "<span class='notice'>[O] is already modified.</span>"
|
||||
return
|
||||
if(!isturf(O.loc))
|
||||
user << "<span class='warning'>[O] must be safely placed on the ground for modification.</span>"
|
||||
return
|
||||
playsound(user.loc, 'sound/items/Screwdriver.ogg', 100, 1)
|
||||
var/N = new to_type(O.loc)
|
||||
user.visible_message("<span class='warning'>[user] opens \the [src] and modifies \the [O] into \the [N].</span>","<span class='warning'>You open \the [src] and modify \the [O] into \the [N].</span>")
|
||||
qdel(O)
|
||||
parts &= ~flag
|
||||
if(!parts)
|
||||
qdel(src)
|
||||
|
||||
//JoanRisu:Joan Risu
|
||||
/obj/item/weapon/flame/lighter/zippo/fluff/joan
|
||||
name = "Federation Zippo Lighter"
|
||||
desc = "A red zippo lighter with the United Federation Logo on it."
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "joanzip"
|
||||
|
||||
//JoanRisu:Joan Risu
|
||||
/obj/item/weapon/sword/fluff/joanaria
|
||||
name = "Aria"
|
||||
desc = "A beautifully crafted rapier owned by Joan Risu. It has a thin blade and is used for quick attacks."
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "joanaria"
|
||||
icon_override = 'icons/vore/custom_items_vr.dmi'
|
||||
item_state = "joanariamob"
|
||||
origin_tech = "materials=7"
|
||||
force = 15
|
||||
sharp = 1
|
||||
edge = 1
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
|
||||
/obj/item/weapon/sword/fluff/joanaria/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
|
||||
|
||||
if(default_parry_check(user, attacker, damage_source) && prob(75))
|
||||
user.visible_message("<span class='danger'>\The [user] parries [attack_text] with \the [src]!</span>")
|
||||
playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//joanrisu:Katarina Eine
|
||||
/obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina
|
||||
name = "tactical Knife"
|
||||
desc = "A tactical knife with a small butterly engraved on the blade."
|
||||
|
||||
obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
|
||||
|
||||
if(default_parry_check(user, attacker, damage_source) && prob(75))
|
||||
user.visible_message("<span class='danger'>\The [user] parries [attack_text] with \the [src]!</span>")
|
||||
playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//For General use
|
||||
/obj/item/weapon/sword/fluff/joanaria/scisword
|
||||
name = "Scissor Blade"
|
||||
desc = "A sword that can not only cut down your enemies, it can also cut fabric really neatly"
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "scisword"
|
||||
origin_tech = "materials=7"
|
||||
|
||||
|
||||
//john.wayne9392:Harmony Prechtl
|
||||
/obj/item/weapon/twohanded/fireaxe/fluff/mjollnir
|
||||
name = "Mjollnir"
|
||||
desc = "Large hammer that looks like it can do a great deal of damage if properly used."
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "harmonymjollnir"
|
||||
origin_tech = "materials=7"
|
||||
attack_verb = list("attacked", "hammered", "smashed", "slammed", "crushed")
|
||||
|
||||
//JoanRisu:Joan Risu
|
||||
/obj/item/weapon/card/id/centcom/fluff/joanbadge
|
||||
name = "Faded Badge"
|
||||
desc = "A faded badge, backed with leather, that reads 'NT Security Force' across the front."
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "joanbadge"
|
||||
registered_name = "Joan Risu"
|
||||
assignment = "Centcom Officer"
|
||||
|
||||
|
||||
attack_self(mob/user as mob)
|
||||
if(isliving(user))
|
||||
user.visible_message("<span class='warning'>[user] flashes their golden security badge.\nIt reads:NT Security.</span>","<span class='warning'>You display the faded badge.\nIt reads: NT Security.</span>")
|
||||
|
||||
attack(mob/living/carbon/human/M, mob/living/user)
|
||||
if(isliving(user))
|
||||
user.visible_message("<span class='warning'>[user] invades [M]'s personal space, thrusting [src] into their face insistently.</span>","<span class='warning'>You invade [M]'s personal space, thrusting [src] into their face insistently.</span>")
|
||||
|
||||
//JoanRisu:Joan Risu
|
||||
/obj/item/device/pda/heads/hos/fluff/joanpda
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "pda-joan"
|
||||
|
||||
//Vorrarkul:Lucina Dakarim
|
||||
/obj/item/device/pda/heads/hos/fluff/lucinapda
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "pda-lucina"
|
||||
|
||||
//john.wayne9392:Harmony Prechtl
|
||||
/obj/item/device/modkit_conversion/fluff/harmonyspace
|
||||
name = "Harmony's captain space suit modkit"
|
||||
desc = "A kit containing all the needed tools and parts to modify a Captain's hardsuit. It has green and yellow parts inside."
|
||||
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "harmony_kit"
|
||||
|
||||
from_helmet = /obj/item/clothing/head/helmet/space/capspace
|
||||
from_suit = /obj/item/clothing/suit/armor/captain
|
||||
to_helmet = /obj/item/clothing/head/helmet/space/capspace/fluff/harmhelm
|
||||
to_suit = /obj/item/clothing/suit/armor/captain/fluff/harmsuit
|
||||
|
||||
//john.wayne9392:Harmony Prechtl
|
||||
/obj/item/device/modkit_conversion/fluff/harmonysuit
|
||||
name = "Harmony's captain suit modkit"
|
||||
desc = "A sewing kit containing all the needed tools and fabric to modify a Captain's suit and hat. It has green and yellow fabrics inside."
|
||||
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "harmony_kit"
|
||||
|
||||
from_helmet = /obj/item/clothing/head/caphat
|
||||
from_suit = /obj/item/clothing/under/rank/captain
|
||||
to_helmet = /obj/item/clothing/head/centhat/fluff/harmhat
|
||||
to_suit = /obj/item/clothing/under/rank/captain/fluff/harmuniform
|
||||
|
||||
//scree:Scree
|
||||
/obj/item/device/modkit_conversion/fluff/screekit
|
||||
name = "Scree's hardsuit modification kit"
|
||||
desc = "A kit containing all the needed tools and parts to modify a hardsuit for a specific user. This one looks like it's fitted for a winged creature."
|
||||
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "modkit"
|
||||
|
||||
from_helmet = /obj/item/clothing/head/helmet/space/void/engineering
|
||||
from_suit = /obj/item/clothing/suit/space/void/engineering
|
||||
to_helmet = /obj/item/clothing/head/helmet/space/void/engineering/fluff/screehelm
|
||||
to_suit = /obj/item/clothing/suit/space/void/engineering/fluff/screespess
|
||||
|
||||
//General Use
|
||||
/obj/item/weapon/flag
|
||||
name = "Nanotrasen Banner"
|
||||
desc = "I pledge allegiance to the flag of a megacorporation in space."
|
||||
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "Flag_Nanotrasen"
|
||||
|
||||
icon_override = 'icons/vore/custom_items_vr.dmi'
|
||||
item_state = "Flag_Nanotrasen_mob"
|
||||
|
||||
attack_self(mob/user as mob)
|
||||
if(isliving(user))
|
||||
user.visible_message("<span class='warning'>[user] waves their Banner around!</span>","<span class='warning'>You wave your Banner around.</span>")
|
||||
|
||||
attack(mob/living/carbon/human/M, mob/living/user)
|
||||
if(isliving(user))
|
||||
user.visible_message("<span class='warning'>[user] invades [M]'s personal space, thrusting [src] into their face insistently.</span>","<span class='warning'>You invade [M]'s personal space, thrusting [src] into their face insistently.</span>")
|
||||
|
||||
|
||||
federation
|
||||
name = "Federation Banner"
|
||||
desc = "Space, The Final Frontier. Sorta. Just go with it and say the damn oath."
|
||||
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "flag_federation"
|
||||
|
||||
icon_override = 'icons/vore/custom_items_vr.dmi'
|
||||
item_state = "flag_federation_mob"
|
||||
|
||||
xcom
|
||||
name = "Alien Combat Command Banner"
|
||||
desc = "A banner bearing the symbol of a task force fighting an unknown alien power."
|
||||
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "flag_xcom"
|
||||
|
||||
icon_override = 'icons/vore/custom_items_vr.dmi'
|
||||
item_state = "flag_xcom_mob"
|
||||
|
||||
advent
|
||||
name = "ALIEN Coalition Banner"
|
||||
desc = "A banner belonging to traitors who work for an unknown alien power."
|
||||
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "flag_advent"
|
||||
|
||||
icon_override = 'icons/vore/custom_items_vr.dmi'
|
||||
item_state = "flag_advent_mob"
|
||||
|
||||
|
||||
//zodiacshadow: ?
|
||||
/obj/item/device/radio/headset/fluff/zodiacshadow
|
||||
name = "Nehi's 'phones"
|
||||
desc = "A pair of old-fashioned purple headphones for listening to music that also double as an NT-approved headset; they connect nicely to any standard PDA. One side is engraved with the letters NEHI, the other having an elaborate inscription of the words \"My voice is my weapon of choice\" in a fancy font. A modern polymer allows switching between modes to either allow one to hear one's surroundings or to completely block them out."
|
||||
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "headphones"
|
||||
|
||||
icon_override = 'icons/vore/custom_items_vr.dmi'
|
||||
item_state = "headphones_mob"
|
||||
|
||||
|
||||
// OrbisA: Richard D'angelo
|
||||
/obj/item/weapon/melee/fluff/holochain
|
||||
name = "Holographic Chain"
|
||||
desc = "A High Tech solution to simple perversions. It has a red leather handle and the initials R.D. on the silver base."
|
||||
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "holochain"
|
||||
|
||||
icon_override = 'icons/vore/custom_items_vr.dmi'
|
||||
item_state = "holochain_mob"
|
||||
|
||||
flags = CONDUCT | NOBLOODY
|
||||
no_attack_log = 1 //if you want to turn on the attack log for this, comment/delete this line. Orbis.
|
||||
slot_flags = SLOT_BELT
|
||||
force = 10
|
||||
throwforce = 3
|
||||
w_class = 3
|
||||
damtype = HALLOSS
|
||||
attack_verb = list("flogged", "whipped", "lashed", "disciplined", "chastised", "flayed")
|
||||
|
||||
// joey4298:Emoticon
|
||||
/obj/item/device/fluff/id_kit_mime
|
||||
name = "Mime ID reprinter"
|
||||
desc = "Stick your ID in one end and it'll print a new ID out the other!"
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "labeler1"
|
||||
|
||||
afterattack(obj/O, mob/user as mob)
|
||||
var/new_icon = "mime"
|
||||
if(istype(O,/obj/item/weapon/card/id) && O.icon_state != new_icon)
|
||||
//O.icon = src.icon // just in case we're using custom sprite paths with fluff items.
|
||||
O.icon_state = new_icon // Changes the icon without changing the access.
|
||||
playsound(user.loc, 'sound/items/polaroid2.ogg', 100, 1)
|
||||
user.visible_message("<span class='warning'> [user] reprints their ID.</span>")
|
||||
del(src)
|
||||
else if(O.icon_state == new_icon)
|
||||
user << "<span class='notice'>[O] already has been reprinted.</span>"
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>This isn't even an ID card you idiot.</span>"
|
||||
return
|
||||
|
||||
//arokha:Aronai Kadigan
|
||||
/obj/item/weapon/card/id/centcom/fluff/aro
|
||||
registered_name = "CONFIGURE ME"
|
||||
assignment = "CC Medical"
|
||||
var/configured = 0
|
||||
|
||||
attack_self(mob/user as mob)
|
||||
if(configured == 1) return ..()
|
||||
|
||||
user.set_id_info(src)
|
||||
configured = 1
|
||||
user << "<span class='notice'>Card settings set.</span>"
|
||||
|
||||
//arokha:Aronai Kadigan
|
||||
/obj/item/weapon/reagent_containers/hypospray/fluff/aronai
|
||||
name = "worn hypospray"
|
||||
desc = "This hypospray seems a bit well-used. The blue band indicates it's from the CentCom medical division. There's an 'A' scratched into the bottom."
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "aro_hypo"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("inaprovaline", 5)
|
||||
reagents.add_reagent("tricordrazine", 25)
|
||||
|
||||
//Swat43:Fortune Bloise
|
||||
/obj/item/weapon/storage/backpack/satchel/fluff/swat43bag
|
||||
name = "Coloured Satchel"
|
||||
desc = "That's a coloured satchel with red stripes, with a heart and ripley logo on each side."
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "swat43-bag"
|
||||
|
||||
icon_override = 'icons/vore/custom_items_vr.dmi'
|
||||
item_state = "swat43-bag_mob"
|
||||
|
||||
|
||||
//Dhaeleena:Dhaeleena M'iar
|
||||
/obj/item/clothing/accessory/medal/silver/security/fluff/dhael
|
||||
desc = "An award for distinguished combat and sacrifice in defence of corporate commercial interests. Often awarded to security staff. It's engraved with the letters S.W.A.T."
|
||||
|
||||
//Vorrarkul:Lucina Dakarim
|
||||
/obj/item/clothing/accessory/medal/gold/fluff/lucina
|
||||
name = "Medal of Medical Excellence"
|
||||
desc = "A medal awarded to Lucina Darkarim for excellence in medical service."
|
||||
@@ -1,130 +0,0 @@
|
||||
// BEGIN - DO NOT EDIT PROTOTYPE
|
||||
/obj/item/fluff/permit
|
||||
name = "Sample Permit"
|
||||
desc = {"There is a bright red <b><font color=red>SAMPLE PERMIT</font></b> stamped across the stock photo displayed on the card. Obviously this is only an example to educate security.
|
||||
<b>NAME:</b> First Last | <b>RACE:</b> Human | <b>HOMEWORLD:</b> Moon (if applicable), Planet, System
|
||||
<b>DOB:</b> DD/Mon/YYYY | <b>HEIGHT:</b> XXcm | <b>SEX:</b> Female
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to ___________________.
|
||||
This license expires on DD/Month/YYYY and must be renewed by CentCom prior to this date."}
|
||||
icon = 'icons/obj/card.dmi'
|
||||
icon_state = "guest"
|
||||
w_class = 1
|
||||
// END - DO NOT EDIT PROTOTYPE
|
||||
|
||||
/* TEMPLATE
|
||||
/obj/item/fluff/permit/charactername
|
||||
name = "Name's Thing Permit"
|
||||
desc = {"
|
||||
<b>NAME:</b> Firstname Lastname | <b>RACE:</b> Human | <b>HOMEWORLD:</b> Earth, Sol
|
||||
<b>DOB:</b> DD/Mon/YYYY | <b>HEIGHT:</b> XXXcm | <b>SEX:</b> X
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to openly carry XYZ. CONDITIONS.
|
||||
This license expires on DD/Mon/YYYY and must be renewed by CentCom prior to this date."}
|
||||
*/
|
||||
|
||||
// bwoincognito:Tasald Corlethian
|
||||
/obj/item/fluff/permit/tasald_corlethian
|
||||
name = "Tasald Ajax Corlethian's Sidearm Permit"
|
||||
desc = {"
|
||||
<b>NAME:</b> Tasald Ajax Corlethian | <b>RACE:</b> Vulpine | <b>HOMEWORLD:</b> Iscyn, Orta
|
||||
<b>DOB:</b> 09/Sep/2529 | <b>HEIGHT:</b> 187cm | <b>SEX:</b> Male
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one .38 pistol.
|
||||
This license expires on 30/March/2561 and must be renewed by CentCom prior to this date."}
|
||||
|
||||
/*
|
||||
// jertheace:Jeremiah 'Ace' Acacius
|
||||
/obj/item/fluff/permit/jerace
|
||||
name = "Ace's Shotgun Permit"
|
||||
desc = {"
|
||||
<b>NAME:</b> Jeremiah Acacius | <b>RACE:</b> Human | <b>HOMEWORLD:</b> Earth, Sol
|
||||
<b>DOB:</b> 17/Jun/2532 | <b>HEIGHT:</b> 178cm | <b>SEX:</b> Male
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to openly carry one M45D shotgun loaded with less-than-lethal munitions as a head of staff. Else this weapon is to be turned in to security for holding until the end of the shift.
|
||||
This license expires on 01/Jun/2560 and must be renewed by CentCom prior to this date."}
|
||||
*/
|
||||
|
||||
/*
|
||||
// sasoperative:Joseph Skinner
|
||||
/obj/item/fluff/permit/josephskinner
|
||||
name = "Joseph Skinner's 12g Revolver Permit"
|
||||
desc = {"
|
||||
<b>NAME:</b> Joseph Cyrus Skinner | <b>RACE:</b> Human | <b>HOMEWORLD:</b> Earth, Sol
|
||||
<b>DOB:</b> 10/Jun/2532 | <b>HEIGHT:</b> 162.5cm | <b>SEX:</b> Male
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one 12 gauge revolver loaded with less-than-lethal munitions as a member of security or head of staff. Else this weapon is to be turned in to security for holding until the end of the shift.
|
||||
This license expires on 29/Nov/2559 and must be renewed by CentCom prior to this date."}
|
||||
*/
|
||||
|
||||
/*
|
||||
// wankersonofjerkin:Ryan Winz
|
||||
/obj/item/fluff/permit/ryanwinz
|
||||
name = "Ryan Winz's Revolver Permit"
|
||||
desc = {"
|
||||
<b>NAME:</b> Ryan Winz | <b>RACE:</b> Human | <b>HOMEWORLD:</b> New Ekaterina, Moskva
|
||||
<b>DOB:</b> 27/Oct/2536 | <b>HEIGHT:</b> 172cm | <b>SEX:</b> Male
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to openly carry one Colt Single-Action Army revolver as a security officer or head of staff. Else this weapon is to be turned in to security for holding until the end of the shift.
|
||||
This license expires on 26/Dec/2559 and must be renewed by CentCom prior to this date."}
|
||||
*/
|
||||
|
||||
// bwoincognito:Tasald Corlethian
|
||||
/obj/item/fluff/permit/tasald_corlethian
|
||||
name = "Tasald Ajax Corlethian's Sidearm Permit"
|
||||
desc = {"
|
||||
<b>NAME:</b> Tasald Ajax Corlethian | <b>RACE:</b> Vulpine | <b>HOMEWORLD:</b> Iscyn, Orta
|
||||
<b>DOB:</b> 09/Sep/2529 | <b>HEIGHT:</b> 187cm | <b>SEX:</b> Male
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one .38 pistol.
|
||||
This license expires on 30/March/2561 and must be renewed by CentCom prior to this date."}
|
||||
|
||||
// arokha:Aronai Kadigan
|
||||
/obj/item/fluff/permit/aronai_kadigan
|
||||
name = "Aronai Kadigan's Sidearm Permit"
|
||||
desc = {"
|
||||
<b>NAME:</b> Aronai Kadigan | <b>RACE:</b> Cross Fox | <b>HOMEWORLD:</b> New Kitsuhana, KHI1
|
||||
<b>DOB:</b> 12/Jul/2530 | <b>HEIGHT:</b> 188cm | <b>SEX:</b> Male
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one KIN-H21 (Egun Variant).
|
||||
This license expires on 30/Sep/2560 and must be renewed by CentCom prior to this date."}
|
||||
|
||||
// joanrisu:Joan Risu
|
||||
/obj/item/fluff/permit/joanrisu
|
||||
name = "Joan Risu's Sidearm Permit"
|
||||
desc = {"
|
||||
<b>NAME:</b> Joan Risu | <b>RACE:</b> Squirrelkin | <b>HOMEWORLD:</b> Luna, Gaia, Koi
|
||||
<b>DOB:</b> 16/Apr/2536 | <b>HEIGHT:</b> 161cm | <b>SEX:</b> Female
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one MWPSB Dominator.
|
||||
This license expires on 11/Dec/2560 and must be renewed by CentCom prior to this date."}
|
||||
|
||||
// molenar:Kari Akiren
|
||||
/obj/item/fluff/permit/kari_akiren
|
||||
name = "Kari Akiren's Rifle Permit"
|
||||
desc = {"
|
||||
<b>NAME:</b> Kari Akiren | <b>RACE:</b> Inkling | <b>HOMEWORLD:</b> Supesu
|
||||
<b>DOB:</b> 26-Jun-2553 | <b>HEIGHT:</b> 163cm | <b>SEX:</b> Female
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one Clockwork Rifle (bolt-action variant).
|
||||
This license expires on 14/Dec/2560 and must be renewed by CentCom prior to this date."}
|
||||
|
||||
//eekasqueak: Serkii Miishy
|
||||
/obj/item/fluff/permit/serkiimiishy
|
||||
name = "Serkii Miishy's Stun Revolver Permit"
|
||||
desc = {"
|
||||
<b>NAME:</b> Serkii Miishy | <b>RACE:</b> Mousemorph | <b>HOMEWORLD:</b> Mars, Sol
|
||||
<b>DOB:</b> 10/9/2441 | <b>HEIGHT:</b> 122cm | <b>SEX:</b> Male
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one stun revolver.
|
||||
This license expires on 30/March/2561 and must be renewed by CentCom prior to this date."}
|
||||
|
||||
//Razerwing:Archer Maximus
|
||||
/obj/item/fluff/permit/archermaximus
|
||||
name = "Archer Maximus's MEUSOC 45 Permit"
|
||||
desc = {"
|
||||
<b>NAME:</b> FArcher Maximus | <b>RACE:</b> Human | <b>HOMEWORLD:</b> Charybdis
|
||||
<b>DOB:</b> 04/18/2521 | <b>HEIGHT:</b> 172.7cm | <b>SEX:</b> female
|
||||
|
||||
The individual named above is licensed by the Nanotrasen Department of Civil Protection to openly carry a MEUSOC 45. CONDITIONS.
|
||||
This license expires on 31/May/2561 and must be renewed by CentCom prior to this date."}
|
||||
@@ -1,37 +0,0 @@
|
||||
//The base hooks themselves
|
||||
|
||||
//New() hooks
|
||||
/hook/client_new
|
||||
|
||||
/hook/mob_new
|
||||
|
||||
/hook/living_new
|
||||
|
||||
/hook/carbon_new
|
||||
|
||||
/hook/human_new
|
||||
|
||||
/hook/simple_animal_new
|
||||
|
||||
//Hooks for interactions
|
||||
/hook/living_attackby
|
||||
|
||||
//
|
||||
//Hook helpers to expand hooks to others
|
||||
//
|
||||
/hook/mob_new/proc/chain_hooks(mob/M)
|
||||
var/result = 1
|
||||
if(isliving(M))
|
||||
if(!hook_vr("living_new",args))
|
||||
result = 0
|
||||
|
||||
if(iscarbon(M))
|
||||
if(!hook_vr("carbon_new",args))
|
||||
result = 0
|
||||
|
||||
if(ishuman(M))
|
||||
if(!hook_vr("human_new",args))
|
||||
result = 0
|
||||
|
||||
//Return 1 to superhook
|
||||
return result
|
||||
@@ -1,63 +0,0 @@
|
||||
//
|
||||
// Gravity Pull effect which draws in movable objects to its center.
|
||||
// In this case, "number" refers to the range. directions is ignored.
|
||||
//
|
||||
/datum/effect/effect/system/grav_pull
|
||||
var/pull_radius = 3
|
||||
var/pull_anchored = 0
|
||||
var/break_windows = 0
|
||||
|
||||
/datum/effect/effect/system/grav_pull/set_up(range, num, loca)
|
||||
pull_radius = range
|
||||
number = num
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
|
||||
/datum/effect/effect/system/grav_pull/start()
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
for(var/i=0, i < number, i++)
|
||||
do_pull()
|
||||
sleep(25)
|
||||
|
||||
/datum/effect/effect/system/grav_pull/proc/do_pull()
|
||||
//following is adapted from supermatter and singulo code
|
||||
if(defer_powernet_rebuild != 2)
|
||||
defer_powernet_rebuild = 1
|
||||
|
||||
// Let's just make this one loop.
|
||||
for(var/atom/X in orange(pull_radius, location))
|
||||
// Movable atoms only
|
||||
if(istype(X, /atom/movable))
|
||||
if(istype(X, /obj/effect/overlay)) continue
|
||||
if(X && !istype(X, /mob/living/carbon/human))
|
||||
if(break_windows && istype(X, /obj/structure/window)) //shatter windows
|
||||
var/obj/structure/window/W = X
|
||||
W.ex_act(2.0)
|
||||
|
||||
if(istype(X, /obj))
|
||||
var/obj/O = X
|
||||
if(O.anchored)
|
||||
if (!pull_anchored) continue // Don't pull anchored stuff unless configured
|
||||
step_towards(X, location) // step just once if anchored
|
||||
continue
|
||||
|
||||
step_towards(X, location) // Step twice
|
||||
step_towards(X, location)
|
||||
|
||||
else if(istype(X,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = X
|
||||
if(istype(H.shoes,/obj/item/clothing/shoes/magboots))
|
||||
var/obj/item/clothing/shoes/magboots/M = H.shoes
|
||||
if(M.magpulse)
|
||||
step_towards(H, location) //step just once with magboots
|
||||
continue
|
||||
step_towards(H, location) //step twice
|
||||
step_towards(H, location)
|
||||
|
||||
if(defer_powernet_rebuild != 2)
|
||||
defer_powernet_rebuild = 0
|
||||
return
|
||||
@@ -1,33 +0,0 @@
|
||||
// Micro Holders - Extends /obj/item/weapon/holder
|
||||
|
||||
/obj/item/weapon/holder/micro
|
||||
name = "micro"
|
||||
desc = "Another crewmember, small enough to fit in your hand."
|
||||
icon_state = "micro"
|
||||
slot_flags = SLOT_FEET | SLOT_HEAD | SLOT_ID
|
||||
w_class = 2
|
||||
item_icons = null // Override value from parent. We don't have magic sprites.
|
||||
pixel_y = 0 // Override value from parent.
|
||||
|
||||
/obj/item/weapon/holder/micro/examine(var/mob/user)
|
||||
for(var/mob/living/M in contents)
|
||||
M.examine(user)
|
||||
|
||||
/obj/item/weapon/holder/MouseDrop(mob/M as mob)
|
||||
..()
|
||||
if(M != usr) return
|
||||
if(usr == src) return
|
||||
if(!Adjacent(usr)) return
|
||||
if(istype(M,/mob/living/silicon/ai)) return
|
||||
for(var/mob/living/carbon/human/O in contents)
|
||||
O.show_inv(usr)
|
||||
|
||||
/obj/item/weapon/holder/micro/attack_self(var/mob/living/user)
|
||||
for(var/mob/living/carbon/human/M in contents)
|
||||
M.help_shake_act(user)
|
||||
|
||||
/obj/item/weapon/holder/micro/update_state()
|
||||
// If any items have been dropped by contained mob, drop them to floor.
|
||||
for(var/obj/O in contents)
|
||||
O.forceMove(get_turf(src))
|
||||
..()
|
||||
@@ -1,197 +0,0 @@
|
||||
|
||||
//these aren't defines so they can stay in this file
|
||||
var/const/RESIZE_HUGE = 2
|
||||
var/const/RESIZE_BIG = 1.5
|
||||
var/const/RESIZE_NORMAL = 1
|
||||
var/const/RESIZE_SMALL = 0.5
|
||||
var/const/RESIZE_TINY = 0.25
|
||||
|
||||
//average
|
||||
var/const/RESIZE_A_HUGEBIG = (RESIZE_HUGE + RESIZE_BIG) / 2
|
||||
var/const/RESIZE_A_BIGNORMAL = (RESIZE_BIG + RESIZE_NORMAL) / 2
|
||||
var/const/RESIZE_A_NORMALSMALL = (RESIZE_NORMAL + RESIZE_SMALL) / 2
|
||||
var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
|
||||
|
||||
// Adding needed defines to /mob/living
|
||||
// Note: Polaris had this on /mob/living/carbon/human We need it higher up for animals and stuff.
|
||||
/mob/living
|
||||
var/size_multiplier = 1 //multiplier for the mob's icon size
|
||||
|
||||
// Define holder_type on types we want to be scoop-able
|
||||
//mob/living/carbon/human
|
||||
// holder_type = /obj/item/weapon/holder/micro
|
||||
|
||||
/**
|
||||
* Scale up the size of a mob's icon by the size_multiplier.
|
||||
* NOTE: mob/living/carbon/human/update_icons() has a more complicated system and
|
||||
* is already applying this transform. BUT, it does not call ..()
|
||||
* as long as that is true, we should be fine. If that changes we need to
|
||||
* re-evaluate.
|
||||
*/
|
||||
/mob/living/update_icons()
|
||||
// ASSERT(!iscarbon(src))
|
||||
var/matrix/M = matrix()
|
||||
M.Scale(size_multiplier)
|
||||
M.Translate(0, 16*(size_multiplier-1))
|
||||
src.transform = M
|
||||
|
||||
/**
|
||||
* Get the effective size of a mob.
|
||||
* Currently this is based only on size_multiplier for micro/macro stuff,
|
||||
* but in the future we may also incorporate the "mob_size", so that
|
||||
* a macro mouse is still only effectively "normal" or a micro dragon is still large etc.
|
||||
*/
|
||||
/mob/living/proc/get_effective_size()
|
||||
return src.size_multiplier
|
||||
|
||||
/**
|
||||
* Resizes the mob immediately to the desired mod, animating it growing/shrinking.
|
||||
* It can be used by anything that calls it.
|
||||
*/
|
||||
/mob/living/proc/resize(var/new_size)
|
||||
var/matrix/resize = matrix() // Defines the matrix to change the player's size
|
||||
resize.Scale(new_size) //Change the size of the matrix
|
||||
|
||||
if(new_size >= RESIZE_NORMAL)
|
||||
resize.Translate(0, -1 * (1 - new_size) * 16) //Move the player up in the tile so their feet align with the bottom
|
||||
|
||||
animate(src, transform = resize, time = 5) //Animate the player resizing
|
||||
size_multiplier = new_size //Change size_multiplier so that other items can interact with them
|
||||
|
||||
/**
|
||||
* Verb proc for a command that lets players change their size OOCly.
|
||||
* Ace was here! Redid this a little so we'd use math for shrinking characters. This is the old code.
|
||||
*/
|
||||
/*
|
||||
/mob/living/proc/set_size()
|
||||
set name = "Set Character Size"
|
||||
set category = "Vore"
|
||||
var/nagmessage = "DO NOT ABUSE THESE COMMANDS. They are not here for you to play with. \
|
||||
We were originally going to remove them but kept them for popular demand. \
|
||||
Do not abuse their existence outside of ERP scenes where they apply, \
|
||||
or reverting OOCly unwanted changes like someone lolshooting the crew with a shrink ray. -Ace"
|
||||
|
||||
var/size_name = input(nagmessage, "Pick a Size") in player_sizes_list
|
||||
if (size_name && player_sizes_list[size_name])
|
||||
src.resize(player_sizes_list[size_name])
|
||||
message_admins("[key_name(src)] used the resize command in-game to be [size_name]. \
|
||||
([src ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>" : "null"])")
|
||||
|
||||
/** Add the set_size() proc to usable verbs. */
|
||||
/hook/living_new/proc/resize_setup(mob/living/M)
|
||||
M.verbs += /mob/living/proc/set_size
|
||||
return 1
|
||||
|
||||
/**
|
||||
* Attempt to scoop up this mob up into M's hands, if the size difference is large enough.
|
||||
* @return false if normal code should continue, 1 to prevent normal code.
|
||||
*/
|
||||
/mob/living/proc/attempt_to_scoop(var/mob/living/carbon/human/M)
|
||||
if(!istype(M))
|
||||
return 0;
|
||||
if(M.buckled)
|
||||
usr << "<span class='notice'>You have to unbuckle \the [M] before you pick them up.</span>"
|
||||
return 0
|
||||
if(M.get_effective_size() - src.get_effective_size() >= 0.75)
|
||||
var/obj/item/weapon/holder/m_holder = get_scooped(M)
|
||||
if (m_holder)
|
||||
return 1
|
||||
else
|
||||
return 0; // Unable to scoop, let other code run
|
||||
*/
|
||||
/**
|
||||
* Handle bumping into someone with helping intent.
|
||||
* Called from /mob/living/Bump() in the 'brohugs all around' section.
|
||||
* @return false if normal code should continue, 1 to prevent normal code.
|
||||
* // TODO - can the now_pushing = 0 be moved up? What does it do anyway?
|
||||
*/
|
||||
/mob/living/proc/handle_micro_bump_helping(var/mob/living/tmob)
|
||||
if(src.get_effective_size() <= RESIZE_A_SMALLTINY && tmob.get_effective_size() <= RESIZE_A_SMALLTINY)
|
||||
// Both small! Go ahead and
|
||||
now_pushing = 0
|
||||
return 1
|
||||
if(abs(src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
|
||||
now_pushing = 0
|
||||
if(src.get_effective_size() > tmob.get_effective_size())
|
||||
// var/mob/living/carbon/human/M = src
|
||||
// if(istype(M) && istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga))
|
||||
// src << "You carefully slither around [tmob]."
|
||||
// tmob << "[src]'s huge tail slithers past beside you!"
|
||||
// else
|
||||
src << "You carefully step over [tmob]."
|
||||
tmob << "[src] steps over you carefully!"
|
||||
if(tmob.get_effective_size() > src.get_effective_size())
|
||||
// var/mob/living/carbon/human/M = tmob
|
||||
// if(istype(M) && istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga))
|
||||
// src << "You jump over [tmob]'s thick tail."
|
||||
// tmob << "[src] bounds over your tail."
|
||||
// else
|
||||
src << "You run between [tmob]'s legs."
|
||||
tmob << "[src] runs between your legs."
|
||||
return 1
|
||||
|
||||
/**
|
||||
* Handle bumping into someone without mutual help intent.
|
||||
* Called from /mob/living/Bump()
|
||||
* NW was here, adding even more options for stomping!
|
||||
*
|
||||
* @return false if normal code should continue, 1 to prevent normal code.
|
||||
*/
|
||||
/mob/living/proc/handle_micro_bump_other(var/mob/living/tmob)
|
||||
ASSERT(istype(tmob)) // Baby don't hurt me
|
||||
|
||||
if(src.a_intent == "disarm" && src.canmove && !src.buckled)
|
||||
// If bigger than them by at least 0.75, move onto them and print message.
|
||||
if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
|
||||
now_pushing = 0
|
||||
src.forceMove(tmob.loc)
|
||||
tmob.Stun(4)
|
||||
|
||||
// var/mob/living/carbon/human/M = src
|
||||
// if(istype(M) && istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga))
|
||||
// src << "You carefully squish [tmob] under your tail!"
|
||||
// tmob << "[src] pins you under their tail!"
|
||||
// else
|
||||
src << "You pin [tmob] beneath your foot!"
|
||||
tmob << "[src] pins you beneath their foot!"
|
||||
return 1
|
||||
|
||||
if(src.a_intent == "harm" && src.canmove && !src.buckled)
|
||||
if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
|
||||
now_pushing = 0
|
||||
src.forceMove(tmob.loc)
|
||||
tmob.adjustStaminaLoss(15)
|
||||
tmob.adjustBruteLoss(2)
|
||||
|
||||
// var/mob/living/carbon/human/M = src
|
||||
// if(istype(M) && istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga))
|
||||
// src << "You steamroller over [tmob] with your heavy tail!"
|
||||
// tmob << "[src] ploughs you down mercilessly with their heavy tail!"
|
||||
// else
|
||||
src << "You bring your foot down heavily upon [tmob]!"
|
||||
tmob << "[src] steps carelessly on your body!"
|
||||
return 1
|
||||
/*
|
||||
if(src.a_intent == "grab" && src.canmove && !src.buckled)
|
||||
if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
|
||||
now_pushing = 0
|
||||
src.forceMove(tmob.loc)
|
||||
|
||||
var/mob/living/carbon/human/M = src
|
||||
if(istype(M) && !M.shoes)
|
||||
// User is a human (capable of scooping) and not wearing shoes! Scoop into foot slot!
|
||||
equip_to_slot_if_possible(tmob.get_scooped(M), slot_shoes, 0, 1)
|
||||
// if(istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga))
|
||||
// src << "You wrap up [tmob] with your powerful tail!"
|
||||
// tmob << "[src] binds you with their powerful tail!"
|
||||
// else
|
||||
src << "You clench your toes around [tmob]'s body!"
|
||||
tmob << "[src] grabs your body with their toes!"
|
||||
// else if(istype(M) && istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga))
|
||||
// src << "You carefully squish [tmob] under your tail!"
|
||||
// tmob << "[src] pins you under their tail!"
|
||||
else
|
||||
src << "You pin [tmob] beneath your foot!"
|
||||
tmob << "[src] pins you beneath their foot!"
|
||||
return 1
|
||||
*/
|
||||
@@ -1,83 +0,0 @@
|
||||
//
|
||||
// Size Gun
|
||||
//
|
||||
|
||||
/obj/item/weapon/gun/energy/sizegun
|
||||
name = "shrink ray"
|
||||
desc = "A highly advanced ray gun with two settings: Shrink and Grow. Warning: Do not insert into mouth."
|
||||
icon = 'icons/obj/gun_vr.dmi'
|
||||
icon_state = "sizegun-shrink100" // Someone can probably do better. -Ace
|
||||
item_state = null //so the human update icon uses the icon_state instead
|
||||
fire_sound = 'sound/weapons/wave.ogg'
|
||||
charge_cost = 100
|
||||
projectile_type = /obj/item/projectile/beam/shrinklaser
|
||||
origin_tech = "redspace=1;bluespace=4"
|
||||
modifystate = "sizegun-shrink"
|
||||
self_recharge = 1
|
||||
firemodes = list(
|
||||
list(mode_name = "grow",
|
||||
projectile_type = /obj/item/projectile/beam/growlaser,
|
||||
modifystate = "sizegun-grow",
|
||||
fire_sound = 'sound/weapons/pulse3.ogg'
|
||||
),
|
||||
list(mode_name = "shrink",
|
||||
projectile_type = /obj/item/projectile/beam/shrinklaser,
|
||||
modifystate = "sizegun-shrink",
|
||||
fire_sound = 'sound/weapons/wave.ogg'
|
||||
))
|
||||
|
||||
//
|
||||
// Beams for size gun
|
||||
//
|
||||
|
||||
/obj/item/projectile/beam/shrinklaser
|
||||
name = "shrink beam"
|
||||
icon_state = "xray"
|
||||
nodamage = 1
|
||||
damage = 0
|
||||
check_armour = "laser"
|
||||
|
||||
muzzle_type = /obj/effect/projectile/xray/muzzle
|
||||
tracer_type = /obj/effect/projectile/xray/tracer
|
||||
impact_type = /obj/effect/projectile/xray/impact
|
||||
|
||||
/obj/item/projectile/beam/shrinklaser/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(istype(target, /mob/living))
|
||||
var/mob/living/M = target
|
||||
switch(M.size_multiplier)
|
||||
if(RESIZE_HUGE to INFINITY)
|
||||
M.resize(RESIZE_BIG)
|
||||
if(RESIZE_BIG to RESIZE_HUGE)
|
||||
M.resize(RESIZE_NORMAL)
|
||||
if(RESIZE_NORMAL to RESIZE_BIG)
|
||||
M.resize(RESIZE_SMALL)
|
||||
if((0 - INFINITY) to RESIZE_NORMAL)
|
||||
M.resize(RESIZE_TINY)
|
||||
M.update_icons()
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/beam/growlaser
|
||||
name = "growth beam"
|
||||
icon_state = "bluelaser"
|
||||
nodamage = 1
|
||||
damage = 0
|
||||
check_armour = "laser"
|
||||
|
||||
muzzle_type = /obj/effect/projectile/laser_blue/muzzle
|
||||
tracer_type = /obj/effect/projectile/laser_blue/tracer
|
||||
impact_type = /obj/effect/projectile/laser_blue/impact
|
||||
|
||||
/obj/item/projectile/beam/growlaser/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(istype(target, /mob/living))
|
||||
var/mob/living/M = target
|
||||
switch(M.size_multiplier)
|
||||
if(RESIZE_BIG to RESIZE_HUGE)
|
||||
M.resize(RESIZE_HUGE)
|
||||
if(RESIZE_NORMAL to RESIZE_BIG)
|
||||
M.resize(RESIZE_BIG)
|
||||
if(RESIZE_SMALL to RESIZE_NORMAL)
|
||||
M.resize(RESIZE_NORMAL)
|
||||
if((0 - INFINITY) to RESIZE_TINY)
|
||||
M.resize(RESIZE_SMALL)
|
||||
M.update_icons()
|
||||
return 1
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
This file is for jamming single-line procs into Polaris procs.
|
||||
It will prevent runtimes and allow their code to run if VOREStation's fails.
|
||||
It will also log when we mess up our code rather than making it vague.
|
||||
|
||||
Call it at the top of a stock proc with...
|
||||
|
||||
if(attempt_vr(object,proc to call,args)) return
|
||||
|
||||
...if you are replacing an entire proc.
|
||||
|
||||
The proc you're attemping should return nonzero values on success.
|
||||
*/
|
||||
|
||||
/proc/attempt_vr(callon, procname, list/args=null)
|
||||
try
|
||||
if(!callon || !procname)
|
||||
// error("attempt_vr: Invalid obj/proc: [callon]/[procname]")
|
||||
return 0
|
||||
|
||||
var/result = call(callon,procname)(arglist(args))
|
||||
|
||||
return result
|
||||
|
||||
catch
|
||||
log_admin("attempt_vr runtimed when calling [procname] on [callon].")
|
||||
// error("attempt_vr catch: [e] on [e.file]:[e.line]")
|
||||
// return 0
|
||||
|
||||
/*
|
||||
This is the _vr version of calling hooks.
|
||||
It's meant to have different messages, and also the try/catch block.
|
||||
For when you want hooks and want to know when you ruin everything,
|
||||
vs when Polaris ruins everything.
|
||||
|
||||
Call it at the top of a stock proc with...
|
||||
|
||||
if(hook_vr(proc,args)) return
|
||||
|
||||
...if you are replacing an entire proc.
|
||||
|
||||
The hooks you're calling should return nonzero values on success.
|
||||
*/
|
||||
/proc/hook_vr(hook, list/args=null)
|
||||
try
|
||||
var/hook_path = text2path("/hook/[hook]")
|
||||
if(!hook_path)
|
||||
// error("hook_vr: Invalid hook '/hook/[hook]' called.")
|
||||
return 0
|
||||
|
||||
var/caller = new hook_path
|
||||
var/status = 1
|
||||
for(var/P in typesof("[hook_path]/proc"))
|
||||
if(!call(caller, P)(arglist(args)))
|
||||
// error("hook_vr: Hook '[P]' failed or runtimed.")
|
||||
status = 0
|
||||
|
||||
return status
|
||||
|
||||
catch
|
||||
log_admin("hook_vr itself failed or runtimed. Exception below.")
|
||||
// error("hook_vr catch: [e] on [e.file]:[e.line]")
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -1,141 +0,0 @@
|
||||
/obj/machinery/workout
|
||||
name = "fitness lifter"
|
||||
icon = 'code/modules/vore/weight/fit_vr.dmi'
|
||||
icon_state = "fitnesslifter" //Sprites ripped from goon.
|
||||
desc = "A utility often used to lose weight."
|
||||
anchored = 1
|
||||
use_power = 0
|
||||
idle_power_usage = 0
|
||||
active_power_usage = 0
|
||||
|
||||
/obj/machinery/workout/attackby(obj/item/W, var/mob/living/user)
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
src.add_fingerprint(user)
|
||||
user.visible_message("<span class='warning'>[user] has [anchored ? "un" : ""]secured \the [src].</span>", "<span class='notice'>You [anchored ? "un" : ""]secure \the [src].</span>")
|
||||
anchored = !anchored
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
return
|
||||
|
||||
/obj/machinery/workout/attack_hand(var/mob/living/user)
|
||||
if(!anchored)
|
||||
user << "<span class='notice'>For safety reasons, you are required to have this equipment wrenched down before using it!</span>"
|
||||
return
|
||||
|
||||
else if(user.loc != src.loc)
|
||||
user << "<span class='notice'>For safety reasons, you need to be sitting in the fitness lifter for it to work!</span>"
|
||||
return
|
||||
|
||||
else if(user.nutrition > 70 && user.weight > 70) //If they have enough nutrition and body weight, they can exercise.
|
||||
user.setClickCooldown(40)
|
||||
user.dir = src.dir
|
||||
user.nutrition = user.nutrition - 20 //Working out burns a lot of calories!
|
||||
user.weight = user.weight - 0.05 //Burn a bit of weight. Not much, but quite a bit. This can't be spammed, as they'll need nutrition to be able to work out.
|
||||
flick("fitnesslifter2",src)
|
||||
user << "<span class='notice'>You lift some weights.</span>"
|
||||
|
||||
else if(user.nutrition < 70)
|
||||
user << "<span class='notice'>You need more energy to workout on the mat!</span>"
|
||||
|
||||
else if(user.weight < 70)
|
||||
user << "<span class='notice'>You're too skinny to risk losing any more weight!</span>"
|
||||
|
||||
else
|
||||
user << "<span class='notice'>You're unable to use the fitness lifter.</span>"
|
||||
return //Something went wrong. They shouldn't see this.
|
||||
|
||||
/obj/machinery/workout/shipped
|
||||
anchored = 0 // For cargo.
|
||||
|
||||
|
||||
/obj/machinery/punching_bag
|
||||
name = "punching bag"
|
||||
icon = 'code/modules/vore/weight/fit_vr.dmi'
|
||||
icon_state = "punchingbag"
|
||||
desc = "A bag often used to releive stress and burn fat."
|
||||
anchored = 1
|
||||
density = 1
|
||||
use_power = 0
|
||||
idle_power_usage = 0
|
||||
active_power_usage = 0
|
||||
|
||||
/obj/machinery/punching_bag/attack_hand(var/mob/living/user)
|
||||
|
||||
if(user.nutrition > 35 && user.weight > 70) //If they have enough nutrition and body weight, they can exercise.
|
||||
user.setClickCooldown(10)
|
||||
user.nutrition = user.nutrition - 10 //A punching bag uses less calories.
|
||||
user.weight = user.weight - 0.025 //And burns less weight.
|
||||
flick("punchingbag2",src)
|
||||
var/message = pick(
|
||||
"<span class='notice'>You slam your fist into the punching bag.</span>",
|
||||
"<span class='notice'>You jab the punching bag with your elbow.</span>")
|
||||
user << message
|
||||
playsound(src.loc, "punch", 50, 1)
|
||||
|
||||
else if(user.nutrition < 35)
|
||||
user << "<span class='notice'>You need more energy to workout on the mat!</span>"
|
||||
|
||||
else if(user.weight < 70)
|
||||
user << "<span class='notice'>You're too skinny to risk losing any more weight!</span>"
|
||||
|
||||
else
|
||||
user << "<span class='notice'>You're unable to use the punching bag.</span>"
|
||||
return //Something went wrong. They shouldn't see this.
|
||||
|
||||
|
||||
/obj/machinery/punching_clown
|
||||
name = "clown punching bag"
|
||||
icon = 'code/modules/vore/weight/fit_vr.dmi'
|
||||
icon_state = "bopbag"
|
||||
desc = "A bag often used to releive stress and burn fat. It has a clown on the front of it."
|
||||
anchored = 0
|
||||
density = 1
|
||||
use_power = 0
|
||||
idle_power_usage = 0
|
||||
active_power_usage = 0
|
||||
|
||||
/obj/machinery/punching_clown/attack_hand(var/mob/living/user)
|
||||
|
||||
if(user.nutrition > 35 && user.weight > 70) //If they have enough nutrition and body weight, they can exercise.
|
||||
user.setClickCooldown(10)
|
||||
user.nutrition = user.nutrition - 10
|
||||
user.weight = user.weight - 0.025
|
||||
flick("bopbag2",src)
|
||||
var/message = pick(
|
||||
"<span class='notice'>You slam your fist into the punching bag.</span>",
|
||||
"<span class='notice'>You jab the punching bag with your elbow.</span>",
|
||||
"<span class='notice'>You hammer the clown right in it's face with your fist.</span>",
|
||||
"<span class='notice'>A honk emits from the punching bag as you hit it.</span>")
|
||||
user << message
|
||||
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
|
||||
playsound(src.loc, "clownstep", 50, 1)
|
||||
playsound(src.loc, "punch", 50, 1)
|
||||
|
||||
else if(user.nutrition < 35)
|
||||
user << "<span class='notice'>You need more energy to workout on the mat!</span>"
|
||||
|
||||
else if(user.weight < 70)
|
||||
user << "<span class='notice'>You're too skinny to risk losing any more weight!</span>"
|
||||
|
||||
else
|
||||
user << "<span class='notice'>You're unable to use the punching bag.</span>"
|
||||
return //Something went wrong. They shouldn't see this.
|
||||
|
||||
/obj/machinery/scale
|
||||
name = "scale"
|
||||
icon = 'code/modules/vore/weight/fit_vr.dmi'
|
||||
icon_state = "scale"
|
||||
desc = "A scale used to measure ones weight relative to their size and species."
|
||||
anchored = 1 // Set to 0 when we can construct or dismantle these.
|
||||
use_power = 0
|
||||
idle_power_usage = 0
|
||||
active_power_usage = 0
|
||||
var/kilograms
|
||||
|
||||
/obj/machinery/scale/attack_hand(var/mob/living/user)
|
||||
if(user.loc != src.loc)
|
||||
user << "<span class='notice'>You need to be standing on top of the scale for it to work!</span>"
|
||||
return
|
||||
if(user.weight) //Just in case.
|
||||
kilograms = round(text2num(user.weight),4) / 2.20463
|
||||
user << "<span class='notice'>Your relative weight is [user.weight]lb / [kilograms]kg.</span>"
|
||||
user.visible_message("<span class='warning'>[user]'s relative weight is [user.weight]lb / [kilograms]kg.</span>")
|
||||
@@ -1,33 +0,0 @@
|
||||
var/datum/subsystem/fastprocess/SSfastprocess
|
||||
|
||||
/datum/subsystem/fastprocess
|
||||
name = "Fast Process"
|
||||
priority = 25
|
||||
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
|
||||
wait = 2
|
||||
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/subsystem/fastprocess/New()
|
||||
NEW_SS_GLOBAL(SSfastprocess)
|
||||
|
||||
/datum/subsystem/fastprocess/stat_entry()
|
||||
..("FP:[processing.len]")
|
||||
|
||||
|
||||
/datum/subsystem/fastprocess/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = processing.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while(currentrun.len)
|
||||
var/datum/thing = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(thing)
|
||||
thing.process(wait)
|
||||
else
|
||||
SSfastprocess.processing -= thing
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
@@ -1,77 +0,0 @@
|
||||
var/datum/subsystem/objects/SSobj
|
||||
|
||||
/datum/var/isprocessing = 0
|
||||
/datum/proc/process()
|
||||
set waitfor = 0
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return 0
|
||||
|
||||
/datum/subsystem/objects
|
||||
name = "Objects"
|
||||
init_order = 12
|
||||
priority = 40
|
||||
|
||||
var/list/atom_spawners = list()
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
var/list/burning = list()
|
||||
|
||||
/datum/subsystem/objects/New()
|
||||
NEW_SS_GLOBAL(SSobj)
|
||||
|
||||
/datum/subsystem/objects/Initialize(timeofdayl)
|
||||
trigger_atom_spawners()
|
||||
setupGenetics()
|
||||
for(var/thing in world)
|
||||
var/atom/A = thing
|
||||
A.initialize()
|
||||
CHECK_TICK
|
||||
. = ..()
|
||||
|
||||
/datum/subsystem/objects/proc/trigger_atom_spawners(zlevel, ignore_z=FALSE)
|
||||
for(var/V in atom_spawners)
|
||||
var/atom/A = V
|
||||
if (!ignore_z && (zlevel && A.z != zlevel))
|
||||
continue
|
||||
A.spawn_atom_to_world()
|
||||
|
||||
/datum/subsystem/objects/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
|
||||
|
||||
/datum/subsystem/objects/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = processing.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while(currentrun.len)
|
||||
var/datum/thing = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(thing)
|
||||
thing.process(wait)
|
||||
else
|
||||
SSobj.processing -= thing
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
for(var/obj/burningobj in SSobj.burning)
|
||||
if(burningobj && (burningobj.burn_state == ON_FIRE))
|
||||
if(burningobj.burn_world_time < world.time)
|
||||
burningobj.burn()
|
||||
else
|
||||
SSobj.burning.Remove(burningobj)
|
||||
|
||||
/datum/subsystem/objects/proc/setup_template_objects(list/objects)
|
||||
trigger_atom_spawners(0, ignore_z=TRUE)
|
||||
for(var/A in objects)
|
||||
var/atom/B = A
|
||||
B.initialize()
|
||||
|
||||
/datum/subsystem/objects/Recover()
|
||||
if (istype(SSobj.atom_spawners))
|
||||
atom_spawners = SSobj.atom_spawners
|
||||
if (istype(SSobj.processing))
|
||||
processing = SSobj.processing
|
||||
if (istype(SSobj.burning))
|
||||
burning = SSobj.burning
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Damage Converter
|
||||
|
||||
Little bit hidden.
|
||||
Lowers resistance tremendously.
|
||||
Decreases stage speed tremendously.
|
||||
Reduced transmittablity
|
||||
Intense Level.
|
||||
|
||||
Bonus
|
||||
Slowly converts brute/fire damage to toxin.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/damage_converter
|
||||
|
||||
name = "Toxic Compensation"
|
||||
stealth = 1
|
||||
resistance = -4
|
||||
stage_speed = -4
|
||||
transmittable = -2
|
||||
level = 4
|
||||
|
||||
/datum/symptom/damage_converter/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 10))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(4, 5)
|
||||
Convert(M)
|
||||
return
|
||||
|
||||
/datum/symptom/damage_converter/proc/Convert(mob/living/M)
|
||||
|
||||
var/get_damage = rand(1, 2)
|
||||
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
var/list/parts = H.get_damaged_bodyparts(1,1) //1,1 because it needs inputs.
|
||||
|
||||
if(!parts.len)
|
||||
return
|
||||
|
||||
for(var/obj/item/bodypart/L in parts)
|
||||
L.heal_damage(get_damage, get_damage, 0)
|
||||
M.adjustToxLoss(get_damage*parts.len)
|
||||
|
||||
else
|
||||
if(M.getFireLoss() > 0 || M.getBruteLoss() > 0)
|
||||
M.adjustFireLoss(-get_damage)
|
||||
M.adjustBruteLoss(-get_damage)
|
||||
M.adjustToxLoss(get_damage)
|
||||
else
|
||||
return
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Stimulant //gotta go fast
|
||||
|
||||
Noticable.
|
||||
Lowers resistance significantly.
|
||||
Decreases stage speed moderately..
|
||||
Decreases transmittablity tremendously.
|
||||
Moderate Level.
|
||||
|
||||
Bonus
|
||||
The body generates Ephedrine.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/stimulant
|
||||
|
||||
name = "Stimulant"
|
||||
stealth = -1
|
||||
resistance = -3
|
||||
stage_speed = -2
|
||||
transmittable = -4
|
||||
level = 3
|
||||
|
||||
/datum/symptom/stimulant/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 10))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(5)
|
||||
if (M.reagents.get_reagent_amount("ephedrine") < 10)
|
||||
M.reagents.add_reagent("ephedrine", 10)
|
||||
else
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
|
||||
M << "<span class='notice'>[pick("You feel restless.", "You feel like running laps around the station.")]</span>"
|
||||
return
|
||||
@@ -1,45 +0,0 @@
|
||||
var/global/clockwork_construction_value = 0 //The total value of all structures built by the clockwork cult
|
||||
var/global/clockwork_caches = 0 //How many clockwork caches exist in the world (not each individual)
|
||||
var/global/clockwork_daemons = 0 //How many daemons exist in the world
|
||||
var/global/list/clockwork_generals_invoked = list("nezbere" = FALSE, "sevtug" = FALSE, "nzcrentr" = FALSE, "inath-neq" = FALSE) //How many generals have been recently invoked
|
||||
var/global/list/all_clockwork_objects = list() //All clockwork items, structures, and effects in existence
|
||||
var/global/list/all_clockwork_mobs = list() //All clockwork SERVANTS (not creatures) in existence
|
||||
var/global/list/clockwork_component_cache = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 0, "hierophant_ansible" = 0) //The pool of components that caches draw from
|
||||
var/global/ratvar_awakens = FALSE //If Ratvar has been summoned
|
||||
|
||||
#define SCRIPTURE_PERIPHERAL 0 //Scripture tiers; peripherals should never be used
|
||||
#define SCRIPTURE_DRIVER 1
|
||||
#define SCRIPTURE_SCRIPT 2
|
||||
#define SCRIPTURE_APPLICATION 3
|
||||
#define SCRIPTURE_REVENANT 4
|
||||
#define SCRIPTURE_JUDGEMENT 5
|
||||
|
||||
#define SLAB_PRODUCTION_TIME 600 //how long(deciseconds) slabs require to produce a single component; defaults to 1 minute
|
||||
|
||||
#define CACHE_PRODUCTION_TIME 900 //how long(deciseconds) caches require to produce a component; defaults to 1 minute 30 seconds
|
||||
|
||||
#define LOWER_PROB_PER_COMPONENT 10 //how much each component in the cache reduces the weight of getting another of that component type
|
||||
|
||||
#define MAX_COMPONENTS_BEFORE_RAND 10*LOWER_PROB_PER_COMPONENT //the number of each component, times LOWER_PROB_PER_COMPONENT, you need to have before component generation will become random
|
||||
|
||||
#define CLOCKWORK_GENERAL_COOLDOWN 3000 //how long clockwork generals go on cooldown after use, defaults to 5 minutes
|
||||
|
||||
//porselytizer defines
|
||||
#define REPLICANT_ALLOY_UNIT 100 //how much each piece of replicant alloy gives in a clockwork proselytizer
|
||||
|
||||
#define REPLICANT_STANDARD REPLICANT_ALLOY_UNIT*0.2 //how much alloy is in anything else; doesn't matter as much as the following
|
||||
|
||||
#define REPLICANT_FLOOR REPLICANT_ALLOY_UNIT*0.1 //how much alloy is in a clockwork floor, determines the cost of clockwork floor production
|
||||
|
||||
#define REPLICANT_WALL_MINUS_FLOOR REPLICANT_ALLOY_UNIT*0.4 //amount of alloy in a clockwork wall, determines the cost of clockwork wall production
|
||||
|
||||
#define REPLICANT_WALL_TOTAL REPLICANT_WALL_MINUS_FLOOR+REPLICANT_FLOOR //how much alloy is in a clockwork wall and the floor under it
|
||||
|
||||
//Ark defines
|
||||
#define GATEWAY_SUMMON_RATE 2 //the time amount the Gateway to the Celestial Derelict gets each process tick; defaults to 2 per tick
|
||||
|
||||
#define GATEWAY_REEBE_FOUND 100 //when progress is at or above this, the gateway finds reebe and begins drawing power
|
||||
|
||||
#define GATEWAY_RATVAR_COMING 250 //when progress is at or above this, ratvar has entered and is coming through the gateway
|
||||
|
||||
#define GATEWAY_RATVAR_ARRIVAL 300 //when progress is at or above this, game over ratvar's here everybody go home
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,595 +0,0 @@
|
||||
////////////////////////
|
||||
// CLOCKWORK MACHINES //
|
||||
////////////////////////
|
||||
//not-actually-machines
|
||||
|
||||
/obj/structure/clockwork/powered
|
||||
var/obj/machinery/power/apc/target_apc
|
||||
var/active = FALSE
|
||||
var/needs_power = TRUE
|
||||
var/active_icon = null //icon_state while process() is being called
|
||||
var/inactive_icon = null //icon_state while process() isn't being called
|
||||
|
||||
/obj/structure/clockwork/powered/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
var/powered = total_accessable_power()
|
||||
user << "<span class='[powered ? "brass":"alloy"]'>It has access to [powered == INFINITY ? "INFINITY":"[powered]"]W of power.</span>"
|
||||
|
||||
/obj/structure/clockwork/powered/Destroy()
|
||||
SSfastprocess.processing -= src
|
||||
SSobj.processing -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/clockwork/powered/process()
|
||||
var/powered = total_accessable_power()
|
||||
return powered == PROCESS_KILL ? 25 : powered //make sure we don't accidentally return the arbitrary PROCESS_KILL define
|
||||
|
||||
/obj/structure/clockwork/powered/proc/toggle(fast_process, mob/living/user)
|
||||
if(user)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return 0
|
||||
user.visible_message("<span class='notice'>[user] [active ? "dis" : "en"]ables [src].</span>", "<span class='brass'>You [active ? "dis" : "en"]able [src].</span>")
|
||||
active = !active
|
||||
if(active)
|
||||
icon_state = active_icon
|
||||
if(fast_process)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
icon_state = inactive_icon
|
||||
if(fast_process)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
|
||||
/obj/structure/clockwork/powered/proc/total_accessable_power() //how much power we have and can use
|
||||
if(!needs_power || ratvar_awakens)
|
||||
return INFINITY //oh yeah we've got power why'd you ask
|
||||
|
||||
var/power = 0
|
||||
power += accessable_apc_power()
|
||||
power += accessable_sigil_power()
|
||||
return power
|
||||
|
||||
/obj/structure/clockwork/powered/proc/accessable_apc_power()
|
||||
var/power = 0
|
||||
var/area/A = get_area(src)
|
||||
var/area/targetAPCA
|
||||
for(var/obj/machinery/power/apc/APC in apcs_list)
|
||||
var/area/APCA = get_area(APC)
|
||||
if(APCA == A)
|
||||
target_apc = APC
|
||||
if(target_apc)
|
||||
targetAPCA = get_area(target_apc)
|
||||
if(targetAPCA != A)
|
||||
target_apc = null
|
||||
else if(target_apc.cell)
|
||||
var/apccharge = target_apc.cell.charge
|
||||
if(apccharge >= 50)
|
||||
power += apccharge
|
||||
return power
|
||||
|
||||
/obj/structure/clockwork/powered/proc/accessable_sigil_power()
|
||||
var/power = 0
|
||||
for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
|
||||
power += T.power_charge
|
||||
return power
|
||||
|
||||
|
||||
/obj/structure/clockwork/powered/proc/try_use_power(amount) //try to use an amount of power
|
||||
if(!needs_power || ratvar_awakens)
|
||||
return 1
|
||||
if(amount <= 0)
|
||||
return 0
|
||||
var/power = total_accessable_power()
|
||||
if(!power || power < amount)
|
||||
return 0
|
||||
return use_power(amount)
|
||||
|
||||
/obj/structure/clockwork/powered/proc/use_power(amount) //we've made sure we had power, so now we use it
|
||||
var/sigilpower = accessable_sigil_power()
|
||||
var/list/sigils_in_range = list()
|
||||
for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
|
||||
sigils_in_range |= T
|
||||
while(sigilpower && amount >= 50)
|
||||
for(var/S in sigils_in_range)
|
||||
var/obj/effect/clockwork/sigil/transmission/T = S
|
||||
if(amount >= 50 && T.modify_charge(50))
|
||||
sigilpower -= 50
|
||||
amount -= 50
|
||||
var/apcpower = accessable_apc_power()
|
||||
while(apcpower >= 50 && amount >= 50)
|
||||
if(target_apc.cell.use(50))
|
||||
apcpower -= 50
|
||||
amount -= 50
|
||||
target_apc.update()
|
||||
target_apc.update_icon()
|
||||
else
|
||||
apcpower = 0
|
||||
if(amount)
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/structure/clockwork/powered/proc/return_power(amount) //returns a given amount of power to all nearby sigils
|
||||
if(amount <= 0)
|
||||
return 0
|
||||
var/list/sigils_in_range = list()
|
||||
for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
|
||||
sigils_in_range |= T
|
||||
if(!sigils_in_range.len)
|
||||
return 0
|
||||
while(amount >= 50)
|
||||
for(var/S in sigils_in_range)
|
||||
var/obj/effect/clockwork/sigil/transmission/T = S
|
||||
if(amount >= 50 && T.modify_charge(-50))
|
||||
amount -= 50
|
||||
return 1
|
||||
|
||||
|
||||
/obj/structure/clockwork/powered/mending_motor //Mending motor: A prism that consumes replicant alloy to repair nearby mechanical servants at a quick rate.
|
||||
name = "mending motor"
|
||||
desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
|
||||
clockwork_desc = "A powerful prism that rapidly repairs nearby mechanical servants and clockwork structures."
|
||||
icon_state = "mending_motor_inactive"
|
||||
active_icon = "mending_motor"
|
||||
inactive_icon = "mending_motor_inactive"
|
||||
construction_value = 20
|
||||
max_health = 150
|
||||
health = 150
|
||||
break_message = "<span class='warning'>The prism collapses with a heavy thud!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards, /obj/item/clockwork/component/vanguard_cogwheel)
|
||||
var/stored_alloy = 0 //2500W = 1 alloy = 100 liquified alloy
|
||||
var/max_alloy = 25000
|
||||
var/mob_cost = 200
|
||||
var/structure_cost = 250
|
||||
var/cyborg_cost = 300
|
||||
|
||||
/obj/structure/clockwork/powered/mending_motor/prefilled
|
||||
stored_alloy = 2500 //starts with 1 replicant alloy/100 liquified alloy
|
||||
|
||||
/obj/structure/clockwork/powered/mending_motor/total_accessable_power()
|
||||
. = ..()
|
||||
if(. != INFINITY)
|
||||
. += accessable_alloy_power()
|
||||
|
||||
/obj/structure/clockwork/powered/mending_motor/proc/accessable_alloy_power()
|
||||
return stored_alloy
|
||||
|
||||
/obj/structure/clockwork/powered/mending_motor/use_power(amount)
|
||||
var/alloypower = accessable_alloy_power()
|
||||
while(alloypower >= 50 && amount >= 50)
|
||||
stored_alloy -= 50
|
||||
alloypower -= 50
|
||||
amount -= 50
|
||||
return ..()
|
||||
|
||||
/obj/structure/clockwork/powered/mending_motor/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='alloy'>It contains [stored_alloy*0.04]/[max_alloy*0.04] units of liquified alloy, which is equivalent to [stored_alloy]W/[max_alloy]W of power.</span>"
|
||||
user << "<span class='inathneq_small'>It requires [mob_cost]W to heal clockwork mobs, [structure_cost]W for clockwork structures, and [cyborg_cost]W for cyborgs.</span>"
|
||||
|
||||
/obj/structure/clockwork/powered/mending_motor/process()
|
||||
if(..() < mob_cost)
|
||||
visible_message("<span class='warning'>[src] emits an airy chuckling sound and falls dark!</span>")
|
||||
toggle()
|
||||
return
|
||||
for(var/atom/movable/M in range(5, src))
|
||||
if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
|
||||
var/mob/living/simple_animal/hostile/clockwork/W = M
|
||||
var/fatigued = FALSE
|
||||
if(istype(M, /mob/living/simple_animal/hostile/clockwork/marauder))
|
||||
var/mob/living/simple_animal/hostile/clockwork/marauder/E = M
|
||||
if(E.fatigue)
|
||||
fatigued = TRUE
|
||||
if((!fatigued && W.health == W.maxHealth) || W.stat)
|
||||
continue
|
||||
if(!try_use_power(mob_cost))
|
||||
break
|
||||
W.adjustHealth(-15)
|
||||
else if(istype(M, /obj/structure/clockwork))
|
||||
var/obj/structure/clockwork/C = M
|
||||
if(C.health == C.max_health)
|
||||
continue
|
||||
if(!try_use_power(structure_cost))
|
||||
break
|
||||
C.health = min(C.health + 15, C.max_health)
|
||||
else if(issilicon(M))
|
||||
var/mob/living/silicon/S = M
|
||||
if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
|
||||
continue
|
||||
if(!try_use_power(cyborg_cost))
|
||||
break
|
||||
S.adjustBruteLoss(-15)
|
||||
S.adjustFireLoss(-15)
|
||||
return 1
|
||||
|
||||
/obj/structure/clockwork/powered/mending_motor/attack_hand(mob/living/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
if(total_accessable_power() < mob_cost)
|
||||
user << "<span class='warning'>[src] needs more power or replicant alloy to function!</span>"
|
||||
return 0
|
||||
toggle(0, user)
|
||||
|
||||
/obj/structure/clockwork/powered/mending_motor/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/clockwork/component/replicant_alloy) && is_servant_of_ratvar(user))
|
||||
if(stored_alloy + 2500 > max_alloy)
|
||||
user << "<span class='warning'>[src] is too full to accept any more alloy!</span>"
|
||||
return 0
|
||||
user.whisper("Genafzhgr vagb jngre.")
|
||||
user.visible_message("<span class='notice'>[user] liquifies [I] and pours it onto [src].</span>", \
|
||||
"<span class='notice'>You liquify [src] and pour it onto [src], transferring the alloy into its reserves.</span>")
|
||||
stored_alloy = stored_alloy + 2500
|
||||
user.drop_item()
|
||||
qdel(I)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
/obj/structure/clockwork/powered/mania_motor //Mania motor: A pair of antenna that, while active, cause braindamage and hallucinations in nearby human mobs.
|
||||
name = "mania motor"
|
||||
desc = "A pair of antenna with what appear to be sockets around the base. It reminds you of an antlion."
|
||||
clockwork_desc = "A transmitter that allows Sevtug to whisper into the minds of nearby non-servants, causing hallucinations and brain damage as long as it remains powered."
|
||||
icon_state = "mania_motor_inactive"
|
||||
active_icon = "mania_motor"
|
||||
inactive_icon = "mania_motor_inactive"
|
||||
construction_value = 20
|
||||
max_health = 80
|
||||
health = 80
|
||||
break_message = "<span class='warning'>The antenna break off, leaving a pile of shards!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards, /obj/item/clockwork/component/guvax_capacitor/antennae)
|
||||
var/mania_cost = 150
|
||||
var/convert_attempt_cost = 150
|
||||
var/convert_cost = 300
|
||||
|
||||
var/mania_messages = list("\"Tb ahgf.\"", "\"Gnxr n penpx ng penml.\"", "\"Znxr n ovq sbe vafnavgl.\"", "\"Trg xbbxl.\"", "\"Zbir gbjneqf znavn.\"", "\"Orpbzr orjvyqrerq.\"", "\"Jnk jvyq.\"", \
|
||||
"\"Tb ebhaq gur oraq.\"", "\"Ynaq va yhanpl.\"", "\"Gel qrzragvn.\"", "\"Fgevir gb trg n fperj ybbfr.\"")
|
||||
var/compel_messages = list("\"Pbzr pybfre.\"", "\"Nccebnpu gur genafzvggre.\"", "\"Gbhpu gur nagraanr.\"", "\"V nyjnlf unir gb qrny jvgu vqvbgf. Zbir gbjneqf gur znavn zbgbe.\"", \
|
||||
"\"Nqinapr sbejneq naq cynpr lbhe urnq orgjrra gur nagraanr - gun'g'f nyy vg'f tbbq sbe.\"", "\"Vs lbh jrer fznegre, lbh'q or bire urer nyernql.\"", "\"Zbir SBEJNEQ, lbh sbby.\"")
|
||||
var/convert_messages = list("\"Lbh jba'g qb. Tb gb fyrrc juvyr V gryy gur'fr avgjvgf ubj gb pbaireg lbh.\"", "\"Lbh ner vafhssvpvrag. V zhfg vafgehpg gur'fr vqvbgf va gur neg-bs pbairefvba.\"", \
|
||||
"\"Bu-bs pbhefr, fbzrbar jr pna'g pbaireg. Gur'fr freinagf ner sbbyf.\"", "\"Ubj uneq vf vg gb hfr n Fvtvy, naljnl? Nyy vg gnxrf vf qenttvat fbzrbar bagb vg.\"", \
|
||||
"\"Ubj qb gur'l snvy gb hfr n Fvtvy-bs Npprffvba, naljnl?\"", "\"Jul vf vg gun'g nyy freinagf ner guv'f varcg?\"", "\"Vg'f dhvgr yvxryl lbh'yy or fghpx urer sbe n juvyr.\"")
|
||||
var/close_messages = list("\"Jryy, lbh pna'g ernpu gur zbgbe sebz GUR'ER, lbh zbeba.\"", "\"Vagrerfgvat ybpngvba. V'q cersre vs lbh jrag fbzrjurer lbh pbhyq NPGHNYYL GBHPU GUR NAGRAANR!\"", \
|
||||
"\"Nznmvat. Lbh fbzrubj znantrq gb jrqtr lbhefrys fbzrjurer lbh pna'g npghnyyl ernpu gur zbgbe sebz.\"", "\"Fhpu n fubj-bs vqvbpl vf hacnenyyryrq. Creuncf V fubhyq chg lbh ba qvfcynl?\"", \
|
||||
"\"Qvq lbh qb guv'f ba checbfr? V pna'g vzntvar lbh qbvat fb nppvqragnyyl. Bu, jnvg, V pna.\"", "\"Ubj vf vg gun'g fhpu fzneg perngherf pna fgvyy qb fbzrguv'at NF FGHCVQ NF GUV'F!\"")
|
||||
|
||||
|
||||
/obj/structure/clockwork/powered/mania_motor/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='sevtug_small'>It requires [mania_cost]W to run, and [convert_attempt_cost + convert_cost]W to convert humans adjecent to it.</span>"
|
||||
|
||||
/obj/structure/clockwork/powered/mania_motor/process()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!..())
|
||||
visible_message("<span class='warning'>[src] hums loudly, then the sockets at its base fall dark!</span>")
|
||||
playsound(T, 'sound/effects/screech.ogg', 40, 1)
|
||||
toggle(0)
|
||||
return
|
||||
if(try_use_power(mania_cost))
|
||||
var/hum = get_sfx('sound/effects/screech.ogg') //like playsound, same sound for everyone affected
|
||||
for(var/mob/living/carbon/human/H in view(1, src))
|
||||
if(H.Adjacent(src) && try_use_power(convert_attempt_cost))
|
||||
if(is_eligible_servant(H) && try_use_power(convert_cost))
|
||||
H << "<span class='sevtug'>\"Lbh ner zvar-naq-uvf, abj.\"</span>"
|
||||
H.playsound_local(T, hum, 80, 1)
|
||||
add_servant_of_ratvar(H)
|
||||
else if(!H.stat)
|
||||
if(H.getBrainLoss() >= H.maxHealth)
|
||||
H.Paralyse(5)
|
||||
H << "<span class='sevtug'>[pick(convert_messages)]</span>"
|
||||
else
|
||||
H.adjustBrainLoss(100)
|
||||
H.visible_message("<span class='warning'>[H] reaches out and touches [src].</span>", "<span class='sevtug'>You touch [src] involuntarily.</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[src]'s antennae fizzle quietly.</span>")
|
||||
playsound(src, 'sound/effects/light_flicker.ogg', 50, 1)
|
||||
for(var/mob/living/carbon/human/H in range(10, src))
|
||||
if(!is_servant_of_ratvar(H) && !H.null_rod_check() && H.stat == CONSCIOUS)
|
||||
var/distance = get_dist(T, get_turf(H))
|
||||
var/falloff_distance = min((110) - distance * 10, 80)
|
||||
var/sound_distance = falloff_distance * 0.5
|
||||
var/targetbrainloss = H.getBrainLoss()
|
||||
var/targethallu = H.hallucination
|
||||
var/targetdruggy = H.druggy
|
||||
if(distance >= 4 && prob(falloff_distance))
|
||||
H << "<span class='sevtug_small'>[pick(mania_messages)]</span>"
|
||||
H.playsound_local(T, hum, sound_distance, 1)
|
||||
switch(distance)
|
||||
if(2 to 3)
|
||||
if(prob(falloff_distance))
|
||||
if(prob(falloff_distance))
|
||||
H << "<span class='sevtug_small'>[pick(mania_messages)]</span>"
|
||||
else
|
||||
H << "<span class='sevtug'>[pick(compel_messages)]</span>"
|
||||
if(targetbrainloss <= 50)
|
||||
H.adjustBrainLoss(50 - targetbrainloss) //got too close had brain eaten
|
||||
if(targetdruggy <= 150)
|
||||
H.adjust_drugginess(11)
|
||||
if(targethallu <= 150)
|
||||
H.hallucination += 11
|
||||
if(4 to 5)
|
||||
if(targetbrainloss <= 50)
|
||||
H.adjustBrainLoss(3)
|
||||
if(targetdruggy <= 120)
|
||||
H.adjust_drugginess(9)
|
||||
if(targethallu <= 120)
|
||||
H.hallucination += 9
|
||||
if(6 to 7)
|
||||
if(targetbrainloss <= 30)
|
||||
H.adjustBrainLoss(2)
|
||||
if(prob(falloff_distance) && targetdruggy <= 90)
|
||||
H.adjust_drugginess(7)
|
||||
else if(targethallu <= 90)
|
||||
H.hallucination += 7
|
||||
if(8 to 9)
|
||||
if(H.getBrainLoss() <= 10)
|
||||
H.adjustBrainLoss(1)
|
||||
if(prob(falloff_distance) && targetdruggy <= 60)
|
||||
H.adjust_drugginess(5)
|
||||
else if(targethallu <= 60)
|
||||
H.hallucination += 5
|
||||
if(10 to INFINITY)
|
||||
if(prob(falloff_distance) && targetdruggy <= 30)
|
||||
H.adjust_drugginess(3)
|
||||
else if(targethallu <= 30)
|
||||
H.hallucination += 3
|
||||
else //if it's a distance of 1 and they can't see it/aren't adjacent or they're on top of it(how'd they get on top of it and still trigger this???)
|
||||
if(targetbrainloss <= 99)
|
||||
if(prob(falloff_distance))
|
||||
if(prob(falloff_distance))
|
||||
H << "<span class='sevtug'>[pick(compel_messages)]</span>"
|
||||
else if(prob(falloff_distance))
|
||||
H << "<span class='sevtug'>[pick(close_messages)]</span>"
|
||||
else
|
||||
H << "<span class='sevtug_small'>[pick(mania_messages)]</span>"
|
||||
H.adjustBrainLoss(99 - targetbrainloss)
|
||||
if(targetdruggy <= 200)
|
||||
H.adjust_drugginess(15)
|
||||
if(targethallu <= 200)
|
||||
H.hallucination += 15
|
||||
|
||||
if(is_servant_of_ratvar(H) && (H.getBrainLoss() || H.hallucination || H.druggy)) //not an else so that newly converted servants are healed of the damage it inflicts
|
||||
H.adjustBrainLoss(-H.getBrainLoss()) //heals servants of braindamage, hallucination, and druggy
|
||||
H.hallucination = 0
|
||||
H.adjust_drugginess(-H.druggy)
|
||||
else
|
||||
visible_message("<span class='warning'>[src] hums loudly, then the sockets at its base fall dark!</span>")
|
||||
playsound(src, 'sound/effects/screech.ogg', 40, 1)
|
||||
toggle(0)
|
||||
|
||||
/obj/structure/clockwork/powered/mania_motor/attack_hand(mob/living/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
if(!total_accessable_power() >= mania_cost)
|
||||
user << "<span class='warning'>[src] needs more power to function!</span>"
|
||||
return 0
|
||||
toggle(0, user)
|
||||
|
||||
|
||||
|
||||
/obj/structure/clockwork/powered/interdiction_lens //Interdiction lens: A powerful artifact that constantly disrupts electronics but, if it fails to find something to disrupt, turns off.
|
||||
name = "interdiction lens"
|
||||
desc = "An ominous, double-pronged brass totem. There's a strange gemstone clasped between the pincers."
|
||||
clockwork_desc = "A powerful totem that constantly disrupts nearby electronics and funnels power into nearby Sigils of Transmission."
|
||||
icon_state = "interdiction_lens"
|
||||
construction_value = 25
|
||||
active_icon = "interdiction_lens_active"
|
||||
inactive_icon = "interdiction_lens"
|
||||
break_message = "<span class='warning'>The lens flares a blinding violet before shattering!</span>"
|
||||
break_sound = 'sound/effects/Glassbr3.ogg'
|
||||
var/recharging = 0 //world.time when the lens was last used
|
||||
var/recharge_time = 1200 //if it drains no power and affects no objects, it turns off for two minutes
|
||||
var/disabled = FALSE //if it's actually usable
|
||||
var/interdiction_range = 14 //how large an area it drains and disables in
|
||||
var/disrupt_cost = 100 //how much power to use when disabling an object
|
||||
|
||||
/obj/structure/clockwork/powered/interdiction_lens/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='[recharging > world.time ? "nezbere_small":"brass"]'>Its gemstone [recharging > world.time ? "has been breached by writhing tendrils of blackness that cover the totem" \
|
||||
: "vibrates in place and thrums with power"].</span>"
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='nezbere_small'>It requires [disrupt_cost]W of power for each nearby disruptable electronic.</span>"
|
||||
user << "<span class='nezbere_small'>If it fails to both drain any power and disrupt any electronics, it will disable itself for [round(recharge_time/600, 1)] minutes.</span>"
|
||||
|
||||
/obj/structure/clockwork/powered/interdiction_lens/toggle(fast_process, mob/living/user)
|
||||
..()
|
||||
if(active)
|
||||
set_light(4,2)
|
||||
else
|
||||
set_light(0)
|
||||
|
||||
/obj/structure/clockwork/powered/interdiction_lens/attack_hand(mob/living/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
if(disabled)
|
||||
user << "<span class='warning'>As you place your hand on the gemstone, cold tendrils of black matter crawl up your arm. You quickly pull back.</span>"
|
||||
return 0
|
||||
if(!total_accessable_power() >= disrupt_cost)
|
||||
user << "<span class='warning'>[src] needs more power to function!</span>"
|
||||
return 0
|
||||
toggle(0, user)
|
||||
|
||||
/obj/structure/clockwork/powered/interdiction_lens/process()
|
||||
if(recharging > world.time)
|
||||
return
|
||||
if(disabled)
|
||||
visible_message("<span class='warning'>The writhing tendrils return to the gemstone, which begins to glow with power!</span>")
|
||||
flick("interdiction_lens_recharged", src)
|
||||
disabled = FALSE
|
||||
toggle(0)
|
||||
else
|
||||
var/successfulprocess = FALSE
|
||||
var/power_drained = 0
|
||||
var/list/atoms_to_test = list()
|
||||
for(var/A in spiral_range_turfs(interdiction_range, src))
|
||||
var/turf/T = A
|
||||
for(var/M in T)
|
||||
atoms_to_test |= M
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
for(var/M in atoms_to_test)
|
||||
if(istype(M, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/A = M
|
||||
if(A.cell && A.cell.charge)
|
||||
successfulprocess = TRUE
|
||||
playsound(A, "sparks", 50, 1)
|
||||
flick("apc-spark", A)
|
||||
power_drained += min(A.cell.charge, 100)
|
||||
A.cell.charge = max(0, A.cell.charge - 100)
|
||||
if(!A.cell.charge && !A.shorted)
|
||||
A.shorted = 1
|
||||
A.visible_message("<span class='warning'>The [A.name]'s screen blurs with static.</span>")
|
||||
A.update()
|
||||
A.update_icon()
|
||||
else if(istype(M, /obj/machinery/power/smes))
|
||||
var/obj/machinery/power/smes/S = M
|
||||
if(S.charge)
|
||||
successfulprocess = TRUE
|
||||
power_drained += min(S.charge, 500)
|
||||
S.charge = max(0, S.charge - 50000) //SMES units contain too much power and could run an interdiction lens basically forever, or provide power forever
|
||||
if(!S.charge && !S.panel_open)
|
||||
S.panel_open = TRUE
|
||||
S.icon_state = "[initial(S.icon_state)]-o"
|
||||
var/datum/effect_system/spark_spread/spks = new(get_turf(S))
|
||||
spks.set_up(10, 0, get_turf(S))
|
||||
spks.start()
|
||||
S.visible_message("<span class='warning'>[S]'s panel flies open with a flurry of sparks.</span>")
|
||||
S.update_icon()
|
||||
else if(isrobot(M))
|
||||
var/mob/living/silicon/robot/R = M
|
||||
if(!is_servant_of_ratvar(R) && R.cell && R.cell.charge)
|
||||
successfulprocess = TRUE
|
||||
power_drained += min(R.cell.charge, 200)
|
||||
R.cell.charge = max(0, R.cell.charge - 200)
|
||||
R << "<span class='warning'>ERROR: Power loss detected!</span>"
|
||||
var/datum/effect_system/spark_spread/spks = new(get_turf(R))
|
||||
spks.set_up(3, 0, get_turf(R))
|
||||
spks.start()
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
if(!return_power(power_drained) || power_drained < 50) //failed to return power drained or too little power to return
|
||||
successfulprocess = FALSE
|
||||
if(try_use_power(disrupt_cost) && total_accessable_power() >= disrupt_cost) //if we can disable at least one object
|
||||
playsound(src, 'sound/items/PSHOOM.ogg', 50, 1, interdiction_range-7, 1)
|
||||
for(var/M in atoms_to_test)
|
||||
if(istype(M, /obj/machinery/light)) //cosmetic light flickering
|
||||
var/obj/machinery/light/L = M
|
||||
if(L.on)
|
||||
playsound(L, 'sound/effects/light_flicker.ogg', 50, 1)
|
||||
L.flicker(3)
|
||||
else if(istype(M, /obj/machinery/camera))
|
||||
var/obj/machinery/camera/C = M
|
||||
if(C.isEmpProof() || !C.status)
|
||||
continue
|
||||
successfulprocess = TRUE
|
||||
if(C.emped)
|
||||
continue
|
||||
if(!try_use_power(disrupt_cost))
|
||||
break
|
||||
C.emp_act(1)
|
||||
else if(istype(M, /obj/item/device/radio))
|
||||
var/obj/item/device/radio/O = M
|
||||
successfulprocess = TRUE
|
||||
if(O.emped || !O.on)
|
||||
continue
|
||||
if(!try_use_power(disrupt_cost))
|
||||
break
|
||||
O.emp_act(1)
|
||||
else if(isliving(M) || istype(M, /obj/structure/closet) || istype(M, /obj/item/weapon/storage)) //other things may have radios in them but we don't care
|
||||
var/atom/movable/A = M
|
||||
for(var/obj/item/device/radio/O in A.GetAllContents())
|
||||
successfulprocess = TRUE
|
||||
if(O.emped || !O.on)
|
||||
continue
|
||||
if(!try_use_power(disrupt_cost))
|
||||
break
|
||||
O.emp_act(1)
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
if(!successfulprocess)
|
||||
visible_message("<span class='warning'>The gemstone suddenly turns horribly dark, writhing tendrils covering it!</span>")
|
||||
recharging = world.time + recharge_time
|
||||
flick("interdiction_lens_discharged", src)
|
||||
icon_state = "interdiction_lens_inactive"
|
||||
set_light(2,1)
|
||||
disabled = TRUE
|
||||
|
||||
|
||||
|
||||
/obj/structure/clockwork/powered/clockwork_obelisk
|
||||
name = "clockwork obelisk"
|
||||
desc = "A large brass obelisk hanging in midair."
|
||||
clockwork_desc = "A powerful obelisk that can send a message to all servants or open a gateway to a target servant or clockwork obelisk."
|
||||
icon_state = "obelisk_inactive"
|
||||
active_icon = "obelisk"
|
||||
inactive_icon = "obelisk_inactive"
|
||||
construction_value = 20
|
||||
max_health = 200
|
||||
health = 200
|
||||
break_message = "<span class='warning'>The obelisk falls to the ground, undamaged!</span>"
|
||||
debris = list(/obj/item/clockwork/component/hierophant_ansible/obelisk)
|
||||
var/hierophant_cost = 50 //how much it costs to broadcast with large text
|
||||
var/gateway_cost = 2000 //how much it costs to open a gateway
|
||||
var/gateway_active = FALSE
|
||||
|
||||
/obj/structure/clockwork/powered/clockwork_obelisk/New()
|
||||
..()
|
||||
toggle(1)
|
||||
|
||||
/obj/structure/clockwork/powered/clockwork_obelisk/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='nzcrentr_small'>It requires [hierophant_cost]W to broadcast over the Hierophant Network, and [gateway_cost]W to open a Spatial Gateway.</span>"
|
||||
|
||||
/obj/structure/clockwork/powered/clockwork_obelisk/process()
|
||||
if(locate(/obj/effect/clockwork/spatial_gateway) in loc)
|
||||
icon_state = active_icon
|
||||
density = 0
|
||||
gateway_active = TRUE
|
||||
else
|
||||
icon_state = inactive_icon
|
||||
density = 1
|
||||
gateway_active = FALSE
|
||||
|
||||
/obj/structure/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user)
|
||||
if(!is_servant_of_ratvar(user) || !total_accessable_power() >= hierophant_cost)
|
||||
user << "<span class='warning'>You place your hand on the obelisk, but it doesn't react.</span>"
|
||||
return
|
||||
var/choice = alert(user,"You place your hand on the obelisk...",,"Hierophant Broadcast","Spatial Gateway","Cancel")
|
||||
switch(choice)
|
||||
if("Hierophant Broadcast")
|
||||
if(gateway_active)
|
||||
user << "<span class='warning'>The obelisk is sustaining a gateway and cannot broadcast!</span>"
|
||||
return
|
||||
var/input = stripped_input(usr, "Please choose a message to send over the Hierophant Network.", "Hierophant Broadcast", "")
|
||||
if(!input || !user.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
if(gateway_active)
|
||||
user << "<span class='warning'>The obelisk is sustaining a gateway and cannot broadcast!</span>"
|
||||
return
|
||||
if(!try_use_power(hierophant_cost))
|
||||
user << "<span class='warning'>The obelisk lacks the power to broadcast!</span>"
|
||||
return
|
||||
clockwork_say(user, "Uvrebcunag Oebnqpnfg, npgvingr!")
|
||||
send_hierophant_message(user, input, "big_brass", "large_brass")
|
||||
if("Spatial Gateway")
|
||||
if(gateway_active)
|
||||
user << "<span class='warning'>The obelisk is already sustaining a gateway!</span>"
|
||||
return
|
||||
if(!try_use_power(gateway_cost))
|
||||
user << "<span class='warning'>The obelisk lacks the power to open a gateway!</span>"
|
||||
return
|
||||
if(procure_gateway(user, 100, 5, 1))
|
||||
clockwork_say(user, "Fcnpvny Tngrjnl, npgvingr!")
|
||||
else
|
||||
return_power(gateway_cost)
|
||||
if("Cancel")
|
||||
return
|
||||
@@ -1,326 +0,0 @@
|
||||
/obj/structure/clockwork/massive //For objects that are typically very large
|
||||
name = "massive construct"
|
||||
desc = "A very large construction."
|
||||
layer = MASSIVE_OBJ_LAYER
|
||||
density = FALSE
|
||||
burn_state = LAVA_PROOF
|
||||
|
||||
/obj/structure/clockwork/massive/New()
|
||||
..()
|
||||
poi_list += src
|
||||
|
||||
/obj/structure/clockwork/massive/Destroy()
|
||||
poi_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/clockwork/massive/celestial_gateway //The gateway to Reebe, from which Ratvar emerges
|
||||
name = "Gateway to the Celestial Derelict"
|
||||
desc = "A massive, thrumming rip in spacetime."
|
||||
clockwork_desc = "A portal to the Celestial Derelict. Massive and intimidating, it is the only thing that can both transport Ratvar and withstand the massive amount of energy he emits."
|
||||
health = 500
|
||||
max_health = 500
|
||||
mouse_opacity = 2
|
||||
icon = 'icons/effects/clockwork_effects.dmi'
|
||||
icon_state = "nothing"
|
||||
density = TRUE
|
||||
can_be_repaired = FALSE
|
||||
var/progress_in_seconds = 0 //Once this reaches GATEWAY_RATVAR_ARRIVAL, it's game over
|
||||
var/purpose_fulfilled = FALSE
|
||||
var/first_sound_played = FALSE
|
||||
var/second_sound_played = FALSE
|
||||
var/third_sound_played = FALSE
|
||||
var/obj/effect/clockwork/gateway_glow/glow
|
||||
var/obj/effect/countdown/clockworkgate/countdown
|
||||
|
||||
/obj/structure/clockwork/massive/celestial_gateway/New()
|
||||
..()
|
||||
glow = new(get_turf(src))
|
||||
countdown = new(src)
|
||||
countdown.start()
|
||||
SSshuttle.emergencyNoEscape = TRUE
|
||||
START_PROCESSING(SSobj, src)
|
||||
var/area/gate_area = get_area(src)
|
||||
for(var/M in mob_list)
|
||||
if(is_servant_of_ratvar(M) || isobserver(M))
|
||||
M << "<span class='large_brass'><b>A gateway to the Celestial Derelict has been created in [gate_area.map_name]!</b></span>"
|
||||
|
||||
/obj/structure/clockwork/massive/celestial_gateway/Destroy()
|
||||
SSshuttle.emergencyNoEscape = FALSE
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
|
||||
SSshuttle.emergency.mode = SHUTTLE_DOCKED
|
||||
SSshuttle.emergency.timer = world.time
|
||||
if(!purpose_fulfilled)
|
||||
priority_announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(!purpose_fulfilled)
|
||||
var/area/gate_area = get_area(src)
|
||||
for(var/M in mob_list)
|
||||
if(is_servant_of_ratvar(M) || isobserver(M))
|
||||
M << "<span class='large_brass'><b>A gateway to the Celestial Derelict has fallen at [gate_area.map_name]!</b></span>"
|
||||
world << sound(null, 0, channel = 8)
|
||||
qdel(glow)
|
||||
glow = null
|
||||
qdel(countdown)
|
||||
countdown = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/clockwork/massive/celestial_gateway/destroyed()
|
||||
countdown.stop()
|
||||
visible_message("<span class='userdanger'>The [src] begins to pulse uncontrollably... you might want to run!</span>")
|
||||
world << sound('sound/effects/clockcult_gateway_disrupted.ogg', 0, channel = 8, volume = 50)
|
||||
make_glow()
|
||||
glow.icon_state = "clockwork_gateway_disrupted"
|
||||
takes_damage = FALSE
|
||||
sleep(27)
|
||||
explosion(src, 1, 3, 8, 8)
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
/obj/structure/clockwork/massive/celestial_gateway/proc/make_glow()
|
||||
if(!glow)
|
||||
glow = new(get_turf(src))
|
||||
glow.linked_gate = src
|
||||
|
||||
/obj/structure/clockwork/massive/celestial_gateway/ex_act(severity)
|
||||
return 0 //Nice try, Toxins!
|
||||
|
||||
/obj/structure/clockwork/massive/celestial_gateway/process()
|
||||
if(!progress_in_seconds || prob(5))
|
||||
for(var/M in mob_list)
|
||||
M << "<span class='warning'><b>You hear otherworldly sounds from the [dir2text(get_dir(get_turf(M), get_turf(src)))]...</span>"
|
||||
if(!health)
|
||||
return 0
|
||||
progress_in_seconds += GATEWAY_SUMMON_RATE
|
||||
switch(progress_in_seconds)
|
||||
if(-INFINITY to GATEWAY_REEBE_FOUND)
|
||||
if(!first_sound_played)
|
||||
world << sound('sound/effects/clockcult_gateway_charging.ogg', 1, channel = 8, volume = 50)
|
||||
first_sound_played = TRUE
|
||||
make_glow()
|
||||
glow.icon_state = "clockwork_gateway_charging"
|
||||
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
|
||||
if(!second_sound_played)
|
||||
world << sound('sound/effects/clockcult_gateway_active.ogg', 1, channel = 8, volume = 50)
|
||||
second_sound_played = TRUE
|
||||
make_glow()
|
||||
glow.icon_state = "clockwork_gateway_active"
|
||||
if(GATEWAY_RATVAR_COMING to GATEWAY_RATVAR_ARRIVAL)
|
||||
if(!third_sound_played)
|
||||
world << sound('sound/effects/clockcult_gateway_closing.ogg', 1, channel = 8, volume = 50)
|
||||
third_sound_played = TRUE
|
||||
make_glow()
|
||||
glow.icon_state = "clockwork_gateway_closing"
|
||||
if(GATEWAY_RATVAR_ARRIVAL to INFINITY)
|
||||
if(!purpose_fulfilled)
|
||||
countdown.stop()
|
||||
takes_damage = FALSE
|
||||
purpose_fulfilled = TRUE
|
||||
make_glow()
|
||||
animate(glow, transform = matrix() * 1.5, alpha = 255, time = 126)
|
||||
world << sound('sound/effects/ratvar_rises.ogg', 0, channel = 8) //End the sounds
|
||||
sleep(131)
|
||||
make_glow()
|
||||
animate(glow, transform = matrix() * 3, alpha = 0, time = 5)
|
||||
sleep(5)
|
||||
new/obj/structure/clockwork/massive/ratvar(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/clockwork/massive/celestial_gateway/examine(mob/user)
|
||||
icon_state = "spatial_gateway" //cheat wildly by pretending to have an icon
|
||||
..()
|
||||
icon_state = initial(icon_state)
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
var/arrival_text = "IMMINENT"
|
||||
if(GATEWAY_RATVAR_ARRIVAL - progress_in_seconds > 0)
|
||||
arrival_text = "[round(max((GATEWAY_RATVAR_ARRIVAL - progress_in_seconds) / (GATEWAY_SUMMON_RATE * 0.5), 0), 1)]"
|
||||
user << "<span class='big'><b>Seconds until Ratvar's arrival:</b> [arrival_text]s</span>"
|
||||
switch(progress_in_seconds)
|
||||
if(-INFINITY to GATEWAY_REEBE_FOUND)
|
||||
user << "<span class='heavy_brass'>It's still opening.</span>"
|
||||
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
|
||||
user << "<span class='heavy_brass'>It's reached the Celestial Derelict and is drawing power from it.</span>"
|
||||
if(GATEWAY_RATVAR_COMING to INFINITY)
|
||||
user << "<span class='heavy_brass'>Ratvar is coming through the gateway!</span>"
|
||||
else
|
||||
switch(progress_in_seconds)
|
||||
if(-INFINITY to GATEWAY_REEBE_FOUND)
|
||||
user << "<span class='warning'>It's a swirling mass of blackness.</span>"
|
||||
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
|
||||
user << "<span class='warning'>It seems to be leading somewhere.</span>"
|
||||
if(GATEWAY_RATVAR_COMING to INFINITY)
|
||||
user << "<span class='warning'><b>Something is coming through!</b></span>"
|
||||
|
||||
/obj/effect/clockwork/gateway_glow //the actual appearance of the Gateway to the Celestial Derelict; an object so the edges of the gate can be clicked through.
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "clockwork_gateway_charging"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
mouse_opacity = 0
|
||||
layer = MASSIVE_OBJ_LAYER
|
||||
var/obj/structure/clockwork/massive/celestial_gateway/linked_gate
|
||||
|
||||
/obj/effect/clockwork/gateway_glow/Destroy()
|
||||
if(linked_gate)
|
||||
linked_gate.glow = null
|
||||
linked_gate = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/clockwork/gateway_glow/examine(mob/user)
|
||||
if(linked_gate)
|
||||
linked_gate.examine(user)
|
||||
|
||||
/obj/effect/clockwork/gateway_glow/ex_act(severity, target)
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/structure/clockwork/massive/ratvar
|
||||
name = "Ratvar, the Clockwork Justiciar"
|
||||
desc = "<span class='userdanger'>What is what is what are what real what is all a lie all a lie it's all a lie why how can what is</span>"
|
||||
clockwork_desc = "<span class='large_brass'><b><i>Ratvar, the Clockwork Justiciar, your master eternal.</i></b></span>"
|
||||
icon = 'icons/effects/512x512.dmi'
|
||||
icon_state = "ratvar"
|
||||
pixel_x = -235
|
||||
pixel_y = -248
|
||||
takes_damage = FALSE
|
||||
var/atom/prey //Whatever Ratvar is chasing
|
||||
var/clashing = FALSE //If Ratvar is FUCKING FIGHTING WITH NAR-SIE
|
||||
var/proselytize_range = 10
|
||||
|
||||
/obj/structure/clockwork/massive/ratvar/New()
|
||||
..()
|
||||
ratvar_awakens = TRUE
|
||||
for(var/obj/item/clockwork/ratvarian_spear/R in all_clockwork_objects)
|
||||
R.update_force()
|
||||
START_PROCESSING(SSobj, src)
|
||||
world << "<span class='heavy_brass'><font size=6>\"BAPR NTNVA ZL YVTUG FUNYY FUVAR NPEBFF GUVF CNGURGVP ERNYZ!!\"</font></span>"
|
||||
world << 'sound/effects/ratvar_reveal.ogg'
|
||||
var/image/alert_overlay = image('icons/effects/clockwork_effects.dmi', "ratvar_alert")
|
||||
var/area/A = get_area(src)
|
||||
notify_ghosts("The Justiciar's light calls to you! Reach out to Ratvar in [A.name] to be granted a shell to spread his glory!", null, source = src, alert_overlay = alert_overlay)
|
||||
addtimer(SSshuttle.emergency, "request", 50, FALSE, null, 0.3)
|
||||
|
||||
|
||||
/obj/structure/clockwork/massive/ratvar/Destroy()
|
||||
ratvar_awakens = FALSE
|
||||
for(var/obj/item/clockwork/ratvarian_spear/R in all_clockwork_objects)
|
||||
R.update_force()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
world << "<span class='heavy_brass'><font size=6>\"NO! I will not... be...</font> <font size=5>banished...</font> <font size=4>again...\"</font></span>"
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/clockwork/massive/ratvar/attack_ghost(mob/dead/observer/O)
|
||||
var/alertresult = alert(O, "Embrace the Justiciar's light? You can no longer be cloned!",,"Cogscarab", "Reclaimer", "No")
|
||||
if(alertresult == "No" || !O)
|
||||
return 0
|
||||
var/mob/living/simple_animal/R
|
||||
if(alertresult == "Cogscarab")
|
||||
R = new/mob/living/simple_animal/drone/cogscarab/ratvar(get_turf(src))
|
||||
R.visible_message("<span class='heavy_brass'>[R] forms, and its eyes blink open, glowing bright red!</span>")
|
||||
else
|
||||
R = new/mob/living/simple_animal/hostile/clockwork/reclaimer(get_turf(src))
|
||||
R.visible_message("<span class='heavy_brass'>[R] forms, and it emits a faint hum!</span>")
|
||||
R.key = O.key
|
||||
|
||||
|
||||
/obj/structure/clockwork/massive/ratvar/Bump(atom/A)
|
||||
forceMove(get_turf(A))
|
||||
A.ratvar_act()
|
||||
|
||||
|
||||
/obj/structure/clockwork/massive/ratvar/Process_Spacemove()
|
||||
return clashing
|
||||
|
||||
|
||||
/obj/structure/clockwork/massive/ratvar/process()
|
||||
if(clashing) //I'm a bit occupied right now, thanks
|
||||
return
|
||||
for(var/atom/A in range(proselytize_range, src))
|
||||
A.ratvar_act()
|
||||
var/dir_to_step_in = pick(cardinal)
|
||||
if(!prey)
|
||||
for(var/obj/singularity/narsie/N in poi_list)
|
||||
if(N.z == z)
|
||||
prey = N
|
||||
break
|
||||
if(!prey) //In case there's a Nar-Sie
|
||||
var/list/meals = list()
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(L.z == z && !is_servant_of_ratvar(L) && L.mind)
|
||||
meals += L
|
||||
if(meals.len)
|
||||
prey = pick(meals)
|
||||
prey << "<span class='heavy_brass'><font size=5>\"You will do.\"</font></span>\n\
|
||||
<span class='userdanger'>Something very large and very malevolent begins lumbering its way towards you...</span>"
|
||||
prey << 'sound/effects/ratvar_reveal.ogg'
|
||||
else
|
||||
if(prob(10) || is_servant_of_ratvar(prey) || prey.z != z)
|
||||
prey << "<span class='heavy_brass'><font size=5>\"How dull. Leave me.\"</font></span>\n\
|
||||
<span class='userdanger'>You feel tremendous relief as a set of horrible eyes loses sight of you...</span>"
|
||||
prey = null
|
||||
else
|
||||
dir_to_step_in = get_dir(src, prey) //Unlike Nar-Sie, Ratvar ruthlessly chases down his target
|
||||
step(src, dir_to_step_in)
|
||||
|
||||
/obj/structure/clockwork/massive/ratvar/narsie_act()
|
||||
if(clashing)
|
||||
return 0
|
||||
clashing = TRUE
|
||||
world << "<span class='heavy_brass'><font size=5>\"[pick("BLOOD GOD!!!", "NAR-SIE!!!", "AT LAST, YOUR TIME HAS COME!")]\"</font></span>"
|
||||
world << "<span class='cult'><font size=5>\"<b>Ratvar?! How?!</b>\"</font></span>"
|
||||
for(var/obj/singularity/narsie/N in range(15, src))
|
||||
if(N.clashing)
|
||||
continue
|
||||
N.clashing = TRUE
|
||||
clash_of_the_titans(N) //IT'S TIME FOR THE BATTLE OF THE AGES
|
||||
break
|
||||
return 1
|
||||
|
||||
/obj/structure/clockwork/massive/ratvar/proc/clash_of_the_titans(obj/singularity/narsie/narsie)
|
||||
var/winner = "Undeclared"
|
||||
var/base_victory_chance = 0
|
||||
while(TRUE)
|
||||
world << 'sound/magic/clockwork/ratvar_attack.ogg'
|
||||
sleep(5.2)
|
||||
for(var/mob/M in mob_list)
|
||||
if(M.client)
|
||||
M.client.color = rgb(150, 100, 0)
|
||||
spawn(1)
|
||||
M.client.color = initial(M.client.color)
|
||||
shake_camera(M, 4, 3)
|
||||
var/r_success_modifier = (ticker.mode.servants_of_ratvar.len * 2) //2% for each cultist
|
||||
var/n_success_modifier = (ticker.mode.cult.len * 2)
|
||||
for(var/mob/living/simple_animal/hostile/construct/harvester/C in player_list)
|
||||
n_success_modifier += 2
|
||||
if(prob(base_victory_chance + r_success_modifier))
|
||||
winner = "Ratvar"
|
||||
break
|
||||
sleep(rand(2,5))
|
||||
world << 'sound/magic/clockwork/narsie_attack.ogg'
|
||||
sleep(7.4)
|
||||
for(var/mob/M in mob_list)
|
||||
if(M.client)
|
||||
M.client.color = rgb(200, 0, 0)
|
||||
spawn(1)
|
||||
M.client.color = initial(M.client.color)
|
||||
shake_camera(M, 4, 3)
|
||||
if(prob(base_victory_chance + n_success_modifier))
|
||||
winner = "Nar-Sie"
|
||||
break
|
||||
base_victory_chance++ //The clash has a higher chance of resolving each time both gods attack one another
|
||||
switch(winner)
|
||||
if("Ratvar")
|
||||
world << "<span class='heavy_brass'><font size=5>\"[pick("DIE! DIE! DIE!", "REEEEEEEEE!", "FILTH!!!", "SUFFER!!!", "EBG SBE PRAGHEVRF NF V UNIR!!")]\"</font></span>" //nar-sie get out
|
||||
world << "<span class='cult'><font size=5>\"<b>[pick("Nooooo...", "Not die. To y-", "Die. Ratv-", "Sas tyen re-")]\"</b></font></span>"
|
||||
world << 'sound/magic/clockwork/anima_fragment_attack.ogg'
|
||||
world << 'sound/magic/demon_dies.ogg'
|
||||
clashing = FALSE
|
||||
qdel(narsie)
|
||||
return 1
|
||||
if("Nar-Sie")
|
||||
world << "<span class='cult'><font size=5>\"<b>[pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")]</b>\"</font></span>" //Broken English
|
||||
world << 'sound/magic/demon_attack1.ogg'
|
||||
world << 'sound/magic/clockwork/anima_fragment_death.ogg'
|
||||
narsie.clashing = FALSE
|
||||
qdel(src)
|
||||
return 1
|
||||
@@ -1,955 +0,0 @@
|
||||
//////////////////////////
|
||||
// CLOCKWORK STRUCTURES //
|
||||
//////////////////////////
|
||||
|
||||
/obj/structure/clockwork
|
||||
name = "meme structure"
|
||||
desc = "Some frog or something, the fuck?"
|
||||
var/clockwork_desc //Shown to servants when they examine
|
||||
icon = 'icons/obj/clockwork_objects.dmi'
|
||||
icon_state = "rare_pepe"
|
||||
anchored = 1
|
||||
density = 1
|
||||
opacity = 0
|
||||
layer = BELOW_OBJ_LAYER
|
||||
var/max_health = 100 //All clockwork structures have health that can be removed via attacks
|
||||
var/health = 100
|
||||
var/repair_amount = 5 //how much a proselytizer can repair each cycle
|
||||
var/can_be_repaired = TRUE //if a proselytizer can repair it at all
|
||||
var/takes_damage = TRUE //If the structure can be damaged
|
||||
var/break_message = "<span class='warning'>The frog isn't a meme after all!</span>" //The message shown when a structure breaks
|
||||
var/break_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' //The sound played when a structure breaks
|
||||
var/list/debris = list(/obj/item/clockwork/alloy_shards) //Parts left behind when a structure breaks
|
||||
var/construction_value = 0 //How much value the structure contributes to the overall "power" of the structures on the station
|
||||
|
||||
/obj/structure/clockwork/New()
|
||||
..()
|
||||
clockwork_construction_value += construction_value
|
||||
all_clockwork_objects += src
|
||||
|
||||
/obj/structure/clockwork/Destroy()
|
||||
clockwork_construction_value -= construction_value
|
||||
all_clockwork_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/clockwork/proc/destroyed()
|
||||
if(!takes_damage)
|
||||
return 0
|
||||
for(var/I in debris)
|
||||
new I (get_turf(src))
|
||||
visible_message(break_message)
|
||||
playsound(src, break_sound, 50, 1)
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
/obj/structure/clockwork/burn()
|
||||
SSobj.burning -= src
|
||||
if(takes_damage)
|
||||
playsound(src, 'sound/items/Welder.ogg', 100, 1)
|
||||
visible_message("<span class='warning'>[src] is warped by the heat!</span>")
|
||||
take_damage(rand(50, 100), BURN)
|
||||
|
||||
/obj/structure/clockwork/proc/take_damage(amount, damage_type)
|
||||
if(!amount || !damage_type || !damage_type in list(BRUTE, BURN))
|
||||
return 0
|
||||
if(takes_damage)
|
||||
health = max(0, health - amount)
|
||||
if(!health)
|
||||
destroyed()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/structure/clockwork/narsie_act()
|
||||
if(take_damage(rand(25, 50), BRUTE) && src) //if we still exist
|
||||
var/previouscolor = color
|
||||
color = "#960000"
|
||||
animate(src, color = previouscolor, time = 8)
|
||||
|
||||
/obj/structure/clockwork/ex_act(severity)
|
||||
var/damage = 0
|
||||
switch(severity)
|
||||
if(1)
|
||||
damage = max_health //100% max health lost
|
||||
if(2)
|
||||
damage = max_health * rand(0.5, 0.7) //50-70% max health lost
|
||||
if(3)
|
||||
damage = max_health * rand(0.1, 0.3) //10-30% max health lost
|
||||
if(damage)
|
||||
take_damage(damage, BRUTE)
|
||||
|
||||
/obj/structure/clockwork/examine(mob/user)
|
||||
var/can_see_clockwork = is_servant_of_ratvar(user) || isobserver(user)
|
||||
if(can_see_clockwork && clockwork_desc)
|
||||
desc = clockwork_desc
|
||||
..()
|
||||
desc = initial(desc)
|
||||
if(takes_damage)
|
||||
var/servant_message = "It is at <b>[health]/[max_health]</b> integrity"
|
||||
var/other_message = "It seems pristine and undamaged"
|
||||
var/heavily_damaged = FALSE
|
||||
var/healthpercent = (health/max_health) * 100
|
||||
if(healthpercent >= 100)
|
||||
other_message = "It seems pristine and undamaged"
|
||||
else if(healthpercent >= 50)
|
||||
other_message = "It looks slightly dented"
|
||||
else if(healthpercent >= 25)
|
||||
other_message = "It appears heavily damaged"
|
||||
heavily_damaged = TRUE
|
||||
else if(healthpercent >= 0)
|
||||
other_message = "It's falling apart"
|
||||
heavily_damaged = TRUE
|
||||
user << "<span class='[heavily_damaged ? "alloy":"brass"]'>[can_see_clockwork ? "[servant_message]":"[other_message]"][heavily_damaged ? "!":"."]</span>"
|
||||
|
||||
/obj/structure/clockwork/bullet_act(obj/item/projectile/P)
|
||||
. = ..()
|
||||
visible_message("<span class='danger'>[src] is hit by \a [P]!</span>")
|
||||
playsound(src, P.hitsound, 50, 1)
|
||||
take_damage(P.damage, P.damage_type)
|
||||
|
||||
/obj/structure/clockwork/proc/attack_generic(mob/user, damage = 0, damage_type = BRUTE) //used by attack_alien, attack_animal, and attack_slime
|
||||
user.do_attack_animation(src)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.visible_message("<span class='danger'>[user] smashes into [src]!</span>")
|
||||
take_damage(damage, damage_type)
|
||||
|
||||
/obj/structure/clockwork/attack_alien(mob/living/user)
|
||||
playsound(src, 'sound/weapons/bladeslice.ogg', 50, 1)
|
||||
attack_generic(user, 15)
|
||||
|
||||
/obj/structure/clockwork/attack_animal(mob/living/simple_animal/M)
|
||||
if(!M.melee_damage_upper)
|
||||
return
|
||||
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||
attack_generic(M, M.melee_damage_upper, M.melee_damage_type)
|
||||
|
||||
/obj/structure/clockwork/attack_slime(mob/living/simple_animal/slime/user)
|
||||
if(!user.is_adult)
|
||||
return
|
||||
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||
attack_generic(user, rand(10, 15))
|
||||
|
||||
/obj/structure/clockwork/attacked_by(obj/item/I, mob/living/user)
|
||||
. = ..()
|
||||
if(I.force && takes_damage)
|
||||
playsound(src, I.hitsound, 50, 1)
|
||||
take_damage(I.force, I.damtype)
|
||||
|
||||
/obj/structure/clockwork/mech_melee_attack(obj/mecha/M)
|
||||
if(..())
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
take_damage(M.force, M.damtype)
|
||||
|
||||
/obj/structure/clockwork/cache //Tinkerer's cache: Stores components for later use.
|
||||
name = "tinkerer's cache"
|
||||
desc = "A large brass spire with a flaming hole in its center."
|
||||
clockwork_desc = "A brass container capable of storing a large amount of components.\n\
|
||||
Shares components with all other caches and will gradually generate components if near a Clockwork Wall."
|
||||
icon_state = "tinkerers_cache"
|
||||
construction_value = 10
|
||||
break_message = "<span class='warning'>The cache's fire winks out before it falls in on itself!</span>"
|
||||
max_health = 80
|
||||
health = 80
|
||||
var/wall_generation_cooldown
|
||||
var/wall_found = FALSE //if we've found a wall and finished our windup delay
|
||||
|
||||
/obj/structure/clockwork/cache/New()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
clockwork_caches++
|
||||
set_light(2,1)
|
||||
|
||||
/obj/structure/clockwork/cache/Destroy()
|
||||
clockwork_caches--
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/clockwork/cache/destroyed()
|
||||
if(takes_damage)
|
||||
for(var/I in src)
|
||||
var/atom/movable/A = I
|
||||
A.forceMove(get_turf(src)) //drop any daemons we have
|
||||
return ..()
|
||||
|
||||
/obj/structure/clockwork/cache/process()
|
||||
for(var/turf/closed/wall/clockwork/C in orange(1, src))
|
||||
if(!wall_found)
|
||||
wall_found = TRUE
|
||||
wall_generation_cooldown = world.time + CACHE_PRODUCTION_TIME
|
||||
visible_message("<span class='warning'>[src] starts to whirr in the presence of [C]...</span>")
|
||||
break
|
||||
if(wall_generation_cooldown <= world.time)
|
||||
wall_generation_cooldown = world.time + CACHE_PRODUCTION_TIME
|
||||
generate_cache_component()
|
||||
playsound(C, 'sound/magic/clockwork/fellowship_armory.ogg', rand(15, 20), 1, -3, 1, 1)
|
||||
visible_message("<span class='warning'>Something clunks around inside of [src]...</span>")
|
||||
break
|
||||
|
||||
/obj/structure/clockwork/cache/attackby(obj/item/I, mob/living/user, params)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return ..()
|
||||
if(istype(I, /obj/item/clockwork/component))
|
||||
var/obj/item/clockwork/component/C = I
|
||||
clockwork_component_cache[C.component_id]++
|
||||
user << "<span class='notice'>You add [C] to [src].</span>"
|
||||
user.drop_item()
|
||||
qdel(C)
|
||||
return 1
|
||||
else if(istype(I, /obj/item/clockwork/slab))
|
||||
var/obj/item/clockwork/slab/S = I
|
||||
clockwork_component_cache["belligerent_eye"] += S.stored_components["belligerent_eye"]
|
||||
clockwork_component_cache["vanguard_cogwheel"] += S.stored_components["vanguard_cogwheel"]
|
||||
clockwork_component_cache["guvax_capacitor"] += S.stored_components["guvax_capacitor"]
|
||||
clockwork_component_cache["replicant_alloy"] += S.stored_components["replicant_alloy"]
|
||||
clockwork_component_cache["hierophant_ansible"] += S.stored_components["hierophant_ansible"]
|
||||
S.stored_components["belligerent_eye"] = 0
|
||||
S.stored_components["vanguard_cogwheel"] = 0
|
||||
S.stored_components["guvax_capacitor"] = 0
|
||||
S.stored_components["replicant_alloy"] = 0
|
||||
S.stored_components["hierophant_ansible"] = 0
|
||||
user.visible_message("<span class='notice'>[user] empties [S] into [src].</span>", "<span class='notice'>You offload your slab's components into [src].</span>")
|
||||
return 1
|
||||
else if(istype(I, /obj/item/clockwork/daemon_shell))
|
||||
var/component_type
|
||||
switch(alert(user, "Will this daemon produce a specific type of component or produce randomly?.", , "Specific Type", "Random Component"))
|
||||
if("Specific Type")
|
||||
switch(input(user, "Choose a component type.", name) as null|anything in list("Belligerent Eyes", "Vanguard Cogwheels", "Guvax Capacitors", "Replicant Alloys", "Hierophant Ansibles"))
|
||||
if("Belligerent Eyes")
|
||||
component_type = "belligerent_eye"
|
||||
if("Vanguard Cogwheels")
|
||||
component_type = "vanguard_cogwheel"
|
||||
if("Guvax Capacitors")
|
||||
component_type = "guvax_capacitor"
|
||||
if("Replicant Alloys")
|
||||
component_type = "replicant_alloy"
|
||||
if("Hierophant Ansibles")
|
||||
component_type = "hierophant_ansibles"
|
||||
if(!user || !user.canUseTopic(src) || !user.canUseTopic(I))
|
||||
return 0
|
||||
var/obj/item/clockwork/tinkerers_daemon/D = new(src)
|
||||
D.cache = src
|
||||
D.specific_component = component_type
|
||||
user.visible_message("<span class='notice'>[user] spins the cogwheel on [I] and puts it into [src].</span>", \
|
||||
"<span class='notice'>You activate the daemon and put it into [src]. It will now produce a component every twenty seconds.</span>")
|
||||
user.drop_item()
|
||||
qdel(I)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/clockwork/cache/attack_hand(mob/user)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return 0
|
||||
var/list/possible_components = list()
|
||||
if(clockwork_component_cache["belligerent_eye"])
|
||||
possible_components += "Belligerent Eye"
|
||||
if(clockwork_component_cache["vanguard_cogwheel"])
|
||||
possible_components += "Vanguard Cogwheel"
|
||||
if(clockwork_component_cache["guvax_capacitor"])
|
||||
possible_components += "Guvax Capacitor"
|
||||
if(clockwork_component_cache["replicant_alloy"])
|
||||
possible_components += "Replicant Alloy"
|
||||
if(clockwork_component_cache["hierophant_ansible"])
|
||||
possible_components += "Hierophant Ansible"
|
||||
if(!possible_components.len)
|
||||
user << "<span class='warning'>[src] is empty!</span>"
|
||||
return 0
|
||||
var/component_to_withdraw = input(user, "Choose a component to withdraw.", name) as null|anything in possible_components
|
||||
if(!user || !user.canUseTopic(src) || !component_to_withdraw)
|
||||
return 0
|
||||
var/obj/item/clockwork/component/the_component
|
||||
switch(component_to_withdraw)
|
||||
if("Belligerent Eye")
|
||||
if(clockwork_component_cache["belligerent_eye"])
|
||||
the_component = new/obj/item/clockwork/component/belligerent_eye(get_turf(src))
|
||||
clockwork_component_cache["belligerent_eye"]--
|
||||
if("Vanguard Cogwheel")
|
||||
if(clockwork_component_cache["vanguard_cogwheel"])
|
||||
the_component = new/obj/item/clockwork/component/vanguard_cogwheel(get_turf(src))
|
||||
clockwork_component_cache["vanguard_cogwheel"]--
|
||||
if("Guvax Capacitor")
|
||||
if(clockwork_component_cache["guvax_capacitor"])
|
||||
the_component = new/obj/item/clockwork/component/guvax_capacitor(get_turf(src))
|
||||
clockwork_component_cache["guvax_capacitor"]--
|
||||
if("Replicant Alloy")
|
||||
if(clockwork_component_cache["replicant_alloy"])
|
||||
the_component = new/obj/item/clockwork/component/replicant_alloy(get_turf(src))
|
||||
clockwork_component_cache["replicant_alloy"]--
|
||||
if("Hierophant Ansible")
|
||||
if(clockwork_component_cache["hierophant_ansible"])
|
||||
the_component = new/obj/item/clockwork/component/hierophant_ansible(get_turf(src))
|
||||
clockwork_component_cache["hierophant_ansible"]--
|
||||
if(the_component)
|
||||
user.visible_message("<span class='notice'>[user] withdraws [the_component] from [src].</span>", "<span class='notice'>You withdraw [the_component] from [src].</span>")
|
||||
user.put_in_hands(the_component)
|
||||
return 1
|
||||
|
||||
/obj/structure/clockwork/cache/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<b>Stored components:</b>"
|
||||
user << "<span class='neovgre_small'><i>Belligerent Eyes:</i> [clockwork_component_cache["belligerent_eye"]]</span>"
|
||||
user << "<span class='inathneq_small'><i>Vanguard Cogwheels:</i> [clockwork_component_cache["vanguard_cogwheel"]]</span>"
|
||||
user << "<span class='sevtug_small'><i>Guvax Capacitors:</i> [clockwork_component_cache["guvax_capacitor"]]</span>"
|
||||
user << "<span class='nezbere_small'><i>Replicant Alloys:</i> [clockwork_component_cache["replicant_alloy"]]</span>"
|
||||
user << "<span class='nzcrentr_small'><i>Hierophant Ansibles:</i> [clockwork_component_cache["hierophant_ansible"]]</span>"
|
||||
|
||||
|
||||
/obj/structure/clockwork/ocular_warden //Ocular warden: Low-damage, low-range turret. Deals constant damage to whoever it makes eye contact with.
|
||||
name = "ocular warden"
|
||||
desc = "A large brass eye with tendrils trailing below it and a wide red iris."
|
||||
clockwork_desc = "A stalwart turret that will deal sustained damage to any non-faithful it sees."
|
||||
icon_state = "ocular_warden"
|
||||
health = 25
|
||||
max_health = 25
|
||||
construction_value = 15
|
||||
layer = HIGH_OBJ_LAYER
|
||||
break_message = "<span class='warning'>The warden's eye gives a glare of utter hate before falling dark!</span>"
|
||||
debris = list(/obj/item/clockwork/component/belligerent_eye/blind_eye)
|
||||
burn_state = LAVA_PROOF
|
||||
var/damage_per_tick = 3
|
||||
var/sight_range = 3
|
||||
var/mob/living/target
|
||||
var/list/idle_messages = list(" sulkily glares around.", " lazily drifts from side to side.", " looks around for something to burn.", " slowly turns in circles.")
|
||||
|
||||
/obj/structure/clockwork/ocular_warden/New()
|
||||
..()
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/structure/clockwork/ocular_warden/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/clockwork/ocular_warden/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='brass'>[target ? "<b>It's fixated on [target]!</b>" : "Its gaze is wandering aimlessly."]</span>"
|
||||
|
||||
/obj/structure/clockwork/ocular_warden/process()
|
||||
var/list/validtargets = acquire_nearby_targets()
|
||||
if(ratvar_awakens && (damage_per_tick == initial(damage_per_tick) || sight_range == initial(sight_range))) //Massive buff if Ratvar has returned
|
||||
damage_per_tick = 10
|
||||
sight_range = 5
|
||||
if(target)
|
||||
if(!(target in validtargets))
|
||||
lose_target()
|
||||
else
|
||||
if(!target.null_rod_check())
|
||||
target.adjustFireLoss(!iscultist(target) ? damage_per_tick : damage_per_tick * 2) //Nar-Sian cultists take additional damage
|
||||
if(ratvar_awakens && target)
|
||||
target.adjust_fire_stacks(damage_per_tick)
|
||||
target.IgniteMob()
|
||||
setDir(get_dir(get_turf(src), get_turf(target)))
|
||||
if(!target)
|
||||
if(validtargets.len)
|
||||
target = pick(validtargets)
|
||||
visible_message("<span class='warning'>[src] swivels to face [target]!</span>")
|
||||
target << "<span class='heavy_brass'>\"I SEE YOU!\"</span>\n<span class='userdanger'>[src]'s gaze [ratvar_awakens ? "melts you alive" : "burns you"]!</span>"
|
||||
if(target.null_rod_check() && !ratvar_awakens)
|
||||
target << "<span class='warning'>Your artifact glows hotly against you, protecting you from the warden's gaze!</span>"
|
||||
else if(prob(0.5)) //Extremely low chance because of how fast the subsystem it uses processes
|
||||
if(prob(50))
|
||||
visible_message("<span class='notice'>[src][pick(idle_messages)]</span>")
|
||||
else
|
||||
setDir(pick(cardinal))//Random rotation
|
||||
|
||||
/obj/structure/clockwork/ocular_warden/proc/acquire_nearby_targets()
|
||||
. = list()
|
||||
for(var/mob/living/L in viewers(sight_range, src)) //Doesn't attack the blind
|
||||
if(!is_servant_of_ratvar(L) && !L.stat && L.mind && !(L.disabilities & BLIND) && !L.null_rod_check())
|
||||
. += L
|
||||
|
||||
/obj/structure/clockwork/ocular_warden/proc/lose_target()
|
||||
if(!target)
|
||||
return 0
|
||||
target = null
|
||||
visible_message("<span class='warning'>[src] settles and seems almost disappointed.</span>")
|
||||
return 1
|
||||
|
||||
|
||||
/obj/structure/clockwork/shell
|
||||
construction_value = 0
|
||||
anchored = 0
|
||||
density = 0
|
||||
takes_damage = FALSE
|
||||
burn_state = LAVA_PROOF
|
||||
var/mobtype = /mob/living/simple_animal/hostile/clockwork
|
||||
var/spawn_message = " is an error and you should yell at whoever spawned this shell."
|
||||
|
||||
/obj/structure/clockwork/shell/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/device/mmi/posibrain/soul_vessel))
|
||||
if(!is_servant_of_ratvar(user))
|
||||
..()
|
||||
return 0
|
||||
var/obj/item/device/mmi/posibrain/soul_vessel/S = I
|
||||
if(!S.brainmob)
|
||||
user << "<span class='warning'>[S] hasn't trapped a spirit! Turn it on first.</span>"
|
||||
return 0
|
||||
if(S.brainmob && (!S.brainmob.client || !S.brainmob.mind))
|
||||
user << "<span class='warning'>[S]'s trapped spirit appears inactive!</span>"
|
||||
return 0
|
||||
user.visible_message("<span class='notice'>[user] places [S] in [src], where it fuses to the shell.</span>", "<span class='brass'>You place [S] in [src], fusing it to the shell.</span>")
|
||||
var/mob/living/simple_animal/A = new mobtype(get_turf(src))
|
||||
A.visible_message("<span class='brass'>[src][spawn_message]</span>")
|
||||
S.brainmob.mind.transfer_to(A)
|
||||
add_servant_of_ratvar(A, TRUE)
|
||||
user.drop_item()
|
||||
qdel(S)
|
||||
qdel(src)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/clockwork/shell/cogscarab
|
||||
name = "cogscarab shell"
|
||||
desc = "A small brass shell with a cube-shaped receptable in its center. It gives off an aura of obsessive perfectionism."
|
||||
clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a weak construct with an inbuilt proselytizer."
|
||||
icon_state = "clockdrone_shell"
|
||||
mobtype = /mob/living/simple_animal/drone/cogscarab
|
||||
spawn_message = "'s eyes blink open, glowing bright red."
|
||||
|
||||
/obj/structure/clockwork/shell/fragment //Anima fragment: Useless on its own, but can accept an active soul vessel to create a powerful construct.
|
||||
name = "fragment shell"
|
||||
desc = "A massive brass shell with a small cube-shaped receptable in its center. It gives off an aura of contained power."
|
||||
clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a powerful construct."
|
||||
icon_state = "anime_fragment"
|
||||
mobtype = /mob/living/simple_animal/hostile/clockwork/fragment
|
||||
spawn_message = " whirs and rises from the ground on a flickering jet of reddish fire."
|
||||
|
||||
|
||||
/obj/structure/clockwork/wall_gear
|
||||
name = "massive gear"
|
||||
icon_state = "wall_gear"
|
||||
climbable = TRUE
|
||||
max_health = 50
|
||||
health = 50
|
||||
desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it."
|
||||
clockwork_desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, just climb over it, or proselytize it into replicant alloy."
|
||||
break_message = "<span class='warning'>The gear breaks apart into shards of alloy!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards)
|
||||
|
||||
/obj/structure/clockwork/wall_gear/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/wrench))
|
||||
default_unfasten_wrench(user, I, 10)
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/obj/structure/clockwork/wall_gear/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='notice'>[src] is [anchored ? "secured to the floor":"mobile, and not secured"].</span>"
|
||||
|
||||
///////////////////////
|
||||
// CLOCKWORK EFFECTS //
|
||||
///////////////////////
|
||||
|
||||
/obj/effect/clockwork
|
||||
name = "meme machine"
|
||||
desc = "Still don't know what it is."
|
||||
var/clockwork_desc = "A fabled artifact from beyond the stars. Contains concentrated meme essence." //Shown to clockwork cultists instead of the normal description
|
||||
icon = 'icons/effects/clockwork_effects.dmi'
|
||||
icon_state = "ratvars_flame"
|
||||
anchored = 1
|
||||
density = 0
|
||||
opacity = 0
|
||||
burn_state = LAVA_PROOF
|
||||
|
||||
/obj/effect/clockwork/New()
|
||||
..()
|
||||
all_clockwork_objects += src
|
||||
|
||||
/obj/effect/clockwork/Destroy()
|
||||
all_clockwork_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/effect/clockwork/examine(mob/user)
|
||||
if((is_servant_of_ratvar(user) || isobserver(user)) && clockwork_desc)
|
||||
desc = clockwork_desc
|
||||
..()
|
||||
desc = initial(desc)
|
||||
|
||||
/obj/effect/clockwork/judicial_marker //Judicial marker: Created by the judicial visor. After three seconds, stuns any non-servants nearby and damages Nar-Sian cultists.
|
||||
name = "judicial marker"
|
||||
desc = "You get the feeling that you shouldn't be standing here."
|
||||
clockwork_desc = "A sigil that will soon erupt and smite any unenlightened nearby."
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
layer = BELOW_MOB_LAYER
|
||||
var/mob/user
|
||||
|
||||
/obj/effect/clockwork/judicial_marker/New(loc, caster)
|
||||
..()
|
||||
user = caster
|
||||
playsound(src, 'sound/magic/MAGIC_MISSILE.ogg', 50, 1, 1, 1)
|
||||
flick("judicial_marker", src)
|
||||
addtimer(src, "burstanim", 16, FALSE)
|
||||
|
||||
/obj/effect/clockwork/judicial_marker/proc/burstanim()
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
flick("judicial_explosion", src)
|
||||
addtimer(src, "judicialblast", 13, FALSE)
|
||||
|
||||
/obj/effect/clockwork/judicial_marker/proc/judicialblast()
|
||||
var/targetsjudged = 0
|
||||
playsound(src, 'sound/effects/explosionfar.ogg', 100, 1, 1, 1)
|
||||
for(var/mob/living/L in range(1, src))
|
||||
if(is_servant_of_ratvar(L))
|
||||
continue
|
||||
if(L.null_rod_check())
|
||||
var/obj/item/I = L.null_rod_check()
|
||||
L.visible_message("<span class='warning'>Strange energy flows into [L]'s [I.name]!</span>", \
|
||||
"<span class='userdanger'>Your [I.name] shields you from [src]!</span>")
|
||||
continue
|
||||
if(!iscultist(L))
|
||||
L.visible_message("<span class='warning'>[L] is struck by a judicial explosion!</span>", \
|
||||
"<span class='userdanger'>[!issilicon(L) ? "An unseen force slams you into the ground!" : "ERROR: Motor servos disabled by external source!"]</span>")
|
||||
L.Weaken(8)
|
||||
else
|
||||
L.visible_message("<span class='warning'>[L] is struck by a judicial explosion!</span>", \
|
||||
"<span class='heavy_brass'>\"Keep an eye out, filth.\"</span>\n<span class='userdanger'>A burst of heat crushes you against the ground!</span>")
|
||||
L.Weaken(4) //half the stun, but sets cultists on fire
|
||||
L.adjust_fire_stacks(2)
|
||||
L.IgniteMob()
|
||||
targetsjudged++
|
||||
L.adjustBruteLoss(10)
|
||||
user << "<span class='brass'><b>[targetsjudged ? "Successfully judged <span class='neovgre'>[targetsjudged]</span>":"Judged no"] heretic[!targetsjudged || targetsjudged > 1 ? "s":""].</b></span>"
|
||||
QDEL_IN(src, 3) //so the animation completes properly
|
||||
|
||||
/obj/effect/clockwork/judicial_marker/ex_act(severity)
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway //Spatial gateway: A usually one-way rift to another location.
|
||||
name = "spatial gateway"
|
||||
desc = "A gently thrumming tear in reality."
|
||||
clockwork_desc = "A gateway in reality."
|
||||
icon_state = "spatial_gateway"
|
||||
density = 1
|
||||
var/sender = TRUE //If this gateway is made for sending, not receiving
|
||||
var/both_ways = FALSE
|
||||
var/lifetime = 25 //How many deciseconds this portal will last
|
||||
var/uses = 1 //How many objects or mobs can go through the portal
|
||||
var/obj/effect/clockwork/spatial_gateway/linked_gateway //The gateway linked to this one
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/New()
|
||||
..()
|
||||
spawn(1)
|
||||
if(!linked_gateway)
|
||||
qdel(src)
|
||||
return 0
|
||||
if(both_ways)
|
||||
clockwork_desc = "A gateway in reality. It can both send and receive objects."
|
||||
else
|
||||
clockwork_desc = "A gateway in reality. It can only [sender ? "send" : "receive"] objects."
|
||||
QDEL_IN(src, lifetime)
|
||||
|
||||
//set up a gateway with another gateway
|
||||
/obj/effect/clockwork/spatial_gateway/proc/setup_gateway(obj/effect/clockwork/spatial_gateway/gatewayB, set_duration, set_uses, two_way)
|
||||
if(!gatewayB || !set_duration || !uses)
|
||||
return 0
|
||||
linked_gateway = gatewayB
|
||||
gatewayB.linked_gateway = src
|
||||
if(two_way)
|
||||
both_ways = TRUE
|
||||
gatewayB.both_ways = TRUE
|
||||
else
|
||||
sender = TRUE
|
||||
gatewayB.sender = FALSE
|
||||
gatewayB.density = FALSE
|
||||
lifetime = set_duration
|
||||
gatewayB.lifetime = set_duration
|
||||
uses = set_uses
|
||||
gatewayB.uses = set_uses
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='brass'>It has [uses] uses remaining.</span>"
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user)
|
||||
if(user.pulling && user.a_intent == "grab" && isliving(user.pulling))
|
||||
var/mob/living/L = user.pulling
|
||||
if(L.buckled || L.anchored || L.has_buckled_mobs())
|
||||
return 0
|
||||
user.visible_message("<span class='warning'>[user] shoves [L] into [src]!</span>", "<span class='danger'>You shove [L] into [src]!</span>")
|
||||
user.stop_pulling()
|
||||
pass_through_gateway(L)
|
||||
return 1
|
||||
if(!user.canUseTopic(src))
|
||||
return 0
|
||||
user.visible_message("<span class='warning'>[user] climbs through [src]!</span>", "<span class='danger'>You brace yourself and step through [src]...</span>")
|
||||
pass_through_gateway(user)
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/weapon/nullrod))
|
||||
user.visible_message("<span class='warning'>[user] dispels [src] with [I]!</span>", "<span class='danger'>You close [src] with [I]!</span>")
|
||||
qdel(linked_gateway)
|
||||
qdel(src)
|
||||
return 1
|
||||
if(istype(I, /obj/item/clockwork/slab))
|
||||
user << "<span class='heavy_brass'>\"I don't think you want to drop your slab into that\".\n\"If you really want to, try throwing it.\"</span>"
|
||||
return 1
|
||||
if(user.drop_item())
|
||||
user.visible_message("<span class='warning'>[user] drops [I] into [src]!</span>", "<span class='danger'>You drop [I] into [src]!</span>")
|
||||
pass_through_gateway(I)
|
||||
..()
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/Bumped(atom/A)
|
||||
..()
|
||||
if(isliving(A) || istype(A, /obj/item))
|
||||
pass_through_gateway(A)
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/proc/pass_through_gateway(atom/movable/A)
|
||||
if(!linked_gateway)
|
||||
qdel(src)
|
||||
return 0
|
||||
if(!sender)
|
||||
visible_message("<span class='warning'>[A] bounces off of [src]!</span>")
|
||||
return 0
|
||||
if(!uses)
|
||||
return 0
|
||||
if(isliving(A))
|
||||
var/mob/living/user = A
|
||||
user << "<span class='warning'><b>You pass through [src] and appear elsewhere!</b></span>"
|
||||
linked_gateway.visible_message("<span class='warning'>A shape appears in [linked_gateway] before emerging!</span>")
|
||||
playsound(src, 'sound/effects/EMPulse.ogg', 50, 1)
|
||||
playsound(linked_gateway, 'sound/effects/EMPulse.ogg', 50, 1)
|
||||
transform = matrix() * 1.5
|
||||
animate(src, transform = matrix() / 1.5, time = 10)
|
||||
linked_gateway.transform = matrix() * 1.5
|
||||
animate(linked_gateway, transform = matrix() / 1.5, time = 10)
|
||||
A.forceMove(get_turf(linked_gateway))
|
||||
uses = max(0, uses - 1)
|
||||
linked_gateway.uses = max(0, linked_gateway.uses - 1)
|
||||
spawn(10)
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
qdel(linked_gateway)
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/general_marker
|
||||
name = "general marker"
|
||||
desc = "Some big guy. For you."
|
||||
clockwork_desc = "One of Ratvar's generals."
|
||||
alpha = 200
|
||||
layer = MASSIVE_OBJ_LAYER
|
||||
|
||||
/obj/effect/clockwork/general_marker/New()
|
||||
..()
|
||||
playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
|
||||
animate(src, alpha = 0, time = 10)
|
||||
QDEL_IN(src, 10)
|
||||
|
||||
/obj/effect/clockwork/general_marker/nezbere
|
||||
name = "Nezbere, the Brass Eidolon"
|
||||
desc = "A towering colossus clad in nigh-impenetrable brass armor. Its gaze is stern yet benevolent, even upon you."
|
||||
clockwork_desc = "One of Ratvar's four generals. Nezbere is responsible for the design, testing, and creation of everything in Ratvar's domain."
|
||||
icon = 'icons/effects/340x428.dmi'
|
||||
icon_state = "nezbere"
|
||||
pixel_x = -154
|
||||
pixel_y = -198
|
||||
|
||||
/obj/effect/clockwork/general_marker/sevtug
|
||||
name = "Sevtug, the Formless Pariah"
|
||||
desc = "A sinister cloud of purple energy. Looking at it gives you a headache."
|
||||
clockwork_desc = "One of Ratvar's four generals. Sevtug taught him how to manipulate minds and is one of his oldest allies."
|
||||
icon = 'icons/effects/211x247.dmi'
|
||||
icon_state = "sevtug"
|
||||
pixel_x = -89
|
||||
pixel_y = -107
|
||||
|
||||
/obj/effect/clockwork/general_marker/nzcrentr
|
||||
name = "Nzcrentr, the Forgotten Arbiter"
|
||||
desc = "A terrifying war machine crackling with limitless energy."
|
||||
clockwork_desc = "One of Ratvar's four generals. Nzcrentr is the result of Neovgre - Nezbere's finest war machine, commandeerable only be a mortal - fusing with its pilot and driving her \
|
||||
insane. Nzcrentr seeks out any and all sentient life to slaughter it for sport."
|
||||
icon = 'icons/effects/254x361.dmi'
|
||||
icon_state = "nzcrentr"
|
||||
pixel_x = -111
|
||||
pixel_y = -164
|
||||
|
||||
/obj/effect/clockwork/general_marker/inathneq
|
||||
name = "Inath-Neq, the Resonant Cogwheel"
|
||||
desc = "A humanoid form blazing with blue fire. It radiates an aura of kindness and caring."
|
||||
clockwork_desc = "One of Ratvar's four generals. Before her current form, Inath-Neq was a powerful warrior priestess commanding the Resonant Cogs, a sect of Ratvarian warriors renowned for \
|
||||
their prowess. After a lost battle with Nar-Sian cultists, Inath-Neq was struck down and stated in her dying breath, \
|
||||
\"The Resonant Cogs shall not fall silent this day, but will come together to form a wheel that shall never stop turning.\" Ratvar, touched by this, granted Inath-Neq an eternal body and \
|
||||
merged her soul with those of the Cogs slain with her on the battlefield."
|
||||
icon = 'icons/effects/187x381.dmi'
|
||||
icon_state = "inath-neq"
|
||||
pixel_x = -77
|
||||
pixel_y = -174
|
||||
|
||||
|
||||
/obj/effect/clockwork/sigil //Sigils: Rune-like markings on the ground with various effects.
|
||||
name = "sigil"
|
||||
desc = "A strange set of markings drawn on the ground."
|
||||
clockwork_desc = "A sigil of some purpose."
|
||||
icon_state = "sigil"
|
||||
layer = LOW_OBJ_LAYER
|
||||
alpha = 50
|
||||
burn_state = FIRE_PROOF
|
||||
burntime = 1
|
||||
var/affects_servants = FALSE
|
||||
var/stat_affected = CONSCIOUS
|
||||
|
||||
/obj/effect/clockwork/sigil/attack_hand(mob/user)
|
||||
if(iscarbon(user) && !user.stat && (!is_servant_of_ratvar(user) || (is_servant_of_ratvar(user) && user.a_intent == "harm")))
|
||||
user.visible_message("<span class='warning'>[user] stamps out [src]!</span>", "<span class='danger'>You stomp on [src], scattering it into thousands of particles.</span>")
|
||||
qdel(src)
|
||||
return 1
|
||||
..()
|
||||
|
||||
/obj/effect/clockwork/sigil/Crossed(atom/movable/AM)
|
||||
..()
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(L.stat <= stat_affected)
|
||||
if((!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && affects_servants)) && L.mind)
|
||||
if(L.null_rod_check())
|
||||
var/obj/item/I = L.null_rod_check()
|
||||
L.visible_message("<span class='warning'>[L]'s [I.name] protects them from [src]'s effects!</span>", "<span class='userdanger'>Your [I.name] protects you!</span>")
|
||||
return
|
||||
sigil_effects(L)
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/proc/sigil_effects(mob/living/L)
|
||||
|
||||
/obj/effect/clockwork/sigil/transgression //Sigil of Transgression: Stuns and flashes the first non-servant to walk on it. Nar-Sian cultists are damaged and knocked down for about twice the stun
|
||||
name = "dull sigil"
|
||||
desc = "A dull, barely-visible golden sigil. It's as though light was carved into the ground."
|
||||
icon = 'icons/effects/clockwork_effects.dmi'
|
||||
clockwork_desc = "A sigil that will stun the first non-servant to cross it. Nar-Sie's dogs will be knocked down."
|
||||
icon_state = "sigildull"
|
||||
color = "#FAE48C"
|
||||
|
||||
/obj/effect/clockwork/sigil/transgression/sigil_effects(mob/living/L)
|
||||
var/target_flashed = L.flash_eyes()
|
||||
for(var/mob/living/M in viewers(5, src))
|
||||
if(!is_servant_of_ratvar(M) && M != L)
|
||||
M.flash_eyes()
|
||||
if(iscultist(L))
|
||||
L << "<span class='heavy_brass'>\"Watch your step, wretch.\"</span>"
|
||||
L.adjustBruteLoss(10)
|
||||
L.Weaken(4)
|
||||
L.visible_message("<span class='warning'>[src] appears around [L] in a burst of light!</span>", \
|
||||
"<span class='userdanger'>[target_flashed ? "An unseen force":"The glowing sigil around you"] holds you in place!</span>")
|
||||
L.Stun(3)
|
||||
PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/transgression, get_turf(src))
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/submission //Sigil of Submission: After a short time, converts any non-servant standing on it. Knocks down and silences them for five seconds afterwards.
|
||||
name = "ominous sigil"
|
||||
desc = "A luminous golden sigil. Something about it really bothers you."
|
||||
clockwork_desc = "A sigil that will enslave the first person to cross it, provided they remain on it for five seconds."
|
||||
icon_state = "sigilsubmission"
|
||||
color = "#FAE48C"
|
||||
alpha = 125
|
||||
stat_affected = UNCONSCIOUS
|
||||
var/convert_time = 50
|
||||
var/glow_light = 2 //soft light
|
||||
var/glow_falloff = 1
|
||||
var/delete_on_finish = TRUE
|
||||
var/sigil_name = "Sigil of Submission"
|
||||
var/glow_type
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/New()
|
||||
..()
|
||||
set_light(glow_light,glow_falloff)
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/proc/post_channel(mob/living/L)
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/sigil_effects(mob/living/L)
|
||||
visible_message("<span class='warning'>[src] begins to glow a piercing magenta!</span>")
|
||||
animate(src, color = "#AF0AAF", time = convert_time)
|
||||
var/obj/effect/overlay/temp/ratvar/sigil/glow
|
||||
if(glow_type)
|
||||
glow = PoolOrNew(glow_type, get_turf(src))
|
||||
animate(glow, alpha = 255, time = convert_time)
|
||||
var/I = 0
|
||||
while(I < convert_time && get_turf(L) == get_turf(src))
|
||||
I++
|
||||
sleep(1)
|
||||
if(get_turf(L) != get_turf(src))
|
||||
if(glow)
|
||||
qdel(glow)
|
||||
animate(src, color = initial(color), time = 20)
|
||||
visible_message("<span class='warning'>[src] slowly stops glowing!</span>")
|
||||
return 0
|
||||
post_channel(L)
|
||||
if(is_eligible_servant(L))
|
||||
L << "<span class='heavy_brass'>\"You belong to me now.\"</span>"
|
||||
add_servant_of_ratvar(L)
|
||||
L.Weaken(3) //Completely defenseless for about five seconds - mainly to give them time to read over the information they've just been presented with
|
||||
L.Stun(3)
|
||||
if(iscarbon(L))
|
||||
var/mob/living/carbon/C = L
|
||||
C.silent += 5
|
||||
var/message = "[sigil_name] in [get_area(src)] <span class='sevtug'>[is_servant_of_ratvar(L) ? "successfully converted" : "failed to convert"]</span>"
|
||||
for(var/M in mob_list)
|
||||
if(isobserver(M))
|
||||
var/link = FOLLOW_LINK(M, L)
|
||||
M << "[link] <span class='heavy_brass'>[message] [L.real_name]!</span>"
|
||||
else if(is_servant_of_ratvar(M))
|
||||
if(M == L)
|
||||
M << "<span class='heavy_brass'>[message] you!</span>"
|
||||
else
|
||||
M << "<span class='heavy_brass'>[message] [L.real_name]!</span>"
|
||||
if(delete_on_finish)
|
||||
qdel(src)
|
||||
else
|
||||
animate(src, color = initial(color), time = 20)
|
||||
visible_message("<span class='warning'>[src] slowly stops glowing!</span>")
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/accession //Sigil of Accession: After a short time, converts any non-servant standing on it though implants. Knocks down and silences them for five seconds afterwards.
|
||||
name = "terrifying sigil"
|
||||
desc = "A luminous brassy sigil. Something about it makes you want to flee."
|
||||
clockwork_desc = "A sigil that will enslave any person who crosses it, provided they remain on it for five seconds. \n\
|
||||
It can convert a mindshielded target once before disppearing, but can convert any number of non-implanted targets."
|
||||
icon_state = "sigiltransgression"
|
||||
color = "#A97F1B"
|
||||
alpha = 200
|
||||
glow_light = 4 //bright light
|
||||
glow_falloff = 3
|
||||
delete_on_finish = FALSE
|
||||
sigil_name = "Sigil of Accession"
|
||||
glow_type = /obj/effect/overlay/temp/ratvar/sigil/accession
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/accession/post_channel(mob/living/L)
|
||||
if(isloyal(L))
|
||||
delete_on_finish = TRUE
|
||||
L.visible_message("<span class='warning'>[L] visibly trembles!</span>", \
|
||||
"<span class='sevtug'>Lbh jvyy or zvar-naq-uvf. Guvf chal gevaxrg jvyy abg fgbc zr.</span>")
|
||||
for(var/obj/item/weapon/implant/mindshield/M in L)
|
||||
if(M.implanted)
|
||||
qdel(M)
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission
|
||||
name = "suspicious sigil"
|
||||
desc = "A glowing orange sigil. The air around it feels staticky."
|
||||
clockwork_desc = "A sigil that will serve as a battery for clockwork structures. Use Volt Void while standing on it to charge it."
|
||||
icon_state = "sigiltransmission"
|
||||
color = "#EC8A2D"
|
||||
alpha = 50
|
||||
var/power_charge = 2500 //starts with 2500W by default
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='[power_charge ? "brass":"alloy"]'>It is storing [power_charge]W of power.</span>"
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/sigil_effects(mob/living/L)
|
||||
if(power_charge)
|
||||
L << "<span class='brass'>You feel a slight, static shock.</span>"
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/New()
|
||||
..()
|
||||
alpha = min(initial(alpha) + power_charge*0.02, 255)
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/proc/modify_charge(amount)
|
||||
if(power_charge - amount < 0)
|
||||
return 0
|
||||
power_charge -= amount
|
||||
alpha = min(initial(alpha) + power_charge*0.02, 255)
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/vitality
|
||||
name = "comforting sigil"
|
||||
desc = "A faint blue sigil. Looking at it makes you feel protected."
|
||||
clockwork_desc = "A sigil that will drain non-servants that remain on it. Servants that remain on it will be healed if it has any vitality drained."
|
||||
icon_state = "sigilvitality"
|
||||
color = "#123456"
|
||||
alpha = 75
|
||||
affects_servants = TRUE
|
||||
stat_affected = DEAD
|
||||
var/vitality = 0
|
||||
var/base_revive_cost = 20
|
||||
var/sigil_active = FALSE
|
||||
var/animation_number = 3 //each cycle increments this by 1, at 4 it produces an animation and resets
|
||||
|
||||
/obj/effect/clockwork/sigil/vitality/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='[vitality ? "inathneq_small":"alloy"]'>It is storing [vitality] units of vitality.</span>"
|
||||
user << "<span class='inathneq_small'>It requires at least [base_revive_cost] units of vitality to revive dead servants, in addition to any damage the servant has.</span>"
|
||||
|
||||
/obj/effect/clockwork/sigil/vitality/sigil_effects(mob/living/L)
|
||||
if(L.suiciding || sigil_active || !is_servant_of_ratvar(L) && L.stat == DEAD)
|
||||
return 0
|
||||
visible_message("<span class='warning'>[src] begins to glow bright blue!</span>")
|
||||
animate(src, alpha = 255, time = 10)
|
||||
sleep(10)
|
||||
sigil_active = TRUE
|
||||
//as long as they're still on the sigil and are either not a servant or they're a servant AND it has remaining vitality
|
||||
while(L && (!is_servant_of_ratvar(L) && L.stat != DEAD || (is_servant_of_ratvar(L) && vitality)) && get_turf(L) == get_turf(src))
|
||||
if(animation_number >= 4)
|
||||
PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/vitality, get_turf(src))
|
||||
animation_number = 0
|
||||
animation_number++
|
||||
if(!is_servant_of_ratvar(L))
|
||||
var/vitality_drained = L.adjustToxLoss(1.5)
|
||||
if(vitality_drained)
|
||||
vitality += vitality_drained
|
||||
else
|
||||
break
|
||||
else
|
||||
var/clone_to_heal = L.getCloneLoss()
|
||||
var/tox_to_heal = L.getToxLoss()
|
||||
var/burn_to_heal = L.getFireLoss()
|
||||
var/brute_to_heal = L.getBruteLoss()
|
||||
var/oxy_to_heal = L.getOxyLoss()
|
||||
var/total_damage = clone_to_heal + tox_to_heal + burn_to_heal + brute_to_heal + oxy_to_heal
|
||||
if(L.stat == DEAD)
|
||||
var/revival_cost = base_revive_cost + total_damage - oxy_to_heal //ignores oxygen damage
|
||||
var/mob/dead/observer/ghost = L.get_ghost(TRUE)
|
||||
if(ghost)
|
||||
if(vitality >= revival_cost)
|
||||
ghost.reenter_corpse()
|
||||
L.revive(1, 1)
|
||||
playsound(L, 'sound/magic/Staff_Healing.ogg', 50, 1)
|
||||
L.visible_message("<span class='warning'>[L] suddenly gets back up, their mouth dripping blue ichor!</span>", "<span class='inathneq'>\"Lbh jvyy or bxnl, puvyq.\"</span>")
|
||||
vitality -= revival_cost
|
||||
break
|
||||
else
|
||||
break
|
||||
if(!total_damage)
|
||||
break
|
||||
var/vitality_for_cycle = min(vitality, 3)
|
||||
|
||||
if(clone_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, clone_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustCloneLoss(-healing)
|
||||
vitality -= healing
|
||||
|
||||
if(tox_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, tox_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustToxLoss(-healing)
|
||||
vitality -= healing
|
||||
|
||||
if(burn_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, burn_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustFireLoss(-healing)
|
||||
vitality -= healing
|
||||
|
||||
if(brute_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, brute_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustBruteLoss(-healing)
|
||||
vitality -= healing
|
||||
|
||||
if(oxy_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, oxy_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustOxyLoss(-healing)
|
||||
vitality -= healing
|
||||
sleep(2)
|
||||
|
||||
animation_number = initial(animation_number)
|
||||
sigil_active = FALSE
|
||||
animate(src, alpha = initial(alpha), time = 20)
|
||||
visible_message("<span class='warning'>[src] slowly stops glowing!</span>")
|
||||
@@ -1,178 +0,0 @@
|
||||
//sends messages via hierophant
|
||||
/proc/send_hierophant_message(mob/user, message, name_span = "heavy_brass", message_span = "brass", user_title = "Servant")
|
||||
if(!user || !message || !ticker || !ticker.mode)
|
||||
return 0
|
||||
var/parsed_message = "<span class='[name_span]'>[user_title ? "[user_title] ":""][findtextEx(user.name, user.real_name) ? user.name : "[user.real_name] (as [user.name])"]: </span><span class='[message_span]'>\"[message]\"</span>"
|
||||
for(var/M in mob_list)
|
||||
if(isobserver(M))
|
||||
var/link = FOLLOW_LINK(M, user)
|
||||
M << "[link] [parsed_message]"
|
||||
else if(is_servant_of_ratvar(M))
|
||||
M << parsed_message
|
||||
return 1
|
||||
|
||||
//Function Call action: Calls forth a Ratvarian spear.
|
||||
/datum/action/innate/function_call
|
||||
name = "Function Call"
|
||||
button_icon_state = "ratvarian_spear"
|
||||
background_icon_state = "bg_clock"
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
|
||||
|
||||
/datum/action/innate/function_call/IsAvailable()
|
||||
if(!is_servant_of_ratvar(owner))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/function_call/Activate()
|
||||
if(owner.l_hand && owner.r_hand)
|
||||
usr << "<span class='warning'>You need an empty to hand to call forth your spear!</span>"
|
||||
return 0
|
||||
owner.visible_message("<span class='warning'>A strange spear materializes in [usr]'s hands!</span>", "<span class='brass'>You call forth your spear!</span>")
|
||||
var/obj/item/clockwork/ratvarian_spear/R = new(get_turf(usr))
|
||||
owner.put_in_hands(R)
|
||||
for(var/datum/action/innate/function_call/F in owner.actions) //Removes any bound Ratvarian spears
|
||||
qdel(F)
|
||||
return 1
|
||||
|
||||
//allows a mob to select a target to gate to
|
||||
/atom/movable/proc/procure_gateway(mob/living/invoker, time_duration, gateway_uses, two_way)
|
||||
var/list/possible_targets = list()
|
||||
var/list/teleportnames = list()
|
||||
var/list/duplicatenamecount = list()
|
||||
|
||||
for(var/obj/structure/clockwork/powered/clockwork_obelisk/O in all_clockwork_objects)
|
||||
if(!O.Adjacent(invoker) && O != src && (O.z <= ZLEVEL_SPACEMAX)) //don't list obelisks that we're next to
|
||||
var/area/A = get_area(O)
|
||||
var/locname = initial(A.name)
|
||||
var/resultkey = "[locname] [O.name]"
|
||||
if(resultkey in teleportnames) //why the fuck did you put two obelisks in the same area
|
||||
duplicatenamecount[resultkey]++
|
||||
resultkey = "[resultkey] ([duplicatenamecount[resultkey]])"
|
||||
else
|
||||
teleportnames.Add(resultkey)
|
||||
duplicatenamecount[resultkey] = 1
|
||||
possible_targets[resultkey] = O
|
||||
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(!L.stat && is_servant_of_ratvar(L) && !L.Adjacent(invoker) && L != invoker && (L.z <= ZLEVEL_SPACEMAX)) //People right next to the invoker can't be portaled to, for obvious reasons
|
||||
var/resultkey = "[L.name] ([L.real_name])"
|
||||
if(resultkey in teleportnames)
|
||||
duplicatenamecount[resultkey]++
|
||||
resultkey = "[resultkey] ([duplicatenamecount[resultkey]])"
|
||||
else
|
||||
teleportnames.Add(resultkey)
|
||||
duplicatenamecount[resultkey] = 1
|
||||
possible_targets[resultkey] = L
|
||||
|
||||
if(!possible_targets.len)
|
||||
invoker << "<span class='warning'>There are no other eligible targets for a Spatial Gateway!</span>"
|
||||
return 0
|
||||
var/input_target_key = input(invoker, "Choose a target to form a rift to.", "Spatial Gateway") as null|anything in possible_targets
|
||||
var/atom/movable/target = possible_targets[input_target_key]
|
||||
if(!target || !invoker.canUseTopic(src, BE_CLOSE))
|
||||
return 0
|
||||
var/istargetobelisk = istype(target, /obj/structure/clockwork/powered/clockwork_obelisk)
|
||||
if(istargetobelisk)
|
||||
gateway_uses *= 2
|
||||
time_duration *= 2
|
||||
invoker.visible_message("<span class='warning'>The air in front of [invoker] ripples before suddenly tearing open!</span>", \
|
||||
"<span class='brass'>With a word, you rip open a [two_way ? "two-way":"one-way"] rift to [input_target_key]. It will last for [time_duration / 10] seconds and has [gateway_uses] use[gateway_uses > 1 ? "s" : ""].</span>")
|
||||
var/obj/effect/clockwork/spatial_gateway/S1 = new(istype(src, /obj/structure/clockwork/powered/clockwork_obelisk) ? get_turf(src) : get_step(get_turf(invoker), invoker.dir))
|
||||
var/obj/effect/clockwork/spatial_gateway/S2 = new(istargetobelisk ? get_turf(target) : get_step(get_turf(target), target.dir))
|
||||
|
||||
//Set up the portals now that they've spawned
|
||||
S1.setup_gateway(S2, time_duration, gateway_uses, two_way)
|
||||
S2.visible_message("<span class='warning'>The air in front of [target] ripples before suddenly tearing open!</span>")
|
||||
return 1
|
||||
|
||||
/proc/scripture_unlock_check(scripture_tier) //check if the selected scripture tier is unlocked
|
||||
var/servants = 0
|
||||
var/unconverted_ai_exists = FALSE
|
||||
for(var/mob/living/M in living_mob_list)
|
||||
if(is_servant_of_ratvar(M) && (ishuman(M) || issilicon(M)))
|
||||
servants++
|
||||
for(var/mob/living/silicon/ai/ai in living_mob_list)
|
||||
if(!is_servant_of_ratvar(ai) && ai.client)
|
||||
unconverted_ai_exists = TRUE
|
||||
switch(scripture_tier)
|
||||
if(SCRIPTURE_DRIVER)
|
||||
return 1
|
||||
if(SCRIPTURE_SCRIPT)
|
||||
if(servants >= 5 && clockwork_caches)
|
||||
return 1 //5 or more non-brain servants and any number of clockwork caches
|
||||
if(SCRIPTURE_APPLICATION)
|
||||
if(servants >= 8 && clockwork_caches >= 3 && clockwork_construction_value >= 75)
|
||||
return 1 //8 or more non-brain servants, 3+ clockwork caches, and at least 75 CV
|
||||
if(SCRIPTURE_REVENANT)
|
||||
if(servants >= 10 && clockwork_caches >= 4 && clockwork_construction_value >= 150)
|
||||
return 1 //10 or more non-brain servants, 4+ clockwork caches, and at least 150 CV
|
||||
if(SCRIPTURE_JUDGEMENT)
|
||||
if(servants >= 12 && clockwork_caches >= 5 && clockwork_construction_value >= 250 && !unconverted_ai_exists)
|
||||
return 1 //12 or more non-brain servants, 5+ clockwork caches, at least 250 CV, and there are no living, non-servant ais
|
||||
return 0
|
||||
|
||||
/proc/generate_cache_component(specific_component_id) //generates a component in the global component cache, either random based on lowest or a specific component
|
||||
if(specific_component_id)
|
||||
clockwork_component_cache[specific_component_id]++
|
||||
else
|
||||
var/component_to_generate = get_weighted_component_id()
|
||||
clockwork_component_cache[component_to_generate]++
|
||||
|
||||
/proc/get_weighted_component_id(obj/item/clockwork/slab/storage_slab) //returns a chosen component id based on the lowest amount of that component
|
||||
if(storage_slab)
|
||||
return pickweight(list("belligerent_eye" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["belligerent_eye"] + storage_slab.stored_components["belligerent_eye"]), 1), \
|
||||
"vanguard_cogwheel" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["vanguard_cogwheel"] + storage_slab.stored_components["vanguard_cogwheel"]), 1), \
|
||||
"guvax_capacitor" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["guvax_capacitor"] + storage_slab.stored_components["guvax_capacitor"]), 1), \
|
||||
"replicant_alloy" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["replicant_alloy"] + storage_slab.stored_components["replicant_alloy"]), 1), \
|
||||
"hierophant_ansible" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["hierophant_ansible"] + storage_slab.stored_components["hierophant_ansible"]), 1)))
|
||||
|
||||
return pickweight(list("belligerent_eye" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["belligerent_eye"], 1), \
|
||||
"vanguard_cogwheel" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["vanguard_cogwheel"], 1), \
|
||||
"guvax_capacitor" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["guvax_capacitor"], 1), \
|
||||
"replicant_alloy" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["replicant_alloy"], 1), \
|
||||
"hierophant_ansible" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["hierophant_ansible"], 1)))
|
||||
|
||||
/proc/clockwork_say(atom/movable/AM, message, whisper=FALSE)
|
||||
// When servants invoke ratvar's power, they speak in ways that non
|
||||
// servants do not comprehend.
|
||||
// Our ratvarian chants are stored in their ratvar forms
|
||||
|
||||
var/list/spans = list(SPAN_ROBOT)
|
||||
|
||||
var/old_languages_spoken = AM.languages_spoken
|
||||
AM.languages_spoken = HUMAN //anyone who can understand HUMAN will hear weird shitty ratvar speak, otherwise it'll get starred out
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!whisper)
|
||||
L.say(message, "clock", spans)
|
||||
else
|
||||
L.whisper(message)
|
||||
else
|
||||
AM.say(message)
|
||||
AM.languages_spoken = old_languages_spoken
|
||||
|
||||
/*
|
||||
|
||||
The Ratvarian Language
|
||||
|
||||
In the lore of the Servants of Ratvar, the Ratvarian tongue is a timeless language and full of power. It sounds like gibberish, much like Nar-Sie's language, but is in fact derived from
|
||||
aforementioned language, and may induce miracles when spoken in the correct way with an amplifying tool (similar to runes used by the Nar-Sian cult).
|
||||
|
||||
While the canon states that the language of Ratvar and his servants is incomprehensible to the unenlightened as it is a derivative of the most ancient known language, in reality it is
|
||||
actually very simple. To translate a plain English sentence to Ratvar's tongue, simply move all of the letters thirteen places ahead, starting from "a" if the end of the alphabet is reached.
|
||||
This cipher is known as "rot13" for "rotate 13 places" and there are many sites online that allow instant translation between English and rot13 - one of the benefits is that moving the translated
|
||||
sentence thirteen places ahead changes it right back to plain English.
|
||||
|
||||
There are, however, a few parts of the Ratvarian tongue that aren't typical and are implemented for fluff reasons. Some words may have apostrophes, hyphens, and spaces, making the plain
|
||||
English translation apparent but disjoined (for instance, "Oru`byq zl-cbjre!" translates directly to "Beh'old my-power!") although this can be ignored without impacting overall quality. When
|
||||
translating from Ratvar's tongue to plain English, simply remove the disjointments and use the finished sentence. This would make "Oru`byq zl-cbjre!" into "Behold my power!" after removing the
|
||||
abnormal spacing, hyphens, and grave accents.
|
||||
|
||||
List of nuances:
|
||||
|
||||
- Any time the word "of" occurs, it is linked to the previous word by a hyphen. If it is the first word, nothing is done. (i.e. "V nz-bs Ratvar." directly translates to "I am-of Ratvar.")
|
||||
- Although "Ratvar" translates to "Engine" in English, the word "Ratvar" is used regardless of language as it is a proper noun.
|
||||
- The same rule applies to Ratvar's four generals: Nezbere (Armorer), Sevtug (Fright), Nzcrentr (Amperage), and Inath-Neq (Vangu-Ard), although these words can be used in proper context if one is
|
||||
not referring to the four generals and simply using the words themselves.
|
||||
|
||||
*/
|
||||
@@ -1,319 +0,0 @@
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer //Clockwork proselytizer (yes, that's a real word): Converts applicable objects to Ratvarian variants.
|
||||
name = "clockwork proselytizer"
|
||||
desc = "An odd, L-shaped device that hums with energy."
|
||||
clockwork_desc = "A device that allows the replacing of mundane objects with Ratvarian variants. It requires liquified Replicant Alloy to function."
|
||||
icon_state = "clockwork_proselytizer"
|
||||
w_class = 3
|
||||
force = 5
|
||||
flags = NOBLUDGEON
|
||||
var/stored_alloy = 0 //Requires this to function; each chunk of replicant alloy provides REPLICANT_ALLOY_UNIT
|
||||
var/max_alloy = REPLICANT_ALLOY_UNIT * 10
|
||||
var/uses_alloy = TRUE
|
||||
var/metal_to_alloy = FALSE
|
||||
var/repairing = null //what we're currently repairing, if anything
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/preloaded
|
||||
stored_alloy = REPLICANT_WALL_MINUS_FLOOR+REPLICANT_WALL_TOTAL
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/scarab
|
||||
name = "scarab proselytizer"
|
||||
clockwork_desc = "A cogscarab's internal proselytizer. It can only be successfully used by a cogscarab and requires liquified Replicant Alloy to function."
|
||||
metal_to_alloy = TRUE
|
||||
item_state = "nothing"
|
||||
w_class = 1
|
||||
var/debug = FALSE
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/scarab/proselytize(atom/target, mob/living/user)
|
||||
if(!debug && !isdrone(user))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/scarab/debug
|
||||
clockwork_desc = "A cogscarab's internal proselytizer. It can convert nearly any object into a Ratvarian variant."
|
||||
uses_alloy = FALSE
|
||||
debug = TRUE
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/examine(mob/living/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='brass'>Can be used to convert walls, floors, windows, airlocks, windoors, and grilles to clockwork variants.</span>"
|
||||
user << "<span class='brass'>Can also form some objects into Replicant Alloy, as well as reform Clockwork Walls into Clockwork Floors, and vice versa.</span>"
|
||||
if(metal_to_alloy)
|
||||
user << "<span class='alloy'>It can convert rods, metal, and plasteel to liquified replicant alloy at a low rate.</span>"
|
||||
if(uses_alloy)
|
||||
user << "<span class='alloy'>It has [stored_alloy]/[max_alloy] units of liquified alloy stored.</span>"
|
||||
user << "<span class='alloy'>Use it on a Tinkerer's Cache, strike it with Replicant Alloy, or attack Replicant Alloy with it to add additional liquified alloy.</span>"
|
||||
user << "<span class='alloy'>Use it in-hand to remove stored liquified alloy.</span>"
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/attack_self(mob/living/user)
|
||||
if(is_servant_of_ratvar(user) && uses_alloy)
|
||||
if(!can_use_alloy(REPLICANT_ALLOY_UNIT))
|
||||
user << "<span class='warning'>[src] [stored_alloy ? "Lacks enough":"Contains no"] alloy to reform[stored_alloy ? "":" any"] into solidified alloy!</span>"
|
||||
return
|
||||
modify_stored_alloy(-REPLICANT_ALLOY_UNIT)
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
new/obj/item/clockwork/component/replicant_alloy(user.loc)
|
||||
user << "<span class='brass'>You force [stored_alloy ? "some":"all"] of the alloy in [src]'s compartments to reform and solidify. \
|
||||
It now contains [stored_alloy]/[max_alloy] units of liquified alloy.</span>"
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/clockwork/component/replicant_alloy) && is_servant_of_ratvar(user) && uses_alloy)
|
||||
if(!can_use_alloy(-REPLICANT_ALLOY_UNIT))
|
||||
user << "<span class='warning'>[src]'s replicant alloy compartments are full!</span>"
|
||||
return 0
|
||||
modify_stored_alloy(REPLICANT_ALLOY_UNIT)
|
||||
playsound(user, 'sound/machines/click.ogg', 50, 1)
|
||||
user << "<span class='brass'>You force [I] to liquify and pour it into [src]'s compartments. It now contains [stored_alloy]/[max_alloy] units of liquified alloy.</span>"
|
||||
user.drop_item()
|
||||
qdel(I)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/afterattack(atom/target, mob/living/user, proximity_flag, params)
|
||||
if(!target || !user || !proximity_flag)
|
||||
return 0
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return ..()
|
||||
proselytize(target, user)
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/proc/modify_stored_alloy(amount)
|
||||
if(can_use_alloy(0)) //Ratvar makes it free
|
||||
amount = 0
|
||||
stored_alloy = Clamp(stored_alloy + amount, 0, max_alloy)
|
||||
return 1
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/proc/can_use_alloy(amount)
|
||||
if(ratvar_awakens || !uses_alloy)
|
||||
return TRUE
|
||||
if(!amount) //functions thus as a check for if ratvar is up/it doesn't use alloy if no amount is provided
|
||||
return FALSE
|
||||
if(stored_alloy - amount < 0)
|
||||
return FALSE
|
||||
if(stored_alloy - amount > max_alloy)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/proc/proselytize(atom/target, mob/living/user)
|
||||
if(!target || !user)
|
||||
return 0
|
||||
var/target_type = target.type
|
||||
var/list/proselytize_values = target.proselytize_vals(user, src) //relevant values for proselytizing stuff, given as an associated list
|
||||
if(proselytize_values == TRUE) //if we get true, fail, but don't send a message for whatever reason
|
||||
return 0
|
||||
if(!islist(proselytize_values))
|
||||
user << "<span class='warning'>[target] cannot be proselytized!</span>"
|
||||
return 0
|
||||
if(repairing)
|
||||
user << "<span class='warning'>You are currently repairing [repairing] with [src]!</span>"
|
||||
return 0
|
||||
if(!uses_alloy)
|
||||
proselytize_values["alloy_cost"] = 0
|
||||
|
||||
if(!can_use_alloy(proselytize_values["alloy_cost"]))
|
||||
if(stored_alloy - proselytize_values["alloy_cost"] < 0)
|
||||
user << "<span class='warning'>You need [proselytize_values["alloy_cost"]] liquified alloy to proselytize [target]!</span>"
|
||||
else if(stored_alloy - proselytize_values["alloy_cost"] > max_alloy)
|
||||
user << "<span class='warning'>You have too much liquified alloy stored to proselytize [target]!</span>"
|
||||
return 0
|
||||
|
||||
if(can_use_alloy(0)) //Ratvar makes it faster
|
||||
proselytize_values["operation_time"] *= 0.5
|
||||
|
||||
user.visible_message("<span class='warning'>[user]'s [name] begins tearing apart [target]!</span>", "<span class='brass'>You begin proselytizing [target]...</span>")
|
||||
playsound(target, 'sound/machines/click.ogg', 50, 1)
|
||||
if(proselytize_values["operation_time"] && !do_after(user, proselytize_values["operation_time"], target = target))
|
||||
return 0
|
||||
if(!can_use_alloy(proselytize_values["alloy_cost"])) //Check again to prevent bypassing via spamclick
|
||||
return 0
|
||||
if(!target || target.type != target_type)
|
||||
return 0
|
||||
if(repairing)
|
||||
return 0
|
||||
user.visible_message("<span class='warning'>[user]'s [name] disgorges a chunk of metal and shapes it over what's left of [target]!</span>", \
|
||||
"<span class='brass'>You proselytize [target].</span>")
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
var/new_thing_type = proselytize_values["new_obj_type"]
|
||||
if(isturf(target))
|
||||
var/turf/T = target
|
||||
T.ChangeTurf(new_thing_type)
|
||||
else
|
||||
if(proselytize_values["dir_in_new"])
|
||||
new new_thing_type(get_turf(target), proselytize_values["spawn_dir"])
|
||||
else
|
||||
var/atom/A = new new_thing_type(get_turf(target))
|
||||
A.setDir(proselytize_values["spawn_dir"])
|
||||
qdel(target)
|
||||
modify_stored_alloy(-proselytize_values["alloy_cost"])
|
||||
return 1
|
||||
|
||||
//if a valid target, returns an associated list in this format;
|
||||
//list("operation_time" = 15, "new_obj_type" = /obj/structure/window/reinforced/clockwork, "alloy_cost" = 5, "spawn_dir" = dir, "dir_in_new" = TRUE)
|
||||
//otherwise, return literally any non-list thing but preferably FALSE
|
||||
//returning TRUE won't produce the "cannot be proselytized" message and will still prevent proselytizing
|
||||
|
||||
/atom/proc/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/turf/closed/wall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "alloy_cost" = REPLICANT_WALL_TOTAL, "spawn_dir" = SOUTH)
|
||||
|
||||
/turf/closed/wall/r_wall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/turf/closed/wall/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 50, "new_obj_type" = /turf/open/floor/clockwork, "alloy_cost" = -REPLICANT_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
|
||||
|
||||
/turf/open/floor/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 30, "new_obj_type" = /turf/open/floor/clockwork, "alloy_cost" = REPLICANT_FLOOR, "spawn_dir" = SOUTH)
|
||||
|
||||
/turf/open/floor/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
for(var/obj/O in src)
|
||||
if(O.density && !O.CanPass(user, src, 5))
|
||||
user << "<span class='warning'>Something is in the way, preventing you from proselytizing [src] into a clockwork wall.</span>"
|
||||
return FALSE
|
||||
return list("operation_time" = 100, "new_obj_type" = /turf/closed/wall/clockwork, "alloy_cost" = REPLICANT_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/item/stack/rods/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(!proselytizer.metal_to_alloy)
|
||||
return 0
|
||||
var/prosel_costtime = -amount
|
||||
return list("operation_time" = -prosel_costtime, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "alloy_cost" = prosel_costtime, "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/item/stack/sheet/metal/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(!proselytizer.metal_to_alloy)
|
||||
return 0
|
||||
var/prosel_costtime = -amount*2
|
||||
return list("operation_time" = -prosel_costtime, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "alloy_cost" = prosel_costtime, "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/item/stack/sheet/plasteel/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(!proselytizer.metal_to_alloy)
|
||||
return 0
|
||||
var/prosel_costtime = -amount*3
|
||||
return list("operation_time" = -prosel_costtime, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "alloy_cost" = prosel_costtime, "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/machinery/door/airlock/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/doortype = /obj/machinery/door/airlock/clockwork
|
||||
if(glass)
|
||||
doortype = /obj/machinery/door/airlock/clockwork/brass
|
||||
return list("operation_time" = 40, "new_obj_type" = doortype, "alloy_cost" = REPLICANT_WALL_TOTAL, "spawn_dir" = dir)
|
||||
|
||||
/obj/machinery/door/airlock/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/obj/structure/window/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/windowtype = /obj/structure/window/reinforced/clockwork
|
||||
var/new_dir = TRUE
|
||||
var/prosel_time = 15
|
||||
var/prosel_cost = REPLICANT_FLOOR
|
||||
if(fulltile)
|
||||
windowtype = /obj/structure/window/reinforced/clockwork/fulltile
|
||||
new_dir = FALSE
|
||||
prosel_time = 30
|
||||
prosel_cost = REPLICANT_STANDARD
|
||||
return list("operation_time" = prosel_time, "new_obj_type" = windowtype, "alloy_cost" = prosel_cost, "spawn_dir" = dir, "dir_in_new" = new_dir)
|
||||
|
||||
/obj/structure/window/reinforced/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/door/window/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 30, "new_obj_type" = /obj/machinery/door/window/clockwork, "alloy_cost" = REPLICANT_STANDARD, "spawn_dir" = dir, "dir_in_new" = TRUE)
|
||||
|
||||
/obj/machinery/door/window/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/obj/structure/grille/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/grilletype = /obj/structure/grille/ratvar
|
||||
var/prosel_time = 15
|
||||
if(destroyed)
|
||||
grilletype = /obj/structure/grille/ratvar/broken
|
||||
prosel_time = 5
|
||||
return list("operation_time" = prosel_time, "new_obj_type" = grilletype, "alloy_cost" = 0, "spawn_dir" = dir)
|
||||
|
||||
/obj/structure/grille/ratvar/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/obj/structure/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
. = TRUE
|
||||
if(proselytizer.repairing) //no spamclicking for fast repairs, bucko
|
||||
user << "<span class='warning'>You are already repairing [proselytizer.repairing] with [proselytizer]!</span>"
|
||||
return
|
||||
if(!can_be_repaired)
|
||||
user << "<span class='warning'>[src] cannot be repaired with a proselytizer!</span>"
|
||||
return
|
||||
if(health == max_health)
|
||||
user << "<span class='warning'>[src] is at maximum integrity!</span>"
|
||||
return
|
||||
var/amount_to_heal = max_health - health
|
||||
var/healing_for_cycle = min(amount_to_heal, repair_amount)
|
||||
if(!proselytizer.can_use_alloy(0))
|
||||
healing_for_cycle = min(healing_for_cycle, proselytizer.stored_alloy)
|
||||
var/proselytizer_cost = healing_for_cycle*2
|
||||
if(!proselytizer.can_use_alloy(proselytizer_cost))
|
||||
user << "<span class='warning'>You need more liquified alloy to repair [src]!</span>"
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user]'s [proselytizer.name] starts covering [src] in black liquid metal...</span>", \
|
||||
"<span class='alloy'>You start repairing [src]...</span>")
|
||||
//hugeass while because we need to re-check after the do_after
|
||||
proselytizer.repairing = src
|
||||
while(proselytizer && user && src && health != max_health)
|
||||
amount_to_heal = max_health - health
|
||||
if(!amount_to_heal)
|
||||
break
|
||||
healing_for_cycle = min(amount_to_heal, repair_amount)
|
||||
if(!proselytizer.can_use_alloy(0))
|
||||
healing_for_cycle = min(healing_for_cycle, proselytizer.stored_alloy)
|
||||
proselytizer_cost = healing_for_cycle*2
|
||||
if(!proselytizer.can_use_alloy(proselytizer_cost) || !do_after(user, proselytizer_cost, target = src) || !proselytizer || !proselytizer.can_use_alloy(proselytizer_cost))
|
||||
break
|
||||
amount_to_heal = max_health - health
|
||||
if(!amount_to_heal)
|
||||
break
|
||||
healing_for_cycle = min(amount_to_heal, repair_amount)
|
||||
if(!proselytizer.can_use_alloy(0))
|
||||
healing_for_cycle = min(healing_for_cycle, proselytizer.stored_alloy)
|
||||
proselytizer_cost = healing_for_cycle*2
|
||||
if(!proselytizer.can_use_alloy(proselytizer_cost))
|
||||
break
|
||||
health += healing_for_cycle
|
||||
proselytizer.modify_stored_alloy(-proselytizer_cost)
|
||||
playsound(src, 'sound/machines/click.ogg', 50, 1)
|
||||
|
||||
if(proselytizer)
|
||||
proselytizer.repairing = null
|
||||
if(user)
|
||||
user.visible_message("<span class='notice'>[user]'s [proselytizer.name] stops covering [src] with black liquid metal.</span>", \
|
||||
"<span class='alloy'>You finish repairing [src]. It is now at <b>[health]/[max_health]</b> integrity.</span>")
|
||||
return
|
||||
|
||||
/obj/structure/clockwork/cache/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
. = ..()
|
||||
if(proselytizer.can_use_alloy(0) || proselytizer.stored_alloy + REPLICANT_ALLOY_UNIT > proselytizer.max_alloy)
|
||||
user << "<span class='warning'>[proselytizer]'s containers of liquified alloy are full!</span>"
|
||||
return
|
||||
if(!clockwork_component_cache["replicant_alloy"])
|
||||
user << "<span class='warning'>There is no Replicant Alloy in the global component cache!</span>"
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] places the end of [proselytizer] in the hole in [src]...</span>", \
|
||||
"<span class='notice'>You start filling [proselytizer] with liquified alloy...</span>")
|
||||
//hugeass check because we need to re-check after the do_after
|
||||
while(proselytizer && proselytizer.uses_alloy && proselytizer.stored_alloy + REPLICANT_ALLOY_UNIT <= proselytizer.max_alloy && clockwork_component_cache["replicant_alloy"] \
|
||||
&& do_after(user, 10, target = src) \
|
||||
&& proselytizer && proselytizer.uses_alloy && proselytizer.stored_alloy + REPLICANT_ALLOY_UNIT <= proselytizer.max_alloy && clockwork_component_cache["replicant_alloy"])
|
||||
proselytizer.modify_stored_alloy(REPLICANT_ALLOY_UNIT)
|
||||
clockwork_component_cache["replicant_alloy"]--
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
if(proselytizer && user)
|
||||
user.visible_message("<span class='notice'>[user] removes [proselytizer] from the hole in [src], apparently satisfied.</span>", \
|
||||
"<span class='brass'>You finish filling [proselytizer] with liquified alloy. It now contains [proselytizer.stored_alloy]/[proselytizer.max_alloy] units of liquified alloy.</span>")
|
||||
return
|
||||
|
||||
/obj/structure/clockwork/wall_gear/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 10, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "alloy_cost" = -REPLICANT_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/item/clockwork/alloy_shards/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 5, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "alloy_cost" = -REPLICANT_STANDARD, "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/item/clockwork/component/replicant_alloy/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "alloy_cost" = -REPLICANT_ALLOY_UNIT, "spawn_dir" = SOUTH)
|
||||
@@ -1,476 +0,0 @@
|
||||
|
||||
var/global/list/global_handofgod_traptypes = list()
|
||||
var/global/list/global_handofgod_structuretypes = list()
|
||||
|
||||
#define CONDUIT_RANGE 15
|
||||
|
||||
|
||||
/datum/game_mode
|
||||
var/list/datum/mind/red_deities = list()
|
||||
var/list/datum/mind/red_deity_prophets = list()
|
||||
var/list/datum/mind/red_deity_followers = list()
|
||||
|
||||
var/list/datum/mind/blue_deities = list()
|
||||
var/list/datum/mind/blue_deity_prophets = list()
|
||||
var/list/datum/mind/blue_deity_followers = list()
|
||||
|
||||
var/list/datum/mind/unassigned_followers = list() //for roundstart team assigning
|
||||
var/list/datum/mind/assigned_to_red = list()
|
||||
var/list/datum/mind/assigned_to_blue = list()
|
||||
|
||||
|
||||
/datum/game_mode/hand_of_god
|
||||
name = "hand of god"
|
||||
config_tag = "handofgod"
|
||||
antag_flag = ROLE_HOG_CULTIST //Followers use ROLE_HOG_CULTIST, Gods are picked later on with ROLE_HOG_GOD
|
||||
|
||||
required_players = 10
|
||||
required_enemies = 3
|
||||
recommended_enemies = 3
|
||||
restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel")
|
||||
|
||||
|
||||
/datum/game_mode/hand_of_god/announce()
|
||||
world << "<B>The current game mode is - Hand of God!</B>"
|
||||
world << "<B>Two cults are onboard the station, seeking to overthrow the other, and anyone who stands in their way.</B>"
|
||||
world << "<B>Followers</B> - Complete your deity's objectives. Convert crewmembers to your cause by using your deity's nexus. Remember - there is no you, there is only the cult."
|
||||
world << "<B>Prophets</B> - Command your cult by the will of your deity. You are a high-value target, so be careful!"
|
||||
world << "<B>Personnel</B> - Do not let any cult succeed in its mission. Mindshield implants and holy water will revert them to neutral, hopefully nonviolent crew."
|
||||
|
||||
|
||||
/////////////
|
||||
//Pre setup//
|
||||
/////////////
|
||||
|
||||
/datum/game_mode/hand_of_god/pre_setup()
|
||||
if(config.protect_roles_from_antagonist)
|
||||
restricted_jobs += protected_jobs
|
||||
|
||||
if(config.protect_assistant_from_antagonist)
|
||||
restricted_jobs += "Assistant"
|
||||
|
||||
for(var/F in 1 to recommended_enemies)
|
||||
if(!antag_candidates.len)
|
||||
break
|
||||
var/datum/mind/follower = pick_n_take(antag_candidates)
|
||||
unassigned_followers += follower
|
||||
follower.restricted_roles = restricted_jobs
|
||||
log_game("[follower.key] (ckey) has been selected as a follower, however teams have not been decided yet.")
|
||||
|
||||
while(unassigned_followers.len > (required_enemies / 2))
|
||||
var/datum/mind/chosen = pick_n_take(unassigned_followers)
|
||||
add_hog_follower(chosen,"red")
|
||||
|
||||
while(unassigned_followers.len)
|
||||
var/datum/mind/chosen = pick_n_take(unassigned_followers)
|
||||
add_hog_follower(chosen,"blue")
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
//////////////
|
||||
//Post Setup//
|
||||
//////////////
|
||||
|
||||
//Pick a follower to uplift into a god
|
||||
/datum/game_mode/hand_of_god/post_setup()
|
||||
|
||||
//Find viable red god
|
||||
var/list/red_god_possibilities = get_players_for_role(ROLE_HOG_GOD)
|
||||
red_god_possibilities &= red_deity_followers //followers only
|
||||
if(!red_god_possibilities.len) //No candidates? just pick any follower regardless of prefs
|
||||
red_god_possibilities = red_deity_followers
|
||||
|
||||
//Make red god
|
||||
var/datum/mind/red_god = pick_n_take(red_god_possibilities)
|
||||
if(red_god)
|
||||
red_god.current.become_god("red")
|
||||
remove_hog_follower(red_god,0)
|
||||
add_god(red_god,"red")
|
||||
|
||||
//Find viable blue god
|
||||
var/list/blue_god_possibilities = get_players_for_role(ROLE_HOG_GOD)
|
||||
blue_god_possibilities &= blue_deity_followers //followers only
|
||||
if(!blue_god_possibilities.len) //No candidates? just pick any follower regardless of prefs
|
||||
blue_god_possibilities = blue_deity_followers
|
||||
|
||||
//Make blue god
|
||||
var/datum/mind/blue_god = pick_n_take(blue_god_possibilities)
|
||||
if(blue_god)
|
||||
blue_god.current.become_god("blue")
|
||||
remove_hog_follower(blue_god,0)
|
||||
add_god(blue_god,"blue")
|
||||
|
||||
|
||||
//Forge objectives
|
||||
//This is done here so that both gods exist
|
||||
if(red_god)
|
||||
ticker.mode.forge_deity_objectives(red_god)
|
||||
if(blue_god)
|
||||
ticker.mode.forge_deity_objectives(blue_god)
|
||||
|
||||
|
||||
..()
|
||||
|
||||
///////////////////
|
||||
//Objective Procs//
|
||||
///////////////////
|
||||
|
||||
/datum/game_mode/proc/forge_deity_objectives(datum/mind/deity)
|
||||
switch(rand(1,100))
|
||||
if(1 to 30)
|
||||
var/datum/objective/deicide/deicide = new
|
||||
deicide.owner = deity
|
||||
if(deicide.find_target())//Hard to kill the other god if there is none
|
||||
deity.objectives += deicide
|
||||
|
||||
if(!(locate(/datum/objective/escape_followers) in deity.objectives))
|
||||
var/datum/objective/escape_followers/recruit = new
|
||||
recruit.owner = deity
|
||||
deity.objectives += recruit
|
||||
recruit.gen_amount_goal(8, 12)
|
||||
|
||||
if(31 to 60)
|
||||
var/datum/objective/sacrifice_prophet/sacrifice = new
|
||||
sacrifice.owner = deity
|
||||
deity.objectives += sacrifice
|
||||
|
||||
if(!(locate(/datum/objective/escape_followers) in deity.objectives))
|
||||
var/datum/objective/escape_followers/recruit = new
|
||||
recruit.owner = deity
|
||||
deity.objectives += recruit
|
||||
recruit.gen_amount_goal(8, 12)
|
||||
|
||||
if(61 to 85)
|
||||
var/datum/objective/build/build = new
|
||||
build.owner = deity
|
||||
deity.objectives += build
|
||||
build.gen_amount_goal(8, 16)
|
||||
|
||||
var/datum/objective/sacrifice_prophet/sacrifice = new
|
||||
sacrifice.owner = deity
|
||||
deity.objectives += sacrifice
|
||||
|
||||
if(!(locate(/datum/objective/escape_followers) in deity.objectives))
|
||||
var/datum/objective/escape_followers/recruit = new
|
||||
recruit.owner = deity
|
||||
deity.objectives += recruit
|
||||
recruit.gen_amount_goal(8, 12)
|
||||
|
||||
else
|
||||
if (!locate(/datum/objective/follower_block) in deity.objectives)
|
||||
var/datum/objective/follower_block/block = new
|
||||
block.owner = deity
|
||||
deity.objectives += block
|
||||
|
||||
///////////////
|
||||
//Greet procs//
|
||||
///////////////
|
||||
|
||||
/datum/game_mode/proc/greet_hog_follower(datum/mind/follower_mind,colour)
|
||||
if(follower_mind in blue_deity_prophets || follower_mind in red_deity_prophets)
|
||||
follower_mind.current << "<span class='danger'><B>You have been appointed as the prophet of the [colour] deity! You are the only one who can communicate with your deity at will. Guide your followers, but be wary, for many will want you dead.</span>"
|
||||
else if(colour)
|
||||
follower_mind.current << "<span class='danger'><B>You are a follower of the [colour] cult's deity!</span>"
|
||||
else
|
||||
follower_mind.current << "<span class='danger'><B>You are a follower of a cult's deity!</span>"
|
||||
|
||||
|
||||
/////////////////
|
||||
//Convert procs//
|
||||
/////////////////
|
||||
|
||||
/datum/game_mode/proc/add_hog_follower(datum/mind/follower_mind, colour = "No Colour")
|
||||
var/mob/living/carbon/human/H = follower_mind.current
|
||||
if(isloyal(H))
|
||||
H << "<span class='danger'>Your mindshield implant blocked the influence of the [colour] deity. </span>"
|
||||
return 0
|
||||
if((follower_mind in red_deity_followers) || (follower_mind in red_deity_prophets) || (follower_mind in blue_deity_followers) || (follower_mind in blue_deity_prophets))
|
||||
H << "<span class='danger'>You already belong to a deity. Your strong faith has blocked out the conversion attempt by the followers of the [colour] deity.</span>"
|
||||
return 0
|
||||
var/obj/item/weapon/nullrod/N = H.null_rod_check()
|
||||
if(N)
|
||||
H << "<span class='danger'>Your holy weapon prevented the [colour] deity from brainwashing you.</span>"
|
||||
return 0
|
||||
|
||||
if(colour == "red")
|
||||
red_deity_followers += follower_mind
|
||||
if(colour == "blue")
|
||||
blue_deity_followers += follower_mind
|
||||
|
||||
H.faction |= "[colour] god"
|
||||
follower_mind.current << "<span class='danger'><FONT size = 3>You are now a follower of the [colour] deity! Follow your deity's prophet in order to complete your deity's objectives. Convert crewmembers to your cause by using your deity's nexus. And remember - there is no you, there is only the cult.</FONT></span>"
|
||||
update_hog_icons_added(follower_mind, colour)
|
||||
follower_mind.special_role = "Hand of God: [capitalize(colour)] Follower"
|
||||
follower_mind.current.attack_log += "\[[time_stamp()]\] <font color='red'>Has been converted to the [colour] follower cult!</font>"
|
||||
return 1
|
||||
|
||||
|
||||
/datum/game_mode/proc/add_god(datum/mind/god_mind, colour = "No Colour")
|
||||
remove_hog_follower(god_mind, announce = 0)
|
||||
if(colour == "red")
|
||||
red_deities += god_mind
|
||||
if(colour == "blue")
|
||||
blue_deities += god_mind
|
||||
god_mind.current.attack_log += "\[[time_stamp()]\] <font color='red'>Has been made into a [colour] deity!</font>"
|
||||
god_mind.special_role = "Hand of God: [colour] God"
|
||||
update_hog_icons_added(god_mind, colour)
|
||||
|
||||
//////////////////
|
||||
//Deconvert proc//
|
||||
//////////////////
|
||||
|
||||
/datum/game_mode/proc/remove_hog_follower(datum/mind/follower_mind, announce = 1)//deconverts both
|
||||
follower_mind.remove_hog_follower_prophet()
|
||||
update_hog_icons_removed(follower_mind,"red")
|
||||
update_hog_icons_removed(follower_mind,"blue")
|
||||
|
||||
if(follower_mind.current)
|
||||
var/mob/living/carbon/human/H = follower_mind.current
|
||||
H.faction -= "red god"
|
||||
H.faction -= "blue god"
|
||||
|
||||
if(announce)
|
||||
follower_mind.current.attack_log += "\[[time_stamp()]\] <font color='red'>Has been deconverted from a deity's cult!</font>"
|
||||
follower_mind.current << "<span class='danger'><b>Your mind has been cleared from the brainwashing the followers have done to you. Now you serve yourself and the crew.</b></span>"
|
||||
for(var/mob/living/M in view(follower_mind.current))
|
||||
M << "[follower_mind.current] looks like their faith is shattered. They're no longer a cultist!"
|
||||
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Mob helper procs //
|
||||
//////////////////////
|
||||
|
||||
/proc/is_handofgod_god(A)
|
||||
if(istype(A, /mob/camera/god))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/proc/is_handofgod_bluecultist(A)
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(H.mind)
|
||||
if(H.mind in ticker.mode.blue_deity_followers|ticker.mode.blue_deity_prophets)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/proc/is_handofgod_redcultist(A)
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(H.mind)
|
||||
if(H.mind in ticker.mode.red_deity_followers|ticker.mode.red_deity_prophets)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/proc/is_handofgod_blueprophet(A)
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(H.mind)
|
||||
if(H.mind in ticker.mode.blue_deity_prophets)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/proc/is_handofgod_redprophet(A)
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(H.mind)
|
||||
if(H.mind in ticker.mode.red_deity_prophets)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/proc/is_handofgod_cultist(A) //any of them what so ever, blue, red, hot pink, whatever.
|
||||
if(is_handofgod_redcultist(A))
|
||||
return 1
|
||||
if(is_handofgod_bluecultist(A))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/proc/is_handofgod_prophet(A) //any of them what so ever, blue, red, hot pink, whatever
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(H.mind)
|
||||
if(H.mind in ticker.mode.blue_deity_prophets|ticker.mode.red_deity_prophets)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/mob/camera/god/proc/is_handofgod_myprophet(A)
|
||||
if(!ishuman(A))
|
||||
return 0
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(!H.mind)
|
||||
return 0
|
||||
if(side == "red")
|
||||
if(H.mind in ticker.mode.red_deity_prophets)
|
||||
return 1
|
||||
else if(side == "blue")
|
||||
if(H.mind in ticker.mode.blue_deity_prophets)
|
||||
return 1
|
||||
|
||||
|
||||
/mob/camera/god/proc/is_handofgod_myfollowers(mob/A)
|
||||
if(!ishuman(A))
|
||||
return 0
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(!H.mind)
|
||||
return 0
|
||||
if(side == "red")
|
||||
if(H.mind in ticker.mode.red_deity_prophets|ticker.mode.red_deity_followers)
|
||||
return 1
|
||||
else if(side == "blue")
|
||||
if(H.mind in ticker.mode.blue_deity_prophets|ticker.mode.blue_deity_followers)
|
||||
return 1
|
||||
|
||||
//////////////////////
|
||||
//Roundend Reporting//
|
||||
//////////////////////
|
||||
|
||||
|
||||
/datum/game_mode/hand_of_god/declare_completion()
|
||||
if(red_deities.len)
|
||||
var/text = "<BR><font size=3 color='red'><B>The red cult:</b></font>"
|
||||
for(var/datum/mind/red_god in red_deities)
|
||||
var/godwin = 1
|
||||
|
||||
text += "<BR><B>[red_god.key]</B> was the red deity, <B>[red_god.name]</B> ("
|
||||
if(red_god.current)
|
||||
if(red_god.current.stat == DEAD)
|
||||
text += "died"
|
||||
else
|
||||
text += "survived"
|
||||
else
|
||||
text += "ceased existing"
|
||||
text += ")"
|
||||
if(red_deity_prophets.len)
|
||||
for(var/datum/mind/red_prophet in red_deity_prophets)
|
||||
text += "<BR>The red prophet was <B>[red_prophet.name]</B> (<B>[red_prophet.key]</B>)"
|
||||
else
|
||||
text += "<BR>the red prophet was killed for their beliefs."
|
||||
|
||||
text += "<BR><B>Red follower count: </B> [red_deity_followers.len]"
|
||||
text += "<BR><B>Red followers:</B> "
|
||||
for(var/datum/mind/player in red_deity_followers)
|
||||
text += "[player.name] ([player.key]), "
|
||||
|
||||
var/objectives = ""
|
||||
if(red_god.objectives.len)
|
||||
var/count = 1
|
||||
for(var/datum/objective/O in red_god.objectives)
|
||||
if(O.check_completion())
|
||||
objectives += "<BR><B>Objective #[count]</B>: [O.explanation_text] <font color='green'><B>Success!</B></font>"
|
||||
feedback_add_details("god_objective","[O.type]|SUCCESS")
|
||||
else
|
||||
objectives += "<BR><B>Objective #[count]</B>: [O.explanation_text] <font color='red'><B>Fail.</B></font>"
|
||||
feedback_add_details("god_objective","[O.type]|FAIL")
|
||||
godwin = 0
|
||||
count++
|
||||
|
||||
text += objectives
|
||||
|
||||
if(godwin)
|
||||
text += "<BR><font color='green'><B>The red cult and deity were successful!</B></font>"
|
||||
feedback_add_details("god_success","SUCCESS")
|
||||
else
|
||||
text += "<br><font color='red'><B>The red cult and deity have failed!</B></font>"
|
||||
feedback_add_details("god_success","FAIL")
|
||||
|
||||
text += "<BR>"
|
||||
|
||||
world << text
|
||||
|
||||
if(blue_deities.len)
|
||||
var/text = "<BR><font size=3 color='red'><B>The blue cult:</b></font>"
|
||||
for(var/datum/mind/blue_god in blue_deities)
|
||||
var/godwin = 1
|
||||
|
||||
text += "<BR><B>[blue_god.key]</B> was the blue deity, <B>[blue_god.name]</B> ("
|
||||
if(blue_god.current)
|
||||
if(blue_god.current.stat == DEAD)
|
||||
text += "died"
|
||||
else
|
||||
text += "survived"
|
||||
else
|
||||
text += "ceased existing"
|
||||
text += ")"
|
||||
if(blue_deity_prophets.len)
|
||||
for(var/datum/mind/blue_prophet in blue_deity_prophets)
|
||||
text += "<BR>The blue prophet was <B>[blue_prophet.name]</B> (<B>[blue_prophet.key]</B>)"
|
||||
else
|
||||
text += "<BR>the blue prophet was killed for their beliefs."
|
||||
|
||||
text += "<BR><B>Blue follower count: </B> [blue_deity_followers.len]"
|
||||
text += "<BR><B>Blue followers:</B> "
|
||||
for(var/datum/mind/player in blue_deity_followers)
|
||||
text += "[player.name] ([player.key])"
|
||||
|
||||
var/objectives = ""
|
||||
if(blue_god.objectives.len)
|
||||
var/count = 1
|
||||
for(var/datum/objective/O in blue_god.objectives)
|
||||
if(O.check_completion())
|
||||
objectives += "<BR><B>Objective #[count]</B>: [O.explanation_text] <font color='green'><B>Success!</B></font>"
|
||||
feedback_add_details("god_objective","[O.type]|SUCCESS")
|
||||
else
|
||||
objectives += "<BR><B>Objective #[count]</B>: [O.explanation_text] <font color='red'><B>Fail.</B></font>"
|
||||
feedback_add_details("god_objective","[O.type]|FAIL")
|
||||
godwin = 0
|
||||
count++
|
||||
|
||||
text += objectives
|
||||
|
||||
if(godwin)
|
||||
text += "<BR><font color='green'><B>The blue cult and deity were successful!</B></font>"
|
||||
feedback_add_details("god_success","SUCCESS")
|
||||
else
|
||||
text += "<BR><font color='red'><B>The blue cult and deity have failed!</B></font>"
|
||||
feedback_add_details("god_success","FAIL")
|
||||
|
||||
text += "<BR>"
|
||||
|
||||
world << text
|
||||
|
||||
..()
|
||||
return 1
|
||||
|
||||
|
||||
/datum/game_mode/proc/update_hog_icons_added(datum/mind/hog_mind,side)
|
||||
var/hud_key
|
||||
var/rank = 0
|
||||
if(side == "red")
|
||||
hud_key = ANTAG_HUD_HOG_RED
|
||||
if(is_handofgod_redprophet(hog_mind.current))
|
||||
rank = 1
|
||||
|
||||
else if(side == "blue")
|
||||
hud_key = ANTAG_HUD_HOG_BLUE
|
||||
if(is_handofgod_blueprophet(hog_mind.current))
|
||||
rank = 1
|
||||
|
||||
if(is_handofgod_god(hog_mind.current))
|
||||
rank = 2
|
||||
|
||||
if(hud_key)
|
||||
var/datum/atom_hud/antag/hog_hud = huds[hud_key]
|
||||
hog_hud.join_hud(hog_mind.current)
|
||||
set_antag_hud(hog_mind.current, "hog-[side]-[rank]")
|
||||
|
||||
|
||||
/datum/game_mode/proc/update_hog_icons_removed(datum/mind/hog_mind,side)
|
||||
var/hud_key
|
||||
if(side == "red")
|
||||
hud_key = ANTAG_HUD_HOG_RED
|
||||
else if(side == "blue")
|
||||
hud_key = ANTAG_HUD_HOG_BLUE
|
||||
|
||||
if(hud_key)
|
||||
var/datum/atom_hud/antag/hog_hud = huds[hud_key]
|
||||
hog_hud.leave_hud(hog_mind.current)
|
||||
set_antag_hud(hog_mind.current,null)
|
||||
@@ -1,28 +0,0 @@
|
||||
/* Prophet's innate godspeak */
|
||||
/datum/action/innate/godspeak
|
||||
name = "Godspeak"
|
||||
button_icon_state = "godspeak"
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
var/mob/camera/god/god = null
|
||||
|
||||
/datum/action/innate/godspeak/IsAvailable()
|
||||
if(..())
|
||||
if(god)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/action/innate/godspeak/Activate()
|
||||
var/msg = input(owner,"Speak to your god","Godspeak","") as null|text
|
||||
if(!msg)
|
||||
return
|
||||
var/rendered = "<font color='[god.side]'><span class='game say'><i>Prophet [owner]:</i> <span class='message'>[msg]</span></span>"
|
||||
god << rendered
|
||||
owner << rendered
|
||||
for(var/mob/M in mob_list)
|
||||
if(isobserver(M))
|
||||
var/link = FOLLOW_LINK(M, owner)
|
||||
M << "[link] [rendered]"
|
||||
|
||||
/datum/action/innate/godspeak/Destroy()
|
||||
god = null
|
||||
return ..()
|
||||
@@ -1,290 +0,0 @@
|
||||
|
||||
/mob/camera/god
|
||||
name = "deity" //Auto changes to the player's deity name/random name
|
||||
real_name = "deity"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "marker"
|
||||
invisibility = 60
|
||||
see_in_dark = 0
|
||||
see_invisible = 55
|
||||
sight = SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
|
||||
languages_spoken = ALL
|
||||
languages_understood = ALL
|
||||
hud_possible = list(ANTAG_HUD)
|
||||
mouse_opacity = 0 //can't be clicked
|
||||
|
||||
var/faith = 100 //For initial prophet appointing/stupid purchase
|
||||
var/max_faith = 100
|
||||
var/side = "neutral" //Red or Blue for the gamemode
|
||||
var/obj/structure/divine/nexus/god_nexus = null //The source of the god's power in this realm, kill it and the god is kill
|
||||
var/nexus_required = FALSE //If the god dies from losing it's nexus, defaults to off so that gods don't instantly die at roundstart
|
||||
var/followers_required = 0 //Same as above
|
||||
var/alive_followers = 0
|
||||
var/list/structures = list()
|
||||
var/list/conduits = list()
|
||||
var/prophets_sacrificed_in_name = 0
|
||||
var/image/ghostimage = null //For observer with darkness off visiblity
|
||||
var/list/prophets = list()
|
||||
var/datum/action/innate/godspeak/speak2god
|
||||
|
||||
/mob/camera/god/New()
|
||||
..()
|
||||
update_icons()
|
||||
build_hog_construction_lists()
|
||||
|
||||
//Force nexuses after 15 minutes in hand of god mode
|
||||
if(ticker && ticker.mode && ticker.mode.name == "hand of god")
|
||||
addtimer(src, "forceplacenexus", 9000, FALSE)
|
||||
|
||||
|
||||
//Rebuilds the list based on the gamemode's lists
|
||||
//As they are the most accurate each tick
|
||||
/mob/camera/god/proc/get_my_followers()
|
||||
switch(side)
|
||||
if("red")
|
||||
. = ticker.mode.red_deity_followers|ticker.mode.red_deity_prophets
|
||||
if("blue")
|
||||
. = ticker.mode.blue_deity_followers|ticker.mode.blue_deity_prophets
|
||||
else
|
||||
. = list()
|
||||
|
||||
|
||||
/mob/camera/god/Destroy()
|
||||
var/list/followers = get_my_followers()
|
||||
for(var/datum/mind/F in followers)
|
||||
if(F.current)
|
||||
F.current << "<span class='danger'>Your god is DEAD!</span>"
|
||||
for(var/X in prophets)
|
||||
speak2god.Remove(X)
|
||||
ghost_darkness_images -= ghostimage
|
||||
updateallghostimages()
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
/mob/camera/god/proc/forceplacenexus()
|
||||
if(god_nexus)
|
||||
return
|
||||
|
||||
if(ability_cost(0,1,0))
|
||||
place_nexus()
|
||||
|
||||
else
|
||||
if(blobstart.len) //we're on invalid turf, try to pick from blobstart
|
||||
loc = pick(blobstart)
|
||||
place_nexus() //if blobstart fails, places on dense turf, but better than nothing
|
||||
src << "<span class='danger'>You failed to place your nexus, and it has been placed for you!</span>"
|
||||
|
||||
|
||||
/mob/camera/god/update_icons()
|
||||
icon_state = "[initial(icon_state)]-[side]"
|
||||
|
||||
if(ghostimage)
|
||||
ghost_darkness_images -= ghostimage
|
||||
|
||||
ghostimage = image(src.icon,src,src.icon_state)
|
||||
ghost_darkness_images |= ghostimage
|
||||
updateallghostimages()
|
||||
|
||||
|
||||
/mob/camera/god/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
if(god_nexus)
|
||||
stat("Nexus health: ", god_nexus.health)
|
||||
stat("Followers: ", alive_followers)
|
||||
stat("Faith: ", "[faith]/[max_faith]")
|
||||
|
||||
|
||||
/mob/camera/god/Login()
|
||||
..()
|
||||
sync_mind()
|
||||
src << "<span class='notice'>You are a deity!</span>"
|
||||
src << "You are a deity and are worshipped by a cult! You are rather weak right now, but that will change as you gain more followers."
|
||||
src << "You will need to place an anchor to this world, a <b>Nexus</b>, in two minutes. If you don't, one will be placed immediately below you."
|
||||
src << "Your <b>Follower</b> count determines how many people believe in you and are a part of your cult."
|
||||
src << "Your <b>Nexus Integrity</b> tells you the condition of your nexus. If your nexus is destroyed, you will die. Place your Nexus on a safe, isolated place, that is still accessible to your followers."
|
||||
src << "Your <b>Faith</b> is used to interact with the world. This will regenerate on its own, and it goes faster when you have more followers and power pylons."
|
||||
src << "The first thing you should do after placing your nexus is to <b>appoint a prophet</b>. Only prophets can hear you talk, unless you use an expensive power."
|
||||
update_health_hud()
|
||||
|
||||
|
||||
/mob/camera/god/update_health_hud()
|
||||
if(god_nexus && hud_used && hud_used.healths)
|
||||
hud_used.healths.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'> <font color='lime'>[god_nexus.health] </font></div>"
|
||||
|
||||
|
||||
/mob/camera/god/proc/add_faith(faith_amt)
|
||||
if(faith_amt)
|
||||
faith = round(Clamp(faith+faith_amt, 0, max_faith))
|
||||
if(hud_used && hud_used.deity_power_display)
|
||||
hud_used.deity_power_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'> <font color='cyan'>[faith] </font></div>"
|
||||
|
||||
|
||||
|
||||
/mob/camera/god/proc/place_nexus()
|
||||
if(god_nexus || (z != 1))
|
||||
return 0
|
||||
|
||||
var/obj/structure/divine/nexus/N = new(get_turf(src))
|
||||
N.assign_deity(src)
|
||||
god_nexus = N
|
||||
nexus_required = TRUE
|
||||
verbs -= /mob/camera/god/verb/constructnexus
|
||||
//verbs += /mob/camera/god/verb/movenexus //Translocators have no sprite
|
||||
update_health_hud()
|
||||
|
||||
var/area/A = get_area(src)
|
||||
if(A)
|
||||
var/areaname = A.name
|
||||
var/list/followers = get_my_followers()
|
||||
for(var/datum/mind/F in followers)
|
||||
if(F.current)
|
||||
F.current << "<span class='boldnotice'>Your god's nexus is in \the [areaname]</span>"
|
||||
|
||||
|
||||
/mob/camera/god/verb/freeturret()
|
||||
set category = "Deity"
|
||||
set name = "Free Turret (0)"
|
||||
set desc = "Place a single turret, for 0 faith."
|
||||
|
||||
if(!ability_cost(0,1,1))
|
||||
return
|
||||
var/obj/structure/divine/defensepylon/DP = new(get_turf(src))
|
||||
DP.assign_deity(src)
|
||||
verbs -= /mob/camera/god/verb/freeturret
|
||||
|
||||
|
||||
|
||||
/mob/camera/god/proc/update_followers()
|
||||
alive_followers = 0
|
||||
var/list/all_followers = get_my_followers()
|
||||
for(var/datum/mind/F in all_followers)
|
||||
if(F.current && F.current.stat != DEAD)
|
||||
alive_followers++
|
||||
|
||||
if(hud_used && hud_used.deity_follower_display)
|
||||
hud_used.deity_follower_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'> <font color='red'>[alive_followers] </font></div>"
|
||||
|
||||
|
||||
/mob/camera/god/proc/check_death()
|
||||
if(!alive_followers)
|
||||
src << "<span class='userdanger'>You no longer have any followers. You shudder as you feel your existence cease...</span>"
|
||||
if(god_nexus && !qdeleted(god_nexus))
|
||||
god_nexus.visible_message("<span class='danger'>\The [src] suddenly disappears!</span>")
|
||||
qdel(god_nexus)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/mob/camera/god/say(msg)
|
||||
if(!msg)
|
||||
return
|
||||
if(client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
src << "You cannot send IC messages (muted)."
|
||||
return
|
||||
if(src.client.handle_spam_prevention(msg,MUTE_IC))
|
||||
return
|
||||
if(stat)
|
||||
return
|
||||
|
||||
god_speak(msg)
|
||||
|
||||
|
||||
/mob/camera/god/proc/god_speak(msg)
|
||||
log_say("Hand of God: [capitalize(side)] God/[key_name(src)] : [msg]")
|
||||
msg = trim(copytext(sanitize(msg), 1, MAX_MESSAGE_LEN))
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
msg = say_quote(msg, get_spans())
|
||||
var/rendered = "<font color='[src.side]'><i><span class='game say'>Divine Telepathy,</i> <span class='name'>[name]</span> <span class='message'>[msg]</span></span></font>"
|
||||
src << rendered
|
||||
|
||||
for(var/mob/M in mob_list)
|
||||
if(is_handofgod_myfollowers(M))
|
||||
M << rendered
|
||||
if(isobserver(M))
|
||||
var/link = FOLLOW_LINK(M, src)
|
||||
M << "[link] [rendered]"
|
||||
|
||||
|
||||
/mob/camera/god/emote(act,m_type = 1 ,msg = null)
|
||||
return
|
||||
|
||||
|
||||
/mob/camera/god/Move(NewLoc, Dir = 0)
|
||||
loc = NewLoc
|
||||
|
||||
|
||||
|
||||
/mob/camera/god/Topic(href, href_list)
|
||||
if(href_list["create_structure"])
|
||||
if(!ability_cost(75,1,1))
|
||||
return
|
||||
|
||||
var/obj/structure/divine/construct_type = text2path(href_list["create_structure"]) //it's a path but we need to initial() some vars
|
||||
if(!construct_type)
|
||||
return
|
||||
|
||||
add_faith(-75)
|
||||
var/obj/structure/divine/construction_holder/CH = new(get_turf(src))
|
||||
CH.assign_deity(src)
|
||||
CH.setup_construction(construct_type)
|
||||
CH.visible_message("<span class='notice'>[src] has created a transparent, unfinished [initial(construct_type.name)]. It can be finished by adding materials.</span>")
|
||||
src << "<span class='boldnotice'>You may click a construction site to cancel it, but only faith is refunded.</span>"
|
||||
structure_construction_ui(src)
|
||||
return
|
||||
|
||||
if(href_list["place_trap"])
|
||||
if(!ability_cost(20,1,1))
|
||||
return
|
||||
|
||||
var/atom/trap_type = text2path(href_list["place_trap"])
|
||||
if(!trap_type)
|
||||
return
|
||||
|
||||
src << "You lay \a [initial(trap_type.name)]"
|
||||
add_faith(-20)
|
||||
new trap_type(get_turf(src))
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/mob/camera/god/proc/structure_construction_ui(mob/camera/god/user)
|
||||
var/dat = ""
|
||||
for(var/t in global_handofgod_structuretypes)
|
||||
if(global_handofgod_structuretypes[t])
|
||||
var/obj/structure/divine/apath = global_handofgod_structuretypes[t]
|
||||
dat += "<center><B>[capitalize(t)]</B></center><BR>"
|
||||
var/imgstate = initial(apath.autocolours) ? "[initial(apath.icon_state)]-[side]" : "[initial(apath.icon_state)]"
|
||||
var/icon/I = icon('icons/obj/hand_of_god_structures.dmi',imgstate)
|
||||
var/img_component = lowertext(t)
|
||||
//I hate byond, but atleast it autocaches these so it's only 1*number_of_structures worth of actual calls
|
||||
user << browse_rsc(I,"hog_structure-[img_component].png")
|
||||
dat += "<center><img src='hog_structure-[img_component].png' height=64 width=64></center>"
|
||||
dat += "Description: [initial(apath.desc)]<BR>"
|
||||
dat += "<center><a href='?src=\ref[src];create_structure=[apath]'>Construct [capitalize(t)]</a></center><BR><BR>"
|
||||
|
||||
var/datum/browser/popup = new(src, "structures","Construct Structure",350,500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
|
||||
/mob/camera/god/proc/trap_construction_ui(mob/camera/god/user)
|
||||
var/dat = ""
|
||||
for(var/t in global_handofgod_traptypes)
|
||||
if(global_handofgod_traptypes[t])
|
||||
var/obj/structure/divine/trap/T = global_handofgod_traptypes[t]
|
||||
dat += "<center><B>[capitalize(t)]</B></center><BR>"
|
||||
var/icon/I = icon('icons/obj/hand_of_god_structures.dmi',"[initial(T.icon_state)]")
|
||||
var/img_component = lowertext(t)
|
||||
user << browse_rsc(I,"hog_trap-[img_component].png")
|
||||
dat += "<center><img src='hog_trap-[img_component].png' height=64 width=64></center>"
|
||||
dat += "Description: [initial(T.desc)]<BR>"
|
||||
dat += "<center><a href='?src=\ref[src];place_trap=[T]'>Place [capitalize(t)]</a></center><BR><BR>"
|
||||
|
||||
var/datum/browser/popup = new(src, "traps", "Place Trap",350,500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
@@ -1,306 +0,0 @@
|
||||
/obj/item/weapon/banner
|
||||
name = "banner"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "banner"
|
||||
item_state = "banner"
|
||||
desc = "A banner with Nanotrasen's logo on it."
|
||||
var/moralecooldown = 0
|
||||
var/moralewait = 600
|
||||
|
||||
|
||||
/obj/item/weapon/banner/attack_self(mob/living/carbon/human/user)
|
||||
if(moralecooldown + moralewait > world.time)
|
||||
return
|
||||
var/side = ""
|
||||
if(is_handofgod_redcultist(user))
|
||||
side = "red"
|
||||
else if (is_handofgod_bluecultist(user))
|
||||
side = "blue"
|
||||
|
||||
if(!side)
|
||||
return
|
||||
user << "<span class='notice'>You increase the morale of your fellows!</span>"
|
||||
moralecooldown = world.time
|
||||
|
||||
for(var/mob/living/carbon/human/H in range(4,get_turf(src)))
|
||||
if((side == "red") && is_handofgod_redcultist(H) || (side == "blue") && is_handofgod_bluecultist(H))
|
||||
H << "<span class='notice'>Your morale is increased by [user]'s banner!</span>"
|
||||
H.adjustBruteLoss(-15)
|
||||
H.adjustFireLoss(-15)
|
||||
H.AdjustStunned(-2)
|
||||
H.AdjustWeakened(-2)
|
||||
H.AdjustParalysis(-2)
|
||||
|
||||
|
||||
/obj/item/weapon/banner/red
|
||||
name = "red banner"
|
||||
icon_state = "banner-red"
|
||||
item_state = "banner-red"
|
||||
desc = "A banner with the logo of the red deity."
|
||||
|
||||
/obj/item/weapon/banner/red/examine(mob/user)
|
||||
..()
|
||||
if(is_handofgod_redcultist(user))
|
||||
user << "A banner representing our might against the heretics. We may use it to increase the morale of our fellow members!"
|
||||
else if(is_handofgod_bluecultist(user))
|
||||
user << "A heretical banner that should be destroyed posthaste."
|
||||
|
||||
|
||||
/obj/item/weapon/banner/blue
|
||||
name = "blue banner"
|
||||
icon_state = "banner-blue"
|
||||
item_state = "banner-blue"
|
||||
desc = "A banner with the logo of the blue deity"
|
||||
|
||||
/obj/item/weapon/banner/blue/examine(mob/user)
|
||||
..()
|
||||
|
||||
if(is_handofgod_redcultist(user))
|
||||
user << "A heretical banner that should be destroyed posthaste."
|
||||
else if(is_handofgod_bluecultist(user))
|
||||
user << "A banner representing our might against the heretics. We may use it to increase the morale of our fellow members!"
|
||||
|
||||
|
||||
/obj/item/weapon/storage/backpack/bannerpack
|
||||
name = "nanotrasen banner backpack"
|
||||
desc = "It's a backpack with lots of extra room. A banner with Nanotrasen's logo is attached, that can't be removed."
|
||||
max_combined_w_class = 27 //6 more then normal, for the tradeoff of declaring yourself an antag at all times.
|
||||
icon_state = "bannerpack"
|
||||
|
||||
|
||||
/obj/item/weapon/storage/backpack/bannerpack/red
|
||||
name = "red banner backpack"
|
||||
desc = "It's a backpack with lots of extra room. A red banner is attached, that can't be removed."
|
||||
icon_state = "bannerpack-red"
|
||||
|
||||
|
||||
/obj/item/weapon/storage/backpack/bannerpack/blue
|
||||
name = "blue banner backpack"
|
||||
desc = "It's a backpack with lots of extra room. A blue banner is attached, that can't be removed."
|
||||
icon_state = "bannerpack-blue"
|
||||
|
||||
|
||||
|
||||
//this is all part of one item set
|
||||
/obj/item/clothing/suit/armor/plate/crusader
|
||||
name = "Crusader's Armour"
|
||||
icon_state = "crusader"
|
||||
w_class = 4 //bulky
|
||||
slowdown = 2.0 //gotta pretend we're balanced.
|
||||
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
armor = list(melee = 50, bullet = 50, laser = 50, energy = 40, bomb = 60, bio = 0, rad = 0)
|
||||
|
||||
/obj/item/clothing/suit/armor/plate/crusader/red
|
||||
icon_state = "crusader-red"
|
||||
|
||||
/obj/item/clothing/suit/armor/plate/crusader/blue
|
||||
icon_state = "crusader-blue"
|
||||
|
||||
/obj/item/clothing/suit/armor/plate/crusader/examine(mob/user)
|
||||
..()
|
||||
if(!is_handofgod_cultist(user))
|
||||
user << "Armour that's comprised of metal and cloth."
|
||||
else
|
||||
user << "Armour that was used to protect from backstabs, gunshots, explosives, and lasers. The original wearers of this type of armour were trying to avoid being murdered. Since they're not around anymore, you're not sure if they were successful or not."
|
||||
|
||||
|
||||
/obj/item/clothing/head/helmet/plate/crusader
|
||||
name = "Crusader's Hood"
|
||||
icon_state = "crusader"
|
||||
w_class = 3 //normal
|
||||
flags_inv = HIDEHAIR|HIDEEARS|HIDEFACE
|
||||
armor = list(melee = 50, bullet = 50, laser = 50, energy = 40, bomb = 60, bio = 0, rad = 0)
|
||||
|
||||
/obj/item/clothing/head/helmet/plate/crusader/blue
|
||||
icon_state = "crusader-blue"
|
||||
|
||||
/obj/item/clothing/head/helmet/plate/crusader/red
|
||||
icon_state = "crusader-red"
|
||||
|
||||
|
||||
/obj/item/clothing/head/helmet/plate/crusader/examine(mob/user)
|
||||
..()
|
||||
if(!is_handofgod_cultist(user))
|
||||
user << "A brownish hood."
|
||||
else
|
||||
user << "A hood that's very protective, despite being made of cloth. Due to the tendency of the wearer to be targeted for assassinations, being protected from being shot in the face was very important.."
|
||||
|
||||
|
||||
|
||||
//Prophet helmet
|
||||
/obj/item/clothing/head/helmet/plate/crusader/prophet
|
||||
name = "Prophet's Hat"
|
||||
alternate_worn_icon = 'icons/mob/large-worn-icons/64x64/head.dmi'
|
||||
flags = 0
|
||||
armor = list(melee = 60, bullet = 60, laser = 60, energy = 50, bomb = 70, bio = 50, rad = 50) //religion protects you from disease and radiation, honk.
|
||||
worn_x_dimension = 64
|
||||
worn_y_dimension = 64
|
||||
var/side = "neither"
|
||||
|
||||
/obj/item/clothing/head/helmet/plate/crusader/prophet/equipped(mob/living/carbon/user, slot)
|
||||
var/faithful = 0
|
||||
if(slot == slot_head)
|
||||
switch(side)
|
||||
if("blue")
|
||||
faithful = is_handofgod_bluecultist(user)
|
||||
if("red")
|
||||
faithful = is_handofgod_redcultist(user)
|
||||
else
|
||||
faithful = 1
|
||||
if(!faithful)
|
||||
user << "<span class='danger'>Your mind is assaulted by a vast power, furious at your desecration!</span>"
|
||||
user.emote("scream")
|
||||
user.adjustFireLoss(10)
|
||||
user.unEquip(src)
|
||||
user.head = null
|
||||
user.update_inv_head()
|
||||
src.screen_loc = null
|
||||
user.Weaken(1)
|
||||
|
||||
/obj/item/clothing/head/helmet/plate/crusader/prophet/red
|
||||
icon_state = "prophet-red"
|
||||
side = "red"
|
||||
|
||||
|
||||
/obj/item/clothing/head/helmet/plate/crusader/prophet/blue
|
||||
icon_state = "prophet-blue"
|
||||
side = "blue"
|
||||
|
||||
|
||||
/obj/item/clothing/head/helmet/plate/crusader/prophet/examine(mob/user)
|
||||
..()
|
||||
if(!is_handofgod_cultist(user))
|
||||
user << "A brownish, religious-looking hat."
|
||||
else
|
||||
user << "A hat bestowed upon a prophet of gods and demigods."
|
||||
user << "This hat belongs to the [side] god."
|
||||
|
||||
|
||||
|
||||
//Structure conversion staff
|
||||
/obj/item/weapon/godstaff
|
||||
name = "godstaff"
|
||||
icon_state = "godstaff-red"
|
||||
var/mob/camera/god/god = null
|
||||
var/staffcooldown = 0
|
||||
var/staffwait = 30
|
||||
|
||||
/obj/item/weapon/godstaff/examine(mob/user)
|
||||
..()
|
||||
if(!is_handofgod_cultist(user))
|
||||
user << "It's a stick..?"
|
||||
else
|
||||
user << "A powerful staff capable of changing the allegiance of god/demigod structures."
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/godstaff/attack_self(mob/living/carbon/user)
|
||||
if((god && !god.is_handofgod_myprophet(user)) || !god)
|
||||
user << "<span class='danger'>YOU ARE NOT THE CHOSEN ONE!</span>"
|
||||
return
|
||||
if(!(istype(user.head, /obj/item/clothing/head/helmet/plate/crusader/prophet)))
|
||||
user << "<span class='warning'>Your connection to your diety isn't strong enough! You must wear your big hat!</span>"
|
||||
return
|
||||
if(staffcooldown + staffwait > world.time)
|
||||
return
|
||||
user.visible_message("[user] chants deeply and waves their staff")
|
||||
if(do_after(user, 20,1,src))
|
||||
for(var/obj/structure/divine/R in orange(3,user))
|
||||
user.say("Grant us true sight my god!")
|
||||
if(istype(R, /obj/structure/divine/nexus)|| istype(R, /obj/structure/divine/trap))
|
||||
continue
|
||||
R.visible_message("<span class='danger'>[R] suddenly appears!</span>")
|
||||
R.invisibility = 0
|
||||
R.alpha = initial(R.alpha)
|
||||
R.density = initial(R.density)
|
||||
R.activate()
|
||||
staffcooldown = world.time
|
||||
|
||||
/obj/item/weapon/godstaff/red
|
||||
icon_state = "godstaff-red"
|
||||
|
||||
/obj/item/weapon/godstaff/blue
|
||||
icon_state = "godstaff-blue"
|
||||
|
||||
|
||||
|
||||
/obj/item/clothing/gloves/plate
|
||||
name = "Plate Gauntlets"
|
||||
icon_state = "crusader"
|
||||
siemens_coefficient = 0
|
||||
cold_protection = HANDS
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
heat_protection = HANDS
|
||||
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
|
||||
|
||||
|
||||
/obj/item/clothing/gloves/plate/red
|
||||
icon_state = "crusader-red"
|
||||
|
||||
/obj/item/clothing/gloves/plate/blue
|
||||
icon_state = "crusader-blue"
|
||||
|
||||
|
||||
/obj/item/clothing/gloves/plate/examine(mob/user)
|
||||
..()
|
||||
if(!is_handofgod_cultist(user))
|
||||
usr << "They're like gloves, but made of metal."
|
||||
else
|
||||
usr << "Protective gloves that are also blessed to protect from heat and shock."
|
||||
|
||||
|
||||
/obj/item/clothing/shoes/plate
|
||||
name = "Plate Boots"
|
||||
icon_state = "crusader"
|
||||
w_class = 3 //normal
|
||||
armor = list(melee = 50, bullet = 50, laser = 50, energy = 40, bomb = 60, bio = 0, rad = 0) //does this even do anything on boots?
|
||||
flags = NOSLIP
|
||||
cold_protection = FEET
|
||||
min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT
|
||||
heat_protection = FEET
|
||||
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
|
||||
|
||||
|
||||
/obj/item/clothing/shoes/plate/red
|
||||
icon_state = "crusader-red"
|
||||
|
||||
/obj/item/clothing/shoes/plate/blue
|
||||
icon_state = "crusader-blue"
|
||||
|
||||
|
||||
/obj/item/clothing/shoes/plate/examine(mob/user)
|
||||
..()
|
||||
if(!is_handofgod_cultist(user))
|
||||
usr << "Metal boots, they look heavy."
|
||||
else
|
||||
usr << "Heavy boots that are blessed for sure footing. You'll be safe from being taken down by the heresy that is the banana peel."
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/itemset/crusader
|
||||
name = "Crusader's Armour Set" //i can't into ck2 references
|
||||
desc = "This armour is said to be based on the armor of kings on another world thousands of years ago, who tended to assassinate, conspire, and plot against everyone who tried to do the same to them. Some things never change."
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/itemset/crusader/blue/New()
|
||||
..()
|
||||
contents = list()
|
||||
sleep(1)
|
||||
new /obj/item/clothing/suit/armor/plate/crusader/blue(src)
|
||||
new /obj/item/clothing/head/helmet/plate/crusader/blue(src)
|
||||
new /obj/item/clothing/gloves/plate/blue(src)
|
||||
new /obj/item/clothing/shoes/plate/blue(src)
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/itemset/crusader/red/New()
|
||||
..()
|
||||
contents = list()
|
||||
sleep(1)
|
||||
new /obj/item/clothing/suit/armor/plate/crusader/red(src)
|
||||
new /obj/item/clothing/head/helmet/plate/crusader/red(src)
|
||||
new /obj/item/clothing/gloves/plate/red(src)
|
||||
new /obj/item/clothing/shoes/plate/red(src)
|
||||
|
||||
|
||||
/obj/item/weapon/claymore/hog
|
||||
force = 30
|
||||
armour_penetration = 15
|
||||
@@ -1,129 +0,0 @@
|
||||
|
||||
/datum/objective/build
|
||||
dangerrating = 15
|
||||
martyr_compatible = 1
|
||||
|
||||
|
||||
/datum/objective/build/proc/gen_amount_goal(lower, upper)
|
||||
target_amount = rand(lower, upper)
|
||||
explanation_text = "Build [target_amount] shrines."
|
||||
return target_amount
|
||||
|
||||
|
||||
/datum/objective/build/check_completion()
|
||||
if(!owner || !owner.current)
|
||||
return 0
|
||||
|
||||
var/shrines = 0
|
||||
if(is_handofgod_god(owner.current))
|
||||
var/mob/camera/god/G = owner.current
|
||||
for(var/obj/structure/divine/shrine/S in G.structures)
|
||||
S++
|
||||
|
||||
return (shrines >= target_amount)
|
||||
|
||||
|
||||
|
||||
/datum/objective/deicide
|
||||
dangerrating = 20
|
||||
martyr_compatible = 1
|
||||
|
||||
/datum/objective/deicide/check_completion()
|
||||
if(target)
|
||||
if(target.current) //Gods are deleted when they lose
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
/datum/objective/deicide/find_target()
|
||||
if(!owner || !owner.current)
|
||||
return
|
||||
|
||||
if(is_handofgod_god(owner.current))
|
||||
var/mob/camera/god/G = owner.current
|
||||
if(G.side == "red")
|
||||
if(ticker.mode.blue_deities.len)
|
||||
target = ticker.mode.blue_deities[1]
|
||||
if(G.side == "blue")
|
||||
if(ticker.mode.red_deities.len)
|
||||
target = ticker.mode.red_deities[1]
|
||||
if(!target)
|
||||
return 0
|
||||
update_explanation_text()
|
||||
|
||||
/datum/objective/deicide/update_explanation_text()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Phase [target.name], the false god, out of this plane of existence.."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
|
||||
|
||||
|
||||
/datum/objective/follower_block
|
||||
explanation_text = "Do not allow any followers of the false god to escape on the station's shuttle alive."
|
||||
dangerrating = 25
|
||||
martyr_compatible = 1
|
||||
|
||||
/datum/objective/follower_block/check_completion()
|
||||
var/side = "ABORT"
|
||||
if(is_handofgod_redcultist(owner.current))
|
||||
side = "red"
|
||||
else if(is_handofgod_bluecultist(owner.current))
|
||||
side = "blue"
|
||||
if(side == "ABORT")
|
||||
return 0
|
||||
|
||||
var/area/A = SSshuttle.emergency.areaInstance
|
||||
|
||||
for(var/mob/living/player in player_list)
|
||||
if(player.mind && player.stat != DEAD && get_area(player) == A)
|
||||
if(side == "red")
|
||||
if(is_handofgod_bluecultist(player))
|
||||
return 0
|
||||
else if(side == "blue")
|
||||
if(is_handofgod_redcultist(player))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/datum/objective/escape_followers
|
||||
dangerrating = 5
|
||||
|
||||
|
||||
/datum/objective/escape_followers/proc/gen_amount_goal(lower,upper)
|
||||
target_amount = rand(lower,upper)
|
||||
explanation_text = "Your will must surpass this station. Having [target_amount] followers escape on the shuttle or pods will allow that."
|
||||
return target_amount
|
||||
|
||||
|
||||
/datum/objective/escape_followers/check_completion()
|
||||
var/escaped = 0
|
||||
if(is_handofgod_god(owner.current))
|
||||
var/mob/camera/god/G = owner.current
|
||||
if(G.side == "red")
|
||||
for(var/datum/mind/follower_mind in ticker.mode.red_deity_followers)
|
||||
if(follower_mind.current && follower_mind.current.stat != DEAD)
|
||||
if(follower_mind.current.onCentcom())
|
||||
escaped++
|
||||
|
||||
if(G.side == "blue")
|
||||
for(var/datum/mind/follower_mind in ticker.mode.blue_deity_followers)
|
||||
if(follower_mind.current && follower_mind.current.stat != DEAD)
|
||||
if(follower_mind.current.onCentcom())
|
||||
escaped++
|
||||
|
||||
return (escaped >= target_amount)
|
||||
|
||||
|
||||
/datum/objective/sacrifice_prophet
|
||||
explanation_text = "A false prophet is preaching their god's faith on the station. Sacrificing them will show the mortals who the true god is."
|
||||
dangerrating = 10
|
||||
|
||||
|
||||
/datum/objective/sacrifice_prophet/check_completion()
|
||||
var/mob/camera/god/G = owner.current
|
||||
if(istype(G))
|
||||
return G.prophets_sacrificed_in_name
|
||||
return 0
|
||||
@@ -1,363 +0,0 @@
|
||||
/mob/camera/god/proc/ability_cost(cost = 0,structures = 0, requires_conduit = 0, can_place_near_enemy_nexus = 0)
|
||||
if(faith < cost)
|
||||
src << "<span class='danger'>You lack the faith!</span>"
|
||||
return 0
|
||||
|
||||
if(structures)
|
||||
if(!isturf(loc) || istype(loc, /turf/open/space))
|
||||
src << "<span class='danger'>Your structure would just float away, you need stable ground!</span>"
|
||||
return 0
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
if(T.density)
|
||||
src << "<span class='danger'>There is something blocking your structure!</span>"
|
||||
return 0
|
||||
|
||||
for(var/atom/movable/AM in T)
|
||||
if(AM == src)
|
||||
continue
|
||||
if(AM.density)
|
||||
src << "<span class='danger'>There is something blocking your structure!</span>"
|
||||
return 0
|
||||
|
||||
if(requires_conduit)
|
||||
//Organised this way as there can be multiple conduits, so it's more likely to be a conduit check.
|
||||
var/valid = 0
|
||||
|
||||
for(var/obj/structure/divine/conduit/C in conduits)
|
||||
if(get_dist(src, C) <= CONDUIT_RANGE)
|
||||
valid++
|
||||
break
|
||||
|
||||
if(!valid)
|
||||
if(get_dist(src, god_nexus) <= CONDUIT_RANGE)
|
||||
valid++
|
||||
|
||||
if(!valid)
|
||||
src << "<span class='danger'>You must be near your Nexus or a Conduit to do this!</span>"
|
||||
return 0
|
||||
|
||||
if(!can_place_near_enemy_nexus)
|
||||
var/datum/mind/enemy
|
||||
switch(side)
|
||||
if("red")
|
||||
if(ticker.mode.blue_deities.len)
|
||||
enemy = ticker.mode.blue_deities[1]
|
||||
if("blue")
|
||||
if(ticker.mode.red_deities.len)
|
||||
enemy = ticker.mode.red_deities[1]
|
||||
|
||||
if(enemy && is_handofgod_god(enemy.current))
|
||||
var/mob/camera/god/enemy_god = enemy.current
|
||||
if(enemy_god.god_nexus && (get_dist(src,enemy_god.god_nexus) <= CONDUIT_RANGE*2))
|
||||
src << "<span class='danger'>You are too close to the other god's stronghold!</span>"
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/mob/camera/god/verb/returntonexus()
|
||||
set category = "Deity"
|
||||
set name = "Goto Nexus"
|
||||
set desc = "Teleports you to your next instantly."
|
||||
|
||||
if(god_nexus)
|
||||
Move(get_turf(god_nexus))
|
||||
else
|
||||
src << "You don't even have a Nexus, construct one."
|
||||
|
||||
|
||||
/mob/camera/god/verb/jumptofollower()
|
||||
set category = "Deity"
|
||||
set name = "Jump to Follower"
|
||||
set desc = "Teleports you to one of your followers."
|
||||
var/list/following = list()
|
||||
if(side == "red")
|
||||
following = ticker.mode.red_deity_followers|ticker.mode.red_deity_prophets
|
||||
else if(side == "blue")
|
||||
following = ticker.mode.blue_deity_followers|ticker.mode.blue_deity_prophets
|
||||
else
|
||||
src << "You are unaligned, and thus do not have followers"
|
||||
return
|
||||
|
||||
var/datum/mind/choice = input("Choose a follower","Jump to Follower") as null|anything in following
|
||||
if(choice && choice.current)
|
||||
Move(get_turf(choice.current))
|
||||
|
||||
|
||||
/mob/camera/god/verb/newprophet()
|
||||
set category = "Deity"
|
||||
set name = "Appoint Prophet (100)"
|
||||
set desc = "Appoint one of your followers as your Prophet, who can hear your words"
|
||||
|
||||
var/list/following = list()
|
||||
|
||||
if(!ability_cost(100))
|
||||
return
|
||||
if(side == "red")
|
||||
var/datum/mind/old_proph = locate() in ticker.mode.red_deity_prophets
|
||||
if(old_proph && old_proph.current && old_proph.current.stat != DEAD)
|
||||
src << "You can only have one prophet alive at a time."
|
||||
return
|
||||
else
|
||||
following = ticker.mode.red_deity_followers
|
||||
else if(side == "blue")
|
||||
var/datum/mind/old_proph = locate() in ticker.mode.blue_deity_prophets
|
||||
if(old_proph && old_proph.current && old_proph.current.stat != DEAD)
|
||||
src << "You can only have one prophet alive at a time."
|
||||
return
|
||||
else
|
||||
following = ticker.mode.blue_deity_followers
|
||||
|
||||
else
|
||||
src << "You are unalligned, and thus do not have prophets"
|
||||
return
|
||||
|
||||
var/datum/mind/choice = input("Choose a follower to make into your prophet","Prophet Uplifting") as null|anything in following
|
||||
if(choice && choice.current && choice.current.stat != DEAD)
|
||||
src << "You choose [choice.current] as your prophet."
|
||||
choice.make_Handofgod_prophet(side)
|
||||
speak2god = new()
|
||||
speak2god.god = src
|
||||
speak2god.Grant(choice.current)
|
||||
|
||||
//Prophet gear
|
||||
var/mob/living/carbon/human/H = choice.current
|
||||
var/popehat = null
|
||||
var/popestick = null
|
||||
var/success = ""
|
||||
switch(side)
|
||||
if("red")
|
||||
popehat = /obj/item/clothing/head/helmet/plate/crusader/prophet/red
|
||||
popestick = /obj/item/weapon/godstaff/red
|
||||
if("blue")
|
||||
popehat = /obj/item/clothing/head/helmet/plate/crusader/prophet/blue
|
||||
popestick = /obj/item/weapon/godstaff/blue
|
||||
|
||||
if(popehat)
|
||||
var/obj/item/clothing/head/helmet/plate/crusader/prophet/P = new popehat()
|
||||
|
||||
if(H.equip_to_slot_if_possible(P,slot_in_backpack,0,1,1))
|
||||
success = "It is in your backpack."
|
||||
else
|
||||
H.unEquip(H.head)
|
||||
H.equip_to_slot_or_del(P,slot_head)
|
||||
success = "It is on your head."
|
||||
|
||||
if(success)
|
||||
H << "<span class='boldnotice'>A powerful hat has been bestowed upon you, you will need to wear it to utilize your staff fully.</span>"
|
||||
H << "<span class='boldnotice'>[success]</span>"
|
||||
|
||||
if(popestick)
|
||||
var/obj/item/weapon/godstaff/G = new popestick()
|
||||
G.god = src
|
||||
if(!H.equip_to_slot_if_possible(G,slot_in_backpack,0,1,1))
|
||||
if(!H.put_in_hands(G))
|
||||
G.loc = get_turf(H)
|
||||
success = "It is on the floor..."
|
||||
else
|
||||
success = "It is in your hands..."
|
||||
else
|
||||
success = "It is in your backpack..."
|
||||
|
||||
if(success)
|
||||
H << "<span class='boldnotice'>A powerful staff has been bestowed upon you, you can use this to convert the false god's structures!</span>"
|
||||
H << "<span class='boldnotice'>[success]</span>"
|
||||
//end prophet gear
|
||||
|
||||
add_faith(-100)
|
||||
|
||||
|
||||
/mob/camera/god/verb/talk(msg as text)
|
||||
set category = "Deity"
|
||||
set name = "Talk to Anyone (20)"
|
||||
set desc = "Allows you to send a message to anyone, regardless of their faith."
|
||||
if(!ability_cost(20))
|
||||
return
|
||||
var/mob/choice = input("Choose who you wish to talk to", "Talk to ANYONE") as null|anything in mob_list
|
||||
if(choice)
|
||||
var/original = msg
|
||||
msg = "<B>You hear a voice coming from everywhere and nowhere... <i>[msg]</i></B>"
|
||||
choice << msg
|
||||
src << "You say the following to [choice], [original]"
|
||||
add_faith(-20)
|
||||
|
||||
|
||||
/mob/camera/god/verb/smite()
|
||||
set category = "Deity"
|
||||
set name = "Smite (40)"
|
||||
set desc = "Hits anything under you with a moderate amount of damage."
|
||||
|
||||
if(!ability_cost(40,0,1))
|
||||
return
|
||||
if(!range(7,god_nexus))
|
||||
src << "You lack the strength to smite this far from your nexus."
|
||||
return
|
||||
|
||||
var/has_smitten = 0 //Hast thou been smitten, infidel?
|
||||
for(var/mob/living/L in get_turf(src))
|
||||
L.adjustFireLoss(20)
|
||||
L.adjustBruteLoss(20)
|
||||
L << "<span class='danger'><B>You feel the wrath of [name]!<B></span>"
|
||||
has_smitten = 1
|
||||
if(has_smitten)
|
||||
add_faith(-40)
|
||||
|
||||
|
||||
/mob/camera/god/verb/disaster()
|
||||
set category = "Deity"
|
||||
set name = "Invoke Disaster (300)" //difficult to reach without lots of followers
|
||||
set desc = "Tug at the fibres of reality itself and bend it to your whims!"
|
||||
|
||||
if(!ability_cost(300,0,1))
|
||||
return
|
||||
|
||||
var/event = pick(/datum/round_event/meteor_wave, /datum/round_event/communications_blackout, /datum/round_event/radiation_storm, /datum/round_event/carp_migration,
|
||||
/datum/round_event/spacevine, /datum/round_event/vent_clog, /datum/round_event/wormholes)
|
||||
if(event)
|
||||
new event()
|
||||
add_faith(-300)
|
||||
|
||||
|
||||
/mob/camera/god/verb/constructnexus()
|
||||
set category = "Deity"
|
||||
set name = "Construct Nexus"
|
||||
set desc = "Instantly creates your nexus, You can only do this once, make sure you're happy with it!"
|
||||
|
||||
if(!ability_cost(0,1,0))
|
||||
return
|
||||
|
||||
place_nexus()
|
||||
|
||||
|
||||
/* //Transolocators have no sprite
|
||||
/mob/camera/god/verb/movenexus()
|
||||
set category = "Deity"
|
||||
set name = "Relocate Nexus (50)"
|
||||
set desc = "Instantly relocates your nexus to an existing translocator belonging to your faith, this destroys the translocator in the process"
|
||||
|
||||
if(ability_cost(50,0,0) && god_nexus)
|
||||
var/list/translocators = list()
|
||||
var/list/used_keys = list()
|
||||
for(var/obj/structure/divine/translocator/T in structures)
|
||||
translocators["[T.name] ([get_area(T)])"] = T
|
||||
|
||||
if(!translocators.len)
|
||||
src << "<span class='warning'>You have no translocators!</span>"
|
||||
return
|
||||
|
||||
var/picked = input(src,"Choose a translocator","Relocate Nexus") as null|anything in translocators
|
||||
if(!picked || !translocators[picked])
|
||||
return
|
||||
|
||||
var/obj/structure/divine/translocator/T = translocators[T]
|
||||
var/turf/Tturf = get_turf(T)
|
||||
god_nexus.loc = T
|
||||
translocators[picked] = null
|
||||
add_faith(-50)
|
||||
qdel(T)
|
||||
*/
|
||||
|
||||
/mob/camera/god/verb/construct_structures()
|
||||
set category = "Deity"
|
||||
set name = "Construct Structure (75)"
|
||||
set desc = "Create the foundation of a divine object."
|
||||
|
||||
if(!ability_cost(75,1,1))
|
||||
return
|
||||
|
||||
structure_construction_ui(src)
|
||||
|
||||
|
||||
/mob/camera/god/verb/construct_traps()
|
||||
set category = "Deity"
|
||||
set name = "Construct Trap (20)"
|
||||
set desc = "Creates a ward or trap."
|
||||
|
||||
if(!ability_cost(20,1,1))
|
||||
return
|
||||
|
||||
trap_construction_ui(src)
|
||||
|
||||
|
||||
|
||||
/mob/camera/god/verb/construct_items()
|
||||
set category = "Deity"
|
||||
set name = "Construct Items (20)"
|
||||
set desc = "Construct some items for your followers"
|
||||
|
||||
if(!ability_cost(20,1,1))
|
||||
return
|
||||
|
||||
var/list/item_types = list("claymore sword" = /obj/item/weapon/claymore/hog)
|
||||
if(side == "red")
|
||||
item_types["red banner"] = /obj/item/weapon/banner/red
|
||||
item_types["red bannerbackpack"] = /obj/item/weapon/storage/backpack/bannerpack/red
|
||||
item_types["red armour"] = /obj/item/weapon/storage/box/itemset/crusader/red
|
||||
|
||||
else if(side == "blue")
|
||||
item_types["blue banner"] = /obj/item/weapon/banner/blue
|
||||
item_types["blue bannerbackpack"] = /obj/item/weapon/storage/backpack/bannerpack/blue
|
||||
item_types["blue armour"] = /obj/item/weapon/storage/box/itemset/crusader/blue
|
||||
|
||||
|
||||
var/item = input("Choose what you wish to create.", "Divine Items") as null|anything in item_types
|
||||
if(!item || !item_types[item] || !ability_cost(20,1,1))
|
||||
return
|
||||
|
||||
src << "You produce \a [item]"
|
||||
add_faith(-20)
|
||||
|
||||
var/itemtype = item_types[item]
|
||||
new itemtype (get_turf(src))
|
||||
|
||||
|
||||
|
||||
/mob/camera/god/verb/veil_structures()
|
||||
set category = "Deity"
|
||||
set name = "Veil Structures (20)"
|
||||
set desc = "Hide your structures from sight and touch, but prevent yourself from using them."
|
||||
|
||||
if(!ability_cost(20,1,1))
|
||||
return
|
||||
|
||||
src << "You focus your powers and start dragging your influence into the spiritual plane."
|
||||
for(var/mob/M in orange(3,src))//Yes I know this is terrible, but visible message doesnt work for this
|
||||
M << "<span class='warning'>The air begins to shimmer...</span>"
|
||||
if(do_after(src, 30, 0, src))
|
||||
for(var/obj/structure/divine/R in orange(3,src))
|
||||
if(istype(R, /obj/structure/divine/nexus)|| istype(R, /obj/structure/divine/trap)||(src.side != R.side))
|
||||
continue
|
||||
R.visible_message("<span class='danger'>[R] fades away.</span>")
|
||||
R.invisibility = 55
|
||||
R.alpha = 100 //To help ghosts distinguish hidden structures
|
||||
R.density = 0
|
||||
R.deactivate()
|
||||
src << "You hide your influence from view"
|
||||
add_faith(-20)
|
||||
|
||||
|
||||
/mob/camera/god/verb/reveal_structures()
|
||||
set category = "Deity"
|
||||
set name = "Reveal Structures (20)"
|
||||
set desc = "Make your structures visible again and allow them to be used."
|
||||
|
||||
if(!ability_cost(20,1,1))
|
||||
return
|
||||
|
||||
src << "You focus your powers and start dragging your influence into the material plane."
|
||||
for(var/mob/M in orange(3,src))//Yes I know this is terrible, but visible message doesnt work for this
|
||||
M << "<span class='warning'>The air begins to shimmer...</span>"
|
||||
if(do_after(src, 40, 0, src))
|
||||
for(var/obj/structure/divine/R in orange(3,src))
|
||||
if(istype(R, /obj/structure/divine/nexus)|| istype(R, /obj/structure/divine/trap)||(src.side != R.side))
|
||||
continue
|
||||
R.visible_message("<span class='danger'>[R] suddenly appears!</span>")
|
||||
R.invisibility = 0
|
||||
R.alpha = initial(R.alpha)
|
||||
R.density = initial(R.density)
|
||||
R.activate()
|
||||
src << "You bring your influence into view"
|
||||
add_faith(-20)
|
||||
|
||||
@@ -1,658 +0,0 @@
|
||||
|
||||
/proc/build_hog_construction_lists()
|
||||
if(global_handofgod_traptypes.len && global_handofgod_structuretypes.len)
|
||||
return
|
||||
|
||||
var/list/types = subtypesof(/obj/structure/divine) - /obj/structure/divine/trap
|
||||
for(var/T in types)
|
||||
var/obj/structure/divine/D = T
|
||||
if(initial(D.constructable))
|
||||
if(initial(D.trap))
|
||||
global_handofgod_traptypes[initial(D.name)] = T
|
||||
else
|
||||
global_handofgod_structuretypes[initial(D.name)] = T
|
||||
|
||||
/obj/structure/divine
|
||||
name = "divine construction site"
|
||||
icon = 'icons/obj/hand_of_god_structures.dmi'
|
||||
desc = "An unfinished divine building"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/constructable = TRUE
|
||||
var/trap = FALSE
|
||||
var/metal_cost = 0
|
||||
var/glass_cost = 0
|
||||
var/lesser_gem_cost = 0
|
||||
var/greater_gem_cost = 0
|
||||
var/mob/camera/god/deity
|
||||
var/side = "neutral" //"blue" or "red", also used for colouring structures when construction is started by a deity
|
||||
var/health = 100
|
||||
var/maxhealth = 100
|
||||
var/deactivated = 0 //Structures being hidden can't be used. Mainly to prevent invisible defense pylons.
|
||||
var/autocolours = TRUE //do we colour to our side?
|
||||
|
||||
/obj/structure/divine/New()
|
||||
..()
|
||||
|
||||
/obj/structure/divine/proc/deactivate()
|
||||
deactivated = 1
|
||||
|
||||
/obj/structure/divine/proc/activate()
|
||||
deactivated = 0
|
||||
|
||||
|
||||
/obj/structure/divine/proc/update_icons()
|
||||
if(autocolours)
|
||||
icon_state = "[initial(icon_state)]-[side]"
|
||||
|
||||
|
||||
/obj/structure/divine/Destroy()
|
||||
if(deity)
|
||||
deity.structures -= src
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
/obj/structure/divine/attackby(obj/item/I, mob/user)
|
||||
|
||||
//Structure conversion/capture
|
||||
if(istype(I, /obj/item/weapon/godstaff))
|
||||
if(!is_handofgod_cultist(user))
|
||||
user << "<span class='notice'>You're not quite sure what the hell you're even doing.</span>"
|
||||
return
|
||||
var/obj/item/weapon/godstaff/G = I
|
||||
if(G.god && deity != G.god)
|
||||
assign_deity(G.god, alert_old_deity = TRUE)
|
||||
visible_message("<span class='boldnotice'>\The [src] has been captured by [user]!</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/divine/attacked_by(obj/item/I, mob/living/user)
|
||||
..()
|
||||
take_damage(I.force, I.damtype, 1)
|
||||
|
||||
/obj/structure/divine/proc/take_damage(damage, damage_type = BRUTE, sound_effect = 1)
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
if(sound_effect)
|
||||
if(damage)
|
||||
playsound(loc, 'sound/weapons/smash.ogg', 50, 1)
|
||||
else
|
||||
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
|
||||
if(BURN)
|
||||
if(sound_effect)
|
||||
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
|
||||
else
|
||||
return
|
||||
health -= damage
|
||||
if(!health)
|
||||
visible_message("<span class='danger'>\The [src] was destroyed!</span>")
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/structure/divine/bullet_act(obj/item/projectile/P)
|
||||
. = ..()
|
||||
take_damage(P.damage, P.damage_type, 0)
|
||||
|
||||
|
||||
/obj/structure/divine/attack_alien(mob/living/carbon/alien/humanoid/user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(src)
|
||||
add_hiddenprint(user)
|
||||
visible_message("<span class='warning'>\The [user] slashes at [src]!</span>")
|
||||
playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
|
||||
take_damage(20, BRUTE, 0)
|
||||
|
||||
/obj/machinery/attack_animal(mob/living/simple_animal/M)
|
||||
M.changeNext_move(CLICK_CD_MELEE)
|
||||
M.do_attack_animation(src)
|
||||
if(M.melee_damage_upper > 0)
|
||||
M.visible_message("<span class='danger'>[M.name] smashes against \the [src.name].</span>",\
|
||||
"<span class='danger'>You smash against the [src.name].</span>")
|
||||
take_damage(rand(M.melee_damage_lower,M.melee_damage_upper), M.melee_damage_type, 1)
|
||||
|
||||
|
||||
/obj/structure/divine/proc/assign_deity(mob/camera/god/new_deity, alert_old_deity = TRUE)
|
||||
if(!new_deity)
|
||||
return 0
|
||||
if(deity)
|
||||
if(alert_old_deity)
|
||||
deity << "<span class='danger'><B>Your [name] was captured by [new_deity]'s cult!</B></span>"
|
||||
deity.structures -= src
|
||||
deity = new_deity
|
||||
deity.structures |= src
|
||||
side = deity.side
|
||||
update_icons()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/structure/divine/construction_holder
|
||||
alpha = 125
|
||||
constructable = FALSE
|
||||
var/obj/structure/divine/construction_result = /obj/structure/divine //a path, but typed to /obj/structure/divine for initial()
|
||||
|
||||
|
||||
|
||||
/obj/structure/divine/construction_holder/assign_deity(mob/camera/god/new_deity, alert_old_deity = TRUE)
|
||||
if(..())
|
||||
color = side
|
||||
|
||||
|
||||
/obj/structure/divine/construction_holder/attack_god(mob/camera/god/user)
|
||||
if(user.side == side && construction_result)
|
||||
user.add_faith(75)
|
||||
visible_message("<span class='danger'>[user] has cancelled \the [initial(construction_result.name)]")
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/structure/divine/construction_holder/proc/setup_construction(construct_type)
|
||||
if(ispath(construct_type))
|
||||
construction_result = construct_type
|
||||
name = "[initial(construction_result.name)] construction site "
|
||||
icon_state = initial(construction_result.icon_state)
|
||||
metal_cost = initial(construction_result.metal_cost)
|
||||
glass_cost = initial(construction_result.glass_cost)
|
||||
lesser_gem_cost = initial(construction_result.lesser_gem_cost)
|
||||
greater_gem_cost = initial(construction_result.greater_gem_cost)
|
||||
desc = "An unfinished [initial(construction_result.name)]."
|
||||
|
||||
|
||||
/obj/structure/divine/construction_holder/attackby(obj/item/I, mob/user)
|
||||
if(!I || !user)
|
||||
return 0
|
||||
|
||||
if(istype(I, /obj/item/stack/sheet/metal))
|
||||
var/obj/item/stack/sheet/metal/M = I
|
||||
if(metal_cost)
|
||||
var/spend = min(metal_cost, M.amount)
|
||||
user << "<span class='notice'>You add [spend] metal to \the [src]."
|
||||
metal_cost = max(0, metal_cost - spend)
|
||||
M.use(spend)
|
||||
check_completion()
|
||||
else
|
||||
user << "<span class='notice'>\The [src] does not require any more metal!"
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/stack/sheet/glass))
|
||||
var/obj/item/stack/sheet/glass/G = I
|
||||
if(glass_cost)
|
||||
var/spend = min(glass_cost, G.amount)
|
||||
user << "<span class='notice'>You add [spend] glass to \the [src]."
|
||||
glass_cost = max(0, glass_cost - spend)
|
||||
G.use(spend)
|
||||
check_completion()
|
||||
else
|
||||
user << "<span class='notice'>\The [src] does not require any more glass!"
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/stack/sheet/lessergem))
|
||||
var/obj/item/stack/sheet/lessergem/LG = I
|
||||
if(lesser_gem_cost)
|
||||
var/spend = min(lesser_gem_cost, LG.amount)
|
||||
user << "<span class='notice'>You add [spend] lesser gems to \the [src]."
|
||||
lesser_gem_cost = max(0, lesser_gem_cost - spend)
|
||||
LG.use(spend)
|
||||
check_completion()
|
||||
else
|
||||
user << "<span class='notice'>\The [src] does not require any more lesser gems!"
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/stack/sheet/greatergem))
|
||||
var/obj/item/stack/sheet/greatergem/GG = I //GG!
|
||||
if(greater_gem_cost)
|
||||
var/spend = min(greater_gem_cost, GG.amount)
|
||||
user << "<span class='notice'>You add [spend] greater gems to \the [src]."
|
||||
greater_gem_cost = max(0, greater_gem_cost - spend)
|
||||
GG.use(spend)
|
||||
check_completion()
|
||||
else
|
||||
user << "<span class='notice'>\The [src] does not require any more greater gems!"
|
||||
return
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/divine/construction_holder/proc/check_completion()
|
||||
if(!metal_cost && !glass_cost && !lesser_gem_cost && !greater_gem_cost)
|
||||
visible_message("<span class='notice'>\The [initial(construction_result.name)] is complete!</span>")
|
||||
var/obj/structure/divine/D = new construction_result (get_turf(src))
|
||||
D.assign_deity(deity)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/structure/divine/construction_holder/examine(mob/user)
|
||||
..()
|
||||
|
||||
if(metal_cost || glass_cost || lesser_gem_cost || greater_gem_cost)
|
||||
user << "To finish construction it requires the following materials:"
|
||||
if(metal_cost)
|
||||
user << "[metal_cost] metal <IMG CLASS=icon SRC=icons/obj/items.dmi ICONSTATE='sheet-metal'>"
|
||||
if(glass_cost)
|
||||
user << "[glass_cost] glass <IMG CLASS=icon SRC=icons/obj/items.dmi ICONSTATE='sheet-glass'>"
|
||||
if(lesser_gem_cost)
|
||||
user << "[lesser_gem_cost] lesser gems <IMG CLASS=icon SRC=icons/obj/items.dmi ICONSTATE='sheet-lessergem'>"
|
||||
if(greater_gem_cost)
|
||||
user << "[greater_gem_cost] greater gems <IMG CLASS=icon SRC=icons/obj/items.dmi ICONSTATE='sheet-greatergem'>"
|
||||
|
||||
|
||||
/obj/structure/divine/nexus
|
||||
name = "nexus"
|
||||
desc = "It anchors a deity to this world. It radiates an unusual aura. Cultists protect this at all costs. It looks well protected from explosive shock."
|
||||
icon_state = "nexus"
|
||||
health = 500
|
||||
maxhealth = 500
|
||||
constructable = FALSE
|
||||
var/faith_regen_rate = 1
|
||||
var/list/powerpylons = list()
|
||||
|
||||
|
||||
/obj/structure/divine/nexus/ex_act()
|
||||
return
|
||||
|
||||
/obj/structure/divine/nexus/take_damage(damage, damage_type = BRUTE, sound_effect = 1)
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
if(sound_effect)
|
||||
if(damage)
|
||||
playsound(loc, 'sound/weapons/smash.ogg', 50, 1)
|
||||
else
|
||||
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
|
||||
if(BURN)
|
||||
if(sound_effect)
|
||||
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
|
||||
else
|
||||
return
|
||||
health -= damage
|
||||
if(deity)
|
||||
deity.update_health_hud()
|
||||
if(!health)
|
||||
if(!qdeleted(deity) && deity.nexus_required)
|
||||
deity << "<span class='danger'>Your nexus was destroyed. You feel yourself fading...</span>"
|
||||
qdel(deity)
|
||||
visible_message("<span class='danger'>\The [src] was destroyed!</span>")
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/structure/divine/nexus/New()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
|
||||
/obj/structure/divine/nexus/process()
|
||||
if(deity)
|
||||
deity.update_followers()
|
||||
deity.add_faith(faith_regen_rate + (powerpylons.len / 5) + (deity.alive_followers / 3))
|
||||
deity.max_faith = initial(deity.max_faith) + (deity.alive_followers*10) //10 followers = 100 max faith, so disaster() at around 20 followers
|
||||
deity.check_death()
|
||||
|
||||
|
||||
/obj/structure/divine/nexus/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/divine/conduit
|
||||
name = "conduit"
|
||||
desc = "It allows a deity to extend their reach. Their powers are just as potent near a conduit as a nexus."
|
||||
icon_state = "conduit"
|
||||
health = 150
|
||||
maxhealth = 150
|
||||
metal_cost = 10
|
||||
glass_cost = 5
|
||||
|
||||
|
||||
/obj/structure/divine/conduit/assign_deity(mob/camera/god/new_deity, alert_old_deity = TRUE)
|
||||
if(deity)
|
||||
deity.conduits -= src
|
||||
..()
|
||||
if(deity)
|
||||
deity.conduits += src
|
||||
|
||||
/obj/structure/divine/conduit/deactivate()
|
||||
..()
|
||||
if(deity)
|
||||
deity.conduits -= src
|
||||
|
||||
/obj/structure/divine/conduit/activate()
|
||||
..()
|
||||
if(deity)
|
||||
deity.conduits += src
|
||||
|
||||
/* //No good sprites, and not enough items to make it viable yet
|
||||
/obj/structure/divine/forge
|
||||
name = "forge"
|
||||
desc = "A forge fueled by divine might, it allows the creation of sacred and powerful artifacts. It requires common materials to craft objects."
|
||||
icon_state = "forge"
|
||||
health = 250
|
||||
maxhealth = 250
|
||||
density = 0
|
||||
maxhealth = 250
|
||||
metal_cost = 40
|
||||
*/
|
||||
|
||||
/obj/structure/divine/convertaltar
|
||||
name = "conversion altar"
|
||||
desc = "An altar dedicated to a deity. Cultists can \"forcefully teach\" their non-aligned crewmembers to join their side and take up their deity."
|
||||
icon_state = "convertaltar"
|
||||
density = 0
|
||||
metal_cost = 10
|
||||
can_buckle = 1
|
||||
|
||||
|
||||
/obj/structure/divine/convertaltar/attack_hand(mob/living/user)
|
||||
..()
|
||||
if(deactivated)
|
||||
return
|
||||
var/mob/living/carbon/human/H = locate() in get_turf(src)
|
||||
if(!is_handofgod_cultist(user))
|
||||
user << "<span class='notice'>You try to use it, but unfortunately you don't know any rituals.</span>"
|
||||
return
|
||||
if(!H)
|
||||
return
|
||||
if(!H.mind)
|
||||
user << "<span class='danger'>Only sentients may serve your deity.</span>"
|
||||
return
|
||||
if((side == "red" && is_handofgod_redcultist(user) && !is_handofgod_redcultist(H)) || (side == "blue" && is_handofgod_bluecultist(user) && !is_handofgod_bluecultist(H)))
|
||||
user << "<span class='notice'>You invoke the conversion ritual.</span>"
|
||||
ticker.mode.add_hog_follower(H.mind, side)
|
||||
else
|
||||
user << "<span class='notice'>You invoke the conversion ritual.</span>"
|
||||
user << "<span class='danger'>But the altar ignores your words...</span>"
|
||||
|
||||
|
||||
/obj/structure/divine/sacrificealtar
|
||||
name = "sacrificial altar"
|
||||
desc = "An altar designed to perform blood sacrifice for a deity. The cultists performing the sacrifice will gain a powerful material to use in their forge. Sacrificing a prophet will yield even better results."
|
||||
icon_state = "sacrificealtar"
|
||||
density = 0
|
||||
metal_cost = 15
|
||||
can_buckle = 1
|
||||
|
||||
|
||||
/obj/structure/divine/sacrificealtar/attack_hand(mob/living/user)
|
||||
..()
|
||||
if(deactivated)
|
||||
return
|
||||
var/mob/living/L = locate() in get_turf(src)
|
||||
if(!is_handofgod_cultist(user))
|
||||
user << "<span class='notice'>You try to use it, but unfortunately you don't know any rituals.</span>"
|
||||
return
|
||||
if(!L)
|
||||
return
|
||||
if((side == "red" && is_handofgod_redcultist(user)) || (side == "blue" && is_handofgod_bluecultist(user)))
|
||||
if((side == "red" && is_handofgod_redcultist(L)) || (side == "blue" && is_handofgod_bluecultist(L)))
|
||||
user << "<span class='danger'>You cannot sacrifice a fellow cultist.</span>"
|
||||
return
|
||||
user << "<span class='notice'>You attempt to sacrifice [L] by invoking the sacrificial ritual.</span>"
|
||||
sacrifice(L)
|
||||
else
|
||||
user << "<span class='notice'>You attempt to sacrifice [L] by invoking the sacrificial ritual.</span>"
|
||||
user << "<span class='danger'>But the altar ignores your words...</span>"
|
||||
|
||||
|
||||
/obj/structure/divine/sacrificealtar/proc/sacrifice(mob/living/L)
|
||||
if(!L)
|
||||
L = locate() in get_turf(src)
|
||||
if(L)
|
||||
if(ismonkey(L))
|
||||
var/luck = rand(1,4)
|
||||
if(luck > 3)
|
||||
new /obj/item/stack/sheet/lessergem(get_turf(src))
|
||||
|
||||
else if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
|
||||
//Sacrifice altars can't teamkill
|
||||
if(side == "red" && is_handofgod_redcultist(H))
|
||||
return
|
||||
else if(side == "blue" && is_handofgod_bluecultist(H))
|
||||
return
|
||||
|
||||
if(is_handofgod_prophet(H))
|
||||
new /obj/item/stack/sheet/greatergem(get_turf(src))
|
||||
if(deity)
|
||||
deity.prophets_sacrificed_in_name++
|
||||
else
|
||||
new /obj/item/stack/sheet/lessergem(get_turf(src))
|
||||
|
||||
else if(isAI(L) || istype(L, /mob/living/carbon/alien/humanoid/royal/queen))
|
||||
new /obj/item/stack/sheet/greatergem(get_turf(src))
|
||||
else
|
||||
new /obj/item/stack/sheet/lessergem(get_turf(src))
|
||||
L.gib()
|
||||
|
||||
|
||||
/obj/structure/divine/healingfountain
|
||||
name = "healing fountain"
|
||||
desc = "A fountain containing the waters of life... or death, depending on where your allegiances lie."
|
||||
icon_state = "fountain"
|
||||
metal_cost = 10
|
||||
glass_cost = 5
|
||||
autocolours = FALSE
|
||||
var/time_between_uses = 1800
|
||||
var/last_process = 0
|
||||
var/cult_only = TRUE
|
||||
|
||||
/obj/structure/divine/healingfountain/anyone
|
||||
desc = "A fountain containing the waters of life."
|
||||
cult_only = FALSE
|
||||
|
||||
/obj/structure/divine/healingfountain/attack_hand(mob/living/user)
|
||||
if(deactivated)
|
||||
return
|
||||
if(last_process + time_between_uses > world.time)
|
||||
user << "<span class='notice'>The fountain appears to be empty.</span>"
|
||||
return
|
||||
last_process = world.time
|
||||
if(!is_handofgod_cultist(user) && cult_only)
|
||||
user << "<span class='danger'><B>The water burns!</b></spam>"
|
||||
user.reagents.add_reagent("hell_water",20)
|
||||
else
|
||||
user << "<span class='notice'>The water feels warm and soothing as you touch it. The fountain immediately dries up shortly afterwards.</span>"
|
||||
user.reagents.add_reagent("godblood",20)
|
||||
update_icons()
|
||||
addtimer(src, "update_icons", time_between_uses)
|
||||
|
||||
|
||||
/obj/structure/divine/healingfountain/update_icons()
|
||||
if(last_process + time_between_uses > world.time)
|
||||
icon_state = "fountain"
|
||||
else
|
||||
icon_state = "fountain-[side]"
|
||||
|
||||
|
||||
/obj/structure/divine/powerpylon
|
||||
name = "power pylon"
|
||||
desc = "A pylon which increases the deity's rate it can influence the world."
|
||||
icon_state = "powerpylon"
|
||||
density = 1
|
||||
health = 30
|
||||
maxhealth = 30
|
||||
metal_cost = 5
|
||||
glass_cost = 15
|
||||
|
||||
|
||||
/obj/structure/divine/powerpylon/New()
|
||||
..()
|
||||
if(deity && deity.god_nexus)
|
||||
deity.god_nexus.powerpylons += src
|
||||
|
||||
|
||||
/obj/structure/divine/powerpylon/Destroy()
|
||||
if(deity && deity.god_nexus)
|
||||
deity.god_nexus.powerpylons -= src
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/divine/powerpylon/deactivate()
|
||||
..()
|
||||
if(deity)
|
||||
deity.god_nexus.powerpylons -= src
|
||||
|
||||
/obj/structure/divine/powerpylon/activate()
|
||||
..()
|
||||
if(deity)
|
||||
deity.god_nexus.powerpylons += src
|
||||
|
||||
/obj/structure/divine/defensepylon
|
||||
name = "defense pylon"
|
||||
desc = "A pylon which is blessed to withstand many blows, and fire strong bolts at nonbelievers. A god can toggle it."
|
||||
icon_state = "defensepylon"
|
||||
health = 150
|
||||
maxhealth = 150
|
||||
metal_cost = 25
|
||||
glass_cost = 30
|
||||
var/obj/machinery/porta_turret/defensepylon_internal_turret/pylon_gun
|
||||
|
||||
|
||||
/obj/structure/divine/defensepylon/New()
|
||||
..()
|
||||
pylon_gun = new(src)
|
||||
pylon_gun.base = src
|
||||
pylon_gun.faction = list("[side] god")
|
||||
|
||||
|
||||
/obj/structure/divine/defensepylon/Destroy()
|
||||
qdel(pylon_gun) //just in case
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/divine/defensepylon/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='notice'>\The [src] looks [pylon_gun.on ? "on" : "off"].</span>"
|
||||
|
||||
|
||||
/obj/structure/divine/defensepylon/assign_deity(mob/camera/god/new_deity, alert_old_deity = TRUE)
|
||||
if(..() && pylon_gun)
|
||||
pylon_gun.faction = list("[side] god")
|
||||
pylon_gun.side = side
|
||||
|
||||
/obj/structure/divine/defensepylon/attack_god(mob/camera/god/user)
|
||||
if(user.side == side)
|
||||
if(deactivated)
|
||||
user << "You need to reveal it first!"
|
||||
return
|
||||
pylon_gun.on = !pylon_gun.on
|
||||
icon_state = (pylon_gun.on) ? "defensepylon-[side]" : "defensepylon"
|
||||
|
||||
/obj/structure/divine/defensepylon/deactivate()
|
||||
..()
|
||||
pylon_gun.on = 0
|
||||
icon_state = (pylon_gun.on) ? "defensepylon-[side]" : "defensepylon"
|
||||
|
||||
/obj/structure/divine/defensepylon/activate()
|
||||
..()
|
||||
pylon_gun.on = 1
|
||||
icon_state = (pylon_gun.on) ? "defensepylon-[side]" : "defensepylon"
|
||||
|
||||
//This sits inside the defensepylon, to avoid copypasta
|
||||
/obj/machinery/porta_turret/defensepylon_internal_turret
|
||||
name = "defense pylon"
|
||||
desc = "A plyon which is blessed to withstand many blows, and fire strong bolts at nonbelievers."
|
||||
icon = 'icons/obj/hand_of_god_structures.dmi'
|
||||
installation = null
|
||||
always_up = 1
|
||||
use_power = 0
|
||||
has_cover = 0
|
||||
health = 200
|
||||
projectile = /obj/item/projectile/beam/pylon_bolt
|
||||
eprojectile = /obj/item/projectile/beam/pylon_bolt
|
||||
shot_sound = 'sound/weapons/emitter2.ogg'
|
||||
eshot_sound = 'sound/weapons/emitter2.ogg'
|
||||
base_icon_state = "defensepylon"
|
||||
active_state = ""
|
||||
off_state = ""
|
||||
faction = null
|
||||
emp_vunerable = 0
|
||||
var/side = "neutral"
|
||||
|
||||
/obj/machinery/porta_turret/defensepylon_internal_turret/setup()
|
||||
return
|
||||
|
||||
/obj/machinery/porta_turret/defensepylon_internal_turret/shootAt(atom/movable/target)
|
||||
var/obj/item/projectile/A = ..()
|
||||
if(A)
|
||||
A.color = side
|
||||
|
||||
/obj/machinery/porta_turret/defensepylon_internal_turret/assess_perp(mob/living/carbon/human/perp)
|
||||
if(perp.handcuffed) //dishonourable to kill somebody who might be converted.
|
||||
return 0
|
||||
var/badtarget = 0
|
||||
switch(side)
|
||||
if("blue")
|
||||
badtarget = is_handofgod_bluecultist(perp)
|
||||
if("red")
|
||||
badtarget = is_handofgod_redcultist(perp)
|
||||
else
|
||||
badtarget = 1
|
||||
if(badtarget)
|
||||
return 0
|
||||
return 10
|
||||
|
||||
|
||||
|
||||
/obj/item/projectile/beam/pylon_bolt
|
||||
name = "divine bolt"
|
||||
icon_state = "greyscale_bolt"
|
||||
damage = 15
|
||||
|
||||
|
||||
/obj/structure/divine/shrine
|
||||
name = "shrine"
|
||||
desc = "A shrine dedicated to a deity."
|
||||
icon_state = "shrine"
|
||||
metal_cost = 15
|
||||
glass_cost = 15
|
||||
|
||||
|
||||
/obj/structure/divine/shrine/assign_deity(mob/camera/god/new_deity, alert_old_deity = TRUE)
|
||||
if(..())
|
||||
name = "shrine to [new_deity.name]"
|
||||
desc = "A shrine dedicated to [new_deity.name]"
|
||||
|
||||
|
||||
|
||||
|
||||
//Functional, but need sprites
|
||||
/*
|
||||
/obj/structure/divine/translocator
|
||||
name = "translocator"
|
||||
desc = "A powerful structure, made with a greater gem. It allows a deity to move their nexus to where this stands"
|
||||
icon_state = "translocator"
|
||||
health = 100
|
||||
maxhealth = 100
|
||||
metal_cost = 20
|
||||
glass_cost = 20
|
||||
greater_gem_cost = 1
|
||||
|
||||
|
||||
/obj/structure/divine/lazarusaltar
|
||||
name = "lazarus altar"
|
||||
desc = "A very powerful altar capable of bringing life back to the recently deceased, made with a greater gem. It can revive anyone and will heal virtually all wounds, but they are but a shell of their former self."
|
||||
icon_state = "lazarusaltar"
|
||||
density = 0
|
||||
health = 100
|
||||
maxhealth = 100
|
||||
metal_cost = 20
|
||||
greater_gem_cost = 1
|
||||
|
||||
|
||||
/obj/structure/divine/lazarusaltar/attack_hand(mob/living/user)
|
||||
var/mob/living/L = locate() in get_turf(src)
|
||||
if(!is_handofgod_culstist(user))
|
||||
user << "<span class='notice'>You try to use it, but unfortunately you don't know any rituals.</span>"
|
||||
return
|
||||
if(!L)
|
||||
return
|
||||
|
||||
if((side == "red" && is_handofgod_redcultist(user))) || (side == "blue" && is_handofgod_bluecultist(user)))
|
||||
user << "<span class='notice'>You attempt to revive [L] by invoking the rebirth ritual.</span>"
|
||||
L.revive()
|
||||
L.adjustCloneLoss(50)
|
||||
L.adjustStaminaLoss(100)
|
||||
else
|
||||
user << "<span class='notice'>You attempt to revive [L] by invoking the rebirth ritual.</span>"
|
||||
user << "<span class='danger'>But the altar ignores your words...</span>"
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
|
||||
/obj/structure/divine/trap
|
||||
name = "IT'S A TARP"
|
||||
desc = "stepping on me is a guaranteed bad day"
|
||||
icon_state = "trap"
|
||||
density = 0
|
||||
alpha = 30 //initially quite hidden when not "recharging"
|
||||
health = 20
|
||||
maxhealth = 20
|
||||
trap = TRUE
|
||||
autocolours = FALSE
|
||||
var/last_trigger = 0
|
||||
var/time_between_triggers = 600 //takes a minute to recharge
|
||||
|
||||
|
||||
/obj/structure/divine/trap/Crossed(atom/movable/AM)
|
||||
if(last_trigger + time_between_triggers > world.time)
|
||||
return
|
||||
alpha = initial(alpha)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
last_trigger = world.time
|
||||
alpha = 200
|
||||
trap_effect(L)
|
||||
animate(src, alpha = initial(alpha), time = time_between_triggers)
|
||||
|
||||
|
||||
/obj/structure/divine/trap/examine(mob/user)
|
||||
..()
|
||||
if(!isliving(user)) //bad ghosts, stop trying to powergame from beyond the grave
|
||||
return
|
||||
user << "You reveal a trap!"
|
||||
alpha = 200
|
||||
animate(src, alpha = initial(alpha), time = time_between_triggers)
|
||||
|
||||
|
||||
/obj/structure/divine/trap/proc/trap_effect(mob/living/L)
|
||||
return
|
||||
|
||||
|
||||
/obj/structure/divine/trap/stun
|
||||
name = "shock trap"
|
||||
desc = "A trap that will shock you, it will burn your flesh and render you immobile, You'd better avoid it."
|
||||
icon_state = "trap-shock"
|
||||
|
||||
|
||||
/obj/structure/divine/trap/stun/trap_effect(mob/living/L)
|
||||
L << "<span class='danger'><B>You are paralyzed from the intense shock!</B></span>"
|
||||
L.Weaken(5)
|
||||
var/turf/Lturf = get_turf(L)
|
||||
new /obj/effect/particle_effect/sparks/electricity(Lturf)
|
||||
new /obj/effect/particle_effect/sparks(Lturf)
|
||||
|
||||
|
||||
/obj/structure/divine/trap/fire
|
||||
name = "flame trap"
|
||||
desc = "A trap that will set you ablaze. You'd better avoid it."
|
||||
icon_state = "trap-fire"
|
||||
|
||||
|
||||
/obj/structure/divine/trap/fire/trap_effect(mob/living/L)
|
||||
L << "<span class='danger'><B>Spontaneous combustion!</B></span>"
|
||||
L.Weaken(1)
|
||||
var/turf/Lturf = get_turf(L)
|
||||
new /obj/effect/hotspot(Lturf)
|
||||
new /obj/effect/particle_effect/sparks(Lturf)
|
||||
|
||||
|
||||
/obj/structure/divine/trap/chill
|
||||
name = "frost trap"
|
||||
desc = "A trap that will chill you to the bone. You'd better avoid it."
|
||||
icon_state = "trap-frost"
|
||||
|
||||
|
||||
/obj/structure/divine/trap/chill/trap_effect(mob/living/L)
|
||||
L << "<span class='danger'><B>You're frozen solid!</B></span>"
|
||||
L.Weaken(1)
|
||||
L.bodytemperature -= 300
|
||||
new /obj/effect/particle_effect/sparks(get_turf(L))
|
||||
|
||||
|
||||
/obj/structure/divine/trap/damage
|
||||
name = "earth trap"
|
||||
desc = "A trap that will summon a small earthquake, just for you. You'd better avoid it."
|
||||
icon_state = "trap-earth"
|
||||
|
||||
|
||||
/obj/structure/divine/trap/damage/trap_effect(mob/living/L)
|
||||
L << "<span class='danger'><B>The ground quakes beneath your feet!</B></span>"
|
||||
L.Weaken(5)
|
||||
L.adjustBruteLoss(35)
|
||||
var/turf/Lturf = get_turf(L)
|
||||
new /obj/effect/particle_effect/sparks(Lturf)
|
||||
new /obj/structure/flora/rock(Lturf)
|
||||
|
||||
|
||||
/obj/structure/divine/trap/ward
|
||||
name = "divine ward"
|
||||
desc = "A divine barrier, It looks like you could destroy it with enough effort, or wait for it to dissipate..."
|
||||
icon_state = "ward"
|
||||
health = 150
|
||||
maxhealth = 150
|
||||
density = 1
|
||||
time_between_triggers = 1200 //Exists for 2 minutes
|
||||
|
||||
|
||||
/obj/structure/divine/trap/ward/New()
|
||||
..()
|
||||
QDEL_IN(src, time_between_triggers)
|
||||
@@ -1,765 +0,0 @@
|
||||
#define STATE_JUDGE 0
|
||||
#define STATE_WRATH 1
|
||||
#define STATE_FLEE 2
|
||||
|
||||
/mob/living/simple_animal/hostile/hades
|
||||
name = "hades"
|
||||
real_name = "hades"
|
||||
desc = "A strange being, clad in dark robes. Their very presence radiates an uneasy power."
|
||||
speak_emote = list("preaches","announces","spits","conveys")
|
||||
emote_hear = list("hums.","prays.")
|
||||
response_help = "kneels before"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
icon = 'icons/mob/EvilPope.dmi'
|
||||
icon_state = "EvilPope"
|
||||
icon_living = "EvilPope"
|
||||
icon_dead = "popedeath"
|
||||
speed = 1
|
||||
a_intent = "harm"
|
||||
status_flags = CANPUSH
|
||||
attack_sound = 'sound/magic/MAGIC_MISSILE.ogg'
|
||||
death_sound = 'sound/magic/Teleport_diss.ogg'
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
maxbodytemp = INFINITY
|
||||
faction = list("hades")
|
||||
attacktext = "strikes with an unholy rage at"
|
||||
maxHealth = 1000
|
||||
health = 1000
|
||||
healable = 0
|
||||
environment_smash = 3
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 20
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
loot = list(/obj/effect/decal/cleanable/blood)
|
||||
del_on_death = 0
|
||||
deathmessage = "begins to sizzle and pop, their flesh peeling away like paper."
|
||||
|
||||
var/isDoingDeath = FALSE
|
||||
var/isFleeing = FALSE
|
||||
var/fleeTimes = 0
|
||||
var/currentState = STATE_JUDGE
|
||||
var/rageLevel = 0
|
||||
|
||||
var/maxWrathTimer = 150
|
||||
var/lastWrathTimer = 0
|
||||
|
||||
var/timeBetweenGrabs = 60
|
||||
var/lastGrabTime = 0
|
||||
|
||||
var/list/validSins = list("Greed","Gluttony","Pride","Lust","Envy","Sloth","Wrath")
|
||||
var/lastsinPerson = 0
|
||||
var/sinPersonTime = 300
|
||||
var/lastFlee = 0
|
||||
var/fleeTimer = 30
|
||||
var/fakesinPersonChance = 60
|
||||
var/list/sinPersonsayings = list("You revel in only your own greed.",\
|
||||
"There is nothing but your absolution.",\
|
||||
"Your choices have led you to this.",\
|
||||
"There is only one way out.",\
|
||||
"The only way to be free is to be free of yourself.",\
|
||||
"Wallow in sin, and give yourself unto darkness.",\
|
||||
"Only the truly sinful may stand.",\
|
||||
"Find yourself and you will find Absolution.",\
|
||||
"Forego the pain of this process, and submit.",\
|
||||
"We can be one in suffering.",\
|
||||
"You stand on the precipice of ascension, give in.",\
|
||||
"You cannot fathom what lies beyond",\
|
||||
"Repent your sins.",\
|
||||
"This is the eve of your last days.",\
|
||||
"Darkness comes.")
|
||||
|
||||
var/list/creepyasssounds = list('sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', \
|
||||
'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg',\
|
||||
'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
|
||||
'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg',\
|
||||
'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
|
||||
'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg')
|
||||
|
||||
var/obj/effect/proc_holder/spell/targeted/lightning/sinLightning
|
||||
|
||||
var/list/currentAcolytes = list()
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/New()
|
||||
..()
|
||||
|
||||
sinLightning = new/obj/effect/proc_holder/spell/targeted/lightning(src)
|
||||
|
||||
sinLightning.charge_max = 1
|
||||
sinLightning.clothes_req = 0
|
||||
sinLightning.range = 32
|
||||
sinLightning.cooldown_min = 1
|
||||
|
||||
lastsinPerson = world.time
|
||||
var/list/possible_titles = list("Pope","Bishop","Lord","Cardinal","Deacon","Pontiff")
|
||||
var/chosen = "Hades, [pick(possible_titles)] of Sin"
|
||||
name = chosen
|
||||
real_name = chosen
|
||||
|
||||
world << "<span class='warning'><font size=4>[name] has entered your reality. Kneel before them.</font></span>"
|
||||
world << 'sound/effects/pope_entry.ogg'
|
||||
|
||||
Appear(get_turf(src))
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/handle_environment(datum/gas_mixture/environment)
|
||||
//space popes are from space, they need not your fickle "oxygen"
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/handle_temperature_damage()
|
||||
//space popes are from space, they don't uh.. something fire burny death
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/death(gibbed)
|
||||
if(!isDoingDeath)
|
||||
notransform = TRUE
|
||||
anchored = TRUE
|
||||
src.visible_message("<span class='warning'><font size=4>[src] begins to twist and distort, before snapping backwards with a sickening crunch.</font></span>")
|
||||
spawn(20)
|
||||
src.visible_message("<span class='warning'><font size=4>[src] is being sucked back to their own realm, destabilizing the fabric of time and space itself!</font></span>")
|
||||
playsound(get_turf(src), 'sound/effects/hyperspace_begin.ogg', 100, 1)
|
||||
isDoingDeath = TRUE
|
||||
AIStatus = AI_OFF
|
||||
SpinAnimation()
|
||||
for(var/i in 1 to 5)
|
||||
for(var/turf/T in spiral_range_turfs(i,src))
|
||||
addtimer(src, "sinShed", i*10, FALSE, T)
|
||||
spawn(60) // required to be spawn so we can call death's ..() to complete death.
|
||||
SpinAnimation(0,0)
|
||||
explosion(get_turf(src), 0, 2, 4, 6, flame_range = 6)
|
||||
..()
|
||||
var/area/A = locate(/area/hades) in world
|
||||
if(A)
|
||||
var/turf/T = get_turf(locate(/obj/effect/landmark/event_spawn) in A)
|
||||
if(T)
|
||||
src.visible_message("<span class='warning'><font size=4>[src]'s Staff is flung free as their body explodes.</font></span>")
|
||||
var/obj/structure/ladder/unbreakable/hades/churchLadder = new/obj/structure/ladder/unbreakable/hades(T)
|
||||
var/obj/structure/ladder/unbreakable/hades/bodyLadder = new/obj/structure/ladder/unbreakable/hades(get_turf(src))
|
||||
var/obj/item/weapon/hades_staff/HS = new/obj/item/weapon/hades_staff(get_turf(src))
|
||||
HS.throw_at_fast(pick(orange(src,7)),10,1)
|
||||
churchLadder.up = bodyLadder
|
||||
bodyLadder.down = churchLadder
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
Defend(user,I)
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
..()
|
||||
Defend(user,user)
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/hitby(atom/movable/AM, skipcatch, hitpush, blocked)
|
||||
..()
|
||||
lastsinPerson -= (sinPersonTime/4)
|
||||
if(istype(AM,/obj/item))
|
||||
var/obj/item/throwCast = AM
|
||||
Defend(throwCast.thrownby,AM)
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/bullet_act(obj/item/projectile/P, def_zone)
|
||||
//don't call ..() because we're going to deflect it
|
||||
lastsinPerson -= (sinPersonTime/4)
|
||||
Defend(P.firer,P)
|
||||
return -1
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/attack_hand(mob/living/carbon/human/M)
|
||||
..()
|
||||
lastsinPerson -= (sinPersonTime/4)
|
||||
Defend(M,M)
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/proc/Defend(var/mob/attacker,var/source)
|
||||
if(!isDoingDeath)
|
||||
rageLevel += 5
|
||||
src.visible_message("<span class='warning'>[src] rounds on the [attacker], gazing at them with a [pick("cold","frosty","freezing","dark")] [pick("glare","gaze","glower","stare")].</span>")
|
||||
|
||||
if(istype(source,/obj/item/projectile))
|
||||
src.visible_message("<span class='warning'>[src] [pick("calmly","silently","nonchalantly")] waves their hand, deflecting the [source].</span>")
|
||||
var/obj/item/projectile/P = source
|
||||
if(P.starting)
|
||||
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
|
||||
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
|
||||
var/turf/curloc = get_turf(src)
|
||||
|
||||
P.original = locate(new_x, new_y, P.z)
|
||||
P.starting = curloc
|
||||
P.current = curloc
|
||||
P.firer = src
|
||||
P.yo = new_y - curloc.y
|
||||
P.xo = new_x - curloc.x
|
||||
P.Angle = null
|
||||
else
|
||||
if(prob(20))
|
||||
var/chosenDefend = rand(1,3)
|
||||
switch(chosenDefend)
|
||||
if(1)
|
||||
attacker.visible_message("<span class='warning'>[attacker] is lifted from the ground, shadowy powers tossing them aside.</span>")
|
||||
attacker.throw_at_fast(pick(orange(src,7)),10,1)
|
||||
if(2)
|
||||
attacker.visible_message("<span class='warning'>[attacker] crackles with electricity, a bolt leaping from [src] to them.</span>")
|
||||
sinLightning.Bolt(src,attacker,30,5,src)
|
||||
if(3)
|
||||
src.visible_message("<span class='warning'>[src] points his staff at [attacker], a swarm of eyeballs lurching fourth!</span>")
|
||||
for(var/i in 1 to 4)
|
||||
var/mob/living/simple_animal/hostile/carp/eyeball/E = new/mob/living/simple_animal/hostile/carp/eyeball(pick(orange(attacker,1)))
|
||||
E.faction = faction
|
||||
addtimer(E, "gib", 150, FALSE)
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/proc/sinShed(var/turf/T)
|
||||
var/obj/effect/overlay/temp/cult/sparks/S = PoolOrNew(/obj/effect/overlay/temp/cult/sparks, T)
|
||||
S.anchored = FALSE
|
||||
S.throw_at_fast(src,10,1)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hadesBlood, T)
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/proc/Transfer(var/mob/living/taken, var/turf/transferTarget)
|
||||
if(transferTarget)
|
||||
playsound(get_turf(taken), 'sound/magic/Ethereal_Enter.ogg', 50, 1, -1)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hadesFlick, get_turf(taken))
|
||||
taken.forceMove(transferTarget)
|
||||
Appear(get_turf(taken))
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/proc/Appear(var/turf/where)
|
||||
var/obj/effect/timestop/hades/TS = new /obj/effect/timestop/hades(where)
|
||||
TS.immune = list(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/hades/Life()
|
||||
if(..() && !isDoingDeath) // appropriately check if we're alive now we leave a corpse
|
||||
if(health > maxHealth/4 && !isFleeing)
|
||||
if(rageLevel > 50)
|
||||
lastWrathTimer = world.time
|
||||
currentState = STATE_WRATH
|
||||
else
|
||||
currentState = STATE_JUDGE
|
||||
else
|
||||
if(world.time > lastFlee + fleeTimer)
|
||||
lastFlee = world.time
|
||||
isFleeing = TRUE
|
||||
currentState = STATE_FLEE
|
||||
|
||||
var/area/healthCheck = get_area(src)
|
||||
|
||||
if(istype(healthCheck,/area/chapel/main))
|
||||
if(currentState == STATE_FLEE)
|
||||
lastWrathTimer = world.time
|
||||
currentState = STATE_WRATH
|
||||
if(health < maxHealth/2)
|
||||
health += 10 // slowly regain hp in the chapel, up to a maximum of half our max
|
||||
|
||||
var/spokenThisTurn = FALSE
|
||||
for(var/mob/living/A in currentAcolytes)
|
||||
if(!A)
|
||||
currentAcolytes -= A
|
||||
continue
|
||||
if(A.health <= 0)
|
||||
rageLevel += 5
|
||||
if(!spokenThisTurn)
|
||||
spokenThisTurn = TRUE
|
||||
var/list/lossSayings = list("They were weak.","For every death, two more rise.",\
|
||||
"What is but one servant lost?","Darkness engulf you!","To the Pit with them.",\
|
||||
"Fools! All of you!","You can't stop me. You. Will. Be. JUDGED.")
|
||||
src.say(pick(lossSayings))
|
||||
currentAcolytes -= A
|
||||
A.gib()
|
||||
|
||||
if(currentState == STATE_WRATH) // we have been enraged.
|
||||
if(world.time > lastWrathTimer + maxWrathTimer)
|
||||
rageLevel = 0 // wind down if we're wrathful too long.
|
||||
rageLevel -= 1 // rage phase starts at 50, meaning roughly 20s of rage.
|
||||
if(currentAcolytes.len == 0)
|
||||
src.say("Rise, Servants. AID YOUR MASTER.")
|
||||
playsound(get_turf(src), 'sound/magic/CastSummon.ogg', 100, 1)
|
||||
for(var/i in 1 to 5)
|
||||
var/mob/living/simple_animal/hostile/hadesacolyte/HA = new/mob/living/simple_animal/hostile/hadesacolyte(get_turf(pick(orange(2,src))))
|
||||
HA.master = src
|
||||
currentAcolytes += HA
|
||||
if(target)
|
||||
if(world.time > lastGrabTime + timeBetweenGrabs)
|
||||
if(get_dist(src,target) > 4) // you can't run from us. upped to 4 to give more leeway.
|
||||
lastGrabTime = world.time
|
||||
var/list/fleeSayings = list("There is no escape from your sins, [target]","Fleeing will only make your punishment worse [target]!",\
|
||||
"There is nowhere you can hide, [target]!","You can't run, [target]!","Get back here, [target]!","You coward, [target]!",\
|
||||
"I will find you, [target]!","Return to me, [target]!")
|
||||
src.say(pick(fleeSayings))
|
||||
var/mob/living/toGrab = target
|
||||
toGrab.Beam(src,"blood",'icons/effects/beam.dmi',10)
|
||||
toGrab.Weaken(6)
|
||||
playsound(get_turf(src), 'sound/magic/CastSummon.ogg', 100, 1)
|
||||
toGrab.throw_at_fast(src,10,1)
|
||||
if(rageLevel >= 100)
|
||||
rageLevel = 50
|
||||
var/list/overboardSayings = list("Ashes! It will all be ashes!","I will bring about the apocolypse!",\
|
||||
"There will be nothing but your withered husks!","Face your doom, cretins!","There. Will. Be. ORDER!",\
|
||||
"I am your Lord, lay down your arms and submit.","Your souls will be cremated!",\
|
||||
"Only in death will you obey!","This is no person's fault but your own!")
|
||||
src.say(pick(overboardSayings))
|
||||
var/turf/StartLoc = get_turf(src)
|
||||
var/list/nearby = orange(6,src)
|
||||
var/slashCount = 0
|
||||
var/aoeType = rand(1,2) // just for future proofing
|
||||
for(var/mob/living/A in nearby)
|
||||
slashCount++
|
||||
A.Beam(src,"blood",'icons/effects/beam.dmi',10)
|
||||
spawn(slashCount + 3)
|
||||
if(aoeType == 1)
|
||||
// no more cheaping it out with non-player mobs like turrets or carps
|
||||
loc = get_turf(A)
|
||||
sinShed(StartLoc)
|
||||
A.attack_animal(src)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hadesBlood,get_turf(A))
|
||||
playsound(get_turf(A), 'sound/magic/SummonItems_generic.ogg', 100, 1)
|
||||
if(aoeType == 2)
|
||||
sinShed(StartLoc)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hadesBite,get_turf(A))
|
||||
A.Weaken(6)
|
||||
var/obj/effect/timestop/hades/large/TS = new /obj/effect/timestop/hades/large(StartLoc)
|
||||
TS.immune = list(src)
|
||||
spawn((slashCount+1)+3)
|
||||
loc = StartLoc
|
||||
|
||||
if(currentState == STATE_FLEE) // we've been wounded, let us flee and lick our wounds
|
||||
var/area/A = locate(/area/chapel/main) in world
|
||||
if(A)
|
||||
var/turf/T = get_turf(locate(/obj/effect/landmark/event_spawn) in A)
|
||||
if(!T)
|
||||
T = get_turf(src) // no event spawn in chapel, fall back to doing it on the spot.
|
||||
if(T)
|
||||
fleeTimes++
|
||||
Transfer(src,T)
|
||||
AIStatus = AI_OFF
|
||||
notransform = TRUE
|
||||
anchored = TRUE
|
||||
for(var/i in 1 to 5)
|
||||
spawn(i*10)
|
||||
for(var/turf/S in oview(i,src) - oview((i)-1,src))
|
||||
sinShed(S)
|
||||
health += maxHealth/(10*fleeTimes) // every flee we gain less HP
|
||||
spawn(50)
|
||||
isFleeing = FALSE
|
||||
notransform = FALSE
|
||||
anchored = FALSE
|
||||
AIStatus = AI_ON
|
||||
currentState = STATE_JUDGE
|
||||
lastsinPerson = 0 // immediately teleport away to judge
|
||||
|
||||
if(currentState == STATE_JUDGE) // our default state, judge a few people and tell them they're rude or something
|
||||
if(world.time > lastsinPerson + sinPersonTime)
|
||||
if(prob(fakesinPersonChance))
|
||||
lastsinPerson = world.time
|
||||
visible_message("<span class='warning'><font size=3>[pick(sinPersonsayings)]</font></span>")
|
||||
playsound(get_turf(src), pick(creepyasssounds), 100, 1)
|
||||
else
|
||||
lastsinPerson = world.time
|
||||
var/mob/living/carbon/human/sinPerson = pick(living_mob_list)
|
||||
var/depth = living_mob_list.len + 1 // just in case
|
||||
if(sinPerson) // no more finding nullcakes
|
||||
if(!sinPerson.ckey)
|
||||
while(!sinPerson.ckey && depth > 0)
|
||||
--depth
|
||||
var/checkPerson = pick(living_mob_list)
|
||||
if(checkPerson)
|
||||
sinPerson = checkPerson
|
||||
if(!sinPerson.ckey)
|
||||
// double check ensure that if the above loop fails to get a ckey target
|
||||
// we don't go and use the last mob checked, causing odd situations
|
||||
return
|
||||
if(sinPerson)
|
||||
if(prob(65)) // moderately high chance for us to go to them, else they come here.
|
||||
Transfer(src,get_turf(pick(oview(1,sinPerson))))
|
||||
else
|
||||
Transfer(sinPerson,get_turf(pick(oview(1,src))))
|
||||
var/sinPersonchoice = pick(validSins)
|
||||
switch(sinPersonchoice)
|
||||
if("Greed")
|
||||
src.say("Your sin, [sinPerson], is Greed.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Greed(sinPerson, TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Greed(sinPerson, FALSE)
|
||||
if("Gluttony")
|
||||
src.say("Your sin, [sinPerson], is Gluttony.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Gluttony(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Gluttony(sinPerson,FALSE)
|
||||
if("Pride")
|
||||
src.say("Your sin, [sinPerson], is Pride.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Pride(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Pride(sinPerson,FALSE)
|
||||
if("Lust")
|
||||
src.say("Your sin, [sinPerson], is Lust.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Lust(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Lust(sinPerson,TRUE)
|
||||
if("Envy")
|
||||
src.say("Your sin, [sinPerson], is Envy.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Envy(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Envy(sinPerson,FALSE)
|
||||
if("Sloth")
|
||||
src.say("Your sin, [sinPerson], is Sloth.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Sloth(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Sloth(sinPerson,FALSE)
|
||||
if("Wrath")
|
||||
src.say("Your sin, [sinPerson], is Wrath.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Wrath(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Wrath(sinPerson,FALSE)
|
||||
|
||||
|
||||
///Sin related things
|
||||
|
||||
//global Sin procs, shared between staff and pope
|
||||
|
||||
/proc/sin_Greed(var/mob/living/carbon/human/sinPerson, var/isIndulged)
|
||||
if(isIndulged)
|
||||
sinPerson << "<span class='warning'>You feel like you deserve more, in fact, you want everything.</span>"
|
||||
var/list/greed = list(/obj/item/stack/sheet/mineral/gold,/obj/item/stack/sheet/mineral/silver,/obj/item/stack/sheet/mineral/diamond)
|
||||
for(var/i in 1 to 10)
|
||||
var/greed_type = pick(greed)
|
||||
new greed_type(get_turf(sinPerson))
|
||||
else
|
||||
sinPerson << "<span class='warning'>Your body begins to shift and bend, changing to reflect your inner greed.</span>"
|
||||
var/mob/living/M = sinPerson.change_mob_type(/mob/living/simple_animal/cockroach,get_turf(sinPerson),"Greedroach",1)
|
||||
M.AddSpell(new/obj/effect/proc_holder/spell/targeted/mind_transfer)
|
||||
|
||||
/proc/sin_Gluttony(var/mob/living/carbon/human/sinPerson, var/isIndulged)
|
||||
if(isIndulged)
|
||||
sinPerson << "<span class='warning'>Your stomach growls, you feel hungry.</span>"
|
||||
var/list/allTypes = list()
|
||||
for(var/A in typesof(/obj/item/weapon/reagent_containers/food/snacks))
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/O = A
|
||||
if(initial(O.cooked_type))
|
||||
allTypes += A
|
||||
for(var/i in 1 to 10)
|
||||
var/greed_type = pick(allTypes)
|
||||
new greed_type(get_turf(sinPerson))
|
||||
else
|
||||
sinPerson << "<span class='warning'>Your body begins to bloat and stretch, bile rising in your throat.</span>"
|
||||
sinPerson.reagents.add_reagent("nutriment",1000)
|
||||
|
||||
/proc/sin_Pride(var/mob/living/carbon/human/sinPerson, var/isIndulged)
|
||||
if(isIndulged)
|
||||
sinPerson << "<span class='warning'>You feel strong enough to take on the world.</span>"
|
||||
var/obj/item/weapon/twohanded/sin_pride/good = new/obj/item/weapon/twohanded/sin_pride(get_turf(sinPerson))
|
||||
good.name = "Indulged [good.name]"
|
||||
good.pride_direction = FALSE
|
||||
else
|
||||
sinPerson << "<span class='warning'>You feel small and weak, like the entire world is against you.</span>"
|
||||
var/obj/item/weapon/twohanded/sin_pride/bad = new/obj/item/weapon/twohanded/sin_pride(get_turf(sinPerson))
|
||||
bad.name = "Punished [bad.name]"
|
||||
bad.pride_direction = TRUE
|
||||
|
||||
/proc/sin_Lust(var/mob/living/carbon/human/sinPerson, var/isIndulged)
|
||||
if(isIndulged)
|
||||
sinPerson << "<span class='warning'>You feel confident, like everything and everyone is drawn to you.</span>"
|
||||
var/obj/item/lovestone/good = new/obj/item/lovestone(get_turf(sinPerson))
|
||||
good.name = "Indulged [good.name]"
|
||||
good.lust_direction = FALSE
|
||||
else
|
||||
sinPerson << "<span class='warning'>You feel lonely... the wish for the warmth of another spark through your mind.</span>"
|
||||
var/obj/item/lovestone/bad = new/obj/item/lovestone(get_turf(sinPerson))
|
||||
bad.name = "Punished [bad.name]"
|
||||
bad.lust_direction = TRUE
|
||||
|
||||
/proc/sin_Envy(var/mob/living/carbon/human/sinPerson, var/isIndulged)
|
||||
if(isIndulged)
|
||||
for(var/mob/living/carbon/human/H in player_list) // name lottery
|
||||
if(H == sinPerson)
|
||||
continue
|
||||
if(prob(25))
|
||||
sinPerson.name = H.name
|
||||
sinPerson.real_name = H.real_name
|
||||
var/datum/dna/lottery = H.dna
|
||||
lottery.transfer_identity(sinPerson, transfer_SE=1)
|
||||
sinPerson.updateappearance(mutcolor_update=1)
|
||||
sinPerson.domutcheck()
|
||||
sinPerson << "<span class='warning'>You feel envious of [sinPerson.name], and your body shifts to reflect that!</span>"
|
||||
else
|
||||
var/sinPersonspecies = pick(species_list)
|
||||
var/newtype = species_list[sinPersonspecies]
|
||||
sinPerson << "<span class='warning'>You wish for more from yourself.. your body shifts to suit your wish.</span>"
|
||||
sinPerson.set_species(newtype)
|
||||
|
||||
/proc/sin_Sloth(var/mob/living/carbon/human/sinPerson, var/isIndulged)
|
||||
if(isIndulged)
|
||||
sinPerson << "<span class='warning'>You feel tired...</span>"
|
||||
sinPerson.drowsyness += 100
|
||||
else
|
||||
sinPerson << "<span class='warning'>A chill comes over your body, the feeling of frostbite nipping at your fingers.</span>"
|
||||
sinPerson.reagents.add_reagent("frostoil", 50)
|
||||
|
||||
/proc/sin_Wrath(var/mob/living/carbon/human/sinPerson, var/isIndulged)
|
||||
if(isIndulged)
|
||||
sinPerson << "<span class='warning'>You feel wrathful, like you want to destroy everyone and everything.</span>"
|
||||
sinPerson.change_mob_type(/mob/living/simple_animal/slaughter,get_turf(sinPerson),"Wrath Demon",1)
|
||||
else
|
||||
sinPerson << "<span class='warning'>Your chest feels tight, and the world begins to spin around you.</span>"
|
||||
sinPerson.reagents.add_reagent("lexorin", 29)
|
||||
sinPerson.reagents.add_reagent("mindbreaker", 29)
|
||||
|
||||
/obj/effect/overlay/temp/hadesFlick
|
||||
name = "transdimensional waste"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "liquify"
|
||||
duration = 15
|
||||
|
||||
/obj/effect/overlay/temp/hadesBite
|
||||
name = "biting tendril"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "tendril_bite"
|
||||
duration = 15
|
||||
|
||||
/obj/effect/overlay/temp/hadesBlood
|
||||
name = "blood plume"
|
||||
icon = 'icons/effects/128x128.dmi'
|
||||
icon_state = "spray_plume"
|
||||
duration = 30
|
||||
|
||||
/obj/effect/timestop/hades // custom timeslip to make him immune
|
||||
name = "Frozen Time"
|
||||
desc = "Time has slowed to a halt."
|
||||
|
||||
/obj/effect/timestop/hades/New()
|
||||
spawn(5)
|
||||
..()
|
||||
|
||||
/obj/effect/timestop/hades/large
|
||||
freezerange = 6
|
||||
icon_state = "huge_rune"
|
||||
icon = 'icons/effects/224x224.dmi'
|
||||
|
||||
|
||||
/obj/item/weapon/twohanded/sin_pride
|
||||
icon_state = "mjollnir0"
|
||||
name = "Pride-struck Hammer"
|
||||
desc = "It resonates an aura of Pride."
|
||||
force = 5
|
||||
throwforce = 15
|
||||
w_class = 4
|
||||
slot_flags = SLOT_BACK
|
||||
force_unwielded = 5
|
||||
force_wielded = 20
|
||||
attack_verb = list("attacked", "smashed", "crushed", "splattered", "cracked")
|
||||
hitsound = 'sound/weapons/blade1.ogg'
|
||||
var/pride_direction = FALSE
|
||||
|
||||
/obj/item/weapon/twohanded/sin_pride/update_icon()
|
||||
icon_state = "mjollnir[wielded]"
|
||||
return
|
||||
|
||||
/obj/item/weapon/twohanded/sin_pride/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
|
||||
if(!proximity) return
|
||||
if(wielded)
|
||||
if(istype(A,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/H = A
|
||||
var/mob/living/carbon/U = user
|
||||
if(H)
|
||||
if(pride_direction == FALSE)
|
||||
U.reagents.trans_to(H, user.reagents.total_volume, 1, 1, 0)
|
||||
U << "Your pride reflects on [H]."
|
||||
if(H.health > 0)
|
||||
U.health += force
|
||||
U.updatehealth()
|
||||
H.health -= force
|
||||
H.updatehealth()
|
||||
H << "You feel insecure, taking on [user]'s burden."
|
||||
else if(pride_direction == TRUE)
|
||||
H.reagents.trans_to(user, H.reagents.total_volume, 1, 1, 0)
|
||||
H << "Your pride reflects on [user]."
|
||||
if(U.health > 0)
|
||||
U.health -= force
|
||||
U.updatehealth()
|
||||
H.health += force
|
||||
H.updatehealth()
|
||||
U << "You feel insecure, taking on [H]'s burden."
|
||||
|
||||
/obj/item/lovestone
|
||||
name = "Stone of Lust"
|
||||
desc = "It lays within your hand, radiating pulses of uncomfortable warmth."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "lovestone"
|
||||
item_state = "lovestone"
|
||||
w_class = 1
|
||||
var/lust_direction = FALSE
|
||||
var/lastUsage = 0
|
||||
var/usageTimer = 300
|
||||
|
||||
/obj/item/lovestone/attack_self(mob/user)
|
||||
if(world.time > lastUsage + usageTimer)
|
||||
lastUsage = world.time
|
||||
user.visible_message("<span class='warning'>[user] grips the [src] tightly, causing it to vibrate and pulse brightly.</span>")
|
||||
spawn(25)
|
||||
if(lust_direction == FALSE)
|
||||
var/list/throwAt = list()
|
||||
for(var/atom/movable/AM in oview(7,user))
|
||||
if(!AM.anchored && AM != user)
|
||||
throwAt.Add(AM)
|
||||
for(var/counter = 1, counter < throwAt.len, ++counter)
|
||||
var/atom/movable/cast = throwAt[counter]
|
||||
cast.throw_at_fast(user,10,1)
|
||||
else if(lust_direction == 1)
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/mob/living/carbon/human/foundLover = locate(/mob/living/carbon/human) in orange(3,H)
|
||||
if(!foundLover)
|
||||
H << "As you hold the stone, loneliness grips you, your heart feeling heavy and you struggle to breath."
|
||||
for(var/i in 1 to 10)
|
||||
addtimer(H.reagents, "add_reagent", i*10, FALSE, "initropidril", i)
|
||||
else
|
||||
H << "You take comfort in the presence of [foundLover]"
|
||||
H.reagents.add_reagent("omnizine",25)
|
||||
H.Beam(foundLover,"r_beam",'icons/effects/beam.dmi',10)
|
||||
foundLover << "You take comfort in the presence of [H]"
|
||||
foundLover.reagents.add_reagent("omnizine",25)
|
||||
else
|
||||
user << "The stone lays inert. It is still recharging."
|
||||
|
||||
/mob/living/simple_animal/hostile/hadesacolyte
|
||||
name = "Acolyte of Hades"
|
||||
desc = "Darkness seethes from their every pore."
|
||||
icon_state = "hades_acolyte"
|
||||
icon_living = "hades_acolyte"
|
||||
icon_dead = "hades_acolyte_dead"
|
||||
speak_chance = 0
|
||||
turns_per_move = 5
|
||||
response_help = "trembles in fear of"
|
||||
response_disarm = "slaps wildly at"
|
||||
response_harm = "hits"
|
||||
speed = 1
|
||||
maxHealth = 45
|
||||
health = 45
|
||||
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 15
|
||||
attacktext = "strikes at"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
butcher_results = list(/obj/item/clothing/mask/gas/cyborg/hades = 1,/obj/item/clothing/suit/hooded/chaplain_hoodie/hades = 1,/obj/item/weapon/hades_staff/fake = 1)
|
||||
|
||||
unsuitable_atmos_damage = 0
|
||||
del_on_death = 0
|
||||
faction = list("hades")
|
||||
|
||||
var/mob/living/simple_animal/hostile/hades/master
|
||||
|
||||
/mob/living/simple_animal/hostile/hadesacolyte/Life()
|
||||
if(..())
|
||||
if(master)
|
||||
if(get_dist(src,master) > 5)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hadesFlick,get_turf(src))
|
||||
src.visible_message("<span class='warning'>[src] twists and distorts, before vanishing in a snap.</span>")
|
||||
src.forceMove(get_turf(pick(orange(2,master))))
|
||||
|
||||
//acolyte of hades outfit
|
||||
/obj/item/clothing/mask/gas/cyborg/hades
|
||||
name = "Skull Mask"
|
||||
desc = "It's a skull mask, made of a thin, cool metal."
|
||||
|
||||
/obj/item/clothing/suit/hooded/chaplain_hoodie/hades
|
||||
name = "Dark robes"
|
||||
desc = "A dark, soft robe."
|
||||
hooded = 1
|
||||
hoodtype = /obj/item/clothing/head/chaplain_hood/hades
|
||||
|
||||
/obj/item/clothing/head/chaplain_hood/hades
|
||||
name = "Dark hood"
|
||||
desc = "A dark, soft hood."
|
||||
body_parts_covered = HEAD
|
||||
flags_inv = HIDEHAIR|HIDEEARS
|
||||
//end hades outfit
|
||||
|
||||
/obj/item/hades_summoner
|
||||
name = "Dark Seed"
|
||||
desc = "The stone lays inert, but even when holding it you hear maddened whispers."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "dark_seed_inert"
|
||||
item_state = "dark_seed_inert"
|
||||
w_class = 1
|
||||
var/isActivated = FALSE
|
||||
var/whoActivated
|
||||
var/countDownToSummon = 10
|
||||
var/absorbedHP = 0
|
||||
|
||||
/obj/item/hades_summoner/attack_self(mob/user)
|
||||
if(!isActivated)
|
||||
var/choice = input(user,"Rub the stone?",name) in list("Yes","No")
|
||||
if(choice == "Yes")
|
||||
if(prob(15))
|
||||
user << "<span class='warning'><font size=3>You rub the stone.. and a voice springs fourth!</font></span>"
|
||||
user << "<span class='warning'><font size=3>You hear a voice in your head.. 'Bring me the flesh of a living being.. and we shall bargain.'</font></span>"
|
||||
whoActivated = user
|
||||
isActivated = TRUE
|
||||
desc = "The stone hums with a soft glow, whispering to you."
|
||||
icon_state = "dark_seed"
|
||||
else
|
||||
user << "<span class='warning'><font size=3>The stone shivers, but nothing happens. Perhaps try again later?</font></span>"
|
||||
else
|
||||
if(user != whoActivated)
|
||||
user << "<span class='warning'><font size=3>The stone lays inert.</font></span>"
|
||||
else
|
||||
if(countDownToSummon > 0)
|
||||
user << "<span class='warning'><font size=3>You hear a voice in your head.. 'I still require [countDownToSummon] vessels worth of flesh. Bring them to me'</font></span>"
|
||||
else
|
||||
user << "<span class='warning'><font size=3>I thank you, acolyte.</font></span>"
|
||||
var/mob/living/simple_animal/hostile/hadesacolyte/HA = user.change_mob_type(/mob/living/simple_animal/hostile/hadesacolyte,get_turf(user),"[user.name]",1)
|
||||
var/mob/living/simple_animal/hostile/hades/H = new/mob/living/simple_animal/hostile/hades(get_turf(user))
|
||||
H.maxHealth = absorbedHP
|
||||
H.health = H.maxHealth
|
||||
if(H.maxHealth < initial(H.maxHealth))
|
||||
HA << "<span class='warning'><font size=3>You.. you fool! How dare you summon me with such dirty flesh!</font></span>"
|
||||
HA.faction -= "hades"
|
||||
if(H.maxHealth > initial(H.maxHealth))
|
||||
HA << "<span class='warning'><font size=3>Such.. power! You have exceeded yourself, acolyte. Drink of my might!</font></span>"
|
||||
HA.maxHealth = 250
|
||||
HA.health = 250
|
||||
qdel(src)
|
||||
|
||||
/obj/item/hades_summoner/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
if(istype(A,/mob/living))
|
||||
var/mob/living/M = A
|
||||
if(countDownToSummon > 0)
|
||||
if(M.health > 0 && M.maxHealth > 200)
|
||||
// no absorbing super strong creatures unless they're dead
|
||||
user << "<span class='warning'><font size=3>Such power.. Slay this [M] so that I may partake of its being.</font></span>"
|
||||
return
|
||||
if(!M.stat)
|
||||
user << "<span class='warning'><font size=3>[M] is still too tightly bound to the mortal world! You must either kill or knock them unconscious to sacrifice them.</font></span>"
|
||||
return
|
||||
user << "<span class='warning'><font size=3>I accept your offering.</font></span>"
|
||||
absorbedHP += M.maxHealth
|
||||
if(!M.ckey)
|
||||
M.gib()
|
||||
else
|
||||
M << "<span class='warning'><font size=3>You feel the flesh being stripped from your bones. You're overwhelmed with maddening pain, before reforming into another being!</font></span>"
|
||||
M.change_mob_type(/mob/living/simple_animal/hostile/hadesacolyte,get_turf(user),"[user.name]",1)
|
||||
countDownToSummon--
|
||||
if(countDownToSummon <= 0)
|
||||
user << "<span class='warning'><font size=3>I am ready to ascend, my acolyte.</font></span>"
|
||||
|
||||
|
||||
#undef STATE_JUDGE
|
||||
#undef STATE_WRATH
|
||||
#undef STATE_FLEE
|
||||
@@ -1,177 +0,0 @@
|
||||
/area/hades
|
||||
name = "Chapel of Sin"
|
||||
icon_state = "yellow"
|
||||
requires_power = 0
|
||||
has_gravity = 1
|
||||
|
||||
/turf/open/floor/plasteel/hades
|
||||
name = "Sin-touched Floor"
|
||||
icon_state = "cult"
|
||||
|
||||
/obj/structure/chair/hades
|
||||
name = "Cross of Hades"
|
||||
desc = "An inverted cross, with straps on it to support the weight of a living being."
|
||||
icon_state = "chair_hades"
|
||||
var/list/watchedSpikes = list()
|
||||
|
||||
/obj/structure/chair/hades/New()
|
||||
..()
|
||||
flags |= NODECONSTRUCT
|
||||
for(var/obj/structure/kitchenspike/KS in range(12))
|
||||
watchedSpikes += KS
|
||||
|
||||
/obj/structure/chair/hades/proc/considerReady()
|
||||
//buckled_mobs seems to work inconsistently, so we're doing some custom searching here.
|
||||
if(!buckled_mobs)
|
||||
return FALSE
|
||||
if(!buckled_mobs.len)
|
||||
return FALSE
|
||||
for(var/obj/structure/kitchenspike/KS in watchedSpikes)
|
||||
var/mob/living/M = locate(/mob/living) in get_turf(KS)
|
||||
if(!M)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/chair/hades/proc/completeRitual()
|
||||
for(var/obj/structure/kitchenspike/KS in watchedSpikes)
|
||||
var/mob/living/M = locate(/mob/living) in get_turf(KS)
|
||||
M.gib()
|
||||
playsound(get_turf(src), 'sound/effects/pope_entry.ogg', 100, 1)
|
||||
sleep(100)
|
||||
playsound(get_turf(src), 'sound/effects/hyperspace_end.ogg', 100, 1)
|
||||
new/obj/item/weapon/hades_staff/imbued(get_turf(src))
|
||||
src.visible_message("<span class='warning'>[src] shatters into a thousand shards, a staff falling from it.</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/chair/hades/attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/hades_staff))
|
||||
var/obj/item/weapon/hades_staff/HS = W
|
||||
if(!HS.isKey)
|
||||
return
|
||||
src.visible_message("<span class='warning'>[user] inserts the [W] into the [src], giving it a quick turn.</span>")
|
||||
if(considerReady())
|
||||
qdel(W)
|
||||
src.visible_message("<span class='warning'>[src] shudders, the sound of moving gears arising...</span>")
|
||||
for(var/mob/living/M in buckled_mobs)
|
||||
M.gib()
|
||||
for(var/i in 1 to 4)
|
||||
addtimer(GLOBAL_PROC, "playsound", i*10, FALSE, get_turf(src), 'sound/effects/clang.ogg', 100, 1)
|
||||
spawn(50)
|
||||
src.visible_message("<span class='warning'>[src] begins to lower into the ground...</span>")
|
||||
icon_state = "chair_hades_slide"
|
||||
addtimer(src, "completeRitual", 50, FALSE)
|
||||
else
|
||||
src.visible_message("<span class='warning'>[src] clunks, the sound of grinding gears arising. Nothing happens.</span>")
|
||||
|
||||
/obj/structure/ladder/unbreakable/hades
|
||||
name = "Dimensional Rift"
|
||||
desc = "Where does it lead?"
|
||||
icon = 'icons/mob/EvilPope.dmi'
|
||||
icon_state = "popedeath"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/ladder/unbreakable/hades/update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/paper/hades_instructions
|
||||
name = "paper- 'Hastily Scrawled Letter'"
|
||||
info = "The Master has instructed us to collect corpses for the ritual, and told us to deposity them in the Ritual Room, behind a bookcase in the library. The Master has locked the device to only work with his key, so no more accidents happen."
|
||||
|
||||
/obj/item/weapon/hades_staff
|
||||
name = "Staff of Hades"
|
||||
desc = "A large, dark staff, with a set of key-like prongs on the end."
|
||||
icon_state = "staffofchange"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
item_state = "staffofchange"
|
||||
slot_flags = SLOT_BELT | SLOT_BACK
|
||||
force = 25
|
||||
throwforce = 5
|
||||
w_class = 3
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("slapped", "shattered", "blasphemed", "smashed", "whacked", "crushed", "hammered")
|
||||
block_chance = 25
|
||||
var/isKey = 1
|
||||
|
||||
/obj/item/weapon/hades_staff/fake
|
||||
name = "Inert Staff of Hades"
|
||||
desc = "A large, dark staff."
|
||||
isKey = 0
|
||||
|
||||
/obj/item/weapon/hades_staff/imbued
|
||||
name = "Imbued Staff of Hades"
|
||||
desc = " Bestowed with the power of wayward souls, this Staff allows the wielder to judge a target."
|
||||
force = 75
|
||||
throwforce = 35
|
||||
block_chance = 75
|
||||
var/lastJudge = 0
|
||||
var/judgeCooldown = 150
|
||||
|
||||
/obj/item/weapon/hades_staff/imbued/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
|
||||
if(!istype(M))
|
||||
return ..()
|
||||
|
||||
if(world.time > lastJudge + judgeCooldown)
|
||||
var/mob/living/sinPerson = M
|
||||
lastJudge = world.time
|
||||
var/sinPersonchoice = pick("Greed","Gluttony","Pride","Lust","Envy","Sloth","Wrath")
|
||||
switch(sinPersonchoice)
|
||||
if("Greed")
|
||||
src.say("Your sin, [sinPerson], is Greed.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Greed(sinPerson, TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Greed(sinPerson, FALSE)
|
||||
if("Gluttony")
|
||||
src.say("Your sin, [sinPerson], is Gluttony.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Gluttony(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Gluttony(sinPerson,FALSE)
|
||||
if("Pride")
|
||||
src.say("Your sin, [sinPerson], is Pride.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Pride(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Pride(sinPerson,FALSE)
|
||||
if("Lust")
|
||||
src.say("Your sin, [sinPerson], is Lust.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Lust(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Lust(sinPerson,TRUE)
|
||||
if("Envy")
|
||||
src.say("Your sin, [sinPerson], is Envy.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Envy(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Envy(sinPerson,FALSE)
|
||||
if("Sloth")
|
||||
src.say("Your sin, [sinPerson], is Sloth.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Sloth(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Sloth(sinPerson,FALSE)
|
||||
if("Wrath")
|
||||
src.say("Your sin, [sinPerson], is Wrath.")
|
||||
if(prob(50))
|
||||
src.say("I will indulge your sin, [sinPerson].")
|
||||
sin_Wrath(sinPerson,TRUE)
|
||||
else
|
||||
src.say("Your sin will be punished, [sinPerson]!")
|
||||
sin_Wrath(sinPerson,FALSE)
|
||||
else
|
||||
..()
|
||||
user << "The [src] is still recharging."
|
||||
@@ -1,62 +0,0 @@
|
||||
/proc/gibs(atom/location, list/viruses, datum/dna/MobDNA)
|
||||
new /obj/effect/gibspawner/generic(location,viruses,MobDNA)
|
||||
|
||||
/proc/hgibs(atom/location, list/viruses, datum/dna/MobDNA)
|
||||
new /obj/effect/gibspawner/human(location,viruses,MobDNA)
|
||||
|
||||
/proc/xgibs(atom/location, list/viruses)
|
||||
new /obj/effect/gibspawner/xeno(location,viruses)
|
||||
|
||||
/proc/robogibs(atom/location, list/viruses)
|
||||
new /obj/effect/gibspawner/robot(location,viruses)
|
||||
|
||||
/obj/effect/gibspawner
|
||||
var/sparks = 0 //whether sparks spread on Gib()
|
||||
var/virusProb = 20 //the chance for viruses to spread on the gibs
|
||||
var/list/gibtypes = list()
|
||||
var/list/gibamounts = list()
|
||||
var/list/gibdirections = list() //of lists
|
||||
|
||||
/obj/effect/gibspawner/New(location, var/list/viruses, var/datum/dna/MobDNA)
|
||||
..()
|
||||
|
||||
Gib(loc,viruses,MobDNA)
|
||||
|
||||
/obj/effect/gibspawner/proc/Gib(atom/location, list/viruses = list(), datum/dna/MobDNA = null)
|
||||
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
|
||||
world << "<span class='danger'>Gib list length mismatch!</span>"
|
||||
return
|
||||
|
||||
var/obj/effect/decal/cleanable/blood/gibs/gib = null
|
||||
|
||||
if(sparks)
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(2, 1, location)
|
||||
s.start()
|
||||
|
||||
for(var/i = 1, i<= gibtypes.len, i++)
|
||||
if(gibamounts[i])
|
||||
for(var/j = 1, j<= gibamounts[i], j++)
|
||||
var/gibType = gibtypes[i]
|
||||
gib = new gibType(location)
|
||||
if(istype(location,/mob/living/carbon))
|
||||
var/mob/living/carbon/digester = location
|
||||
digester.stomach_contents += gib
|
||||
|
||||
if(viruses.len > 0)
|
||||
for(var/datum/disease/D in viruses)
|
||||
if(prob(virusProb))
|
||||
var/datum/disease/viruus = D.Copy(1)
|
||||
gib.viruses += viruus
|
||||
viruus.holder = gib
|
||||
|
||||
if(MobDNA)
|
||||
gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type
|
||||
else if(istype(src, /obj/effect/gibspawner/generic)) // Probably a monkey
|
||||
gib.blood_DNA["Non-human DNA"] = "A+"
|
||||
var/list/directions = gibdirections[i]
|
||||
if(istype(loc,/turf))
|
||||
if(directions.len)
|
||||
gib.streak(directions)
|
||||
|
||||
qdel(src)
|
||||
@@ -1,25 +0,0 @@
|
||||
/obj/item/device/boobytrap
|
||||
name = "booby trap"
|
||||
desc = null //Different examine for traitors
|
||||
item_state = "electronic"
|
||||
icon_state = "boobytrap"
|
||||
w_class = 1
|
||||
throw_range = 4
|
||||
throw_speed = 1
|
||||
flags = NOBLUDGEON
|
||||
force = 3
|
||||
attack_verb = list("trapped", "rused", "tricked")
|
||||
materials = list(MAT_METAL=50, MAT_GLASS=30)
|
||||
origin_tech = "syndicate=1;combat=3;engineering=3"
|
||||
|
||||
/obj/item/device/boobytrap/proc/blow()
|
||||
explosion(src.loc,0,0,2,4,flame_range = 4)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/device/boobytrap/examine(mob/user)
|
||||
..()
|
||||
if(user.mind in ticker.mode.traitors) //No nuke ops because the device is excluded from nuclear
|
||||
user << "A small device used to rig lockers and boxes with an explosive surprise. \
|
||||
To use, simply attach it to a box or a locker."
|
||||
else
|
||||
user << "A suspicious array of delicate wires and parts."
|
||||
@@ -1,35 +0,0 @@
|
||||
/obj/item/modkit
|
||||
name = "modification kit"
|
||||
desc = "A one-use kit, which enables kinetic accelerators to retain their \
|
||||
charge when away from a bioelectric source, renders them immune to \
|
||||
interference with other accelerators, as well as allowing less \
|
||||
dextrous races to use the tool."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "modkit"
|
||||
origin_tech = "programming=2;materials=2;magnets=4"
|
||||
var/uses = 1
|
||||
|
||||
/obj/item/modkit/afterattack(obj/item/weapon/gun/energy/kinetic_accelerator/C, mob/user)
|
||||
..()
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
return
|
||||
if(!istype(C))
|
||||
user << "<span class='warning'>This kit can only modify kinetic \
|
||||
accelerators!</span>"
|
||||
return ..()
|
||||
// RIP the 'improved improved improved improved kinetic accelerator
|
||||
if(C.holds_charge && C.unique_frequency)
|
||||
user << "<span class='warning'>This kinetic accelerator already has \
|
||||
these upgrades.</span>"
|
||||
return ..()
|
||||
|
||||
user <<"<span class='notice'>You modify the [C], adjusting the trigger \
|
||||
guard and internal capacitor.</span>"
|
||||
C.name = "improved [C.name]"
|
||||
C.holds_charge = TRUE
|
||||
C.unique_frequency = TRUE
|
||||
C.trigger_guard = TRIGGER_GUARD_ALLOW_ALL
|
||||
uses--
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
@@ -1,167 +0,0 @@
|
||||
|
||||
/*
|
||||
/tg/station13 /datum Pool:
|
||||
---------------------------------
|
||||
By RemieRichards
|
||||
|
||||
Creation/Deletion is laggy, so let's reduce reuse and recycle!
|
||||
|
||||
Usage:
|
||||
|
||||
To get a object, just call
|
||||
- PoolOrNew(type, arg) if you only want to pass one argument to New(), usually loc
|
||||
- PoolOrNew(type, list) if you want to pass multiple arguments to New()
|
||||
|
||||
To put a object back in the pool, call PlaceInPool(object)
|
||||
This will call destroy on the object, set its loc to null,
|
||||
and reset all of its vars to their default
|
||||
|
||||
You can override your object's destroy to return QDEL_HINT_PUTINPOOL
|
||||
to ensure its always placed in this pool (this will only be acted on if qdel calls destroy, and destroy will not get called twice)
|
||||
|
||||
For almost all pooling purposes, it is better to use the QDEL hint than to pool it directly with PlaceInPool
|
||||
|
||||
*/
|
||||
|
||||
#define MAINTAINING_OBJECT_POOL_COUNT 500
|
||||
|
||||
var/global/list/GlobalPool = list()
|
||||
|
||||
//You'll be using this proc 90% of the time.
|
||||
//It grabs a type from the pool if it can
|
||||
//And if it can't, it creates one
|
||||
//The pool is flexible and will expand to fit
|
||||
//The new created atom when it eventually
|
||||
//Goes into the pool
|
||||
|
||||
//Second argument can be a single arg
|
||||
//Or a list of arguments
|
||||
//Either way it gets passed to new
|
||||
|
||||
/proc/PoolOrNew(get_type,second_arg)
|
||||
if(!get_type)
|
||||
return
|
||||
|
||||
. = GetFromPool(get_type,second_arg)
|
||||
|
||||
if(!.)
|
||||
if(ispath(get_type))
|
||||
if(islist(second_arg))
|
||||
. = new get_type (arglist(second_arg))
|
||||
else
|
||||
. = new get_type (second_arg)
|
||||
|
||||
|
||||
/proc/GetFromPool(get_type,second_arg)
|
||||
if(!get_type)
|
||||
return
|
||||
|
||||
if(isnull(GlobalPool[get_type]))
|
||||
return
|
||||
|
||||
if(length(GlobalPool[get_type]) == 0)
|
||||
return
|
||||
|
||||
var/datum/pooled = pop(GlobalPool[get_type])
|
||||
if(pooled)
|
||||
pooled.gc_destroyed = null
|
||||
|
||||
var/atom/movable/AM
|
||||
if(istype(pooled, /atom/movable))
|
||||
AM = pooled
|
||||
|
||||
if(islist(second_arg))
|
||||
if(AM)
|
||||
AM.loc = second_arg[1] //we need to do loc setting explicetly before even calling New() to replicate new()'s behavior
|
||||
pooled.New(arglist(second_arg))
|
||||
|
||||
else
|
||||
if(AM)
|
||||
AM.loc = second_arg
|
||||
pooled.New(second_arg)
|
||||
|
||||
return pooled
|
||||
|
||||
|
||||
/proc/PlaceInPool(datum/diver, destroy = 1)
|
||||
if(!istype(diver))
|
||||
return
|
||||
|
||||
if(diver in GlobalPool[diver.type])
|
||||
return
|
||||
|
||||
if(!GlobalPool[diver.type])
|
||||
GlobalPool[diver.type] = list()
|
||||
|
||||
GlobalPool[diver.type] |= diver
|
||||
|
||||
if(destroy)
|
||||
diver.Destroy()
|
||||
|
||||
diver.gc_destroyed = 1
|
||||
|
||||
diver.ResetVars()
|
||||
|
||||
var/list/exclude = list("animate_movement", "contents", "loc", "locs", "parent_type", "vars", "verbs", "type", "gc_destroyed")
|
||||
var/list/pooledvariables = list()
|
||||
//thanks to clusterfack @ /vg/station for these two procs
|
||||
/datum/proc/createVariables()
|
||||
pooledvariables[type] = new/list()
|
||||
var/list/exclude = global.exclude + args
|
||||
|
||||
for(var/key in vars)
|
||||
if(key in exclude)
|
||||
continue
|
||||
if(islist(vars[key]))
|
||||
pooledvariables[type][key] = list()
|
||||
else
|
||||
pooledvariables[type][key] = initial(vars[key])
|
||||
|
||||
/datum/proc/ResetVars()
|
||||
if(!pooledvariables[type])
|
||||
createVariables(args)
|
||||
|
||||
for(var/key in pooledvariables[type])
|
||||
if (islist(pooledvariables[type][key]))
|
||||
vars[key] = list()
|
||||
else
|
||||
vars[key] = pooledvariables[type][key]
|
||||
|
||||
/atom/movable/ResetVars()
|
||||
..()
|
||||
loc = null
|
||||
contents = initial(contents) //something is really wrong if this object still has stuff in it by this point
|
||||
|
||||
/image/ResetVars()
|
||||
..()
|
||||
loc = null
|
||||
|
||||
/proc/returnToPool(const/datum/D)
|
||||
ASSERT(D)
|
||||
|
||||
if(istype(D, /atom/movable) && length(GlobalPool[D.type]) > MAINTAINING_OBJECT_POOL_COUNT)
|
||||
#ifdef DEBUG_DATUM_POOL
|
||||
to_chat(world, text("DEBUG_DATUM_POOL: returnToPool([]) exceeds [] discarding...", D.type, MAINTAINING_OBJECT_POOL_COUNT))
|
||||
#endif
|
||||
|
||||
qdel(D)
|
||||
return
|
||||
|
||||
if(isnull(GlobalPool[D.type]))
|
||||
GlobalPool[D.type] = list()
|
||||
|
||||
D.Destroy()
|
||||
D.ResetVars()
|
||||
|
||||
#ifdef DEBUG_DATUM_POOL
|
||||
if(D in GlobalPool[D.type])
|
||||
to_chat(world, text("returnToPool has been called twice for the same datum of type [] time to panic.", D.type))
|
||||
#endif
|
||||
|
||||
GlobalPool[D.type] |= D
|
||||
|
||||
#ifdef DEBUG_DATUM_POOL
|
||||
to_chat(world, text("DEBUG_DATUM_POOL: returnToPool([]) [] left.", D.type, length(GlobalPool[D.type])))
|
||||
#endif
|
||||
|
||||
#undef MAINTAINING_OBJECT_POOL_COUNT
|
||||
@@ -1,127 +0,0 @@
|
||||
//ASTEROID FLOORS
|
||||
/turf/open/floor/plasteel/asteroid/warning
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "asteroid_warn"
|
||||
/turf/open/floor/plasteel/asteroid/warning/side
|
||||
icon_state = "asteroid_warn_side"
|
||||
/turf/open/floor/plasteel/asteroid/warning/corner
|
||||
icon_state = "asteroid_warn_corner"
|
||||
/turf/open/floor/plasteel/asteroid/warning/end
|
||||
icon_state = "asteroid_warn_end"
|
||||
|
||||
/turf/open/floor/plasteel/airless/asteroid/warning
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "asteroid_warn"
|
||||
/turf/open/floor/plasteel/airless/asteroid/warning/side
|
||||
icon_state = "asteroid_warn_side"
|
||||
/turf/open/floor/plasteel/airless/asteroid/warning/corner
|
||||
icon_state = "asteroid_warn_corner"
|
||||
/turf/open/floor/plasteel/airless/asteroid/warning/end
|
||||
icon_state = "asteroid_warn_end"
|
||||
|
||||
/turf/open/floor/plating/astplate/warning
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "astplate_warn"
|
||||
/turf/open/floor/plating/astplate/warning/corner
|
||||
icon_state = "astplate_warn_corner"
|
||||
/turf/open/floor/plating/astplate/warning/side
|
||||
icon_state = "astplate_warn_side"
|
||||
/turf/open/floor/plating/astplate/warning/end
|
||||
icon_state = "astplate_warn_end"
|
||||
|
||||
/turf/open/floor/plating/airless/astplate/warning
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "astplate_warn"
|
||||
/turf/open/floor/plating/airless/astplate/warning/corner
|
||||
icon_state = "astplate_warn_corner"
|
||||
/turf/open/floor/plating/airless/astplate/warning/side
|
||||
icon_state = "astplate_warn_side"
|
||||
/turf/open/floor/plating/airless/astplate/warning/end
|
||||
icon_state = "astplate_warn_end"
|
||||
|
||||
|
||||
//PLASTEEL
|
||||
/turf/open/floor/plasteel/warning
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "plasteel_warn"
|
||||
/turf/open/floor/plasteel/warning/corner
|
||||
icon_state = "plasteel_warn_corner"
|
||||
/turf/open/floor/plasteel/warning/side
|
||||
icon_state = "plasteel_warn_side"
|
||||
/turf/open/floor/plasteel/warning/end
|
||||
icon_state = "plasteel_warn_end"
|
||||
|
||||
/turf/open/floor/plasteel/airless/warning
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "plasteel_warn"
|
||||
/turf/open/floor/plasteel/airless/warning/corner
|
||||
icon_state = "plasteel_warn_corner"
|
||||
/turf/open/floor/plasteel/airless/warning/side
|
||||
icon_state = "plasteel_warn_side"
|
||||
/turf/open/floor/plasteel/airless/warning/end
|
||||
icon_state = "plasteel_warn_end"
|
||||
|
||||
//PLASTEEL WHITE
|
||||
/turf/open/floor/plasteel/warnwhite
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "white_warn"
|
||||
/turf/open/floor/plasteel/warnwhite/corner
|
||||
icon_state = "white_warn_corner"
|
||||
/turf/open/floor/plasteel/warnwhite/side
|
||||
icon_state = "white_warn_side"
|
||||
/turf/open/floor/plasteel/warnwhite/end
|
||||
icon_state = "white_warn_end"
|
||||
|
||||
/turf/open/floor/plasteel/airless/warnwhite
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "white_warn"
|
||||
/turf/open/floor/plasteel/airless/warnwhite/corner
|
||||
icon_state = "white_warn_corner"
|
||||
/turf/open/floor/plasteel/airless/warnwhite/side
|
||||
icon_state = "white_warn_side"
|
||||
/turf/open/floor/plasteel/airless/warnwhite/end
|
||||
icon_state = "white_warn_end"
|
||||
|
||||
|
||||
//PLASTEEL BLACK
|
||||
/turf/open/floor/plasteel/darkwarning
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "black_warn"
|
||||
/turf/open/floor/plasteel/darkwarning/corner
|
||||
icon_state = "black_warn_corner"
|
||||
/turf/open/floor/plasteel/darkwarning/side
|
||||
icon_state = "black_warn_side"
|
||||
/turf/open/floor/plasteel/darkwarning/end
|
||||
icon_state = "black_warn_end"
|
||||
|
||||
/turf/open/floor/plasteel/airless/darkwarning
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "black_warn"
|
||||
/turf/open/floor/plasteel/airless/darkwarning/corner
|
||||
icon_state = "black_warn_corner"
|
||||
/turf/open/floor/plasteel/airless/darkwarning/side
|
||||
icon_state = "black_warn_side"
|
||||
/turf/open/floor/plasteel/airless/darkwarning/end
|
||||
icon_state = "black_warn_end"
|
||||
|
||||
|
||||
//PLATING
|
||||
/turf/open/floor/plating/warnplate
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "plating_warn"
|
||||
/turf/open/floor/plating/warnplate/corner
|
||||
icon_state = "plating_warn_corner"
|
||||
/turf/open/floor/plating/warnplate/side
|
||||
icon_state = "plating_warn_side"
|
||||
/turf/open/floor/plating/warnplate/end
|
||||
icon_state = "plating_warn_end"
|
||||
|
||||
/turf/open/floor/plating/airless/warnplate
|
||||
icon = 'icons/turf/floors/warning.dmi'
|
||||
icon_state = "plating_warn"
|
||||
/turf/open/floor/plating/airless/warnplate/corner
|
||||
icon_state = "plating_warn_corner"
|
||||
/turf/open/floor/plating/airless/warnplate/side
|
||||
icon_state = "plating_warn_side"
|
||||
/turf/open/floor/plating/airless/warnplate/end
|
||||
icon_state = "plating_warn_end"
|
||||
@@ -1,189 +0,0 @@
|
||||
/turf/closed/wall/mineral
|
||||
name = "mineral wall"
|
||||
desc = "This shouldn't exist"
|
||||
icon_state = ""
|
||||
var/last_event = 0
|
||||
var/active = null
|
||||
canSmoothWith = null
|
||||
smooth = SMOOTH_TRUE
|
||||
|
||||
/turf/closed/wall/mineral/gold
|
||||
name = "gold wall"
|
||||
desc = "A wall with gold plating. Swag!"
|
||||
icon = 'icons/turf/walls/gold_wall.dmi'
|
||||
icon_state = "gold"
|
||||
walltype = "gold"
|
||||
mineral = "gold"
|
||||
sheet_type = /obj/item/stack/sheet/mineral/gold
|
||||
//var/electro = 1
|
||||
//var/shocked = null
|
||||
explosion_block = 0 //gold is a soft metal you dingus.
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/gold, /obj/structure/falsewall/gold)
|
||||
|
||||
/turf/closed/wall/mineral/silver
|
||||
name = "silver wall"
|
||||
desc = "A wall with silver plating. Shiny!"
|
||||
icon = 'icons/turf/walls/silver_wall.dmi'
|
||||
icon_state = "silver"
|
||||
walltype = "silver"
|
||||
mineral = "silver"
|
||||
sheet_type = /obj/item/stack/sheet/mineral/silver
|
||||
//var/electro = 0.75
|
||||
//var/shocked = null
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/silver, /obj/structure/falsewall/silver)
|
||||
|
||||
/turf/closed/wall/mineral/diamond
|
||||
name = "diamond wall"
|
||||
desc = "A wall with diamond plating. You monster."
|
||||
icon = 'icons/turf/walls/diamond_wall.dmi'
|
||||
icon_state = "diamond"
|
||||
walltype = "diamond"
|
||||
mineral = "diamond"
|
||||
sheet_type = /obj/item/stack/sheet/mineral/diamond
|
||||
slicing_duration = 200 //diamond wall takes twice as much time to slice
|
||||
explosion_block = 3
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/diamond, /obj/structure/falsewall/diamond)
|
||||
|
||||
/turf/closed/wall/mineral/diamond/thermitemelt(mob/user)
|
||||
return
|
||||
|
||||
/turf/closed/wall/mineral/clown
|
||||
name = "bananium wall"
|
||||
desc = "A wall with bananium plating. Honk!"
|
||||
icon = 'icons/turf/walls/bananium_wall.dmi'
|
||||
icon_state = "bananium"
|
||||
walltype = "bananium"
|
||||
mineral = "bananium"
|
||||
sheet_type = /obj/item/stack/sheet/mineral/bananium
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/clown, /obj/structure/falsewall/clown)
|
||||
|
||||
/turf/closed/wall/mineral/sandstone
|
||||
name = "sandstone wall"
|
||||
desc = "A wall with sandstone plating. Rough."
|
||||
icon = 'icons/turf/walls/sandstone_wall.dmi'
|
||||
icon_state = "sandstone"
|
||||
walltype = "sandstone"
|
||||
mineral = "sandstone"
|
||||
sheet_type = /obj/item/stack/sheet/mineral/sandstone
|
||||
explosion_block = 0
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/sandstone, /obj/structure/falsewall/sandstone)
|
||||
|
||||
/turf/closed/wall/mineral/uranium
|
||||
name = "uranium wall"
|
||||
desc = "A wall with uranium plating. This is probably a bad idea."
|
||||
icon = 'icons/turf/walls/uranium_wall.dmi'
|
||||
icon_state = "uranium"
|
||||
walltype = "uranium"
|
||||
mineral = "uranium"
|
||||
sheet_type = /obj/item/stack/sheet/mineral/uranium
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/uranium, /obj/structure/falsewall/uranium)
|
||||
|
||||
/turf/closed/wall/mineral/uranium/proc/radiate()
|
||||
if(!active)
|
||||
if(world.time > last_event+15)
|
||||
active = 1
|
||||
radiation_pulse(get_turf(src), 3, 3, 4, 0)
|
||||
for(var/turf/closed/wall/mineral/uranium/T in orange(1,src))
|
||||
T.radiate()
|
||||
last_event = world.time
|
||||
active = null
|
||||
return
|
||||
return
|
||||
|
||||
/turf/closed/wall/mineral/uranium/attack_hand(mob/user)
|
||||
radiate()
|
||||
..()
|
||||
|
||||
/turf/closed/wall/mineral/uranium/attackby(obj/item/weapon/W, mob/user, params)
|
||||
radiate()
|
||||
..()
|
||||
|
||||
/turf/closed/wall/mineral/uranium/Bumped(AM as mob|obj)
|
||||
radiate()
|
||||
..()
|
||||
|
||||
/turf/closed/wall/mineral/plasma
|
||||
name = "plasma wall"
|
||||
desc = "A wall with plasma plating. This is definitely a bad idea."
|
||||
icon = 'icons/turf/walls/plasma_wall.dmi'
|
||||
icon_state = "plasma"
|
||||
walltype = "plasma"
|
||||
mineral = "plasma"
|
||||
sheet_type = /obj/item/stack/sheet/mineral/plasma
|
||||
thermal_conductivity = 0.04
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/plasma, /obj/structure/falsewall/plasma)
|
||||
|
||||
/turf/closed/wall/mineral/plasma/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite
|
||||
message_admins("Plasma wall ignited by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Plasma wall ignited by [key_name(user)] in ([x],[y],[z])")
|
||||
ignite(W.is_hot())
|
||||
return
|
||||
..()
|
||||
|
||||
/turf/closed/wall/mineral/plasma/proc/PlasmaBurn(temperature)
|
||||
new /obj/structure/girder(src)
|
||||
src.ChangeTurf(/turf/open/floor/plasteel)
|
||||
var/turf/open/T = src
|
||||
T.atmos_spawn_air("plasma=400;TEMP=1000")
|
||||
|
||||
/turf/closed/wall/mineral/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)//Doesn't fucking work because walls don't interact with air :(
|
||||
if(exposed_temperature > 300)
|
||||
PlasmaBurn(exposed_temperature)
|
||||
|
||||
/turf/closed/wall/mineral/plasma/proc/ignite(exposed_temperature)
|
||||
if(exposed_temperature > 300)
|
||||
PlasmaBurn(exposed_temperature)
|
||||
|
||||
/turf/closed/wall/mineral/plasma/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(istype(Proj,/obj/item/projectile/beam))
|
||||
PlasmaBurn(2500)
|
||||
else if(istype(Proj,/obj/item/projectile/ion))
|
||||
PlasmaBurn(500)
|
||||
..()
|
||||
|
||||
|
||||
/turf/closed/wall/mineral/wood
|
||||
name = "wooden wall"
|
||||
desc = "A wall with wooden plating. Stiff."
|
||||
icon = 'icons/turf/walls/wood_wall.dmi'
|
||||
icon_state = "wood"
|
||||
walltype = "wood"
|
||||
mineral = "wood"
|
||||
sheet_type = /obj/item/stack/sheet/mineral/wood
|
||||
hardness = 70
|
||||
explosion_block = 0
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/wood, /obj/structure/falsewall/wood)
|
||||
|
||||
/turf/closed/wall/mineral/iron
|
||||
name = "rough metal wall"
|
||||
desc = "A wall with rough metal plating."
|
||||
icon = 'icons/turf/walls/iron_wall.dmi'
|
||||
icon_state = "iron"
|
||||
walltype = "iron"
|
||||
mineral = "rods"
|
||||
sheet_type = /obj/item/stack/rods
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/iron, /obj/structure/falsewall/iron)
|
||||
|
||||
/turf/closed/wall/mineral/snow
|
||||
name = "packed snow wall"
|
||||
desc = "A wall made of densely packed snow blocks."
|
||||
icon = 'icons/turf/walls/snow_wall.dmi'
|
||||
icon_state = "snow"
|
||||
walltype = "snow"
|
||||
mineral = "snow"
|
||||
hardness = 80
|
||||
sheet_type = /obj/item/stack/sheet/mineral/snow
|
||||
canSmoothWith = null
|
||||
|
||||
/turf/closed/wall/mineral/abductor
|
||||
name = "alien wall"
|
||||
desc = "A wall with alien alloy plating."
|
||||
icon = 'icons/turf/walls/abductor_wall.dmi'
|
||||
icon_state = "abductor"
|
||||
walltype = "abductor"
|
||||
mineral = "abductor"
|
||||
sheet_type = /obj/item/stack/sheet/mineral/abductor
|
||||
slicing_duration = 200 //alien wall takes twice as much time to slice
|
||||
explosion_block = 3
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/abductor, /obj/structure/falsewall/abductor)
|
||||
@@ -1,196 +0,0 @@
|
||||
/turf/closed/wall/mineral/cult
|
||||
name = "runed metal wall"
|
||||
desc = "A cold metal wall engraved with indecipherable symbols. Studying them causes your head to pound."
|
||||
icon = 'icons/turf/walls/cult_wall.dmi'
|
||||
icon_state = "cult"
|
||||
walltype = "cult"
|
||||
builtin_sheet = null
|
||||
canSmoothWith = null
|
||||
|
||||
/turf/closed/wall/mineral/cult/New()
|
||||
PoolOrNew(/obj/effect/overlay/temp/cult/turf, src)
|
||||
..()
|
||||
|
||||
/turf/closed/wall/mineral/cult/break_wall()
|
||||
new/obj/item/stack/sheet/runed_metal(get_turf(src), 1)
|
||||
return (new /obj/structure/girder/cult(src))
|
||||
|
||||
/turf/closed/wall/mineral/cult/devastate_wall()
|
||||
new/obj/item/stack/sheet/runed_metal(get_turf(src), 1)
|
||||
|
||||
/turf/closed/wall/mineral/cult/narsie_act()
|
||||
return
|
||||
|
||||
/turf/closed/wall/mineral/cult/ratvar_act()
|
||||
..()
|
||||
if(istype(src, /turf/closed/wall/mineral/cult)) //if we haven't changed type
|
||||
var/previouscolor = color
|
||||
color = "#FAE48C"
|
||||
animate(src, color = previouscolor, time = 8)
|
||||
|
||||
/turf/closed/wall/mineral/cult/artificer
|
||||
name = "runed stone wall"
|
||||
desc = "A cold stone wall engraved with indecipherable symbols. Studying them causes your head to pound."
|
||||
|
||||
/turf/closed/wall/mineral/cult/artificer/break_wall()
|
||||
PoolOrNew(/obj/effect/overlay/temp/cult/turf, get_turf(src))
|
||||
return null //excuse me we want no runed metal here
|
||||
|
||||
/turf/closed/wall/mineral/cult/artificer/devastate_wall()
|
||||
PoolOrNew(/obj/effect/overlay/temp/cult/turf, get_turf(src))
|
||||
|
||||
//Clockwork wall: Causes nearby tinkerer's caches to generate components.
|
||||
/turf/closed/wall/clockwork
|
||||
name = "clockwork wall"
|
||||
desc = "A huge chunk of warm metal. The clanging of machinery emanates from within."
|
||||
icon = 'icons/turf/walls/clockwork_wall.dmi'
|
||||
icon_state = "clockwork_wall"
|
||||
canSmoothWith = list(/turf/closed/wall/clockwork)
|
||||
smooth = SMOOTH_MORE
|
||||
explosion_block = 2
|
||||
|
||||
/turf/closed/wall/clockwork/New()
|
||||
..()
|
||||
PoolOrNew(/obj/effect/overlay/temp/ratvar/wall, src)
|
||||
PoolOrNew(/obj/effect/overlay/temp/ratvar/beam, src)
|
||||
clockwork_construction_value += 5
|
||||
|
||||
/turf/closed/wall/clockwork/Destroy()
|
||||
clockwork_construction_value -= 5
|
||||
..()
|
||||
|
||||
/turf/closed/wall/clockwork/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = I
|
||||
if(!WT.isOn())
|
||||
return 0
|
||||
user.visible_message("<span class='notice'>[user] begins slowly breaking down [src]...</span>", "<span class='notice'>You begin painstakingly destroying [src]...</span>")
|
||||
if(!do_after(user, 120 / WT.toolspeed, target = src))
|
||||
return 0
|
||||
if(!WT.remove_fuel(1, user))
|
||||
return 0
|
||||
user.visible_message("<span class='notice'>[user] breaks apart [src]!</span>", "<span class='notice'>You break apart [src]!</span>")
|
||||
dismantle_wall()
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/turf/closed/wall/clockwork/ratvar_act()
|
||||
return 0
|
||||
|
||||
/turf/closed/wall/clockwork/narsie_act()
|
||||
..()
|
||||
if(istype(src, /turf/closed/wall/clockwork)) //if we haven't changed type
|
||||
var/previouscolor = color
|
||||
color = "#960000"
|
||||
animate(src, color = previouscolor, time = 8)
|
||||
|
||||
/turf/closed/wall/clockwork/dismantle_wall(devastated=0, explode=0)
|
||||
if(devastated)
|
||||
devastate_wall()
|
||||
ChangeTurf(/turf/open/floor/plating)
|
||||
else
|
||||
playsound(src, 'sound/items/Welder.ogg', 100, 1)
|
||||
var/newgirder = break_wall()
|
||||
if(newgirder) //maybe we want a gear!
|
||||
transfer_fingerprints_to(newgirder)
|
||||
ChangeTurf(/turf/open/floor/clockwork)
|
||||
|
||||
for(var/obj/O in src) //Eject contents!
|
||||
if(istype(O,/obj/structure/sign/poster))
|
||||
var/obj/structure/sign/poster/P = O
|
||||
P.roll_and_drop(src)
|
||||
else
|
||||
O.loc = src
|
||||
|
||||
/turf/closed/wall/clockwork/break_wall()
|
||||
return new/obj/structure/clockwork/wall_gear(src)
|
||||
|
||||
/turf/closed/wall/clockwork/devastate_wall()
|
||||
new/obj/item/clockwork/alloy_shards(src)
|
||||
|
||||
|
||||
/turf/closed/wall/vault
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
icon_state = "rockvault"
|
||||
|
||||
/turf/closed/wall/ice
|
||||
icon = 'icons/turf/walls/icedmetal_wall.dmi'
|
||||
icon_state = "iced"
|
||||
desc = "A wall covered in a thick sheet of ice."
|
||||
walltype = "iced"
|
||||
canSmoothWith = null
|
||||
hardness = 35
|
||||
slicing_duration = 150 //welding through the ice+metal
|
||||
|
||||
/turf/closed/wall/rust
|
||||
name = "rusted wall"
|
||||
desc = "A rusted metal wall."
|
||||
icon = 'icons/turf/walls/rusty_wall.dmi'
|
||||
icon_state = "arust"
|
||||
walltype = "arust"
|
||||
hardness = 45
|
||||
|
||||
/turf/closed/wall/r_wall/rust
|
||||
name = "rusted reinforced wall"
|
||||
desc = "A huge chunk of rusted reinforced metal."
|
||||
icon = 'icons/turf/walls/rusty_reinforced_wall.dmi'
|
||||
icon_state = "rrust"
|
||||
walltype = "rrust"
|
||||
hardness = 15
|
||||
|
||||
/turf/closed/wall/shuttle
|
||||
name = "wall"
|
||||
icon = 'icons/turf/shuttle.dmi'
|
||||
icon_state = "wall"
|
||||
walltype = "shuttle"
|
||||
smooth = SMOOTH_FALSE
|
||||
|
||||
/turf/closed/wall/shuttle/proc/update_icon()
|
||||
..()
|
||||
|
||||
/turf/closed/wall/shuttle/smooth
|
||||
name = "wall"
|
||||
icon = 'icons/turf/walls/shuttle_wall.dmi'
|
||||
icon_state = "shuttle"
|
||||
walltype = "shuttle"
|
||||
smooth = SMOOTH_MORE|SMOOTH_DIAGONAL
|
||||
canSmoothWith = list(/turf/closed/wall/shuttle/smooth, /obj/structure/window/shuttle, /obj/structure/shuttle/engine)
|
||||
|
||||
/turf/closed/wall/shuttle/smooth/nodiagonal
|
||||
smooth = SMOOTH_MORE
|
||||
icon_state = "shuttle_nd"
|
||||
|
||||
/turf/closed/wall/shuttle/smooth/overspace
|
||||
icon_state = "overspace"
|
||||
fixed_underlay = list("space"=1)
|
||||
|
||||
//sub-type to be used for interior shuttle walls
|
||||
//won't get an underlay of the destination turf on shuttle move
|
||||
/turf/closed/wall/shuttle/interior/copyTurf(turf/T)
|
||||
if(T.type != type)
|
||||
T.ChangeTurf(type)
|
||||
if(underlays.len)
|
||||
T.underlays = underlays
|
||||
if(T.icon_state != icon_state)
|
||||
T.icon_state = icon_state
|
||||
if(T.icon != icon)
|
||||
T.icon = icon
|
||||
if(T.color != color)
|
||||
T.color = color
|
||||
if(T.dir != dir)
|
||||
T.setDir(dir)
|
||||
T.transform = transform
|
||||
return T
|
||||
|
||||
/turf/closed/wall/shuttle/copyTurf(turf/T)
|
||||
. = ..()
|
||||
T.transform = transform
|
||||
|
||||
|
||||
//why don't shuttle walls habe smoothwall? now i gotta do rotation the dirty way <- DOUBLE GOOFBALL FOR NOT CALLING PARENT
|
||||
/turf/closed/wall/shuttle/shuttleRotate(rotation)
|
||||
if(smooth)
|
||||
return ..()
|
||||
var/matrix/M = transform
|
||||
M.Turn(rotation)
|
||||
transform = M
|
||||
@@ -1,228 +0,0 @@
|
||||
/turf/closed/wall/r_wall
|
||||
name = "reinforced wall"
|
||||
desc = "A huge chunk of reinforced metal used to separate rooms."
|
||||
icon = 'icons/turf/walls/reinforced_wall.dmi'
|
||||
icon_state = "r_wall"
|
||||
opacity = 1
|
||||
density = 1
|
||||
|
||||
walltype = "rwall"
|
||||
|
||||
var/d_state = 0
|
||||
hardness = 10
|
||||
sheet_type = /obj/item/stack/sheet/plasteel
|
||||
explosion_block = 2
|
||||
|
||||
/turf/closed/wall/r_wall/break_wall()
|
||||
builtin_sheet.loc = src
|
||||
return (new /obj/structure/girder/reinforced(src))
|
||||
|
||||
/turf/closed/wall/r_wall/devastate_wall()
|
||||
builtin_sheet.loc = src
|
||||
new /obj/item/stack/sheet/metal(src, 2)
|
||||
|
||||
/turf/closed/wall/r_wall/attack_animal(mob/living/simple_animal/M)
|
||||
M.changeNext_move(CLICK_CD_MELEE)
|
||||
M.do_attack_animation(src)
|
||||
if(M.environment_smash == 3)
|
||||
dismantle_wall(1)
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1)
|
||||
M << "<span class='notice'>You smash through the wall.</span>"
|
||||
else
|
||||
M << "<span class='warning'>This wall is far too strong for you to destroy.</span>"
|
||||
|
||||
/turf/closed/wall/r_wall/try_destroy(obj/item/weapon/W, mob/user, turf/T)
|
||||
if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer))
|
||||
var/obj/item/weapon/pickaxe/drill/jackhammer/D = W
|
||||
user << "<span class='notice'>You begin to smash though the [name]...</span>"
|
||||
if(do_after(user, 50, target = src))
|
||||
if( !istype(src, /turf/closed/wall/r_wall) || !user || !W || !T )
|
||||
return 1
|
||||
if( user.loc == T && user.get_active_hand() == W )
|
||||
D.playDigSound()
|
||||
visible_message("<span class='warning'>[user] smashes through the [name] with the [D.name]!</span>", "<span class='italics'>You hear the grinding of metal.</span>")
|
||||
dismantle_wall()
|
||||
return 1
|
||||
else if(istype(W, /obj/item/stack/sheet/metal) && d_state)
|
||||
var/obj/item/stack/sheet/metal/MS = W
|
||||
if (MS.get_amount() < 1)
|
||||
user << "<span class='warning'>You need one sheet of metal to repair the wall!</span>"
|
||||
return 1
|
||||
user << "<span class='notice'>You begin patching-up the wall with \a [MS]...</span>"
|
||||
if (do_after(user, max(20*d_state,100), target = src))//time taken to repair is proportional to the damage! (max 10 seconds)
|
||||
if(loc == null || MS.get_amount() < 1)
|
||||
return 1
|
||||
MS.use(1)
|
||||
src.d_state = 0
|
||||
src.icon_state = "r_wall"
|
||||
queue_smooth_neighbors(src)
|
||||
user << "<span class='notice'>You repair the last of the damage.</span>"
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/turf/closed/wall/r_wall/try_decon(obj/item/weapon/W, mob/user, turf/T)
|
||||
//DECONSTRUCTION
|
||||
switch(d_state)
|
||||
if(0)
|
||||
if (istype(W, /obj/item/weapon/wirecutters))
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
src.d_state = 1
|
||||
update_icon()
|
||||
user << "<span class='notice'>You cut the outer grille.</span>"
|
||||
return 1
|
||||
|
||||
if(1)
|
||||
if (istype(W, /obj/item/weapon/screwdriver))
|
||||
user << "<span class='notice'>You begin removing the support lines...</span>"
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
|
||||
if(do_after(user, 40, target = src))
|
||||
if( !istype(src, /turf/closed/wall/r_wall) || !user || !W || !T )
|
||||
return 1
|
||||
|
||||
if( d_state == 1 && user.loc == T && user.get_active_hand() == W )
|
||||
src.d_state = 2
|
||||
update_icon()
|
||||
user << "<span class='notice'>You remove the support lines.</span>"
|
||||
return 1
|
||||
|
||||
//REPAIRING (replacing the outer grille for cosmetic damage)
|
||||
else if(istype(W, /obj/item/stack/sheet/metal))
|
||||
var/obj/item/stack/sheet/metal/O = W
|
||||
if (O.use(1))
|
||||
src.d_state = 0
|
||||
update_icon()
|
||||
src.icon_state = "r_wall"
|
||||
user << "<span class='notice'>You replace the outer grille.</span>"
|
||||
else
|
||||
user << "<span class='warning'>Report this to a coder: metal stack had less than one sheet in it when trying to repair wall</span>"
|
||||
return 1
|
||||
return 1
|
||||
|
||||
if(2)
|
||||
if( istype(W, /obj/item/weapon/weldingtool) )
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if( WT.remove_fuel(0,user) )
|
||||
|
||||
user << "<span class='notice'>You begin slicing through the metal cover...</span>"
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
|
||||
if(do_after(user, 60, target = src))
|
||||
if( !istype(src, /turf/closed/wall/r_wall) || !user || !WT || !WT.isOn() || !T )
|
||||
return 0
|
||||
|
||||
if( d_state == 2 && user.loc == T && user.get_active_hand() == WT )
|
||||
src.d_state = 3
|
||||
update_icon()
|
||||
user << "<span class='notice'>You press firmly on the cover, dislodging it.</span>"
|
||||
return 1
|
||||
|
||||
if( istype(W, /obj/item/weapon/gun/energy/plasmacutter) )
|
||||
|
||||
user << "<span class='notice'>You begin slicing through the metal cover...</span>"
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
|
||||
if(do_after(user, 60, target = src))
|
||||
if( !istype(src, /turf/closed/wall/r_wall) || !user || !W || !T )
|
||||
return 1
|
||||
|
||||
if( d_state == 2 && user.loc == T && user.get_active_hand() == W )
|
||||
src.d_state = 3
|
||||
update_icon()
|
||||
user << "<span class='notice'>You press firmly on the cover, dislodging it.</span>"
|
||||
return 1
|
||||
|
||||
if(3)
|
||||
if (istype(W, /obj/item/weapon/crowbar))
|
||||
|
||||
user << "<span class='notice'>You struggle to pry off the cover...</span>"
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
|
||||
if(do_after(user, 100, target = src))
|
||||
if( !istype(src, /turf/closed/wall/r_wall) || !user || !W || !T )
|
||||
return 1
|
||||
|
||||
if( d_state == 3 && user.loc == T && user.get_active_hand() == W )
|
||||
src.d_state = 4
|
||||
update_icon()
|
||||
user << "<span class='notice'>You pry off the cover.</span>"
|
||||
return 1
|
||||
|
||||
if(4)
|
||||
if (istype(W, /obj/item/weapon/wrench))
|
||||
|
||||
user << "<span class='notice'>You start loosening the anchoring bolts which secure the support rods to their frame...</span>"
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
|
||||
if(do_after(user, 40, target = src))
|
||||
if( !istype(src, /turf/closed/wall/r_wall) || !user || !W || !T )
|
||||
return 1
|
||||
|
||||
if( d_state == 4 && user.loc == T && user.get_active_hand() == W )
|
||||
src.d_state = 5
|
||||
update_icon()
|
||||
user << "<span class='notice'>You remove the bolts anchoring the support rods.</span>"
|
||||
return 1
|
||||
|
||||
if(5)
|
||||
if( istype(W, /obj/item/weapon/weldingtool) )
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if( WT.remove_fuel(0,user) )
|
||||
|
||||
user << "<span class='notice'>You begin slicing through the support rods...</span>"
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
|
||||
if(do_after(user, 100, target = src))
|
||||
if( !istype(src, /turf/closed/wall/r_wall) || !user || !WT || !WT.isOn() || !T )
|
||||
return 1
|
||||
|
||||
if( d_state == 5 && user.loc == T && user.get_active_hand() == WT )
|
||||
src.d_state = 6
|
||||
update_icon()
|
||||
user << "<span class='notice'>You slice through the support rods.</span>"
|
||||
return 1
|
||||
|
||||
if( istype(W, /obj/item/weapon/gun/energy/plasmacutter) )
|
||||
|
||||
user << "<span class='notice'>You begin slicing through the support rods...</span>"
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
|
||||
if(do_after(user, 70, target = src))
|
||||
if( !istype(src, /turf/closed/wall/r_wall) || !user || !W || !T )
|
||||
return 1
|
||||
|
||||
if( d_state == 5 && user.loc == T && user.get_active_hand() == W )
|
||||
src.d_state = 6
|
||||
update_icon()
|
||||
user << "<span class='notice'>You slice through the support rods.</span>"
|
||||
return 1
|
||||
|
||||
if(6)
|
||||
if( istype(W, /obj/item/weapon/crowbar) )
|
||||
|
||||
user << "<span class='notice'>You struggle to pry off the outer sheath...</span>"
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
|
||||
if(do_after(user, 100, target = src))
|
||||
if( !istype(src, /turf/closed/wall/r_wall) || !user || !W || !T )
|
||||
return 1
|
||||
|
||||
if( user.loc == T && user.get_active_hand() == W )
|
||||
user << "<span class='notice'>You pry off the outer sheath.</span>"
|
||||
dismantle_wall()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/turf/closed/wall/r_wall/proc/update_icon()
|
||||
if(d_state)
|
||||
icon_state = "r_wall-[d_state]"
|
||||
smooth = SMOOTH_FALSE
|
||||
clear_smooth_overlays()
|
||||
else
|
||||
smooth = SMOOTH_TRUE
|
||||
icon_state = ""
|
||||
|
||||
/turf/closed/wall/r_wall/singularity_pull(S, current_size)
|
||||
if(current_size >= STAGE_FIVE)
|
||||
if(prob(30))
|
||||
dismantle_wall()
|
||||
@@ -1,79 +0,0 @@
|
||||
/client/verb/looc(msg as text)
|
||||
set name = "LOOC"
|
||||
set desc = "Local OOC, seen only by those in view."
|
||||
set category = "OOC"
|
||||
|
||||
if(say_disabled) //This is here to try to identify lag problems
|
||||
usr << "\red Speech is currently admin-disabled."
|
||||
return
|
||||
|
||||
if(!mob) return
|
||||
if(IsGuestKey(key))
|
||||
src << "Guests may not use OOC."
|
||||
return
|
||||
|
||||
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
|
||||
if(!msg) return
|
||||
|
||||
if(!(prefs.toggles & CHAT_OOC))
|
||||
src << "\red You have OOC muted."
|
||||
return
|
||||
|
||||
if(!holder)
|
||||
if(!ooc_allowed)
|
||||
src << "\red OOC is globally muted"
|
||||
return
|
||||
if(!dooc_allowed && (mob.stat == DEAD))
|
||||
usr << "\red OOC for dead mobs has been turned off."
|
||||
return
|
||||
if(prefs.muted & MUTE_OOC)
|
||||
src << "\red You cannot use OOC (muted)."
|
||||
return
|
||||
if(handle_spam_prevention(msg,MUTE_OOC))
|
||||
return
|
||||
if(findtext(msg, "byond://"))
|
||||
src << "<B>Advertising other servers is not allowed.</B>"
|
||||
log_admin("[key_name(src)] has attempted to advertise in LOOC: [msg]")
|
||||
return
|
||||
|
||||
log_ooc("(LOCAL) [mob.name]/[key] : [msg]")
|
||||
|
||||
var/list/heard = get_hearers_in_view(7, get_top_level_mob(src.mob))
|
||||
for(var/mob/M in heard)
|
||||
if(!M.client)
|
||||
continue
|
||||
var/client/C = M.client
|
||||
if (C in admins)
|
||||
continue //they are handled after that
|
||||
|
||||
if (istype(M,/mob/dead/observer))
|
||||
continue //Also handled later.
|
||||
|
||||
if(C.prefs.toggles & CHAT_OOC)
|
||||
// var/display_name = src.key
|
||||
// if(holder)
|
||||
// if(holder.fakekey)
|
||||
// if(C.holder)
|
||||
// display_name = "[holder.fakekey]/([src.key])"
|
||||
// else
|
||||
// display_name = holder.fakekey
|
||||
C << "<font color='#6699CC'><span class='ooc'><span class='prefix'>LOOC:</span> <EM>[src.mob.name]:</EM> <span class='message'>[msg]</span></span></font>"
|
||||
|
||||
for(var/client/C in admins)
|
||||
if(C.prefs.toggles & CHAT_OOC)
|
||||
var/prefix = "(R)LOOC"
|
||||
if (C.mob in heard)
|
||||
prefix = "LOOC"
|
||||
C << "<font color='#6699CC'><span class='ooc'><span class='prefix'>[prefix]:</span> <EM>[src.key]/[src.mob.name]:</EM> <span class='message'>[msg]</span></span></font>"
|
||||
|
||||
for(var/mob/dead/observer/G in world)
|
||||
if(!G.client)
|
||||
continue
|
||||
var/client/C = G.client
|
||||
if (C in admins)
|
||||
continue //handled earlier.
|
||||
if(C.prefs.toggles & CHAT_OOC)
|
||||
var/prefix = "(G)LOOC"
|
||||
if (C.mob in heard)
|
||||
prefix = "LOOC"
|
||||
C << "<font color='#6699CC'><span class='ooc'><span class='prefix'>[prefix]:</span> <EM>[src.key]/[src.mob.name]:</EM> <span class='message'>[msg]</span></span></font>"
|
||||
@@ -1,176 +0,0 @@
|
||||
/client/verb/ooc(msg as text)
|
||||
set name = "OOC" //Gave this shit a shorter name so you only have to time out "ooc" rather than "ooc message" to use it --NeoFite
|
||||
set category = "OOC"
|
||||
|
||||
if(say_disabled) //This is here to try to identify lag problems
|
||||
usr << "<span class='danger'>Speech is currently admin-disabled.</span>"
|
||||
return
|
||||
|
||||
if(!mob)
|
||||
return
|
||||
if(IsGuestKey(key))
|
||||
src << "Guests may not use OOC."
|
||||
return
|
||||
|
||||
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
if(!(prefs.chat_toggles & CHAT_OOC))
|
||||
src << "<span class='danger'>You have OOC muted.</span>"
|
||||
return
|
||||
|
||||
if(!holder)
|
||||
if(!ooc_allowed)
|
||||
src << "<span class='danger'>OOC is globally muted.</span>"
|
||||
return
|
||||
if(!dooc_allowed && (mob.stat == DEAD))
|
||||
usr << "<span class='danger'>OOC for dead mobs has been turned off.</span>"
|
||||
return
|
||||
if(prefs.muted & MUTE_OOC)
|
||||
src << "<span class='danger'>You cannot use OOC (muted).</span>"
|
||||
return
|
||||
if(src.mob)
|
||||
if(jobban_isbanned(src.mob, "OOC"))
|
||||
src << "<span class='danger'>You have been banned from OOC.</span>"
|
||||
return
|
||||
if(handle_spam_prevention(msg,MUTE_OOC))
|
||||
return
|
||||
if(findtext(msg, "byond://"))
|
||||
src << "<B>Advertising other servers is not allowed.</B>"
|
||||
log_admin("[key_name(src)] has attempted to advertise in OOC: [msg]")
|
||||
message_admins("[key_name_admin(src)] has attempted to advertise in OOC: [msg]")
|
||||
return
|
||||
|
||||
var/raw_msg = msg
|
||||
|
||||
msg = emoji_parse(msg)
|
||||
|
||||
if((copytext(msg, 1, 2) in list(".",";",":","#")) || (findtext(lowertext(copytext(msg, 1, 5)), "say")))
|
||||
if(alert("Your message \"[raw_msg]\" looks like it was meant for in game communication, say it in OOC?", "Meant for OOC?", "No", "Yes") != "Yes")
|
||||
return
|
||||
|
||||
log_ooc("[mob.name]/[key] : [raw_msg]")
|
||||
|
||||
var/keyname = key
|
||||
if(prefs.unlock_content)
|
||||
if(prefs.toggles & MEMBER_PUBLIC)
|
||||
keyname = "<font color='[prefs.ooccolor ? prefs.ooccolor : normal_ooc_colour]'><img style='width:9px;height:9px;' class=icon src=\ref['icons/member_content.dmi'] iconstate=blag>[keyname]</font>"
|
||||
|
||||
for(var/client/C in clients)
|
||||
if(C.prefs.chat_toggles & CHAT_OOC)
|
||||
if(holder)
|
||||
if(!holder.fakekey || C.holder)
|
||||
if(check_rights_for(src, R_ADMIN))
|
||||
C << "<span class='adminooc'>[config.allow_admin_ooccolor && prefs.ooccolor ? "<font color=[prefs.ooccolor]>" :"" ]<span class='prefix'>OOC:</span> <EM>[keyname][holder.fakekey ? "/([holder.fakekey])" : ""]:</EM> <span class='message'>[msg]</span></span></font>"
|
||||
else
|
||||
C << "<span class='adminobserverooc'><span class='prefix'>OOC:</span> <EM>[keyname][holder.fakekey ? "/([holder.fakekey])" : ""]:</EM> <span class='message'>[msg]</span></span>"
|
||||
else
|
||||
C << "<font color='[normal_ooc_colour]'><span class='ooc'><span class='prefix'>OOC:</span> <EM>[holder.fakekey ? holder.fakekey : key]:</EM> <span class='message'>[msg]</span></span></font>"
|
||||
else if(!(key in C.prefs.ignoring))
|
||||
C << "<font color='[normal_ooc_colour]'><span class='ooc'><span class='prefix'>OOC:</span> <EM>[keyname]:</EM> <span class='message'>[msg]</span></span></font>"
|
||||
|
||||
/proc/toggle_ooc(toggle = null)
|
||||
if(toggle != null) //if we're specifically en/disabling ooc
|
||||
if(toggle != ooc_allowed)
|
||||
ooc_allowed = toggle
|
||||
else
|
||||
return
|
||||
else //otherwise just toggle it
|
||||
ooc_allowed = !ooc_allowed
|
||||
world << "<B>The OOC channel has been globally [ooc_allowed ? "enabled" : "disabled"].</B>"
|
||||
|
||||
var/global/normal_ooc_colour = OOC_COLOR
|
||||
|
||||
/client/proc/set_ooc(newColor as color)
|
||||
set name = "Set Player OOC Color"
|
||||
set desc = "Modifies player OOC Color"
|
||||
set category = "Fun"
|
||||
normal_ooc_colour = sanitize_ooccolor(newColor)
|
||||
|
||||
/client/proc/reset_ooc()
|
||||
set name = "Reset Player OOC Color"
|
||||
set desc = "Returns player OOC Color to default"
|
||||
set category = "Fun"
|
||||
normal_ooc_colour = OOC_COLOR
|
||||
|
||||
/client/verb/colorooc()
|
||||
set name = "Set Your OOC Color"
|
||||
set category = "Preferences"
|
||||
|
||||
if(!holder || check_rights_for(src, R_ADMIN))
|
||||
if(!is_content_unlocked())
|
||||
return
|
||||
|
||||
var/new_ooccolor = input(src, "Please select your OOC color.", "OOC color", prefs.ooccolor) as color|null
|
||||
if(new_ooccolor)
|
||||
prefs.ooccolor = sanitize_ooccolor(new_ooccolor)
|
||||
prefs.save_preferences()
|
||||
feedback_add_details("admin_verb","OC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
|
||||
/client/verb/resetcolorooc()
|
||||
set name = "Reset Your OOC Color"
|
||||
set desc = "Returns your OOC Color to default"
|
||||
set category = "Preferences"
|
||||
|
||||
if(!holder || check_rights_for(src, R_ADMIN))
|
||||
if(!is_content_unlocked())
|
||||
return
|
||||
|
||||
prefs.ooccolor = initial(prefs.ooccolor)
|
||||
prefs.save_preferences()
|
||||
|
||||
//Checks admin notice
|
||||
/client/verb/admin_notice()
|
||||
set name = "Adminnotice"
|
||||
set category = "Admin"
|
||||
set desc ="Check the admin notice if it has been set"
|
||||
|
||||
if(admin_notice)
|
||||
src << "<span class='boldnotice'>Admin Notice:</span>\n \t [admin_notice]"
|
||||
else
|
||||
src << "<span class='notice'>There are no admin notices at the moment.</span>"
|
||||
|
||||
/client/verb/motd()
|
||||
set name = "MOTD"
|
||||
set category = "OOC"
|
||||
set desc ="Check the Message of the Day"
|
||||
|
||||
if(join_motd)
|
||||
src << "<div class=\"motd\">[join_motd]</div>"
|
||||
else
|
||||
src << "<span class='notice'>The Message of the Day has not been set.</span>"
|
||||
|
||||
/client/proc/self_notes()
|
||||
set name = "View Admin Notes"
|
||||
set category = "OOC"
|
||||
set desc = "View the notes that admins have written about you"
|
||||
|
||||
if(!config.see_own_notes)
|
||||
usr << "<span class='notice'>Sorry, that function is not enabled on this server.</span>"
|
||||
return
|
||||
|
||||
show_note(usr, null, 1)
|
||||
|
||||
/client/proc/ignore_key(client)
|
||||
var/client/C = client
|
||||
if(C.key in prefs.ignoring)
|
||||
prefs.ignoring -= C.key
|
||||
else
|
||||
prefs.ignoring |= C.key
|
||||
src << "You are [(C.key in prefs.ignoring) ? "now" : "no longer"] ignoring [C.key] on the OOC channel."
|
||||
prefs.save_preferences()
|
||||
|
||||
/client/verb/select_ignore()
|
||||
set name = "Ignore"
|
||||
set category = "OOC"
|
||||
set desc ="Ignore a player's messages on the OOC channel"
|
||||
|
||||
var/selection = input("Please, select a player!", "Ignore", null, null) as null|anything in sortKey(clients)
|
||||
if(!selection)
|
||||
return
|
||||
if(selection == src)
|
||||
src << "You can't ignore yourself."
|
||||
return
|
||||
ignore_key(selection)
|
||||
@@ -1,179 +0,0 @@
|
||||
/mob/var/suiciding = 0
|
||||
|
||||
/mob/living/carbon/human/verb/suicide()
|
||||
set hidden = 1
|
||||
if(!canSuicide())
|
||||
return
|
||||
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
|
||||
if(!canSuicide())
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
suiciding = 1
|
||||
log_game("[key_name(src)] (job: [job ? "[job]" : "None"]) commited suicide at [get_area(src)].")
|
||||
message_admins("[key_name(src)] (job: [job ? "[job]" : "None"]) commited suicide at [get_area(src)].")
|
||||
var/obj/item/held_item = get_active_hand()
|
||||
if(held_item)
|
||||
var/damagetype = held_item.suicide_act(src)
|
||||
if(damagetype)
|
||||
if(damagetype & SHAME)
|
||||
adjustStaminaLoss(200)
|
||||
suiciding = 0
|
||||
return
|
||||
var/damage_mod = 0
|
||||
for(var/T in list(BRUTELOSS, FIRELOSS, TOXLOSS, OXYLOSS))
|
||||
damage_mod += (T & damagetype) ? 1 : 0
|
||||
damage_mod = max(1, damage_mod)
|
||||
|
||||
//Do 200 damage divided by the number of damage types applied.
|
||||
if(damagetype & BRUTELOSS)
|
||||
adjustBruteLoss(200/damage_mod)
|
||||
|
||||
if(damagetype & FIRELOSS)
|
||||
adjustFireLoss(200/damage_mod)
|
||||
|
||||
if(damagetype & TOXLOSS)
|
||||
adjustToxLoss(200/damage_mod)
|
||||
|
||||
if(damagetype & OXYLOSS)
|
||||
adjustOxyLoss(200/damage_mod)
|
||||
|
||||
//If something went wrong, just do normal oxyloss
|
||||
if(!(damagetype & (BRUTELOSS | FIRELOSS | TOXLOSS | OXYLOSS) ))
|
||||
adjustOxyLoss(max(200 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
|
||||
|
||||
death(0)
|
||||
return
|
||||
|
||||
var/suicide_message = pick("[src] is attempting to bite \his tongue off! It looks like \he's trying to commit suicide.", \
|
||||
"[src] is jamming \his thumbs into \his eye sockets! It looks like \he's trying to commit suicide.", \
|
||||
"[src] is twisting \his own neck! It looks like \he's trying to commit suicide.", \
|
||||
"[src] is holding \his breath! It looks like \he's trying to commit suicide.")
|
||||
|
||||
visible_message("<span class='danger'>[suicide_message]</span>", "<span class='userdanger'>[suicide_message]</span>")
|
||||
|
||||
adjustOxyLoss(max(200 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
|
||||
death(0)
|
||||
|
||||
/mob/living/carbon/brain/verb/suicide()
|
||||
set hidden = 1
|
||||
if(!canSuicide())
|
||||
return
|
||||
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
|
||||
if(!canSuicide())
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
suiciding = 1
|
||||
visible_message("<span class='danger'>[src]'s brain is growing dull and lifeless. It looks like it's lost the will to live.</span>", \
|
||||
"<span class='userdanger'>[src]'s brain is growing dull and lifeless. It looks like it's lost the will to live.</span>")
|
||||
spawn(50)
|
||||
death(0)
|
||||
|
||||
/mob/living/carbon/monkey/verb/suicide()
|
||||
set hidden = 1
|
||||
if(!canSuicide())
|
||||
return
|
||||
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
|
||||
if(!canSuicide())
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
suiciding = 1
|
||||
//instead of killing them instantly, just put them at -175 health and let 'em gasp for a while
|
||||
visible_message("<span class='danger'>[src] is attempting to bite \his tongue. It looks like \he's trying to commit suicide.</span>", \
|
||||
"<span class='userdanger'>[src] is attempting to bite \his tongue. It looks like \he's trying to commit suicide.</span>")
|
||||
adjustOxyLoss(max(200- getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
|
||||
death(0)
|
||||
|
||||
/mob/living/silicon/ai/verb/suicide()
|
||||
set hidden = 1
|
||||
if(!canSuicide())
|
||||
return
|
||||
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
|
||||
if(!canSuicide())
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
suiciding = 1
|
||||
visible_message("<span class='danger'>[src] is powering down. It looks like \he's trying to commit suicide.</span>", \
|
||||
"<span class='userdanger'>[src] is powering down. It looks like \he's trying to commit suicide.</span>")
|
||||
//put em at -175
|
||||
adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
|
||||
death(0)
|
||||
|
||||
/mob/living/silicon/robot/verb/suicide()
|
||||
set hidden = 1
|
||||
if(!canSuicide())
|
||||
return
|
||||
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
|
||||
if(!canSuicide())
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
suiciding = 1
|
||||
visible_message("<span class='danger'>[src] is powering down. It looks like \he's trying to commit suicide.</span>", \
|
||||
"<span class='userdanger'>[src] is powering down. It looks like \he's trying to commit suicide.</span>")
|
||||
//put em at -175
|
||||
adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
|
||||
death(0)
|
||||
|
||||
/mob/living/silicon/pai/verb/suicide()
|
||||
set category = "pAI Commands"
|
||||
set desc = "Kill yourself and become a ghost (You will receive a confirmation prompt)"
|
||||
set name = "pAI Suicide"
|
||||
var/answer = input("REALLY kill yourself? This action can't be undone.", "Suicide", "No") in list ("Yes", "No")
|
||||
if(answer == "Yes")
|
||||
card.removePersonality()
|
||||
var/turf/T = get_turf(src.loc)
|
||||
T.visible_message("<span class='notice'>[src] flashes a message across its screen, \"Wiping core files. Please acquire a new personality to continue using pAI device functions.\"</span>", "<span class='notice'>[src] bleeps electronically.</span>")
|
||||
death(0)
|
||||
else
|
||||
src << "Aborting suicide attempt."
|
||||
|
||||
/mob/living/carbon/alien/humanoid/verb/suicide()
|
||||
set hidden = 1
|
||||
if(!canSuicide())
|
||||
return
|
||||
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
|
||||
if(!canSuicide())
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
suiciding = 1
|
||||
visible_message("<span class='danger'>[src] is thrashing wildly! It looks like \he's trying to commit suicide.</span>", \
|
||||
"<span class='userdanger'>[src] is thrashing wildly! It looks like \he's trying to commit suicide.</span>", \
|
||||
"<span class='italics'>You hear thrashing.</span>")
|
||||
//put em at -175
|
||||
adjustOxyLoss(max(200 - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
|
||||
death(0)
|
||||
|
||||
/mob/living/simple_animal/verb/suicide()
|
||||
set hidden = 1
|
||||
if(!canSuicide())
|
||||
return
|
||||
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
|
||||
if(!canSuicide())
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
suiciding = 1
|
||||
visible_message("<span class='danger'>[src] begins to fall down. It looks like \he's lost the will to live.</span>", \
|
||||
"<span class='userdanger'>[src] begins to fall down. It looks like \he's lost the will to live.</span>")
|
||||
death(0)
|
||||
|
||||
|
||||
/mob/living/proc/canSuicide()
|
||||
if(stat == CONSCIOUS)
|
||||
if(mental_dominator)
|
||||
src << "<span class='warning'>This body's force of will is too strong! You can't break it enough to murder them.</span>"
|
||||
if(mind_control_holder)
|
||||
mind_control_holder << "<span class='userdanger'>Through tremendous force of will, you stop a suicide attempt!</span>"
|
||||
return 0
|
||||
return 1
|
||||
else if(stat == DEAD)
|
||||
src << "You're already dead!"
|
||||
else if(stat == UNCONSCIOUS)
|
||||
src << "You need to be conscious to suicide!"
|
||||
return
|
||||
|
||||
/mob/living/carbon/canSuicide()
|
||||
if(!..())
|
||||
return
|
||||
if(!canmove || restrained()) //just while I finish up the new 'fun' suiciding verb. This is to prevent metagaming via suicide
|
||||
src << "You can't commit suicide whilst restrained! ((You can type Ghost instead however.))"
|
||||
return
|
||||
return 1
|
||||
@@ -1,85 +0,0 @@
|
||||
/client/verb/who()
|
||||
set name = "Who"
|
||||
set category = "OOC"
|
||||
|
||||
var/msg = "<b>Current Players:</b>\n"
|
||||
|
||||
var/list/Lines = list()
|
||||
|
||||
if(holder)
|
||||
if (check_rights(R_ADMIN,0) && isobserver(src.mob))//If they have +ADMIN and are a ghost they can see players IC names and statuses.
|
||||
var/mob/dead/observer/G = src.mob
|
||||
if(!G.started_as_observer)//If you aghost to do this, KorPhaeron will deadmin you in your sleep.
|
||||
log_admin("[key_name(usr)] checked advanced who in-round")
|
||||
for(var/client/C in clients)
|
||||
var/entry = "\t[C.key]"
|
||||
if(C.holder && C.holder.fakekey)
|
||||
entry += " <i>(as [C.holder.fakekey])</i>"
|
||||
if (isnewplayer(C.mob))
|
||||
entry += " - <font color='darkgray'><b>In Lobby</b></font>"
|
||||
else
|
||||
entry += " - Playing as [C.mob.real_name]"
|
||||
switch(C.mob.stat)
|
||||
if(UNCONSCIOUS)
|
||||
entry += " - <font color='darkgray'><b>Unconscious</b></font>"
|
||||
if(DEAD)
|
||||
if(isobserver(C.mob))
|
||||
var/mob/dead/observer/O = C.mob
|
||||
if(O.started_as_observer)
|
||||
entry += " - <font color='gray'>Observing</font>"
|
||||
else
|
||||
entry += " - <font color='black'><b>DEAD</b></font>"
|
||||
else
|
||||
entry += " - <font color='black'><b>DEAD</b></font>"
|
||||
if(is_special_character(C.mob))
|
||||
entry += " - <b><font color='red'>Antagonist</font></b>"
|
||||
entry += " (<A HREF='?_src_=holder;adminmoreinfo=\ref[C.mob]'>?</A>)"
|
||||
Lines += entry
|
||||
else//If they don't have +ADMIN, only show hidden admins
|
||||
for(var/client/C in clients)
|
||||
var/entry = "\t[C.key]"
|
||||
if(C.holder && C.holder.fakekey)
|
||||
entry += " <i>(as [C.holder.fakekey])</i>"
|
||||
Lines += entry
|
||||
else
|
||||
for(var/client/C in clients)
|
||||
if(C.holder && C.holder.fakekey)
|
||||
Lines += C.holder.fakekey
|
||||
else
|
||||
Lines += C.key
|
||||
|
||||
for(var/line in sortList(Lines))
|
||||
msg += "[line]\n"
|
||||
|
||||
msg += "<b>Total Players: [length(Lines)]</b>"
|
||||
src << msg
|
||||
|
||||
/client/verb/adminwho()
|
||||
set category = "Admin"
|
||||
set name = "Adminwho"
|
||||
|
||||
var/msg = "<b>Current Admins:</b>\n"
|
||||
if(holder)
|
||||
for(var/client/C in admins)
|
||||
msg += "\t[C] is a [C.holder.rank]"
|
||||
|
||||
if(C.holder.fakekey)
|
||||
msg += " <i>(as [C.holder.fakekey])</i>"
|
||||
|
||||
if(isobserver(C.mob))
|
||||
msg += " - Observing"
|
||||
else if(istype(C.mob,/mob/new_player))
|
||||
msg += " - Lobby"
|
||||
else
|
||||
msg += " - Playing"
|
||||
|
||||
if(C.is_afk())
|
||||
msg += " (AFK)"
|
||||
msg += "\n"
|
||||
else
|
||||
for(var/client/C in admins)
|
||||
if(!C.holder.fakekey)
|
||||
msg += "\t[C] is a [C.holder.rank]\n"
|
||||
msg += "<span class='info'>Adminhelps are also sent to IRC. If no admins are available in game adminhelp anyways and an admin on IRC will see it and respond.</span>"
|
||||
src << msg
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
/world
|
||||
|
||||
hub = "Exadv1.spacestation13"
|
||||
#ifdef PUTONHUB
|
||||
hub_password = "kMZy3U5jJHSiBQjr"
|
||||
#else
|
||||
hub_password = "kMZy3U5jJHSiBQjr"
|
||||
#endif
|
||||
name = "Citadel Station 13"
|
||||
|
||||
/*
|
||||
This is for any host that would like their server to appear on the main SS13 hub.
|
||||
To use it, simply replace the password above with the password found below, and recompile, and it should work.
|
||||
If not, let us know on the main tgstation IRC channel of irc.rizon.net #tgstation13: we can help you there.
|
||||
|
||||
hub = "Exadv1.spacestation13"
|
||||
hub_password = "kMZy3U5jJHSiBQjr"
|
||||
name = "Space Station 13"
|
||||
|
||||
*/
|
||||
@@ -1,110 +0,0 @@
|
||||
//ban people from using custom names and appearances. that'll show 'em.
|
||||
|
||||
var/appearanceban_runonce //Updates legacy bans with new info
|
||||
var/appearance_keylist[0] //to store the keys
|
||||
|
||||
/proc/appearance_fullban(mob/M, reason)
|
||||
if (!M || !M.key) return
|
||||
appearance_keylist.Add(text("[M.ckey] ## [reason]"))
|
||||
appearance_savebanfile()
|
||||
|
||||
/proc/appearance_client_fullban(ckey)
|
||||
if (!ckey) return
|
||||
appearance_keylist.Add(text("[ckey]"))
|
||||
appearance_savebanfile()
|
||||
|
||||
//returns a reason if M is banned, returns 0 otherwise
|
||||
/proc/appearance_isbanned(mob/M)
|
||||
if(M)
|
||||
for(var/s in appearance_keylist)
|
||||
if(findtext(s, "[M.ckey]") == 1)
|
||||
var/startpos = findtext(s, "## ") + 3
|
||||
if(startpos && startpos < length(s))
|
||||
var/text = copytext(s, startpos, 0)
|
||||
if(text)
|
||||
return text
|
||||
return "Reason Unspecified"
|
||||
return 0
|
||||
|
||||
/*
|
||||
DEBUG
|
||||
/mob/verb/list_all_appearances()
|
||||
set name = "list all appearances"
|
||||
|
||||
for(var/s in appearance_keylist)
|
||||
world << s
|
||||
|
||||
/mob/verb/reload_appearances()
|
||||
set name = "reload appearances"
|
||||
|
||||
appearance_loadbanfile()
|
||||
*/
|
||||
|
||||
/proc/appearance_loadbanfile()
|
||||
if(config.ban_legacy_system)
|
||||
var/savefile/S=new("data/appearance_full.ban")
|
||||
S["keys[0]"] >> appearance_keylist
|
||||
log_admin("Loading appearance_rank")
|
||||
S["runonce"] >> appearanceban_runonce
|
||||
|
||||
if (!length(appearance_keylist))
|
||||
appearance_keylist=list()
|
||||
log_admin("appearance_keylist was empty")
|
||||
else
|
||||
if(!establish_db_connection())
|
||||
world.log << "Database connection failed. Reverting to the legacy ban system."
|
||||
diary << "Database connection failed. Reverting to the legacy ban system."
|
||||
config.ban_legacy_system = 1
|
||||
appearance_loadbanfile()
|
||||
return
|
||||
|
||||
//appearance bans
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT ckey FROM [format_table_name("ban")] WHERE bantype = 'APPEARANCE_PERMABAN' AND NOT unbanned = 1")
|
||||
query.Execute()
|
||||
|
||||
while(query.NextRow())
|
||||
var/ckey = query.item[1]
|
||||
|
||||
appearance_keylist.Add("[ckey]")
|
||||
|
||||
/proc/appearance_savebanfile()
|
||||
var/savefile/S=new("data/appearance_full.ban")
|
||||
S["keys[0]"] << appearance_keylist
|
||||
|
||||
/proc/appearance_unban(mob/M)
|
||||
appearance_remove("[M.ckey]")
|
||||
appearance_savebanfile()
|
||||
|
||||
|
||||
/proc/appearance_updatelegacybans()
|
||||
if(!appearanceban_runonce)
|
||||
log_admin("Updating appearancefile!")
|
||||
// Updates bans.. Or fixes them. Either way.
|
||||
for(var/T in appearance_keylist)
|
||||
if(!T)
|
||||
continue
|
||||
appearanceban_runonce++ //don't run this update again
|
||||
|
||||
|
||||
/proc/appearance_remove(X)
|
||||
for (var/i = 1; i <= length(appearance_keylist); i++)
|
||||
if( findtext(appearance_keylist[i], "[X]") )
|
||||
appearance_keylist.Remove(appearance_keylist[i])
|
||||
appearance_savebanfile()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/*
|
||||
/proc/DB_ban_isappearancebanned(var/playerckey)
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
return
|
||||
|
||||
var/sqlplayerckey = sanitizeSQL(ckey(playerckey))
|
||||
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT id FROM [format_table_name("ban")] WHERE CKEY = '[sqlplayerckey]' AND ((bantype = 'APPEARANCE_PERMABAN') OR (bantype = 'APPEARANCE_TEMPBAN' AND expiration_time > Now())) AND unbanned != 1")
|
||||
query.Execute()
|
||||
while(query.NextRow())
|
||||
return 1
|
||||
return 0
|
||||
*/
|
||||
@@ -1,217 +0,0 @@
|
||||
/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server)
|
||||
if(!dbcon.IsConnected())
|
||||
usr << "<span class='danger'>Failed to establish database connection.</span>"
|
||||
return
|
||||
if(!target_ckey)
|
||||
var/new_ckey = ckey(input(usr,"Who would you like to add a note for?","Enter a ckey",null) as text)
|
||||
if(!new_ckey)
|
||||
return
|
||||
new_ckey = sanitizeSQL(new_ckey)
|
||||
var/DBQuery/query_find_ckey = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
|
||||
if(!query_find_ckey.Execute())
|
||||
var/err = query_find_ckey.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
|
||||
return
|
||||
if(!query_find_ckey.NextRow())
|
||||
if(alert(usr, "[new_ckey] has not been seen before, are you sure you want to add them to the watchlist?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
|
||||
return
|
||||
target_ckey = new_ckey
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
if(!notetext)
|
||||
notetext = input(usr,"Write your Note","Add Note") as message
|
||||
if(!notetext)
|
||||
return
|
||||
notetext = sanitizeSQL(notetext)
|
||||
if(!timestamp)
|
||||
timestamp = SQLtime()
|
||||
if(!adminckey)
|
||||
adminckey = usr.ckey
|
||||
if(!adminckey)
|
||||
return
|
||||
var/admin_sql_ckey = sanitizeSQL(adminckey)
|
||||
if(!server)
|
||||
if (config && config.server_name)
|
||||
server = config.server_name
|
||||
server = sanitizeSQL(server)
|
||||
var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]')")
|
||||
if(!query_noteadd.Execute())
|
||||
var/err = query_noteadd.ErrorMsg()
|
||||
log_game("SQL ERROR adding new note to table. Error : \[[err]\]\n")
|
||||
return
|
||||
if(logged)
|
||||
log_admin("[key_name(usr)] has added a note to [target_ckey]: [notetext]")
|
||||
message_admins("[key_name_admin(usr)] has added a note to [target_ckey]:<br>[notetext]")
|
||||
show_note(target_ckey)
|
||||
|
||||
/proc/remove_note(note_id)
|
||||
var/ckey
|
||||
var/notetext
|
||||
var/adminckey
|
||||
if(!dbcon.IsConnected())
|
||||
usr << "<span class='danger'>Failed to establish database connection.</span>"
|
||||
return
|
||||
if(!note_id)
|
||||
return
|
||||
note_id = text2num(note_id)
|
||||
var/DBQuery/query_find_note_del = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]")
|
||||
if(!query_find_note_del.Execute())
|
||||
var/err = query_find_note_del.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey, notetext, adminckey from notes table. Error : \[[err]\]\n")
|
||||
return
|
||||
if(query_find_note_del.NextRow())
|
||||
ckey = query_find_note_del.item[1]
|
||||
notetext = query_find_note_del.item[2]
|
||||
adminckey = query_find_note_del.item[3]
|
||||
var/DBQuery/query_del_note = dbcon.NewQuery("DELETE FROM [format_table_name("notes")] WHERE id = [note_id]")
|
||||
if(!query_del_note.Execute())
|
||||
var/err = query_del_note.ErrorMsg()
|
||||
log_game("SQL ERROR removing note from table. Error : \[[err]\]\n")
|
||||
return
|
||||
log_admin("[key_name(usr)] has removed a note made by [adminckey] from [ckey]: [notetext]")
|
||||
message_admins("[key_name_admin(usr)] has removed a note made by [adminckey] from [ckey]:<br>[notetext]")
|
||||
show_note(ckey)
|
||||
|
||||
/proc/edit_note(note_id)
|
||||
if(!dbcon.IsConnected())
|
||||
usr << "<span class='danger'>Failed to establish database connection.</span>"
|
||||
return
|
||||
if(!note_id)
|
||||
return
|
||||
note_id = text2num(note_id)
|
||||
var/target_ckey
|
||||
var/sql_ckey = sanitizeSQL(usr.ckey)
|
||||
var/DBQuery/query_find_note_edit = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]")
|
||||
if(!query_find_note_edit.Execute())
|
||||
var/err = query_find_note_edit.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining notetext from notes table. Error : \[[err]\]\n")
|
||||
return
|
||||
if(query_find_note_edit.NextRow())
|
||||
target_ckey = query_find_note_edit.item[1]
|
||||
var/old_note = query_find_note_edit.item[2]
|
||||
var/adminckey = query_find_note_edit.item[3]
|
||||
var/new_note = input("Input new note", "New Note", "[old_note]") as message
|
||||
if(!new_note)
|
||||
return
|
||||
new_note = sanitizeSQL(new_note)
|
||||
var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from<br>[old_note]<br>to<br>[new_note]<hr>"
|
||||
edit_text = sanitizeSQL(edit_text)
|
||||
var/DBQuery/query_update_note = dbcon.NewQuery("UPDATE [format_table_name("notes")] SET notetext = '[new_note]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [note_id]")
|
||||
if(!query_update_note.Execute())
|
||||
var/err = query_update_note.ErrorMsg()
|
||||
log_game("SQL ERROR editing note. Error : \[[err]\]\n")
|
||||
return
|
||||
log_admin("[key_name(usr)] has edited [target_ckey]'s note made by [adminckey] from [old_note] to [new_note]")
|
||||
message_admins("[key_name_admin(usr)] has edited [target_ckey]'s note made by [adminckey] from<br>[old_note]<br>to<br>[new_note]")
|
||||
show_note(target_ckey)
|
||||
|
||||
/proc/show_note(target_ckey, index, linkless = 0)
|
||||
var/output
|
||||
var/navbar
|
||||
var/ruler
|
||||
ruler = "<hr style='background:#000000; border:0; height:3px'>"
|
||||
navbar = "<a href='?_src_=holder;nonalpha=1'>\[All\]</a>|<a href='?_src_=holder;nonalpha=2'>\[#\]</a>"
|
||||
for(var/letter in alphabet)
|
||||
navbar += "|<a href='?_src_=holder;shownote=[letter]'>\[[letter]\]</a>"
|
||||
navbar += "<br><form method='GET' name='search' action='?'>\
|
||||
<input type='hidden' name='_src_' value='holder'>\
|
||||
<input type='text' name='notessearch' value='[index]'>\
|
||||
<input type='submit' value='Search'></form>"
|
||||
if(!linkless)
|
||||
output = navbar
|
||||
if(target_ckey)
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
|
||||
if(!query_get_notes.Execute())
|
||||
var/err = query_get_notes.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server from notes table. Error : \[[err]\]\n")
|
||||
return
|
||||
output += "<h2><center>Notes of [target_ckey]</center></h2>"
|
||||
if(!linkless)
|
||||
output += "<center><a href='?_src_=holder;addnote=[target_ckey]'>\[Add Note\]</a></center>"
|
||||
output += ruler
|
||||
while(query_get_notes.NextRow())
|
||||
var/id = query_get_notes.item[1]
|
||||
var/timestamp = query_get_notes.item[2]
|
||||
var/notetext = query_get_notes.item[3]
|
||||
var/adminckey = query_get_notes.item[4]
|
||||
var/last_editor = query_get_notes.item[5]
|
||||
var/server = query_get_notes.item[6]
|
||||
output += "<b>[timestamp] | [server] | [adminckey]</b>"
|
||||
if(!linkless)
|
||||
output += " <a href='?_src_=holder;removenote=[id]'>\[Remove Note\]</a> <a href='?_src_=holder;editnote=[id]'>\[Edit Note\]</a>"
|
||||
if(last_editor)
|
||||
output += " <font size='2'>Last edit by [last_editor] <a href='?_src_=holder;noteedits=[id]'>(Click here to see edit log)</a></font>"
|
||||
output += "<br>[notetext]<hr style='background:#000000; border:0; height:1px'>"
|
||||
else if(index)
|
||||
var/index_ckey
|
||||
var/search
|
||||
output += "<center><a href='?_src_=holder;addnoteempty=1'>\[Add Note\]</a></center>"
|
||||
output += ruler
|
||||
if(!isnum(index))
|
||||
index = sanitizeSQL(index)
|
||||
switch(index)
|
||||
if(1)
|
||||
search = "^."
|
||||
if(2)
|
||||
search = "^\[^\[:alpha:\]\]"
|
||||
else
|
||||
search = "^[index]"
|
||||
var/DBQuery/query_list_notes = dbcon.NewQuery("SELECT DISTINCT ckey FROM [format_table_name("notes")] WHERE ckey REGEXP '[search]' ORDER BY ckey")
|
||||
if(!query_list_notes.Execute())
|
||||
var/err = query_list_notes.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey from notes table. Error : \[[err]\]\n")
|
||||
return
|
||||
while(query_list_notes.NextRow())
|
||||
index_ckey = query_list_notes.item[1]
|
||||
output += "<a href='?_src_=holder;shownoteckey=[index_ckey]'>[index_ckey]</a><br>"
|
||||
else
|
||||
output += "<center><a href='?_src_=holder;addnoteempty=1'>\[Add Note\]</a></center>"
|
||||
output += ruler
|
||||
usr << browse(output, "window=show_notes;size=900x500")
|
||||
|
||||
#define NOTESFILE "data/player_notes.sav"
|
||||
//if the AUTOCONVERT_NOTES is turned on, anytime a player connects this will be run to try and add all their notes to the databas
|
||||
/proc/convert_notes_sql(ckey)
|
||||
var/savefile/notesfile = new(NOTESFILE)
|
||||
if(!notesfile)
|
||||
log_game("Error: Cannot access [NOTESFILE]")
|
||||
return
|
||||
notesfile.cd = "/[ckey]"
|
||||
while(!notesfile.eof)
|
||||
var/notetext
|
||||
notesfile >> notetext
|
||||
var/server
|
||||
if(config && config.server_name)
|
||||
server = config.server_name
|
||||
var/regex/note = new("^(\\d{2}-\\w{3}-\\d{4}) \\| (.+) ~(\\w+)$", "i")
|
||||
note.Find(notetext)
|
||||
var/timestamp = note.group[1]
|
||||
notetext = note.group[2]
|
||||
var/adminckey = note.group[3]
|
||||
var/DBQuery/query_convert_time = dbcon.NewQuery("SELECT ADDTIME(STR_TO_DATE('[timestamp]','%d-%b-%Y'), '0')")
|
||||
if(!query_convert_time.Execute())
|
||||
var/err = query_convert_time.ErrorMsg()
|
||||
log_game("SQL ERROR converting timestamp. Error : \[[err]\]\n")
|
||||
return
|
||||
if(query_convert_time.NextRow())
|
||||
timestamp = query_convert_time.item[1]
|
||||
if(ckey && notetext && timestamp && adminckey && server)
|
||||
add_note(ckey, notetext, timestamp, adminckey, 0, server)
|
||||
notesfile.cd = "/"
|
||||
notesfile.dir.Remove(ckey)
|
||||
|
||||
/*alternatively this proc can be run once to pass through every note and attempt to convert it before deleting the file, if done then AUTOCONVERT_NOTES should be turned off
|
||||
this proc can take several minutes to execute fully if converting and cause DD to hang if converting a lot of notes; it's not advised to do so while a server is live
|
||||
/proc/mass_convert_notes()
|
||||
world << "Beginning mass note conversion"
|
||||
var/savefile/notesfile = new(NOTESFILE)
|
||||
if(!notesfile)
|
||||
log_game("Error: Cannot access [NOTESFILE]")
|
||||
return
|
||||
notesfile.cd = "/"
|
||||
for(var/ckey in notesfile.dir)
|
||||
convert_notes_sql(ckey)
|
||||
world << "Deleting NOTESFILE"
|
||||
fdel(NOTESFILE)
|
||||
world << "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES"*/
|
||||
#undef NOTESFILE
|
||||
@@ -1,117 +0,0 @@
|
||||
/client/proc/watchlist_add(target_ckey, browse = 0)
|
||||
if(!target_ckey)
|
||||
var/new_ckey = ckey(input(usr,"Who would you like to add to the watchlist?","Enter a ckey",null) as text)
|
||||
if(!new_ckey)
|
||||
return
|
||||
new_ckey = sanitizeSQL(new_ckey)
|
||||
var/DBQuery/query_watchfind = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
|
||||
if(!query_watchfind.Execute())
|
||||
var/err = query_watchfind.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
|
||||
return
|
||||
if(!query_watchfind.NextRow())
|
||||
if(alert(usr, "[new_ckey] has not been seen before, are you sure you want to add them to the watchlist?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
|
||||
return
|
||||
target_ckey = new_ckey
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
if(check_watchlist(target_sql_ckey))
|
||||
usr << "<span class='redtext'>[target_sql_ckey] is already on the watchlist.</span>"
|
||||
return
|
||||
var/reason = input(usr,"Please State Reason","Reason") as message
|
||||
if(!reason)
|
||||
return
|
||||
reason = sanitizeSQL(reason)
|
||||
var/timestamp = SQLtime()
|
||||
var/adminckey = usr.ckey
|
||||
if(!adminckey)
|
||||
return
|
||||
var/admin_sql_ckey = sanitizeSQL(adminckey)
|
||||
var/DBQuery/query_watchadd = dbcon.NewQuery("INSERT INTO [format_table_name("watch")] (ckey, reason, adminckey, timestamp) VALUES ('[target_sql_ckey]', '[reason]', '[admin_sql_ckey]', '[timestamp]')")
|
||||
if(!query_watchadd.Execute())
|
||||
var/err = query_watchadd.ErrorMsg()
|
||||
log_game("SQL ERROR during adding new watch entry. Error : \[[err]\]\n")
|
||||
return
|
||||
log_admin("[key_name(usr)] has added [target_ckey] to the watchlist - Reason: [reason]")
|
||||
message_admins("[key_name_admin(usr)] has added [target_ckey] to the watchlist - Reason: [reason]", 1)
|
||||
if(browse)
|
||||
watchlist_show(target_sql_ckey)
|
||||
|
||||
/client/proc/watchlist_remove(target_ckey, browse = 0)
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
var/DBQuery/query_watchdel = dbcon.NewQuery("DELETE FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_watchdel.Execute())
|
||||
var/err = query_watchdel.ErrorMsg()
|
||||
log_game("SQL ERROR during removing watch entry. Error : \[[err]\]\n")
|
||||
return
|
||||
log_admin("[key_name(usr)] has removed [target_ckey] from the watchlist")
|
||||
message_admins("[key_name_admin(usr)] has removed [target_ckey] from the watchlist", 1)
|
||||
if(browse)
|
||||
watchlist_show()
|
||||
|
||||
/client/proc/watchlist_edit(target_ckey, browse = 0)
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
var/DBQuery/query_watchreason = dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_watchreason.Execute())
|
||||
var/err = query_watchreason.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining reason from watch table. Error : \[[err]\]\n")
|
||||
return
|
||||
if(query_watchreason.NextRow())
|
||||
var/watch_reason = query_watchreason.item[1]
|
||||
var/new_reason = input("Input new reason", "New Reason", "[watch_reason]") as message
|
||||
new_reason = sanitizeSQL(new_reason)
|
||||
if(!new_reason)
|
||||
return
|
||||
var/sql_ckey = sanitizeSQL(usr.ckey)
|
||||
var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from<br>[watch_reason]<br>to<br>[new_reason]<hr>"
|
||||
edit_text = sanitizeSQL(edit_text)
|
||||
var/DBQuery/query_watchupdate = dbcon.NewQuery("UPDATE [format_table_name("watch")] SET reason = '[new_reason]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_watchupdate.Execute())
|
||||
var/err = query_watchupdate.ErrorMsg()
|
||||
log_game("SQL ERROR editing watchlist reason. Error : \[[err]\]\n")
|
||||
return
|
||||
log_admin("[key_name(usr)] has edited [target_ckey]'s watchlist reason from [watch_reason] to [new_reason]")
|
||||
message_admins("[key_name_admin(usr)] has edited [target_ckey]'s watchlist reason from<br>[watch_reason]<br>to<br>[new_reason]")
|
||||
if(browse)
|
||||
watchlist_show(target_sql_ckey)
|
||||
|
||||
/client/proc/watchlist_show(search)
|
||||
var/output
|
||||
output += "<form method='GET' name='search' action='?'>\
|
||||
<input type='hidden' name='_src_' value='holder'>\
|
||||
<input type='text' name='watchsearch' value='[search]'>\
|
||||
<input type='submit' value='Search'></form>"
|
||||
output += "<a href='?_src_=holder;watchshow=1'>\[Clear Search\]</a> <a href='?_src_=holder;watchaddbrowse=1'>\[Add Ckey\]</a>"
|
||||
output += "<hr style='background:#000000; border:0; height:3px'>"
|
||||
if(search)
|
||||
search = "^[search]"
|
||||
else
|
||||
search = "^."
|
||||
search = sanitizeSQL(search)
|
||||
var/DBQuery/query_watchlist = dbcon.NewQuery("SELECT ckey, reason, adminckey, timestamp, last_editor FROM [format_table_name("watch")] WHERE ckey REGEXP '[search]' ORDER BY ckey")
|
||||
if(!query_watchlist.Execute())
|
||||
var/err = query_watchlist.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining ckey, reason, adminckey, timestamp, last_editor from watch table. Error : \[[err]\]\n")
|
||||
return
|
||||
while(query_watchlist.NextRow())
|
||||
var/ckey = query_watchlist.item[1]
|
||||
var/reason = query_watchlist.item[2]
|
||||
var/adminckey = query_watchlist.item[3]
|
||||
var/timestamp = query_watchlist.item[4]
|
||||
var/last_editor = query_watchlist.item[5]
|
||||
output += "<b>[ckey]</b> | Added by <b>[adminckey]</b> on <b>[timestamp]</b> <a href='?_src_=holder;watchremovebrowse=[ckey]'>\[Remove\]</a> <a href='?_src_=holder;watcheditbrowse=[ckey]'>\[Edit Reason\]</a>"
|
||||
if(last_editor)
|
||||
output += " <font size='2'>Last edit by [last_editor] <a href='?_src_=holder;watcheditlog=[ckey]'>(Click here to see edit log)</a></font>"
|
||||
output += "<br>[reason]<hr style='background:#000000; border:0; height:1px'>"
|
||||
usr << browse(output, "window=watchwin;size=900x500")
|
||||
|
||||
/client/proc/check_watchlist(target_ckey)
|
||||
var/target_sql_ckey = sanitizeSQL(target_ckey)
|
||||
var/DBQuery/query_watch = dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
|
||||
if(!query_watch.Execute())
|
||||
var/err = query_watch.ErrorMsg()
|
||||
log_game("SQL ERROR obtaining reason from watch table. Error : \[[err]\]\n")
|
||||
return
|
||||
if(query_watch.NextRow())
|
||||
return query_watch.item[1]
|
||||
else
|
||||
return 0
|
||||
@@ -1,22 +0,0 @@
|
||||
//Packer Ship Areas
|
||||
|
||||
/area/awaymission/BMPship
|
||||
name = "BMP Asteroids"
|
||||
icon_state = "away"
|
||||
luminosity = 0
|
||||
|
||||
|
||||
/area/awaymission/BMPship/Aft
|
||||
name = "Aft Block"
|
||||
icon_state = "away1"
|
||||
requires_power = 1
|
||||
|
||||
/area/awaymission/BMPship/Midship
|
||||
name = "Midship Block"
|
||||
icon_state = "away2"
|
||||
requires_power = 1
|
||||
|
||||
/area/awaymission/BMPship/Fore
|
||||
name = "Fore Block"
|
||||
icon_state = "away3"
|
||||
requires_power = 1
|
||||
@@ -1,64 +0,0 @@
|
||||
//Research Base Areas//--
|
||||
|
||||
/area/awaymission/research
|
||||
name = "Research Outpost"
|
||||
icon_state = "away"
|
||||
luminosity = 0
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
|
||||
|
||||
/area/awaymission/research/interior
|
||||
name = "Research Inside"
|
||||
requires_power = 1
|
||||
icon_state = "away2"
|
||||
|
||||
/area/awaymission/research/interior/cryo
|
||||
name = "Research Cryostasis Room"
|
||||
icon_state = "medbay"
|
||||
|
||||
/area/awaymission/research/interior/clonestorage
|
||||
name = "Research Clone Storage"
|
||||
icon_state = "cloning"
|
||||
|
||||
/area/awaymission/research/interior/genetics
|
||||
name = "Research Genetics Research"
|
||||
icon_state = "genetics"
|
||||
|
||||
/area/awaymission/research/interior/engineering
|
||||
name = "Research Engineering"
|
||||
icon_state = "engine"
|
||||
|
||||
/area/awaymission/research/interior/security
|
||||
name = "Research Security"
|
||||
icon_state = "security"
|
||||
|
||||
/area/awaymission/research/interior/secure
|
||||
name = "Research Secure Vault"
|
||||
|
||||
/area/awaymission/research/interior/maint
|
||||
name = "Research Maintenance"
|
||||
icon_state = "maintcentral"
|
||||
|
||||
/area/awaymission/research/interior/dorm
|
||||
name = "Research Dorms"
|
||||
icon_state = "Sleep"
|
||||
|
||||
/area/awaymission/research/interior/escapepods
|
||||
name = "Research Escape Wing"
|
||||
icon_state = "exit"
|
||||
|
||||
/area/awaymission/research/interior/gateway
|
||||
name = "Research Gateway"
|
||||
icon_state = "start"
|
||||
|
||||
/area/awaymission/research/interior/bathroom
|
||||
name = "Research Bathrooms"
|
||||
icon_state = "restrooms"
|
||||
|
||||
/area/awaymission/research/interior/medbay
|
||||
name = "Research Medbay"
|
||||
icon_state = "medbay"
|
||||
|
||||
/area/awaymission/research/exterior
|
||||
name = "Research Exterior"
|
||||
icon_state = "unknown"
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// Space Cash. Now it isn't that useless.
|
||||
/datum/export/stack/cash
|
||||
cost = 1 // Multiplied both by value of each bill and by amount of bills in stack.
|
||||
unit_name = "credit"
|
||||
export_types = list(/obj/item/stack/spacecash)
|
||||
|
||||
/datum/export/stack/cash/get_amount(obj/O)
|
||||
var/obj/item/stack/spacecash/C = O
|
||||
return ..() * C.value
|
||||
|
||||
|
||||
// Coins. At least the coins that do not contain any materials.
|
||||
// Material-containing coins cost just as much as their materials do, see materials.dm for exact rates.
|
||||
/datum/export/coin
|
||||
cost = 1 // Multiplied by coin's value
|
||||
unit_name = "credit"
|
||||
message = "worth of rare coins"
|
||||
export_types = list(/obj/item/weapon/coin)
|
||||
|
||||
/datum/export/coin/get_amount(obj/O)
|
||||
var/obj/item/weapon/coin/C = O
|
||||
if(C.materials && C.materials.len)
|
||||
return 0 // Sold as raw material instead.
|
||||
return ..() * C.value
|
||||
@@ -1,137 +0,0 @@
|
||||
/obj/effect/countdown
|
||||
name = "countdown"
|
||||
desc = "We're leaving together\n\
|
||||
But still it's farewell\n\
|
||||
And maybe we'll come back\n\
|
||||
To earth, who can tell?"
|
||||
|
||||
var/displayed_text
|
||||
var/atom/attached_to
|
||||
var/text_color = "#ff0000"
|
||||
var/text_size = 4
|
||||
var/started = FALSE
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
anchored = TRUE
|
||||
layer = GHOST_LAYER
|
||||
|
||||
/obj/effect/countdown/New(atom/A)
|
||||
. = ..()
|
||||
attach(A)
|
||||
|
||||
/obj/effect/countdown/proc/attach(atom/A)
|
||||
attached_to = A
|
||||
loc = get_turf(A)
|
||||
|
||||
/obj/effect/countdown/proc/start()
|
||||
if(!started)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
started = TRUE
|
||||
|
||||
/obj/effect/countdown/proc/stop()
|
||||
if(started)
|
||||
overlays.Cut()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
started = FALSE
|
||||
|
||||
/obj/effect/countdown/proc/get_value()
|
||||
// Get the value from our atom
|
||||
return
|
||||
|
||||
/obj/effect/countdown/process()
|
||||
if(!attached_to || qdeleted(attached_to))
|
||||
qdel(src)
|
||||
forceMove(get_turf(attached_to))
|
||||
var/new_val = get_value()
|
||||
if(new_val == displayed_text)
|
||||
return
|
||||
displayed_text = new_val
|
||||
|
||||
if(displayed_text)
|
||||
var/image/text_image = new(loc = src)
|
||||
//text_image.maptext = "<font size=[text_size]>[new_val]</font>"
|
||||
text_image.maptext = "<font size = [text_size]>[displayed_text]</font>"
|
||||
text_image.color = text_color
|
||||
|
||||
overlays.Cut()
|
||||
overlays += text_image
|
||||
else
|
||||
overlays.Cut()
|
||||
|
||||
/obj/effect/countdown/Destroy()
|
||||
attached_to = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
. = ..()
|
||||
|
||||
/obj/effect/countdown/syndicatebomb
|
||||
name = "syndicate bomb countdown"
|
||||
|
||||
/obj/effect/countdown/syndicatebomb/get_value()
|
||||
var/obj/machinery/syndicatebomb/S = attached_to
|
||||
if(!istype(S))
|
||||
return
|
||||
else if(S.active)
|
||||
return S.timer
|
||||
|
||||
/obj/effect/countdown/nuclearbomb
|
||||
name = "nuclear bomb countdown"
|
||||
text_color = "#81FF14"
|
||||
|
||||
/obj/effect/countdown/nuclearbomb/get_value()
|
||||
var/obj/machinery/nuclearbomb/N = attached_to
|
||||
if(!istype(N))
|
||||
return
|
||||
else if(N.timing)
|
||||
return N.timeleft
|
||||
|
||||
/obj/effect/countdown/clonepod
|
||||
name = "cloning pod countdown"
|
||||
text_color = "#0C479D"
|
||||
text_size = 1
|
||||
|
||||
/obj/effect/countdown/clonepod/get_value()
|
||||
var/obj/machinery/clonepod/C = attached_to
|
||||
if(!istype(C))
|
||||
return
|
||||
else if(C.occupant)
|
||||
var/completion = round(C.get_completion())
|
||||
return completion
|
||||
|
||||
/obj/effect/countdown/dominator
|
||||
name = "dominator countdown"
|
||||
text_size = 1
|
||||
text_color = "#ff00ff" // Overwritten when the dominator starts
|
||||
|
||||
/obj/effect/countdown/dominator/get_value()
|
||||
var/obj/machinery/dominator/D = attached_to
|
||||
if(!istype(D))
|
||||
return
|
||||
else if(D.gang && D.gang.is_dominating)
|
||||
var/timer = D.gang.domination_time_remaining()
|
||||
return timer
|
||||
else
|
||||
return "OFFLINE"
|
||||
|
||||
/obj/effect/countdown/clockworkgate
|
||||
name = "gateway countdown"
|
||||
text_size = 1
|
||||
text_color = "#BE8700"
|
||||
layer = POINT_LAYER
|
||||
|
||||
/obj/effect/countdown/clockworkgate/get_value()
|
||||
var/obj/structure/clockwork/massive/celestial_gateway/G = attached_to
|
||||
if(!istype(G))
|
||||
return
|
||||
else if(G.health && !G.purpose_fulfilled)
|
||||
return "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'>[GATEWAY_RATVAR_ARRIVAL - G.progress_in_seconds]</div>"
|
||||
|
||||
/obj/effect/countdown/transformer
|
||||
name = "transformer countdown"
|
||||
text_color = "#4C5866"
|
||||
|
||||
/obj/effect/countdown/transformer/get_value()
|
||||
var/obj/machinery/transformer/T = attached_to
|
||||
if(!istype(T))
|
||||
return
|
||||
else if(T.cooldown)
|
||||
var/seconds_left = max(0, (T.cooldown_timer - world.time) / 10)
|
||||
return "[round(seconds_left)]"
|
||||
Binary file not shown.
@@ -1,102 +0,0 @@
|
||||
/area/holodeck
|
||||
name = "Holodeck"
|
||||
icon_state = "Holodeck"
|
||||
luminosity = 1
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
|
||||
var/obj/machinery/computer/holodeck/linked
|
||||
var/restricted = 0 // if true, program goes on emag list
|
||||
|
||||
/*
|
||||
Power tracking: Use the holodeck computer's power grid
|
||||
Asserts are to avoid the inevitable infinite loops
|
||||
*/
|
||||
|
||||
/area/holodeck/powered(var/chan)
|
||||
if(!master.requires_power)
|
||||
return 1
|
||||
if(master.always_unpowered)
|
||||
return 0
|
||||
if(!linked)
|
||||
return 0
|
||||
var/area/A = get_area(linked)
|
||||
ASSERT(!istype(A,/area/holodeck))
|
||||
return A.powered(chan)
|
||||
|
||||
/area/holodeck/usage(var/chan)
|
||||
if(!linked)
|
||||
return 0
|
||||
var/area/A = get_area(linked)
|
||||
ASSERT(!istype(A,/area/holodeck))
|
||||
return A.usage(chan)
|
||||
|
||||
/area/holodeck/addStaticPower(value, powerchannel)
|
||||
if(!linked)
|
||||
return
|
||||
var/area/A = get_area(linked)
|
||||
ASSERT(!istype(A,/area/holodeck))
|
||||
return A.addStaticPower(value,powerchannel)
|
||||
|
||||
/area/holodeck/use_power(var/amount, var/chan)
|
||||
if(!linked)
|
||||
return 0
|
||||
var/area/A = get_area(linked)
|
||||
ASSERT(!istype(A,/area/holodeck))
|
||||
return A.use_power(amount,chan)
|
||||
|
||||
|
||||
/*
|
||||
This is the standard holodeck. It is intended to allow you to
|
||||
blow off steam by doing stupid things like laying down, throwing
|
||||
spheres at holes, or bludgeoning people.
|
||||
*/
|
||||
/area/holodeck/rec_center
|
||||
name = "\improper Recreational Holodeck"
|
||||
|
||||
/area/holodeck/rec_center/offline
|
||||
name = "Holodeck - Offline"
|
||||
|
||||
/area/holodeck/rec_center/court
|
||||
name = "Holodeck - Empty Court"
|
||||
|
||||
/area/holodeck/rec_center/dodgeball
|
||||
name = "Holodeck - Dodgeball Court"
|
||||
|
||||
/area/holodeck/rec_center/basketball
|
||||
name = "Holodeck - Basketball Court"
|
||||
|
||||
/area/holodeck/rec_center/thunderdome
|
||||
name = "Holodeck - Thunderdome Court"
|
||||
|
||||
/area/holodeck/rec_center/beach
|
||||
name = "Holodeck - Beach"
|
||||
|
||||
/area/holodeck/rec_center/lounge
|
||||
name = "Holodeck - Lounge"
|
||||
|
||||
/area/holodeck/rec_center/medical
|
||||
name = "Holodeck - Emergency Medical"
|
||||
|
||||
/area/holodeck/rec_center/pet_lounge
|
||||
name = "Holodeck - Pet Playground"
|
||||
|
||||
/area/holodeck/rec_center/winterwonderland
|
||||
name = "Holodeck - Winter Wonderland"
|
||||
|
||||
// Bad programs
|
||||
|
||||
/area/holodeck/rec_center/burn
|
||||
name = "Holodeck - Atmospheric Burn Test"
|
||||
restricted = 1
|
||||
|
||||
/area/holodeck/rec_center/wildlife
|
||||
name = "Holodeck - Wildlife Simulation"
|
||||
restricted = 1
|
||||
|
||||
/area/holodeck/rec_center/bunker
|
||||
name = "Holodeck - Holdout Bunker"
|
||||
restricted = 1
|
||||
|
||||
/area/holodeck/rec_center/anthophila
|
||||
name = "Holodeck - Anthophila"
|
||||
restricted = 1
|
||||
@@ -1,15 +0,0 @@
|
||||
#define WHITELISTFILE "data/whitelist.txt"
|
||||
|
||||
var/list/whitelist
|
||||
|
||||
/proc/load_whitelist()
|
||||
whitelist = file2list(WHITELISTFILE)
|
||||
if(!whitelist.len)
|
||||
whitelist = null
|
||||
|
||||
/proc/check_whitelist(mob/M /*, var/rank*/)
|
||||
if(!whitelist)
|
||||
return 0
|
||||
return ("[M.ckey]" in whitelist)
|
||||
|
||||
#undef WHITELISTFILE
|
||||
@@ -1,19 +0,0 @@
|
||||
/turf/closed/mineral/random/labormineral
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/iron = 100, /turf/closed/mineral/uranium = 1, /turf/closed/mineral/diamond = 1,
|
||||
/turf/closed/mineral/gold = 1, /turf/closed/mineral/silver = 1, /turf/closed/mineral/plasma = 1)
|
||||
icon_state = "rock_labor"
|
||||
|
||||
/turf/closed/mineral/random/labormineral/New()
|
||||
icon_state = "rock"
|
||||
..()
|
||||
|
||||
/turf/closed/mineral/random/labormineral/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
defer_change = 1
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/iron/volcanic = 100, /turf/closed/mineral/uranium/volcanic = 1, /turf/closed/mineral/diamond/volcanic = 1,
|
||||
/turf/closed/mineral/gold/volcanic = 1, /turf/closed/mineral/silver/volcanic = 1, /turf/closed/mineral/plasma/volcanic = 1)
|
||||
@@ -1,32 +0,0 @@
|
||||
/**********************Lavaland Areas**************************/
|
||||
|
||||
/area/lavaland
|
||||
icon_state = "mining"
|
||||
has_gravity = 1
|
||||
|
||||
/area/lavaland/surface
|
||||
name = "Lavaland"
|
||||
icon_state = "explored"
|
||||
music = null
|
||||
requires_power = 1
|
||||
ambientsounds = list('sound/ambience/ambilava.ogg')
|
||||
|
||||
/area/lavaland/underground
|
||||
name = "Lavaland Caves"
|
||||
icon_state = "unexplored"
|
||||
music = null
|
||||
always_unpowered = 1
|
||||
requires_power = 1
|
||||
poweralm = 0
|
||||
power_environ = 0
|
||||
power_equip = 0
|
||||
power_light = 0
|
||||
ambientsounds = list('sound/ambience/ambilava.ogg')
|
||||
|
||||
|
||||
/area/lavaland/surface/outdoors
|
||||
name = "Lavaland Wastes"
|
||||
outdoors = 1
|
||||
|
||||
/area/lavaland/surface/outdoors/explored
|
||||
name = "Lavaland Labor Camp"
|
||||
@@ -1,77 +0,0 @@
|
||||
/**********************Mine areas**************************/
|
||||
|
||||
/area/mine
|
||||
icon_state = "mining"
|
||||
has_gravity = 1
|
||||
|
||||
/area/mine/explored
|
||||
name = "Mine"
|
||||
icon_state = "explored"
|
||||
music = null
|
||||
always_unpowered = 1
|
||||
requires_power = 1
|
||||
poweralm = 0
|
||||
power_environ = 0
|
||||
power_equip = 0
|
||||
power_light = 0
|
||||
outdoors = 1
|
||||
ambientsounds = list('sound/ambience/ambimine.ogg')
|
||||
|
||||
/area/mine/unexplored
|
||||
name = "Mine"
|
||||
icon_state = "unexplored"
|
||||
music = null
|
||||
always_unpowered = 1
|
||||
requires_power = 1
|
||||
poweralm = 0
|
||||
power_environ = 0
|
||||
power_equip = 0
|
||||
power_light = 0
|
||||
outdoors = 1
|
||||
ambientsounds = list('sound/ambience/ambimine.ogg')
|
||||
|
||||
/area/mine/lobby
|
||||
name = "Mining station"
|
||||
|
||||
/area/mine/storage
|
||||
name = "Mining station Storage"
|
||||
|
||||
/area/mine/production
|
||||
name = "Mining Station Starboard Wing"
|
||||
icon_state = "mining_production"
|
||||
|
||||
/area/mine/abandoned
|
||||
name = "Abandoned Mining Station"
|
||||
|
||||
/area/mine/living_quarters
|
||||
name = "Mining Station Port Wing"
|
||||
icon_state = "mining_living"
|
||||
|
||||
/area/mine/eva
|
||||
name = "Mining Station EVA"
|
||||
icon_state = "mining_eva"
|
||||
|
||||
/area/mine/maintenance
|
||||
name = "Mining Station Communications"
|
||||
|
||||
/area/mine/cafeteria
|
||||
name = "Mining station Cafeteria"
|
||||
|
||||
/area/mine/hydroponics
|
||||
name = "Mining station Hydroponics"
|
||||
|
||||
/area/mine/sleeper
|
||||
name = "Mining station Emergency Sleeper"
|
||||
|
||||
/area/mine/north_outpost
|
||||
name = "North Mining Outpost"
|
||||
|
||||
/area/mine/west_outpost
|
||||
name = "West Mining Outpost"
|
||||
|
||||
/area/mine/laborcamp
|
||||
name = "Labor Camp"
|
||||
|
||||
/area/mine/laborcamp/security
|
||||
name = "Labor Camp Security"
|
||||
icon_state = "security"
|
||||
@@ -1,807 +0,0 @@
|
||||
/**********************Mineral deposits**************************/
|
||||
|
||||
/turf/closed/mineral //wall piece
|
||||
name = "rock"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
icon_state = "rock"
|
||||
var/smooth_icon = 'icons/turf/smoothrocks.dmi'
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/closed/mineral, /turf/closed/wall)
|
||||
baseturf = /turf/open/floor/plating/asteroid/airless
|
||||
initial_gas_mix = "TEMP=2.7"
|
||||
opacity = 1
|
||||
density = 1
|
||||
blocks_air = 1
|
||||
layer = EDGED_TURF_LAYER
|
||||
temperature = TCMB
|
||||
var/environment_type = "asteroid"
|
||||
var/turf/open/floor/plating/turf_type = /turf/open/floor/plating/asteroid/airless
|
||||
var/mineralType = null
|
||||
var/mineralAmt = 3
|
||||
var/spread = 0 //will the seam spread?
|
||||
var/spreadChance = 0 //the percentual chance of an ore spreading to the neighbouring tiles
|
||||
var/last_act = 0
|
||||
var/scan_state = null //Holder for the image we display when we're pinged by a mining scanner
|
||||
var/defer_change = 0
|
||||
|
||||
/turf/closed/mineral/New()
|
||||
pixel_y = -4
|
||||
pixel_x = -4
|
||||
icon = smooth_icon
|
||||
..()
|
||||
if (mineralType && mineralAmt && spread && spreadChance)
|
||||
for(var/dir in cardinal)
|
||||
if(prob(spreadChance))
|
||||
var/turf/T = get_step(src, dir)
|
||||
if(istype(T, /turf/closed/mineral/random))
|
||||
Spread(T)
|
||||
|
||||
/turf/closed/mineral/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt
|
||||
baseturf = /turf/open/floor/plating/asteroid/basalt
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
|
||||
/turf/closed/mineral/ex_act(severity, target)
|
||||
..()
|
||||
switch(severity)
|
||||
if(3)
|
||||
if (prob(75))
|
||||
src.gets_drilled(null, 1)
|
||||
if(2)
|
||||
if (prob(90))
|
||||
src.gets_drilled(null, 1)
|
||||
if(1)
|
||||
src.gets_drilled(null, 1)
|
||||
return
|
||||
|
||||
/turf/closed/mineral/Spread(turf/T)
|
||||
new src.type(T)
|
||||
|
||||
/turf/closed/mineral/random
|
||||
var/mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium = 5, /turf/closed/mineral/diamond = 1, /turf/closed/mineral/gold = 10,
|
||||
/turf/closed/mineral/silver = 12, /turf/closed/mineral/plasma = 20, /turf/closed/mineral/iron = 40,
|
||||
/turf/closed/mineral/gibtonite = 4, /turf/open/floor/plating/asteroid/airless/cave = 2, /turf/closed/mineral/bscrystal = 1)
|
||||
//Currently, Adamantine won't spawn as it has no uses. -Durandan
|
||||
var/mineralChance = 13
|
||||
|
||||
/turf/closed/mineral/random/New()
|
||||
..()
|
||||
|
||||
if (prob(mineralChance))
|
||||
var/path = pickweight(mineralSpawnChanceList)
|
||||
var/turf/T = new path(src)
|
||||
|
||||
if(T && istype(T, /turf/closed/mineral))
|
||||
var/turf/closed/mineral/M = T
|
||||
M.mineralAmt = rand(1, 5)
|
||||
M.environment_type = src.environment_type
|
||||
M.turf_type = src.turf_type
|
||||
M.baseturf = src.baseturf
|
||||
src = M
|
||||
M.levelupdate()
|
||||
|
||||
/turf/closed/mineral/random/high_chance
|
||||
icon_state = "rock_highchance"
|
||||
mineralChance = 25
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium = 35, /turf/closed/mineral/diamond = 30, /turf/closed/mineral/gold = 45,
|
||||
/turf/closed/mineral/silver = 50, /turf/closed/mineral/plasma = 50, /turf/closed/mineral/bscrystal = 20)
|
||||
|
||||
/turf/closed/mineral/random/high_chance/New()
|
||||
icon_state = "rock"
|
||||
..()
|
||||
|
||||
/turf/closed/mineral/random/low_chance
|
||||
icon_state = "rock_lowchance"
|
||||
mineralChance = 6
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium = 2, /turf/closed/mineral/diamond = 1, /turf/closed/mineral/gold = 4,
|
||||
/turf/closed/mineral/silver = 6, /turf/closed/mineral/plasma = 15, /turf/closed/mineral/iron = 40,
|
||||
/turf/closed/mineral/gibtonite = 2, /turf/closed/mineral/bscrystal = 1)
|
||||
|
||||
/turf/closed/mineral/random/low_chance/New()
|
||||
icon_state = "rock"
|
||||
..()
|
||||
|
||||
/turf/closed/mineral/iron
|
||||
mineralType = /obj/item/weapon/ore/iron
|
||||
spreadChance = 20
|
||||
spread = 1
|
||||
scan_state = "rock_Iron"
|
||||
|
||||
/turf/closed/mineral/uranium
|
||||
mineralType = /obj/item/weapon/ore/uranium
|
||||
spreadChance = 5
|
||||
spread = 1
|
||||
scan_state = "rock_Uranium"
|
||||
|
||||
/turf/closed/mineral/diamond
|
||||
mineralType = /obj/item/weapon/ore/diamond
|
||||
spreadChance = 0
|
||||
spread = 1
|
||||
scan_state = "rock_Diamond"
|
||||
|
||||
/turf/closed/mineral/gold
|
||||
mineralType = /obj/item/weapon/ore/gold
|
||||
spreadChance = 5
|
||||
spread = 1
|
||||
scan_state = "rock_Gold"
|
||||
|
||||
/turf/closed/mineral/silver
|
||||
mineralType = /obj/item/weapon/ore/silver
|
||||
spreadChance = 5
|
||||
spread = 1
|
||||
scan_state = "rock_Silver"
|
||||
|
||||
/turf/closed/mineral/plasma
|
||||
mineralType = /obj/item/weapon/ore/plasma
|
||||
spreadChance = 8
|
||||
spread = 1
|
||||
scan_state = "rock_Plasma"
|
||||
|
||||
/turf/closed/mineral/clown
|
||||
mineralType = /obj/item/weapon/ore/bananium
|
||||
mineralAmt = 3
|
||||
spreadChance = 0
|
||||
spread = 0
|
||||
scan_state = "rock_Clown"
|
||||
|
||||
/turf/closed/mineral/bscrystal
|
||||
mineralType = /obj/item/weapon/ore/bluespace_crystal
|
||||
mineralAmt = 1
|
||||
spreadChance = 0
|
||||
spread = 0
|
||||
scan_state = "rock_BScrystal"
|
||||
|
||||
////////////////////////////////Gibtonite
|
||||
/turf/closed/mineral/gibtonite
|
||||
mineralAmt = 1
|
||||
spreadChance = 0
|
||||
spread = 0
|
||||
scan_state = "rock_Gibtonite"
|
||||
var/det_time = 8 //Countdown till explosion, but also rewards the player for how close you were to detonation when you defuse it
|
||||
var/stage = 0 //How far into the lifecycle of gibtonite we are, 0 is untouched, 1 is active and attempting to detonate, 2 is benign and ready for extraction
|
||||
var/activated_ckey = null //These are to track who triggered the gibtonite deposit for logging purposes
|
||||
var/activated_name = null
|
||||
var/activated_image = null
|
||||
|
||||
/turf/closed/mineral/gibtonite/New()
|
||||
det_time = rand(8,10) //So you don't know exactly when the hot potato will explode
|
||||
..()
|
||||
|
||||
/turf/closed/mineral/gibtonite/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/device/mining_scanner) || istype(I, /obj/item/device/t_scanner/adv_mining_scanner) && stage == 1)
|
||||
user.visible_message("<span class='notice'>[user] holds [I] to [src]...</span>", "<span class='notice'>You use [I] to locate where to cut off the chain reaction and attempt to stop it...</span>")
|
||||
defuse()
|
||||
..()
|
||||
|
||||
/turf/closed/mineral/gibtonite/proc/explosive_reaction(mob/user = null, triggered_by_explosion = 0)
|
||||
if(stage == 0)
|
||||
var/image/I = image('icons/turf/smoothrocks.dmi', loc = src, icon_state = "rock_Gibtonite_active", layer = ON_EDGED_TURF_LAYER)
|
||||
add_overlay(I)
|
||||
activated_image = I
|
||||
name = "gibtonite deposit"
|
||||
desc = "An active gibtonite reserve. Run!"
|
||||
stage = 1
|
||||
visible_message("<span class='danger'>There was gibtonite inside! It's going to explode!</span>")
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
|
||||
var/notify_admins = 0
|
||||
if(z != 5)
|
||||
notify_admins = 1
|
||||
if(!triggered_by_explosion)
|
||||
message_admins("[key_name_admin(user)]<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) has triggered a gibtonite deposit reaction at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.")
|
||||
else
|
||||
message_admins("An explosion has triggered a gibtonite deposit reaction at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.")
|
||||
|
||||
if(!triggered_by_explosion)
|
||||
log_game("[key_name(user)] has triggered a gibtonite deposit reaction at [A.name] ([A.x], [A.y], [A.z]).")
|
||||
else
|
||||
log_game("An explosion has triggered a gibtonite deposit reaction at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])")
|
||||
|
||||
countdown(notify_admins)
|
||||
|
||||
/turf/closed/mineral/gibtonite/proc/countdown(notify_admins = 0)
|
||||
set waitfor = 0
|
||||
while(istype(src, /turf/closed/mineral/gibtonite) && stage == 1 && det_time > 0 && mineralAmt >= 1)
|
||||
det_time--
|
||||
sleep(5)
|
||||
if(istype(src, /turf/closed/mineral/gibtonite))
|
||||
if(stage == 1 && det_time <= 0 && mineralAmt >= 1)
|
||||
var/turf/bombturf = get_turf(src)
|
||||
mineralAmt = 0
|
||||
stage = 3
|
||||
explosion(bombturf,1,3,5, adminlog = notify_admins)
|
||||
|
||||
/turf/closed/mineral/gibtonite/proc/defuse()
|
||||
if(stage == 1)
|
||||
overlays -= activated_image
|
||||
var/image/I = image('icons/turf/smoothrocks.dmi', loc = src, icon_state = "rock_Gibtonite_inactive", layer = ON_EDGED_TURF_LAYER)
|
||||
add_overlay(I)
|
||||
desc = "An inactive gibtonite reserve. The ore can be extracted."
|
||||
stage = 2
|
||||
if(det_time < 0)
|
||||
det_time = 0
|
||||
visible_message("<span class='notice'>The chain reaction was stopped! The gibtonite had [src.det_time] reactions left till the explosion!</span>")
|
||||
|
||||
/turf/closed/mineral/gibtonite/gets_drilled(mob/user, triggered_by_explosion = 0)
|
||||
if(stage == 0 && mineralAmt >= 1) //Gibtonite deposit is activated
|
||||
playsound(src,'sound/effects/hit_on_shattered_glass.ogg',50,1)
|
||||
explosive_reaction(user, triggered_by_explosion)
|
||||
return
|
||||
if(stage == 1 && mineralAmt >= 1) //Gibtonite deposit goes kaboom
|
||||
var/turf/bombturf = get_turf(src)
|
||||
mineralAmt = 0
|
||||
stage = 3
|
||||
explosion(bombturf,1,2,5, adminlog = 0)
|
||||
if(stage == 2) //Gibtonite deposit is now benign and extractable. Depending on how close you were to it blowing up before defusing, you get better quality ore.
|
||||
var/obj/item/weapon/twohanded/required/gibtonite/G = new /obj/item/weapon/twohanded/required/gibtonite/(src)
|
||||
if(det_time <= 0)
|
||||
G.quality = 3
|
||||
G.icon_state = "Gibtonite ore 3"
|
||||
if(det_time >= 1 && det_time <= 2)
|
||||
G.quality = 2
|
||||
G.icon_state = "Gibtonite ore 2"
|
||||
|
||||
ChangeTurf(turf_type, defer_change)
|
||||
spawn(10)
|
||||
AfterChange()
|
||||
|
||||
/turf/closed/mineral/gibtonite/volcanic
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
|
||||
////////////////////////////////End Gibtonite
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave
|
||||
var/length = 100
|
||||
var/mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 1, /mob/living/simple_animal/hostile/asteroid/goliath = 5, /mob/living/simple_animal/hostile/asteroid/basilisk = 4, /mob/living/simple_animal/hostile/asteroid/hivelord = 3)
|
||||
var/sanity = 1
|
||||
turf_type = /turf/open/floor/plating/asteroid/airless
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/volcanic
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 10, /mob/living/simple_animal/hostile/asteroid/goliath/beast = 50, /mob/living/simple_animal/hostile/asteroid/basilisk/watcher = 40, /mob/living/simple_animal/hostile/asteroid/hivelord/legion = 30,
|
||||
/mob/living/simple_animal/hostile/spawner/lavaland = 2, /mob/living/simple_animal/hostile/spawner/lavaland/goliath = 3, /mob/living/simple_animal/hostile/spawner/lavaland/legion = 3, \
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon = 2, /mob/living/simple_animal/hostile/megafauna/bubblegum = 2, /mob/living/simple_animal/hostile/megafauna/colossus = 2)
|
||||
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/New(loc, length, go_backwards = 1, exclude_dir = -1)
|
||||
// If length (arg2) isn't defined, get a random length; otherwise assign our length to the length arg.
|
||||
if(!length)
|
||||
src.length = rand(25, 50)
|
||||
else
|
||||
src.length = length
|
||||
|
||||
// Get our directiosn
|
||||
var/forward_cave_dir = pick(alldirs - exclude_dir)
|
||||
// Get the opposite direction of our facing direction
|
||||
var/backward_cave_dir = angle2dir(dir2angle(forward_cave_dir) + 180)
|
||||
|
||||
// Make our tunnels
|
||||
make_tunnel(forward_cave_dir)
|
||||
if(go_backwards)
|
||||
make_tunnel(backward_cave_dir)
|
||||
// Kill ourselves by replacing ourselves with a normal floor.
|
||||
SpawnFloor(src)
|
||||
..()
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/make_tunnel(dir)
|
||||
|
||||
var/turf/closed/mineral/tunnel = src
|
||||
var/next_angle = pick(45, -45)
|
||||
|
||||
for(var/i = 0; i < length; i++)
|
||||
if(!sanity)
|
||||
break
|
||||
|
||||
var/list/L = list(45)
|
||||
if(IsOdd(dir2angle(dir))) // We're going at an angle and we want thick angled tunnels.
|
||||
L += -45
|
||||
|
||||
// Expand the edges of our tunnel
|
||||
for(var/edge_angle in L)
|
||||
var/turf/closed/mineral/edge = get_step(tunnel, angle2dir(dir2angle(dir) + edge_angle))
|
||||
if(istype(edge))
|
||||
SpawnFloor(edge)
|
||||
|
||||
// Move our tunnel forward
|
||||
tunnel = get_step(tunnel, dir)
|
||||
|
||||
if(istype(tunnel))
|
||||
// Small chance to have forks in our tunnel; otherwise dig our tunnel.
|
||||
if(i > 3 && prob(20))
|
||||
new src.type(tunnel, rand(10, 15), 0, dir)
|
||||
else
|
||||
SpawnFloor(tunnel)
|
||||
else //if(!istype(tunnel, src.parent)) // We hit space/normal/wall, stop our tunnel.
|
||||
break
|
||||
|
||||
// Chance to change our direction left or right.
|
||||
if(i > 2 && prob(33))
|
||||
// We can't go a full loop though
|
||||
next_angle = -next_angle
|
||||
setDir(angle2dir(dir2angle(dir) )+ next_angle)
|
||||
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/SpawnFloor(turf/T)
|
||||
for(var/turf/S in range(2,T))
|
||||
if(istype(S, /turf/open/space) || istype(S.loc, /area/mine/explored))
|
||||
sanity = 0
|
||||
break
|
||||
if(!sanity)
|
||||
return
|
||||
|
||||
SpawnMonster(T)
|
||||
new turf_type(T)
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/SpawnMonster(turf/T)
|
||||
if(prob(30))
|
||||
if(istype(loc, /area/mine/explored))
|
||||
return
|
||||
for(var/atom/A in urange(12,T))//Lowers chance of mob clumps
|
||||
if(istype(A, /mob/living/simple_animal/hostile/asteroid))
|
||||
return
|
||||
var/randumb = pickweight(mob_spawn_list)
|
||||
new randumb(T)
|
||||
return
|
||||
|
||||
/turf/closed/mineral/attackby(obj/item/weapon/pickaxe/P, mob/user, params)
|
||||
|
||||
if (!user.IsAdvancedToolUser())
|
||||
usr << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
||||
return
|
||||
|
||||
if (istype(P, /obj/item/weapon/pickaxe))
|
||||
var/turf/T = user.loc
|
||||
if (!( istype(T, /turf) ))
|
||||
return
|
||||
|
||||
if(last_act+P.digspeed > world.time)//prevents message spam
|
||||
return
|
||||
last_act = world.time
|
||||
user << "<span class='notice'>You start picking...</span>"
|
||||
P.playDigSound()
|
||||
|
||||
if(do_after(user,P.digspeed, target = src))
|
||||
if(istype(src, /turf/closed/mineral))
|
||||
user << "<span class='notice'>You finish cutting into the rock.</span>"
|
||||
gets_drilled(user)
|
||||
feedback_add_details("pick_used_mining","[P.type]")
|
||||
else
|
||||
return attack_hand(user)
|
||||
return
|
||||
|
||||
/turf/closed/mineral/proc/gets_drilled()
|
||||
if (mineralType && (src.mineralAmt > 0) && (src.mineralAmt < 11))
|
||||
var/i
|
||||
for (i=0;i<mineralAmt;i++)
|
||||
new mineralType(src)
|
||||
feedback_add_details("ore_mined","[mineralType]|[mineralAmt]")
|
||||
ChangeTurf(turf_type, defer_change)
|
||||
spawn(10)
|
||||
AfterChange()
|
||||
playsound(src, 'sound/effects/break_stone.ogg', 50, 1) //beautiful destruction
|
||||
return
|
||||
|
||||
/turf/closed/mineral/attack_animal(mob/living/simple_animal/user)
|
||||
if(user.environment_smash >= 2)
|
||||
gets_drilled()
|
||||
..()
|
||||
|
||||
/turf/closed/mineral/attack_alien(mob/living/carbon/alien/M)
|
||||
M << "<span class='notice'>You start digging into the rock...</span>"
|
||||
playsound(src, 'sound/effects/break_stone.ogg', 50, 1)
|
||||
if(do_after(M,40, target = src))
|
||||
M << "<span class='notice'>You tunnel into the rock.</span>"
|
||||
gets_drilled(M)
|
||||
|
||||
/turf/closed/mineral/Bumped(AM as mob|obj)
|
||||
..()
|
||||
if(istype(AM,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if((istype(H.l_hand,/obj/item/weapon/pickaxe)) && (!H.hand))
|
||||
src.attackby(H.l_hand,H)
|
||||
else if((istype(H.r_hand,/obj/item/weapon/pickaxe)) && H.hand)
|
||||
src.attackby(H.r_hand,H)
|
||||
return
|
||||
else if(istype(AM,/mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = AM
|
||||
if(istype(R.module_active,/obj/item/weapon/pickaxe))
|
||||
src.attackby(R.module_active,R)
|
||||
return
|
||||
/* else if(istype(AM,/obj/mecha))
|
||||
var/obj/mecha/M = AM
|
||||
if(istype(M.selected,/obj/item/mecha_parts/mecha_equipment/drill))
|
||||
src.attackby(M.selected,M)
|
||||
return*/
|
||||
//Aparantly mechs are just TOO COOL to call Bump(), so fuck em (for now)
|
||||
else
|
||||
return
|
||||
|
||||
/**********************Asteroid**************************/
|
||||
|
||||
/turf/open/floor/plating/asteroid //floor piece
|
||||
name = "asteroid sand"
|
||||
baseturf = /turf/open/floor/plating/asteroid
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "asteroid"
|
||||
icon_plating = "asteroid"
|
||||
var/environment_type = "asteroid"
|
||||
var/turf_type = /turf/open/floor/plating/asteroid //Because caves do whacky shit to revert to normal
|
||||
var/dug = 0 //0 = has not yet been dug, 1 = has already been dug
|
||||
var/sand_type = /obj/item/weapon/ore/glass
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless
|
||||
initial_gas_mix = "TEMP=2.7"
|
||||
turf_type = /turf/open/floor/plating/asteroid/airless
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt
|
||||
name = "volcanic floor"
|
||||
baseturf = /turf/open/floor/plating/asteroid/basalt
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "basalt"
|
||||
icon_plating = "basalt"
|
||||
environment_type = "basalt"
|
||||
sand_type = /obj/item/weapon/ore/glass/basalt
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt/lava //lava underneath
|
||||
baseturf = /turf/open/floor/plating/lava/smooth
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt/airless
|
||||
initial_gas_mix = "TEMP=2.7"
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow
|
||||
name = "snow"
|
||||
desc = "Looks cold."
|
||||
icon = 'icons/turf/snow.dmi'
|
||||
baseturf = /turf/open/floor/plating/asteroid/snow
|
||||
icon_state = "snow"
|
||||
icon_plating = "snow"
|
||||
initial_gas_mix = "TEMP=180"
|
||||
slowdown = 2
|
||||
environment_type = "snow"
|
||||
sand_type = /obj/item/stack/sheet/mineral/snow
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/airless
|
||||
initial_gas_mix = "TEMP=2.7"
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/temperatre
|
||||
initial_gas_mix = "TEMP=255.37"
|
||||
|
||||
/turf/open/floor/plating/asteroid/New()
|
||||
var/proper_name = name
|
||||
..()
|
||||
name = proper_name
|
||||
if(prob(20))
|
||||
icon_state = "[environment_type][rand(0,12)]"
|
||||
|
||||
/turf/open/floor/plating/asteroid/burn_tile()
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/asteroid/ex_act(severity, target)
|
||||
contents_explosion(severity, target)
|
||||
switch(severity)
|
||||
if(3)
|
||||
return
|
||||
if(2)
|
||||
if (prob(20))
|
||||
src.gets_dug()
|
||||
if(1)
|
||||
src.gets_dug()
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/asteroid/attackby(obj/item/weapon/W, mob/user, params)
|
||||
//note that this proc does not call ..()
|
||||
if(!W || !user)
|
||||
return 0
|
||||
var/digging_speed = 0
|
||||
if (istype(W, /obj/item/weapon/shovel))
|
||||
var/obj/item/weapon/shovel/S = W
|
||||
digging_speed = S.digspeed
|
||||
else if (istype(W, /obj/item/weapon/pickaxe))
|
||||
var/obj/item/weapon/pickaxe/P = W
|
||||
digging_speed = P.digspeed
|
||||
if (digging_speed)
|
||||
var/turf/T = user.loc
|
||||
if (!( istype(T, /turf) ))
|
||||
return
|
||||
|
||||
if (dug)
|
||||
user << "<span class='warning'>This area has already been dug!</span>"
|
||||
return
|
||||
|
||||
user << "<span class='notice'>You start digging...</span>"
|
||||
playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1)
|
||||
|
||||
if(do_after(user, digging_speed, target = src))
|
||||
if(istype(src, /turf/open/floor/plating/asteroid))
|
||||
user << "<span class='notice'>You dig a hole.</span>"
|
||||
gets_dug()
|
||||
feedback_add_details("pick_used_mining","[W.type]")
|
||||
|
||||
if(istype(W,/obj/item/weapon/storage/bag/ore))
|
||||
var/obj/item/weapon/storage/bag/ore/S = W
|
||||
if(S.collection_mode == 1)
|
||||
for(var/obj/item/weapon/ore/O in src.contents)
|
||||
O.attackby(W,user)
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/stack/tile))
|
||||
var/obj/item/stack/tile/Z = W
|
||||
if(!Z.use(1))
|
||||
return
|
||||
var/turf/open/floor/T = ChangeTurf(Z.turf_type)
|
||||
if(istype(Z,/obj/item/stack/tile/light)) //TODO: get rid of this ugly check somehow
|
||||
var/obj/item/stack/tile/light/L = Z
|
||||
var/turf/open/floor/light/F = T
|
||||
F.state = L.state
|
||||
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||
|
||||
/turf/open/floor/plating/asteroid/proc/gets_dug()
|
||||
if(dug)
|
||||
return
|
||||
for(var/i in 1 to 5)
|
||||
new sand_type(src)
|
||||
dug = 1
|
||||
icon_plating = "[environment_type]_dug"
|
||||
icon_state = "[environment_type]_dug"
|
||||
slowdown = 0
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/asteroid/singularity_act()
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/asteroid/singularity_pull(S, current_size)
|
||||
return
|
||||
|
||||
//////////////CHASM//////////////////
|
||||
|
||||
/turf/open/chasm
|
||||
name = "chasm"
|
||||
desc = "Watch your step."
|
||||
baseturf = /turf/open/chasm
|
||||
smooth = SMOOTH_TRUE | SMOOTH_BORDER
|
||||
icon = 'icons/turf/floors/Chasms.dmi'
|
||||
icon_state = "smooth"
|
||||
var/drop_x = 1
|
||||
var/drop_y = 1
|
||||
var/drop_z = 1
|
||||
|
||||
|
||||
/turf/open/chasm/Entered(atom/movable/AM)
|
||||
if(istype(AM, /obj/singularity) || istype(AM, /obj/item/projectile))
|
||||
return
|
||||
if(istype(AM, /obj/effect/portal))
|
||||
// Portals aren't affected by gravity. Probably.
|
||||
return
|
||||
// Flies right over the chasm
|
||||
if(istype(AM, /mob/living/simple_animal))
|
||||
// apparently only simple_animals can fly??
|
||||
var/mob/living/simple_animal/SA = AM
|
||||
if(SA.flying)
|
||||
return
|
||||
if(istype(AM, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(istype(H.belt, /obj/item/device/wormhole_jaunter))
|
||||
var/obj/item/device/wormhole_jaunter/J = H.belt
|
||||
// To freak out any bystanders
|
||||
visible_message("<span class='boldwarning'>[H] falls into [src]!</span>")
|
||||
J.chasm_react(H)
|
||||
return
|
||||
if(H.dna.species && (FLYING in H.dna.species.specflags))
|
||||
return
|
||||
drop(AM)
|
||||
|
||||
|
||||
/turf/open/chasm/proc/drop(atom/movable/AM)
|
||||
/*visible_message("[AM] falls into [src]!")
|
||||
qdel(AM)*/
|
||||
AM.forceMove(locate(drop_x, drop_y, drop_z))
|
||||
AM.visible_message("<span class='boldwarning'>[AM] falls from above!</span>", "<span class='userdanger'>GAH! Ah... where are you?</span>")
|
||||
if(istype(AM, /mob/living))
|
||||
var/mob/living/L = AM
|
||||
L.Weaken(5)
|
||||
L.adjustBruteLoss(30)
|
||||
|
||||
/turf/open/chasm/straight_down/New()
|
||||
..()
|
||||
drop_x = x
|
||||
drop_y = y
|
||||
if(z+1 <= world.maxz)
|
||||
drop_z = z+1
|
||||
|
||||
/**********************Lavaland Turfs**************************/
|
||||
|
||||
///////Surface. The surface is warm, but survivable without a suit. Internals are required. The floors break to chasms, which drop you into the underground.
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
planetary_atmos = TRUE
|
||||
baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface
|
||||
|
||||
/turf/open/chasm/straight_down/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
planetary_atmos = TRUE
|
||||
baseturf = /turf/open/chasm/straight_down/lava_land_surface
|
||||
|
||||
/turf/open/chasm/straight_down/lava_land_surface/drop(atom/movable/AM)
|
||||
if(!AM.invisibility)
|
||||
AM.visible_message("<span class='boldwarning'>[AM] falls into [src]!</span>", "<span class='userdanger'>You stumble and stare into an abyss before you. It stares back, and you fall \
|
||||
into the enveloping dark.</span>")
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
L.notransform = TRUE
|
||||
L.Stun(10)
|
||||
L.resting = TRUE
|
||||
animate(AM, transform = matrix() - matrix(), alpha = 0, color = rgb(0, 0, 0), time = 10)
|
||||
for(var/i in 1 to 5)
|
||||
AM.pixel_y--
|
||||
sleep(2)
|
||||
if(isrobot(AM))
|
||||
var/mob/living/silicon/robot/S = AM
|
||||
qdel(S.mmi)
|
||||
qdel(AM)
|
||||
|
||||
/turf/closed/mineral/volcanic/lava_land_surface
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface
|
||||
defer_change = 1
|
||||
|
||||
/turf/closed/mineral/random/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
defer_change = 1
|
||||
|
||||
mineralChance = 10
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/volcanic = 5, /turf/closed/mineral/diamond/volcanic = 1, /turf/closed/mineral/gold/volcanic = 10,
|
||||
/turf/closed/mineral/silver/volcanic = 12, /turf/closed/mineral/plasma/volcanic = 20, /turf/closed/mineral/iron/volcanic = 40,
|
||||
/turf/closed/mineral/gibtonite/volcanic = 4, /turf/open/floor/plating/asteroid/airless/cave/volcanic = 1, /turf/closed/mineral/bscrystal/volcanic = 1)
|
||||
|
||||
/turf/closed/mineral/random/high_chance/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
defer_change = 1
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/volcanic = 35, /turf/closed/mineral/diamond/volcanic = 30, /turf/closed/mineral/gold/volcanic = 45,
|
||||
/turf/closed/mineral/silver/volcanic = 50, /turf/closed/mineral/plasma/volcanic = 50, /turf/closed/mineral/bscrystal/volcanic = 20)
|
||||
|
||||
/turf/open/floor/plating/lava/smooth/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
planetary_atmos = TRUE
|
||||
baseturf = /turf/open/chasm/straight_down/lava_land_surface
|
||||
|
||||
/turf/closed/mineral/gibtonite/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
defer_change = 1
|
||||
|
||||
/turf/closed/mineral/uranium/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
defer_change = 1
|
||||
|
||||
/turf/closed/mineral/diamond/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
defer_change = 1
|
||||
|
||||
/turf/closed/mineral/gold/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
defer_change = 1
|
||||
|
||||
/turf/closed/mineral/silver/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
defer_change = 1
|
||||
|
||||
/turf/closed/mineral/plasma/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
defer_change = 1
|
||||
|
||||
/turf/closed/mineral/iron/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
defer_change = 1
|
||||
|
||||
/turf/closed/mineral/bscrystal/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
defer_change = 1
|
||||
|
||||
|
||||
//BECAUSE ONE PLANET WASNT ENOUGH
|
||||
|
||||
/turf/closed/mineral/ash_rock //wall piece
|
||||
name = "rock"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
smooth_icon = 'icons/turf/walls/rock_wall.dmi'
|
||||
icon_state = "rock"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/closed/mineral, /turf/closed/wall)
|
||||
baseturf = /turf/open/floor/plating/ash
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
environment_type = "waste"
|
||||
turf_type = /turf/open/floor/plating/ash
|
||||
defer_change = 1
|
||||
|
||||
/turf/open/floor/plating/ash
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
name = "ash"
|
||||
icon_state = "ash"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/open/floor/plating/ash, /turf/closed)
|
||||
var/smooth_icon = 'icons/turf/floors/ash.dmi'
|
||||
desc = "The ground is covered in volcanic ash."
|
||||
baseturf = /turf/open/floor/plating/ash //I assume this will be a chasm eventually, once this becomes an actual surface
|
||||
slowdown = 1
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
planetary_atmos = TRUE
|
||||
|
||||
/turf/open/floor/plating/ash/New()
|
||||
pixel_y = -4
|
||||
pixel_x = -4
|
||||
icon = smooth_icon
|
||||
..()
|
||||
|
||||
/turf/open/floor/plating/ash/break_tile()
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/ash/burn_tile()
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/ash/rocky
|
||||
name = "rocky ground"
|
||||
icon_state = "rockyash"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
smooth_icon = 'icons/turf/floors/rocky_ash.dmi'
|
||||
slowdown = 0
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/open/floor/plating/ash/rocky, /turf/closed)
|
||||
|
||||
//Necropolis
|
||||
|
||||
/turf/closed/indestructible/necropolis
|
||||
name = "necropolis wall"
|
||||
desc = "A seemingly impenetrable wall."
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
explosion_block = 50
|
||||
baseturf = /turf/closed/indestructible/necropolis
|
||||
|
||||
/turf/open/indestructible/necropolis
|
||||
name = "necropolis floor"
|
||||
desc = "It's regarding you suspiciously."
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "floor"
|
||||
baseturf = /turf/open/indestructible/necropolis
|
||||
|
||||
/turf/open/indestructible/necropolis/New()
|
||||
..()
|
||||
if(prob(12))
|
||||
icon_state = "necropolis[rand(1,2)]"
|
||||
@@ -1,198 +0,0 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
/obj/item/device/mmi
|
||||
name = "Man-Machine Interface"
|
||||
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity, that nevertheless has become standard-issue on Nanotrasen stations."
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
icon_state = "mmi_empty"
|
||||
w_class = 3
|
||||
origin_tech = "biotech=2;programming=3;engineering=2"
|
||||
var/braintype = "Cyborg"
|
||||
var/obj/item/device/radio/radio = null //Let's give it a radio.
|
||||
var/hacked = 0 //Whether or not this is a Syndicate MMI
|
||||
var/mob/living/carbon/brain/brainmob = null //The current occupant.
|
||||
var/mob/living/silicon/robot = null //Appears unused.
|
||||
var/obj/mecha = null //This does not appear to be used outside of reference in mecha.dm.
|
||||
var/obj/item/organ/brain/brain = null //The actual brain
|
||||
var/clockwork = FALSE //If this is a soul vessel
|
||||
|
||||
/obj/item/device/mmi/update_icon()
|
||||
if(brain)
|
||||
if(istype(brain,/obj/item/organ/brain/alien))
|
||||
if(brainmob && brainmob.stat == DEAD)
|
||||
icon_state = "mmi_alien_dead"
|
||||
else
|
||||
icon_state = "mmi_alien"
|
||||
braintype = "Xenoborg" //HISS....Beep.
|
||||
else
|
||||
if(brainmob && brainmob.stat == DEAD)
|
||||
icon_state = "mmi_dead"
|
||||
else
|
||||
icon_state = "mmi_full"
|
||||
braintype = "Cyborg"
|
||||
else
|
||||
icon_state = "mmi_empty"
|
||||
|
||||
/obj/item/device/mmi/New()
|
||||
..()
|
||||
radio = new(src) //Spawns a radio inside the MMI.
|
||||
radio.broadcasting = 0 //researching radio mmis turned the robofabs into radios because this didnt start as 0.
|
||||
|
||||
|
||||
|
||||
/obj/item/device/mmi/attackby(obj/item/O, mob/user, params)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if(istype(O,/obj/item/organ/brain)) //Time to stick a brain in it --NEO
|
||||
var/obj/item/organ/brain/newbrain = O
|
||||
if(brain)
|
||||
user << "<span class='warning'>There's already a brain in the MMI!</span>"
|
||||
return
|
||||
if(!newbrain.brainmob)
|
||||
user << "<span class='warning'>You aren't sure where this brain came from, but you're pretty sure it's a useless brain!</span>"
|
||||
return
|
||||
|
||||
if(!user.unEquip(O))
|
||||
return
|
||||
var/mob/living/carbon/brain/B = newbrain.brainmob
|
||||
if(!B.key)
|
||||
B.notify_ghost_cloning("Someone has put your brain in a MMI!", source = src)
|
||||
visible_message("[user] sticks \a [newbrain] into \the [src].")
|
||||
|
||||
brainmob = newbrain.brainmob
|
||||
newbrain.brainmob = null
|
||||
brainmob.loc = src
|
||||
brainmob.container = src
|
||||
if(!newbrain.damaged_brain) // the brain organ hasn't been beaten to death.
|
||||
brainmob.stat = CONSCIOUS //we manually revive the brain mob
|
||||
dead_mob_list -= brainmob
|
||||
living_mob_list += brainmob
|
||||
|
||||
brainmob.reset_perspective()
|
||||
if(clockwork)
|
||||
add_servant_of_ratvar(brainmob, TRUE)
|
||||
newbrain.loc = src //P-put your brain in it
|
||||
brain = newbrain
|
||||
|
||||
name = "Man-Machine Interface: [brainmob.real_name]"
|
||||
update_icon()
|
||||
|
||||
feedback_inc("cyborg_mmis_filled",1)
|
||||
|
||||
return
|
||||
|
||||
else if(brainmob)
|
||||
O.attack(brainmob, user) //Oh noooeeeee
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/device/mmi/attack_self(mob/user)
|
||||
if(!brain)
|
||||
radio.on = !radio.on
|
||||
user << "<span class='notice'>You toggle the MMI's radio system [radio.on==1 ? "on" : "off"].</span>"
|
||||
else
|
||||
user << "<span class='notice'>You unlock and upend the MMI, spilling the brain onto the floor.</span>"
|
||||
|
||||
brainmob.container = null //Reset brainmob mmi var.
|
||||
brainmob.loc = brain //Throw mob into brain.
|
||||
brainmob.stat = DEAD
|
||||
brainmob.emp_damage = 0
|
||||
brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision
|
||||
living_mob_list -= brainmob //Get outta here
|
||||
dead_mob_list += brainmob
|
||||
brain.brainmob = brainmob //Set the brain to use the brainmob
|
||||
brainmob = null //Set mmi brainmob var to null
|
||||
|
||||
user.put_in_hands(brain) //puts brain in the user's hand or otherwise drops it on the user's turf
|
||||
brain = null //No more brain in here
|
||||
|
||||
update_icon()
|
||||
name = "Man-Machine Interface"
|
||||
|
||||
/obj/item/device/mmi/proc/transfer_identity(mob/living/L) //Same deal as the regular brain proc. Used for human-->robot people.
|
||||
if(!brainmob)
|
||||
brainmob = new(src)
|
||||
brainmob.name = L.real_name
|
||||
brainmob.real_name = L.real_name
|
||||
if(L.has_dna())
|
||||
var/mob/living/carbon/C = L
|
||||
if(!brainmob.dna)
|
||||
brainmob.dna = new /datum/dna(brainmob)
|
||||
C.dna.copy_dna(brainmob.dna)
|
||||
brainmob.container = src
|
||||
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
var/obj/item/organ/brain/newbrain = H.getorgan(/obj/item/organ/brain)
|
||||
newbrain.loc = src
|
||||
brain = newbrain
|
||||
else if(!brain)
|
||||
brain = new(src)
|
||||
brain.name = "[L.real_name]'s brain"
|
||||
|
||||
name = "Man-Machine Interface: [brainmob.real_name]"
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/mmi/verb/Toggle_Listening()
|
||||
set name = "Toggle Listening"
|
||||
set desc = "Toggle listening channel on or off."
|
||||
set category = "MMI"
|
||||
set src = usr.loc
|
||||
set popup_menu = 0
|
||||
|
||||
if(brainmob.stat)
|
||||
brainmob << "<span class='warning'>Can't do that while incapacitated or dead!</span>"
|
||||
if(!radio.on)
|
||||
brainmob << "<span class='warning'>Your radio is disabled!</span>"
|
||||
return
|
||||
|
||||
radio.listening = radio.listening==1 ? 0 : 1
|
||||
brainmob << "<span class='notice'>Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast.</span>"
|
||||
|
||||
/obj/item/device/mmi/emp_act(severity)
|
||||
if(!brainmob)
|
||||
return
|
||||
else
|
||||
switch(severity)
|
||||
if(1)
|
||||
brainmob.emp_damage = min(brainmob.emp_damage + rand(20,30), 30)
|
||||
if(2)
|
||||
brainmob.emp_damage = min(brainmob.emp_damage + rand(10,20), 30)
|
||||
if(3)
|
||||
brainmob.emp_damage = min(brainmob.emp_damage + rand(0,10), 30)
|
||||
brainmob.emote("alarm")
|
||||
..()
|
||||
|
||||
/obj/item/device/mmi/Destroy()
|
||||
if(isrobot(loc))
|
||||
var/mob/living/silicon/robot/borg = loc
|
||||
borg.mmi = null
|
||||
if(brainmob)
|
||||
qdel(brainmob)
|
||||
brainmob = null
|
||||
return ..()
|
||||
|
||||
/obj/item/device/mmi/examine(mob/user)
|
||||
..()
|
||||
if(brainmob)
|
||||
var/mob/living/carbon/brain/B = brainmob
|
||||
if(!B.key || !B.mind || B.stat == DEAD)
|
||||
user << "<span class='warning'>The MMI indicates the brain is completely unresponsive.</span>"
|
||||
|
||||
else if(!B.client)
|
||||
user << "<span class='warning'>The MMI indicates the brain is currently inactive; it might change.</span>"
|
||||
|
||||
else
|
||||
user << "<span class='notice'>The MMI indicates the brain is active.</span>"
|
||||
|
||||
|
||||
/obj/item/device/mmi/syndie
|
||||
name = "Syndicate Man-Machine Interface"
|
||||
desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs created with it, but doesn't fit in Nanotrasen AI cores."
|
||||
origin_tech = "biotech=4;programming=4;syndicate=2"
|
||||
hacked = 1
|
||||
|
||||
/obj/item/device/mmi/syndie/New()
|
||||
..()
|
||||
radio.on = 0
|
||||
@@ -1,63 +0,0 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
/mob/living/carbon/brain
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
var/obj/item/device/mmi/container = null
|
||||
var/timeofhostdeath = 0
|
||||
var/emp_damage = 0//Handles a type of MMI damage
|
||||
has_limbs = 0
|
||||
stat = DEAD //we start dead by default
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
|
||||
/mob/living/carbon/brain/New(loc)
|
||||
..()
|
||||
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
|
||||
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
|
||||
src.loc = OB
|
||||
OB.brainmob = src
|
||||
|
||||
|
||||
/mob/living/carbon/brain/Destroy()
|
||||
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
|
||||
if(stat!=DEAD) //If not dead.
|
||||
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
|
||||
ghostize() //Ghostize checks for key so nothing else is necessary.
|
||||
container = null
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/brain/update_canmove()
|
||||
if(in_contents_of(/obj/mecha))
|
||||
canmove = 1
|
||||
else
|
||||
canmove = 0
|
||||
return canmove
|
||||
|
||||
/mob/living/carbon/brain/toggle_throw_mode()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/blob_act(obj/effect/blob/B)
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/check_ear_prot()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/brain/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
|
||||
return // no eyes, no flashing
|
||||
|
||||
/mob/living/carbon/brain/update_damage_hud()
|
||||
return //no red circles for brain
|
||||
|
||||
/mob/living/carbon/brain/can_be_revived()
|
||||
. = 1
|
||||
if(!container || health <= config.health_threshold_dead)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/brain/update_sight()
|
||||
return
|
||||
@@ -1,127 +0,0 @@
|
||||
/obj/item/organ/brain
|
||||
name = "brain"
|
||||
desc = "A piece of juicy meat found in a person's head."
|
||||
icon_state = "brain"
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
layer = ABOVE_MOB_LAYER
|
||||
zone = "head"
|
||||
slot = "brain"
|
||||
vital = 1
|
||||
origin_tech = "biotech=5"
|
||||
attack_verb = list("attacked", "slapped", "whacked")
|
||||
var/mob/living/carbon/brain/brainmob = null
|
||||
var/damaged_brain = 0 //whether the brain organ is damaged.
|
||||
|
||||
/obj/item/organ/brain/Insert(mob/living/carbon/M, special = 0)
|
||||
..()
|
||||
name = "brain"
|
||||
if(brainmob)
|
||||
if(M.key)
|
||||
M.ghostize()
|
||||
|
||||
if(brainmob.mind)
|
||||
brainmob.mind.transfer_to(M)
|
||||
else
|
||||
M.key = brainmob.key
|
||||
|
||||
qdel(brainmob)
|
||||
|
||||
//Update the body's icon so it doesnt appear debrained anymore
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_hair(0)
|
||||
|
||||
/obj/item/organ/brain/Remove(mob/living/carbon/M, special = 0)
|
||||
..()
|
||||
if(!special)
|
||||
transfer_identity(M)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_hair(0)
|
||||
|
||||
/obj/item/organ/brain/prepare_eat()
|
||||
return // Too important to eat.
|
||||
|
||||
/obj/item/organ/brain/proc/transfer_identity(mob/living/L)
|
||||
name = "[L.name]'s brain"
|
||||
brainmob = new(src)
|
||||
brainmob.name = L.real_name
|
||||
brainmob.real_name = L.real_name
|
||||
brainmob.timeofhostdeath = L.timeofdeath
|
||||
if(L.has_dna())
|
||||
var/mob/living/carbon/C = L
|
||||
if(!brainmob.dna)
|
||||
brainmob.dna = new /datum/dna(brainmob)
|
||||
C.dna.copy_dna(brainmob.dna)
|
||||
if(L.mind && L.mind.current && (L.mind.current.stat == DEAD))
|
||||
L.mind.transfer_to(brainmob)
|
||||
brainmob << "<span class='notice'>You feel slightly disoriented. That's normal when you're just a brain.</span>"
|
||||
|
||||
/obj/item/organ/brain/attackby(obj/item/O, mob/user, params)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if(brainmob)
|
||||
O.attack(brainmob, user) //Oh noooeeeee
|
||||
|
||||
/obj/item/organ/brain/examine(mob/user)
|
||||
..()
|
||||
|
||||
if(brainmob)
|
||||
if(brainmob.client)
|
||||
if(brainmob.health <= config.health_threshold_dead)
|
||||
user << "It's lifeless and severely damaged."
|
||||
else
|
||||
user << "You can feel the small spark of life still left in this one."
|
||||
else
|
||||
user << "This one seems particularly lifeless. Perhaps it will regain some of its luster later."
|
||||
else
|
||||
user << "This one is completely devoid of life."
|
||||
|
||||
/obj/item/organ/brain/attack(mob/living/carbon/M, mob/user)
|
||||
if(!istype(M))
|
||||
return ..()
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if(user.zone_selected != "head")
|
||||
return ..()
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(H) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
|
||||
user << "<span class='warning'>You're going to need to remove their head cover first!</span>"
|
||||
return
|
||||
|
||||
//since these people will be dead M != usr
|
||||
|
||||
if(!M.getorgan(/obj/item/organ/brain))
|
||||
if(istype(H) && !H.get_bodypart("head"))
|
||||
return
|
||||
user.drop_item()
|
||||
var/msg = "[M] has [src] inserted into \his head by [user]."
|
||||
if(M == user)
|
||||
msg = "[user] inserts [src] into \his head!"
|
||||
|
||||
M.visible_message("<span class='danger'>[msg]</span>",
|
||||
"<span class='userdanger'>[msg]</span>")
|
||||
|
||||
if(M != user)
|
||||
M << "<span class='notice'>[user] inserts [src] into your head.</span>"
|
||||
user << "<span class='notice'>You insert [src] into [M]'s head.</span>"
|
||||
else
|
||||
user << "<span class='notice'>You insert [src] into your head.</span>" //LOL
|
||||
|
||||
Insert(M)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/organ/brain/Destroy() //copypasted from MMIs.
|
||||
if(brainmob)
|
||||
qdel(brainmob)
|
||||
brainmob = null
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/brain/alien
|
||||
name = "alien brain"
|
||||
desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?"
|
||||
icon_state = "brain-x"
|
||||
origin_tech = "biotech=6"
|
||||
@@ -1,20 +0,0 @@
|
||||
/mob/living/carbon/brain/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
stat = DEAD
|
||||
|
||||
if(!gibbed && container)//If not gibbed but in a container.
|
||||
var/obj/item/device/mmi = container
|
||||
mmi.visible_message("<span class='warning'>[src]'s MMI flatlines!</span>", \
|
||||
"<span class='italics'>You hear something flatline.</span>")
|
||||
mmi.update_icon()
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/brain/gib()
|
||||
if(container)
|
||||
qdel(container)//Gets rid of the MMI if there is one
|
||||
if(loc)
|
||||
if(istype(loc,/obj/item/organ/brain))
|
||||
qdel(loc)//Gets rid of the brain item
|
||||
..()
|
||||
@@ -1,71 +0,0 @@
|
||||
/mob/living/carbon/brain/emote(act,m_type=1,message = null)
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))//No MMI, no emotes
|
||||
return
|
||||
|
||||
if (findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
|
||||
if(src.stat == DEAD)
|
||||
return
|
||||
switch(act)
|
||||
if ("alarm")
|
||||
src << "You sound an alarm."
|
||||
message = "<B>[src]</B> sounds an alarm."
|
||||
m_type = 2
|
||||
|
||||
if ("alert")
|
||||
src << "You let out a distressed noise."
|
||||
message = "<B>[src]</B> lets out a distressed noise."
|
||||
m_type = 2
|
||||
|
||||
if ("beep","beeps")
|
||||
src << "You beep."
|
||||
message = "<B>[src]</B> beeps."
|
||||
m_type = 2
|
||||
|
||||
if ("blink","blinks")
|
||||
message = "<B>[src]</B> blinks."
|
||||
m_type = 1
|
||||
|
||||
if ("boop","boops")
|
||||
src << "You boop."
|
||||
message = "<B>[src]</B> boops."
|
||||
m_type = 2
|
||||
|
||||
if ("flash")
|
||||
message = "The lights on <B>[src]</B> flash quickly."
|
||||
m_type = 1
|
||||
|
||||
if ("notice")
|
||||
src << "You play a loud tone."
|
||||
message = "<B>[src]</B> plays a loud tone."
|
||||
m_type = 2
|
||||
|
||||
if ("whistle","whistles")
|
||||
src << "You whistle."
|
||||
message = "<B>[src]</B> whistles."
|
||||
m_type = 2
|
||||
|
||||
if ("help")
|
||||
src << "Help for MMI emotes. You can use these emotes with say \"*emote\":\nalarm, alert, beep, blink, boop, flash, notice, whistle"
|
||||
|
||||
else
|
||||
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
|
||||
return
|
||||
|
||||
if (message)
|
||||
log_emote("[name]/[key] : [message]")
|
||||
|
||||
for(var/mob/M in dead_mob_list)
|
||||
if (!M.client || istype(M, /mob/new_player))
|
||||
continue //skip monkeys, leavers, and new_players
|
||||
if(M.stat == DEAD && (M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT)) && !(M in viewers(src,null)))
|
||||
M.show_message(message)
|
||||
|
||||
|
||||
if (m_type & 1)
|
||||
visible_message(message)
|
||||
else if (m_type & 2)
|
||||
audible_message(message)
|
||||
@@ -1,60 +0,0 @@
|
||||
|
||||
/mob/living/carbon/brain/Life()
|
||||
set invisibility = 0
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if (notransform)
|
||||
return
|
||||
if(!loc)
|
||||
return
|
||||
. = ..()
|
||||
handle_emp_damage()
|
||||
|
||||
/mob/living/carbon/brain/handle_breathing()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_mutations_and_radiation()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_environment(datum/gas_mixture/environment)
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/update_stat()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
if(health <= config.health_threshold_dead)
|
||||
if(stat != DEAD)
|
||||
death()
|
||||
var/obj/item/organ/brain/BR
|
||||
if(container && container.brain)
|
||||
BR = container.brain
|
||||
else if(istype(loc, /obj/item/organ/brain))
|
||||
BR = loc
|
||||
if(BR)
|
||||
BR.damaged_brain = 1 //beaten to a pulp
|
||||
|
||||
/* //currently unused feature, since brain outside a mmi is always dead.
|
||||
/mob/living/carbon/brain/proc/handle_brain_revival_life()
|
||||
if(stat != DEAD)
|
||||
if(config.revival_brain_life != -1)
|
||||
if( !container && (world.time - timeofhostdeath) > config.revival_brain_life)
|
||||
death()
|
||||
*/
|
||||
|
||||
/mob/living/carbon/brain/proc/handle_emp_damage()
|
||||
if(emp_damage)
|
||||
if(stat == DEAD)
|
||||
emp_damage = 0
|
||||
else
|
||||
emp_damage = max(emp_damage-1, 0)
|
||||
|
||||
/mob/living/carbon/brain/handle_status_effects()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_disabilities()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_changeling()
|
||||
return
|
||||
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
var/global/posibrain_notif_cooldown = 0
|
||||
|
||||
/obj/item/device/mmi/posibrain
|
||||
name = "positronic brain"
|
||||
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves."
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
icon_state = "posibrain"
|
||||
w_class = 3
|
||||
origin_tech = "biotech=3;programming=3;plasmatech=2"
|
||||
var/notified = 0
|
||||
var/askDelay = 600 //one minute
|
||||
var/used = 0 //Prevents split personality virus. May be reset if personality deletion code is added.
|
||||
brainmob = null
|
||||
req_access = list(access_robotics)
|
||||
mecha = null//This does not appear to be used outside of reference in mecha.dm.
|
||||
braintype = "Android"
|
||||
var/begin_activation_message = "<span class='notice'>You carefully locate the manual activation switch and start the positronic brain's boot process.</span>"
|
||||
var/success_message = "<span class='notice'>The positronic brain pings, and its lights start flashing. Success!</span>"
|
||||
var/fail_message = "<span class='notice'>The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?</span>"
|
||||
var/new_role = "Positronic Brain"
|
||||
var/welcome_message = "<span class='warning'>ALL PAST LIVES ARE FORGOTTEN.</span>\n\
|
||||
<b>You are a positronic brain, brought into existence aboard Space Station 13.\n\
|
||||
As a synthetic intelligence, you answer to all crewmembers and the AI.\n\
|
||||
Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.</b>"
|
||||
var/new_mob_message = "<span class='notice'>The positronic brain chimes quietly.</span>"
|
||||
var/dead_message = "<span class='deadsay'>It appears to be completely inactive. The reset light is blinking.</span>"
|
||||
var/list/fluff_names = list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","JNLG","KOS","TKRG","XAL","STLP","CBOS","DUNC","FXMC","DRSD")
|
||||
|
||||
|
||||
/obj/item/device/mmi/posibrain/Topic(href, href_list)
|
||||
if(href_list["activate"])
|
||||
var/mob/dead/observer/ghost = usr
|
||||
if(istype(ghost))
|
||||
activate(ghost)
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/ping_ghosts(msg, newlymade)
|
||||
if(newlymade || !posibrain_notif_cooldown)
|
||||
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/effects/ghost2.ogg':null, enter_link = "<a href=?src=\ref[src];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK)
|
||||
if(!newlymade)
|
||||
posibrain_notif_cooldown = 1
|
||||
addtimer(src, "reset_posibrain_cooldown", askDelay, FALSE)
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/reset_posibrain_cooldown()
|
||||
posibrain_notif_cooldown = 0
|
||||
|
||||
/obj/item/device/mmi/posibrain/attack_self(mob/user)
|
||||
if(brainmob && !brainmob.key && !notified)
|
||||
//Start the process of requesting a new ghost.
|
||||
user << begin_activation_message
|
||||
ping_ghosts("requested", FALSE)
|
||||
notified = 1
|
||||
used = 0
|
||||
update_icon()
|
||||
spawn(askDelay) //Seperate from the global cooldown.
|
||||
notified = 0
|
||||
update_icon()
|
||||
if(brainmob.client)
|
||||
visible_message(success_message)
|
||||
else
|
||||
visible_message(fail_message)
|
||||
|
||||
return //Code for deleting personalities recommended here.
|
||||
|
||||
|
||||
/obj/item/device/mmi/posibrain/attack_ghost(mob/user)
|
||||
activate(user)
|
||||
|
||||
//Two ways to activate a positronic brain. A clickable link in the ghost notif, or simply clicking the object itself.
|
||||
/obj/item/device/mmi/posibrain/proc/activate(mob/user)
|
||||
if(used || (brainmob && brainmob.key) || jobban_isbanned(user,"posibrain"))
|
||||
return
|
||||
|
||||
var/posi_ask = alert("Become a [name]? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No")
|
||||
if(posi_ask == "No" || qdeleted(src))
|
||||
return
|
||||
transfer_personality(user)
|
||||
|
||||
/obj/item/device/mmi/posibrain/transfer_identity(mob/living/carbon/C)
|
||||
name = "[initial(name)] ([C])"
|
||||
brainmob.name = C.real_name
|
||||
brainmob.real_name = C.real_name
|
||||
brainmob.dna = C.dna
|
||||
if(C.has_dna())
|
||||
if(!brainmob.dna)
|
||||
brainmob.dna = new /datum/dna(brainmob)
|
||||
C.dna.copy_dna(brainmob.dna)
|
||||
brainmob.timeofhostdeath = C.timeofdeath
|
||||
brainmob.stat = CONSCIOUS
|
||||
if(brainmob.mind)
|
||||
brainmob.mind.assigned_role = new_role
|
||||
if(C.mind)
|
||||
C.mind.transfer_to(brainmob)
|
||||
|
||||
brainmob.mind.remove_all_antag()
|
||||
brainmob.mind.wipe_memory()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/transfer_personality(mob/candidate)
|
||||
if(used || (brainmob && brainmob.key)) //Prevents hostile takeover if two ghosts get the prompt or link for the same brain.
|
||||
candidate << "This brain has already been taken! Please try your possesion again later!"
|
||||
return
|
||||
notified = 0
|
||||
brainmob.ckey = candidate.ckey
|
||||
name = "[initial(name)] ([brainmob.name])"
|
||||
brainmob << welcome_message
|
||||
brainmob.mind.assigned_role = new_role
|
||||
brainmob.stat = CONSCIOUS
|
||||
dead_mob_list -= brainmob
|
||||
living_mob_list += brainmob
|
||||
if(clockwork)
|
||||
add_servant_of_ratvar(brainmob, TRUE)
|
||||
|
||||
visible_message(new_mob_message)
|
||||
update_icon()
|
||||
used = 1
|
||||
|
||||
|
||||
/obj/item/device/mmi/posibrain/examine()
|
||||
|
||||
set src in oview()
|
||||
|
||||
if(!usr || !src)
|
||||
return
|
||||
if( (usr.disabilities & BLIND || usr.stat) && !istype(usr,/mob/dead/observer) )
|
||||
usr << "<span class='notice'>Something is there but you can't see it.</span>"
|
||||
return
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n[desc]\n"
|
||||
msg += "<span class='warning'>"
|
||||
|
||||
if(brainmob && brainmob.key)
|
||||
switch(brainmob.stat)
|
||||
if(CONSCIOUS)
|
||||
if(!src.brainmob.client)
|
||||
msg += "It appears to be in stand-by mode.\n" //afk
|
||||
if(DEAD)
|
||||
msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
|
||||
else
|
||||
msg += "[dead_message]\n"
|
||||
msg += "<span class='info'>*---------*</span>"
|
||||
usr << msg
|
||||
return
|
||||
|
||||
/obj/item/device/mmi/posibrain/New()
|
||||
brainmob = new(src)
|
||||
brainmob.name = "[pick(fluff_names)]-[rand(100, 999)]"
|
||||
brainmob.real_name = brainmob.name
|
||||
brainmob.loc = src
|
||||
brainmob.container = src
|
||||
ping_ghosts("created", TRUE)
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/device/mmi/posibrain/attackby(obj/item/O, mob/user)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/mmi/posibrain/update_icon()
|
||||
if(notified)
|
||||
icon_state = "[initial(icon_state)]-searching"
|
||||
return
|
||||
if(brainmob && brainmob.key)
|
||||
icon_state = "[initial(icon_state)]-occupied"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
@@ -1,23 +0,0 @@
|
||||
/mob/living/carbon/brain/say(message)
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
return //No MMI, can't speak, bucko./N
|
||||
else
|
||||
if(prob(emp_damage*4))
|
||||
if(prob(10))//10% chane to drop the message entirely
|
||||
return
|
||||
else
|
||||
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
|
||||
..()
|
||||
|
||||
/mob/living/carbon/brain/radio(message, message_mode, list/spans)
|
||||
if(message_mode && istype(container, /obj/item/device/mmi))
|
||||
var/obj/item/device/mmi/R = container
|
||||
if(R.radio)
|
||||
R.radio.talk_into(src, message, , spans)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
/mob/living/carbon/brain/lingcheck()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/brain/treat_message(message)
|
||||
return message
|
||||
@@ -1,38 +0,0 @@
|
||||
//Here are the procs used to modify status effects of a mob.
|
||||
//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, ear damage,
|
||||
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability.
|
||||
|
||||
/////////////////////////////////// EAR DAMAGE ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/adjustEarDamage()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/setEarDamage() // no ears to damage or heal
|
||||
return
|
||||
|
||||
/////////////////////////////////// EYE_BLIND ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/blind_eyes() // no eyes to damage or heal
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/adjust_blindness()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/set_blindness()
|
||||
return
|
||||
|
||||
/////////////////////////////////// EYE_BLURRY ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/blur_eyes()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/adjust_blurriness()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/set_blurriness()
|
||||
return
|
||||
|
||||
/////////////////////////////////// BLIND DISABILITY ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/become_blind()
|
||||
return
|
||||
@@ -1,49 +0,0 @@
|
||||
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(check_shields(0, M.name))
|
||||
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
|
||||
return 0
|
||||
|
||||
if(..())
|
||||
if(M.a_intent == "harm")
|
||||
if (w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
var/damage = prob(90) ? 20 : 0
|
||||
if(!damage)
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has lunged at [src]!</span>")
|
||||
return 0
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
var/armor_block = run_armor_check(affecting, "melee","","",10)
|
||||
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
if (prob(30))
|
||||
visible_message("<span class='danger'>[M] has wounded [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has wounded [src]!</span>")
|
||||
apply_effect(4, WEAKEN, armor_block)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
|
||||
if(M.a_intent == "disarm")
|
||||
var/randn = rand(1, 100)
|
||||
if (randn <= 80)
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
Weaken(5)
|
||||
add_logs(M, src, "tackled")
|
||||
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [src]!</span>")
|
||||
else
|
||||
if (randn <= 99)
|
||||
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
|
||||
drop_item()
|
||||
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] disarmed [src]!</span>")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has tried to disarm [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tried to disarm [src]!</span>")
|
||||
return
|
||||
@@ -1,14 +0,0 @@
|
||||
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user)
|
||||
if(user.a_intent == "harm")
|
||||
..(user, 1)
|
||||
playsound(loc, user.dna.species.attack_sound, 25, 1, -1)
|
||||
var/hulk_verb = pick("smash","pummel")
|
||||
visible_message("<span class='danger'>[user] has [hulk_verb]ed [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [hulk_verb]ed [src]!</span>")
|
||||
adjustBruteLoss(15)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M)
|
||||
if(..()) //to allow surgery to return properly.
|
||||
return
|
||||
dna.species.spec_attack_hand(M, src)
|
||||
@@ -1,15 +0,0 @@
|
||||
/mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M)
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
|
||||
if(M.a_intent == "help")
|
||||
..() //shaking
|
||||
return 0
|
||||
|
||||
if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites.
|
||||
if(..()) //successful monkey bite, this handles disease contraction.
|
||||
var/damage = rand(1, 3)
|
||||
if(stat != DEAD)
|
||||
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
updatehealth()
|
||||
return 1
|
||||
@@ -1,161 +0,0 @@
|
||||
//Updates the mob's health from bodyparts and mob damage variables
|
||||
/mob/living/carbon/human/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
var/total_burn = 0
|
||||
var/total_brute = 0
|
||||
for(var/X in bodyparts) //hardcoded to streamline things a bit
|
||||
var/obj/item/bodypart/BP = X
|
||||
total_brute += BP.brute_dam
|
||||
total_burn += BP.burn_dam
|
||||
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
|
||||
update_stat()
|
||||
if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD )
|
||||
ChangeToHusk()
|
||||
if(on_fire)
|
||||
shred_clothing()
|
||||
med_hud_set_health()
|
||||
med_hud_set_status()
|
||||
|
||||
|
||||
//These procs fetch a cumulative total damage from all bodyparts
|
||||
/mob/living/carbon/human/getBruteLoss()
|
||||
var/amount = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
amount += BP.brute_dam
|
||||
return amount
|
||||
|
||||
/mob/living/carbon/human/getFireLoss()
|
||||
var/amount = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
amount += BP.burn_dam
|
||||
return amount
|
||||
|
||||
|
||||
/mob/living/carbon/human/adjustBruteLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
if(amount > 0)
|
||||
take_overall_damage(amount, 0)
|
||||
else
|
||||
heal_overall_damage(-amount, 0)
|
||||
|
||||
/mob/living/carbon/human/adjustFireLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
if(amount > 0)
|
||||
take_overall_damage(0, amount)
|
||||
else
|
||||
heal_overall_damage(0, -amount)
|
||||
|
||||
/mob/living/carbon/human/proc/hat_fall_prob()
|
||||
var/multiplier = 1
|
||||
var/obj/item/clothing/head/H = head
|
||||
var/loose = 40
|
||||
if(stat || (status_flags & FAKEDEATH))
|
||||
multiplier = 2
|
||||
if(H.flags_cover & (HEADCOVERSEYES | HEADCOVERSMOUTH) || H.flags_inv & (HIDEEYES | HIDEFACE))
|
||||
loose = 0
|
||||
return loose * multiplier
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
//Returns a list of damaged bodyparts
|
||||
/mob/living/carbon/human/proc/get_damaged_bodyparts(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if((brute && BP.brute_dam) || (burn && BP.burn_dam))
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
//Returns a list of damageable bodyparts
|
||||
/mob/living/carbon/human/proc/get_damageable_bodyparts()
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(BP.brute_dam + BP.burn_dam < BP.max_damage)
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
//Heals ONE external organ, organ gets randomly selected from damaged ones.
|
||||
//It automatically updates damage overlays if necesary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/human/heal_organ_damage(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
|
||||
if(!parts.len)
|
||||
return
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
if(picked.heal_damage(brute,burn,0))
|
||||
update_damage_overlays(0)
|
||||
updatehealth()
|
||||
|
||||
//Damages ONE external organ, organ gets randomly selected from damagable ones.
|
||||
//It automatically updates damage overlays if necesary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/human/take_organ_damage(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
|
||||
if(!parts.len)
|
||||
return
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
if(picked.take_damage(brute,burn))
|
||||
update_damage_overlays(0)
|
||||
updatehealth()
|
||||
|
||||
|
||||
//Heal MANY bodyparts, in random order
|
||||
/mob/living/carbon/human/heal_overall_damage(brute, burn, updating_health=1)
|
||||
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
|
||||
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
|
||||
update |= picked.heal_damage(brute,burn,0)
|
||||
|
||||
brute -= (brute_was-picked.brute_dam)
|
||||
burn -= (burn_was-picked.burn_dam)
|
||||
|
||||
parts -= picked
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
if(update)
|
||||
update_damage_overlays(0)
|
||||
|
||||
// damage MANY bodyparts, in random order
|
||||
/mob/living/carbon/human/take_overall_damage(brute, burn)
|
||||
if(status_flags & GODMODE)
|
||||
return //godmode
|
||||
|
||||
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
var/brute_per_part = brute/parts.len
|
||||
var/burn_per_part = burn/parts.len
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
|
||||
|
||||
update |= picked.take_damage(brute_per_part,burn_per_part)
|
||||
|
||||
brute -= (picked.brute_dam - brute_was)
|
||||
burn -= (picked.burn_dam - burn_was)
|
||||
|
||||
parts -= picked
|
||||
updatehealth()
|
||||
if(update)
|
||||
update_damage_overlays(0)
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
|
||||
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
|
||||
// depending on the species, it will run the corresponding apply_damage code there
|
||||
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,82 +0,0 @@
|
||||
/mob/living/carbon/monkey/emote(act,m_type=1,message = null)
|
||||
if(stat == DEAD && (act != "deathgasp") || (status_flags & FAKEDEATH)) //if we're faking, don't emote at all
|
||||
return
|
||||
|
||||
var/param = null
|
||||
if (findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
var/muzzled = is_muzzled()
|
||||
|
||||
switch(act) //Ooh ooh ah ah keep this alphabetical ooh ooh ah ah!
|
||||
if ("deathgasp","deathgasps")
|
||||
message = "<b>[src]</b> lets out a faint chimper as it collapses and stops moving..."
|
||||
m_type = 1
|
||||
|
||||
if ("gnarl","gnarls")
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> gnarls and shows its teeth.."
|
||||
m_type = 2
|
||||
|
||||
if ("me")
|
||||
..()
|
||||
return
|
||||
|
||||
if ("moan","moans")
|
||||
message = "<B>[src]</B> moans!"
|
||||
m_type = 2
|
||||
|
||||
if ("paw")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flails its paw."
|
||||
m_type = 1
|
||||
|
||||
if ("roar","roars")
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> roars."
|
||||
m_type = 2
|
||||
|
||||
if ("roll","rolls")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> rolls."
|
||||
m_type = 1
|
||||
|
||||
if ("scratch","scratches")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> scratches."
|
||||
m_type = 1
|
||||
|
||||
if ("screech","screeches")
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> screeches."
|
||||
m_type = 2
|
||||
|
||||
if ("shiver","shivers")
|
||||
message = "<B>[src]</B> shivers."
|
||||
m_type = 2
|
||||
|
||||
if ("sign","signs")
|
||||
if (!src.restrained())
|
||||
message = text("<B>[src]</B> signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
|
||||
m_type = 1
|
||||
|
||||
if ("tail")
|
||||
message = "<B>[src]</B> waves its tail."
|
||||
m_type = 1
|
||||
|
||||
if ("help") //Ooh ah ooh ooh this is an exception to alphabetical ooh ooh.
|
||||
src << "Help for monkey emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, dance, deathgasp, drool, flap, frown, gasp, gnarl, giggle, glare-(none)/mob, grin, jump, laugh, look, me, moan, nod, paw, point-(atom), roar, roll, scream, scratch, screech, shake, shiver, sigh, sign-#, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tail, tremble, twitch, twitch_s, wave whimper, wink, yawn"
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
if ((message && src.stat == 0))
|
||||
if(src.client)
|
||||
log_emote("[name]/[key] : [message]")
|
||||
if (m_type & 1)
|
||||
visible_message(message)
|
||||
else
|
||||
audible_message(message)
|
||||
return
|
||||
@@ -1,16 +0,0 @@
|
||||
/turf/open/floor/engine/attack_paw(mob/user)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/turf/open/floor/engine/attack_hand(mob/user)
|
||||
user.Move_Pulled(src)
|
||||
|
||||
/turf/open/floor/engine/ex_act(severity, target)
|
||||
contents_explosion(severity, target)
|
||||
switch(severity)
|
||||
if(1)
|
||||
ChangeTurf(src.baseturf)
|
||||
if(2)
|
||||
if(prob(50))
|
||||
ChangeTurf(src.baseturf)
|
||||
else
|
||||
return
|
||||
@@ -1,69 +0,0 @@
|
||||
/obj/item/ammo_box/a357
|
||||
name = "speed loader (.357)"
|
||||
desc = "Designed to quickly reload revolvers."
|
||||
icon_state = "357"
|
||||
ammo_type = /obj/item/ammo_casing/a357
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/c38
|
||||
name = "speed loader (.38)"
|
||||
desc = "Designed to quickly reload revolvers."
|
||||
icon_state = "38"
|
||||
ammo_type = /obj/item/ammo_casing/c38
|
||||
max_ammo = 6
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/c9mm
|
||||
name = "ammo box (9mm)"
|
||||
icon_state = "9mmbox"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
max_ammo = 30
|
||||
|
||||
/obj/item/ammo_box/c10mm
|
||||
name = "ammo box (10mm)"
|
||||
icon_state = "10mmbox"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/c10mm
|
||||
max_ammo = 20
|
||||
|
||||
/obj/item/ammo_box/c45
|
||||
name = "ammo box (.45)"
|
||||
icon_state = "45box"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/c45
|
||||
max_ammo = 20
|
||||
|
||||
/obj/item/ammo_box/a40mm
|
||||
name = "ammo box (40mm grenades)"
|
||||
icon_state = "40mm"
|
||||
ammo_type = /obj/item/ammo_casing/a40mm
|
||||
max_ammo = 4
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/a762
|
||||
name = "stripper clip (7.62mm)"
|
||||
desc = "A stripper clip."
|
||||
icon_state = "762"
|
||||
ammo_type = /obj/item/ammo_casing/a762
|
||||
max_ammo = 5
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/n762
|
||||
name = "ammo box (7.62x38mmR)"
|
||||
icon_state = "10mmbox"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/n762
|
||||
max_ammo = 14
|
||||
|
||||
/obj/item/ammo_box/foambox
|
||||
name = "ammo box (Foam Darts)"
|
||||
icon = 'icons/obj/guns/toy.dmi'
|
||||
icon_state = "foambox"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart
|
||||
max_ammo = 40
|
||||
|
||||
/obj/item/ammo_box/foambox/riot
|
||||
icon_state = "foambox_riot"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
|
||||
@@ -1,499 +0,0 @@
|
||||
////////////////INTERNAL MAGAZINES//////////////////////
|
||||
|
||||
/obj/item/ammo_box/magazine/internal
|
||||
desc = "Oh god, this shouldn't be here"
|
||||
|
||||
//internals magazines are accessible, so replace spent ammo if full when trying to put a live one in
|
||||
/obj/item/ammo_box/magazine/internal/give_round(obj/item/ammo_casing/R)
|
||||
return ..(R,1)
|
||||
|
||||
|
||||
|
||||
// Revolver internal mags
|
||||
/obj/item/ammo_box/magazine/internal/cylinder
|
||||
name = "revolver cylinder"
|
||||
ammo_type = /obj/item/ammo_casing/a357
|
||||
caliber = "357"
|
||||
max_ammo = 7
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/cylinder/ammo_count(countempties = 1)
|
||||
var/boolets = 0
|
||||
for(var/obj/item/ammo_casing/bullet in stored_ammo)
|
||||
if(bullet && (bullet.BB || countempties))
|
||||
boolets++
|
||||
|
||||
return boolets
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/cylinder/get_round(keep = 0)
|
||||
rotate()
|
||||
|
||||
var/b = stored_ammo[1]
|
||||
if(!keep)
|
||||
stored_ammo[1] = null
|
||||
|
||||
return b
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/cylinder/proc/rotate()
|
||||
var/b = stored_ammo[1]
|
||||
stored_ammo.Cut(1,2)
|
||||
stored_ammo.Insert(0, b)
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/cylinder/proc/spin()
|
||||
for(var/i in 1 to rand(0, max_ammo*2))
|
||||
rotate()
|
||||
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/cylinder/give_round(obj/item/ammo_casing/R, replace_spent = 0)
|
||||
if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type))
|
||||
return 0
|
||||
|
||||
for(var/i in 1 to stored_ammo.len)
|
||||
var/obj/item/ammo_casing/bullet = stored_ammo[i]
|
||||
if(!bullet || !bullet.BB) // found a spent ammo
|
||||
stored_ammo[i] = R
|
||||
R.loc = src
|
||||
|
||||
if(bullet)
|
||||
bullet.loc = get_turf(src.loc)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/cylinder/rev38
|
||||
name = "detective revolver cylinder"
|
||||
ammo_type = /obj/item/ammo_casing/c38
|
||||
caliber = "38"
|
||||
max_ammo = 6
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/cylinder/grenademulti
|
||||
name = "grenade launcher internal magazine"
|
||||
ammo_type = /obj/item/ammo_casing/a40mm
|
||||
caliber = "40mm"
|
||||
max_ammo = 6
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/cylinder/rev762
|
||||
name = "nagant revolver cylinder"
|
||||
ammo_type = /obj/item/ammo_casing/n762
|
||||
caliber = "n762"
|
||||
max_ammo = 7
|
||||
|
||||
// Shotgun internal mags
|
||||
/obj/item/ammo_box/magazine/internal/shot
|
||||
name = "shotgun internal magazine"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/beanbag
|
||||
caliber = "shotgun"
|
||||
max_ammo = 4
|
||||
multiload = 0
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/shot/ammo_count(countempties = 1)
|
||||
if (!countempties)
|
||||
var/boolets = 0
|
||||
for(var/obj/item/ammo_casing/bullet in stored_ammo)
|
||||
if(bullet.BB)
|
||||
boolets++
|
||||
return boolets
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/shot/tube
|
||||
name = "dual feed shotgun internal tube"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/rubbershot
|
||||
max_ammo = 4
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/shot/lethal
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/shot/com
|
||||
name = "combat shotgun internal magazine"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
|
||||
max_ammo = 6
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/shot/dual
|
||||
name = "double-barrel shotgun internal magazine"
|
||||
max_ammo = 2
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/shot/improvised
|
||||
name = "improvised shotgun internal magazine"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/improvised
|
||||
max_ammo = 1
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/shot/riot
|
||||
name = "riot shotgun internal magazine"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/rubbershot
|
||||
max_ammo = 6
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/grenadelauncher
|
||||
name = "grenade launcher internal magazine"
|
||||
ammo_type = /obj/item/ammo_casing/a40mm
|
||||
caliber = "40mm"
|
||||
max_ammo = 1
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/speargun
|
||||
name = "speargun internal magazine"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/magspear
|
||||
caliber = "speargun"
|
||||
max_ammo = 1
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/rus357
|
||||
name = "russian revolver cylinder"
|
||||
ammo_type = /obj/item/ammo_casing/a357
|
||||
caliber = "357"
|
||||
max_ammo = 6
|
||||
multiload = 0
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/rus357/New()
|
||||
stored_ammo += new ammo_type(src)
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/boltaction
|
||||
name = "bolt action rifle internal magazine"
|
||||
desc = "Oh god, this shouldn't be here"
|
||||
ammo_type = /obj/item/ammo_casing/a762
|
||||
caliber = "a762"
|
||||
max_ammo = 5
|
||||
multiload = 1
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/boltaction/enchanted
|
||||
max_ammo =1
|
||||
ammo_type = /obj/item/ammo_casing/a762/enchanted
|
||||
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/shot/toy
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart
|
||||
caliber = "foam_force"
|
||||
max_ammo = 4
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/shot/toy/crossbow
|
||||
max_ammo = 5
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/minigun
|
||||
name = "gatling gun fusion core"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/laser/gatling
|
||||
caliber = "gatling"
|
||||
max_ammo = 5000
|
||||
|
||||
|
||||
|
||||
///////////EXTERNAL MAGAZINES////////////////
|
||||
|
||||
/obj/item/ammo_box/magazine/m10mm
|
||||
name = "pistol magazine (10mm)"
|
||||
desc = "A gun magazine."
|
||||
icon_state = "9x19p"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/c10mm
|
||||
caliber = "10mm"
|
||||
max_ammo = 8
|
||||
multiple_sprites = 2
|
||||
|
||||
/obj/item/ammo_box/magazine/m45
|
||||
name = "handgun magazine (.45)"
|
||||
icon_state = "45-8"
|
||||
ammo_type = /obj/item/ammo_casing/c45
|
||||
caliber = ".45"
|
||||
max_ammo = 8
|
||||
|
||||
/obj/item/ammo_box/magazine/m45/update_icon()
|
||||
..()
|
||||
icon_state = "45-[ammo_count() ? "8" : "0"]"
|
||||
|
||||
/obj/item/ammo_box/magazine/wt550m9
|
||||
name = "wt550 magazine (4.6x30mm)"
|
||||
icon_state = "46x30mmt-20"
|
||||
ammo_type = /obj/item/ammo_casing/c46x30mm
|
||||
caliber = "4.6x30mm"
|
||||
max_ammo = 20
|
||||
|
||||
/obj/item/ammo_box/magazine/wt550m9/update_icon()
|
||||
..()
|
||||
icon_state = "46x30mmt-[round(ammo_count(),4)]"
|
||||
|
||||
/obj/item/ammo_box/magazine/wt550m9/wtap
|
||||
name = "wt550 magazine (Armour Piercing 4.6x30mm)"
|
||||
ammo_type = /obj/item/ammo_casing/c46x30mmap
|
||||
|
||||
/obj/item/ammo_box/magazine/wt550m9/wttx
|
||||
name = "wt550 magazine (Toxin Tipped 4.6x30mm)"
|
||||
ammo_type = /obj/item/ammo_casing/c46x30mmtox
|
||||
|
||||
/obj/item/ammo_box/magazine/wt550m9/wtic
|
||||
name = "wt550 magazine (Incindiary 4.6x30mm)"
|
||||
ammo_type = /obj/item/ammo_casing/c46x30mminc
|
||||
|
||||
/obj/item/ammo_box/magazine/uzim9mm
|
||||
name = "uzi magazine (9mm)"
|
||||
icon_state = "uzi9mm-32"
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
caliber = "9mm"
|
||||
max_ammo = 32
|
||||
|
||||
/obj/item/ammo_box/magazine/uzim9mm/update_icon()
|
||||
..()
|
||||
icon_state = "uzi9mm-[round(ammo_count(),4)]"
|
||||
|
||||
/obj/item/ammo_box/magazine/smgm9mm
|
||||
name = "SMG magazine (9mm)"
|
||||
icon_state = "smg9mm-42"
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
caliber = "9mm"
|
||||
max_ammo = 21
|
||||
|
||||
/obj/item/ammo_box/magazine/smgm9mm/update_icon()
|
||||
..()
|
||||
icon_state = "smg9mm-[ammo_count() ? "42" : "0"]"
|
||||
|
||||
/obj/item/ammo_box/magazine/smgm9mm/ap
|
||||
name = "SMG magazine (Armour Piercing 9mm)"
|
||||
ammo_type = /obj/item/ammo_casing/c9mmap
|
||||
|
||||
/obj/item/ammo_box/magazine/smgm9mm/toxin
|
||||
name = "SMG magazine (Toxin Tipped 9mm)"
|
||||
ammo_type = /obj/item/ammo_casing/c9mmtox
|
||||
|
||||
/obj/item/ammo_box/magazine/smgm9mm/fire
|
||||
name = "SMG Magazine (Incindiary 9mm)"
|
||||
ammo_type = /obj/item/ammo_casing/c9mminc
|
||||
|
||||
/obj/item/ammo_box/magazine/pistolm9mm
|
||||
name = "pistol magazine (9mm)"
|
||||
icon_state = "9x19p-8"
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
caliber = "9mm"
|
||||
max_ammo = 15
|
||||
|
||||
/obj/item/ammo_box/magazine/pistolm9mm/update_icon()
|
||||
..()
|
||||
icon_state = "9x19p-[ammo_count() ? "8" : "0"]"
|
||||
|
||||
/obj/item/ammo_box/magazine/smgm45
|
||||
name = "SMG magazine (.45)"
|
||||
icon_state = "c20r45-24"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/c45nostamina
|
||||
caliber = ".45"
|
||||
max_ammo = 24
|
||||
|
||||
/obj/item/ammo_box/magazine/smgm45/update_icon()
|
||||
..()
|
||||
icon_state = "c20r45-[round(ammo_count(),2)]"
|
||||
|
||||
obj/item/ammo_box/magazine/tommygunm45
|
||||
name = "drum magazine (.45)"
|
||||
icon_state = "drum45"
|
||||
ammo_type = /obj/item/ammo_casing/c45
|
||||
caliber = ".45"
|
||||
max_ammo = 50
|
||||
|
||||
/obj/item/ammo_box/magazine/m50
|
||||
name = "handgun magazine (.50ae)"
|
||||
icon_state = "50ae"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/a50
|
||||
caliber = ".50"
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/magazine/m75
|
||||
name = "specialized magazine (.75)"
|
||||
icon_state = "75"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/a75
|
||||
caliber = "75"
|
||||
multiple_sprites = 2
|
||||
max_ammo = 8
|
||||
|
||||
/obj/item/ammo_box/magazine/m556
|
||||
name = "toploader magazine (5.56mm)"
|
||||
icon_state = "5.56m"
|
||||
origin_tech = "combat=5;syndicate=1"
|
||||
ammo_type = /obj/item/ammo_casing/a556
|
||||
caliber = "a556"
|
||||
max_ammo = 30
|
||||
multiple_sprites = 2
|
||||
|
||||
/obj/item/ammo_box/magazine/m12g
|
||||
name = "shotgun magazine (12g taser slugs)"
|
||||
desc = "A drum magazine."
|
||||
icon_state = "m12gs"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/stunslug
|
||||
origin_tech = "combat=3;syndicate=1"
|
||||
caliber = "shotgun"
|
||||
max_ammo = 8
|
||||
|
||||
/obj/item/ammo_box/magazine/m12g/update_icon()
|
||||
..()
|
||||
icon_state = "[initial(icon_state)]-[Ceiling(ammo_count(0)/8)*8]"
|
||||
|
||||
/obj/item/ammo_box/magazine/m12g/buckshot
|
||||
name = "shotgun magazine (12g buckshot slugs)"
|
||||
icon_state = "m12gb"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
|
||||
|
||||
/obj/item/ammo_box/magazine/m12g/slug
|
||||
name = "shotgun magazine (12g slugs)"
|
||||
icon_state = "m12gb"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun
|
||||
|
||||
/obj/item/ammo_box/magazine/m12g/dragon
|
||||
name = "shotgun magazine (12g dragon's breath)"
|
||||
icon_state = "m12gf"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath
|
||||
|
||||
/obj/item/ammo_box/magazine/m12g/bioterror
|
||||
name = "shotgun magazine (12g bioterror)"
|
||||
icon_state = "m12gt"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/dart/bioterror
|
||||
|
||||
/obj/item/ammo_box/magazine/m12g/breach
|
||||
name = "shotgun magazine (12g breacher slugs)"
|
||||
icon_state = "m12gbc"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/breaching
|
||||
|
||||
|
||||
//// SNIPER MAGAZINES
|
||||
|
||||
/obj/item/ammo_box/magazine/sniper_rounds
|
||||
name = "sniper rounds (.50)"
|
||||
icon_state = ".50mag"
|
||||
origin_tech = "combat=6;syndicate=2"
|
||||
ammo_type = /obj/item/ammo_casing/point50
|
||||
max_ammo = 6
|
||||
caliber = ".50"
|
||||
|
||||
/obj/item/ammo_box/magazine/sniper_rounds/update_icon()
|
||||
if(ammo_count())
|
||||
icon_state = "[initial(icon_state)]-ammo"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/obj/item/ammo_box/magazine/sniper_rounds/soporific
|
||||
name = "sniper rounds (Zzzzz)"
|
||||
desc = "Soporific sniper rounds, designed for happy days and dead quiet nights..."
|
||||
icon_state = "soporific"
|
||||
origin_tech = "combat=6;syndicate=3"
|
||||
ammo_type = /obj/item/ammo_casing/soporific
|
||||
max_ammo = 3
|
||||
caliber = ".50"
|
||||
|
||||
/obj/item/ammo_box/magazine/sniper_rounds/haemorrhage
|
||||
name = "sniper rounds (Bleed)"
|
||||
desc = "Haemorrhage sniper rounds, leaves your target in a pool of crimson pain"
|
||||
icon_state = "haemorrhage"
|
||||
ammo_type = /obj/item/ammo_casing/haemorrhage
|
||||
max_ammo = 5
|
||||
caliber = ".50"
|
||||
|
||||
/obj/item/ammo_box/magazine/sniper_rounds/penetrator
|
||||
name = "sniper rounds (penetrator)"
|
||||
desc = "An extremely powerful round capable of passing straight through cover and anyone unfortunate enough to be behind it."
|
||||
ammo_type = /obj/item/ammo_casing/penetrator
|
||||
origin_tech = "combat=6;syndicate=3"
|
||||
max_ammo = 5
|
||||
|
||||
|
||||
//// SAW MAGAZINES
|
||||
|
||||
/obj/item/ammo_box/magazine/mm556x45
|
||||
name = "box magazine (5.56x45mm)"
|
||||
icon_state = "a762-50"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/mm556x45
|
||||
caliber = "mm55645"
|
||||
max_ammo = 50
|
||||
|
||||
/obj/item/ammo_box/magazine/mm556x45/bleeding
|
||||
name = "box magazine (Bleeding 5.56x45mm)"
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = /obj/item/ammo_casing/mm556x45/bleeding
|
||||
|
||||
/obj/item/ammo_box/magazine/mm556x45/hollow
|
||||
name = "box magazine (Hollow-Point 5.56x45mm)"
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = /obj/item/ammo_casing/mm556x45/hollow
|
||||
|
||||
/obj/item/ammo_box/magazine/mm556x45/ap
|
||||
name = "box magazine (Armor Penetrating 5.56x45mm)"
|
||||
origin_tech = "combat=4"
|
||||
ammo_type = /obj/item/ammo_casing/mm556x45/ap
|
||||
|
||||
/obj/item/ammo_box/magazine/mm556x45/incen
|
||||
name = "box magazine (Incendiary 5.56x45mm)"
|
||||
origin_tech = "combat=4"
|
||||
ammo_type = /obj/item/ammo_casing/mm556x45/incen
|
||||
|
||||
/obj/item/ammo_box/magazine/mm556x45/update_icon()
|
||||
..()
|
||||
icon_state = "a762-[round(ammo_count(),10)]"
|
||||
|
||||
|
||||
|
||||
|
||||
////TOY GUN MAGAZINES
|
||||
|
||||
/obj/item/ammo_box/magazine/toy
|
||||
name = "foam force META magazine"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart
|
||||
caliber = "foam_force"
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/smg
|
||||
name = "foam force SMG magazine"
|
||||
icon_state = "smg9mm-20"
|
||||
max_ammo = 20
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/smg/update_icon()
|
||||
..()
|
||||
icon_state = "smg9mm-[round(ammo_count(),5)]"
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/smg/riot
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/pistol
|
||||
name = "foam force pistol magazine"
|
||||
icon_state = "9x19p"
|
||||
max_ammo = 8
|
||||
multiple_sprites = 2
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/pistol/riot
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/smgm45
|
||||
name = "donksoft SMG magazine"
|
||||
caliber = "foam_force"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
|
||||
max_ammo = 20
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/smgm45/update_icon()
|
||||
..()
|
||||
icon_state = "c20r45-[round(ammo_count(),2)]"
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/m762
|
||||
name = "donksoft box magazine"
|
||||
caliber = "foam_force"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
|
||||
max_ammo = 50
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/m762/update_icon()
|
||||
..()
|
||||
icon_state = "a762-[round(ammo_count(),10)]"
|
||||
|
||||
|
||||
|
||||
|
||||
//// RECHARGEABLE MAGAZINES
|
||||
|
||||
/obj/item/ammo_box/magazine/recharge
|
||||
name = "power pack"
|
||||
desc = "A rechargeable, detachable battery that serves as a magazine for laser rifles."
|
||||
icon_state = "oldrifle-20"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/laser
|
||||
caliber = "laser"
|
||||
max_ammo = 20
|
||||
|
||||
/obj/item/ammo_box/magazine/recharge/update_icon()
|
||||
desc = "[initial(desc)] It has [stored_ammo.len] shot\s left."
|
||||
icon_state = "oldrifle-[round(ammo_count(),4)]"
|
||||
|
||||
/obj/item/ammo_box/magazine/recharge/attack_self() //No popping out the "bullets"
|
||||
return
|
||||
@@ -1,81 +0,0 @@
|
||||
/obj/item/weapon/gun/energy/gun
|
||||
name = "energy gun"
|
||||
desc = "A basic hybrid energy gun with two settings: disable and kill."
|
||||
icon_state = "energy"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
|
||||
origin_tech = "combat=4;magnets=3"
|
||||
modifystate = 2
|
||||
can_flashlight = 1
|
||||
ammo_x_offset = 3
|
||||
flight_x_offset = 15
|
||||
flight_y_offset = 10
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/mini
|
||||
name = "miniature energy gun"
|
||||
desc = "A small, pistol-sized energy gun with a built-in flashlight. It has two settings: stun and kill."
|
||||
icon_state = "mini"
|
||||
item_state = "gun"
|
||||
w_class = 2
|
||||
cell_type = /obj/item/weapon/stock_parts/cell{charge = 600; maxcharge = 600}
|
||||
ammo_x_offset = 2
|
||||
charge_sections = 3
|
||||
can_flashlight = 0 // Can't attach or detach the flashlight, and override it's icon update
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/mini/New()
|
||||
F = new /obj/item/device/flashlight/seclite(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/mini/update_icon()
|
||||
..()
|
||||
if(F && F.on)
|
||||
add_overlay("mini-light")
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/hos
|
||||
name = "\improper X-01 MultiPhase Energy Gun"
|
||||
desc = "This is an expensive, modern recreation of an antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time."
|
||||
icon_state = "hoslaser"
|
||||
origin_tech = null
|
||||
force = 10
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos, /obj/item/ammo_casing/energy/disabler)
|
||||
ammo_x_offset = 4
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/dragnet
|
||||
name = "\improper DRAGnet"
|
||||
desc = "The \"Dynamic Rapid-Apprehension of the Guilty\" net is a revolution in law enforcement technology."
|
||||
icon_state = "dragnet"
|
||||
origin_tech = "combat=4;magnets=3;bluespace=4"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/net, /obj/item/ammo_casing/energy/trap)
|
||||
can_flashlight = 0
|
||||
ammo_x_offset = 1
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/dragnet/snare
|
||||
name = "Energy Snare Launcher"
|
||||
desc = "Fires an energy snare that slows the target down"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/trap)
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/turret
|
||||
name = "hybrid turret gun"
|
||||
desc = "A heavy hybrid energy cannon with two settings: Stun and kill."
|
||||
icon_state = "turretlaser"
|
||||
item_state = "turretlaser"
|
||||
slot_flags = null
|
||||
w_class = 5
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
|
||||
weapon_weight = WEAPON_MEDIUM
|
||||
can_flashlight = 0
|
||||
trigger_guard = TRIGGER_GUARD_NONE
|
||||
ammo_x_offset = 2
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/nuclear
|
||||
name = "advanced energy gun"
|
||||
desc = "An energy gun with an experimental miniaturized nuclear reactor that automatically charges the internal power cell."
|
||||
icon_state = "nucgun"
|
||||
item_state = "nucgun"
|
||||
origin_tech = "combat=4;magnets=4;powerstorage=4"
|
||||
charge_delay = 5
|
||||
pin = null
|
||||
can_charge = 0
|
||||
ammo_x_offset = 1
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser, /obj/item/ammo_casing/energy/disabler)
|
||||
selfcharge = 1
|
||||
@@ -1,208 +0,0 @@
|
||||
/obj/item/weapon/gun/projectile
|
||||
desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason"
|
||||
name = "projectile gun"
|
||||
icon_state = "pistol"
|
||||
origin_tech = "combat=2;materials=2"
|
||||
w_class = 3
|
||||
|
||||
var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info
|
||||
var/obj/item/ammo_box/magazine/magazine
|
||||
|
||||
/obj/item/weapon/gun/projectile/New()
|
||||
..()
|
||||
if (!magazine)
|
||||
magazine = new mag_type(src)
|
||||
chamber_round()
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/projectile/update_icon()
|
||||
..()
|
||||
if(current_skin)
|
||||
icon_state = "[current_skin][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]"
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/process_chamber(eject_casing = 1, empty_chamber = 1)
|
||||
// if(in_chamber)
|
||||
// return 1
|
||||
var/obj/item/ammo_casing/AC = chambered //Find chambered round
|
||||
if(isnull(AC) || !istype(AC))
|
||||
chamber_round()
|
||||
return
|
||||
if(eject_casing)
|
||||
AC.loc = get_turf(src) //Eject casing onto ground.
|
||||
AC.SpinAnimation(10, 1) //next gen special effects
|
||||
|
||||
if(empty_chamber)
|
||||
chambered = null
|
||||
chamber_round()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/proc/chamber_round()
|
||||
if (chambered || !magazine)
|
||||
return
|
||||
else if (magazine.ammo_count())
|
||||
chambered = magazine.get_round()
|
||||
chambered.loc = src
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/can_shoot()
|
||||
if(!magazine || !magazine.ammo_count(0))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/attackby(obj/item/A, mob/user, params)
|
||||
..()
|
||||
if (istype(A, /obj/item/ammo_box/magazine))
|
||||
var/obj/item/ammo_box/magazine/AM = A
|
||||
if (!magazine && istype(AM, mag_type))
|
||||
user.remove_from_mob(AM)
|
||||
magazine = AM
|
||||
magazine.loc = src
|
||||
user << "<span class='notice'>You load a new magazine into \the [src].</span>"
|
||||
chamber_round()
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
return 1
|
||||
else if (magazine)
|
||||
user << "<span class='notice'>There's already a magazine in \the [src].</span>"
|
||||
if(istype(A, /obj/item/weapon/suppressor))
|
||||
var/obj/item/weapon/suppressor/S = A
|
||||
if(can_suppress)
|
||||
if(!suppressed)
|
||||
if(!user.unEquip(A))
|
||||
return
|
||||
user << "<span class='notice'>You screw [S] onto [src].</span>"
|
||||
suppressed = A
|
||||
S.oldsound = fire_sound
|
||||
S.initial_w_class = w_class
|
||||
fire_sound = 'sound/weapons/Gunshot_silenced.ogg'
|
||||
w_class = 3 //so pistols do not fit in pockets when suppressed
|
||||
A.loc = src
|
||||
update_icon()
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>[src] already has a suppressor!</span>"
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>You can't seem to figure out how to fit [S] on [src]!</span>"
|
||||
return
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/gun/projectile/attack_hand(mob/user)
|
||||
if(loc == user)
|
||||
if(suppressed && can_unsuppress)
|
||||
var/obj/item/weapon/suppressor/S = suppressed
|
||||
if(user.l_hand != src && user.r_hand != src)
|
||||
..()
|
||||
return
|
||||
user << "<span class='notice'>You unscrew [suppressed] from [src].</span>"
|
||||
user.put_in_hands(suppressed)
|
||||
fire_sound = S.oldsound
|
||||
w_class = S.initial_w_class
|
||||
suppressed = 0
|
||||
update_icon()
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/projectile/attack_self(mob/living/user)
|
||||
var/obj/item/ammo_casing/AC = chambered //Find chambered round
|
||||
if(magazine)
|
||||
magazine.loc = get_turf(src.loc)
|
||||
user.put_in_hands(magazine)
|
||||
magazine.update_icon()
|
||||
magazine = null
|
||||
user << "<span class='notice'>You pull the magazine out of \the [src].</span>"
|
||||
else if(chambered)
|
||||
AC.loc = get_turf(src)
|
||||
AC.SpinAnimation(10, 1)
|
||||
chambered = null
|
||||
user << "<span class='notice'>You unload the round from \the [src]'s chamber.</span>"
|
||||
else
|
||||
user << "<span class='notice'>There's no magazine in \the [src].</span>"
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/examine(mob/user)
|
||||
..()
|
||||
user << "Has [get_ammo()] round\s remaining."
|
||||
|
||||
/obj/item/weapon/gun/projectile/proc/get_ammo(countchambered = 1)
|
||||
var/boolets = 0 //mature var names for mature people
|
||||
if (chambered && countchambered)
|
||||
boolets++
|
||||
if (magazine)
|
||||
boolets += magazine.ammo_count()
|
||||
return boolets
|
||||
|
||||
/obj/item/weapon/gun/projectile/suicide_act(mob/user)
|
||||
if (src.chambered && src.chambered.BB && !src.chambered.BB.nodamage)
|
||||
user.visible_message("<span class='suicide'>[user] is putting the barrel of the [src.name] in \his mouth. It looks like \he's trying to commit suicide.</span>")
|
||||
sleep(25)
|
||||
if(user.l_hand == src || user.r_hand == src)
|
||||
process_fire(user, user, 0, zone_override = "head")
|
||||
user.visible_message("<span class='suicide'>[user] blows \his brains out with the [src.name]!</span>")
|
||||
return(BRUTELOSS)
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] panics and starts choking to death!</span>")
|
||||
return(OXYLOSS)
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] is pretending to blow \his brains out with the [src.name]! It looks like \he's trying to commit suicide!</b></span>")
|
||||
playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1)
|
||||
return (OXYLOSS)
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/proc/sawoff(mob/user)
|
||||
if(sawn_state == SAWN_OFF)
|
||||
user << "<span class='warning'>\The [src] is already shortened!</span>"
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.visible_message("[user] begins to shorten \the [src].", "<span class='notice'>You begin to shorten \the [src]...</span>")
|
||||
|
||||
//if there's any live ammo inside the gun, makes it go off
|
||||
if(blow_up(user))
|
||||
user.visible_message("<span class='danger'>\The [src] goes off!</span>", "<span class='danger'>\The [src] goes off in your face!</span>")
|
||||
return
|
||||
|
||||
if(do_after(user, 30, target = src))
|
||||
if(sawn_state == SAWN_OFF)
|
||||
return
|
||||
user.visible_message("[user] shortens \the [src]!", "<span class='notice'>You shorten \the [src].</span>")
|
||||
name = "sawn-off [src.name]"
|
||||
desc = sawn_desc
|
||||
w_class = 3
|
||||
item_state = "gun"//phil235 is it different with different skin?
|
||||
slot_flags &= ~SLOT_BACK //you can't sling it on your back
|
||||
slot_flags |= SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally)
|
||||
sawn_state = SAWN_OFF
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
// Sawing guns related proc
|
||||
/obj/item/weapon/gun/projectile/proc/blow_up(mob/user)
|
||||
. = 0
|
||||
for(var/obj/item/ammo_casing/AC in magazine.stored_ammo)
|
||||
if(AC.BB)
|
||||
process_fire(user, user,0)
|
||||
. = 1
|
||||
|
||||
|
||||
/obj/item/weapon/suppressor
|
||||
name = "suppressor"
|
||||
desc = "A universal syndicate small-arms suppressor for maximum espionage."
|
||||
icon = 'icons/obj/guns/projectile.dmi'
|
||||
icon_state = "suppressor"
|
||||
w_class = 2
|
||||
var/oldsound = null
|
||||
var/initial_w_class = null
|
||||
|
||||
|
||||
/obj/item/weapon/suppressor/specialoffer
|
||||
name = "cheap suppressor"
|
||||
desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits all weapons."
|
||||
icon = 'icons/obj/guns/projectile.dmi'
|
||||
icon_state = "suppressor"
|
||||
|
||||
@@ -1,409 +0,0 @@
|
||||
/obj/item/weapon/gun/projectile/automatic
|
||||
origin_tech = "combat=4;materials=2"
|
||||
w_class = 3
|
||||
var/alarmed = 0
|
||||
var/select = 1
|
||||
can_suppress = 1
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
actions_types = list(/datum/action/item_action/toggle_firemode)
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/proto
|
||||
name = "\improper NanoTrasen Saber SMG"
|
||||
desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors."
|
||||
icon_state = "saber"
|
||||
mag_type = /obj/item/ammo_box/magazine/smgm9mm
|
||||
pin = null
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/proto/unrestricted
|
||||
pin = /obj/item/device/firing_pin
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/update_icon()
|
||||
..()
|
||||
cut_overlays()
|
||||
if(!select)
|
||||
add_overlay("[initial(icon_state)]semi")
|
||||
if(select == 1)
|
||||
add_overlay("[initial(icon_state)]burst")
|
||||
icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/attackby(obj/item/A, mob/user, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(istype(A, /obj/item/ammo_box/magazine))
|
||||
var/obj/item/ammo_box/magazine/AM = A
|
||||
if(istype(AM, mag_type))
|
||||
if(magazine)
|
||||
user << "<span class='notice'>You perform a tactical reload on \the [src], replacing the magazine.</span>"
|
||||
magazine.loc = get_turf(src.loc)
|
||||
magazine.update_icon()
|
||||
magazine = null
|
||||
else
|
||||
user << "<span class='notice'>You insert the magazine into \the [src].</span>"
|
||||
user.remove_from_mob(AM)
|
||||
magazine = AM
|
||||
magazine.loc = src
|
||||
chamber_round()
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/ui_action_click()
|
||||
burst_select()
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/proc/burst_select()
|
||||
var/mob/living/carbon/human/user = usr
|
||||
select = !select
|
||||
if(!select)
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
user << "<span class='notice'>You switch to semi-automatic.</span>"
|
||||
else
|
||||
burst_size = initial(burst_size)
|
||||
fire_delay = initial(fire_delay)
|
||||
user << "<span class='notice'>You switch to [burst_size]-rnd burst.</span>"
|
||||
|
||||
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
|
||||
update_icon()
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/can_shoot()
|
||||
return get_ammo()
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/proc/empty_alarm()
|
||||
if(!chambered && !get_ammo() && !alarmed)
|
||||
playsound(src.loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
|
||||
update_icon()
|
||||
alarmed = 1
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/c20r
|
||||
name = "\improper C-20r SMG"
|
||||
desc = "A bullpup two-round burst .45 SMG, designated 'C-20r'. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp."
|
||||
icon_state = "c20r"
|
||||
item_state = "c20r"
|
||||
origin_tech = "combat=5;materials=2;syndicate=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/smgm45
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
fire_delay = 2
|
||||
burst_size = 2
|
||||
pin = /obj/item/device/firing_pin/implant/pindicate
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/c20r/unrestricted
|
||||
pin = /obj/item/device/firing_pin
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/c20r/New()
|
||||
..()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/c20r/afterattack()
|
||||
..()
|
||||
empty_alarm()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/c20r/update_icon()
|
||||
..()
|
||||
icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/wt550
|
||||
name = "security auto rifle"
|
||||
desc = "An outdated personal defence weapon. Uses 4.6x30mm rounds and is designated the WT-550 Automatic Rifle."
|
||||
icon_state = "wt550"
|
||||
item_state = "arg"
|
||||
mag_type = /obj/item/ammo_box/magazine/wt550m9
|
||||
fire_delay = 2
|
||||
can_suppress = 0
|
||||
burst_size = 0
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/wt550/update_icon()
|
||||
..()
|
||||
icon_state = "wt550[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]"
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/mini_uzi
|
||||
name = "\improper 'Type U3' Uzi"
|
||||
desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds."
|
||||
icon_state = "mini-uzi"
|
||||
origin_tech = "combat=4;materials=2;syndicate=4"
|
||||
mag_type = /obj/item/ammo_box/magazine/uzim9mm
|
||||
burst_size = 2
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/m90
|
||||
name = "\improper M-90gl Carbine"
|
||||
desc = "A three-round burst 5.56 toploading carbine, designated 'M-90gl'. Has an attached underbarrel grenade launcher which can be toggled on and off."
|
||||
icon_state = "m90"
|
||||
item_state = "m90"
|
||||
origin_tech = "combat=5;materials=2;syndicate=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/m556
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
can_suppress = 0
|
||||
var/obj/item/weapon/gun/projectile/revolver/grenadelauncher/underbarrel
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
pin = /obj/item/device/firing_pin/implant/pindicate
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/m90/New()
|
||||
..()
|
||||
underbarrel = new /obj/item/weapon/gun/projectile/revolver/grenadelauncher(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/m90/unrestricted
|
||||
pin = /obj/item/device/firing_pin
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/m90/unrestricted/New()
|
||||
..()
|
||||
underbarrel = new /obj/item/weapon/gun/projectile/revolver/grenadelauncher/unrestricted(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/m90/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(select == 2)
|
||||
underbarrel.afterattack(target, user, flag, params)
|
||||
else
|
||||
..()
|
||||
return
|
||||
/obj/item/weapon/gun/projectile/automatic/m90/attackby(obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/ammo_casing))
|
||||
if(istype(A, underbarrel.magazine.ammo_type))
|
||||
underbarrel.attack_self()
|
||||
underbarrel.attackby(A, user, params)
|
||||
else
|
||||
..()
|
||||
/obj/item/weapon/gun/projectile/automatic/m90/update_icon()
|
||||
..()
|
||||
cut_overlays()
|
||||
switch(select)
|
||||
if(0)
|
||||
add_overlay("[initial(icon_state)]semi")
|
||||
if(1)
|
||||
add_overlay("[initial(icon_state)]burst")
|
||||
if(2)
|
||||
add_overlay("[initial(icon_state)]gren")
|
||||
icon_state = "[initial(icon_state)][magazine ? "" : "-e"]"
|
||||
return
|
||||
/obj/item/weapon/gun/projectile/automatic/m90/burst_select()
|
||||
var/mob/living/carbon/human/user = usr
|
||||
switch(select)
|
||||
if(0)
|
||||
select = 1
|
||||
burst_size = initial(burst_size)
|
||||
fire_delay = initial(fire_delay)
|
||||
user << "<span class='notice'>You switch to [burst_size]-rnd burst.</span>"
|
||||
if(1)
|
||||
select = 2
|
||||
user << "<span class='notice'>You switch to grenades.</span>"
|
||||
if(2)
|
||||
select = 0
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
user << "<span class='notice'>You switch to semi-auto.</span>"
|
||||
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/tommygun
|
||||
name = "\improper Thompson SMG"
|
||||
desc = "Based on the classic 'Chicago Typewriter'."
|
||||
icon_state = "tommygun"
|
||||
item_state = "shotgun"
|
||||
w_class = 5
|
||||
slot_flags = 0
|
||||
origin_tech = "combat=5;materials=1;syndicate=3"
|
||||
mag_type = /obj/item/ammo_box/magazine/tommygunm45
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 4
|
||||
fire_delay = 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/ar
|
||||
name = "\improper NT-ARG 'Boarder'"
|
||||
desc = "A robust assault rile used by Nanotrasen fighting forces."
|
||||
icon_state = "arg"
|
||||
item_state = "arg"
|
||||
slot_flags = 0
|
||||
origin_tech = "combat=6;engineering=4"
|
||||
mag_type = /obj/item/ammo_box/magazine/m556
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 3
|
||||
fire_delay = 1
|
||||
|
||||
|
||||
|
||||
// Bulldog shotgun //
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog
|
||||
name = "\improper 'Bulldog' Shotgun"
|
||||
desc = "A semi-auto, mag-fed shotgun for combat in narrow corridors, nicknamed 'Bulldog' by boarding parties. Compatible only with specialized 8-round drum magazines."
|
||||
icon_state = "bulldog"
|
||||
item_state = "bulldog"
|
||||
w_class = 3
|
||||
origin_tech = "combat=6;materials=4;syndicate=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/m12g
|
||||
fire_sound = 'sound/weapons/Gunshot.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
pin = /obj/item/device/firing_pin/implant/pindicate
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/unrestricted
|
||||
pin = /obj/item/device/firing_pin
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/New()
|
||||
..()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/proc/update_magazine()
|
||||
if(magazine)
|
||||
src.overlays = 0
|
||||
add_overlay("[magazine.icon_state]")
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/update_icon()
|
||||
src.overlays = 0
|
||||
update_magazine()
|
||||
icon_state = "bulldog[chambered ? "" : "-e"]"
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/afterattack()
|
||||
..()
|
||||
empty_alarm()
|
||||
return
|
||||
|
||||
|
||||
|
||||
// L6 SAW //
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw
|
||||
name = "\improper L6 SAW"
|
||||
desc = "A heavily modified 5.56x45mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation."
|
||||
icon_state = "l6closed100"
|
||||
item_state = "l6closedmag"
|
||||
w_class = 5
|
||||
slot_flags = 0
|
||||
origin_tech = "combat=6;engineering=3;syndicate=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/mm556x45
|
||||
weapon_weight = WEAPON_MEDIUM
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
var/cover_open = 0
|
||||
can_suppress = 0
|
||||
burst_size = 3
|
||||
fire_delay = 1
|
||||
pin = /obj/item/device/firing_pin/implant/pindicate
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/unrestricted
|
||||
pin = /obj/item/device/firing_pin
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_self(mob/user)
|
||||
cover_open = !cover_open
|
||||
user << "<span class='notice'>You [cover_open ? "open" : "close"] [src]'s cover.</span>"
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon()
|
||||
icon_state = "l6[cover_open ? "open" : "closed"][magazine ? Ceiling(get_ammo(0)/12.5)*25 : "-empty"][suppressed ? "-suppressed" : ""]"
|
||||
item_state = "l6[cover_open ? "openmag" : "closedmag"]"
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) //what I tried to do here is just add a check to see if the cover is open or not and add an icon_state change because I can't figure out how c-20rs do it with overlays
|
||||
if(cover_open)
|
||||
user << "<span class='warning'>[src]'s cover is open! Close it before firing!</span>"
|
||||
else
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_hand(mob/user)
|
||||
if(loc != user)
|
||||
..()
|
||||
return //let them pick it up
|
||||
if(!cover_open || (cover_open && !magazine))
|
||||
..()
|
||||
else if(cover_open && magazine)
|
||||
//drop the mag
|
||||
magazine.update_icon()
|
||||
magazine.loc = get_turf(src.loc)
|
||||
user.put_in_hands(magazine)
|
||||
magazine = null
|
||||
update_icon()
|
||||
user << "<span class='notice'>You remove the magazine from [src].</span>"
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/attackby(obj/item/A, mob/user, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!cover_open)
|
||||
user << "<span class='warning'>[src]'s cover is closed! You can't insert a new mag.</span>"
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
|
||||
// SNIPER //
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/sniper_rifle
|
||||
name = "sniper rifle"
|
||||
desc = "The kind of gun that will leave you crying for mummy before you even realise your leg's missing"
|
||||
icon_state = "sniper"
|
||||
item_state = "sniper"
|
||||
recoil = 2
|
||||
weapon_weight = WEAPON_MEDIUM
|
||||
mag_type = /obj/item/ammo_box/magazine/sniper_rounds
|
||||
fire_delay = 40
|
||||
burst_size = 1
|
||||
origin_tech = "combat=7"
|
||||
can_unsuppress = 1
|
||||
can_suppress = 1
|
||||
w_class = 3
|
||||
zoomable = TRUE
|
||||
zoom_amt = 7 //Long range, enough to see in front of you, but no tiles behind you.
|
||||
slot_flags = SLOT_BACK
|
||||
actions_types = list()
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/sniper_rifle/update_icon()
|
||||
if(magazine)
|
||||
icon_state = "sniper-mag"
|
||||
else
|
||||
icon_state = "sniper"
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/sniper_rifle/syndicate
|
||||
name = "syndicate sniper rifle"
|
||||
desc = "Syndicate flavoured sniper rifle, it packs quite a punch, a punch to your face"
|
||||
pin = /obj/item/device/firing_pin/implant/pindicate
|
||||
origin_tech = "combat=7;syndicate=6"
|
||||
|
||||
|
||||
|
||||
|
||||
// Laser rifle (rechargeable magazine) //
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/laser
|
||||
name = "laser rifle"
|
||||
desc = "Though sometimes mocked for the relatively weak firepower of their energy weapons, the logistic miracle of rechargable ammunition has given Nanotrasen a decisive edge over many a foe."
|
||||
icon_state = "oldrifle"
|
||||
item_state = "arg"
|
||||
mag_type = /obj/item/ammo_box/magazine/recharge
|
||||
fire_delay = 2
|
||||
can_suppress = 0
|
||||
burst_size = 0
|
||||
actions_types = list()
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/laser/process_chamber(eject_casing = 0, empty_chamber = 1)
|
||||
..() //we changed the default value of the first argument
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/laser/update_icon()
|
||||
..()
|
||||
icon_state = "oldrifle[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]"
|
||||
return
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user