Merge branch 'master' of https://github.com/ParadiseSS13/Paradise into turfs

# Conflicts:
#	code/modules/mob/living/simple_animal/hostile/hostile.dm
This commit is contained in:
Mark van Alphen
2019-04-04 22:04:55 +02:00
73 changed files with 846 additions and 577 deletions
+6 -6
View File
@@ -2364,42 +2364,42 @@
/area/awaymission/spacehotel)
"ev" = (
/obj/machinery/door/unpowered/hotel_door{
icon = 'icons/obj/doors/Doorgold.dmi';
icon = 'icons/obj/doors/doorgold.dmi';
id = 110
},
/turf/unsimulated/floor/carpet,
/area/awaymission/spacehotel)
"ew" = (
/obj/machinery/door/unpowered/hotel_door{
icon = 'icons/obj/doors/Doorgold.dmi';
icon = 'icons/obj/doors/doorgold.dmi';
id = 111
},
/turf/unsimulated/floor/carpet,
/area/awaymission/spacehotel)
"ex" = (
/obj/machinery/door/unpowered/hotel_door{
icon = 'icons/obj/doors/Doorgold.dmi';
icon = 'icons/obj/doors/doorgold.dmi';
id = 112
},
/turf/unsimulated/floor/carpet,
/area/awaymission/spacehotel)
"ey" = (
/obj/machinery/door/unpowered/hotel_door{
icon = 'icons/obj/doors/Doorgold.dmi';
icon = 'icons/obj/doors/doorgold.dmi';
id = 210
},
/turf/unsimulated/floor/carpet,
/area/awaymission/spacehotel)
"ez" = (
/obj/machinery/door/unpowered/hotel_door{
icon = 'icons/obj/doors/Doorgold.dmi';
icon = 'icons/obj/doors/doorgold.dmi';
id = 211
},
/turf/unsimulated/floor/carpet,
/area/awaymission/spacehotel)
"eA" = (
/obj/machinery/door/unpowered/hotel_door{
icon = 'icons/obj/doors/Doorgold.dmi';
icon = 'icons/obj/doors/doorgold.dmi';
id = 212
},
/turf/unsimulated/floor/carpet,
+6
View File
@@ -215,6 +215,9 @@
// Automatic localhost admin disable
var/disable_localhost_admin = 0
//Start now warning
var/start_now_confirmation = 0
// Lavaland
var/lavaland_budget = 60
@@ -647,6 +650,9 @@
if("disable_karma")
config.disable_karma = 1
if("start_now_confirmation")
config.start_now_confirmation = 1
if("tick_limit_mc_init")
config.tick_limit_mc_init = text2num(value)
+6
View File
@@ -870,6 +870,7 @@
special_role = SPECIAL_ROLE_WIZARD
//ticker.mode.learn_basic_spells(current)
ticker.mode.update_wiz_icons_added(src)
SEND_SOUND(current, 'sound/ambience/antag/ragesmages.ogg')
to_chat(current, "<span class='danger'>You are a Space Wizard!</span>")
current.faction = list("wizard")
log_admin("[key_name(usr)] has wizarded [key_name(current)]")
@@ -911,6 +912,7 @@
ticker.mode.grant_changeling_powers(current)
ticker.mode.update_change_icons_added(src)
special_role = SPECIAL_ROLE_CHANGELING
SEND_SOUND(current, 'sound/ambience/antag/ling_aler.ogg')
to_chat(current, "<B><font color='red'>Your powers have awoken. A flash of memory returns to us... we are a changeling!</font></B>")
log_admin("[key_name(usr)] has changelinged [key_name(current)]")
message_admins("[key_name_admin(usr)] has changelinged [key_name_admin(current)]")
@@ -955,6 +957,7 @@
slaved.masters += src
som = slaved //we MIGT want to mindslave someone
special_role = SPECIAL_ROLE_VAMPIRE
SEND_SOUND(current, 'sound/ambience/antag/vampalert.ogg')
to_chat(current, "<B><font color='red'>Your powers have awoken. Your lust for blood grows... You are a Vampire!</font></B>")
log_admin("[key_name(usr)] has vampired [key_name(current)]")
message_admins("[key_name_admin(usr)] has vampired [key_name_admin(current)]")
@@ -1157,6 +1160,9 @@
if(isAI(current))
var/mob/living/silicon/ai/A = current
ticker.mode.add_law_zero(A)
SEND_SOUND(current, 'sound/ambience/antag/malf.ogg')
else
SEND_SOUND(current, 'sound/ambience/antag/tatoralert.ogg')
ticker.mode.update_traitor_icons_added(src)
if("autoobjectives")
+1 -1
View File
@@ -1199,7 +1199,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/datum/supply_packs/organic/hydroponics/beekeeping_fullkit
name = "Beekeeping Starter Kit"
contains = list(/obj/structure/beebox,
contains = list(/obj/structure/beebox/unwrenched,
/obj/item/honey_frame,
/obj/item/honey_frame,
/obj/item/honey_frame,
+26 -7
View File
@@ -90,7 +90,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
if(hijack_only)
if(!(locate(/datum/objective/hijack) in usr.mind.objectives))
to_chat(usr, "<span class='warning'>The Syndicate lacks resources to provide you with this item.</span>")
to_chat(usr, "<span class='warning'>The Syndicate will only issue this extremely dangerous item to agents assigned the Hijack objective.</span>")
return
if(item)
@@ -182,6 +182,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
cost = 3
job = list("Clown")
/datum/uplink_item/jobspecific/trick_revolver
name = "Trick Revolver"
desc = "A revolver that will fire backwards and kill whoever attempts to use it. Perfect for those pesky vigilante or just a good laugh."
reference = "CTR"
item = /obj/item/toy/russian_revolver/trick_revolver
cost = 1
job = list("Clown")
//mime
/datum/uplink_item/jobspecific/caneshotgun
name = "Cane Shotgun and Assassination Shells"
@@ -921,6 +929,8 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
reference = "SB"
item = /obj/item/radio/beacon/syndicate/bomb
cost = 11
surplus = 0
cant_discount = TRUE
/datum/uplink_item/explosives/syndicate_minibomb
name = "Syndicate Minibomb"
@@ -970,13 +980,22 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
gamemodes = list(/datum/game_mode/nuclear)
surplus = 0
/datum/uplink_item/explosives/atmosgrenades
name = "Atmos Grenades"
desc = "A box of two (2) grenades that wreak havoc with the atmosphere of the target area. Capable of engulfing a large area in lit plasma, or N2O. Deploy with extreme caution!"
reference = "AGG"
item = /obj/item/storage/box/syndie_kit/atmosgasgrenades
cost = 11
/datum/uplink_item/explosives/atmosn2ogrenades
name = "Knockout Gas Grenades"
desc = "A box of two (2) grenades that spread knockout gas over a large area. Equip internals before using one of these."
reference = "ANG"
item = /obj/item/storage/box/syndie_kit/atmosn2ogrenades
cost = 8
/datum/uplink_item/explosives/atmosfiregrenades
name = "Plasma Fire Grenades"
desc = "A box of two (2) grenades that cause large plasma fires. Can be used to deny access to a large area. Most useful if you have an atmospherics hardsuit."
reference = "APG"
item = /obj/item/storage/box/syndie_kit/atmosfiregrenades
hijack_only = TRUE
cost = 12
surplus = 0
cant_discount = TRUE
/datum/uplink_item/explosives/emp
name = "EMP Grenades and Implanter Kit"
@@ -130,8 +130,10 @@
forge_traitor_objectives(newtraitor.mind)
if(istype(newtraitor, /mob/living/silicon))
SEND_SOUND(newtraitor, 'sound/ambience/antag/malf.ogg')
add_law_zero(newtraitor)
else
SEND_SOUND(newtraitor, 'sound/ambience/antag/tatoralert.ogg')
equip_traitor(newtraitor)
traitors += newtraitor.mind
+10 -9
View File
@@ -45,7 +45,6 @@
var/obj/structure/blob/factory/factory = null
var/list/human_overlays = list()
var/is_zombie = 0
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
pressure_resistance = 100 //100 kPa difference required to push
throw_pressure_limit = 120 //120 kPa difference required to throw
@@ -68,15 +67,17 @@
/mob/living/simple_animal/hostile/blob/blobspore/Life(seconds, times_fired)
if(!is_zombie && isturf(src.loc))
for(var/mob/living/carbon/human/H in oview(src,1)) //Only for corpse right next to/on same tile
if(H.stat == DEAD)
for(var/mob/living/carbon/human/H in oview(src, 1)) //Only for corpse right next to/on same tile
if(H.stat == DEAD || (!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD))
Zombify(H)
break
..()
/mob/living/simple_animal/hostile/blob/blobspore/proc/Zombify(var/mob/living/carbon/human/H)
/mob/living/simple_animal/hostile/blob/blobspore/proc/Zombify(mob/living/carbon/human/H)
if(!H.check_death_method())
H.death()
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
is_zombie = 1
is_zombie = TRUE
if(H.wear_suit)
var/obj/item/clothing/suit/armor/A = H.wear_suit
if(A.armor && A.armor["melee"])
@@ -90,14 +91,15 @@
icon = H.icon
speak_emote = list("groans")
icon_state = "zombie2_s"
head_organ.h_style = null
if(head_organ)
head_organ.h_style = null
H.update_hair()
human_overlays = H.overlays
update_icons()
H.loc = src
H.forceMove(src)
pressure_resistance = 20 //5 kPa difference required to push lowered
throw_pressure_limit = 30 //15 kPa difference required to throw lowered
loc.visible_message("<span class='warning'>The corpse of [H.name] suddenly rises!</span>")
visible_message("<span class='warning'>The corpse of [H.name] suddenly rises!</span>")
/mob/living/simple_animal/hostile/blob/blobspore/death(gibbed)
// Only execute the below if we successfuly died
@@ -174,7 +176,6 @@
force_threshold = 10
mob_size = MOB_SIZE_LARGE
environment_smash = ENVIRONMENT_SMASH_RWALLS
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
pressure_resistance = 100 //100 kPa difference required to push
throw_pressure_limit = 120 //120 kPa difference required to throw
+1
View File
@@ -185,6 +185,7 @@ var/global/list/all_cults = list()
cult_mind.current.faction |= "cult"
var/datum/action/innate/cultcomm/C = new()
C.Grant(cult_mind.current)
SEND_SOUND(cult_mind.current, 'sound/ambience/antag/bloodcult.ogg')
cult_mind.current.create_attack_log("<span class='danger'>Has been converted to the cult!</span>")
if(jobban_isbanned(cult_mind.current, ROLE_CULTIST) || jobban_isbanned(cult_mind.current, ROLE_SYNDICATE))
replace_jobbanned_player(cult_mind.current, ROLE_CULTIST)
@@ -60,9 +60,9 @@
/mob/living/simple_animal/hostile/guardian/Life(seconds, times_fired) //Dies if the summoner dies
..()
if(summoner)
if(summoner.stat == DEAD)
if(summoner.stat == DEAD || (!summoner.check_death_method() && summoner.health <= HEALTH_THRESHOLD_DEAD))
to_chat(src, "<span class='danger'>Your summoner has died!</span>")
visible_message("<span class='danger'>The [src] dies along with its user!</span>")
visible_message("<span class='danger'>[src] dies along with its user!</span>")
ghostize()
qdel(src)
snapback()
+12 -3
View File
@@ -1,12 +1,12 @@
/mob/proc/rightandwrong(var/summon_type) //0 = Summon Guns, 1 = Summon Magic
var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","arg","uzi","turret","pulsecarbine","decloner","mindflayer","kinetic","advplasmacutter","wormhole","wt550","grenadelauncher","medibeam")
/mob/proc/rightandwrong(summon_type, revolver_fight = FALSE, fake_revolver_fight = FALSE) //0 = Summon Guns, 1 = Summon Magic
var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","arg","uzi","turret","pulsecarbine","decloner","mindflayer","kinetic","advplasmacutter","wormhole","wt550","grenadelauncher","medibeam", "fakerevolver")
var/list/magiclist = list("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge", "summonitem", "wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffhealing", "armor", "scrying", "staffdoor", "special","voodoo","special")
var/list/magicspeciallist = list("staffchange","staffanimation", "wandbelt", "contract", "staffchaos","necromantic")
to_chat(usr, "<B>You summoned [summon_type ? "magic" : "guns"]!</B>")
message_admins("[key_name_admin(usr)] summoned [summon_type ? "magic" : "guns"]!")
message_admins("[key_name_admin(usr)] summoned [summon_type ? "magic" : "guns"]! ([revolver_fight ? "Revolver duel!" : ""] [fake_revolver_fight ? "Suicidal revolver duel!" : ""])")
for(var/mob/living/carbon/human/H in GLOB.player_list)
if(H.stat == 2 || !(H.client))
@@ -17,6 +17,13 @@
var/randomizeguns = pick(gunslist)
var/randomizemagic = pick(magiclist)
var/randomizemagicspecial = pick(magicspeciallist)
if(revolver_fight)
randomizeguns = "revolver"
if(fake_revolver_fight)
if(prob(50))
randomizeguns = "revolver"
else
randomizeguns = "fakerevolver"
if(!summon_type)
switch(randomizeguns)
if("taser")
@@ -88,6 +95,8 @@
new /obj/item/gun/projectile/revolver/grenadelauncher(get_turf(H))
if("medibeam")
new /obj/item/gun/medbeam(get_turf(H))
if("fakerevolver")
new /obj/item/toy/russian_revolver/trick_revolver(get_turf(H)) //lol
playsound(get_turf(H), 'sound/magic/summon_guns.ogg', 50, 1)
else
+2 -2
View File
@@ -18,8 +18,8 @@
access_heads, access_construction, access_sec_doors,
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_minisat, access_mechanic, access_mineral_storeroom)
minimal_player_age = 21
exp_requirements = 1200
exp_type = EXP_TYPE_CREW
exp_requirements = 300
exp_type = EXP_TYPE_ENGINEERING
outfit = /datum/outfit/job/chief_engineer
/datum/outfit/job/chief_engineer
+2 -2
View File
@@ -16,8 +16,8 @@
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce,
access_keycard_auth, access_sec_doors, access_psychiatrist, access_maint_tunnels, access_paramedic, access_mineral_storeroom)
minimal_player_age = 21
exp_requirements = 1200
exp_type = EXP_TYPE_CREW
exp_requirements = 300
exp_type = EXP_TYPE_MEDICAL
outfit = /datum/outfit/job/cmo
/datum/outfit/job/cmo
+2 -2
View File
@@ -18,8 +18,8 @@
access_research, access_robotics, access_xenobiology, access_ai_upload,
access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_minisat, access_maint_tunnels, access_mineral_storeroom, access_network)
minimal_player_age = 21
exp_requirements = 1200
exp_type = EXP_TYPE_CREW
exp_requirements = 300
exp_type = EXP_TYPE_SCIENCE
// All science-y guys get bonuses for maxing out their tech.
required_objectives = list(
/datum/job_objective/further_research
+2 -2
View File
@@ -18,8 +18,8 @@
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_pilot, access_weapons)
minimal_player_age = 21
exp_requirements = 1200
exp_type = EXP_TYPE_CREW
exp_requirements = 300
exp_type = EXP_TYPE_SECURITY
disabilities_allowed = 0
outfit = /datum/outfit/job/hos
+2 -2
View File
@@ -9,8 +9,8 @@
department_head = list("Captain")
req_admin_notify = 1
minimal_player_age = 30
exp_requirements = 1200
exp_type = EXP_TYPE_CREW
exp_requirements = 300
exp_type = EXP_TYPE_SILICON
/datum/job/ai/equip(mob/living/carbon/human/H)
if(!H)
+4 -4
View File
@@ -13,8 +13,8 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
access = list() //See get_access()
minimal_access = list() //See get_access()
minimal_player_age = 30
exp_requirements = 2400
exp_type = EXP_TYPE_CREW
exp_requirements = 300
exp_type = EXP_TYPE_COMMAND
disabilities_allowed = 0
outfit = /datum/outfit/job/captain
@@ -68,8 +68,8 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
req_admin_notify = 1
is_command = 1
minimal_player_age = 21
exp_requirements = 1200
exp_type = EXP_TYPE_CREW
exp_requirements = 300
exp_type = EXP_TYPE_COMMAND
access = list(access_security, access_sec_doors, access_brig, access_court, access_forensics_lockers,
access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads,
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
+2
View File
@@ -100,6 +100,7 @@ var/global/list/role_playtime_requirements = list(
// Procs
/proc/role_available_in_playtime(client/C, role)
// "role" is a special role defined in role_playtime_requirements above. e.g: ROLE_ERT. This is *not* a job title.
if(!C)
return 0
if(!role)
@@ -121,6 +122,7 @@ var/global/list/role_playtime_requirements = list(
return req_mins
return max(0, req_mins - my_exp)
/datum/job/proc/available_in_playtime(client/C)
if(!C)
return 0
+11 -2
View File
@@ -36,10 +36,13 @@
if(scanner.occupant && can_autoprocess())
scan_mob(scanner.occupant)
if(!LAZYLEN(records))
return
for(var/obj/machinery/clonepod/pod in pods)
if(!(pod.occupant || pod.mess) && (pod.efficiency > 5))
for(var/datum/dna2/record/R in src.records)
for(var/datum/dna2/record/R in records)
if(!(pod.occupant || pod.mess))
if(pod.growclone(R))
records.Remove(R)
@@ -392,6 +395,12 @@
SSnanoui.update_uis(src)
return
for(var/obj/machinery/clonepod/pod in pods)
if(pod.occupant && pod.clonemind == subject.mind)
scantemp = "Subject already getting cloned."
SSnanoui.update_uis(src)
return
subject.dna.check_integrity()
var/datum/dna2/record/R = new /datum/dna2/record()
@@ -192,7 +192,7 @@ var/global/list/image/splatter_cache = list()
icon = 'icons/effects/blood.dmi'
icon_state = "gibbl5"
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
noclear = TRUE
no_clear = TRUE
var/fleshcolor = "#FFFFFF"
/obj/effect/decal/cleanable/blood/gibs/update_icon()
@@ -221,18 +221,11 @@ var/global/list/image/splatter_cache = list()
/obj/effect/decal/cleanable/blood/gibs/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
/obj/effect/decal/cleanable/blood/gibs/Initialize()
. = ..()
reagents.add_reagent("liquidgibs", 5)
scoop_reagents = list("liquidgibs" = 5)
/obj/effect/decal/cleanable/blood/gibs/cleangibs //most ironic name ever...
/obj/effect/decal/cleanable/blood/gibs/cleangibs/Initialize() //no reagent!
. = ..()
reagents.remove_reagent("liquidgibs",5)
scoop_reagents = null
/obj/effect/decal/cleanable/blood/gibs/proc/streak(var/list/directions)
set waitfor = 0
@@ -15,10 +15,7 @@
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
anchored = TRUE
/obj/effect/decal/cleanable/ash/Initialize()
. = ..()
reagents.add_reagent("ash", 10)
scoop_reagents = list("ash" = 10)
/obj/effect/decal/cleanable/dirt
name = "dirt"
@@ -40,11 +37,8 @@
/obj/effect/decal/cleanable/dirt/blackpowder
name = "black powder"
mouse_opacity = TRUE
noscoop = TRUE
/obj/effect/decal/cleanable/dirt/blackpowder/Initialize()
. = ..()
reagents.add_reagent("blackpowder", 40) // size 2 explosion when activated
no_scoop = TRUE
scoop_reagents = list("blackpowder" = 40) // size 2 explosion when activated
/obj/effect/decal/cleanable/flour
name = "flour"
@@ -127,22 +121,15 @@
icon = 'icons/effects/blood.dmi'
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
noclear = TRUE
/obj/effect/decal/cleanable/vomit/Initialize()
. = ..()
reagents.add_reagent("vomit", 5)
no_clear = TRUE
scoop_reagents = list("vomit" = 5)
/obj/effect/decal/cleanable/vomit/green
name = "green vomit"
desc = "It's all gummy. Ew."
icon_state = "gvomit_1"
random_icon_states = list("gvomit_1", "gvomit_2", "gvomit_3", "gvomit_4")
/obj/effect/decal/cleanable/vomit/green/Initialize()
. = ..()
reagents.remove_reagent("vomit", 5)
reagents.add_reagent("green_vomit", 5)
scoop_reagents = list("green_vomit" = 5)
/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"
@@ -189,10 +176,7 @@
icon = 'icons/effects/effects.dmi'
icon_state = "flour"
color = "#D5820B"
/obj/effect/decal/cleanable/fungus/Initialize()
. = ..()
reagents.add_reagent("fungus", 10)
scoop_reagents = list("fungus" = 10)
/obj/effect/decal/cleanable/confetti //PARTY TIME!
name = "confetti"
+1 -25
View File
@@ -1,8 +1,6 @@
/obj/effect/decal/cleanable
anchored = TRUE
var/list/random_icon_states = list()
var/noscoop = FALSE //if it has this, don't let it be scooped up
var/noclear = FALSE //if it has this, don't delete it when its' scooped up
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
return FALSE
@@ -10,7 +8,6 @@
/obj/effect/decal/cleanable/New()
if(random_icon_states && length(src.random_icon_states) > 0)
src.icon_state = pick(src.random_icon_states)
create_reagents(100)
if(smooth)
queue_smooth(src)
queue_smooth_neighbors(src)
@@ -19,25 +16,4 @@
/obj/effect/decal/cleanable/Destroy()
if(smooth)
queue_smooth_neighbors(src)
return ..()
/obj/effect/decal/cleanable/attackby(obj/item/W as obj, mob/user as mob,)
if(istype(W, /obj/item/reagent_containers/glass) || istype(W, /obj/item/reagent_containers/food/drinks))
if(src.reagents && W.reagents && !noscoop)
if(!src.reagents.total_volume)
to_chat(user, "<span class='notice'>There isn't enough [src] to scoop up!</span>")
return
if(W.reagents.total_volume >= W.reagents.maximum_volume)
to_chat(user, "<span class='notice'>[W] is full!</span>")
return
to_chat(user, "<span class='notice'>You scoop the [src] into [W]!</span>")
reagents.trans_to(W, reagents.total_volume)
if(!reagents.total_volume && !noclear) //scooped up all of it
qdel(src)
return
/obj/effect/decal/cleanable/ex_act()
if(reagents)
for(var/datum/reagent/R in reagents.reagent_list)
R.on_ex_act()
..()
return ..()
+13
View File
@@ -54,3 +54,16 @@
/obj/effect/decal/straw/edge
icon_state = "strawscatterededge"
/obj/effect/decal/ants
name = "space ants"
desc = "A bunch of space ants."
icon = 'icons/goonstation/effects/effects.dmi'
icon_state = "spaceants"
scoop_reagents = list("ants" = 20)
/obj/effect/decal/ants/Initialize(mapload)
. = ..()
var/scale = (rand(2, 10) / 10) + (rand(0, 5) / 100)
transform = matrix(transform, scale, scale, MATRIX_SCALE)
setDir(pick(NORTH, SOUTH, EAST, WEST))
+35 -1
View File
@@ -13,4 +13,38 @@
return
/obj/effect/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
return FALSE
return FALSE
/obj/effect/decal
var/no_scoop = FALSE //if it has this, don't let it be scooped up
var/no_clear = FALSE //if it has this, don't delete it when its' scooped up
var/list/scoop_reagents = null
/obj/effect/decal/Initialize(mapload)
. = ..()
if(scoop_reagents)
create_reagents(100)
reagents.add_reagent_list(scoop_reagents)
/obj/effect/decal/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/reagent_containers/glass) || istype(I, /obj/item/reagent_containers/food/drinks))
scoop(I, user)
/obj/effect/decal/proc/scoop(obj/item/I, mob/user)
if(reagents && I.reagents && !no_scoop)
if(!reagents.total_volume)
to_chat(user, "<span class='notice'>There isn't enough [src] to scoop up!</span>")
return
if(I.reagents.total_volume >= I.reagents.maximum_volume)
to_chat(user, "<span class='notice'>[I] is full!</span>")
return
to_chat(user, "<span class='notice'>You scoop [src] into [I]!</span>")
reagents.trans_to(I, reagents.total_volume)
if(!reagents.total_volume && !no_clear) //scooped up all of it
qdel(src)
/obj/effect/decal/ex_act()
if(reagents)
for(var/datum/reagent/R in reagents.reagent_list)
R.on_ex_act()
..()
@@ -279,7 +279,7 @@
/obj/item/clothing/glasses/thermal = 1,
/obj/item/chameleon = 1,
/obj/item/reagent_containers/hypospray/autoinjector/stimulants = 1,
/obj/item/storage/box/syndie_kit/atmosgasgrenades = 1,
/obj/item/storage/box/syndie_kit/atmosn2ogrenades = 1,
/obj/item/grenade/plastic/x4 = 1)
+5 -10
View File
@@ -23,7 +23,6 @@ var/list/world_uplinks = list()
var/used_TC = 0
var/job = null
var/show_descriptions = 0
var/temp_category
var/uplink_type = "traitor"
@@ -72,7 +71,10 @@ var/list/world_uplinks = list()
if(I.job && I.job.len)
if(!(I.job.Find(job)))
continue
dat += "<A href='byond://?src=[UID()];buy_item=[I.reference];cost=[I.cost]'>[I.name]</A> ([I.cost])<BR>"
dat += "<A href='byond://?src=[UID()];buy_item=[I.reference];cost=[I.cost]'>[I.name]</A> ([I.cost])"
if(I.hijack_only)
dat += " (HIJACK ONLY)"
dat += " <BR>"
category_items++
dat += "<A href='byond://?src=[UID()];buy_item=random'>Random Item (??)</A><br>"
@@ -95,7 +97,7 @@ var/list/world_uplinks = list()
if(I.job && I.job.len)
if(!(I.job.Find(job)))
continue
nano[nano.len]["items"] += list(list("Name" = sanitize(I.name), "Description" = sanitize(I.description()),"Cost" = I.cost, "obj_path" = I.reference))
nano[nano.len]["items"] += list(list("Name" = sanitize(I.name), "Description" = sanitize(I.description()),"Cost" = I.cost, "hijack_only" = I.hijack_only, "obj_path" = I.reference))
reference[I.reference] = I
var/datum/nano_item_lists/result = new
@@ -231,7 +233,6 @@ var/list/world_uplinks = list()
data["welcome"] = welcome
data["crystals"] = uses
data["menu"] = nanoui_menu
data["descriptions"] = show_descriptions
if(!nanoui_items)
generate_items(user)
data["nano_items"] = nanoui_items
@@ -266,12 +267,6 @@ var/list/world_uplinks = list()
if(href_list["menu"])
nanoui_menu = text2num(href_list["menu"])
update_nano_data(href_list["id"])
if(href_list["menu"])
nanoui_menu = text2num(href_list["menu"])
update_nano_data(href_list["id"])
if(href_list["descriptions"])
show_descriptions = !show_descriptions
update_nano_data()
if(href_list["category"])
temp_category = href_list["category"]
update_nano_data()
+58 -33
View File
@@ -1372,7 +1372,8 @@ obj/item/toy/cards/deck/syndicate/black
force = 5
origin_tech = "combat=1"
attack_verb = list("struck", "hit", "bashed")
var/bullet_position = 1
var/bullets_left = 0
var/max_shots = 6
/obj/item/toy/russian_revolver/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] quickly loads six bullets into [src]'s cylinder and points it at [user.p_their()] head before pulling the trigger! It looks like [user.p_theyre()] trying to commit suicide.</span>")
@@ -1380,46 +1381,70 @@ obj/item/toy/cards/deck/syndicate/black
return BRUTELOSS
/obj/item/toy/russian_revolver/New()
spin_cylinder()
..()
spin_cylinder()
/obj/item/toy/russian_revolver/attack_self(mob/user)
if(!bullet_position)
user.visible_message("<span class='warning'>[user] loads a bullet into [src]'s cylinder.</span>")
bullet_position = 1
else
if(!bullets_left)
user.visible_message("<span class='warning'>[user] loads a bullet into [src]'s cylinder before spinning it.</span>")
spin_cylinder()
user.visible_message("<span class='warning'>[user] spins the cylinder on [src]!</span>")
/obj/item/toy/russian_revolver/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
if(M != user) //can't use this on other people
return ..()
if(!bullet_position)
to_chat(user, "<span class='notice'>[src] is empty.</span>")
return
if(!(user.has_organ("head"))) //For sanity
to_chat(user, "<span class='notice'>Playing this game without a head would be classed as cheating.</span>")
return
user.visible_message("<span class='danger'>[user] points [src] at [user.p_their()] head, ready to pull the trigger!</span>")
if(do_after(user, 30, target = user))
if(bullet_position > 1)
user.visible_message("<span class='danger'>*click*</span>")
playsound(src, 'sound/weapons/empty.ogg', 100, 1)
bullet_position--
return
else
bullet_position = null
playsound(src, 'sound/weapons/gunshots/gunshot_strong.ogg', 50, 1)
user.visible_message("<span class='danger'>[src] goes off!</span>")
user.apply_damage(200, BRUTE, "head", sharp = 1, used_weapon = "Self-inflicted gunshot wound to the head.")
user.death()
else
user.visible_message("<span class='danger'>[user] lowers [src] from [user.p_their()] head.</span>")
user.visible_message("<span class='warning'>[user] spins the cylinder on [src]!</span>")
spin_cylinder()
/obj/item/toy/russian_revolver/attack(mob/M, mob/living/user)
return
/obj/item/toy/russian_revolver/afterattack(atom/target, mob/user, proximity)
shoot_gun(user)
/obj/item/toy/russian_revolver/proc/spin_cylinder()
bullet_position = rand(1,6)
bullets_left = rand(1, max_shots)
/obj/item/toy/russian_revolver/proc/post_shot(mob/user)
return
/obj/item/toy/russian_revolver/proc/shoot_gun(mob/living/carbon/human/user)
if(bullets_left > 1)
bullets_left--
user.visible_message("<span class='danger'>*click*</span>")
playsound(src, 'sound/weapons/empty.ogg', 100, 1)
return FALSE
if(bullets_left == 1)
bullets_left = 0
var/zone = "head"
if(!(user.has_organ(zone))) // If they somehow don't have a head.
zone = "chest"
playsound(src, 'sound/weapons/gunshots/gunshot_strong.ogg', 50, 1)
user.visible_message("<span class='danger'>[src] goes off!</span>")
post_shot(user)
user.apply_damage(300, BRUTE, zone, sharp = TRUE, used_weapon = "Self-inflicted gunshot wound to the [zone].")
user.bleed(BLOOD_VOLUME_NORMAL)
user.death() // Just in case
return TRUE
else
to_chat(user, "<span class='warning'>[src] needs to be reloaded.</span>")
return FALSE
/obj/item/toy/russian_revolver/trick_revolver
name = "\improper .357 revolver"
desc = "A suspicious revolver. Uses .357 ammo."
icon_state = "revolver"
max_shots = 1
var/fake_bullets = 0
/obj/item/toy/russian_revolver/trick_revolver/New()
..()
fake_bullets = rand(2, 7)
/obj/item/toy/russian_revolver/trick_revolver/examine(mob/user) //Sneaky sneaky
..()
to_chat(user, "Has [fake_bullets] round\s remaining.")
to_chat(user, "[fake_bullets] of those are live rounds.")
/obj/item/toy/russian_revolver/trick_revolver/post_shot(user)
to_chat(user, "<span class='danger'>[src] did look pretty dodgey!</span>")
SEND_SOUND(user, 'sound/misc/sadtrombone.ogg') //HONK
/*
* Rubber Chainsaw
*/
@@ -6,6 +6,7 @@
light_power = 10
light_color = LIGHT_COLOR_WHITE
var/light_time = 2
var/range = 7
/obj/item/grenade/flashbang/prime()
update_mob()
@@ -15,60 +16,65 @@
set_light(7)
for(var/mob/living/M in hearers(7, flashbang_turf))
bang(get_turf(M), M)
do_sparks(rand(5, 9), FALSE, src)
playsound(flashbang_turf, 'sound/effects/bang.ogg', 25, 1)
bang(flashbang_turf, range, src)
for(var/obj/structure/blob/B in hear(8,flashbang_turf)) //Blob damage here
var/damage = round(30/(get_dist(B,get_turf(src))+1))
for(var/obj/structure/blob/B in hear(8, flashbang_turf)) //Blob damage here
var/damage = round(30 / (get_dist(B, get_turf(src)) + 1))
B.health -= damage
B.update_icon()
spawn(light_time)
qdel(src)
/obj/item/grenade/flashbang/proc/bang(var/turf/T , var/mob/living/M)
M.show_message("<span class='warning'>BANG</span>", 2)
playsound(loc, 'sound/effects/bang.ogg', 25, 1)
/proc/bang(turf/T, atom/A, range = 7, flash = TRUE, bang = TRUE)
for(var/mob/living/M in hearers(range, T))
if(M.stat == DEAD)
continue
M.show_message("<span class='warning'>BANG</span>", 2)
//Checking for protections
var/ear_safety = M.check_ear_prot()
var/distance = max(1,get_dist(src,T))
//Checking for protections
var/ear_safety = M.check_ear_prot()
var/distance = max(1, get_dist(get_turf(A), get_turf(M)))
//Flash
if(M.weakeyes)
M.visible_message("<span class='disarm'><b>[M]</b> screams and collapses!</span>")
to_chat(M, "<span class='userdanger'><font size=3>AAAAGH!</font></span>")
M.Weaken(15) //hella stunned
M.Stun(15)
if(ishuman(M))
M.emote("scream")
var/mob/living/carbon/human/H = M
var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes)
if(E)
E.receive_damage(8, 1)
//Flash
if(flash)
if(M.weakeyes)
M.visible_message("<span class='disarm'><b>[M]</b> screams and collapses!</span>")
to_chat(M, "<span class='userdanger'><font size=3>AAAAGH!</font></span>")
M.Weaken(15) //hella stunned
M.Stun(15)
if(ishuman(M))
M.emote("scream")
var/mob/living/carbon/human/H = M
var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes)
if(E)
E.receive_damage(8, 1)
if(M.flash_eyes(affect_silicon = 1))
M.Stun(max(10/distance, 3))
M.Weaken(max(10/distance, 3))
if(M.flash_eyes(affect_silicon = TRUE))
M.Stun(max(10 / distance, 3))
M.Weaken(max(10 / distance, 3))
//Bang
if(get_turf(M) == get_turf(src))//Holding on person or being exactly where lies is significantly more dangerous and voids protection
M.Stun(10)
M.Weaken(10)
if(!ear_safety)
M.Stun(max(10/distance, 3))
M.Weaken(max(10/distance, 3))
M.AdjustEarDamage(rand(0, 5), 15)
if(iscarbon(M))
var/mob/living/carbon/C = M
var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears)
if(istype(ears))
if(ears.ear_damage >= 15)
to_chat(M, "<span class='warning'>Your ears start to ring badly!</span>")
if(prob(ears.ear_damage - 5))
to_chat(M, "<span class='warning'>You can't hear anything!</span>")
M.BecomeDeaf()
else
if(ears.ear_damage >= 5)
to_chat(M, "<span class='warning'>Your ears start to ring!</span>")
//Bang
if(bang)
if(!distance || A.loc == M || A.loc == M.loc) //Holding on person or being exactly where lies is significantly more dangerous and voids protection
M.Stun(10)
M.Weaken(10)
if(!ear_safety)
M.Stun(max(10 / distance, 3))
M.Weaken(max(10 / distance, 3))
M.AdjustEarDamage(rand(0, 5), 15)
if(iscarbon(M))
var/mob/living/carbon/C = M
var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears)
if(istype(ears))
if(ears.ear_damage >= 15)
to_chat(M, "<span class='warning'>Your ears start to ring badly!</span>")
if(prob(ears.ear_damage - 5))
to_chat(M, "<span class='warning'>You can't hear anything!</span>")
M.BecomeDeaf()
else
if(ears.ear_damage >= 5)
to_chat(M, "<span class='warning'>Your ears start to ring!</span>")
@@ -262,13 +262,24 @@
new /obj/item/spellbook/oneuse/mime/greaterwall(src)
new /obj/item/spellbook/oneuse/mime/fingergun(src)
/obj/item/storage/box/syndie_kit/atmosgasgrenades
name = "Atmos Grenades"
/obj/item/storage/box/syndie_kit/atmosgasgrenades/New()
/obj/item/storage/box/syndie_kit/atmosn2ogrenades
name = "Atmos N2O Grenades"
/obj/item/storage/box/syndie_kit/atmosn2ogrenades/New()
..()
new /obj/item/grenade/clusterbuster/n2o(src)
new /obj/item/grenade/clusterbuster/n2o(src)
/obj/item/storage/box/syndie_kit/atmosfiregrenades
name = "Plasma Fire Grenades"
/obj/item/storage/box/syndie_kit/atmosfiregrenades/New()
..()
new /obj/item/grenade/clusterbuster/plasma(src)
new /obj/item/grenade/clusterbuster/n2o(src)
new /obj/item/grenade/clusterbuster/plasma(src)
/obj/item/storage/box/syndie_kit/missionary_set
name = "Missionary Starter Kit"
@@ -278,9 +278,11 @@
if(src == user.loc)
to_chat(user, "<span class='notice'>You can not [welded?"unweld":"weld"] the locker from inside.</span>")
return
if(!WT.remove_fuel(0,user))
if(!WT.remove_fuel(0, user))
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
if(!do_after_once(user, 15, target = src))
return
welded = !welded
update_icon()
for(var/mob/M in viewers(src))
+10 -6
View File
@@ -19,15 +19,19 @@
listeners = listeners & hearers(maxdistance, turf_source)
for(var/P in listeners)
var/mob/M = P
if(!M || !M.client || M.z != turf_source.z)
if(!M || !M.client)
continue
var/turf/T = get_turf(M) // These checks need to be changed if z-levels are ever further refactored
if(!T)
continue
if(T.z != turf_source.z)
continue
var/distance = get_dist(M, turf_source)
if(distance <= maxdistance)
var/turf/T = get_turf(M)
if(T && T.z == turf_source.z)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S)
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, channel = 0, pressure_affected = TRUE, sound/S)
if(!client || !can_hear())
@@ -156,4 +160,4 @@
soundin = pick('sound/effects/bone_break_1.ogg', 'sound/effects/bone_break_2.ogg', 'sound/effects/bone_break_3.ogg', 'sound/effects/bone_break_4.ogg', 'sound/effects/bone_break_5.ogg', 'sound/effects/bone_break_6.ogg')
if("honkbot_e")
soundin = pick('sound/items/bikehorn.ogg', 'sound/items/AirHorn2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/items/AirHorn.ogg', 'sound/items/WEEOO1.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bcreep.ogg','sound/magic/Fireball.ogg' ,'sound/effects/pray.ogg', 'sound/voice/hiss1.ogg','sound/machines/buzz-sigh.ogg', 'sound/machines/ping.ogg', 'sound/weapons/flashbang.ogg', 'sound/weapons/bladeslice.ogg')
return soundin
return soundin
+1
View File
@@ -322,6 +322,7 @@ var/world_topic_spam_protect_time = world.timeofday
//kick_clients_in_lobby("<span class='boldannounce'>The round came to an end with you in the lobby.</span>", 1)
processScheduler.stop()
Master.Shutdown() //run SS shutdowns
shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss.
for(var/client/C in GLOB.clients)
+3 -2
View File
@@ -671,8 +671,9 @@ var/global/nologevent = 0
alert("Unable to start the game as it is not set up.")
return
if(ticker.current_state == GAME_STATE_PREGAME)
if(alert(usr, "Are you sure you want to start now?", "Start game", "Yes", "No") != "Yes")
return
if(config.start_now_confirmation)
if(alert(usr, "This is a live server. Are you sure you want to start now?", "Start game", "Yes", "No") != "Yes")
return
ticker.current_state = GAME_STATE_SETTING_UP
log_admin("[key_name(usr)] has started the game.")
message_admins("[key_name_admin(usr)] has started the game.")
+3 -1
View File
@@ -113,7 +113,9 @@
<A href='?src=[UID()];secretsfun=schoolgirl'>Japanese Animes Mode</A>&nbsp;&nbsp;
<A href='?src=[UID()];secretsfun=eagles'>Egalitarian Station Mode</A><BR>
<A href='?src=[UID()];secretsfun=guns'>Summon Guns</A>&nbsp;&nbsp;
<A href='?src=[UID()];secretsfun=magic'>Summon Magic</A>
<A href='?src=[UID()];secretsfun=magic'>Summon Magic</A>&nbsp;&nbsp;
<A href='?src=[UID()];secretsfun=revolver'>Summon Revolver Duel</A>&nbsp;&nbsp;
<A href='?src=[UID()];secretsfun=fakerevolver'>Summon Suicidal Revolver Duel</A>
<BR>
<A href='?src=[UID()];secretsfun=rolldice'>Roll the Dice</A><BR>
<BR>
+10 -2
View File
@@ -2843,11 +2843,19 @@
if("guns")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","SG")
usr.rightandwrong(0)
usr.rightandwrong(FALSE)
if("magic")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","SM")
usr.rightandwrong(1)
usr.rightandwrong(TRUE)
if("revolver")
feedback_inc("admin_secrets_fun_used", 1)
feedback_add_details("admin_secrets_fun_used", "SRD")
usr.rightandwrong(FALSE, revolver_fight = TRUE)
if("fakerevolver")
feedback_inc("admin_secrets_fun_used", 1)
feedback_add_details("admin_secrets_fun_used", "SFD")
usr.rightandwrong(FALSE, fake_revolver_fight = TRUE)
if("tdomereset")
var/delete_mobs = alert("Clear all mobs?","Confirm","Yes","No","Cancel")
if(delete_mobs == "Cancel")
+4
View File
@@ -532,6 +532,10 @@
actions_types = list(/datum/action/item_action/toggle)
up = 0
tint = 0
species_fit = list("Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi'
)
/obj/item/clothing/glasses/tajblind/eng
name = "industrial veil"
+8
View File
@@ -165,6 +165,10 @@
flags_cover = GLASSESCOVERSEYES
actions_types = list(/datum/action/item_action/toggle)
up = 0
species_fit = list("Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi'
)
/obj/item/clothing/glasses/hud/security/tajblind/attack_self()
toggle_veil()
@@ -177,6 +181,10 @@
flags_cover = GLASSESCOVERSEYES
actions_types = list(/datum/action/item_action/toggle)
up = 0
species_fit = list("Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi'
)
/obj/item/clothing/glasses/hud/health/tajblind/attack_self()
toggle_veil()
+8 -2
View File
@@ -1,12 +1,18 @@
/datum/event/grid_check //NOTE: Times are measured in master controller ticks!
announceWhen = 5
/datum/event/grid_check/setup()
endWhen = rand(30,120)
/datum/event/grid_check/start()
power_failure(0)
var/sound/S = sound('sound/effects/powerloss.ogg')
for(var/mob/living/M in GLOB.player_list)
var/turf/T = get_turf(M)
if(!M.client || !is_station_level(T.z))
continue
SEND_SOUND(M, S)
/datum/event/grid_check/announce()
event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check", new_sound = 'sound/AI/poweroff.ogg')
@@ -55,6 +55,11 @@
then click where you want to fire. After firing, you will need to pump the gun, by clicking on the gun in your hand. To reload, load more shotgun \
shells into the gun."
/obj/item/toy/russian_revolver/trick_revolver //oh no
description_info = "This is a ballistic weapon. To fire the weapon, have your gun mode set to 'fire', \
then click where you want to fire. To reload, click the weapon in your hand to unload (if needed), then add the appropriate ammo. The description \
will tell you what caliber you need."
//*******
//*Melee*
//*******
@@ -11,6 +11,7 @@
possible_transfer_amounts = list(5,10,15,20,25,30,50)
volume = 50
burn_state = FIRE_PROOF
antable = FALSE
/obj/item/reagent_containers/food/drinks/New()
..()
+34 -2
View File
@@ -13,10 +13,42 @@
var/transfer_efficiency = 1.0
var/instant_application = 0 //if we want to bypass the forcedfeed delay
var/taste = TRUE//whether you can taste eating from this
var/antable = TRUE // Will ants come near it?
var/ant_location = null
var/ant_timer = null
burn_state = FLAMMABLE
container_type = INJECTABLE
/obj/item/reagent_containers/food/New()
..()
/obj/item/reagent_containers/food/Initialize(mapload)
. = ..()
pixel_x = rand(-5, 5) //Randomizes postion
pixel_y = rand(-5, 5)
if(antable)
ant_location = get_turf(src)
ant_timer = addtimer(CALLBACK(src, .proc/check_for_ants), 3000, TIMER_STOPPABLE)
/obj/item/reagent_containers/food/Destroy()
ant_location = null
if(ant_timer)
deltimer(ant_timer)
return ..()
/obj/item/reagent_containers/food/proc/check_for_ants()
if(!antable)
return
var/turf/T = get_turf(src)
if(isturf(loc) && !locate(/obj/structure/table) in T)
if(ant_location == T)
if(prob(15))
if(!locate(/obj/effect/decal/ants) in T)
new /obj/effect/decal/ants(T)
antable = FALSE
desc += " It appears to be infested with ants. Yuck!"
reagents.add_reagent("ants", 1) // Don't eat things with ants in i you weirdo.
if(ant_timer)
deltimer(ant_timer)
else
ant_location = T
if(ant_timer)
deltimer(ant_timer)
ant_timer = addtimer(CALLBACK(src, .proc/check_for_ants), 3000, TIMER_STOPPABLE)
+45 -26
View File
@@ -8,35 +8,36 @@
/mob/proc/bee_friendly()
return 0
return FALSE
/mob/living/simple_animal/hostile/poison/bees/bee_friendly()
return 1
return TRUE
/mob/living/simple_animal/bot/bee_friendly()
if(paicard)
return 0
return 1
return FALSE
return TRUE
/mob/living/simple_animal/diona/bee_friendly()
return 1
return TRUE
/mob/living/carbon/human/bee_friendly()
if(isdiona(src)) //bees pollinate plants, duh.
return 1
return TRUE
if((wear_suit && (wear_suit.flags & THICKMATERIAL)) && (head && (head.flags & THICKMATERIAL)))
return 1
return 0
return TRUE
return FALSE
/obj/structure/beebox
name = "apiary"
desc = "Dr Miles Manners is just your average Wasp themed super hero by day, but by night he becomes DR BEES!"
desc = "Dr. Miles Manners is just your average wasp-themed super hero by day, but by night he becomes DR. BEES!"
icon = 'icons/obj/hydroponics/equipment.dmi'
icon_state = "beebox"
anchored = 1
density = 1
anchored = TRUE
density = TRUE
max_integrity = 300
var/mob/living/simple_animal/hostile/poison/bees/queen/queen_bee = null
var/list/bees = list() //bees owned by the box, not those inside it
var/list/honeycombs = list()
@@ -44,8 +45,8 @@
var/bee_resources = 0
/obj/structure/beebox/New()
..()
/obj/structure/beebox/Initialize(mapload)
. = ..()
processing_objects.Add(src)
@@ -66,12 +67,11 @@
var/random_reagent = FALSE
/obj/structure/beebox/premade/New()
..()
/obj/structure/beebox/premade/Initialize(mapload)
. = ..()
var/datum/reagent/R = null
if(random_reagent)
R = get_random_reagent_id()
R = GLOB.chemical_reagents_list[get_random_reagent_id()]
queen_bee = new(src)
queen_bee.beehome = src
@@ -83,7 +83,7 @@
honey_frames += HF
for(var/i in 1 to get_max_bees())
var/mob/living/simple_animal/hostile/poison/bees/worker/B = new(src)
var/mob/living/simple_animal/hostile/poison/bees/B = new(src)
bees += B
B.beehome = src
B.assign_reagent(R)
@@ -93,7 +93,7 @@
/obj/structure/beebox/process()
if(queen_bee && (!queen_bee.beegent || !queen_bee.beegent.can_synth))
if(queen_bee)
if(bee_resources >= BEE_RESOURCE_HONEYCOMB_COST)
if(honeycombs.len < get_max_honeycomb())
bee_resources = max(bee_resources-BEE_RESOURCE_HONEYCOMB_COST, 0)
@@ -109,7 +109,7 @@
if((bee_resources >= BEE_RESOURCE_NEW_BEE_COST && prob(BEE_PROB_NEW_BEE)) || freebee)
if(!freebee)
bee_resources = max(bee_resources - BEE_RESOURCE_NEW_BEE_COST, 0)
var/mob/living/simple_animal/hostile/poison/bees/worker/B = new(src)
var/mob/living/simple_animal/hostile/poison/bees/B = new(get_turf(src))
B.beehome = src
B.assign_reagent(queen_bee.beegent)
bees += B
@@ -152,14 +152,16 @@
if(istype(I, /obj/item/honey_frame))
var/obj/item/honey_frame/HF = I
if(honey_frames.len < BEEBOX_MAX_FRAMES)
if(!user.unEquip(HF))
return
visible_message("<span class='notice'>[user] adds a frame to the apiary.</span>")
user.unEquip(HF)
HF.forceMove(src)
honey_frames += HF
else
to_chat(user, "<span class='warning'>There's no room for anymore frames in the apiary!</span>")
return
if(istype(I, /obj/item/wrench))
if(iswrench(I))
if(default_unfasten_wrench(user, I, time = 20))
return
@@ -169,25 +171,27 @@
return
var/obj/item/queen_bee/qb = I
user.unEquip(qb)
if(!qb.queen.beegent || (qb.queen.beegent && qb.queen.beegent.can_synth))
if(!user.unEquip(qb))
return
qb.queen.forceMove(src)
bees += qb.queen
queen_bee = qb.queen
qb.queen = null
else
visible_message("<span class='notice'>The [qb] refuses to settle down. Maybe it's something to do with its reagent?</span>")
return
if(queen_bee)
visible_message("<span class='notice'>[user] sets [qb] down inside the apiary, making it [user.p_their()] new home.</span>")
var/relocated = 0
for(var/b in bees)
var/mob/living/simple_animal/hostile/poison/bees/worker/B = b
var/mob/living/simple_animal/hostile/poison/bees/B = b
if(B.reagent_incompatible(queen_bee))
bees -= B
B.beehome = null
if(B.loc == src)
B.forceMove(get_turf(src))
B.forceMove(drop_location())
relocated++
if(relocated)
to_chat(user, "<span class='warning'>This queen has a different reagent to some of the bees who live here, those bees will not return to this apiary!</span>")
@@ -196,6 +200,8 @@
to_chat(user, "<span class='warning'>The queen bee disappeared! bees disappearing has been in the news lately...</span>")
qdel(qb)
return
return ..()
/obj/structure/beebox/attack_hand(mob/user)
@@ -208,7 +214,7 @@
if(B.isqueen)
continue
if(B.loc == src)
B.forceMove(get_turf(src))
B.forceMove(drop_location())
B.target = user
bees = TRUE
if(bees)
@@ -254,3 +260,16 @@
QB.forceMove(get_turf(src))
visible_message("<span class='notice'>[user] removes the queen from the apiary.</span>")
queen_bee = null
/obj/structure/beebox/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/wood(loc, 20)
for(var/mob/living/simple_animal/hostile/poison/bees/B in bees)
if(B.loc == src)
B.forceMove(drop_location())
for(var/obj/item/honey_frame/HF in honey_frames)
HF.forceMove(drop_location())
honey_frames -= HF
qdel(src)
/obj/structure/beebox/unwrenched
anchored = FALSE
+2 -1
View File
@@ -95,7 +95,8 @@
force = round((5 + seed.potency / 2.5), 1)
/obj/item/grown/nettle/death/pickup(mob/living/carbon/user)
if(..() && ishuman(user)) // If the pickup succeeded and is humanoid
. = ..()
if(. && ishuman(user)) // If the pickup succeeded and is humanoid
var/mob/living/carbon/human/H = user
if(!H.gloves && prob(50))
user.Paralyse(5)
+2 -2
View File
@@ -35,7 +35,7 @@
/mob/proc/put_in_l_hand(var/obj/item/W)
if(!put_in_hand_check(W))
return 0
if(!l_hand)
if(!l_hand && has_left_hand())
W.forceMove(src) //TODO: move to equipped?
l_hand = W
W.layer = 20 //TODO: move to equipped?
@@ -51,7 +51,7 @@
/mob/proc/put_in_r_hand(var/obj/item/W)
if(!put_in_hand_check(W))
return 0
if(!r_hand)
if(!r_hand && has_right_hand())
W.forceMove(src)
r_hand = W
W.layer = 20
+18 -30
View File
@@ -4,22 +4,15 @@
if(!iscarbon(target)) //something is bypassing the give arguments, no clue what, adding a sanity check JIC
to_chat(usr, "<span class='danger'>Wait a second... \the [target] HAS NO HANDS! AHH!</span>")//cheesy messages ftw
return
if(target.incapacitated() || usr.incapacitated() || target.client == null)
return
if(target.stat == 2 || usr.stat == 2|| target.client == null)
return
var/obj/item/I
if(!usr.hand && usr.r_hand == null)
to_chat(usr, "<span class='warning'> You don't have anything in your right hand to give to [target.name]</span>")
return
if(usr.hand && usr.l_hand == null)
to_chat(usr, "<span class='warning'> You don't have anything in your left hand to give to [target.name]</span>")
return
if(usr.hand)
I = usr.l_hand
else if(!usr.hand)
I = usr.r_hand
var/obj/item/I = get_active_hand()
if(!I)
to_chat(usr, "<span class='warning'> You don't have anything in your hand to give to [target.name]</span>")
return
if((I.flags & NODROP) || (I.flags & ABSTRACT))
to_chat(usr, "<span class='notice'>That's not exactly something you can give.</span>")
@@ -29,35 +22,30 @@
if("Yes")
if(!I)
return
if(target.incapacitated() || usr.incapacitated())
return
if(!Adjacent(target))
to_chat(usr, "<span class='warning'> You need to stay in reaching distance while giving an object.</span>")
to_chat(target, "<span class='warning'> [usr.name] moved too far away.</span>")
return
if((usr.hand && usr.l_hand != I) || (!usr.hand && usr.r_hand != I))
if((I.flags & NODROP) || (I.flags & ABSTRACT))
to_chat(usr, "<span class='warning'>[I] stays stuck to your hand when you try to give it!</span>")
to_chat(target, "<span class='warning'>[I] stays stuck to [usr.name]'s hand when you try to take it!</span>")
return
if(I != get_active_hand())
to_chat(usr, "<span class='warning'> You need to keep the item in your active hand.</span>")
to_chat(target, "<span class='warning'> [usr.name] seem to have given up on giving \the [I.name] to you.</span>")
to_chat(target, "<span class='warning'> [usr.name] seem to have given up on giving [I] to you.</span>")
return
if(target.r_hand != null && target.l_hand != null)
to_chat(target, "<span class='warning'> Your hands are full.</span>")
to_chat(usr, "<span class='warning'> Their hands are full.</span>")
return
else
usr.drop_item()
if(target.r_hand == null)
target.r_hand = I
else
target.l_hand = I
I.loc = target
I.layer = 20
I.plane = HUD_PLANE
usr.unEquip(I)
target.put_in_hands(I)
I.add_fingerprint(target)
src.update_inv_l_hand()
src.update_inv_r_hand()
target.update_inv_l_hand()
target.update_inv_r_hand()
target.visible_message("<span class='notice'> [usr.name] handed \the [I.name] to [target.name].</span>")
target.visible_message("<span class='notice'> [usr.name] handed [I] to [target.name].</span>")
I.on_give(usr, target)
if("No")
target.visible_message("<span class='warning'> [usr.name] tried to hand [I.name] to [target.name] but [target.name] didn't want it.</span>")
target.visible_message("<span class='warning'> [usr.name] tried to hand [I] to [target.name] but [target.name] didn't want it.</span>")
else
to_chat(usr, "<span class='warning'> [target.name]'s hands are full.</span>")
@@ -172,6 +172,7 @@
// Defined here solely to take species flags into account without having to recast at mob/living level.
/mob/living/carbon/human/adjustOxyLoss(amount)
if(NO_BREATHE in dna.species.species_traits)
oxyloss = 0
return FALSE
if(dna.species && amount > 0)
amount = amount * dna.species.oxy_mod
@@ -179,6 +180,7 @@
/mob/living/carbon/human/setOxyLoss(amount)
if(NO_BREATHE in dna.species.species_traits)
oxyloss = 0
return FALSE
if(dna.species && amount > 0)
amount = amount * dna.species.oxy_mod
@@ -434,11 +434,11 @@
if(slot_l_hand)
if(l_hand)
return 0
return 1
return !incapacitated()
if(slot_r_hand)
if(r_hand)
return 0
return 1
return !incapacitated()
if(slot_wear_mask)
if(wear_mask)
return 0
@@ -1,5 +1,6 @@
/mob/living/carbon/human/SetLoseBreath(amount)
if(NO_BREATHE in dna.species.species_traits)
losebreath = 0
return FALSE
. = ..()
+4
View File
@@ -122,8 +122,10 @@
/mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE)
if(status_flags & GODMODE)
oxyloss = 0
return FALSE //godmode
if(BREATHLESS in mutations)
oxyloss = 0
return FALSE
var/old_oxyloss = oxyloss
oxyloss = max(oxyloss + amount, 0)
@@ -137,8 +139,10 @@
/mob/living/proc/setOxyLoss(amount, updating_health = TRUE)
if(status_flags & GODMODE)
oxyloss = 0
return FALSE //godmode
if(BREATHLESS in mutations)
oxyloss = 0
return FALSE
var/old_oxyloss = oxyloss
oxyloss = amount
+1 -1
View File
@@ -759,7 +759,7 @@
if(!silent)
visible_message("<span class='notice'>[src] tries to put [what] on [who].</span>")
if(do_mob(src, who, what.put_on_delay))
if(what && Adjacent(who))
if(what && Adjacent(who) && !(what.flags & NODROP))
unEquip(what)
who.equip_to_slot_if_possible(what, where, 0, 1)
add_attack_logs(src, who, "Equipped [what]")
@@ -429,6 +429,7 @@
modules += new /obj/item/bonesetter(src)
modules += new /obj/item/surgicaldrill(src)
modules += new /obj/item/gripper/medical(src)
modules += new /obj/item/gun/medbeam(src)
modules += new /obj/item/melee/energy/sword/cyborg/saw(src) //Energy saw -- primary weapon
modules += new /obj/item/card/emag(src)
modules += new /obj/item/crowbar/cyborg(src)
@@ -11,7 +11,7 @@
/mob/living/simple_animal/hostile/poison/bees
name = "bee"
desc = "buzzy buzzy bee, stingy sti- Ouch!"
desc = "Buzzy buzzy bee, stingy sti- Ouch!"
icon_state = ""
icon_living = ""
icon = 'icons/mob/bees.dmi'
@@ -33,25 +33,28 @@
environment_smash = 0
mouse_opacity = MOUSE_OPACITY_OPAQUE
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
flying = 1
search_objects = 1 //have to find those plant trays!
density = 0
density = FALSE
mob_size = MOB_SIZE_TINY
flying = TRUE
search_objects = TRUE //have to find those plant trays!
//Spaceborn beings don't get hurt by space
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
del_on_death = 1
del_on_death = TRUE
var/datum/reagent/beegent = null //hehe, beegent
var/obj/structure/beebox/beehome = null
var/isqueen = FALSE
var/idle = 0
var/isqueen = FALSE
var/bee_syndicate = FALSE
var/icon_base = "bee"
var/static/list/bee_icons = list()
var/static/beehometypecache = typecacheof(/obj/structure/beebox)
var/static/hydroponicstypecache = typecacheof(/obj/machinery/hydroponics)
/mob/living/simple_animal/hostile/poison/bees/Process_Spacemove(movement_dir = 0)
return 1
return TRUE
/mob/living/simple_animal/hostile/poison/bees/New()
..()
@@ -65,6 +68,20 @@
beehome = null
return ..()
/mob/living/simple_animal/hostile/poison/bees/death(gibbed)
. = ..()
if(!.)
return
if(beehome)
if(beehome.bees)
beehome.bees.Remove(src)
beehome = null
/mob/living/simple_animal/hostile/poison/bees/examine(mob/user)
..()
if(!bee_syndicate && !beehome)
to_chat(user, "<span class='warning'>This bee is homeless!</span>")
/mob/living/simple_animal/hostile/poison/bees/proc/generate_bee_visuals()
overlays.Cut()
@@ -94,21 +111,45 @@
//We don't attack beekeepers/people dressed as bees//Todo: bee costume
/mob/living/simple_animal/hostile/poison/bees/CanAttack(atom/the_target)
. = ..()
return .
if(!.)
return FALSE
if(!bee_syndicate && isliving(the_target))
var/mob/living/H = the_target
return !H.bee_friendly()
/mob/living/simple_animal/hostile/poison/bees/Found(atom/A)
if(isliving(A))
var/mob/living/L = A
return !L.bee_friendly()
return 0
var/mob/living/H = A
return !H.bee_friendly()
if(istype(A, /obj/machinery/hydroponics))
var/obj/machinery/hydroponics/Hydro = A
if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit)
wanted_objects |= hydroponicstypecache //so we only hunt them while they're alive/seeded/not visisted
return TRUE
return FALSE
/mob/living/simple_animal/hostile/poison/bees/AttackingTarget()
if(beegent && isliving(target))
var/mob/living/L = target
if(!isnull(target.reagents))
beegent.reaction_mob(L, INGEST)
L.reagents.add_reagent(beegent.id, rand(1,5))
target.attack_animal(src)
//Pollinate
if(istype(target, /obj/machinery/hydroponics))
var/obj/machinery/hydroponics/Hydro = target
pollinate(Hydro)
else if(istype(target, /obj/structure/beebox))
if(target == beehome)
var/obj/structure/beebox/BB = target
forceMove(BB)
target = null
wanted_objects -= beehometypecache //so we don't attack beeboxes when not going home
return //no don't attack the goddamm box
else
..()
if(isliving(target))
var/mob/living/L = target
if(L.reagents)
if(beegent)
beegent.reaction_mob(L, INGEST)
L.reagents.add_reagent(beegent.id, rand(1, 5))
else
L.reagents.add_reagent("spidertoxin", 5)
/mob/living/simple_animal/hostile/poison/bees/proc/assign_reagent(datum/reagent/R)
if(istype(R))
@@ -116,81 +157,13 @@
name = "[initial(name)] ([R.name])"
generate_bee_visuals()
/mob/living/simple_animal/hostile/poison/bees/handle_automated_action()
. = ..()
if(!.)
return
/mob/living/simple_animal/hostile/poison/bees/proc/reagent_incompatible(mob/living/simple_animal/hostile/poison/bees/B)
if(!B)
return 0
if(B.beegent && beegent && B.beegent.id != beegent.id || B.beegent && !beegent || !B.beegent && beegent)
return 1
return 0
//Botany Worker Bees
/mob/living/simple_animal/hostile/poison/bees/worker
//Blank type define in case we need to give them special stuff later, plus organization (currently they are same as base type bee)
/mob/living/simple_animal/hostile/poison/bees/worker/Destroy()
if(beehome)
if(beehome.bees)
beehome.bees.Remove(src)
beehome = null
return ..()
/mob/living/simple_animal/hostile/poison/bees/worker/death(gibbed)
. = ..()
if(!.)
return
if(beehome)
if(beehome.bees)
beehome.bees.Remove(src)
beehome = null
/mob/living/simple_animal/hostile/poison/bees/worker/examine(mob/user)
..()
if(!beehome)
to_chat(user, "<span class='warning'>This bee is homeless!</span>")
/mob/living/simple_animal/hostile/poison/bees/worker/Found(atom/A)
if(istype(A, /obj/machinery/hydroponics))
var/obj/machinery/hydroponics/Hydro = A
if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit && !Hydro.lid_state)
wanted_objects |= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted and uncovered
return 1
..()
/mob/living/simple_animal/hostile/poison/bees/worker/CanAttack(atom/the_target)
. = ..()
if(!.)
return 0
if(isliving(the_target)) //Should ignore ghosts and camera mobs already, but just in case
var/mob/living/L = the_target
return !L.bee_friendly()
/mob/living/simple_animal/hostile/poison/bees/worker/AttackingTarget()
//Pollinate
if(istype(target, /obj/machinery/hydroponics))
var/obj/machinery/hydroponics/Hydro = target
pollinate(Hydro)
else if(target == beehome)
var/obj/structure/beebox/BB = target
forceMove(BB)
target = null
wanted_objects -= /obj/structure/beebox //so we don't attack beeboxes when not going home
else
..()
/mob/living/simple_animal/hostile/poison/bees/worker/proc/pollinate(obj/machinery/hydroponics/Hydro)
/mob/living/simple_animal/hostile/poison/bees/proc/pollinate(obj/machinery/hydroponics/Hydro)
if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit || Hydro.lid_state)
target = null
return
target = null //so we pick a new hydro tray next FindTarget(), instead of loving the same plant for eternity
wanted_objects -= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted and uncovered
wanted_objects -= hydroponicstypecache //so we only hunt them while they're alive/seeded/not visisted
Hydro.recent_bee_visit = TRUE
spawn(BEE_TRAY_RECENT_VISIT)
if(Hydro)
@@ -210,68 +183,79 @@
if(beehome)
beehome.bee_resources = min(beehome.bee_resources + growth, 100)
/mob/living/simple_animal/hostile/poison/bees/worker/handle_automated_action()
/mob/living/simple_animal/hostile/poison/bees/handle_automated_action()
. = ..()
if(!.)
return
if(!isqueen)
if(loc == beehome)
idle = min(100, ++idle)
if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM))
forceMove(get_turf(beehome))
else
idle = max(0, --idle)
if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME))
if(!FindTarget())
wanted_objects += /obj/structure/beebox //so we don't attack beeboxes when not going home
target = beehome
if(!beehome) //add outselves to a beebox (of the same reagent) if we have no home
for(var/obj/structure/beebox/BB in view(vision_range, src))
if(reagent_incompatible(BB.queen_bee) || BB.bees.len >= BB.get_max_bees())
continue
BB.bees |= src
beehome = BB
if(!bee_syndicate)
if(!isqueen)
if(loc == beehome)
idle = min(100, ++idle)
if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM))
forceMove(beehome.drop_location())
else
idle = max(0, --idle)
if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME))
if(!FindTarget())
wanted_objects |= beehometypecache //so we don't attack beeboxes when not going home
target = beehome
if(!beehome) //add ourselves to a beebox (of the same reagent) if we have no home
for(var/obj/structure/beebox/BB in view(vision_range, src))
if(reagent_incompatible(BB.queen_bee) || BB.bees.len >= BB.get_max_bees())
continue
BB.bees |= src
beehome = BB
break // End loop after the first compatible find.
//Botany Queen Bee
/mob/living/simple_animal/hostile/poison/bees/queen
name = "queen bee"
desc = "she's the queen of bees, BZZ BZZ"
desc = "She's the queen of bees, BZZ BZZ"
icon_base = "queen"
isqueen = TRUE
//the Queen doesn't leave the box on her own, and she CERTAINLY doesn't pollinate by herself
//the Queen doesn't leave the box on her own, and she CERTAINLY doesn't pollinate by herself
/mob/living/simple_animal/hostile/poison/bees/queen/Found(atom/A)
return 0
return FALSE
//leave pollination for the peasent bees
/mob/living/simple_animal/hostile/poison/bees/queen/AttackingTarget()
..()
if(beegent && isliving(target))
var/mob/living/L = target
beegent.reaction_mob(L, TOUCH)
L.reagents.add_reagent(beegent.id, rand(1, 5))
//PEASENT BEES
/mob/living/simple_animal/hostile/poison/bees/queen/pollinate()
return
/mob/living/simple_animal/hostile/poison/bees/proc/reagent_incompatible(mob/living/simple_animal/hostile/poison/bees/B)
if(!B)
return FALSE
if(B.beegent && beegent && B.beegent.id != beegent.id || B.beegent && !beegent || !B.beegent && beegent)
return TRUE
return FALSE
/mob/living/simple_animal/hostile/poison/bees/queen/CanAttack(atom/the_target)
. = ..()
if(!.)
return 0
if(isliving(the_target)) //Should ignore ghosts and camera mobs already, but just in case
var/mob/living/L = the_target
return !L.bee_friendly()
/obj/item/queen_bee
name = "queen bee"
desc = "she's the queen of bees, BZZ BZZ"
desc = "She's the queen of bees, BZZ BZZ"
icon_state = "queen_item"
item_state = ""
icon = 'icons/mob/bees.dmi'
var/mob/living/simple_animal/hostile/poison/bees/queen/queen
/obj/item/queen_bee/attackby(obj/item/I, mob/user, params)
if(istype(I,/obj/item/reagent_containers/syringe))
if(istype(I, /obj/item/reagent_containers/syringe))
var/obj/item/reagent_containers/syringe/S = I
if(S.reagents.has_reagent("royal_bee_jelly")) //checked twice, because I really don't want royal bee jelly to be duped
if(S.reagents.has_reagent("royal_bee_jelly",5))
if(S.reagents.has_reagent("royal_bee_jelly", 5))
S.reagents.remove_reagent("royal_bee_jelly", 5)
if(!queen.beegent.can_synth)
to_chat(user, "<span class='warning'>You inject [src] with the royal bee jelly. It's ineffective! Maybe it's something to do with the [src] reagent.</span>")
return
var/obj/item/queen_bee/qb = new(get_turf(user))
var/obj/item/queen_bee/qb = new(user.drop_location())
qb.queen = new(qb)
if(queen && queen.beegent)
qb.queen.assign_reagent(queen.beegent) //Bees use the global singleton instances of reagents, so we don't need to worry about one bee being deleted and her copies losing their reagents.
@@ -282,16 +266,17 @@
else
var/datum/reagent/R = GLOB.chemical_reagents_list[S.reagents.get_master_reagent_id()]
if(R && S.reagents.has_reagent(R.id, 5))
S.reagents.remove_reagent(R.id,5)
S.reagents.remove_reagent(R.id, 5)
queen.assign_reagent(R)
user.visible_message("<span class='warning'>[user] injects [src]'s genome with [R.name], mutating it's DNA!</span>","<span class='warning'>You inject [src]'s genome with [R.name], mutating it's DNA!</span>")
user.visible_message("<span class='warning'>[user] injects [src]'s genome with [R.name], mutating its DNA!</span>", "<span class='warning'>You inject [src]'s genome with [R.name], mutating its DNA!</span>")
name = queen.name
else
to_chat(user, "<span class='warning'>You don't have enough units of that chemical to modify the bee's DNA!</span>")
..()
else
return ..()
/obj/item/queen_bee/bought/New()
..()
/obj/item/queen_bee/bought/Initialize(mapload)
. = ..()
queen = new(src)
/obj/item/queen_bee/Destroy()
@@ -299,7 +284,6 @@
return ..()
//Syndicate Bees
/mob/living/simple_animal/hostile/poison/bees/syndi
name = "syndi-bee"
@@ -309,10 +293,14 @@
maxHealth = 25
health = 25
faction = list("hostile", "syndicate")
search_objects = 0 //these bees don't care about trivial things like plants, especially when there is havoc to sow
beegent = new /datum/reagent/facid() //prepare to die
search_objects = FALSE //these bees don't care about trivial things like plants, especially when there is havoc to sow
bee_syndicate = TRUE
var/list/master_and_friends = list()
/mob/living/simple_animal/hostile/poison/bees/syndi/New()
beegent = GLOB.chemical_reagents_list["facid"] //Prepare to die
..()
/mob/living/simple_animal/hostile/poison/bees/syndi/Destroy()
master_and_friends.Cut()
return ..()
@@ -320,24 +308,27 @@
/mob/living/simple_animal/hostile/poison/bees/syndi/assign_reagent(datum/reagent/R)
return
/mob/living/simple_animal/hostile/poison/bees/syndi/Found(atom/A)
return CanAttack(A)
/mob/living/simple_animal/hostile/poison/bees/syndi/pollinate() // No Pollination
return
/mob/living/simple_animal/hostile/poison/bees/syndi/Found(atom/A) //Typical usual hostile mob targeting list
return
/mob/living/simple_animal/hostile/poison/bees/syndi/CanAttack(atom/the_target)
. = ..()
if(!.)
return 0
return FALSE
if(isliving(the_target))
var/mob/living/L = the_target
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H in master_and_friends)
return 0
return 1
return FALSE
return TRUE
/mob/living/simple_animal/hostile/poison/bees/syndi/AttackingTarget()
..()
if(target && isliving(target))
var/mob/living/L = target
if(L.stat)
LoseTarget()
LoseTarget()
@@ -58,6 +58,7 @@
if(!targets_from)
targets_from = src
environment_target_typecache = typecacheof(environment_target_typecache)
wanted_objects = typecacheof(wanted_objects)
/mob/living/simple_animal/hostile/Destroy()
targets_from = null
+1
View File
@@ -298,6 +298,7 @@
/mob/living/SetLoseBreath(amount)
if(BREATHLESS in mutations)
losebreath = 0
return FALSE
losebreath = max(amount, 0)
+4 -4
View File
@@ -54,8 +54,8 @@
feedback_add_details("gun_fired","[type]")
/obj/item/gun/medbeam/process()
var/mob/living/carbon/human/H = loc
if(!istype(H))
var/source = loc
if(!ishuman(source) && !isrobot(source))
LoseTarget()
return
@@ -68,9 +68,9 @@
last_check = world.time
if(get_dist(H,current_target)>max_range || !los_check(H,current_target))
if(get_dist(source,current_target)>max_range || !los_check(source,current_target))
LoseTarget()
to_chat(H, "<span class='warning'>You lose control of the beam!</span>")
to_chat(source, "<span class='warning'>You lose control of the beam!</span>")
return
if(current_target)
+4 -3
View File
@@ -465,8 +465,8 @@ var/const/INGEST = 2
add_reagent(S, C.result_amount * C.secondary_results[S] * multiplier)
var/list/seen = viewers(4, get_turf(my_atom))
for(var/mob/M in seen)
if(!C.no_message)
for(var/mob/living/M in seen)
if(C.mix_message)
to_chat(M, "<span class='notice'>[bicon(my_atom)] [C.mix_message]</span>")
if(istype(my_atom, /obj/item/slime_extract))
@@ -478,7 +478,8 @@ var/const/INGEST = 2
ME2.name = "used slime extract"
ME2.desc = "This extract has been used up."
playsound(get_turf(my_atom), C.mix_sound, 80, 1)
if(C.mix_sound)
playsound(get_turf(my_atom), C.mix_sound, 80, 1)
C.on_reaction(src, created_volume)
reaction_occured = 1
@@ -262,12 +262,6 @@
T.create_reagents(50)
T.reagents.add_reagent("sorium", 5)
/datum/reagent/sorium_vortex
name = "sorium_vortex"
id = "sorium_vortex"
reagent_state = LIQUID
color = "#FFA500"
/datum/reagent/liquid_dark_matter
name = "Liquid Dark Matter"
id = "liquid_dark_matter"
@@ -285,12 +279,6 @@
T.create_reagents(50)
T.reagents.add_reagent("liquid_dark_matter", 5)
/datum/reagent/ldm_vortex
name = "LDM Vortex"
id = "ldm_vortex"
reagent_state = LIQUID
color = "#800080"
/datum/reagent/blackpowder
name = "Black Powder"
id = "blackpowder"
@@ -1049,6 +1049,11 @@
update_flags |= M.adjustToxLoss(1, FALSE)
return ..() | update_flags
/datum/reagent/pestkiller/reaction_obj(obj/O, volume)
if(istype(O, /obj/effect/decal/ants))
O.visible_message("<span class='warning'>The ants die.</span>")
qdel(O)
/datum/reagent/pestkiller/reaction_mob(mob/living/M, method=TOUCH, volume)
if(iscarbon(M))
var/mob/living/carbon/C = M
@@ -11,13 +11,11 @@
var/required_other = 0 // an integer required for the reaction to happen
var/result_amount = 0
var/secondary = 0 // set to nonzero if secondary reaction
var/list/secondary_results = list() //additional reagents produced by the reaction
var/min_temp = 0 //Minimum temperature required for the reaction to occur (heat to/above this). min_temp = 0 means no requirement
var/max_temp = 9999 //Maximum temperature allowed for the reaction to occur (cool to/below this).
var/mix_message = "The solution begins to bubble."
var/mix_sound = 'sound/effects/bubbles.ogg'
var/no_message = 0
/datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, created_volume)
return
@@ -89,55 +89,59 @@
name = "Sorium"
id = "sorium"
result = "sorium"
required_reagents = list("mercury" = 1, "oxygen" = 1, "nitrogen" = 1, "carbon" = 1)
required_reagents = list("mercury" = 1, "carbon" = 1, "nitrogen" = 1, "oxygen" = 1, "stabilizing_agent" = 1)
result_amount = 4
mix_message = "The mixture pops and crackles before settling down."
/datum/chemical_reaction/sorium/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
/datum/chemical_reaction/sorium_explosion
name = "Sorium Explosion"
id = "sorium_explosion"
required_reagents = list("mercury" = 1, "carbon" = 1, "nitrogen" = 1, "oxygen" = 1)
result_amount = 1
mix_message = "The mixture explodes with a big bang."
/datum/chemical_reaction/sorium_explosion/on_reaction(datum/reagents/holder, created_volume)
var/turf/T = get_turf(holder.my_atom)
if(!T)
return
var/turf/simulated/T = get_turf(holder.my_atom)
goonchem_vortex(T, 0, created_volume)
holder.remove_reagent("sorium", created_volume)
/datum/chemical_reaction/sorium_vortex
/datum/chemical_reaction/sorium_explosion/sorium
name = "sorium_vortex"
id = "sorium_vortex"
result = "sorium_vortex"
required_reagents = list("sorium" = 1)
result_amount = 1
min_temp = T0C + 200
/datum/chemical_reaction/sorium_vortex/on_reaction(datum/reagents/holder, created_volume)
var/turf/simulated/T = get_turf(holder.my_atom)
goonchem_vortex(T, 0, created_volume)
holder.remove_reagent("sorium_vortex", created_volume)
mix_sound = null
mix_message = null
/datum/chemical_reaction/liquid_dark_matter
name = "Liquid Dark Matter"
id = "liquid_dark_matter"
result = "liquid_dark_matter"
required_reagents = list("plasma" = 1, "radium" = 1, "carbon" = 1, "stabilizing_agent" = 1)
result_amount = 4
mix_message = "The mixture begins to glow in a dark purple."
/datum/chemical_reaction/ldm_implosion
name = "Implosion"
id = "implosion"
required_reagents = list("plasma" = 1, "radium" = 1, "carbon" = 1)
result_amount = 3
result_amount = 1
mix_message = "The mixture implodes suddenly."
/datum/chemical_reaction/liquid_dark_matter/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
/datum/chemical_reaction/ldm_implosion/on_reaction(datum/reagents/holder, created_volume)
var/turf/simulated/T = get_turf(holder.my_atom)
if(!T)
return
goonchem_vortex(T, 1, created_volume)
holder.remove_reagent("liquid_dark_matter", created_volume)
/datum/chemical_reaction/ldm_vortex
/datum/chemical_reaction/ldm_implosion/liquid_dark_matter
name = "LDM Vortex"
id = "ldm_vortex"
result = "ldm_vortex"
required_reagents = list("liquid_dark_matter" = 1)
result_amount = 1
min_temp = T0C + 200
/datum/chemical_reaction/ldm_vortex/on_reaction(datum/reagents/holder, created_volume)
var/turf/simulated/T = get_turf(holder.my_atom)
goonchem_vortex(T, 1, created_volume)
holder.remove_reagent("ldm_vortex", created_volume)
mix_sound = null
mix_message = null
/datum/chemical_reaction/blackpowder
name = "Black Powder"
@@ -154,7 +158,7 @@
required_reagents = list("blackpowder" = 1)
result_amount = 1
min_temp = T0C + 200
no_message = 1
mix_message = null
mix_sound = null
/datum/chemical_reaction/blackpowder_explosion/on_reaction(datum/reagents/holder, created_volume)
@@ -175,42 +179,35 @@
spawn(0)
qdel(holder.my_atom)
datum/chemical_reaction/flash_powder
/datum/chemical_reaction/flash_powder
name = "Flash powder"
id = "flash_powder"
result = "flash_powder"
required_reagents = list("aluminum" = 1, "potassium" = 1, "sulfur" = 1, "chlorine" = 1)
result_amount = 3
required_reagents = list("aluminum" = 1, "potassium" = 1, "sulfur" = 1, "chlorine" = 1, "stabilizing_agent" = 1)
result_amount = 5
mix_message = "The chemicals hiss and fizz briefly before falling still."
/datum/chemical_reaction/flash_powder/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
var/location = get_turf(holder.my_atom)
do_sparks(2, 1, location)
for(var/mob/living/carbon/C in viewers(5, location))
if(C.flash_eyes())
if(get_dist(C, location) < 4)
C.Weaken(5)
continue
C.Stun(5)
holder.remove_reagent("flash_powder", created_volume)
/datum/chemical_reaction/flash_powder_flash
name = "Flash powder activation"
id = "flash_powder_flash"
/datum/chemical_reaction/flash
name = "Flash"
id = "flash"
result = null
required_reagents = list("aluminum" = 1, "potassium" = 1, "sulfur" = 1, "chlorine" = 1)
mix_message = "The chemicals catch fire, burning brightly and violently!"
mix_sound = 'sound/effects/bang.ogg'
/datum/chemical_reaction/flash/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
if(!location)
return
do_sparks(2, 1, location)
bang(location, holder.my_atom, 5, flash = TRUE, bang = FALSE)
/datum/chemical_reaction/flash/flash_powder
name = "flash_powder_flash"
id = "flash_powder_flash"
required_reagents = list("flash_powder" = 1)
min_temp = T0C + 100
/datum/chemical_reaction/flash_powder_flash/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
do_sparks(2, 1, location)
for(var/mob/living/carbon/C in viewers(5, location))
if(C.flash_eyes())
if(get_dist(C, location) < 4)
C.Weaken(5)
continue
C.Stun(5)
mix_message = null
/datum/chemical_reaction/phlogiston
name = "Phlogiston"
@@ -250,7 +247,7 @@ datum/chemical_reaction/flash_powder
name = "smoke_powder"
id = "smoke_powder"
result = "smoke_powder"
required_reagents = list("stabilizing_agent" = 1, "potassium" = 1, "sugar" = 1, "phosphorus" = 1)
required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1, "stabilizing_agent" = 1)
result_amount = 3
mix_message = "The mixture sets into a greyish powder!"
@@ -285,7 +282,6 @@ datum/chemical_reaction/flash_powder
id = "smoke_powder_smoke"
required_reagents = list("smoke_powder" = 1)
min_temp = T0C + 100
secondary = 1
result_amount = 1
forbidden_reagents = list("stimulants")
mix_sound = null
@@ -294,78 +290,30 @@ datum/chemical_reaction/flash_powder
name = "sonic_powder"
id = "sonic_powder"
result = "sonic_powder"
required_reagents = list("oxygen" = 1, "cola" = 1, "phosphorus" = 1, "stabilizing_agent" = 1)
result_amount = 2
mix_message = "The mixture begins to bubble slighly!"
/datum/chemical_reaction/sonic_deafen
name = "sonic_deafen"
id = "sonic_deafen"
result = null
required_reagents = list("oxygen" = 1, "cola" = 1, "phosphorus" = 1)
result_amount = 3
mix_message = "The mixture begins to bubble furiously!"
mix_sound = 'sound/effects/bang.ogg'
/datum/chemical_reaction/sonic_powder/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
/datum/chemical_reaction/sonic_deafen/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
playsound(location, 'sound/effects/bang.ogg', 25, 1)
for(var/mob/living/M in hearers(5, location))
var/ear_safety = 0
var/distance = max(1,get_dist(src,T))
if(iscarbon(M))
var/mob/living/carbon/C = M
if(ishuman(C))
var/mob/living/carbon/human/H = C
if((H.r_ear && (H.r_ear.flags & EARBANGPROTECT)) || (H.l_ear && (H.l_ear.flags & EARBANGPROTECT)) || (H.head && (H.head.flags & HEADBANGPROTECT)))
ear_safety++
to_chat(C, "<span class='warning'>BANG</span>")
if(!ear_safety)
M.Stun(max(10/distance, 3))
M.Weaken(max(10/distance, 3))
M.AdjustEarDamage(rand(0, 5), 15)
if(iscarbon(M))
var/mob/living/carbon/C = M
var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears)
if(istype(ears))
if(ears.ear_damage >= 15)
to_chat(M, "<span class='warning'>Your ears start to ring badly!</span>")
if(prob(ears.ear_damage - 5))
to_chat(M, "<span class='warning'>You can't hear anything!</span>")
M.BecomeDeaf()
else
if(ears.ear_damage >= 5)
to_chat(M, "<span class='warning'>Your ears start to ring!</span>")
holder.remove_reagent("sonic_powder", created_volume)
if(!location)
return
bang(location, holder.my_atom, 5, flash = FALSE, bang = TRUE)
/datum/chemical_reaction/sonic_powder_deafen
/datum/chemical_reaction/sonic_deafen/sonic_powder
name = "sonic_powder_deafen"
id = "sonic_powder_deafen"
result = null
required_reagents = list("sonic_powder" = 1)
min_temp = T0C + 100
/datum/chemical_reaction/sonic_powder_deafen/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
playsound(location, 'sound/effects/bang.ogg', 25, 1)
for(var/mob/living/M in hearers(5, location))
var/ear_safety = 0
var/distance = max(1,get_dist(src,T))
if(iscarbon(M))
var/mob/living/carbon/C = M
if(ishuman(C))
var/mob/living/carbon/human/H = C
if((H.r_ear && (H.r_ear.flags & EARBANGPROTECT)) || (H.l_ear && (H.l_ear.flags & EARBANGPROTECT)) || (H.head && (H.head.flags & HEADBANGPROTECT)))
ear_safety++
to_chat(M, "<span class='warning'>BANG</span>")
if(!ear_safety)
M.Stun(max(10/distance, 3))
M.Weaken(max(10/distance, 3))
M.AdjustEarDamage(rand(0, 5), 15)
if(iscarbon(M))
var/mob/living/carbon/C = M
var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears)
if(istype(ears))
if(ears.ear_damage >= 15)
to_chat(M, "<span class='warning'>Your ears start to ring badly!</span>")
if(prob(ears.ear_damage - 5))
to_chat(M, "<span class='warning'>You can't hear anything!</span>")
M.BecomeDeaf()
else
if(ears.ear_damage >= 5)
to_chat(M, "<span class='warning'>Your ears start to ring!</span>")
mix_message = null
/datum/chemical_reaction/cryostylane
name = "cryostylane"
@@ -15,7 +15,7 @@
result_amount = 1
min_temp = T0C + 400
mix_sound = null
no_message = 1
mix_message = null
/datum/chemical_reaction/cyanide
name = "Cyanide"
@@ -113,7 +113,7 @@
to_chat(user, "<span class='warning'>You cannot fill [target] while it is sealed.</span>")
return
else if(istype(target, /obj/effect/decal/cleanable)) //stops splashing while scooping up fluids
else if(istype(target, /obj/effect/decal)) //stops splashing while scooping up fluids
return
else if(reagents.total_volume)
@@ -11,6 +11,7 @@
volume = 100
consume_sound = null
taste = FALSE
antable = FALSE
/obj/item/reagent_containers/food/pill/New()
..()
+6 -2
View File
@@ -177,7 +177,9 @@
var/obj/structure/closet/crate/O = target
if(O.opened)
return
if(use(3))
if(amount >= 3 && do_after_once(user, 15, target = target))
if(O.opened || !use(3))
return
var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc))
P.icon_state = "deliverycrate"
P.wrapped = O
@@ -189,7 +191,9 @@
var/obj/structure/closet/O = target
if(O.opened)
return
if(use(3))
if(amount >= 3 && do_after_once(user, 15, target = target))
if(O.opened || !use(3))
return
var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc))
P.wrapped = O
P.init_welded = O.welded
+1 -13
View File
@@ -18,23 +18,11 @@
// Takes care blood loss and regeneration
/mob/living/carbon/human/handle_blood()
var/list/blood_data = get_blood_data(get_blood_id())//PROCCEPTION
if(NO_BLOOD in dna.species.species_traits)
bleed_rate = 0
return
if(bodytemperature >= 225 && !(NOCLONE in mutations)) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
if(blood_volume < max_blood && blood_volume)
if(mind) //Handles vampires "eating" blood that isn't their own.
if(mind in ticker.mode.vampires)
if(nutrition >= NUTRITION_LEVEL_WELL_FED)
return //We don't want blood tranfusions making vampires fat.
if(blood_data["donor"] != src)
nutrition += (15 * REAGENTS_METABOLISM)
return //Only process one blood per tick, to maintain the same metabolism as nutriment for non-vampires.
if(blood_volume < BLOOD_VOLUME_NORMAL)
blood_volume += 0.1 // regenerate blood VERY slowly
@@ -56,7 +44,7 @@
if(prob(15))
Paralyse(rand(1,3))
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
if(0 to BLOOD_VOLUME_SURVIVE)
if(-INFINITY to BLOOD_VOLUME_SURVIVE)
death()
var/temp_bleed = 0
+4 -1
View File
@@ -402,4 +402,7 @@ DISABLE_HIGH_POP_MC_MODE_AMOUNT 60
##DEVELOPER_EXPRESS_START
## Uncomment to disable automatic admin for localhost
#DISABLE_LOCALHOST_ADMIN
#DISABLE_LOCALHOST_ADMIN
## Uncomment to give a confirmation before hitting start now
#START_NOW_CONFIRMATION
+85
View File
@@ -56,6 +56,91 @@
-->
<div class="commit sansserif">
<h2 class="date">04 April 2019</h2>
<h3 class="author">Kyep updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Improved the interface for Syndicate Uplinks. They now clearly mark which items are hijack-only and which are not. If you attempt to purchase a hijack-only item without hijack, they will explain why you can't.</li>
<li class="tweak">Atmos Gas Grenades (the uplink grenade kit) are now split into Knockout grenades (2 N2O grenades, 8 TC, available to all agents), and Plasma Fire grenades (2 plasma fire grenades, 12 TC, only available if you have hijack). This both makes knockout grenades more useful for normal traitors, and also prevents non-hijackers using a plasma fire grenade to cause massive casualties/damage.</li>
<li class="tweak">Plasma Grenades and the Syndicate Bomb can no longer show up in surplus crates, or be discounted. This means while you can buy one if you intend to, you're not randomly encouraged to bomb your target.</li>
</ul>
<h2 class="date">03 April 2019</h2>
<h3 class="author">Fox McCloud updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Dramatically improves human life performance (sorry, doesn't fix your actual crappy real life)</li>
<li class="tweak">Blobspores will additionally zomify all players who have 200 damage or more</li>
<li class="tweak">Holoparasites will additionally die once their host has 200 damage or more</li>
<li class="bugfix">Fixes blob zombies who infect players who have no head being invisible</li>
</ul>
<h3 class="author">farie82 updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Death nettle can be picked up again</li>
<li class="bugfix">Auto cloning now doesn't clone a person more than once.</li>
<li class="tweak">A person in the cloning scanner won't be scanned if he's already being cloned</li>
</ul>
<h2 class="date">02 April 2019</h2>
<h3 class="author">Alonefromhell & AffectedArc07 updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Fixed an edgecase compile error for spacehotel.dmm</li>
</ul>
<h3 class="author">Arkatos updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Added Medical Beamgun to a Syndicate Medical Cyborg</li>
<li class="tweak">Appropriate antagonist sound theme now plays when an antagonist is selected via Traitor Panel</li>
<li class="tweak">Cult sound theme now plays for a new cult converts</li>
<li class="tweak">Traitor/Malfunction sound theme now plays for newly autotraitored crew/AI</li>
</ul>
<h3 class="author">AzuleUtama updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Cleaned up some outdated code left in uplinks.dm</li>
</ul>
<h3 class="author">Fox McCloud updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Fixes some mobs not being able to hear sounds</li>
<li class="bugfix">Fixes the Master Controller not actually shutting down on round end</li>
<li class="rscadd">Adds space ants to the game; leave your food on tables or inside a container to avoid infestation!</li>
<li class="bugfix">Fixes bees not properly generating if they have a reagent in them</li>
<li class="rscadd">Can break bee boxes</li>
<li class="bugfix">Fixes bees breaking things they shouldn't</li>
<li class="bugfix">Fixes bees not properly injecting toxin if they lacked a reagent</li>
<li class="tweak">purchased bee boxes are no longer wrenched down by default</li>
<li class="rscadd">Adds trick revolver to the syndicate uplink for the clown. Teach those pesky validhunters a lesson!</li>
<li class="rscadd">Adds the ability for admins to start a revolver only summon gun version; there's also a suicidal version that makes half the guns summoned real and the other half trick revolvers</li>
<li class="tweak">stabilizing agent gets used up in reactions that utilize it</li>
<li class="tweak">flashbangs spark when they initially go off</li>
<li class="bugfix">Fixes mech users being stunned by their own flashbangs</li>
<li class="bugfix">Fixes necromantic stone not working properly and other edge cases where you had O2 damage and could become O2 damage immune</li>
</ul>
<h3 class="author">KasparoVy updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Adds Vox-fitted Tajaran veil sprites.</li>
<li class="rscdel">Removed stray pixel from Vox-fitted gasmask sprites.</li>
<li class="tweak">Adjusts the Vox-fitted blindfold sprite.</li>
</ul>
<h3 class="author">Kyep updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Blob mobs can definitely no longer be spawned in xenobio.</li>
<li class="tweak">Changed playtime requirements for command jobs. HoS/RD/CE/CMO/AI now require 5h played in their department to be playable. HoP/Captain now require 5h played as a member of the command staff.</li>
</ul>
<h3 class="author">Markolie updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Fixed some issues the compiler doesn't spot and some start up issues.</li>
</ul>
<h3 class="author">Ty-Omaha updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Start now confirmation is now a config option</li>
<li class="rscadd">Grid check event sound effect</li>
</ul>
<h3 class="author">farie82 updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Antidrop give edge case fixed</li>
<li class="bugfix">Can't give items to resting people now</li>
<li class="bugfix">put_in_hands now checks if you actually have hands</li>
<li class="tweak">Wrapping lockers and crates now takes 1.5 seconds to do</li>
<li class="tweak">Welding lockers now takes 1.5 seconds to do</li>
</ul>
<h2 class="date">01 April 2019</h2>
<h3 class="author">Arkatos updated:</h3>
<ul class="changes bgimages16">
+77
View File
@@ -9610,3 +9610,80 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- bugfix: Bluespace golems no longer can crash the server
- tweak: Spontaneous combustion now has a minimum stacksize of 1. No more getting
wet from the fire virus
2019-04-02:
Alonefromhell & AffectedArc07:
- bugfix: Fixed an edgecase compile error for spacehotel.dmm
Arkatos:
- rscadd: Added Medical Beamgun to a Syndicate Medical Cyborg
- tweak: Appropriate antagonist sound theme now plays when an antagonist is selected
via Traitor Panel
- tweak: Cult sound theme now plays for a new cult converts
- tweak: Traitor/Malfunction sound theme now plays for newly autotraitored crew/AI
AzuleUtama:
- tweak: Cleaned up some outdated code left in uplinks.dm
Fox McCloud:
- bugfix: Fixes some mobs not being able to hear sounds
- bugfix: Fixes the Master Controller not actually shutting down on round end
- rscadd: Adds space ants to the game; leave your food on tables or inside a container
to avoid infestation!
- bugfix: Fixes bees not properly generating if they have a reagent in them
- rscadd: Can break bee boxes
- bugfix: Fixes bees breaking things they shouldn't
- bugfix: Fixes bees not properly injecting toxin if they lacked a reagent
- tweak: purchased bee boxes are no longer wrenched down by default
- rscadd: Adds trick revolver to the syndicate uplink for the clown. Teach those
pesky validhunters a lesson!
- rscadd: Adds the ability for admins to start a revolver only summon gun version;
there's also a suicidal version that makes half the guns summoned real and the
other half trick revolvers
- tweak: stabilizing agent gets used up in reactions that utilize it
- tweak: flashbangs spark when they initially go off
- bugfix: Fixes mech users being stunned by their own flashbangs
- bugfix: Fixes necromantic stone not working properly and other edge cases where
you had O2 damage and could become O2 damage immune
KasparoVy:
- rscadd: Adds Vox-fitted Tajaran veil sprites.
- rscdel: Removed stray pixel from Vox-fitted gasmask sprites.
- tweak: Adjusts the Vox-fitted blindfold sprite.
Kyep:
- bugfix: Blob mobs can definitely no longer be spawned in xenobio.
- tweak: Changed playtime requirements for command jobs. HoS/RD/CE/CMO/AI now require
5h played in their department to be playable. HoP/Captain now require 5h played
as a member of the command staff.
Markolie:
- bugfix: Fixed some issues the compiler doesn't spot and some start up issues.
Ty-Omaha:
- tweak: Start now confirmation is now a config option
- rscadd: Grid check event sound effect
farie82:
- bugfix: Antidrop give edge case fixed
- bugfix: Can't give items to resting people now
- bugfix: put_in_hands now checks if you actually have hands
- tweak: Wrapping lockers and crates now takes 1.5 seconds to do
- tweak: Welding lockers now takes 1.5 seconds to do
2019-04-03:
Fox McCloud:
- bugfix: Dramatically improves human life performance (sorry, doesn't fix your
actual crappy real life)
- tweak: Blobspores will additionally zomify all players who have 200 damage or
more
- tweak: Holoparasites will additionally die once their host has 200 damage or more
- bugfix: Fixes blob zombies who infect players who have no head being invisible
farie82:
- bugfix: Death nettle can be picked up again
- bugfix: Auto cloning now doesn't clone a person more than once.
- tweak: A person in the cloning scanner won't be scanned if he's already being
cloned
2019-04-04:
Kyep:
- tweak: Improved the interface for Syndicate Uplinks. They now clearly mark which
items are hijack-only and which are not. If you attempt to purchase a hijack-only
item without hijack, they will explain why you can't.
- tweak: Atmos Gas Grenades (the uplink grenade kit) are now split into Knockout
grenades (2 N2O grenades, 8 TC, available to all agents), and Plasma Fire grenades
(2 plasma fire grenades, 12 TC, only available if you have hijack). This both
makes knockout grenades more useful for normal traitors, and also prevents non-hijackers
using a plasma fire grenade to cause massive casualties/damage.
- tweak: Plasma Grenades and the Syndicate Bomb can no longer show up in surplus
crates, or be discounted. This means while you can buy one if you intend to,
you're not randomly encouraged to bomb your target.
@@ -1,4 +0,0 @@
author: "Markolie"
delete-after: True
changes:
- bugfix: "Fixed some issues the compiler doesn't spot and some start up issues."
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

+1 -1
View File
@@ -46,7 +46,7 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm
{{for value.items :itemValue:itemIndex}}
<tr>
<td><div class='floatLeft tooltipRight' data-tooltip='{{:tooltiptext(itemValue.Description)}}'>
{{:helper.link( itemValue.Name, 'gear', {'buy_item' : itemValue.obj_path, 'cost' : itemValue.Cost}, itemValue.Cost > data.crystals ? 'disabled' : null, null)}} - <span class="white">{{:itemValue.Cost}}</span>
{{:helper.link( itemValue.Name, 'gear', {'buy_item' : itemValue.obj_path, 'cost' : itemValue.Cost}, itemValue.Cost > data.crystals ? 'disabled' : null, null)}} - <span class="white">{{:itemValue.Cost}}</span> {{if itemValue.hijack_only}}(HIJACK AGENTS ONLY){{/if}}
</div></td>
</tr>
{{/for}}
Binary file not shown.