Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit235
This commit is contained in:
@@ -105,6 +105,7 @@
|
||||
#define MATRIXED 22 //if icon is color matrix'd
|
||||
#define SKINTONE 23 //uses skin tones
|
||||
#define HORNCOLOR 24
|
||||
#define WINGCOLOR 25
|
||||
|
||||
//organ slots
|
||||
#define ORGAN_SLOT_BRAIN "brain"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define ACCESS_MORGUE 6
|
||||
#define ACCESS_TOX 7 //R&D department, R&D console, burn chamber on some maps
|
||||
#define ACCESS_TOX_STORAGE 8 //Toxins storage, burn chamber on some maps
|
||||
#define ACCESS_GENETICS 9
|
||||
#define ACCESS_GENETICS 9
|
||||
#define ACCESS_ENGINE 10 //Engineering area, power monitor, power flow control console
|
||||
#define ACCESS_ENGINE_EQUIP 11 //APCs, EngiVend/YouTool, engineering equipment lockers
|
||||
#define ACCESS_MAINT_TUNNELS 12
|
||||
@@ -64,6 +64,8 @@
|
||||
#define ACCESS_WEAPONS 66 //Weapon authorization for secbots
|
||||
#define ACCESS_NETWORK 67 //NTnet diagnostics/monitoring software
|
||||
#define ACCESS_CLONING 68 //Cloning room and clone pod ejection
|
||||
#define ACCESS_ENTER_GENPOP 69
|
||||
#define ACCESS_LEAVE_GENPOP 70
|
||||
|
||||
//BEGIN CENTCOM ACCESS
|
||||
/*Should leave plenty of room if we need to add more access levels.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult
|
||||
GLOBAL_VAR_INIT(clockwork_vitality, 0) //How much Vitality is stored, total
|
||||
GLOBAL_VAR_INIT(clockwork_power, 0) //How many watts of power are globally available to the clockwork cult
|
||||
GLOBAL_VAR_INIT(neovgre_exists, 0) //Does neovgre exist?
|
||||
|
||||
GLOBAL_LIST_EMPTY(all_clockwork_objects) //All clockwork items, structures, and effects in existence
|
||||
GLOBAL_LIST_EMPTY(all_clockwork_mobs) //All clockwork SERVANTS (not creatures) in existence
|
||||
|
||||
@@ -33,4 +33,6 @@
|
||||
#define MOVESPEED_ID_SANITY "MOOD_SANITY"
|
||||
|
||||
#define MOVESPEED_ID_PRONE_DRAGGING "PRONE_DRAG"
|
||||
#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
|
||||
#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
|
||||
|
||||
#define MOVESPEED_ID_TASED_STATUS "TASED"
|
||||
+10
-37
@@ -31,41 +31,14 @@
|
||||
#define STIMULUM_RESEARCH_AMOUNT 50
|
||||
//Plasma fusion properties
|
||||
#define FUSION_ENERGY_THRESHOLD 3e9 //Amount of energy it takes to start a fusion reaction
|
||||
#define FUSION_TEMPERATURE_THRESHOLD 1000 //Temperature required to start a fusion reaction
|
||||
#define FUSION_MOLE_THRESHOLD 250 //Mole count required (tritium/plasma) to start a fusion reaction
|
||||
#define FUSION_RELEASE_ENERGY_SUPER 3e9 //Amount of energy released in the fusion process, super tier
|
||||
#define FUSION_RELEASE_ENERGY_HIGH 1e9 //Amount of energy released in the fusion process, high tier
|
||||
#define FUSION_RELEASE_ENERGY_MID 5e8 //Amount of energy released in the fusion process, mid tier
|
||||
#define FUSION_RELEASE_ENERGY_LOW 1e8 //Amount of energy released in the fusion process, low tier
|
||||
#define FUSION_MEDIATION_FACTOR 80 //Arbitrary
|
||||
#define FUSION_SUPER_TIER_THRESHOLD 50 //anything above this is super tier
|
||||
#define FUSION_HIGH_TIER_THRESHOLD 20 //anything above this and below 50 is high tier
|
||||
#define FUSION_MID_TIER_THRESHOLD 5 //anything above this and below 20 is mid tier - below this is low tier, but that doesnt need a define
|
||||
#define FUSION_ENERGY_DIVISOR_SUPER 25 //power_ratio is divided by this during energy calculations
|
||||
#define FUSION_ENERGY_DIVISOR_HIGH 20
|
||||
#define FUSION_ENERGY_DIVISOR_MID 10
|
||||
#define FUSION_ENERGY_DIVISOR_LOW 2
|
||||
#define FUSION_GAS_CREATION_FACTOR_TRITIUM 0.40 //trit - one gas rather than two, so think about that when calculating stuff - 40% in total
|
||||
#define FUSION_GAS_CREATION_FACTOR_STIM 0.05 //stim percentage creation from high tier - 5%, 60% in total with pluox
|
||||
#define FUSION_GAS_CREATION_FACTOR_PLUOX 0.55 //pluox percentage creation from high tier - 55%, 60% in total with stim
|
||||
#define FUSION_GAS_CREATION_FACTOR_NITRYL 0.20 //nitryl and N2O - 80% in total
|
||||
#define FUSION_GAS_CREATION_FACTOR_N2O 0.60 //nitryl and N2O - 80% in total
|
||||
#define FUSION_GAS_CREATION_FACTOR_BZ 0.05 //BZ - 5% - 90% in total with CO2
|
||||
#define FUSION_GAS_CREATION_FACTOR_CO2 0.85 //CO2 - 85% - 90% in total with BZ
|
||||
#define FUSION_MID_TIER_RAD_PROB_FACTOR 2 //probability of radpulse is power ratio * this for whatever tier
|
||||
#define FUSION_LOW_TIER_RAD_PROB_FACTOR 5
|
||||
#define FUSION_EFFICIENCY_BASE 60 //used in the fusion efficiency calculations
|
||||
#define FUSION_EFFICIENCY_DIVISOR 0.6 //ditto
|
||||
#define FUSION_RADIATION_FACTOR 15000 //horizontal asymptote
|
||||
#define FUSION_RADIATION_CONSTANT 30 //equation is form of (ax) / (x + b), where a = radiation factor and b = radiation constant and x = power ratio (https://www.desmos.com/calculator/4i1f296phl)
|
||||
#define FUSION_ZAP_POWER_ASYMPTOTE 50000 //maximum value - not enough to instacrit but it'll still hurt like shit
|
||||
#define FUSION_ZAP_POWER_CONSTANT 75 //equation is of from [ax / (x + b)] + c, where a = zap power asymptote, b = zap power constant, c = zap power base and x = power ratio
|
||||
#define FUSION_ZAP_POWER_BASE 1000 //(https://www.desmos.com/calculator/vvbmhf4unm)
|
||||
#define FUSION_ZAP_RANGE_SUPER 9 //range of the tesla zaps that occur from fusion
|
||||
#define FUSION_ZAP_RANGE_HIGH 7
|
||||
#define FUSION_ZAP_RANGE_MID 5
|
||||
#define FUSION_ZAP_RANGE_LOW 3
|
||||
#define FUSION_PARTICLE_FACTOR_SUPER 4 //# of particles fired out is equal to rand(3,6) * this for whatever tier
|
||||
#define FUSION_PARTICLE_FACTOR_HIGH 3
|
||||
#define FUSION_PARTICLE_FACTOR_MID 2
|
||||
#define FUSION_PARTICLE_FACTOR_LOW 1
|
||||
#define FUSION_TRITIUM_CONVERSION_COEFFICIENT (1e-10)
|
||||
#define INSTABILITY_GAS_POWER_FACTOR 0.003
|
||||
#define FUSION_TRITIUM_MOLES_USED 1
|
||||
#define PLASMA_BINDING_ENERGY 20000000
|
||||
#define TOROID_VOLUME_BREAKEVEN 1000
|
||||
#define FUSION_TEMPERATURE_THRESHOLD 10000
|
||||
#define PARTICLE_CHANCE_CONSTANT (-20000000)
|
||||
#define FUSION_RAD_MAX 2000
|
||||
#define FUSION_RAD_COEFFICIENT (-1000)
|
||||
#define FUSION_INSTABILITY_ENDOTHERMALITY 2
|
||||
|
||||
@@ -50,3 +50,7 @@
|
||||
#define ASSEMBLY_THIRD_STEP 2
|
||||
#define ASSEMBLY_FOURTH_STEP 3
|
||||
#define ASSEMBLY_FIFTH_STEP 4
|
||||
|
||||
|
||||
//Checks to determine borg availability depending on the server's config. These are defines in the interest of reducing copypasta
|
||||
#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert))
|
||||
@@ -44,6 +44,8 @@
|
||||
|
||||
#define STATUS_EFFECT_SLEEPING /datum/status_effect/incapacitating/sleeping //the affected is asleep
|
||||
|
||||
#define STATUS_EFFECT_TASED /datum/status_effect/electrode //the affected has been tased, preventing fine muscle control
|
||||
|
||||
#define STATUS_EFFECT_PACIFY /datum/status_effect/pacify //the affected is pacified, preventing direct hostile actions
|
||||
|
||||
#define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run
|
||||
|
||||
@@ -400,6 +400,12 @@ GLOBAL_LIST_EMPTY(species_list)
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(L.recoveringstam)
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(!QDELETED(Tloc) && (QDELETED(target) || Tloc != target.loc))
|
||||
if((Uloc != Tloc || Tloc != user) && !drifting)
|
||||
. = 0
|
||||
|
||||
@@ -70,6 +70,9 @@
|
||||
|
||||
/datum/config_entry/flag/disable_peaceborg
|
||||
|
||||
/datum/config_entry/number/minimum_secborg_alert //Minimum alert level for secborgs to be chosen.
|
||||
config_entry_value = 3
|
||||
|
||||
/datum/config_entry/number/traitor_scaling_coeff //how much does the amount of players get divided by to determine traitors
|
||||
config_entry_value = 6
|
||||
min_val = 1
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
/obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector,
|
||||
/obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper,
|
||||
/obj/item/implanter, /obj/item/screwdriver, /obj/item/weldingtool/mini,
|
||||
/obj/item/firing_pin
|
||||
/obj/item/firing_pin, /obj/item/gun/ballistic/automatic/pistol/mag
|
||||
))
|
||||
|
||||
/datum/component/storage/concrete/pockets/shoes/clown/Initialize()
|
||||
|
||||
@@ -80,6 +80,36 @@
|
||||
desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
|
||||
icon_state = "asleep"
|
||||
|
||||
//TASER
|
||||
/datum/status_effect/electrode
|
||||
id = "tased"
|
||||
blocks_combatmode = TRUE
|
||||
status_type = STATUS_EFFECT_REPLACE
|
||||
alert_type = null
|
||||
|
||||
/datum/status_effect/electrode/on_creation(mob/living/new_owner, set_duration)
|
||||
if(isnum(set_duration))
|
||||
duration = set_duration
|
||||
. = ..()
|
||||
if(iscarbon(owner))
|
||||
var/mob/living/carbon/C = owner
|
||||
if(C.combatmode)
|
||||
C.toggle_combat_mode(TRUE)
|
||||
C.add_movespeed_modifier(MOVESPEED_ID_TASED_STATUS, TRUE, override = TRUE, multiplicative_slowdown = 8)
|
||||
|
||||
/datum/status_effect/electrode/on_remove()
|
||||
if(iscarbon(owner))
|
||||
var/mob/living/carbon/C = owner
|
||||
C.remove_movespeed_modifier(MOVESPEED_ID_TASED_STATUS)
|
||||
. = ..()
|
||||
|
||||
/datum/status_effect/electrode/tick()
|
||||
if(owner)
|
||||
owner.adjustStaminaLoss(5) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
|
||||
|
||||
/datum/status_effect/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
|
||||
return 2
|
||||
|
||||
//OTHER DEBUFFS
|
||||
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
|
||||
id = "his_wrath"
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
var/on_remove_on_mob_delete = FALSE //if we call on_remove() when the mob is deleted
|
||||
var/examine_text //If defined, this text will appear when the mob is examined - to use he, she etc. use "SUBJECTPRONOUN" and replace it in the examines themselves
|
||||
var/alert_type = /obj/screen/alert/status_effect //the alert thrown by the status effect, contains name and description
|
||||
var/blocks_combatmode //Does this status effect prevent the user from toggling combat mode?
|
||||
var/obj/screen/alert/status_effect/linked_alert = null //the alert itself, if it exists
|
||||
|
||||
/datum/status_effect/New(list/arguments)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
area_type = /area
|
||||
protected_areas = list(/area/maintenance, /area/ai_monitored/turret_protected/ai_upload, /area/ai_monitored/turret_protected/ai_upload_foyer,
|
||||
/area/ai_monitored/turret_protected/ai, /area/storage/emergency/starboard, /area/storage/emergency/port, /area/shuttle)
|
||||
/area/ai_monitored/turret_protected/ai, /area/storage/emergency/starboard, /area/storage/emergency/port, /area/shuttle, /area/security/prison)
|
||||
target_trait = ZTRAIT_STATION
|
||||
|
||||
immunity_type = "rad"
|
||||
|
||||
@@ -575,7 +575,7 @@
|
||||
if(user)
|
||||
if(message)
|
||||
if(authenticated)
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
if(user.canUseTopic(src, !issilicon(user)))
|
||||
if(!record1 || record1 == active1)
|
||||
if(!record2 || record2 == active2)
|
||||
return 1
|
||||
|
||||
@@ -801,7 +801,7 @@ What a mess.*/
|
||||
/obj/machinery/computer/secure_data/proc/canUseSecurityRecordsConsole(mob/user, message1 = 0, record1, record2)
|
||||
if(user)
|
||||
if(authenticated)
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
if(user.canUseTopic(src, !issilicon(user)))
|
||||
if(!trim(message1))
|
||||
return 0
|
||||
if(!record1 || record1 == active1)
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = M
|
||||
|
||||
var/desc = input("Please select a location to lock in.", "Locking Computer") as null|anything in L
|
||||
if(!user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) //check if we are still around
|
||||
if(!user.canUseTopic(src, !issilicon(user), NO_DEXTERY)) //check if we are still around
|
||||
return
|
||||
target = L[desc]
|
||||
if(imp_t)
|
||||
@@ -167,7 +167,7 @@
|
||||
to_chat(user, "<span class='alert'>No active connected stations located.</span>")
|
||||
return
|
||||
var/desc = input("Please select a station to lock in.", "Locking Computer") as null|anything in L
|
||||
if(!user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) //again, check if we are still around
|
||||
if(!user.canUseTopic(src, !issilicon(user), NO_DEXTERY)) //again, check if we are still around
|
||||
return
|
||||
var/obj/machinery/teleport/station/target_station = L[desc]
|
||||
if(!target_station || !target_station.teleporter_hub)
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
|
||||
var/stun_projectile = null //stun mode projectile type
|
||||
var/stun_projectile_sound
|
||||
var/nonlethal_projectile //projectile to use in stun mode when the target is resting, if any
|
||||
var/nonlethal_projectile_sound
|
||||
var/lethal_projectile = null //lethal mode projectile type
|
||||
var/lethal_projectile_sound
|
||||
|
||||
@@ -535,13 +537,22 @@
|
||||
T = closer
|
||||
break
|
||||
|
||||
var/mob/living/carbon/C
|
||||
if(iscarbon(target))
|
||||
C = target
|
||||
|
||||
update_icon()
|
||||
var/obj/item/projectile/A
|
||||
//any emagged turrets drains 2x power and uses a different projectile?
|
||||
if(mode == TURRET_STUN)
|
||||
use_power(reqpower)
|
||||
A = new stun_projectile(T)
|
||||
playsound(loc, stun_projectile_sound, 75, 1)
|
||||
if(nonlethal_projectile && C && C.resting)
|
||||
use_power(reqpower*0.5)
|
||||
A = new nonlethal_projectile(T)
|
||||
playsound(loc, nonlethal_projectile_sound, 75, 1)
|
||||
else
|
||||
use_power(reqpower)
|
||||
A = new stun_projectile(T)
|
||||
playsound(loc, stun_projectile_sound, 75, 1)
|
||||
else
|
||||
use_power(reqpower * 2)
|
||||
A = new lethal_projectile(T)
|
||||
@@ -653,6 +664,8 @@
|
||||
base_icon_state = "standard"
|
||||
stun_projectile = /obj/item/projectile/energy/electrode
|
||||
stun_projectile_sound = 'sound/weapons/taser.ogg'
|
||||
nonlethal_projectile = /obj/item/projectile/beam/disabler
|
||||
nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
|
||||
lethal_projectile = /obj/item/projectile/beam/laser
|
||||
lethal_projectile_sound = 'sound/weapons/laser.ogg'
|
||||
desc = "An energy blaster auto-turret."
|
||||
@@ -662,6 +675,8 @@
|
||||
base_icon_state = "standard"
|
||||
stun_projectile = /obj/item/projectile/energy/electrode
|
||||
stun_projectile_sound = 'sound/weapons/taser.ogg'
|
||||
nonlethal_projectile = /obj/item/projectile/beam/disabler
|
||||
nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
|
||||
lethal_projectile = /obj/item/projectile/beam/laser/heavylaser
|
||||
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
|
||||
desc = "An energy blaster auto-turret."
|
||||
@@ -681,6 +696,8 @@
|
||||
|
||||
/obj/machinery/porta_turret/ai
|
||||
faction = list("silicon")
|
||||
nonlethal_projectile = /obj/item/projectile/beam/disabler
|
||||
nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
|
||||
|
||||
/obj/machinery/porta_turret/ai/assess_perp(mob/living/carbon/human/perp)
|
||||
return 10 //AI turrets shoot at everything not in their faction
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/obj/machinery/turnstile
|
||||
name = "turnstile"
|
||||
desc = "A mechanical door that permits one-way access and prevents tailgating."
|
||||
icon = 'icons/obj/turnstile.dmi'
|
||||
icon_state = "turnstile_map"
|
||||
density = FALSE
|
||||
armor = list(melee = 50, bullet = 50, laser = 50, energy = 50, bomb = 10, bio = 100, rad = 100, fire = 90, acid = 70)
|
||||
anchored = TRUE
|
||||
use_power = FALSE
|
||||
idle_power_usage = 2
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
layer = OPEN_DOOR_LAYER
|
||||
|
||||
/obj/machinery/turnstile/Initialize()
|
||||
. = ..()
|
||||
icon_state = "turnstile"
|
||||
|
||||
/obj/machinery/turnstile/CanAtmosPass(turf/T)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/turnstile/bullet_act(obj/item/projectile/P, def_zone)
|
||||
return -1 //Pass through!
|
||||
|
||||
/obj/machinery/turnstile/proc/allowed_access(var/mob/B)
|
||||
if(B.pulledby && ismob(B.pulledby))
|
||||
return allowed(B.pulledby) | allowed(B)
|
||||
else
|
||||
return allowed(B)
|
||||
|
||||
/obj/machinery/turnstile/CanPass(atom/movable/AM, turf/T)
|
||||
if(ismob(AM))
|
||||
var/mob/B = AM
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
|
||||
if(world.time - M.last_bumped <= 5)
|
||||
return FALSE
|
||||
M.last_bumped = world.time
|
||||
|
||||
var/allowed_access = FALSE
|
||||
var/turf/behind = get_step(src, dir)
|
||||
|
||||
if(B in behind.contents)
|
||||
allowed_access = allowed_access(B)
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>\the [src] resists your efforts.</span>")
|
||||
return FALSE
|
||||
|
||||
if(allowed_access)
|
||||
flick("operate", src)
|
||||
playsound(src,'sound/items/ratchet.ogg',50,0,3)
|
||||
return TRUE
|
||||
else
|
||||
flick("deny", src)
|
||||
playsound(src,'sound/machines/deniedbeep.ogg',50,0,3)
|
||||
return FALSE
|
||||
if(ispath(AM, /obj/item/))
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/turnstile/CheckExit(atom/movable/AM as mob|obj, target)
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
var/outdir = dir
|
||||
if(allowed_access(M))
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
outdir = SOUTH
|
||||
if(SOUTH)
|
||||
outdir = NORTH
|
||||
if(EAST)
|
||||
outdir = WEST
|
||||
if(WEST)
|
||||
outdir = EAST
|
||||
var/turf/outturf = get_step(src, outdir)
|
||||
var/canexit = (target == src.loc) | (target == outturf)
|
||||
|
||||
if(!canexit && world.time - M.last_bumped <= 5)
|
||||
to_chat(usr, "<span class='notice'>\the [src] resists your efforts.</span>")
|
||||
M.last_bumped = world.time
|
||||
return canexit
|
||||
else
|
||||
return TRUE
|
||||
@@ -0,0 +1,96 @@
|
||||
/obj/mecha/combat/neovgre
|
||||
name = "Neovgre, the Anima Bulwark"
|
||||
desc = "Nezbere's most powerful creation, a mighty war machine of unmatched power said to have ended wars in a single night."
|
||||
icon = 'icons/mecha/neovgre.dmi'
|
||||
icon_state = "neovgre"
|
||||
max_integrity = 500 //This is THE ratvarian superweaon, its deployment is an investment
|
||||
armor = list("melee" = 50, "bullet" = 40, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) //Its similar to the clockwork armour albeit with a few buffs becuase RATVARIAN SUPERWEAPON!!
|
||||
force = 50 //SMASHY SMASHY!!
|
||||
internal_damage_threshold = 0
|
||||
step_in = 3
|
||||
pixel_x = -16
|
||||
layer = ABOVE_MOB_LAYER
|
||||
breach_time = 100 //ten seconds till all goes to shit
|
||||
recharge_rate = 100
|
||||
wreckage = /obj/structure/mecha_wreckage/durand/neovgre
|
||||
|
||||
/obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar!
|
||||
internals_action.Grant(user, src)
|
||||
cycle_action.Grant(user, src)
|
||||
lights_action.Grant(user, src)
|
||||
stats_action.Grant(user, src)
|
||||
strafing_action.Grant(user, src)
|
||||
|
||||
/obj/mecha/combat/neovgre/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
internals_action.Remove(user)
|
||||
cycle_action.Remove(user)
|
||||
lights_action.Remove(user)
|
||||
stats_action.Remove(user)
|
||||
strafing_action.Remove(user)
|
||||
|
||||
/obj/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
to_chat(user, "<span class='brass'>BEGONE HERETIC!</span>")
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/mecha/combat/neovgre/moved_inside(mob/living/carbon/human/H)
|
||||
var/list/Itemlist = H.get_contents()
|
||||
for(var/obj/item/clockwork/slab/W in Itemlist)
|
||||
to_chat(H, "<span class='brass'>You safely store [W] inside [src].</span>")
|
||||
qdel(W)
|
||||
. = ..()
|
||||
|
||||
/obj/mecha/combat/neovgre/obj_destruction()
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<span class='brass'>You are consumed by the fires raging within Neovgre...</span>")
|
||||
M.dust()
|
||||
playsound(src, 'sound/magic/lightning_chargeup.ogg', 100, 0)
|
||||
src.visible_message("<span class = 'userdanger'>The reactor has gone critical, its going to blow!</span>")
|
||||
addtimer(CALLBACK(src,.proc/go_critical),breach_time)
|
||||
|
||||
/obj/mecha/combat/neovgre/proc/go_critical()
|
||||
explosion(get_turf(loc), 3, 5, 10, 20, 30)
|
||||
Destroy(src)
|
||||
|
||||
/obj/mecha/combat/neovgre/container_resist(mob/living/user)
|
||||
to_chat(user, "<span class='brass'>Neovgre requires a lifetime commitment friend, no backing out now!</span>")
|
||||
return
|
||||
|
||||
/obj/mecha/combat/neovgre/process()
|
||||
..()
|
||||
if(GLOB.ratvar_awakens) // At this point only timley intervention by lord singulo could hople to stop the superweapon
|
||||
cell.charge = INFINITY
|
||||
max_integrity = INFINITY
|
||||
obj_integrity = max_integrity
|
||||
CHECK_TICK //Just to be on the safe side lag wise
|
||||
else if(cell.charge < cell.maxcharge)
|
||||
for(var/obj/effect/clockwork/sigil/transmission/T in range(SIGIL_ACCESS_RANGE, src))
|
||||
var/delta = min(recharge_rate, cell.maxcharge - cell.charge)
|
||||
if (get_clockwork_power() <= delta)
|
||||
cell.charge += delta
|
||||
adjust_clockwork_power(-delta)
|
||||
CHECK_TICK
|
||||
|
||||
/obj/mecha/combat/neovgre/Initialize()
|
||||
.=..()
|
||||
GLOB.neovgre_exists ++
|
||||
var/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/N = new
|
||||
N.attach(src)
|
||||
|
||||
/obj/structure/mecha_wreckage/durand/neovgre
|
||||
name = "\improper Neovgre wreckage?"
|
||||
desc = "On closer inspection this looks like the wreck of a durand with some spraypainted cardboard duct taped to it!"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre
|
||||
equip_cooldown = 8 //Rapid fire heavy laser cannon, simple yet elegant
|
||||
energy_drain = 30
|
||||
name = "Aribter Laser Cannon"
|
||||
desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Nanotrasen issue Solaris laser cannon - Nezbere"
|
||||
fire_sound = "sound/weapons/neovgre_laser.ogg"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/can_attach(obj/mecha/combat/neovgre/M)
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
@@ -49,6 +49,8 @@
|
||||
var/lights = FALSE
|
||||
var/lights_power = 6
|
||||
var/last_user_hud = 1 // used to show/hide the mecha hud while preserving previous preference
|
||||
var/breach_time = 0
|
||||
var/recharge_rate = 0
|
||||
|
||||
var/bumpsmash = 0 //Whether or not the mech destroys walls by running into it.
|
||||
//inner atmos
|
||||
|
||||
@@ -342,12 +342,41 @@ update_label("John Doe", "Clowny")
|
||||
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
|
||||
assignment = "Prisoner"
|
||||
registered_name = "Scum"
|
||||
access = list(ACCESS_ENTER_GENPOP)
|
||||
|
||||
//Lavaland labor camp
|
||||
var/goal = 0 //How far from freedom?
|
||||
var/points = 0
|
||||
//Genpop
|
||||
var/sentence = 0 //When world.time is greater than this number, the card will have its ACCESS_ENTER_GENPOP access replaced with ACCESS_LEAVE_GENPOP the next time it's checked, unless this value is 0/null
|
||||
var/crime= "\[REDACTED\]"
|
||||
|
||||
/obj/item/card/id/prisoner/attack_self(mob/user)
|
||||
to_chat(usr, "<span class='notice'>You have accumulated [points] out of the [goal] points you need for freedom.</span>")
|
||||
/obj/item/card/id/prisoner/GetAccess()
|
||||
if((sentence && world.time >= sentence) || (goal && points >= goal))
|
||||
access = list(ACCESS_LEAVE_GENPOP)
|
||||
return ..()
|
||||
|
||||
/obj/item/card/id/prisoner/process()
|
||||
if(!sentence)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
if(world.time >= sentence)
|
||||
playsound(loc, 'sound/machines/ping.ogg', 50, 1)
|
||||
if(isliving(loc))
|
||||
to_chat(loc, "<span class='boldnotice'>[src]</span><span class='notice'> buzzes: You have served your sentence! You may now exit prison through the turnstiles and collect your belongings.</span>")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
|
||||
/obj/item/card/id/prisoner/examine(mob/user)
|
||||
. = ..()
|
||||
if(sentence && world.time < sentence)
|
||||
to_chat(user, "<span class='notice'>You're currently serving a sentence for [crime]. <b>[DisplayTimeText(sentence - world.time)]</b> left.</span>")
|
||||
else if(goal)
|
||||
to_chat(user, "<span class='notice'>You have accumulated [points] out of the [goal] points you need for freedom.</span>")
|
||||
else if(!sentence)
|
||||
to_chat(user, "<span class='warning'>You are currently serving a permanent sentence for [crime].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Your sentence is up! You're free!</span>")
|
||||
|
||||
/obj/item/card/id/prisoner/one
|
||||
name = "Prisoner #13-001"
|
||||
|
||||
@@ -174,6 +174,7 @@
|
||||
gender = PLURAL
|
||||
var/open_panel = 0
|
||||
can_attach_mob = TRUE
|
||||
full_damage_on_mobs = TRUE
|
||||
|
||||
/obj/item/grenade/plastic/c4/New()
|
||||
wires = new /datum/wires/explosive/c4(src)
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/obj/structure/closet/secure_closet/genpop
|
||||
desc = "It's a secure locker for inmates's personal belongings."
|
||||
var/default_desc = "It's a secure locker for the storage inmates's personal belongings during their time in prison."
|
||||
name = "prisoner closet"
|
||||
var/default_name = "prisoner closet"
|
||||
req_access = list(ACCESS_BRIG)
|
||||
var/obj/item/card/id/prisoner/registered_id = null
|
||||
icon_state = "prisoner"
|
||||
locked = FALSE
|
||||
anchored = TRUE
|
||||
opened = TRUE
|
||||
density = FALSE
|
||||
|
||||
/obj/structure/closet/secure_closet/genpop/attackby(obj/item/W, mob/user, params)
|
||||
if(!broken && locked && W == registered_id) //Prisoner opening
|
||||
handle_prisoner_id(user)
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/genpop/proc/handle_prisoner_id(mob/user)
|
||||
var/obj/item/card/id/prisoner/prisoner_id = null
|
||||
for(prisoner_id in user.held_items)
|
||||
if(prisoner_id != registered_id)
|
||||
prisoner_id = null
|
||||
else
|
||||
break
|
||||
|
||||
if(!prisoner_id)
|
||||
to_chat(user, "<span class='danger'>Access Denied.</span>")
|
||||
return FALSE
|
||||
|
||||
qdel(registered_id)
|
||||
registered_id = null
|
||||
locked = FALSE
|
||||
open(user)
|
||||
desc = "It's a secure locker for prisoner effects."
|
||||
to_chat(user, "<span class='notice'>You insert your prisoner id into \the [src] and it springs open!</span>")
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/secure_closet/genpop/proc/handle_edit_sentence(mob/user)
|
||||
var/prisoner_name = input(user, "Please input the name of the prisoner.", "Prisoner Name", registered_id.registered_name) as text|null
|
||||
if(prisoner_name == null | !user.Adjacent(src))
|
||||
return FALSE
|
||||
var/sentence_length = input(user, "Please input the length of their sentence in minutes (0 for perma).", "Sentence Length", registered_id.sentence) as num|null
|
||||
if(sentence_length == null | !user.Adjacent(src))
|
||||
return FALSE
|
||||
var/crimes = input(user, "Please input their crimes.", "Crimes", registered_id.crime) as text|null
|
||||
if(crimes == null | !user.Adjacent(src))
|
||||
return FALSE
|
||||
|
||||
registered_id.registered_name = prisoner_name
|
||||
var/filteredsentlength = text2num(sentence_length)
|
||||
registered_id.sentence = filteredsentlength ? (filteredsentlength MINUTES) + world.time : 0
|
||||
registered_id.crime = crimes
|
||||
registered_id.update_label(prisoner_name, registered_id.assignment)
|
||||
if(registered_id.sentence)
|
||||
START_PROCESSING(SSobj, registered_id)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, registered_id)
|
||||
|
||||
name = "[default_name] ([prisoner_name])"
|
||||
desc = "[default_desc] It contains the personal effects of [prisoner_name]."
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/secure_closet/genpop/togglelock(mob/living/user)
|
||||
if(!allowed(user))
|
||||
return ..()
|
||||
|
||||
if(!broken && locked && registered_id != null)
|
||||
var/name = registered_id.registered_name
|
||||
var/result = alert(user, "This locker currently contains [name]'s personal belongings ","Locker In Use","Reset","Amend ID", "Open")
|
||||
if(!user.Adjacent(src))
|
||||
return
|
||||
if(result == "Reset")
|
||||
name = default_name
|
||||
desc = default_desc
|
||||
registered_id = null
|
||||
if(result == "Open" | result == "Reset")
|
||||
locked = FALSE
|
||||
open(user)
|
||||
if(result == "Amend ID")
|
||||
handle_edit_sentence(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/genpop/close(mob/living/user)
|
||||
if(registered_id != null)
|
||||
locked = TRUE
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/genpop/attack_hand(mob/user)
|
||||
if(user.lying && get_dist(src, user) > 0)
|
||||
return
|
||||
|
||||
if(!broken && registered_id != null && registered_id in user.held_items)
|
||||
handle_prisoner_id(user)
|
||||
return
|
||||
|
||||
if(!broken && opened && !locked && allowed(user) && !registered_id) //Genpop setup
|
||||
|
||||
registered_id = new /obj/item/card/id/prisoner/(src.contents)
|
||||
if(handle_edit_sentence(user))
|
||||
close(user)
|
||||
locked = TRUE
|
||||
update_icon()
|
||||
registered_id.forceMove(src.loc)
|
||||
new /obj/item/clothing/under/rank/prisoner(src.loc)
|
||||
else
|
||||
qdel(registered_id)
|
||||
registered_id = null
|
||||
|
||||
return
|
||||
|
||||
..()
|
||||
@@ -26,7 +26,7 @@
|
||||
sub_role = "Scientist"
|
||||
outfit = /datum/outfit/abductor/scientist
|
||||
landmark_type = /obj/effect/landmark/abductor/scientist
|
||||
greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
|
||||
greet_text = "Use your experimental console and surgical equipment to monitor your agent and experiment upon abducted humans."
|
||||
show_in_antagpanel = TRUE
|
||||
|
||||
/datum/antagonist/abductor/create_team(datum/team/abductor_team/new_team)
|
||||
@@ -40,15 +40,14 @@
|
||||
return team
|
||||
|
||||
/datum/antagonist/abductor/on_gain()
|
||||
owner.special_role = "[name] [sub_role]"
|
||||
owner.assigned_role = "[name] [sub_role]"
|
||||
owner.objectives += team.objectives
|
||||
owner.special_role = "[name]"
|
||||
owner.assigned_role = "[name]"
|
||||
objectives += team.objectives
|
||||
finalize_abductor()
|
||||
ADD_TRAIT(owner, TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/abductor/on_removal()
|
||||
owner.objectives -= team.objectives
|
||||
if(owner.current)
|
||||
to_chat(owner.current,"<span class='userdanger'>You are no longer the [owner.special_role]!</span>")
|
||||
owner.special_role = null
|
||||
@@ -66,6 +65,7 @@
|
||||
//Equip
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
H.set_species(/datum/species/abductor)
|
||||
|
||||
H.real_name = "[team.name] [sub_role]"
|
||||
H.equipOutfit(outfit)
|
||||
|
||||
@@ -99,8 +99,8 @@
|
||||
else
|
||||
return
|
||||
new_owner.add_antag_datum(src)
|
||||
log_admin("[key_name(usr)] made [key_name(new_owner.current)] [name] on [choice]!")
|
||||
message_admins("[key_name_admin(usr)] made [key_name_admin(new_owner.current)] [name] on [choice] !")
|
||||
log_admin("[key_name(usr)] made [key_name(new_owner)] [name] on [choice]!")
|
||||
message_admins("[key_name_admin(usr)] made [key_name_admin(new_owner)] [name] on [choice] !")
|
||||
|
||||
/datum/antagonist/abductor/get_admin_commands()
|
||||
. = ..()
|
||||
@@ -153,7 +153,7 @@
|
||||
result += "<span class='header'>The abductors of [name] were:</span>"
|
||||
for(var/datum/mind/abductor_mind in members)
|
||||
result += printplayer(abductor_mind)
|
||||
result += printobjectives(abductor_mind)
|
||||
result += printobjectives(objectives)
|
||||
|
||||
return "<div class='panel redborder'>[result.Join("<br>")]</div>"
|
||||
|
||||
@@ -178,7 +178,6 @@
|
||||
var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random))
|
||||
var/datum/objective/abductee/O = new objtype()
|
||||
objectives += O
|
||||
owner.objectives += objectives
|
||||
|
||||
/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override)
|
||||
update_abductor_icons_added(mob_override ? mob_override.mind : owner,"abductee")
|
||||
|
||||
@@ -135,12 +135,14 @@
|
||||
/obj/item/abductor/proc/AbductorCheck(mob/user)
|
||||
if(HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING))
|
||||
return TRUE
|
||||
if (istype(user) && user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>You can't figure how this works!</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/item/abductor/proc/ScientistCheck(mob/user)
|
||||
var/training = HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING)
|
||||
var/sci_training = HAS_TRAIT(user, TRAIT_ABDUCTOR_SCIENTIST_TRAINING)
|
||||
var/training = HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING) || (user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
|
||||
var/sci_training = HAS_TRAIT(user, TRAIT_ABDUCTOR_SCIENTIST_TRAINING) || (user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_SCIENTIST_TRAINING))
|
||||
|
||||
if(training && !sci_training)
|
||||
to_chat(user, "<span class='warning'>You're not trained to use this!</span>")
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/obj/item/organ/heart/gland/examine(mob/user)
|
||||
. = ..()
|
||||
if(HAS_TRAIT(user, TRAIT_ABDUCTOR_SCIENTIST_TRAINING) || isobserver(user))
|
||||
if((user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_SCIENTIST_TRAINING)) || isobserver(user))
|
||||
to_chat(user, "<span class='notice'>It is \a [true_name].</span>")
|
||||
|
||||
/obj/item/organ/heart/gland/proc/ownerCheck()
|
||||
@@ -48,19 +48,19 @@
|
||||
|
||||
/obj/item/organ/heart/gland/proc/mind_control(command, mob/living/user)
|
||||
if(!ownerCheck() || !mind_control_uses || active_mind_control)
|
||||
return
|
||||
return FALSE
|
||||
mind_control_uses--
|
||||
to_chat(owner, "<span class='userdanger'>You suddenly feel an irresistible compulsion to follow an order...</span>")
|
||||
to_chat(owner, "<span class='mind_control'>[command]</span>")
|
||||
active_mind_control = TRUE
|
||||
log_admin("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]")
|
||||
message_admins("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]")
|
||||
update_gland_hud()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/clear_mind_control), mind_control_duration)
|
||||
|
||||
/obj/item/organ/heart/gland/proc/clear_mind_control()
|
||||
if(!ownerCheck() || !active_mind_control)
|
||||
return
|
||||
return FALSE
|
||||
to_chat(owner, "<span class='userdanger'>You feel the compulsion fade, and you completely forget about your previous orders.</span>")
|
||||
active_mind_control = FALSE
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING))
|
||||
if(!HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING) && !HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
|
||||
to_chat(user, "<span class='warning'>You start mashing alien buttons at random!</span>")
|
||||
if(do_after(user,100, target = src))
|
||||
TeleporterSend()
|
||||
|
||||
@@ -119,3 +119,33 @@
|
||||
var/datum/clockwork_scripture/create_object/construct/clockwork_marauder/CM = new()
|
||||
CM.recent_marauders--
|
||||
qdel(CM)
|
||||
|
||||
//Summon Neovgre: Summon a very powerful combat mech that explodes when destroyed for massive damage.
|
||||
/datum/clockwork_scripture/create_object/summon_arbiter
|
||||
descname = "Powerful Assault Mech"
|
||||
name = "Summon Neovgre, the Anima Bulwark"
|
||||
desc = "Calls forth the mighty Anima Bulwark, a weapon of unmatched power,\
|
||||
mech with superior defensive and offensive capabilities. It will \
|
||||
steadily regenerate HP and triple its regeneration speed while standing \
|
||||
on a clockwork tile. It will automatically draw power from nearby sigils of \
|
||||
transmission should the need arise. Its Arbiter laser cannon can decimate foes \
|
||||
from a range and is capable of smashing through any barrier presented to it. \
|
||||
Be warned, choosing to pilot Neovgre is a lifetime commitment, once you are \
|
||||
in you cannot leave and when it is destroyed it will explode catastrophically with you inside."
|
||||
invocations = list("By the strength of the alloy...!!", "...call forth the Arbiter!!")
|
||||
channel_time = 200 // This is a strong fucking weapon, 20 seconds channel time is getting off light I tell ya.
|
||||
power_cost = 75000 //75 KW
|
||||
usage_tip = "Neovgre is a powerful mech that will crush your enemies!"
|
||||
invokers_required = 5
|
||||
multiple_invokers_used = TRUE
|
||||
object_path = /obj/mecha/combat/neovgre
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
primary_component = BELLIGERENT_EYE
|
||||
sort_priority = 2
|
||||
creator_message = "<span class='brass'>Neovgre, the Anima Bulwark towers over you... your enemies reckoning has come.</span>"
|
||||
|
||||
/datum/clockwork_scripture/create_object/summon_arbiter/check_special_requirements()
|
||||
if(GLOB.neovgre_exists)
|
||||
to_chat(invoker, "<span class='brass'>\"You've already got one...\"</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -210,9 +210,9 @@
|
||||
|
||||
return cached_results["fire"] ? REACTING : NO_REACTION
|
||||
|
||||
//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again)
|
||||
//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again). Again!
|
||||
//Fusion Rework Counter: Please increment this if you make a major overhaul to this system again.
|
||||
//5 reworks
|
||||
//6 reworks
|
||||
|
||||
/datum/gas_reaction/fusion
|
||||
exclude = FALSE
|
||||
@@ -220,100 +220,79 @@
|
||||
name = "Plasmic Fusion"
|
||||
id = "fusion"
|
||||
|
||||
//Since fusion isn't really intended to happen in successive chains, the requirements are very high
|
||||
/datum/gas_reaction/fusion/init_reqs()
|
||||
min_requirements = list(
|
||||
"TEMP" = FUSION_TEMPERATURE_THRESHOLD,
|
||||
"ENER" = FUSION_ENERGY_THRESHOLD,
|
||||
/datum/gas/tritium = FUSION_TRITIUM_MOLES_USED,
|
||||
/datum/gas/plasma = FUSION_MOLE_THRESHOLD,
|
||||
/datum/gas/tritium = FUSION_MOLE_THRESHOLD
|
||||
)
|
||||
/datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD)
|
||||
|
||||
/datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder)
|
||||
var/list/cached_gases = air.gases
|
||||
var/temperature = air.temperature
|
||||
if(!air.analyzer_results)
|
||||
air.analyzer_results = new
|
||||
var/list/cached_scan_results = air.analyzer_results
|
||||
var/turf/open/location
|
||||
if (istype(holder,/datum/pipeline)) //Find the tile the reaction is occuring on, or a random part of the network if it's a pipenet.
|
||||
var/datum/pipeline/fusion_pipenet = holder
|
||||
location = get_turf(pick(fusion_pipenet.members))
|
||||
else
|
||||
location = get_turf(holder)
|
||||
|
||||
if(!air.analyzer_results)
|
||||
air.analyzer_results = new
|
||||
var/list/cached_scan_results = air.analyzer_results
|
||||
var/old_heat_capacity = air.heat_capacity()
|
||||
var/reaction_energy = 0
|
||||
|
||||
var/mediation = FUSION_MEDIATION_FACTOR*(air.heat_capacity()-(cached_gases[/datum/gas/plasma]*GLOB.meta_gas_specific_heats[/datum/gas/plasma]))/(air.total_moles()-cached_gases[/datum/gas/plasma]) //This is the average specific heat of the mixture,not including plasma.
|
||||
|
||||
var/gases_fused = air.total_moles() - cached_gases[/datum/gas/plasma]
|
||||
var/plasma_differential = (cached_gases[/datum/gas/plasma] - gases_fused) / air.total_moles()
|
||||
var/reaction_efficiency = FUSION_EFFICIENCY_BASE ** -((plasma_differential ** 2) / FUSION_EFFICIENCY_DIVISOR) //https://www.desmos.com/calculator/6jjx3vdrvx
|
||||
|
||||
var/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions.
|
||||
var/initial_plasma = cached_gases[/datum/gas/plasma]
|
||||
var/initial_carbon = cached_gases[/datum/gas/carbon_dioxide]
|
||||
var/scale_factor = (air.volume)/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions.
|
||||
var/toroidal_size = (2*PI)+TORADIANS(arctan((air.volume-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
|
||||
var/gas_power = 0
|
||||
var/list/gas_fusion_powers = GLOB.meta_gas_fusions
|
||||
for (var/gas_id in cached_gases)
|
||||
gas_power += reaction_efficiency * (GLOB.meta_gas_fusions[gas_id]*cached_gases[gas_id])
|
||||
gas_power += (gas_fusion_powers[gas_id]*cached_gases[gas_id])
|
||||
var/instability = MODULUS((gas_power*INSTABILITY_GAS_POWER_FACTOR)**2,toroidal_size) //Instability effects how chaotic the behavior of the reaction is
|
||||
cached_scan_results[id] = instability//used for analyzer feedback
|
||||
|
||||
var/power_ratio = gas_power/mediation
|
||||
cached_scan_results[id] = power_ratio //used for analyzer feedback
|
||||
var/plasma = (initial_plasma-FUSION_MOLE_THRESHOLD)/(scale_factor) //We have to scale the amounts of carbon and plasma down a significant amount in order to show the chaotic dynamics we want
|
||||
var/carbon = (initial_carbon-FUSION_MOLE_THRESHOLD)/(scale_factor) //We also subtract out the threshold amount to make it harder for fusion to burn itself out.
|
||||
|
||||
for (var/gas_id in cached_gases) //and now we fuse
|
||||
cached_gases[gas_id] = 0
|
||||
//The reaction is a specific form of the Kicked Rotator system, which displays chaotic behavior and can be used to model particle interactions.
|
||||
plasma = MODULUS(plasma - (instability*sin(TODEGREES(carbon))), toroidal_size)
|
||||
carbon = MODULUS(carbon - plasma, toroidal_size)
|
||||
|
||||
var/radiation_power = (FUSION_RADIATION_FACTOR * power_ratio) / (power_ratio + FUSION_RADIATION_CONSTANT) //https://www.desmos.com/calculator/4i1f296phl
|
||||
var/zap_power = ((FUSION_ZAP_POWER_ASYMPTOTE * power_ratio) / (power_ratio + FUSION_ZAP_POWER_CONSTANT)) + FUSION_ZAP_POWER_BASE //https://www.desmos.com/calculator/n0zkdpxnrr
|
||||
var/do_explosion = FALSE
|
||||
var/zap_range //these ones are set later
|
||||
var/fusion_prepare_to_die_edition_rng
|
||||
|
||||
if (power_ratio > FUSION_SUPER_TIER_THRESHOLD) //power ratio 50+: SUPER TIER. The gases become so energized that they fuse into a ton of tritium, which is pretty nice! Until you consider the fact that everything just exploded, the canister is probably going to break and you're irradiated.
|
||||
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_SUPER * (power_ratio / FUSION_ENERGY_DIVISOR_SUPER)
|
||||
cached_gases[/datum/gas/tritium] += gases_fused * FUSION_GAS_CREATION_FACTOR_TRITIUM //60% of the gas is converted to energy, 40% to trit
|
||||
fusion_prepare_to_die_edition_rng = 100 //Wait a minute..
|
||||
do_explosion = TRUE
|
||||
zap_range = FUSION_ZAP_RANGE_SUPER
|
||||
cached_gases[/datum/gas/plasma] = plasma*scale_factor + FUSION_MOLE_THRESHOLD //Scales the gases back up
|
||||
cached_gases[/datum/gas/carbon_dioxide] = carbon*scale_factor + FUSION_MOLE_THRESHOLD
|
||||
var/delta_plasma = initial_plasma - cached_gases[/datum/gas/plasma]
|
||||
|
||||
else if (power_ratio > FUSION_HIGH_TIER_THRESHOLD) //power ratio 20-50; High tier. The reaction is so energized that it fuses into a small amount of stimulum, and some pluoxium. Very dangerous, but super cool and super useful.
|
||||
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_HIGH * (power_ratio / FUSION_ENERGY_DIVISOR_HIGH)
|
||||
cached_gases[/datum/gas/stimulum] += gases_fused * FUSION_GAS_CREATION_FACTOR_STIM //40% of the gas is converted to energy, 60% to stim and pluox
|
||||
cached_gases[/datum/gas/pluoxium] += gases_fused * FUSION_GAS_CREATION_FACTOR_PLUOX
|
||||
fusion_prepare_to_die_edition_rng = power_ratio //Now we're getting into dangerous territory
|
||||
do_explosion = TRUE
|
||||
zap_range = FUSION_ZAP_RANGE_HIGH
|
||||
|
||||
else if (power_ratio > FUSION_MID_TIER_THRESHOLD) //power_ratio 5 to 20; Mediation is overpowered, fusion reaction starts to break down.
|
||||
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_MID * (power_ratio / FUSION_ENERGY_DIVISOR_MID)
|
||||
cached_gases[/datum/gas/nitryl] += gases_fused * FUSION_GAS_CREATION_FACTOR_NITRYL //20% of the gas is converted to energy, 80% to nitryl and N2O
|
||||
cached_gases[/datum/gas/nitrous_oxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_N2O
|
||||
fusion_prepare_to_die_edition_rng = power_ratio * FUSION_MID_TIER_RAD_PROB_FACTOR //Still unlikely, but don't stand next to the reaction unprotected
|
||||
zap_range = FUSION_ZAP_RANGE_MID
|
||||
|
||||
else //power ratio 0 to 5; Gas power is overpowered. Fusion isn't nearly as powerful.
|
||||
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_LOW * (power_ratio / FUSION_ENERGY_DIVISOR_LOW)
|
||||
cached_gases[/datum/gas/bz] += gases_fused * FUSION_GAS_CREATION_FACTOR_BZ //10% of the gas is converted to energy, 90% to BZ and CO2
|
||||
cached_gases[/datum/gas/carbon_dioxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_CO2
|
||||
fusion_prepare_to_die_edition_rng = power_ratio * FUSION_LOW_TIER_RAD_PROB_FACTOR //Low, but still something to look out for
|
||||
zap_range = FUSION_ZAP_RANGE_LOW
|
||||
|
||||
//All the deadly consequences of fusion, consolidated for your viewing pleasure
|
||||
if (location)
|
||||
if(prob(fusion_prepare_to_die_edition_rng)) //Some.. permanent effects
|
||||
if(do_explosion)
|
||||
explosion(location, 0, 0, 5, power_ratio, TRUE, TRUE) //large shockwave, the actual radius is quite small - people will recognize that you're doing fusion
|
||||
radiation_pulse(location, radiation_power) //You mean causing a super-tier fusion reaction in the halls is a bad idea?
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, 30000)//The science is cool though.
|
||||
playsound(location, 'sound/effects/supermatter.ogg', 100, 0)
|
||||
else
|
||||
playsound(location, 'sound/effects/phasein.ogg', 75, 0)
|
||||
//These will always happen, so be prepared
|
||||
tesla_zap(location, zap_range, zap_power, TESLA_FUSION_FLAGS) //larpers beware
|
||||
location.fire_nuclear_particles(power_ratio) //see code/modules/projectile/energy/nuclear_particle.dm
|
||||
reaction_energy += delta_plasma*PLASMA_BINDING_ENERGY //Energy is gained or lost corresponding to the creation or destruction of mass.
|
||||
if(instability < FUSION_INSTABILITY_ENDOTHERMALITY)
|
||||
reaction_energy = max(reaction_energy,0) //Stable reactions don't end up endothermic.
|
||||
else if (reaction_energy < 0)
|
||||
reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5
|
||||
|
||||
if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist.
|
||||
cached_gases[/datum/gas/plasma] = initial_plasma
|
||||
cached_gases[/datum/gas/carbon_dioxide] = initial_carbon
|
||||
return NO_REACTION
|
||||
cached_gases[/datum/gas/tritium] -= FUSION_TRITIUM_MOLES_USED
|
||||
//The decay of the tritium and the reaction's energy produces waste gases, different ones depending on whether the reaction is endo or exothermic
|
||||
if(reaction_energy > 0)
|
||||
cached_gases[/datum/gas/oxygen] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
cached_gases[/datum/gas/nitrous_oxide] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
else
|
||||
cached_gases[/datum/gas/bz] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
cached_gases[/datum/gas/nitryl] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
|
||||
if(reaction_energy)
|
||||
if(location)
|
||||
var/particle_chance = ((PARTICLE_CHANCE_CONSTANT)/(reaction_energy-PARTICLE_CHANCE_CONSTANT)) + 1//Asymptopically approaches 100% as the energy of the reaction goes up.
|
||||
if(prob(PERCENT(particle_chance)))
|
||||
location.fire_nuclear_particle()
|
||||
var/rad_power = max((FUSION_RAD_COEFFICIENT/instability) + FUSION_RAD_MAX,0)
|
||||
radiation_pulse(location,rad_power)
|
||||
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.temperature = max(((temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB)
|
||||
air.temperature = CLAMP(((air.temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY)
|
||||
return REACTING
|
||||
|
||||
/datum/gas_reaction/nitrylformation //The formation of nitryl. Endothermic. Requires N2O as a catalyst.
|
||||
|
||||
@@ -86,6 +86,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/skin_tone = "caucasian1" //Skin color
|
||||
var/eye_color = "000" //Eye color
|
||||
var/horn_color = "85615a" //Horn color
|
||||
var/wing_color = "fff" //Wing color
|
||||
var/datum/species/pref_species = new /datum/species/human() //Mutant race
|
||||
var/list/features = list("mcolor" = "FFF",
|
||||
"tail_lizard" = "Smooth",
|
||||
@@ -591,6 +592,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<h3>Decorative wings</h3>"
|
||||
|
||||
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=deco_wings;task=input'>[features["deco_wings"]]</a>"
|
||||
dat += "<span style='border:1px solid #161616; background-color: #[wing_color];'> </span> <a href='?_src_=prefs;preference=wings_color;task=input'>Change</a><BR>"
|
||||
|
||||
if("insect_wings" in pref_species.default_features)
|
||||
if(!mutant_category)
|
||||
dat += APPEARANCE_CATEGORY_COLUMN
|
||||
@@ -598,6 +601,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<h3>Insect wings</h3>"
|
||||
|
||||
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=insect_wings;task=input'>[features["insect_wings"]]</a>"
|
||||
dat += "<span style='border:1px solid #161616; background-color: #[wing_color];'> </span> <a href='?_src_=prefs;preference=wings_color;task=input'>Change</a><BR>"
|
||||
mutant_category++
|
||||
if(mutant_category >= MAX_MUTANT_ROWS)
|
||||
dat += "</td>"
|
||||
@@ -1689,7 +1693,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("horns_color")
|
||||
var/new_horn_color = input(user, "Choose your character's horn colour:", "Character Preference","#"+horn_color) as color|null
|
||||
if(new_horn_color)
|
||||
horn_color = sanitize_hexcolor(new_horn_color)
|
||||
if (new_horn_color == "#000000")
|
||||
horn_color = "#85615A"
|
||||
else
|
||||
horn_color = sanitize_hexcolor(new_horn_color)
|
||||
|
||||
if("wings")
|
||||
var/new_wings
|
||||
@@ -1697,6 +1704,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(new_wings)
|
||||
features["wings"] = new_wings
|
||||
|
||||
if("wings_color")
|
||||
var/new_wing_color = input(user, "Choose your character's wing colour:", "Character Preference","#"+wing_color) as color|null
|
||||
if(new_wing_color)
|
||||
if (new_wing_color == "#000000")
|
||||
wing_color = "#FFFFFF"
|
||||
else
|
||||
wing_color = sanitize_hexcolor(new_wing_color)
|
||||
|
||||
if("frills")
|
||||
var/new_frills
|
||||
new_frills = input(user, "Choose your character's frills:", "Character Preference") as null|anything in GLOB.frills_list
|
||||
@@ -1730,13 +1745,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
new_insect_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.insect_wings_list
|
||||
if(new_insect_wings)
|
||||
features["insect_wings"] = new_insect_wings
|
||||
|
||||
|
||||
if("deco_wings")
|
||||
var/new_deco_wings
|
||||
new_deco_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.deco_wings_list
|
||||
if(new_deco_wings)
|
||||
features["deco_wings"] = new_deco_wings
|
||||
|
||||
|
||||
if("insect_fluffs")
|
||||
var/new_insect_fluff
|
||||
new_insect_fluff = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.insect_fluffs_list
|
||||
@@ -2262,6 +2277,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
character.hair_color = hair_color
|
||||
character.facial_hair_color = facial_hair_color
|
||||
character.horn_color = horn_color
|
||||
character.wing_color = wing_color
|
||||
|
||||
character.skin_tone = skin_tone
|
||||
character.hair_style = hair_style
|
||||
|
||||
@@ -317,6 +317,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000")
|
||||
WRITE_FILE(S["features["mcolor"]"] , "#FFF")
|
||||
|
||||
if(!S["features["horn_color"]"] || S["features["horn_color"]"] == "#000")
|
||||
WRITE_FILE(S["features["horn_color"]"] , "#85615a")
|
||||
|
||||
if(!S["features["wing_color"]"] || S["features["wing_color"]"] == "#000")
|
||||
WRITE_FILE(S["features["wing_color"]"] , "#FFF")
|
||||
|
||||
//Character
|
||||
S["real_name"] >> real_name
|
||||
S["nameless"] >> nameless
|
||||
@@ -338,6 +344,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["socks"] >> socks
|
||||
S["socks_color"] >> socks_color
|
||||
S["horn_color"] >> horn_color
|
||||
S["wing_color"] >> wing_color
|
||||
S["backbag"] >> backbag
|
||||
S["jumpsuit_style"] >> jumpsuit_style
|
||||
S["uplink_loc"] >> uplink_spawn_loc
|
||||
@@ -449,6 +456,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
if(!features["mcolor"] || features["mcolor"] == "#000")
|
||||
features["mcolor"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
|
||||
|
||||
if(!features["horn_color"] || features["horn_color"] == "#000")
|
||||
features["horn_color"] = "85615a"
|
||||
|
||||
if(!features["wing_color"] || features["wing_color"] == "#000")
|
||||
features["wing_color"] = "FFFFFF"
|
||||
|
||||
nameless = sanitize_integer(nameless, 0, 1, initial(nameless))
|
||||
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
|
||||
be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body))
|
||||
@@ -471,6 +484,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
eye_color = sanitize_hexcolor(eye_color, 3, 0)
|
||||
skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones)
|
||||
horn_color = sanitize_hexcolor(horn_color, 3, FALSE)
|
||||
wing_color = sanitize_hexcolor(wing_color, 3, FALSE, "#FFFFFF")
|
||||
backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag))
|
||||
jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style))
|
||||
uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc))
|
||||
@@ -485,7 +499,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
features["body_markings"] = sanitize_inlist(features["body_markings"], GLOB.body_markings_list)
|
||||
features["feature_lizard_legs"] = sanitize_inlist(features["legs"], GLOB.legs_list)
|
||||
features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list)
|
||||
features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list)
|
||||
features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list, "None")
|
||||
features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list)
|
||||
|
||||
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
|
||||
@@ -540,6 +554,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["socks"] , socks)
|
||||
WRITE_FILE(S["socks_color"] , socks_color)
|
||||
WRITE_FILE(S["horn_color"] , horn_color)
|
||||
WRITE_FILE(S["wing_color"] , wing_color)
|
||||
WRITE_FILE(S["backbag"] , backbag)
|
||||
WRITE_FILE(S["jumpsuit_style"] , jumpsuit_style)
|
||||
WRITE_FILE(S["uplink_loc"] , uplink_spawn_loc)
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]")
|
||||
IF_HAS_BLOOD_DNA(src)
|
||||
if(taurmode >= SNEK_TAURIC)
|
||||
if(tauric)
|
||||
. += mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "[blood_overlay_type]blood")
|
||||
else
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood")
|
||||
|
||||
@@ -133,18 +133,6 @@
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
|
||||
/datum/crafting_recipe/minigun
|
||||
name = "Laser Minigun"
|
||||
result = /obj/item/minigunpack2
|
||||
reqs = list(/obj/item/gun/energy/laser/carbine = 3,
|
||||
/obj/item/stack/sheet/plasteel = 5,
|
||||
/obj/item/stack/cable_coil = 30,
|
||||
/obj/item/stock_parts/cell/bluespace = 2)
|
||||
tools = list(TOOL_WIRECUTTER, TOOL_SCREWDRIVER, TOOL_WELDER)
|
||||
time = 150
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
|
||||
/datum/crafting_recipe/ed209
|
||||
name = "ED209"
|
||||
result = /mob/living/simple_animal/bot/ed209
|
||||
|
||||
@@ -32,8 +32,6 @@
|
||||
determine_wave_type()
|
||||
|
||||
/datum/round_event/meteor_wave/proc/determine_wave_type()
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
|
||||
wave_name = "halloween"
|
||||
if(!wave_name)
|
||||
wave_name = pickweight(list(
|
||||
"normal" = 50,
|
||||
@@ -45,7 +43,10 @@
|
||||
if("threatening")
|
||||
wave_type = GLOB.meteors_threatening
|
||||
if("catastrophic")
|
||||
wave_type = GLOB.meteors_catastrophic
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
|
||||
wave_type = GLOB.meteorsSPOOKY
|
||||
else
|
||||
wave_type = GLOB.meteors_catastrophic
|
||||
if("meaty")
|
||||
wave_type = GLOB.meteorsB
|
||||
if("space dust")
|
||||
|
||||
@@ -771,7 +771,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
..()
|
||||
var/turf/source = random_far_turf()
|
||||
if(!sound_type)
|
||||
sound_type = pick("airlock","airlock pry","console","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack")
|
||||
sound_type = pick("airlock","airlock pry","console","flash","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack")
|
||||
feedback_details += "Type: [sound_type]"
|
||||
//Strange audio
|
||||
switch(sound_type)
|
||||
@@ -788,6 +788,8 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
target.playsound_local(source,'sound/effects/explosion1.ogg', 50, 1)
|
||||
else
|
||||
target.playsound_local(source, 'sound/effects/explosion2.ogg', 50, 1)
|
||||
if("flash")
|
||||
target.playsound_local(source, 'sound/weapons/flash.ogg', 50, 1)
|
||||
if("far explosion")
|
||||
target.playsound_local(source, 'sound/effects/explosionfar.ogg', 50, 1)
|
||||
if("glass")
|
||||
@@ -1291,4 +1293,4 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
H.hal_target = target
|
||||
H.preparePixelProjectile(target, start)
|
||||
H.fire()
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_BAR)
|
||||
|
||||
/proc/get_all_accesses()
|
||||
return list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT,
|
||||
return list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP,
|
||||
ACCESS_MEDICAL, ACCESS_GENETICS, ACCESS_MORGUE, ACCESS_RD,
|
||||
ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_CHEMISTRY, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_MAINT_TUNNELS,
|
||||
ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD,
|
||||
@@ -157,7 +157,7 @@
|
||||
if(1) //station general
|
||||
return list(ACCESS_KITCHEN,ACCESS_BAR, ACCESS_HYDROPONICS, ACCESS_JANITOR, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_LIBRARY, ACCESS_THEATRE, ACCESS_LAWYER)
|
||||
if(2) //security
|
||||
return list(ACCESS_SEC_DOORS, ACCESS_WEAPONS, ACCESS_SECURITY, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT, ACCESS_HOS)
|
||||
return list(ACCESS_SEC_DOORS, ACCESS_WEAPONS, ACCESS_SECURITY, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT, ACCESS_HOS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP,)
|
||||
if(3) //medbay
|
||||
return list(ACCESS_MEDICAL, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MORGUE, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_SURGERY, ACCESS_CMO)
|
||||
if(4) //research
|
||||
@@ -312,6 +312,10 @@
|
||||
return "Gateway"
|
||||
if(ACCESS_SEC_DOORS)
|
||||
return "Brig"
|
||||
if(ACCESS_ENTER_GENPOP)
|
||||
return "Prison Turnstile Entrance"
|
||||
if(ACCESS_LEAVE_GENPOP)
|
||||
return "Prison Turnstile Exit"
|
||||
if(ACCESS_MINERAL_STOREROOM)
|
||||
return "Mineral Storage"
|
||||
if(ACCESS_MINISAT)
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
outfit = /datum/outfit/job/hos
|
||||
mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM)
|
||||
|
||||
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS,
|
||||
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP,
|
||||
ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS,
|
||||
ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING,
|
||||
ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM)
|
||||
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS,
|
||||
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP,
|
||||
ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS,
|
||||
ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING,
|
||||
ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM)
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
outfit = /datum/outfit/job/security
|
||||
|
||||
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM)
|
||||
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) // See /datum/job/officer/get_access()
|
||||
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM)
|
||||
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_MINERAL_STOREROOM) // See /datum/job/officer/get_access()
|
||||
|
||||
mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM)
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
outfit = /datum/outfit/job/warden
|
||||
|
||||
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM)
|
||||
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) // See /datum/job/warden/get_access()
|
||||
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM)
|
||||
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_MINERAL_STOREROOM) // See /datum/job/warden/get_access()
|
||||
|
||||
mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
heat_protection = CHEST|GROIN|LEGS|ARMS
|
||||
hoodtype = /obj/item/clothing/head/hooded/explorer
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
|
||||
flags_inv = HIDEJUMPSUIT|HIDETAUR
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
|
||||
resistance_flags = FIRE_PROOF
|
||||
tauric = TRUE //Citadel Add for tauric hardsuits
|
||||
@@ -129,7 +130,7 @@
|
||||
|
||||
/obj/item/clothing/suit/hooded/explorer/seva
|
||||
name = "SEVA Suit"
|
||||
desc = "A fire-proof suit for exploring hot environments."
|
||||
desc = "A fire-proof suit for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer."
|
||||
icon_state = "seva"
|
||||
item_state = "seva"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
@@ -141,7 +142,7 @@
|
||||
|
||||
/obj/item/clothing/head/hooded/explorer/seva
|
||||
name = "SEVA Hood"
|
||||
desc = "A fire-proof hood for exploring hot environments."
|
||||
desc = "A fire-proof hood for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer."
|
||||
icon_state = "seva"
|
||||
item_state = "seva"
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
@@ -159,7 +160,7 @@
|
||||
|
||||
/obj/item/clothing/suit/hooded/explorer/exo
|
||||
name = "Exo-suit"
|
||||
desc = "A robust suit for exploring dangerous environments."
|
||||
desc = "A robust suit for fighting dangerous animals. Its design and material make it harder for a Goliath to keep their grip on the wearer."
|
||||
icon_state = "exo"
|
||||
item_state = "exo"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
@@ -170,7 +171,7 @@
|
||||
|
||||
/obj/item/clothing/head/hooded/explorer/exo
|
||||
name = "Exo-hood"
|
||||
desc = "A robust helmet for exploring dangerous environments."
|
||||
desc = "A robust helmet for fighting dangerous animals. Its design and material make it harder for a Goliath to keep their grip on the wearer."
|
||||
icon_state = "exo"
|
||||
item_state = "exo"
|
||||
armor = list("melee" = 65, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 60, "bio" = 25, "rad" = 10, "fire" = 0, "acid" = 0)
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
hair_color = random_short_color()
|
||||
facial_hair_color = hair_color
|
||||
eye_color = random_eye_color()
|
||||
horn_color = "85615a"
|
||||
wing_color = "fff"
|
||||
if(!pref_species)
|
||||
var/rando_race = pick(GLOB.roundstart_races)
|
||||
pref_species = new rando_race()
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
// Decorative wings
|
||||
/datum/sprite_accessory/deco_wings
|
||||
icon = 'icons/mob/wings.dmi'
|
||||
color_src = WINGCOLOR
|
||||
|
||||
/datum/sprite_accessory/deco_wings/plain
|
||||
name = "Plain"
|
||||
@@ -104,6 +105,22 @@
|
||||
center = TRUE
|
||||
dimension_y = 34
|
||||
|
||||
/datum/sprite_accessory/deco_wings/bee
|
||||
name = "Bee"
|
||||
icon_state = "bee"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/fairy
|
||||
name = "Fairy"
|
||||
icon_state = "fairy"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/bat
|
||||
name = "Bat"
|
||||
icon_state = "bat"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/feathery
|
||||
name = "Feathery"
|
||||
icon_state = "feathery"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
@@ -113,7 +130,7 @@
|
||||
|
||||
/datum/sprite_accessory/insect_wings
|
||||
icon = 'icons/mob/wings.dmi'
|
||||
color_src = null
|
||||
color_src = WINGCOLOR
|
||||
|
||||
/datum/sprite_accessory/insect_wings/none
|
||||
name = "None"
|
||||
@@ -183,35 +200,10 @@
|
||||
name = "Snow"
|
||||
icon_state = "snow"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/colored
|
||||
name = "Colored (Hair)"
|
||||
icon_state = "snowplain"
|
||||
color_src = HAIR
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/colored1
|
||||
name = "Colored (Primary)"
|
||||
icon_state = "snowplain"
|
||||
color_src = MUTCOLORS
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/colored2
|
||||
name = "Colored (Secondary)"
|
||||
icon_state = "snowplain"
|
||||
color_src = MUTCOLORS2
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/colored3
|
||||
name = "Colored (Tertiary)"
|
||||
icon_state = "snowplain"
|
||||
color_src = MUTCOLORS3
|
||||
|
||||
/datum/sprite_accessory/insect_wings/bee
|
||||
name = "Bee"
|
||||
icon_state = "bee"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/bee_color
|
||||
name = "Bee (Hair colored)"
|
||||
icon_state = "bee"
|
||||
color_src = HAIR
|
||||
|
||||
/datum/sprite_accessory/insect_wings/fairy
|
||||
name = "Fairy"
|
||||
icon_state = "fairy"
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
var/horn_color = "85615a" //specific horn colors, because why not?
|
||||
|
||||
var/wing_color = "fff" //wings too
|
||||
|
||||
var/skin_tone = "caucasian1" //Skin tone
|
||||
|
||||
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
|
||||
|
||||
@@ -37,6 +37,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
|
||||
|
||||
var/horn_color //specific horn colors, because why not?
|
||||
var/wing_color
|
||||
|
||||
var/use_skintones = 0 // does it use skintones or not? (spoiler alert this is only used by humans)
|
||||
var/exotic_blood = "" // If your race wants to bleed something other than bog standard blood, change this to reagent id.
|
||||
@@ -869,6 +870,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
accessory_overlay.color = "#[H.eye_color]"
|
||||
if(HORNCOLOR)
|
||||
accessory_overlay.color = "#[H.horn_color]"
|
||||
if(WINGCOLOR)
|
||||
accessory_overlay.color = "#[H.wing_color]"
|
||||
else
|
||||
accessory_overlay.color = forced_colour
|
||||
else
|
||||
@@ -946,6 +949,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
if(HORNCOLOR)
|
||||
extra_accessory_overlay.color = "#[H.horn_color]"
|
||||
if(WINGCOLOR)
|
||||
extra_accessory_overlay.color = "#[H.wing_color]"
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
extra_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
@@ -985,6 +990,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
extra2_accessory_overlay.color = "#[H.hair_color]"
|
||||
if(HORNCOLOR)
|
||||
extra2_accessory_overlay.color = "#[H.horn_color]"
|
||||
if(WINGCOLOR)
|
||||
extra2_accessory_overlay.color = "#[H.wing_color]"
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
extra2_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
id = "insect"
|
||||
say_mod = "flutters"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(LIPS,NOEYES,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR)
|
||||
species_traits = list(LIPS,NOEYES,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_BUG)
|
||||
mutant_bodyparts = list("mam_ears", "mam_snout", "mam_tail", "taur", "insect_wings", "mam_snouts", "insect_fluff","horns")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None",
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
id = "felinid"
|
||||
limbs_id = "human"
|
||||
|
||||
mutant_bodyparts = list("mam_ears", "mam_tail")
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "Cat", "mam_ears" = "Cat", "wings" = "None")
|
||||
mutant_bodyparts = list("mam_ears", "mam_tail", "deco_wings")
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "Cat", "mam_ears" = "Cat", "wings" = "None", "deco_wings" = "None")
|
||||
|
||||
mutantears = /obj/item/organ/ears/cat
|
||||
mutanttail = /obj/item/organ/tail/cat
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
id = "mammal"
|
||||
default_color = "4B4B4B"
|
||||
should_draw_citadel = TRUE
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "deco_wings", "taur", "horns", "legs")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None",
|
||||
|
||||
@@ -1,41 +1,42 @@
|
||||
/datum/species/human
|
||||
name = "Human"
|
||||
id = "human"
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY)
|
||||
mutant_bodyparts = list("ears", "tail_human", "wings", "taur") // CITADEL EDIT gives humans snowflake parts
|
||||
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "None")
|
||||
use_skintones = 1
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
disliked_food = GROSS | RAW
|
||||
liked_food = JUNKFOOD | FRIED
|
||||
|
||||
/datum/species/human/qualifies_for_rank(rank, list/features)
|
||||
return TRUE //Pure humans are always allowed in all roles.
|
||||
|
||||
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
|
||||
/datum/species/human/spec_stun(mob/living/carbon/human/H,amount)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
. = ..()
|
||||
|
||||
/datum/species/human/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
|
||||
|
||||
/datum/species/human/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("waggingtail_human" in mutant_bodyparts)
|
||||
|
||||
/datum/species/human/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("tail_human" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "tail_human"
|
||||
mutant_bodyparts |= "waggingtail_human"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/human/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("waggingtail_human" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "waggingtail_human"
|
||||
mutant_bodyparts |= "tail_human"
|
||||
H.update_body()
|
||||
/datum/species/human
|
||||
name = "Human"
|
||||
id = "human"
|
||||
default_color = "FFFFFF"
|
||||
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR)
|
||||
mutant_bodyparts = list("ears", "tail_human", "wings", "taur", "deco_wings") // CITADEL EDIT gives humans snowflake parts
|
||||
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
use_skintones = 1
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
disliked_food = GROSS | RAW
|
||||
liked_food = JUNKFOOD | FRIED
|
||||
|
||||
/datum/species/human/qualifies_for_rank(rank, list/features)
|
||||
return TRUE //Pure humans are always allowed in all roles.
|
||||
|
||||
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
|
||||
/datum/species/human/spec_stun(mob/living/carbon/human/H,amount)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
. = ..()
|
||||
|
||||
/datum/species/human/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
|
||||
|
||||
/datum/species/human/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("waggingtail_human" in mutant_bodyparts)
|
||||
|
||||
/datum/species/human/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("tail_human" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "tail_human"
|
||||
mutant_bodyparts |= "waggingtail_human"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/human/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("waggingtail_human" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "waggingtail_human"
|
||||
mutant_bodyparts |= "tail_human"
|
||||
H.update_body()
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
id = "jelly"
|
||||
default_color = "00FF90"
|
||||
say_mod = "chirps"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD,WINGCOLOR)
|
||||
mutantlungs = /obj/item/organ/lungs/slime
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur") //CIT CHANGE
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None") //CIT CHANGE
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur", "deco_wings") //CIT CHANGE
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None") //CIT CHANGE
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
|
||||
exotic_blood = "slimejelly"
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
id = "lizard"
|
||||
say_mod = "hisses"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_REPTILE)
|
||||
mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur")
|
||||
mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur", "deco_wings")
|
||||
mutanttongue = /obj/item/organ/tongue/lizard
|
||||
mutanttail = /obj/item/organ/tail/lizard
|
||||
coldmod = 1.5
|
||||
heatmod = 0.67
|
||||
default_features = list("mcolor" = "0F0", "mcolor2" = "0F0", "mcolor3" = "0F0", "tail_lizard" = "Smooth", "snout" = "Round",
|
||||
"horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None",
|
||||
"legs" = "Digitigrade", "taur" = "None")
|
||||
"legs" = "Digitigrade", "taur" = "None", "deco_wings" = "None")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
|
||||
|
||||
|
||||
/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE)
|
||||
/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE, knockdown_stamoverride, knockdown_stammax)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!effect || (hit_percent <= 0))
|
||||
return 0
|
||||
@@ -87,7 +87,7 @@
|
||||
if(EFFECT_STUN)
|
||||
Stun(effect * hit_percent)
|
||||
if(EFFECT_KNOCKDOWN)
|
||||
Knockdown(effect * hit_percent)
|
||||
Knockdown(effect * hit_percent, override_stamdmg = knockdown_stammax ? CLAMP(knockdown_stamoverride, 0, knockdown_stammax-getStaminaLoss()) : knockdown_stamoverride)
|
||||
if(EFFECT_UNCONSCIOUS)
|
||||
Unconscious(effect * hit_percent)
|
||||
if(EFFECT_IRRADIATE)
|
||||
@@ -107,13 +107,13 @@
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0)
|
||||
/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0, kd_stamoverride, kd_stammax)
|
||||
if(blocked >= 100)
|
||||
return 0
|
||||
if(stun)
|
||||
apply_effect(stun, EFFECT_STUN, blocked)
|
||||
if(knockdown)
|
||||
apply_effect(knockdown, EFFECT_KNOCKDOWN, blocked)
|
||||
apply_effect(knockdown, EFFECT_KNOCKDOWN, blocked, kd_stamoverride, kd_stammax)
|
||||
if(unconscious)
|
||||
apply_effect(unconscious, EFFECT_UNCONSCIOUS, blocked)
|
||||
if(irradiate)
|
||||
|
||||
@@ -226,6 +226,9 @@
|
||||
to_chat(src,"<span class='userdanger'>ERROR: Module installer reply timeout. Please check internal connections.</span>")
|
||||
return
|
||||
|
||||
if(!CONFIG_GET(flag/disable_secborg) && GLOB.security_level < CONFIG_GET(number/minimum_secborg_alert))
|
||||
to_chat(src, "<span class='notice'>NOTICE: Due to local station regulations, the security cyborg module and its variants are only available during [num2seclevel(CONFIG_GET(number/minimum_secborg_alert))] alert and greater.</span>")
|
||||
|
||||
var/list/modulelist = list("Standard" = /obj/item/robot_module/standard, \
|
||||
"Engineering" = /obj/item/robot_module/engineering, \
|
||||
"Medical" = /obj/item/robot_module/medical, \
|
||||
@@ -234,7 +237,7 @@
|
||||
"Service" = /obj/item/robot_module/butler)
|
||||
if(!CONFIG_GET(flag/disable_peaceborg))
|
||||
modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper
|
||||
if(!CONFIG_GET(flag/disable_secborg))
|
||||
if(BORG_SEC_AVAILABLE)
|
||||
modulelist["Security"] = /obj/item/robot_module/security
|
||||
|
||||
modulelist += get_cit_modules() //Citadel change - adds Citadel's borg modules.
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
C.adjustBruteLoss(-5)
|
||||
C.adjustFireLoss(-5)
|
||||
C.adjustOxyLoss(-5)
|
||||
C.adjustToxLoss(-5)
|
||||
C.adjustToxLoss(-5, forced = TRUE)
|
||||
var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(C))
|
||||
if(namedatum)
|
||||
H.color = namedatum.colour
|
||||
|
||||
@@ -421,7 +421,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
if(prob(50))
|
||||
radiation_pulse(src, power * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + ((pluoxiumcomp * PLUOXIUM_RADIOACTIVITY_MODIFIER) * pluoxiumbonus) * (power_transmission_bonus/(10-(bzcomp * BZ_RADIOACTIVITY_MODIFIER))))) // Rad Modifiers BZ(500%), Tritium(300%), and Pluoxium(-200%)
|
||||
if(bzcomp >= 0.4 && prob(30 * bzcomp))
|
||||
src.fire_nuclear_particles() // Start to emit radballs at a maximum of 30% chance per tick
|
||||
fire_nuclear_particle() // Start to emit radballs at a maximum of 30% chance per tick
|
||||
|
||||
var/device_energy = power * REACTION_POWER_MODIFIER
|
||||
|
||||
|
||||
@@ -71,9 +71,3 @@
|
||||
projectile_type = /obj/item/projectile/beam/mindflayer
|
||||
select_name = "MINDFUCK"
|
||||
fire_sound = 'sound/weapons/laser.ogg'
|
||||
|
||||
/obj/item/ammo_casing/energy/laser/weak
|
||||
projectile_type = /obj/item/projectile/beam/weak/minigun
|
||||
e_cost = 10
|
||||
fire_sound = 'sound/weapons/gatling.ogg'
|
||||
click_cooldown_override = 1
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
//The ammo/gun is stored in a back slot item
|
||||
/obj/item/minigunpack2
|
||||
name = " Laser Gatling Pack"
|
||||
desc = "A massive battery pack with an attached laser gatling gun!"
|
||||
icon = 'icons/obj/guns/minigun.dmi'
|
||||
icon_state = "holstered"
|
||||
item_state = "backpack"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/backpack_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi'
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
var/obj/item/gun/energy/minigun/gun
|
||||
var/armed = 0 //whether the gun is attached, 0 is attached, 1 is the gun is wielded.
|
||||
var/overheat = 0
|
||||
var/overheat_max = 60
|
||||
var/heat_diffusion = 5
|
||||
|
||||
/obj/item/minigunpack2/Initialize()
|
||||
. = ..()
|
||||
gun = new(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/minigunpack2/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/minigunpack2/process()
|
||||
overheat = max(0, overheat - heat_diffusion)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/minigunpack2/attack_hand(var/mob/living/carbon/user)
|
||||
if(src.loc == user)
|
||||
if(!armed)
|
||||
if(user.get_item_by_slot(SLOT_BACK) == src)
|
||||
armed = 1
|
||||
if(!user.put_in_hands(gun))
|
||||
armed = 0
|
||||
to_chat(user, "<span class='warning'>You need a free hand to hold the gun!</span>")
|
||||
return
|
||||
update_icon()
|
||||
user.update_inv_back()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You are already holding the gun!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/minigunpack2/attackby(obj/item/W, mob/user, params)
|
||||
if(W == gun) //Don't need armed check, because if you have the gun assume its armed.
|
||||
user.dropItemToGround(gun, TRUE)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/minigunpack2/dropped(mob/user)
|
||||
if(armed)
|
||||
user.dropItemToGround(gun, TRUE)
|
||||
|
||||
/obj/item/minigunpack2/MouseDrop(atom/over_object)
|
||||
. = ..()
|
||||
if(armed)
|
||||
return
|
||||
if(iscarbon(usr))
|
||||
var/mob/M = usr
|
||||
|
||||
if(!over_object)
|
||||
return
|
||||
|
||||
if(!M.incapacitated())
|
||||
|
||||
if(istype(over_object, /obj/screen/inventory/hand))
|
||||
var/obj/screen/inventory/hand/H = over_object
|
||||
M.putItemFromInventoryInHandIfPossible(src, H.held_index)
|
||||
|
||||
|
||||
/obj/item/minigunpack2/update_icon()
|
||||
if(armed)
|
||||
icon_state = "notholstered"
|
||||
else
|
||||
icon_state = "holstered"
|
||||
|
||||
/obj/item/minigunpack2/proc/attach_gun(var/mob/user)
|
||||
if(!gun)
|
||||
gun = new(src)
|
||||
gun.forceMove(src)
|
||||
armed = 0
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>You attach the [gun.name] to the [name].</span>")
|
||||
else
|
||||
src.visible_message("<span class='warning'>The [gun.name] snaps back onto the [name]!</span>")
|
||||
update_icon()
|
||||
user.update_inv_back()
|
||||
|
||||
|
||||
/obj/item/gun/energy/minigun
|
||||
name = "laser gatling gun"
|
||||
desc = "An advanced laser cannon with an incredible rate of fire. Requires a bulky backpack power source to use."
|
||||
icon = 'icons/obj/guns/minigun.dmi'
|
||||
icon_state = "minigun_spin"
|
||||
item_state = "minigun"
|
||||
flags_1 = CONDUCT_1
|
||||
force = 15
|
||||
recoil = 2
|
||||
slowdown = 1
|
||||
slot_flags = null
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
materials = list()
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/weak)
|
||||
burst_size = 2
|
||||
automatic = 1
|
||||
can_charge = 0
|
||||
selfcharge = EGUN_SELFCHARGE
|
||||
charge_tick = 2
|
||||
charge_delay = 5
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
item_flags = NEEDS_PERMIT | SLOWS_WHILE_IN_HAND
|
||||
var/obj/item/minigunpack2/ammo_pack
|
||||
|
||||
/obj/item/gun/energy/minigun/Initialize()
|
||||
if(istype(loc, /obj/item/minigunpack2)) //We should spawn inside an ammo pack so let's use that one.
|
||||
ammo_pack = loc
|
||||
else
|
||||
return INITIALIZE_HINT_QDEL //No pack, no gun
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/minigun/attack_self(mob/living/user)
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/minigun/dropped(mob/user)
|
||||
if(ammo_pack)
|
||||
ammo_pack.attach_gun(user)
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/item/gun/energy/minigun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
|
||||
if(ammo_pack)
|
||||
if(ammo_pack.overheat < ammo_pack.overheat_max)
|
||||
ammo_pack.overheat += burst_size
|
||||
..()
|
||||
else
|
||||
to_chat(user, "The gun's heat sensor locked the trigger to prevent lens damage.")
|
||||
|
||||
/obj/item/gun/energy/minigun/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(!ammo_pack || ammo_pack.loc != user)
|
||||
to_chat(user, "You need the backpack power source to fire the gun!")
|
||||
. = ..()
|
||||
|
||||
/obj/item/gun/energy/minigun/dropped(mob/living/user)
|
||||
ammo_pack.attach_gun(user)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
name = "hybrid taser"
|
||||
desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams."
|
||||
icon_state = "advtaser"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler)
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/electrode)
|
||||
ammo_x_offset = 2
|
||||
|
||||
/obj/item/gun/energy/e_gun/advtaser/cyborg
|
||||
|
||||
@@ -88,6 +88,8 @@
|
||||
//Effects
|
||||
var/stun = 0
|
||||
var/knockdown = 0
|
||||
var/knockdown_stamoverride
|
||||
var/knockdown_stam_max
|
||||
var/unconscious = 0
|
||||
var/irradiate = 0
|
||||
var/stutter = 0
|
||||
@@ -202,7 +204,7 @@
|
||||
else
|
||||
L.log_message("has been shot by [firer] with [src]", LOG_ATTACK, color="orange")
|
||||
|
||||
return L.apply_effects(stun, knockdown, unconscious, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter)
|
||||
return L.apply_effects(stun, knockdown, unconscious, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter, knockdown_stamoverride, knockdown_stam_max)
|
||||
|
||||
/obj/item/projectile/proc/vol_by_damage()
|
||||
if(src.damage)
|
||||
|
||||
@@ -39,14 +39,6 @@
|
||||
/obj/item/projectile/beam/weak
|
||||
damage = 15
|
||||
|
||||
/obj/item/projectile/beam/weak/minigun
|
||||
damage = 12.5
|
||||
armour_penetration = 40
|
||||
|
||||
/obj/item/projectile/beam/weak/minigun/Initialize()
|
||||
.=..()
|
||||
speed = pick(0.7,0.75,0.8,0.85,0.9,0.95,1,1.05,1.1,1.15)
|
||||
|
||||
/obj/item/projectile/beam/weak/penetrator
|
||||
armour_penetration = 50
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
name = "nuclear particle"
|
||||
icon_state = "nuclear_particle"
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
damage = 20
|
||||
damage_type = TOX
|
||||
irradiate = 2500 //enough to knockdown and induce vomiting
|
||||
speed = 0.4
|
||||
flag = "rad"
|
||||
irradiate = 5000
|
||||
speed = 0.4
|
||||
hitsound = 'sound/weapons/emitter2.ogg'
|
||||
impact_type = /obj/effect/projectile/impact/xray
|
||||
var/static/list/particle_colors = list(
|
||||
@@ -25,22 +24,6 @@
|
||||
add_atom_colour(particle_colors[our_color], FIXED_COLOUR_PRIORITY)
|
||||
set_light(4, 3, particle_colors[our_color]) //Range of 4, brightness of 3 - Same range as a flashlight
|
||||
|
||||
/atom/proc/fire_nuclear_particles(power_ratio) //used by fusion to fire random # of nuclear particles - power ratio determines about how many are fired
|
||||
var/random_particles = rand(3,6)
|
||||
var/particles_to_fire
|
||||
var/particles_fired
|
||||
switch(power_ratio) //multiply random_particles * factor for whatever tier
|
||||
if(0 to FUSION_MID_TIER_THRESHOLD)
|
||||
particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_LOW
|
||||
if(FUSION_MID_TIER_THRESHOLD to FUSION_HIGH_TIER_THRESHOLD)
|
||||
particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_MID
|
||||
if(FUSION_HIGH_TIER_THRESHOLD to FUSION_SUPER_TIER_THRESHOLD)
|
||||
particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_HIGH
|
||||
if(FUSION_SUPER_TIER_THRESHOLD to INFINITY)
|
||||
particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_SUPER
|
||||
while(particles_to_fire)
|
||||
particles_fired++
|
||||
var/angle = rand(0,360)
|
||||
var/obj/item/projectile/energy/nuclear_particle/P = new /obj/item/projectile/energy/nuclear_particle(src)
|
||||
addtimer(CALLBACK(P, /obj/item/projectile.proc/fire, angle), particles_fired) //multiply particles fired * delay so the particles end up stagnated (once every decisecond)
|
||||
particles_to_fire--
|
||||
/atom/proc/fire_nuclear_particle(angle = rand(0,360)) //used by fusion to fire random nuclear particles. Fires one particle in a random direction.
|
||||
var/obj/item/projectile/energy/nuclear_particle/P = new /obj/item/projectile/energy/nuclear_particle(src)
|
||||
P.fire(angle)
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
icon_state = "spark"
|
||||
color = "#FFFF00"
|
||||
nodamage = 1
|
||||
knockdown = 100
|
||||
knockdown = 60
|
||||
knockdown_stamoverride = 36
|
||||
knockdown_stam_max = 50
|
||||
stutter = 5
|
||||
jitter = 20
|
||||
hitsound = 'sound/weapons/taserhit.ogg'
|
||||
@@ -11,6 +13,7 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/stun
|
||||
muzzle_type = /obj/effect/projectile/muzzle/stun
|
||||
impact_type = /obj/effect/projectile/impact/stun
|
||||
var/tase_duration = 50
|
||||
|
||||
/obj/item/projectile/energy/electrode/on_hit(atom/target, blocked = FALSE)
|
||||
. = ..()
|
||||
@@ -23,6 +26,7 @@
|
||||
if(C.dna && C.dna.check_mutation(HULK))
|
||||
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
|
||||
else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE))
|
||||
C.apply_status_effect(STATUS_EFFECT_TASED, tase_duration)
|
||||
addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5)
|
||||
|
||||
/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
if(replaced_by == /datum/surgery)
|
||||
return FALSE
|
||||
|
||||
if(HAS_TRAIT(user, TRAIT_SURGEON))
|
||||
if(HAS_TRAIT(user, TRAIT_SURGEON) || HAS_TRAIT(user.mind, TRAIT_SURGEON))
|
||||
if(replaced_by)
|
||||
return FALSE
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user