Merge branch 'master' of https://github.com/tgstation/-tg-station into why_did_this_take_months

# Conflicts:
#	code/modules/client/preferences_savefile.dm
This commit is contained in:
Incoming
2016-09-22 00:12:55 -04:00
316 changed files with 4012 additions and 4693 deletions
+1
View File
@@ -266,6 +266,7 @@
if(client)
client.screen -= I
I.layer = initial(I.layer)
I.appearance_flags &= ~NO_CLIENT_COLOR
I.forceMove(loc)
I.dropped(src)
return TRUE
@@ -6,7 +6,7 @@
if (notransform)
return
if(..())
if(..()) //not dead
// GROW!
if(amount_grown < max_grown)
amount_grown++
@@ -91,7 +91,7 @@ var/const/MAX_ACTIVE_TIME = 400
return Attach(AM)
return 0
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin)
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0)
if(!..())
return
if(stat == CONSCIOUS)
+2 -1
View File
@@ -672,7 +672,8 @@
if(B)
B.damaged_brain = 0
for(var/datum/disease/D in viruses)
D.cure(0)
if (D.severity != NONTHREAT)
D.cure(0)
if(admin_revive)
regenerate_limbs()
handcuffed = initial(handcuffed)
@@ -191,18 +191,26 @@
for(var/obj/item/I in BP.embedded_objects)
msg += "<B>[t_He] [t_has] \a \icon[I] [I] embedded in [t_his] [BP.name]!</B>\n"
//stores how many left limbs are missing
//stores missing limbs
var/l_limbs_missing = 0
var/r_limbs_missing = 0
for(var/t in missing)
if(t=="head")
msg += "<span class='deadsay'><B>[capitalize(t_his)] [parse_zone(t)] is missing!</B><span class='warning'>\n"
continue
if(t == "l_arm" || t == "l_leg")
l_limbs_missing++
else if(t == "r_arm" || t == "r_leg")
r_limbs_missing++
msg += "<B>[capitalize(t_his)] [parse_zone(t)] is missing!</B>\n"
if(l_limbs_missing >= 2)
if(l_limbs_missing >= 2 && r_limbs_missing == 0)
msg += "[t_He] looks all right now.\n"
else if(l_limbs_missing == 0 && r_limbs_missing >= 2)
msg += "[t_He] really keeps to the left.\n"
else if(l_limbs_missing >= 2 && r_limbs_missing >= 2)
msg += "[t_He] doesn't seem all there.\n"
if(temp)
if(temp < 30)
@@ -15,7 +15,7 @@
return 0
return ..()
/mob/living/carbon/human/has_gravity()
/mob/living/carbon/human/mob_has_gravity()
. = ..()
if(!.)
if(mob_negates_gravity())
@@ -69,6 +69,8 @@
if(slot_glasses)
glasses = I
var/obj/item/clothing/glasses/G = I
if(G.glass_colour_type)
update_glasses_color(G, 1)
if(G.tint)
update_tint()
if(G.vision_correction)
@@ -144,6 +146,8 @@
else if(I == glasses)
glasses = null
var/obj/item/clothing/glasses/G = I
if(G.glass_colour_type)
update_glasses_color(G, 0)
if(G.tint)
update_tint()
if(G.vision_correction)
+7 -1
View File
@@ -29,20 +29,26 @@
if (notransform)
return
if(..())
if(..()) //not dead
for(var/datum/mutation/human/HM in dna.mutations)
HM.on_life(src)
if(stat != DEAD)
//heart attack stuff
handle_heart()
if(stat != DEAD)
//Stuff jammed in your limbs hurts
handle_embedded_objects()
//Update our name based on whether our face is obscured/disfigured
name = get_visible_name()
dna.species.spec_life(src) // for mutantraces
if(stat != DEAD)
return 1
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
if((wear_suit && (wear_suit.flags & STOPSPRESSUREDMAGE)) && (head && (head.flags & STOPSPRESSUREDMAGE)))
@@ -172,6 +172,34 @@
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/shadow
specflags = list(NOBREATH,NOBLOOD,RADIMMUNE,VIRUSIMMUNE)
dangerous_existence = 1
var/datum/action/innate/shadow/darkvision/vision_toggle
/datum/action/innate/shadow/darkvision //Darkvision toggle so shadowpeople can actually see where darkness is
name = "Toggle Darkvision"
check_flags = AB_CHECK_CONSCIOUS
background_icon_state = "bg_default"
button_icon_state = "blind"
/datum/action/innate/shadow/darkvision/Activate()
var/mob/living/carbon/human/H = owner
if(H.see_in_dark < 8)
H.see_in_dark = 8
H.see_invisible = SEE_INVISIBLE_MINIMUM
H << "<span class='notice'>You adjust your vision to pierce the darkness.</span>"
else
H.see_in_dark = 2
H.see_invisible = SEE_INVISIBLE_LIVING
H << "<span class='notice'>You adjust your vision to recognize the shadows.</span>"
/datum/species/shadow/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
vision_toggle = new
vision_toggle.Grant(C)
/datum/species/shadow/on_species_loss(mob/living/carbon/C)
. = ..()
if(vision_toggle)
vision_toggle.Remove(C)
/datum/species/shadow/spec_life(mob/living/carbon/human/H)
var/light_amount = 0
@@ -37,6 +37,7 @@
observe.client.screen -= I
I.loc = src
I.layer = ABOVE_HUD_LAYER
I.appearance_flags |= NO_CLIENT_COLOR
var/not_handled = FALSE
switch(slot)
if(slot_back)
+5 -3
View File
@@ -9,11 +9,10 @@
damageoverlaytemp = 0
update_damage_hud()
if(..())
. = 1
if(..()) //not dead
handle_blood()
if(stat != DEAD)
for(var/X in internal_organs)
var/obj/item/organ/O = X
O.on_life()
@@ -21,6 +20,9 @@
//Updates the number of stored chemicals for powers
handle_changeling()
if(stat != DEAD)
return 1
///////////////
// BREATHING //
///////////////
@@ -11,10 +11,6 @@
/mob/living/carbon/monkey/punpun/New()
Read_Memory()
if(relic_hat)
equip_to_slot_or_del(new relic_hat, slot_head)
if(relic_mask)
equip_to_slot_or_del(new relic_mask, slot_wear_mask)
if(ancestor_name)
name = ancestor_name
if(ancestor_chain > 1)
@@ -27,6 +23,14 @@
gender = pick(MALE, FEMALE)
..()
//These have to be after the parent new to ensure that the monkey
//bodyparts are actually created before we try to equip things to
//those slots
if(relic_hat)
equip_to_slot_or_del(new relic_hat, slot_head)
if(relic_mask)
equip_to_slot_or_del(new relic_mask, slot_wear_mask)
/mob/living/carbon/monkey/punpun/Life()
if(ticker.current_state == GAME_STATE_FINISHED && !memory_saved)
Write_Memory(0)
+4
View File
@@ -24,3 +24,7 @@
var/obj/item/organ/tongue/T = getorganslot("tongue")
if(T)
. |= T.get_spans()
var/obj/item/I = get_active_held_item()
if(I)
. |= I.get_held_item_speechspans(src)
-6
View File
@@ -3,13 +3,9 @@
if(stat != DEAD)
death(1)
if(buckled)
buckled.unbuckle_mob(src,force=1) //to update alien nest overlay, forced because we don't exist anymore
if(!prev_lying)
gib_animation()
spill_organs(no_brain, no_organs, no_bodyparts)
if(!no_bodyparts)
@@ -64,8 +60,6 @@
living_mob_list -= src
if(!gibbed)
dead_mob_list += src
else if(buckled)
buckled.unbuckle_mob(src,force=1)
paralysis = 0
stunned = 0
weakened = 0
+8 -8
View File
@@ -19,21 +19,18 @@
var/datum/gas_mixture/environment = loc.return_air()
if(stat != DEAD)
//Breathing, if applicable
handle_breathing()
if(stat != DEAD)
//Mutations and radiation
handle_mutations_and_radiation()
if(stat != DEAD)
//Chemicals in the body
handle_chemicals_in_body()
if(stat != DEAD)
//Random events (vomiting etc)
handle_random_events()
. = 1
//Handle temperature/pressure differences between body and environment
if(environment)
handle_environment(environment)
@@ -43,16 +40,19 @@
//stuff in the stomach
handle_stomach()
update_gravity(has_gravity())
update_gravity(mob_has_gravity())
if(machine)
machine.check_eye(src)
if(stat != DEAD)
handle_disabilities() // eye, ear, brain damages
if(stat != DEAD)
handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc
if(stat != DEAD)
return 1
/mob/living/proc/handle_breathing()
return
+3
View File
@@ -29,6 +29,9 @@
/mob/living/Destroy()
..()
if(buckled)
buckled.unbuckle_mob(src,force=1)
for(var/mob/living/simple_animal/drone/D in player_list)
for(var/image/I in staticOverlays)
D.staticOverlays.Remove(I)
+2 -1
View File
@@ -92,11 +92,12 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
if(message_mode != MODE_WHISPER) //whisper() calls treat_message(); double process results in "hisspering"
message = treat_message(message)
spans += get_spans()
if(!message)
return
spans += get_spans()
//Log of what we've said, plain message, no spans or junk
say_log += message
+2 -2
View File
@@ -4,12 +4,12 @@
#define POWER_RESTORATION_APC_FOUND 3
/mob/living/silicon/ai/Life()
if (src.stat == DEAD)
if (stat == DEAD)
return
else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist
//Being dead doesn't mean your temperature never changes
update_gravity(has_gravity())
update_gravity(mob_has_gravity())
if(malfhack && malfhack.aidisabled)
deltimer(malfhacking)
-1
View File
@@ -3,5 +3,4 @@
ticker.mode.remove_cultist(mind, 0, 0)
ticker.mode.remove_revolutionary(mind, 0)
ticker.mode.remove_gangster(mind, remove_bosses=1)
ticker.mode.remove_hog_follower(mind,0)
..()
+2 -2
View File
@@ -1,7 +1,7 @@
/mob/living/silicon/pai/Life()
if (src.stat == DEAD)
if(stat == DEAD)
return
if(src.cable)
if(cable)
if(get_dist(src, src.cable) > 1)
var/turf/T = get_turf(src.loc)
T.visible_message("<span class='warning'>[src.cable] rapidly retracts back into its spool.</span>", "<span class='italics'>You hear a click and the sound of wire spooling rapidly.</span>")
@@ -6,4 +6,3 @@
if(mind)
ticker.mode.remove_revolutionary(mind)
ticker.mode.remove_gangster(mind,1,remove_bosses=1)
ticker.mode.remove_hog_follower(mind, 0)
@@ -785,9 +785,8 @@
if(isturf(tile))
tile.clean_blood()
for(var/A in tile)
if(istype(A, /obj/effect))
if(is_cleanable(A))
qdel(A)
if(is_cleanable(A))
qdel(A)
else if(istype(A, /obj/item))
var/obj/item/cleaned_item = A
cleaned_item.clean_blood()
@@ -402,4 +402,4 @@
/datum/robot_energy_storage/medical
max_energy = 2500
recharge_rate = 250
name = "Medical Synthesizer"
name = "Medical Synthesizer"
@@ -11,7 +11,7 @@
/mob/living/silicon/robot/mob_negates_gravity()
return magpulse
/mob/living/silicon/robot/has_gravity()
/mob/living/silicon/robot/mob_has_gravity()
return ..() || mob_negates_gravity()
/mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction)
@@ -55,7 +55,7 @@
if(health < maxHealth)
adjustHealth(-5)
if(src != M)
Beam(M,icon_state="sendbeam",icon='icons/effects/effects.dmi',time=4)
Beam(M,icon_state="sendbeam",time=4)
M.visible_message("<span class='danger'>[M] repairs some of \the <b>[src]'s</b> dents.</span>", \
"<span class='cult'>You repair some of <b>[src]'s</b> dents, leaving <b>[src]</b> at <b>[health]/[maxHealth]</b> health.</span>")
else
@@ -53,4 +53,3 @@
icon = 'icons/effects/blood.dmi'
icon_state = "xfloor1"
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
layer = ABOVE_OPEN_TURF_LAYER
@@ -46,7 +46,7 @@
staticOverlays = list()
hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD)
unique_name = TRUE
faction = list("silicon")
faction = list("neutral","silicon")
dextrous = TRUE
dextrous_hud_type = /datum/hud/dextrous/drone
var/staticChoice = "static"
@@ -245,7 +245,7 @@
/mob/living/simple_animal/drone/mob_negates_gravity()
return 1
/mob/living/simple_animal/drone/has_gravity()
/mob/living/simple_animal/drone/mob_has_gravity()
return ..() || mob_negates_gravity()
/mob/living/simple_animal/drone/experience_pressure_difference(pressure_difference, direction)
@@ -30,7 +30,7 @@
var/datum/beam/C = pick(enemychains)
qdel(C)
enemychains -= C
enemychains += Beam(target,"lightning[rand(1,12)]",'icons/effects/effects.dmi',70, 7,/obj/effect/ebeam/chain)
enemychains += Beam(target, "lightning[rand(1,12)]", time=70, maxdistance=7, beam_type=/obj/effect/ebeam/chain)
/mob/living/simple_animal/hostile/guardian/beam/Destroy()
removechains()
@@ -39,7 +39,7 @@
/mob/living/simple_animal/hostile/guardian/beam/Manifest()
if(..())
if(summoner)
summonerchain = Beam(summoner,"lightning[rand(1,12)]",'icons/effects/effects.dmi',INFINITY, INFINITY,/obj/effect/ebeam/chain)
summonerchain = Beam(summoner, "lightning[rand(1,12)]", time=INFINITY, maxdistance=INFINITY, beam_type=/obj/effect/ebeam/chain)
while(loc != summoner)
if(successfulshocks > 5)
successfulshocks = 0
@@ -57,7 +57,7 @@
if(summonerchain && !qdeleted(summonerchain))
. += chainshock(summonerchain)
else
summonerchain = Beam(summoner,"lightning[rand(1,12)]",'icons/effects/effects.dmi',INFINITY, INFINITY,/obj/effect/ebeam/chain)
summonerchain = Beam(summoner, "lightning[rand(1,12)]", time=INFINITY, maxdistance=INFINITY, beam_type=/obj/effect/ebeam/chain)
if(enemychains.len)
for(var/chain in enemychains)
if(!qdeleted(chain))
@@ -27,6 +27,7 @@
var/ranged_message = "fires" //Fluff text for ranged mobs
var/ranged_cooldown = 0 //What the current cooldown on ranged attacks is, generally world.time + ranged_cooldown_time
var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is
var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash
var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting
var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat.
var/minimum_distance = 1 //Minimum approach distance, so ranged mobs chase targets down, but still keep their distance set in tiles to the target, set higher to make mobs keep distance
@@ -53,6 +54,10 @@
environment_target_typecache = typecacheof(environment_target_typecache)
/mob/living/simple_animal/hostile/Destroy()
targets_from = null
return ..()
/mob/living/simple_animal/hostile/Life()
. = ..()
if(!.) //dead
@@ -225,12 +230,14 @@
else
Goto(target,move_to_delay,minimum_distance)
if(target)
if(isturf(targets_from.loc) && target.Adjacent(targets_from)) //If they're next to us, attack
if(targets_from && isturf(targets_from.loc) && target.Adjacent(targets_from)) //If they're next to us, attack
AttackingTarget()
return 1
return 0
if(environment_smash)
if(target.loc != null && get_dist(targets_from, target.loc) <= vision_range) //We can't see our target, but he's in our vision range still
if(ranged_ignores_vision && ranged_cooldown <= world.time) //we can't see our target... but we can fire at them!
OpenFire(target)
if(environment_smash >= 2) //If we're capable of smashing through walls, forget about vision completely after finding our target
Goto(target,move_to_delay,minimum_distance)
FindHidden()
@@ -9,15 +9,15 @@ Bubblegum's footsteps are heralded by shaking booms, proving its tremendous size
It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage.
It often charges, dealing massive damage to anything unfortunate enough to be standing where it's aiming.
Whenever it isn't chasing something down, it will sink into nearby blood pools (if possible) and springs out of the closest one to its target.
To make this possible, it sprays streams of blood at random.
From these blood pools Bubblegum may summon slaughterlings - weak, low-damage minions designed to impede the target's progress.
It tries to strike at its target through any bloodpools under them; if it fails to do that, it will spray blood and then attempt to warp to a bloodpool near the target.
If it fails to warp to a target, it may summon up to 6 slaughterlings from the blood around it.
If it does not summon all 6 slaughterlings, it will instead charge at its target, dealing massive damage to anything it hits and spraying a stream of blood.
At half health, it will either charge three times or warp, then charge, instead of doing a single charge.
When Bubblegum dies, it leaves behind a chest that can contain three things:
1. A slaughter demon spawner
2. A bottle that, when activated, drives everyone nearby into a frenzy
3. A contract that marks for death the chosen target
1. A bottle that, when activated, drives everyone nearby into a frenzy
2. A contract that marks for death the chosen target
3. A spellblade that can slice off limbs at range
Difficulty: Hard
@@ -45,6 +45,7 @@ Difficulty: Hard
pixel_x = -32
del_on_death = 1
loot = list(/obj/structure/closet/crate/necropolis/bubblegum)
blood_volume = BLOOD_VOLUME_MAXIMUM //BLEED FOR ME
var/charging = 0
medal_type = MEDAL_PREFIX
score_type = BUBBLEGUM_SCORE
@@ -57,6 +58,12 @@ Difficulty: Hard
desc = "You're not quite sure how a signal can be bloody."
invisibility = 100
/mob/living/simple_animal/hostile/megafauna/bubblegum/adjustBruteLoss(amount)
if(amount > 0 && prob(33))
var/obj/effect/decal/cleanable/blood/B = new /obj/effect/decal/cleanable/blood(loc)
B.bloodiness = 20
. = ..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Life()
..()
move_to_delay = Clamp(round((health/maxHealth) * 10), 5, 10)
@@ -67,18 +74,21 @@ Difficulty: Hard
return
ranged_cooldown = world.time + ranged_cooldown_time
blood_warp()
if(prob(25))
var/warped = FALSE
if(!try_bloodattack())
addtimer(src, "blood_spray", 0)
warped = blood_warp()
if(warped && prob(100 - anger_modifier))
return
else if(prob(5+anger_modifier/2))
slaughterlings()
else
if(health > maxHealth/2 && !client)
if(prob(90 - anger_modifier) || slaughterlings())
if(health > maxHealth * 0.5 || client)
addtimer(src, "charge", 0)
else
addtimer(src, "triple_charge", 0)
if(prob(70) || warped)
addtimer(src, "triple_charge", 0)
else
addtimer(src, "warp_charge", 0)
/mob/living/simple_animal/hostile/megafauna/bubblegum/New()
@@ -109,20 +119,22 @@ Difficulty: Hard
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Move()
if(!stat)
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
if(charging)
PoolOrNew(/obj/effect/overlay/temp/decoy/fading, list(loc,src))
DestroySurroundings()
. = ..()
if(!stat && .)
playsound(src, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
if(charging)
DestroySurroundings()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/warp_charge()
blood_warp()
charge()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/triple_charge()
charge()
sleep(10)
charge()
sleep(10)
charge()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge()
@@ -135,11 +147,11 @@ Difficulty: Hard
walk(src, 0)
setDir(get_dir(src, T))
var/obj/effect/overlay/temp/decoy/D = PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
D.color = "#FF0000"
animate(D, alpha = 0, color = initial(D.color), transform = matrix()*2, time = 5)
animate(D, alpha = 0, color = "#FF0000", transform = matrix()*2, time = 5)
sleep(5)
throw_at(T, get_dist(src, T), 1, src, 0)
charging = 0
try_bloodattack()
Goto(target, move_to_delay, minimum_distance)
@@ -167,17 +179,132 @@ Difficulty: Hard
charging = 0
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_mobs_on_blood()
var/list/targets = ListTargets()
. = list()
for(var/mob/living/L in targets)
var/list/bloodpool = get_pools(get_turf(L), 0)
if(bloodpool.len && !faction_check(L))
. += L
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/try_bloodattack()
var/list/targets = get_mobs_on_blood()
if(targets.len)
addtimer(src, "bloodattack", 0, FALSE, targets)
return TRUE
return FALSE
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodattack(list/targets)
var/mob/living/target_one = pick_n_take(targets)
var/turf/target_one_turf = get_turf(target_one)
var/mob/living/target_two
if(targets.len)
target_two = pick_n_take(targets)
var/turf/target_two_turf = get_turf(target_two)
if(target_two.stat != CONSCIOUS || prob(10))
PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightpaw, target_two_turf)
PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightthumb, target_two_turf)
bloodgrab(target_two_turf)
else
PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightsmack, target_two_turf)
bloodsmack(target_two_turf)
var/list/pools = get_pools(get_turf(target_one), 0)
if(pools.len)
target_one_turf = get_turf(target_one)
if(target_one.stat != CONSCIOUS || prob(10))
PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/leftpaw, target_one_turf)
PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/leftthumb, target_one_turf)
bloodgrab(target_one_turf)
else
PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/leftsmack, target_one_turf)
bloodsmack(target_one_turf)
if(!target_two && target_one)
pools = get_pools(get_turf(target_one), 0)
if(pools.len)
target_one_turf = get_turf(target_one)
if(target_one.stat != CONSCIOUS || prob(10))
PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightpaw, target_one_turf)
PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightthumb, target_one_turf)
bloodgrab(target_one_turf)
else
PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightsmack, target_one_turf)
bloodsmack(target_one_turf)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodsmack(turf/T)
sleep(2.5)
for(var/mob/living/L in T)
if(!faction_check(L))
L << "<span class='userdanger'>[src] rends you!</span>"
playsound(T, attack_sound, 100, 1, -1)
var/limb_to_hit = L.get_bodypart(pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg"))
L.apply_damage(25, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, "melee", null, null, armour_penetration))
sleep(3)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodgrab(turf/T)
sleep(6)
for(var/mob/living/L in T)
if(!faction_check(L))
L << "<span class='userdanger'>[src] drags you through the blood!</span>"
playsound(T, 'sound/magic/enter_blood.ogg', 100, 1, -1)
var/turf/targetturf = get_step(src, dir)
L.forceMove(targetturf)
playsound(targetturf, 'sound/magic/exit_blood.ogg', 100, 1, -1)
if(L.stat != CONSCIOUS)
addtimer(src, "devour", 2, FALSE, L)
sleep(1)
/obj/effect/overlay/temp/bubblegum_hands
icon = 'icons/effects/bubblegum.dmi'
duration = 9
/obj/effect/overlay/temp/bubblegum_hands/rightthumb
icon_state = "rightthumbgrab"
/obj/effect/overlay/temp/bubblegum_hands/leftthumb
icon_state = "leftthumbgrab"
/obj/effect/overlay/temp/bubblegum_hands/rightpaw
icon_state = "rightpawgrab"
layer = BELOW_MOB_LAYER
/obj/effect/overlay/temp/bubblegum_hands/leftpaw
icon_state = "leftpawgrab"
layer = BELOW_MOB_LAYER
/obj/effect/overlay/temp/bubblegum_hands/rightsmack
icon_state = "rightsmack"
/obj/effect/overlay/temp/bubblegum_hands/leftsmack
icon_state = "leftsmack"
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_warp()
if(Adjacent(target))
return FALSE
var/list/can_jaunt = get_pools(get_turf(src), 1)
if(!can_jaunt.len)
return FALSE
var/list/pools = get_pools(get_turf(target), 2)
var/list/pools_to_remove = get_pools(get_turf(target), 1)
pools -= pools_to_remove
if(!pools.len)
return FALSE
var/obj/effect/overlay/temp/decoy/DA = PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
DA.color = "#FF0000"
var/oldtransform = DA.transform
DA.transform = matrix()*2
animate(DA, alpha = 255, color = initial(DA.color), transform = oldtransform, time = 5)
sleep(5)
qdel(DA)
var/obj/effect/decal/cleanable/blood/found_bloodpool
var/list/pools = list()
var/can_jaunt = FALSE
for(var/obj/effect/decal/cleanable/blood/nearby in view(src,2))
can_jaunt = TRUE
break
if(!can_jaunt)
return
for(var/obj/effect/decal/cleanable/blood/nearby in view(get_turf(target),2))
pools += nearby
pools = get_pools(get_turf(target), 2)
pools_to_remove = get_pools(get_turf(target), 1)
pools -= pools_to_remove
if(pools.len)
shuffle(pools)
found_bloodpool = pick(pools)
@@ -187,35 +314,56 @@ Difficulty: Hard
forceMove(get_turf(found_bloodpool))
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
visible_message("<span class='danger'>And springs back out!</span>")
return TRUE
return FALSE
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_pools(turf/T, range)
. = list()
for(var/obj/effect/decal/cleanable/blood/nearby in view(T, range))
. += nearby
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_spray()
visible_message("<span class='danger'>[src] sprays a stream of gore!</span>")
var/turf/E = get_edge_target_turf(src, src.dir)
var/range = 10
var/range = 6 + round(anger_modifier * 0.4)
var/turf/previousturf = get_turf(src)
for(var/turf/J in getline(src,E))
if(!range)
var/turf/J = previousturf
var/targetdir = get_dir(src, target)
if(target.loc == loc)
targetdir = dir
face_atom(target)
new /obj/effect/decal/cleanable/blood(J)
for(var/i in 1 to range)
J = get_step(previousturf, targetdir)
PoolOrNew(/obj/effect/overlay/temp/dir_setting/bloodsplatter, list(previousturf, get_dir(previousturf, J)))
playsound(previousturf,'sound/effects/splat.ogg', 100, 1, -1)
if(!J || !previousturf.CanAtmosPass(J))
break
PoolOrNew(/obj/effect/overlay/temp/bloodsplatter, list(previousturf, get_dir(previousturf, J)))
if(!previousturf.CanAtmosPass(J))
break
playsound(J,'sound/effects/splat.ogg', 100, 1, -1)
new /obj/effect/decal/cleanable/blood(J)
range--
var/obj/effect/decal/cleanable/blood/B = new /obj/effect/decal/cleanable/blood(J)
B.bloodiness = 0
previousturf = J
sleep(1)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/slaughterlings()
visible_message("<span class='danger'>[src] summons a shoal of slaughterlings!</span>")
for(var/obj/effect/decal/cleanable/blood/H in range(src, 10))
if(prob(25))
new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter(H.loc)
var/max_amount = 6
for(var/H in get_pools(get_turf(src), 1))
if(!max_amount)
break
max_amount--
var/obj/effect/decal/cleanable/blood/B = H
new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter(B.loc)
return max_amount
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter
name = "slaughterling"
desc = "Though not yet strong enough to create a true physical form, it's nonetheless determined to murder you."
faction = list("mining")
density = 0
faction = list("mining", "boss")
weather_immunities = list("lava","ash")
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter/CanPass(atom/movable/mover, turf/target, height = 0)
if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum))
return 1
return 0
#undef MEDAL_PREFIX
@@ -220,7 +220,8 @@ Difficulty: Very Hard
/mob/living/simple_animal/hostile/megafauna/colossus/proc/blast()
playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 200, 1, 2)
for(var/turf/turf in range(1, target))
var/turf/T = get_turf(target)
for(var/turf/turf in range(1, T))
shoot_projectile(turf)
/mob/living/simple_animal/hostile/megafauna/colossus/proc/dir_shots(list/dirs)
@@ -381,7 +382,7 @@ Difficulty: Very Hard
var/activation_sound = 'sound/effects/break_stone.ogg'
/obj/machinery/anomalous_crystal/New()
activation_method = pick("touch","laser","bullet","energy","magic","mob_bump","heat","weapon","speech")
activation_method = pick("touch","laser","bullet","energy","bomb","mob_bump","heat","weapon","speech")
..()
/obj/machinery/anomalous_crystal/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans)
@@ -423,8 +424,11 @@ Difficulty: Very Hard
if(ismob(AM))
ActivationReaction(AM,"mob_bump")
/obj/machinery/anomalous_crystal/ex_act()
ActivationReaction(null,"bomb")
/obj/machinery/anomalous_crystal/random/New()//Just a random crysal spawner for loot
var/random_crystal = pick(typesof(/obj/machinery/anomalous_crystal) - /obj/machinery/anomalous_crystal/random)
var/random_crystal = pick(typesof(/obj/machinery/anomalous_crystal) - /obj/machinery/anomalous_crystal/random - /obj/machinery/anomalous_crystal)
new random_crystal(loc)
qdel(src)
@@ -472,13 +476,14 @@ Difficulty: Very Hard
NewTerrainChairs = /obj/structure/chair/wood/normal
NewTerrainTables = /obj/structure/table/glass
NewFlora = list(/obj/structure/flora/grass/green, /obj/structure/flora/grass/brown, /obj/structure/flora/grass/both)
if("jungle") //Beneficial due to actually having breathable air. Plus, monkeys.
if("jungle") //Beneficial due to actually having breathable air. Plus, monkeys and bows and arrows.
NewTerrainFloors = /turf/open/floor/grass
NewTerrainWalls = /turf/closed/wall/mineral/sandstone
NewTerrainChairs = /obj/structure/chair/wood
NewTerrainTables = /obj/structure/table/wood
NewFlora = list(/obj/structure/flora/ausbushes/sparsegrass, /obj/structure/flora/ausbushes/fernybush, /obj/structure/flora/ausbushes/leafybush,
/obj/structure/flora/ausbushes/grassybush, /obj/structure/flora/ausbushes/sunnybush, /obj/structure/flora/tree/palm, /mob/living/carbon/monkey)
/obj/structure/flora/ausbushes/grassybush, /obj/structure/flora/ausbushes/sunnybush, /obj/structure/flora/tree/palm, /mob/living/carbon/monkey,
/obj/item/weapon/gun/projectile/bow, /obj/item/weapon/storage/backpack/quiver/full)
florachance = 20
if("ayy lmao") //Beneficial, turns stuff into alien alloy which is useful to cargo and research. Also repairs atmos.
NewTerrainFloors = /turf/open/floor/plating/abductor
@@ -523,8 +528,8 @@ Difficulty: Very Hard
/obj/machinery/anomalous_crystal/emitter/New()
..()
generated_projectile = pick(/obj/item/projectile/beam/emitter,/obj/item/projectile/magic/fireball/infernal,/obj/item/projectile/magic/spellblade,
/obj/item/projectile/energy/net, /obj/item/projectile/bullet/meteorshot, /obj/item/projectile/beam/xray)
generated_projectile = pick(/obj/item/projectile/magic/fireball/infernal,/obj/item/projectile/magic/spellblade,
/obj/item/projectile/bullet/meteorshot, /obj/item/projectile/beam/xray, /obj/item/projectile/colossus)
/obj/machinery/anomalous_crystal/emitter/ActivationReaction(mob/user, method)
if(..())
@@ -545,17 +550,23 @@ Difficulty: Very Hard
P.xo = 0
P.fire()
/obj/machinery/anomalous_crystal/dark_reprise //Revives anyone nearby, but turns them into shadowpeople. Cannot revive shadowpeople, so this is a one time thing.
/obj/machinery/anomalous_crystal/dark_reprise //Revives anyone nearby, but turns them into shadowpeople and renders them uncloneable, so the crystal is your only hope of getting up again if you go down.
activation_method = "touch"
activation_sound = 'sound/hallucinations/growl1.ogg'
/obj/machinery/anomalous_crystal/dark_reprise/ActivationReaction(mob/user, method)
if(..())
for(var/i in range(1, src))
if(isturf(i))
PoolOrNew(/obj/effect/overlay/temp/cult/sparks, i)
continue
if(ishuman(i))
var/mob/living/carbon/human/H = i
if(H.stat == DEAD && !isshadowperson(H))
if(H.stat == DEAD)
H.set_species(/datum/species/shadow, 1)
H.revive(1,0)
H.disabilities |= NOCLONE //Free revives, but significantly limits your options for reviving except via the crystal
H.grab_ghost(force = TRUE)
/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans
activation_method = "touch"
@@ -564,17 +575,23 @@ Difficulty: Very Hard
/obj/machinery/anomalous_crystal/helpers/ActivationReaction(mob/user, method)
if(..() && !ready_to_deploy)
ready_to_deploy = 1
notify_ghosts("An anomalous crystal has been activated in [get_area(src)]!", enter_link = "<a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK)
notify_ghosts("An anomalous crystal has been activated in [get_area(src)]! This crystal can always be used by ghosts hereafter.", enter_link = "<a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK)
/obj/machinery/anomalous_crystal/helpers/attack_ghost(mob/dead/observer/user)
..()
if(ready_to_deploy)
var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No")
if(!be_helper == "No")
if(be_helper == "No")
return
var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc))
W.key = user.key
/obj/machinery/anomalous_crystal/helpers/Topic(href, href_list)
if(href_list["ghostjoin"])
var/mob/dead/observer/ghost = usr
if(istype(ghost))
attack_ghost(ghost)
/mob/living/simple_animal/hostile/lightgeist
name = "lightgeist"
desc = "This small floating creature is a completely unknown form of life... being near it fills you with a sense of tranquility."
@@ -603,19 +620,24 @@ Difficulty: Very Hard
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
luminosity = 4
faction = list("neutral")
languages_spoken = 0
languages_spoken = SLIME
languages_understood = ALL
del_on_death = 1
unsuitable_atmos_damage = 0
flying = 1
minbodytemp = 0
maxbodytemp = 1500
environment_smash = 0
AIStatus = AI_OFF
stop_automated_movement = 1
var/heal_power = 5
/mob/living/simple_animal/hostile/lightgeist/New()
..()
verbs -= /mob/living/verb/pulled
verbs -= /mob/verb/me_verb
var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED]
medsensor.add_hud_to(src)
/mob/living/simple_animal/hostile/lightgeist/AttackingTarget()
..()
@@ -625,29 +647,35 @@ Difficulty: Very Hard
L.heal_overall_damage(heal_power, heal_power)
PoolOrNew(/obj/effect/overlay/temp/heal, list(get_turf(target), "#80F5FF"))
/mob/living/simple_animal/hostile/lightgeist/Life()
if(!ckey)
/mob/living/simple_animal/hostile/lightgeist/ghostize()
if(..())
death()
..()
/obj/machinery/anomalous_crystal/refresher //Deletes and recreates a copy of the item, "refreshing" it. Only works once per item.
/obj/machinery/anomalous_crystal/refresher //Deletes and recreates a copy of the item, "refreshing" it.
activation_method = "touch"
cooldown_add = 50
activation_sound = 'sound/magic/TIMEPARADOX2.ogg'
var/list/banned_items_typecache = list(/obj/item/weapon/storage, /obj/item/weapon/implant, /obj/item/weapon/implanter, /obj/item/weapon/disk/nuclear, /obj/item/projectile, /obj/item/weapon/spellbook)
/obj/machinery/anomalous_crystal/refresher/New()
..()
banned_items_typecache = typecacheof(banned_items_typecache)
/obj/machinery/anomalous_crystal/refresher/ActivationReaction(mob/user, method)
if(..())
var/list/L
var/list/L = list()
var/turf/T = get_step(src, dir)
PoolOrNew(/obj/effect/overlay/temp/emp/pulse,T)
for(var/i in T)
if(istype(i, /obj/item) && !istype(i, /obj/item/weapon/storage) && !(i in affected_targets) && !istype(i, /obj/item/weapon/implant) && !istype(i, /obj/item/weapon/implanter) && !istype(i, /obj/item/weapon/disk/nuclear))
if(istype(i, /obj/item) && !is_type_in_typecache(i, banned_items_typecache))
var/obj/item/W = i
if(!W.admin_spawned)
L += W
var/obj/item/CHOSEN = pick(L)
if(CHOSEN)
var/A = new CHOSEN.type(T)
affected_targets += A
if(L.len)
var/obj/item/CHOSEN = pick(L)
new CHOSEN.type(T)
qdel(CHOSEN)
/obj/machinery/anomalous_crystal/possessor //Allows you to bodyjack small animals, then exit them at your leisure, but you can only do this once per activation. Because they blow up. Also, if the bodyjacked animal dies, SO DO YOU.
@@ -665,7 +693,7 @@ Difficulty: Very Hard
mobcheck = 1
break
if(!mobcheck)
new /mob/living/simple_animal/cockroach(loc) //Just in case there aren't any animals on the station, this will leave you with a terrible option to possess if you feel like it
new /mob/living/simple_animal/cockroach(get_step(src,dir)) //Just in case there aren't any animals on the station, this will leave you with a terrible option to possess if you feel like it
/obj/structure/closet/stasis
name = "quantum entanglement stasis warp field"
@@ -673,17 +701,15 @@ Difficulty: Very Hard
icon_state = null //This shouldn't even be visible, so if it DOES show up, at least nobody will notice
density = 1
anchored = 1
health = 0
health = 999
var/mob/living/simple_animal/holder_animal
/obj/structure/closet/stasis/process()
if(!isanimal(loc))
dump_contents(1)
return
if(holder_animal)
if(holder_animal.stat == DEAD)
dump_contents(1)
if(holder_animal.stat == DEAD && !qdeleted(holder_animal))
dump_contents()
holder_animal.gib()
return
/obj/structure/closet/stasis/New()
..()
@@ -702,14 +728,15 @@ Difficulty: Very Hard
holder_animal.mind.AddSpell(P)
holder_animal.verbs -= /mob/living/verb/pulled
/obj/structure/closet/stasis/dump_contents(var/kill = 0)
/obj/structure/closet/stasis/dump_contents(var/kill = 1)
STOP_PROCESSING(SSobj, src)
for(var/mob/living/L in src)
L.disabilities &= ~MUTE
L.status_flags &= ~GODMODE
L.notransform = 0
holder_animal.mind.transfer_to(L)
L.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession)
if(holder_animal && !qdeleted(holder_animal))
holder_animal.mind.transfer_to(L)
L.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession)
if(kill || !isanimal(loc))
L.death(0)
..()
@@ -717,6 +744,9 @@ Difficulty: Very Hard
/obj/structure/closet/stasis/emp_act()
return
/obj/structure/closet/stasis/ex_act()
return
/obj/effect/proc_holder/spell/targeted/exit_possession
name = "Exit Possession"
desc = "Exits the body you are possessing"
@@ -737,7 +767,7 @@ Difficulty: Very Hard
for(var/i in user)
if(istype(i, /obj/structure/closet/stasis))
var/obj/structure/closet/stasis/S = i
S.dump_contents()
S.dump_contents(0)
qdel(S)
break
user.gib()
@@ -166,6 +166,7 @@ Difficulty: Medium
addtimer(src, "fire_wall", 0, FALSE, d)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_wall(dir)
var/list/hit_things = list(src)
var/turf/E = get_edge_target_turf(src, dir)
var/range = 10
var/turf/previousturf = get_turf(src)
@@ -175,10 +176,10 @@ Difficulty: Medium
range--
PoolOrNew(/obj/effect/hotspot,J)
J.hotspot_expose(700,50,1)
for(var/mob/living/L in J)
if(L != src)
L.adjustFireLoss(20)
L << "<span class='userdanger'>You're hit by the drake's fire breath!</span>"
for(var/mob/living/L in J.contents - hit_things)
L.adjustFireLoss(20)
L << "<span class='userdanger'>You're hit by the drake's fire breath!</span>"
hit_things += L
previousturf = J
sleep(1)
@@ -257,6 +258,7 @@ Difficulty: Medium
name = "lesser ash drake"
maxHealth = 300
health = 300
faction = list("neutral")
melee_damage_upper = 30
melee_damage_lower = 30
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
@@ -87,7 +87,7 @@ Difficulty: Hard
did_reset = TRUE
//visible_message("<span class='hierophant'>\"Vixyvrmrk xs fewi...\"</span>")
blink(spawned_rune)
adjustHealth(max((health - maxHealth) * 0.5, 25)) //heal for 50% of our missing health
adjustHealth(min((health - maxHealth) * 0.5, -50)) //heal for 50% of our missing health
wander = FALSE
/*if(health > maxHealth * 0.9)
visible_message("<span class='hierophant'>\"Vitemvw gsqtpixi. Stivexmrk ex qebmqyq ijjmgmirgc.\"</span>")
@@ -279,6 +279,8 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/diagonal_blasts(mob/victim) //fire diagonal cross blasts with a delay
var/turf/T = get_turf(victim)
if(!T)
return
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/diagonal, list(T, src))
playsound(T,'sound/magic/blink.ogg', 200, 1)
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
@@ -289,6 +291,8 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/cardinal_blasts(mob/victim) //fire cardinal cross blasts with a delay
var/turf/T = get_turf(victim)
if(!T)
return
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/cardinal, list(T, src))
playsound(T,'sound/magic/blink.ogg', 200, 1)
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
@@ -299,6 +303,8 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/alldir_blasts(mob/victim) //fire alldir cross blasts with a delay
var/turf/T = get_turf(victim)
if(!T)
return
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
playsound(T,'sound/magic/blink.ogg', 200, 1)
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
@@ -396,6 +402,7 @@ Difficulty: Hard
/obj/effect/overlay/temp/hierophant/chaser //a hierophant's chaser. follows target around, moving and producing a blast every speed deciseconds.
duration = 98
var/mob/living/target //what it's following
var/turf/targetturf //what turf the target is actually on
var/moving_dir //what dir it's moving in
var/previous_moving_dir //what dir it was moving in before that
var/more_previouser_moving_dir //what dir it was moving in before THAT
@@ -415,7 +422,7 @@ Difficulty: Hard
addtimer(src, "seek_target", 1)
/obj/effect/overlay/temp/hierophant/chaser/proc/get_target_dir()
. = get_cardinal_dir(src, target)
. = get_cardinal_dir(src, targetturf)
if((. != previous_moving_dir && . == more_previouser_moving_dir) || . == 0) //we're alternating, recalculate
var/list/cardinal_copy = cardinal.Copy()
cardinal_copy -= more_previouser_moving_dir
@@ -424,12 +431,13 @@ Difficulty: Hard
/obj/effect/overlay/temp/hierophant/chaser/proc/seek_target()
if(!currently_seeking)
currently_seeking = TRUE
while(target && src && !qdeleted(src) && currently_seeking && x && y && target.x && target.y) //can this target actually be sook out
targetturf = get_turf(target)
while(target && src && !qdeleted(src) && currently_seeking && x && y && targetturf) //can this target actually be sook out
if(!moving) //we're out of tiles to move, find more and where the target is!
more_previouser_moving_dir = previous_moving_dir
previous_moving_dir = moving_dir
moving_dir = get_target_dir()
var/standard_target_dir = get_cardinal_dir(src, target)
var/standard_target_dir = get_cardinal_dir(src, targetturf)
if((standard_target_dir != previous_moving_dir && standard_target_dir == more_previouser_moving_dir) || standard_target_dir == 0)
moving = 1 //we would be repeating, only move a tile before checking
else
@@ -446,6 +454,7 @@ Difficulty: Hard
make_blast() //make a blast, too
moving--
sleep(speed)
targetturf = get_turf(target)
/obj/effect/overlay/temp/hierophant/chaser/proc/make_blast()
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(loc, caster, friendly_fire_check))
@@ -15,6 +15,7 @@
weather_immunities = list("lava","ash")
flying = 1
robust_searching = 1
ranged_ignores_vision = TRUE
stat_attack = 2
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)
damage_coeff = list(BRUTE = 1, BURN = 0.5, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
@@ -833,7 +833,7 @@
desc = "[src] has become inert, it crackles no more and is useless for \
healing injuries."
/obj/item/organ/hivelord_core/legion/preserved()
/obj/item/organ/hivelord_core/legion/preserved(implanted = 0)
..()
desc = "[src] has been stabilized. It no longer crackles with power, but it's healing properties are preserved indefinitely."
@@ -70,7 +70,7 @@
loot = list(/obj/effect/decal/remains/human,
/obj/item/clothing/suit/armor/riot/knight/templar,
/obj/item/clothing/head/helmet/knight/templar,
/obj/item/weapon/claymore/hog{name = "holy sword"})
/obj/item/weapon/claymore/weak{name = "holy sword"})
/mob/living/simple_animal/hostile/skeleton/ice
name = "ice skeleton"
@@ -21,7 +21,7 @@
anchors += locate(x+2,y-2,z)
for(var/turf/T in anchors)
var/datum/beam/B = Beam(T,"vine",'icons/effects/spacevines.dmi',INFINITY, 5,/obj/effect/ebeam/vine)
var/datum/beam/B = Beam(T, "vine", time=INFINITY, maxdistance=5, beam_type=/obj/effect/ebeam/vine)
B.sleep_time = 10 //these shouldn't move, so let's slow down updates to 1 second (any slower and the deletion of the vines would be too slow)
addtimer(src, "bear_fruit", growth_time)
@@ -98,15 +98,15 @@
if(A.density && A != L)
continue grasping
if(prob(grasp_chance))
L << "<span class='userdanger'>\the [src] has you entangled!</span>"
grasping[L] = Beam(L,"vine",'icons/effects/spacevines.dmi',INFINITY, 5,/obj/effect/ebeam/vine)
L << "<span class='userdanger'>\The [src] has you entangled!</span>"
grasping[L] = Beam(L, "vine", time=INFINITY, maxdistance=5, beam_type=/obj/effect/ebeam/vine)
break //only take 1 new victim per cycle
/mob/living/simple_animal/hostile/venus_human_trap/OpenFire(atom/the_target)
var/dist = get_dist(src,the_target)
Beam(the_target,"vine",'icons/effects/spacevines.dmi',dist*2, dist+2,/obj/effect/ebeam/vine)
Beam(the_target, "vine", time=dist*2, maxdistance=dist+2, beam_type=/obj/effect/ebeam/vine)
the_target.attack_animal(src)
@@ -43,7 +43,7 @@
if(istype(M, /mob/living/simple_animal/hostile/construct/builder))
if(health < maxHealth)
adjustHealth(-25)
Beam(M,icon_state="sendbeam",icon='icons/effects/effects.dmi',time=4)
Beam(M,icon_state="sendbeam",time=4)
M.visible_message("<span class='danger'>[M] heals \the <b>[src]</b>.</span>", \
"<span class='cult'>You heal <b>[src]</b>, leaving <b>[src]</b> at <b>[health]/[maxHealth]</b> health.</span>")
else
@@ -104,10 +104,14 @@
/mob/living/simple_animal/Life()
if(..()) //alive
if(!ckey)
handle_automated_movement()
handle_automated_action()
handle_automated_speech()
return 1
if(stat != DEAD)
handle_automated_movement()
if(stat != DEAD)
handle_automated_action()
if(stat != DEAD)
handle_automated_speech()
if(stat != DEAD)
return 1
/mob/living/simple_animal/updatehealth()
..()
@@ -301,7 +305,11 @@
if(del_on_death)
ghostize()
stat = DEAD
//Prevent infinite loops if the mob Destroy() is overriden in such
//a manner as to cause a call to death() again
del_on_death = FALSE
qdel(src)
return
else
health = 0
icon_state = icon_dead
+2 -2
View File
@@ -499,8 +499,8 @@ var/next_mob_id = 0
return
var/mob/mob_eye = creatures[eye_name]
if(client && mob_eye)
//Istype so we filter out points of interest that are not mobs
if(client && mob_eye && istype(mob_eye))
client.eye = mob_eye
if(isobserver(src))
src.client.screen = list()
+12
View File
@@ -465,3 +465,15 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
M << "There were no ghosts willing to take control."
message_admins("No ghosts were willing to take control of [key_name_admin(M)])")
return FALSE
//toggles the talk wheel
/mob/verb/toggle_talk_wheel()
set name = "talk-wheel"
set hidden = 1
if(isliving(src))
var/mob/living/L = src
if(L.hud_used)
for(var/obj/screen/wheel/talk/TW in L.hud_used.wheels)
TW.Click()
+5 -4
View File
@@ -236,14 +236,12 @@
L.loc = locate(locx,locy,mobloc.z)
var/limit = 2//For only two trailing shadows.
for(var/turf/T in getline(mobloc, L.loc))
spawn(0)
anim(T,L,'icons/mob/mob.dmi',,"shadow",,L.dir)
PoolOrNew(/obj/effect/overlay/temp/dir_setting/ninja/shadow, list(T, L.dir))
limit--
if(limit<=0)
break
else
spawn(0)
anim(mobloc,mob,'icons/mob/mob.dmi',,"shadow",,L.dir)
PoolOrNew(/obj/effect/overlay/temp/dir_setting/ninja/shadow, list(mobloc, L.dir))
L.loc = get_step(L, direct)
L.setDir(direct)
if(3) //Incorporeal move, but blocked by holy-watered tiles and salt piles.
@@ -303,6 +301,9 @@
break
. = dense_object_backup
/mob/proc/mob_has_gravity()
return has_gravity()
/mob/proc/mob_negates_gravity()
return 0
@@ -332,6 +332,9 @@
data_core.manifest_inject(humanc)
AnnounceArrival(humanc, rank)
AddEmploymentContract(humanc)
if(highlander)
humanc << "<span class='userdanger'><i>THERE CAN BE ONLY ONE!!!</i></span>"
humanc.make_scottish()
joined_player_list += character.ckey
+2 -29
View File
@@ -41,14 +41,9 @@
cut_overlays()
invisibility = INVISIBILITY_MAXIMUM
var/atom/movable/overlay/animation = new( loc )
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
flick("h2monkey", animation)
PoolOrNew(/obj/effect/overlay/temp/monkeyify, get_turf(src))
sleep(22)
var/mob/living/carbon/monkey/O = new /mob/living/carbon/monkey( loc )
qdel(animation)
// hash the original name?
if(tr_flags & TR_HASHNAME)
@@ -188,16 +183,11 @@
icon = null
cut_overlays()
invisibility = INVISIBILITY_MAXIMUM
var/atom/movable/overlay/animation = new( loc )
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
flick("monkey2h", animation)
PoolOrNew(/obj/effect/overlay/temp/monkeyify/humanify, get_turf(src))
sleep(22)
var/mob/living/carbon/human/O = new( loc )
for(var/obj/item/C in O.loc)
O.equip_to_appropriate_slot(C)
qdel(animation)
dna.transfer_identity(O)
O.updateappearance(mutcolor_update=1)
@@ -496,23 +486,6 @@
qdel(src)
/mob/proc/become_god(var/side_colour)
var/mob/camera/god/G = new /mob/camera/god(loc)
G.side = side_colour
if(mind)
mind.transfer_to(G)
else
G.key = key
G.job = "Deity"
G.rename_self("deity")
G.update_icons()
. = G
qdel(src)
/mob/living/carbon/human/proc/corgize()
if (notransform)
return