Merge branch 'master' into upstream-merge-31222

This commit is contained in:
LetterJay
2017-10-04 21:50:07 -04:00
committed by GitHub
100 changed files with 1202 additions and 499 deletions
@@ -49,7 +49,7 @@
icon = 'icons/effects/fire.dmi'
icon_state = "1"
layer = ABOVE_OPEN_TURF_LAYER
light_range = 3
light_range = LIGHT_RANGE_FIRE
light_color = LIGHT_COLOR_FIRE
var/volume = 125
@@ -175,3 +175,15 @@
..()
if(isliving(L))
L.fire_act(temperature, volume)
/obj/effect/dummy/fire
name = "fire"
desc = "OWWWWWW. IT BURNS. Tell a coder if you're seeing this."
icon_state = "nothing"
light_color = LIGHT_COLOR_FIRE
light_range = LIGHT_RANGE_FIRE
/obj/effect/dummy/fire/Initialize()
. = ..()
if(!isliving(loc))
qdel(src)
@@ -185,7 +185,9 @@
/obj/item/reagent_containers/food/snacks/monkeycube/proc/Expand()
visible_message("<span class='notice'>[src] expands!</span>")
new /mob/living/carbon/monkey(get_turf(src))
var/mob/spammer = get_mob_by_key(src.fingerprintslast)
var/mob/living/carbon/monkey/bananas = new(get_turf(src))
bananas.log_message("Spawned via [src] at [COORD(src)], Last attached mob: [key_name(spammer)].", INDIVIDUAL_ATTACK_LOG)
qdel(src)
/obj/item/reagent_containers/food/snacks/enchiladas
+15
View File
@@ -25,6 +25,21 @@
var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/book) //Things allowed in the bookcase
/obj/structure/bookcase/examine(mob/user)
..()
if(!anchored)
to_chat(user, "<span class='notice'>The <i>bolts</i> on the bottom are unsecured.</span>")
if(anchored)
to_chat(user, "<span class='notice'>It's secured in place with <b>bolts</b>.</span>")
switch(state)
if(0)
to_chat(user, "<span class='notice'>There's a <b>small crack</b> visible on the back panel.</span>")
if(1)
to_chat(user, "<span class='notice'>There's space inside for a <i>wooden</i> shelf.</span>")
if(2)
to_chat(user, "<span class='notice'>There's a <b>small crack</b> visible on the shelf.</span>")
/obj/structure/bookcase/Initialize(mapload)
. = ..()
if(!mapload)
@@ -59,6 +59,7 @@
if(previewJob && !nude)
mannequin.job = previewJob.title
previewJob.equip(mannequin, TRUE)
mannequin.compile_overlays()
CHECK_TICK
preview_icon = icon('icons/effects/effects.dmi', "nothing")
preview_icon.Scale(48+32, 16+32)
+4 -8
View File
@@ -18,12 +18,12 @@
vital = FALSE
decoy_override = TRUE
/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0)
/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0,no_id_transfer = FALSE)
..()
name = "brain"
if(C.mind && C.mind.changeling) //congrats, you're trapped in a body you don't control
if(C.mind && C.mind.changeling && !no_id_transfer) //congrats, you're trapped in a body you don't control
if(brainmob && !(C.stat == DEAD || (C.status_flags & FAKEDEATH)))
to_chat(brainmob, "<span class = danger>You can't feel your body! You're still just a brain!</span>")
loc = C
@@ -44,13 +44,9 @@
//Update the body's icon so it doesnt appear debrained anymore
C.update_hair()
/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0)
/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0, no_id_transfer = FALSE)
..()
if(!special)
if(C.has_brain_worms())
var/mob/living/simple_animal/borer/B = C.has_brain_worms()
B.leave_victim() //Should remove borer if the brain is removed - RR
if(!gc_destroyed || (owner && !owner.gc_destroyed))
if((!gc_destroyed || (owner && !owner.gc_destroyed)) && !no_id_transfer)
transfer_identity(C)
C.update_hair()
@@ -250,6 +250,9 @@
if(health >= 0 && !(status_flags & FAKEDEATH))
if(lying)
if(buckled)
to_chat(M, "<span class='warning'>You need to unbuckle [src] first to do that!")
return
M.visible_message("<span class='notice'>[M] shakes [src] trying to get [p_them()] up!</span>", \
"<span class='notice'>You shake [src] trying to get [p_them()] up!</span>")
else if(check_zone(M.zone_selected) == "head")
@@ -277,9 +277,11 @@
if(!appears_dead)
if(stat == UNCONSCIOUS)
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
else if(getBrainLoss() >= 60)
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
else
if(getBrainLoss() >= 60)
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
if(InCritical())
msg += "[t_He] is barely concious.\n"
if(getorgan(/obj/item/organ/brain))
if(istype(src, /mob/living/carbon/human/interactive))
var/mob/living/carbon/human/interactive/auto = src
+2 -30
View File
@@ -4,6 +4,7 @@
voice_name = "Unknown"
icon = 'icons/mob/human.dmi'
icon_state = "caucasian_m"
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE
/mob/living/carbon/human/Initialize()
verbs += /mob/living/proc/mob_sleep
@@ -21,41 +22,12 @@
set_species(dna.species.type)
//initialise organs
create_internal_organs()
create_internal_organs() //most of it is done in set_species now, this is only for parent call
handcrafting = new()
. = ..()
/mob/living/carbon/human/create_internal_organs()
if(!(NOHUNGER in dna.species.species_traits))
internal_organs += new /obj/item/organ/appendix
if(!(NOBREATH in dna.species.species_traits))
if(dna.species.mutantlungs)
internal_organs += new dna.species.mutantlungs()
else
internal_organs += new /obj/item/organ/lungs()
if(!(NOBLOOD in dna.species.species_traits))
internal_organs += new /obj/item/organ/heart
if(!(NOLIVER in dna.species.species_traits))
if(dna.species.mutantliver)
internal_organs += new dna.species.mutantliver()
else
internal_organs += new /obj/item/organ/liver()
if(!(NOSTOMACH in dna.species.species_traits))
if(dna.species.mutantstomach)
internal_organs += new dna.species.mutantstomach()
else
internal_organs += new /obj/item/organ/stomach()
internal_organs += new dna.species.mutanteyes
internal_organs += new dna.species.mutantears
internal_organs += new dna.species.mutanttongue
internal_organs += new /obj/item/organ/brain
..()
/mob/living/carbon/human/OpenCraftingMenu()
handcrafting.ui_interact(src)
+110 -74
View File
@@ -68,7 +68,8 @@
//Flight and floating
var/override_float = 0
var/obj/item/organ/brain/mutant_brain = /obj/item/organ/brain
var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes
var/obj/item/organ/ears/mutantears = /obj/item/organ/ears
var/obj/item/mutanthands
@@ -123,6 +124,113 @@
return 0
return 1
//Will regenerate missing organs
/datum/species/proc/regenerate_organs(mob/living/carbon/C,datum/species/old_species,replace_current=TRUE)
var/obj/item/organ/brain/brain = C.getorganslot("brain")
var/obj/item/organ/heart/heart = C.getorganslot("heart")
var/obj/item/organ/lungs/lungs = C.getorganslot("lungs")
var/obj/item/organ/appendix/appendix = C.getorganslot("appendix")
var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
var/obj/item/organ/ears/ears = C.getorganslot("ears")
var/obj/item/organ/tongue/tongue = C.getorganslot("tongue")
var/obj/item/organ/liver/liver = C.getorganslot("liver")
var/obj/item/organ/stomach/stomach = C.getorganslot("stomach")
var/should_have_brain = TRUE
var/should_have_heart = !(NOBLOOD in species_traits)
var/should_have_lungs = !(NOBREATH in species_traits)
var/should_have_appendix = !(NOHUNGER in species_traits)
var/should_have_eyes = TRUE
var/should_have_ears = TRUE
var/should_have_tongue = TRUE
var/should_have_liver = !(NOLIVER in species_traits)
var/should_have_stomach = !(NOSTOMACH in species_traits)
if(brain && (replace_current || !should_have_brain))
if(!brain.decoy_override)//Just keep it if it's fake
brain.Remove(C,TRUE,TRUE)
QDEL_NULL(brain)
if(should_have_brain && !brain)
brain = new mutant_brain()
brain.Insert(C, TRUE, TRUE)
if(heart && (!should_have_heart || replace_current))
heart.Remove(C,1)
QDEL_NULL(heart)
if(should_have_heart && !heart)
heart = new()
heart.Insert(C)
if(lungs && (replace_current || !should_have_lungs))
lungs.Remove(C,1)
QDEL_NULL(lungs)
if(should_have_lungs && !lungs)
if(mutantlungs)
lungs = new mutantlungs()
else
lungs = new()
lungs.Insert(C)
if(liver && (!should_have_liver || replace_current))
liver.Remove(C,1)
QDEL_NULL(liver)
if(should_have_liver && !liver)
if(mutantliver)
liver = new mutantliver()
else
liver = new()
liver.Insert(C)
if(stomach && (!should_have_stomach || replace_current))
stomach.Remove(C,1)
QDEL_NULL(stomach)
if(should_have_stomach && !stomach)
if(mutantstomach)
stomach = new mutantstomach()
else
stomach = new()
stomach.Insert(C)
if(appendix && (!should_have_appendix || replace_current))
appendix.Remove(C,1)
QDEL_NULL(appendix)
if(should_have_appendix && !appendix)
appendix = new()
appendix.Insert(C)
if(C.get_bodypart("head"))
if(eyes && (replace_current || !should_have_eyes))
eyes.Remove(C,1)
QDEL_NULL(eyes)
if(should_have_eyes && !eyes)
eyes = new mutanteyes
eyes.Insert(C)
if(ears && (replace_current || !should_have_ears))
ears.Remove(C,1)
QDEL_NULL(ears)
if(should_have_ears && !ears)
ears = new mutantears
ears.Insert(C)
if(tongue && (replace_current || !should_have_tongue))
tongue.Remove(C,1)
QDEL_NULL(tongue)
if(should_have_tongue && !tongue)
tongue = new mutanttongue
tongue.Insert(C)
if(old_species)
for(var/mutantorgan in old_species.mutant_organs)
var/obj/item/organ/I = C.getorgan(mutantorgan)
if(I)
I.Remove(C)
QDEL_NULL(I)
for(var/path in mutant_organs)
var/obj/item/organ/I = new path()
I.Insert(C)
/datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species)
// Drop the items the new species can't wear
for(var/slot_id in no_equip)
@@ -138,79 +246,7 @@
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(FALSE)
var/obj/item/organ/heart/heart = C.getorganslot("heart")
var/obj/item/organ/lungs/lungs = C.getorganslot("lungs")
var/obj/item/organ/appendix/appendix = C.getorganslot("appendix")
var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
var/obj/item/organ/ears/ears = C.getorganslot("ears")
var/obj/item/organ/tongue/tongue = C.getorganslot("tongue")
var/obj/item/organ/liver/liver = C.getorganslot("liver")
var/obj/item/organ/stomach/stomach = C.getorganslot("stomach")
if((NOBLOOD in species_traits) && heart)
heart.Remove(C)
qdel(heart)
else if((!(NOBLOOD in species_traits)) && (!heart))
heart = new()
heart.Insert(C)
if(lungs)
qdel(lungs)
lungs = null
QDEL_NULL(liver)
QDEL_NULL(stomach)
if(C.get_bodypart("head"))
if(eyes)
qdel(eyes)
eyes = new mutanteyes
eyes.Insert(C)
if(ears)
qdel(ears)
ears = new mutantears
ears.Insert(C)
if(tongue)
qdel(tongue)
tongue = new mutanttongue
tongue.Insert(C)
if((!(NOBREATH in species_traits)) && !lungs)
if(mutantlungs)
lungs = new mutantlungs()
else
lungs = new()
lungs.Insert(C)
if((!(NOLIVER in species_traits)) && (!liver))
if(mutantliver)
liver = new mutantliver()
else
liver = new()
liver.Insert(C)
if((!(NOSTOMACH in species_traits)) && (!stomach))
if(mutantstomach)
stomach = new mutantstomach()
else
stomach = new()
stomach.Insert(C)
if((NOHUNGER in species_traits) && appendix)
qdel(appendix)
else if((!(NOHUNGER in species_traits)) && (!appendix))
appendix = new()
appendix.Insert(C)
for(var/path in mutant_organs)
var/obj/item/organ/I = new path()
I.Insert(C)
regenerate_organs(C,old_species)
if(exotic_bloodtype && C.dna.blood_type != exotic_bloodtype)
C.dna.blood_type = exotic_bloodtype
@@ -37,7 +37,7 @@
if(H.nutrition > NUTRITION_LEVEL_FULL)
H.nutrition = NUTRITION_LEVEL_FULL
if(light_amount > 0.2) //if there's enough light, heal
H.heal_overall_damage(0.05,0)
H.heal_overall_damage(0.75,0)
H.adjustOxyLoss(-0.5)
if(H.nutrition < NUTRITION_LEVEL_STARVING + 55)
@@ -1,3 +1,5 @@
#define HEART_RESPAWN_THRESHHOLD 40
/datum/species/shadow
// Humans cursed to stay in the darkness, lest their life forces drain. They regain health in shadow and die in light.
name = "???"
@@ -32,31 +34,21 @@
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store)
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR,NOHUNGER,NO_DNA_COPY,NOTRANSSTING)
mutanteyes = /obj/item/organ/eyes/night_vision/nightmare
var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk
mutant_organs = list(/obj/item/organ/heart/nightmare)
mutant_brain = /obj/item/organ/brain/nightmare
var/info_text = "You are a <span class='danger'>Nightmare</span>. The ability <span class='warning'>shadow walk</span> allows unlimited, unrestricted movement in the dark using. \
Your <span class='warning'>light eater</span> will destroy any light producing objects you attack, as well as destroy any lights a living creature may be holding. You will automatically dodge gunfire and melee attacks when on a dark tile."
var/info_text = "You are a <span class='danger'>Nightmare</span>. The ability <span class='warning'>shadow walk</span> allows unlimited, unrestricted movement in the dark while activated. \
Your <span class='warning'>light eater</span> will destroy any light producing objects you attack, as well as destroy any lights a living creature may be holding. You will automatically dodge gunfire and melee attacks when on a dark tile. If killed, you will eventually revive if left in darkness."
/datum/species/shadow/nightmare/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
var/obj/effect/proc_holder/spell/targeted/shadowwalk/SW = new
C.AddSpell(SW)
shadowwalk = SW
var/obj/item/light_eater/blade = new
C.put_in_hands(blade)
to_chat(C, "[info_text]")
C.real_name = "Nightmare"
C.name = "Nightmare"
C.real_name = "[pick(GLOB.nightmare_names)]"
C.name = C.real_name
if(C.mind)
C.mind.name = "Nightmare"
C.dna.real_name = "Nightmare"
/datum/species/shadow/nightmare/on_species_loss(mob/living/carbon/C)
. = ..()
if(shadowwalk)
C.RemoveSpell(shadowwalk)
C.mind.name = C.real_name
C.dna.real_name = C.real_name
/datum/species/shadow/nightmare/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
var/turf/T = H.loc
@@ -68,6 +60,93 @@
return -1
return 0
//Organs
/obj/item/organ/brain/nightmare
name = "tumorous mass"
desc = "A fleshy growth that was dug out of the skull of a Nightmare."
icon_state = "brain-x-d"
var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk
/obj/item/organ/brain/nightmare/Insert(mob/living/carbon/M, special = 0)
..()
if(M.dna.species.id != "nightmare")
M.set_species(/datum/species/shadow/nightmare)
visible_message("<span class='warning'>[M] thrashes as [src] takes root in their body!</span>")
var/obj/effect/proc_holder/spell/targeted/shadowwalk/SW = new
M.AddSpell(SW)
shadowwalk = SW
/obj/item/organ/brain/nightmare/Remove(mob/living/carbon/M, special = 0)
if(shadowwalk)
M.RemoveSpell(shadowwalk)
..()
/obj/item/organ/heart/nightmare
name = "heart of darkness"
desc = "An alien organ that twists and writhes when exposed to light."
icon = 'icons/obj/surgery.dmi'
icon_state = "demon_heart-on"
color = "#1C1C1C"
var/respawn_progress = 0
var/obj/item/light_eater/blade
/obj/item/organ/heart/nightmare/attack(mob/M, mob/living/carbon/user, obj/target)
if(M != user)
return ..()
user.visible_message("<span class='warning'>[user] raises [src] to their mouth and tears into it with their teeth!</span>", \
"<span class='danger'>[src] feels unnaturally cold in your hands. You raise [src] your mouth and devour it!</span>")
playsound(user, 'sound/magic/demon_consume.ogg', 50, 1)
user.visible_message("<span class='warning'>Blood erupts from [user]'s arm as it reforms into a weapon!</span>", \
"<span class='userdanger'>Icy blood pumps through your veins as your arm reforms itself!</span>")
user.temporarilyRemoveItemFromInventory(src, TRUE)
Insert(user)
/obj/item/organ/heart/nightmare/Insert(mob/living/carbon/M, special = 0)
..()
blade = new/obj/item/light_eater
M.put_in_hands(blade)
START_PROCESSING(SSobj, src)
/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0)
STOP_PROCESSING(SSobj, src)
respawn_progress = 0
if(blade)
QDEL_NULL(blade)
M.visible_message("<span class='warning'>\The [blade] disintegrates!</span>")
..()
/obj/item/organ/heart/nightmare/Stop()
return 0
/obj/item/organ/heart/nightmare/update_icon()
return //always beating visually
/obj/item/organ/heart/nightmare/process()
if(QDELETED(owner) || owner.stat != DEAD)
respawn_progress = 0
return
var/turf/T = get_turf(owner)
if(istype(T))
var/light_amount = T.get_lumcount()
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
respawn_progress++
playsound(owner,'sound/effects/singlebeat.ogg',40,1)
if(respawn_progress >= HEART_RESPAWN_THRESHHOLD)
owner.revive(full_heal = TRUE)
owner.visible_message("<span class='warning'>[owner] staggers to their feet!</span>")
playsound(owner, 'sound/hallucinations/far_noise.ogg', 50, 1)
respawn_progress = 0
//Weapon
/obj/item/light_eater
name = "light eater"
icon_state = "arm_blade"
@@ -113,3 +192,5 @@
visible_message("<span class='danger'>[O] is disintegrated by [src]!</span>")
O.burn()
playsound(src, 'sound/items/welder.ogg', 50, 1)
#undef HEART_RESPAWN_THRESHHOLD
@@ -1,13 +1,13 @@
/datum/species/skeleton
// 2spooky
name = "Spooky Scary Skeleton"
id = "skeleton"
say_mod = "rattles"
blacklisted = 1
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
mutant_organs = list(/obj/item/organ/tongue/bone)
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
disliked_food = NONE
liked_food = NONE
/datum/species/skeleton
// 2spooky
name = "Spooky Scary Skeleton"
id = "skeleton"
say_mod = "rattles"
blacklisted = 1
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
mutanttongue = /obj/item/organ/tongue/bone
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
disliked_food = NONE
liked_food = NONE
@@ -9,7 +9,7 @@
blacklisted = 1
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT,NOTRANSSTING)
mutant_organs = list(/obj/item/organ/tongue/zombie)
mutanttongue = /obj/item/organ/tongue/zombie
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
disliked_food = NONE
liked_food = NONE
@@ -37,6 +37,7 @@
C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW
if(regen_cooldown < world.time)
C.heal_overall_damage(4,4)
C.adjustToxLoss(-4)
if(prob(4))
playsound(C, pick(spooks), 50, TRUE, 10)
if(C.InCritical())
@@ -64,6 +65,6 @@
limbs_id = "zombie" //They look like zombies
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
mutant_organs = list(/obj/item/organ/tongue/zombie)
mutanttongue = /obj/item/organ/tongue/zombie
#undef REGENERATION_DELAY
+3 -2
View File
@@ -884,7 +884,7 @@
on_fire = 1
src.visible_message("<span class='warning'>[src] catches fire!</span>", \
"<span class='userdanger'>You're set on fire!</span>")
src.set_light(3)
new/obj/effect/dummy/fire(src)
throw_alert("fire", /obj/screen/alert/fire)
update_fire()
return TRUE
@@ -894,7 +894,8 @@
if(on_fire)
on_fire = 0
fire_stacks = 0
src.set_light(0)
for(var/obj/effect/dummy/fire/F in src)
qdel(F)
clear_alert("fire")
update_fire()
@@ -86,7 +86,7 @@
if(istype(head, /obj/item/clothing/mask))
used_head_icon = 'icons/mob/mask.dmi'
var/mutable_appearance/head_overlay = head.build_worn_icon(state = head.icon_state, default_layer = DRONE_HEAD_LAYER, default_icon_file = used_head_icon)
head_overlay.pixel_y += -15
head_overlay.pixel_y -= 15
drone_overlays[DRONE_HEAD_LAYER] = head_overlay
@@ -180,10 +180,13 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
new /obj/effect/temp_visual/guardian/phase(loc)
/mob/living/simple_animal/hostile/guardian/canSuicide()
return 0
return FALSE
/mob/living/simple_animal/hostile/guardian/proc/is_deployed()
return loc != summoner
/mob/living/simple_animal/hostile/guardian/AttackingTarget()
if(loc == summoner)
if(!is_deployed())
to_chat(src, "<span class='danger'><B>You must be manifested to attack!</span></B>")
return FALSE
else
@@ -28,7 +28,7 @@
/mob/living/simple_animal/hostile/guardian/healer/AttackingTarget()
. = ..()
if(. && toggle && iscarbon(target))
if(is_deployed() && toggle && iscarbon(target))
var/mob/living/carbon/C = target
C.adjustBruteLoss(-5)
C.adjustFireLoss(-5)
@@ -105,22 +105,22 @@
/mob/living/simple_animal/hostile/poison/bees/CanAttack(atom/the_target)
. = ..()
if(!.)
return 0
return FALSE
if(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/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 |= typecacheof(/obj/machinery/hydroponics) //so we only hunt them while they're alive/seeded/not visisted
return 1
if(isliving(A))
var/mob/living/H = A
return !H.bee_friendly()
return 0
return TRUE
return FALSE
/mob/living/simple_animal/hostile/poison/bees/AttackingTarget()
@@ -187,7 +187,7 @@
if(loc == beehome)
idle = min(100, ++idle)
if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM))
forceMove(get_turf(beehome))
forceMove(beehome.drop_location())
else
idle = max(0, --idle)
if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME))
@@ -200,6 +200,7 @@
continue
BB.bees |= src
beehome = BB
break // End loop after the first compatible find.
/mob/living/simple_animal/hostile/poison/bees/toxin/Initialize()
. = ..()
@@ -215,7 +216,7 @@
//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
@@ -234,10 +235,10 @@
/mob/living/simple_animal/hostile/poison/bees/proc/reagent_incompatible(mob/living/simple_animal/hostile/poison/bees/B)
if(!B)
return 0
return FALSE
if(B.beegent && beegent && B.beegent.id != beegent.id || B.beegent && !beegent || !B.beegent && beegent)
return 1
return 0
return TRUE
return FALSE
/obj/item/queen_bee
@@ -255,7 +256,7 @@
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))
S.reagents.remove_reagent("royal_bee_jelly", 5)
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.
@@ -115,7 +115,11 @@
if(can_see(targets_from, HM, vision_range))
. += HM
else
. = oview(vision_range, targets_from)
. = list() // The following code is only very slightly slower than just returning oview(vision_range, targets_from), but it saves us much more work down the line, particularly when bees are involved
for (var/obj/A in oview(vision_range, targets_from))
. += A
for (var/mob/A in oview(vision_range, targets_from))
. += A
/mob/living/simple_animal/hostile/proc/FindTarget(var/list/possible_targets, var/HasTargetsList = 0)//Step 2, filter down possible targets to things we actually care about
. = list()
@@ -62,6 +62,9 @@
return TRUE
if(isobj(the_target) && is_type_in_typecache(the_target, wanted_objects))
return TRUE
return FALSE
/mob/living/simple_animal/hostile/asteroid/gutlunch/Destroy()
+1 -1
View File
@@ -63,7 +63,7 @@
if(isnum(.)) //Numerical values of drained handle their feedback here, Alpha values handle it themselves (Research hacking)
if(.)
to_chat(H, "<span class='notice'>Gained <B>[.]</B> energy from \the [A].</span>")
to_chat(H, "<span class='notice'>Gained <B>[DisplayPower(.)]</B> of energy from [A].</span>")
else
to_chat(H, "<span class='danger'>\The [A] has run dry of power, you must find another source!</span>")
else
@@ -1,62 +1,65 @@
/obj/effect/accelerated_particle
name = "Accelerated Particles"
desc = "Small things moving very fast."
icon = 'icons/obj/machines/particle_accelerator.dmi'
icon_state = "particle"
/obj/effect/accelerated_particle
name = "Accelerated Particles"
desc = "Small things moving very fast."
icon = 'icons/obj/machines/particle_accelerator.dmi'
icon_state = "particle"
anchored = TRUE
density = FALSE
var/movement_range = 10
var/energy = 10
var/speed = 1
/obj/effect/accelerated_particle/weak
movement_range = 8
energy = 5
/obj/effect/accelerated_particle/strong
movement_range = 15
energy = 15
/obj/effect/accelerated_particle/powerful
movement_range = 20
energy = 50
/obj/effect/accelerated_particle/New(loc)
..()
addtimer(CALLBACK(src, .proc/move), 1)
var/movement_range = 10
var/energy = 10
var/speed = 1
/obj/effect/accelerated_particle/weak
movement_range = 8
energy = 5
/obj/effect/accelerated_particle/strong
movement_range = 15
energy = 15
/obj/effect/accelerated_particle/powerful
movement_range = 20
energy = 50
/obj/effect/accelerated_particle/New(loc)
..()
addtimer(CALLBACK(src, .proc/move), 1)
/obj/effect/accelerated_particle/Collide(atom/A)
if(A)
if(isliving(A))
toxmob(A)
else if(istype(A, /obj/machinery/the_singularitygen))
var/obj/machinery/the_singularitygen/S = A
S.energy += energy
else if(istype(A, /obj/singularity))
var/obj/singularity/S = A
S.energy += energy
/obj/effect/accelerated_particle/Crossed(atom/A)
if(isliving(A))
toxmob(A)
/obj/effect/accelerated_particle/ex_act(severity, target)
qdel(src)
/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
M.rad_act(energy*6)
/obj/effect/accelerated_particle/proc/move()
if(!step(src,dir))
forceMove(get_step(src,dir))
movement_range--
if(movement_range == 0)
qdel(src)
else
sleep(speed)
move()
if(A)
if(isliving(A))
toxmob(A)
else if(istype(A, /obj/machinery/the_singularitygen))
var/obj/machinery/the_singularitygen/S = A
S.energy += energy
else if(istype(A, /obj/singularity))
var/obj/singularity/S = A
S.energy += energy
else if(istype(A, /obj/structure/blob))
var/obj/structure/blob/B = A
B.take_damage(energy*0.6)
movement_range = 0
/obj/effect/accelerated_particle/Crossed(atom/A)
if(isliving(A))
toxmob(A)
/obj/effect/accelerated_particle/ex_act(severity, target)
qdel(src)
/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
M.rad_act(energy*6)
/obj/effect/accelerated_particle/proc/move()
if(!step(src,dir))
forceMove(get_step(src,dir))
movement_range--
if(movement_range == 0)
qdel(src)
else
sleep(speed)
move()
@@ -12,21 +12,17 @@
randomspread = FALSE
var/obj/item/device/transfer_valve/bomb
var/datum/gas_mixture/air1
var/datum/gas_mixture/air2
/obj/item/gun/blastcannon/New()
if(!pin)
pin = new
. = ..()
return ..()
/obj/item/gun/blastcannon/Destroy()
if(bomb)
qdel(bomb)
bomb = null
air1 = null
air2 = null
. = ..()
return ..()
/obj/item/gun/blastcannon/attack_self(mob/user)
if(bomb)
@@ -35,7 +31,7 @@
user.visible_message("<span class='warning'>[user] detaches the [bomb] from the [src]</span>")
bomb = null
update_icon()
. = ..(user)
return ..()
/obj/item/gun/blastcannon/update_icon()
if(bomb)
@@ -46,7 +42,6 @@
icon_state = initial(icon_state)
name = initial(name)
desc = initial(desc)
. = ..()
/obj/item/gun/blastcannon/attackby(obj/O, mob/user)
if(istype(O, /obj/item/device/transfer_valve))
@@ -59,20 +54,17 @@
return FALSE
user.visible_message("<span class='warning'>[user] attaches the [O] to the [src]!</span>")
bomb = O
O.loc = src
O.forceMove(src)
update_icon()
return TRUE
. = ..()
return ..()
/obj/item/gun/blastcannon/proc/calculate_bomb()
if(!istype(bomb)||!istype(bomb.tank_one)||!istype(bomb.tank_two))
return 0
air1 = bomb.tank_one.air_contents
air2 = bomb.tank_two.air_contents
var/datum/gas_mixture/temp
temp.volume = air1.volume + air2.volume
temp.merge(air1)
temp.merge(air2)
var/datum/gas_mixture/temp = new(60) //directional buff.
temp.merge(bomb.tank_one.air_contents.remove_ratio(1))
temp.merge(bomb.tank_two.air_contents.remove_ratio(2))
for(var/i in 1 to 6)
temp.react()
var/pressure = temp.return_pressure()
@@ -82,7 +74,7 @@
return (pressure/TANK_FRAGMENT_SCALE)
/obj/item/gun/blastcannon/afterattack(atom/target, mob/user, flag, params)
if((!bomb) || (target == user) || (target.loc == user) || (!target) || (target.loc == user.loc) || (target.loc in range(user, 2)) || (target in range(user, 2)))
if((!bomb) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2))
return ..()
var/power = calculate_bomb()
qdel(bomb)
@@ -90,13 +82,17 @@
var/heavy = power * 0.2
var/medium = power * 0.5
var/light = power
user.visible_message("<span class='danger'>[user] opens \the [bomb] on \his [src.name] and fires a blast wave at \the [target]!</span>","<span class='danger'>You open \the [bomb] on your [src.name] and fire a blast wave at \the [target]!</span>")
user.visible_message("<span class='danger'>[user] opens \the [bomb] on \his [name] and fires a blast wave at \the [target]!</span>","<span class='danger'>You open \the [bomb] on your [name] and fire a blast wave at \the [target]!</span>")
playsound(user, "explosion", 100, 1)
var/turf/starting = get_turf(user)
var/turf/targturf = get_turf(target)
var/area/A = get_area(user)
var/log_str = "Blast wave fired at [ADMIN_COORDJMP(starting)] ([A.name]) by [user.name]([user.ckey]) with power [heavy]/[medium]/[light]."
var/log_str = "Blast wave fired from [ADMIN_COORDJMP(starting)] ([A.name]) at [ADMIN_COORDJMP(targturf)] ([target.name]) by [user.name]([user.ckey]) with power [heavy]/[medium]/[light]."
message_admins(log_str)
log_game(log_str)
var/obj/item/projectile/blastwave/BW = new(loc, heavy, medium, light)
BW.preparePixelProjectile(target, get_turf(target), user, params, 0)
BW.fire()
/obj/item/projectile/blastwave
name = "blast wave"
@@ -109,6 +105,12 @@
var/lightr = 0
range = 150
/obj/item/projectile/blastwave/Initialize(mapload, _h, _m, _l)
heavyr = _h
mediumr = _m
lightr = _l
return ..()
/obj/item/projectile/blastwave/Range()
..()
if(heavyr)
+2 -2
View File
@@ -90,8 +90,6 @@
new impact_effect_type(target_loca, target, src)
return 0
var/mob/living/L = target
if(L.buckled && ismob(L.buckled))
L = L.buckled
if(blocked != 100) // not completely blocked
if(damage && L.blood_volume && damage_type == BRUTE)
var/splatter_dir = dir
@@ -178,6 +176,8 @@
var/mob/living/picked_mob = pick(mobs_list)
if(!prehit(picked_mob))
return FALSE
if(ismob(picked_mob.buckled))
picked_mob = picked_mob.buckled
picked_mob.bullet_act(src, def_zone)
qdel(src)
return TRUE
@@ -10,7 +10,7 @@
/obj/item/projectile/bullet/pellet/Range()
..()
damage += -0.75
damage -= 0.75
if(damage < 0)
qdel(src)
@@ -66,7 +66,7 @@
/obj/item/projectile/bullet/c38
name = ".38 bullet"
damage = 15
knockdown = 30
knockdown = 60
stamina = 50
// 10mm (Stechkin)
@@ -608,6 +608,14 @@
build_path = /obj/item/device/electropack
category = list("hacked", "Tools")
/datum/design/shock_collar
name = "Shock Collar"
id = "shock_collar"
build_type = AUTOLATHE
materials = list(MAT_METAL = 5000, MAT_GLASS = 2000)
build_path = /obj/item/device/electropack/shockcollar
category = list("hacked", "Security")
/datum/design/large_welding_tool
name = "Industrial Welding Tool"
id = "large_welding_tool"
@@ -89,6 +89,8 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE)
return "No message set!"
SERVER_TOOLS_WORLD_ANNOUNCE(msg)
return "SUCCESS"
if(SERVICE_CMD_PLAYER_COUNT)
return "[SERVER_TOOLS_CLIENT_COUNT]"
if(SERVICE_CMD_LIST_CUSTOM)
return json_encode(ListServiceCustomCommands(FALSE))
else
@@ -25,8 +25,9 @@
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
playsound(get_turf(user), 'sound/magic/ethereal_enter.ogg', 50, 1, -1)
visible_message("<span class='boldwarning'>[user] melts into the shadows!</span>")
user.AdjustStun(-20, 0)
user.AdjustKnockdown(-20, 0)
user.SetStun(0, FALSE)
user.SetKnockdown(0, FALSE)
user.setStaminaLoss(0, 0)
var/obj/effect/dummy/shadow/S2 = new(get_turf(user.loc))
user.forceMove(S2)
S2.jaunter = user
+3
View File
@@ -44,9 +44,11 @@
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
actions_types = list(/datum/action/item_action/organ_action/use)
sight_flags = SEE_BLACKNESS
var/night_vision = TRUE
/obj/item/organ/eyes/night_vision/ui_action_click()
sight_flags = initial(sight_flags)
switch(lighting_alpha)
if (LIGHTING_PLANE_ALPHA_VISIBLE)
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
@@ -56,6 +58,7 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
else
lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
sight_flags &= ~SEE_BLACKNESS
owner.update_sight()
/obj/item/organ/eyes/night_vision/alien
@@ -10,6 +10,8 @@
var/slot
// DO NOT add slots with matching names to different zones - it will break internal_organs_slot list!
var/vital = 0
//Was this organ implanted/inserted/etc, if true will not be removed during species change.
var/external = FALSE
/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)