Fixes merge conflicts, adds new sprites, hopefully fixes weird helmet sprite bug.

This commit is contained in:
as334
2015-11-12 21:54:08 -05:00
458 changed files with 17271 additions and 18159 deletions
+46 -4
View File
@@ -22,6 +22,8 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi
var/image/ghostimage = null //this mobs ghost image, for deleting and stuff
var/ghostvision = 1 //is the ghost able to see things humans can't?
var/seedarkness = 1
var/ghost_hud_enabled = 1 //did this ghost disable the on-screen HUD?
var/data_hud_seen = 0 //this should one of the defines in __DEFINES/hud.dm
/mob/dead/observer/New(mob/body)
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
@@ -106,8 +108,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/Move(NewLoc, direct)
if (orbiting)
stop_orbit()
if(NewLoc)
loc = NewLoc
for(var/obj/effect/step_trigger/S in NewLoc)
@@ -163,9 +163,17 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
mind.current.key = key
return 1
/mob/dead/observer/proc/notify_cloning(var/message, var/sound)
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source)
if(message)
src << "<span class='ghostalert'>[message]</span>"
if(source)
var/obj/screen/alert/A = throw_alert("\ref[source]_notify_cloning", /obj/screen/alert/notify_cloning)
if(A)
A.desc = message
var/old_layer = source.layer
source.layer = FLOAT_LAYER
A.overlays += source
source.layer = old_layer
src << "<span class='ghostalert'><a href=?src=\ref[src];reenter=1>(Click to re-enter)</a></span>"
if(sound)
src << sound(sound)
@@ -348,7 +356,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
usr.visible_message("<span class='deadsay'><b>[src]</b> points to [A].</span>")
return 1
/mob/dead/observer/verb/view_manfiest()
/mob/dead/observer/verb/view_manifest()
set name = "View Crew Manifest"
set category = "Ghost"
@@ -376,3 +384,37 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
ManualFollow(target)
if(href_list["reenter"])
reenter_corpse()
//We don't want to update the current var
//But we will still carry a mind.
/mob/dead/observer/mind_initialize()
return
/mob/dead/observer/verb/toggle_ghosthud()
set name = "Toggle Ghost HUD"
set desc = "Toggles your ghost's on-screen HUD"
set category = "Ghost"
ghost_hud_enabled = !ghost_hud_enabled
hud_used.ghost_hud()
/mob/dead/observer/proc/show_me_the_hud(hud_index)
var/datum/atom_hud/H = huds[hud_index]
H.add_hud_to(src)
data_hud_seen = hud_index
/mob/dead/observer/verb/toggle_ghost_med_sec_hud()
set name = "Toggle Sec/Med HUD"
set desc = "Toggles whether you see medical/security HUDs"
set category = "Ghost"
if(data_hud_seen) //remove old huds
var/datum/atom_hud/H = huds[data_hud_seen]
H.remove_hud_from(src)
switch(data_hud_seen) //give new huds
if(0)
show_me_the_hud(DATA_HUD_SECURITY_BASIC)
if(DATA_HUD_SECURITY_BASIC)
show_me_the_hud(DATA_HUD_MEDICAL_ADVANCED)
if(DATA_HUD_MEDICAL_ADVANCED)
data_hud_seen = 0
+1 -1
View File
@@ -88,7 +88,7 @@
//this is here because this has no client/prefs/brain whatever.
age = rand(AGE_MIN,AGE_MAX)
//job handling
var/list/jobs = SSjob.occupations
var/list/jobs = SSjob.occupations.Copy()
for(var/datum/job/J in jobs)
if(J.title == "Cyborg" || J.title == "AI" || J.title == "Chaplain" || J.title == "Mime")
jobs -= J
+8 -4
View File
@@ -52,8 +52,12 @@ obj/effect/dummy/slaughter/relaymove(mob/user, direction)
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1)
var/obj/effect/dummy/slaughter/holder = PoolOrNew(/obj/effect/dummy/slaughter,mobloc)
src.ExtinguishMob()
if(src.buckled)
src.buckled.unbuckle_mob()
if(buckled)
buckled.unbuckle_mob(force=1)
if(buckled_mob)
unbuckle_mob(force=1)
if(pulledby)
pulledby.stop_pulling()
if(src.pulling && src.bloodcrawl == BLOODCRAWL_EAT)
if(istype(src.pulling, /mob/living))
var/mob/living/victim = src.pulling
@@ -95,7 +99,7 @@ obj/effect/dummy/slaughter/relaymove(mob/user, direction)
name = "blood crawl"
desc = "You are unable to hold anything while in this form."
icon = 'icons/effects/blood.dmi'
flags = NODROP
flags = NODROP|ABSTRACT
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
if(src.notransform)
@@ -113,7 +117,7 @@ obj/effect/dummy/slaughter/relaymove(mob/user, direction)
if(iscarbon(src))
var/mob/living/carbon/C = src
for(var/obj/item/weapon/bloodcrawl/BC in C)
C.flags = null
BC.flags = null
C.unEquip(BC)
qdel(BC)
var/oldcolor = src.color
@@ -128,7 +128,6 @@
if(statpanel("Status"))
stat(null, "Intent: [a_intent]")
stat(null, "Move Mode: [m_intent]")
/mob/living/carbon/alien/Stun(amount)
if(status_flags & CANSTUN)
@@ -139,8 +138,10 @@
return
/mob/living/carbon/alien/getTrail()
return "xltrails"
if(getBruteLoss() < 200)
return pick (list("xltrails_1", "xltrails2"))
else
return pick (list("xttrails_1", "xttrails2"))
/*----------------------------------------
Proc: AddInfectionImages()
Des: Gives the client of the alien an image on each infected mob.
@@ -7,7 +7,7 @@ As such, they can either help or harm other aliens. Help works like the human he
In all, this is a lot like the monkey code. /N
*/
/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M)
if (!ticker)
if(!ticker || !ticker.mode)
M << "You cannot attack people before the game has started."
return
@@ -285,6 +285,24 @@ Doesn't work on other aliens/AI.*/
return 1
/obj/effect/proc_holder/alien/sneak
name = "Sneak"
desc = "Blend into the shadows to stalk your prey."
var/active = 0
action_icon_state = "alien_sneak"
/obj/effect/proc_holder/alien/sneak/fire(mob/living/carbon/alien/humanoid/user)
if(!active)
user.alpha = 75 //Still easy to see in lit areas with bright tiles, almost invisible on resin.
user.sneaking = 1
active = 1
user << "<span class='noticealien'>You blend into the shadows...</span>"
else
user.alpha = initial(user.alpha)
user.sneaking = 0
active = 0
user << "<span class='noticealien'>You reveal yourself!</span>"
/mob/living/carbon/proc/getPlasma()
@@ -10,6 +10,7 @@
internal_organs += new /obj/item/organ/internal/alien/plasmavessel
internal_organs += new /obj/item/organ/internal/alien/acid
internal_organs += new /obj/item/organ/internal/alien/neurotoxin
AddAbility(new /obj/effect/proc_holder/alien/sneak)
..()
/mob/living/carbon/alien/humanoid/sentinel/handle_hud_icons_health()
@@ -12,6 +12,7 @@
var/pounce_cooldown_time = 30
var/custom_pixel_x_offset = 0 //for admin fuckery.
var/custom_pixel_y_offset = 0
var/sneaking = 0 //For sneaky-sneaky mode and appropriate slowdown
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/humanoid/New()
@@ -21,7 +22,7 @@
/mob/living/carbon/alien/humanoid/movement_delay()
. = ..()
. += move_delay_add + config.alien_delay //move_delay_add is used to slow aliens with stuns
. += move_delay_add + config.alien_delay + sneaking //move_delay_add is used to slow aliens with stuns
/mob/living/carbon/alien/humanoid/emp_act(severity)
if(r_store) r_store.emp_act(severity)
@@ -8,6 +8,7 @@
mob_size = MOB_SIZE_LARGE
layer = 6
pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper.
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 20, /obj/item/stack/sheet/animalhide/xeno = 3)
var/alt_inhands_file = 'icons/mob/alienqueen.dmi'
@@ -19,8 +19,6 @@
else if(lying || resting || sleeping)
icon_state = "alien[caste]_sleep"
else if(m_intent == "run")
icon_state = "alien[caste]_running"
else if(mob_size == MOB_SIZE_LARGE)
icon_state = "alien[caste]"
else
@@ -63,4 +63,7 @@
/mob/living/carbon/alien/CheckStamina()
setStaminaLoss(max((staminaloss - 2), 0))
return
/mob/living/carbon/alien/handle_changeling()
return
@@ -30,7 +30,7 @@
/obj/item/organ/internal/alien/plasmavessel
name = "plasma vessel"
icon_state = "plasma"
origin_tech = "biotech=5;plasma=2"
origin_tech = "biotech=5;plasmatech=2"
w_class = 3
zone = "chest"
slot = "plasmavessel"
@@ -55,7 +55,7 @@
plasma_rate = 15
/obj/item/organ/internal/alien/plasmavessel/large/queen
origin_tech = "biotech=6;plasma=3"
origin_tech = "biotech=6;plasmatech=3"
plasma_rate = 20
/obj/item/organ/internal/alien/plasmavessel/small
@@ -67,7 +67,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds
/obj/item/organ/internal/body_egg/alien_embryo/proc/AttemptGrow(gib_on_success = 1)
if(!owner) return
var/list/candidates = get_candidates(BE_ALIEN, ALIEN_AFK_BRACKET, "alien candidate")
var/list/candidates = get_candidates(ROLE_ALIEN, ALIEN_AFK_BRACKET, "alien candidate")
var/client/C = null
// To stop clientless larva, we will check that our host has a client
+1 -1
View File
@@ -41,7 +41,7 @@
return
var/mob/living/carbon/brain/B = newbrain.brainmob
if(!B.key)
B.notify_ghost_cloning("Someone has put your brain in a MMI!")
B.notify_ghost_cloning("Someone has put your brain in a MMI!", source = src)
visible_message("[user] sticks \a [newbrain] into \the [src].")
brainmob = newbrain.brainmob
@@ -38,3 +38,9 @@
/mob/living/carbon/brain/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default
return
/mob/living/carbon/brain/check_ear_prot()
return 1
/mob/living/carbon/brain/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
return // no eyes, no flashing
@@ -144,8 +144,12 @@
/mob/living/carbon/brain/handle_status_effects()
return
/mob/living/carbon/brain/handle_changeling()
return
/mob/living/carbon/brain/handle_regular_hud_updates()
handle_vision()
handle_hud_icons_health()
update_action_buttons()
return 1
@@ -9,6 +9,7 @@ var/global/posibrain_notif_cooldown = 0
origin_tech = "biotech=3;programming=2"
var/notified = 0
var/askDelay = 10 * 60 * 1
var/used = 0 //Prevents split personality virus. May be reset if personality deletion code is added.
brainmob = null
req_access = list(access_robotics)
mecha = null//This does not appear to be used outside of reference in mecha.dm.
@@ -22,17 +23,18 @@ var/global/posibrain_notif_cooldown = 0
/obj/item/device/mmi/posibrain/proc/ping_ghosts(msg)
if(!posibrain_notif_cooldown)
notify_ghosts("Positronic brain [msg] in [get_area(src)]! <a href=?src=\ref[src];activate=1>(Click to enter)</a>", 'sound/effects/ghost2.ogg')
notify_ghosts("Positronic brain [msg] in [get_area(src)]!", enter_link="<a href=?src=\ref[src];activate=1>(Click to enter)</a>", 'sound/effects/ghost2.ogg', source = src, attack_not_jump = 1)
posibrain_notif_cooldown = 1
spawn(askDelay) //Global one minute cooldown to avoid spam.
posibrain_notif_cooldown = 0
/obj/item/device/mmi/posibrain/attack_self(mob/user)
if(brainmob && !brainmob.key && !notified)
//Start the process of notified for a new user.
//Start the process of requesting a new ghost.
user << "<span class='notice'>You carefully locate the manual activation switch and start the positronic brain's boot process.</span>"
ping_ghosts("requested")
notified = 1
used = 0
update_icon()
spawn(askDelay) //Seperate from the global cooldown.
notified = 0
@@ -47,7 +49,7 @@ var/global/posibrain_notif_cooldown = 0
//Two ways to activate a positronic brain. A clickable link in the ghost notif, or simply clicking the object itself.
/obj/item/device/mmi/posibrain/proc/activate(mob/user)
if((brainmob && brainmob.key) || jobban_isbanned(user,"posibrain"))
if(used || (brainmob && brainmob.key) || jobban_isbanned(user,"posibrain"))
return
var/posi_ask = alert("Become a positronic brain? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No")
@@ -81,7 +83,7 @@ var/global/posibrain_notif_cooldown = 0
return
/obj/item/device/mmi/posibrain/proc/transfer_personality(mob/candidate)
if(brainmob && brainmob.key) //Prevents hostile takeover if two ghosts get the prompt or link for the same brain.
if(used || (brainmob && brainmob.key)) //Prevents hostile takeover if two ghosts get the prompt or link for the same brain.
candidate << "This brain has already been taken! Please try your possesion again later!"
return
notified = 0
@@ -97,6 +99,7 @@ var/global/posibrain_notif_cooldown = 0
visible_message("<span class='notice'>The positronic brain chimes quietly.</span>")
update_icon()
used = 1
/obj/item/device/mmi/posibrain/examine()
@@ -118,7 +121,7 @@ var/global/posibrain_notif_cooldown = 0
if(UNCONSCIOUS) msg += "<span class='warning'>It doesn't seem to be responsive.</span>\n"
if(DEAD) msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
else
msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
msg += "<span class='deadsay'>It appears to be completely inactive. The reset light is blinking.</span>\n"
msg += "<span class='info'>*---------*</span>"
usr << msg
return
@@ -126,7 +129,7 @@ var/global/posibrain_notif_cooldown = 0
/obj/item/device/mmi/posibrain/New()
brainmob = new(src)
brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR"))]-[rand(100, 999)]"
brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","ANNS","KOS","TKRG","XAL","STLP","CBOS","DNCN","FXMC","DRSD"))]-[rand(100, 999)]"
brainmob.real_name = brainmob.name
brainmob.loc = src
brainmob.container = src
+5 -1
View File
@@ -37,7 +37,7 @@
src.bodytemperature += 2
/mob/living/carbon/movement_delay()
. = 0
. = ..()
if(legcuffed)
. += legcuffed.slowdown
@@ -144,6 +144,10 @@
mode() // Activate held item
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
if(on_fire)
M << "<span class='warning'>You can't put them out with just your bare hands!"
return
if(health >= 0)
if(lying)
@@ -24,7 +24,6 @@
has_limbs = 1
var/obj/item/weapon/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/
var/remote_view = 0
var/list/obj/effect/proc_holder/alien/abilities = list()
var/gib_type = /obj/effect/decal/cleanable/blood/gibs
+1
View File
@@ -1,5 +1,6 @@
/mob/living/carbon/death(gibbed)
silent = 0
losebreath = 0
med_hud_set_health()
med_hud_set_status()
..(gibbed)
@@ -14,8 +14,10 @@
new /obj/effect/decal/remains/human(loc)
/mob/living/carbon/human/death(gibbed)
if(stat == DEAD) return
if(healths) healths.icon_state = "health5"
if(stat == DEAD)
return
if(healths)
healths.icon_state = "health5"
stat = DEAD
dizziness = 0
jitteriness = 0
@@ -72,6 +72,13 @@
m_type = 2
if ("custom")
if(jobban_isbanned(src, "emote"))
src << "You cannot send custom emotes (banned)"
return
if(src.client)
if(client.prefs.muted & MUTE_IC)
src << "You cannot send IC messages (muted)."
return
var/input = copytext(sanitize(input("Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN)
if (!input)
return
@@ -189,6 +196,9 @@
if ("me")
if(silent)
return
if(jobban_isbanned(src, "emote"))
src << "You cannot send custom emotes (banned)"
return
if (src.client)
if (client.prefs.muted & MUTE_IC)
src << "<span class='danger'>You cannot send IC messages (muted).</span>"
@@ -48,7 +48,7 @@
sec_hud_set_implants()
sec_hud_set_security_status()
//...and display them.
add_to_all_data_huds()
add_to_all_human_data_huds()
/mob/living/carbon/human/Destroy()
for(var/atom/movable/organelle in organs)
@@ -27,7 +27,7 @@ emp_act
/mob/living/carbon/human/proc/checkarmor(obj/item/organ/limb/def_zone, type)
if(!type) return 0
var/protection = 0
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform)
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
for(var/bp in body_parts)
if(!bp) continue
if(bp && istype(bp ,/obj/item/clothing))
+3 -12
View File
@@ -266,7 +266,7 @@
if(machine)
if(!machine.check_eye(src)) reset_view(null)
else
if(!client.adminobs) reset_view(null)
if(!remote_view && !client.adminobs) reset_view(null)
dna.species.handle_vision(src)
@@ -295,16 +295,6 @@
// make it so you can only puke so fast
lastpuke = 0
/mob/living/carbon/human/handle_changeling()
if(mind && hud_used)
if(mind.changeling)
mind.changeling.regenerate(src)
hud_used.lingchemdisplay.invisibility = 0
hud_used.lingchemdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#dd66dd'>[round(mind.changeling.chem_charges)]</font></div>"
else
hud_used.lingchemdisplay.invisibility = 101
/mob/living/carbon/human/has_smoke_protection()
if(wear_mask)
if(wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)
@@ -335,7 +325,8 @@
if(!heart_attack)
return
else
losebreath += 5
if(losebreath < 3)
losebreath += 2
adjustOxyLoss(5)
adjustBruteLoss(1)
+12 -14
View File
@@ -822,7 +822,7 @@
////////////////
/datum/species/proc/movement_delay(mob/living/carbon/human/H)
var/mspeed = 0
. = 0
if(!(H.status_flags & IGNORESLOWDOWN))
@@ -844,39 +844,37 @@
if(P.allow_thrust(0.01, H))
hasjetpack = 1
mspeed = -1 - hasjetpack
. = -1 - hasjetpack
if(grav || !hasjetpack)
var/health_deficiency = (100 - H.health + H.staminaloss)
if(health_deficiency >= 40)
mspeed += (health_deficiency / 25)
. += (health_deficiency / 25)
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
if(hungry >= 70)
mspeed += hungry / 50
. += hungry / 50
if(H.wear_suit)
mspeed += H.wear_suit.slowdown
. += H.wear_suit.slowdown
if(H.shoes)
mspeed += H.shoes.slowdown
. += H.shoes.slowdown
if(H.back)
mspeed += H.back.slowdown
. += H.back.slowdown
if((H.disabilities & FAT))
mspeed += 1.5
. += 1.5
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
mspeed += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR
. += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR
mspeed += speedmod
. += speedmod
if(grav)
if(H.status_flags & GOTTAGOFAST)
mspeed -= 1
. -= 1
if(H.status_flags & GOTTAGOREALLYFAST)
mspeed -= 2
return mspeed
. -= 2
//////////////////
// ATTACK PROCS //
@@ -35,7 +35,7 @@
/datum/species/human/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "mutationtoxin")
H << "<span class='danger'>Your flesh rapidly mutates!</span>"
H.set_species(/datum/species/slime)
H.set_species(/datum/species/jelly/slime)
H.reagents.del_reagent(chem.type)
H.faction |= "slime"
return 1
@@ -111,13 +111,12 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
/datum/species/pod/spec_life(mob/living/carbon/human/H)
if(H.stat == DEAD)
return
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
if(isturf(H.loc)) //else, there's considered to be no light
var/turf/T = H.loc
var/area/A = T.loc
if(A)
if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5
else light_amount = 5
light_amount = min(10,T.get_lumcount()) - 5
H.nutrition += light_amount
if(H.nutrition > NUTRITION_LEVEL_FULL)
H.nutrition = NUTRITION_LEVEL_FULL
@@ -173,58 +172,13 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
var/light_amount = 0
if(isturf(H.loc))
var/turf/T = H.loc
var/area/A = T.loc
if(A)
if(A.lighting_use_dynamic) light_amount = T.lighting_lumcount
else light_amount = 10
light_amount = T.get_lumcount()
if(light_amount > 2) //if there's enough light, start dying
H.take_overall_damage(1,1)
else if (light_amount < 2) //heal in the dark
H.heal_overall_damage(1,1)
/*
SLIMEPEOPLE
*/
/datum/species/slime
// Humans mutated by slime mutagen, produced from green slimes. They are not targetted by slimes.
name = "Slimeperson"
id = "slime"
default_color = "00FFFF"
darksight = 3
invis_sight = SEE_INVISIBLE_LEVEL_ONE
specflags = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
hair_color = "mutcolor"
hair_alpha = 150
ignored_by = list(/mob/living/simple_animal/slime)
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime
exotic_blood = /datum/reagent/toxin/slimejelly
var/recently_changed = 1
/datum/species/slime/spec_life(mob/living/carbon/human/H)
if(!H.reagents.get_reagent_amount("slimejelly"))
if(recently_changed)
H.reagents.add_reagent("slimejelly", 80)
recently_changed = 0
else
H.reagents.add_reagent("slimejelly", 5)
H.adjustBruteLoss(5)
H << "<span class='danger'>You feel empty!</span>"
for(var/datum/reagent/toxin/slimejelly/S in H.reagents.reagent_list)
if(S.volume < 100)
if(H.nutrition >= NUTRITION_LEVEL_STARVING)
H.reagents.add_reagent("slimejelly", 0.5)
H.nutrition -= 5
if(S.volume < 50)
if(prob(5))
H << "<span class='danger'>You feel drained!</span>"
if(S.volume < 10)
H.losebreath++
/datum/species/slime/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "slimejelly")
return 1
/*
JELLYPEOPLE
*/
@@ -242,6 +196,8 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
var/recently_changed = 1
/datum/species/jelly/spec_life(mob/living/carbon/human/H)
if(H.stat == DEAD) //can't farm slime jelly from a dead slime/jelly person indefinitely
return
if(!H.reagents.get_reagent_amount("slimejelly"))
if(recently_changed)
H.reagents.add_reagent("slimejelly", 80)
@@ -255,8 +211,9 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
if(S.volume < 100)
if(H.nutrition >= NUTRITION_LEVEL_STARVING)
H.reagents.add_reagent("slimejelly", 0.5)
H.nutrition -= 5
else if(prob(5))
H.nutrition -= 2.5
if(S.volume < 50)
if(prob(5))
H << "<span class='danger'>You feel drained!</span>"
if(S.volume < 10)
H.losebreath++
@@ -264,6 +221,110 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
/datum/species/jelly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "slimejelly")
return 1
/*
SLIMEPEOPLE
*/
/datum/species/jelly/slime
// Humans mutated by slime mutagen, produced from green slimes. They are not targetted by slimes.
name = "Slimeperson"
id = "slime"
default_color = "00FFFF"
darksight = 3
invis_sight = SEE_INVISIBLE_LEVEL_ONE
specflags = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
say_mod = "says"
eyes = "eyes"
hair_color = "mutcolor"
hair_alpha = 150
ignored_by = list(/mob/living/simple_animal/slime)
burnmod = 0.5
coldmod = 2
heatmod = 0.5
/datum/species/jelly/slime/spec_life(mob/living/carbon/human/H)
if(recently_changed)
var/datum/action/innate/split_body/S = new
S.Grant(H)
for(var/datum/reagent/toxin/slimejelly/S in H.reagents.reagent_list)
if(S.volume >= 200)
if(prob(5))
H << "<span class='notice'>You feel very bloated!</span>"
if(S.volume < 200)
if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
H.reagents.add_reagent("slimejelly", 0.5)
H.nutrition -= 2.5
..()
/datum/action/innate/split_body
name = "Split Body"
check_flags = AB_CHECK_ALIVE
button_icon_state = "slimesplit"
background_icon_state = "bg_alien"
/datum/action/innate/split_body/CheckRemoval()
var/mob/living/carbon/human/H = owner
if(!ishuman(H) || !H.dna || !H.dna.species || H.dna.species.id != "slime")
return 1
return 0
/datum/action/innate/split_body/Activate()
var/mob/living/carbon/human/H = owner
H << "<span class='notice'>You focus intently on moving your body while standing perfectly still...</span>"
H.notransform = 1
for(var/datum/reagent/toxin/slimejelly/S in H.reagents.reagent_list)
if(S.volume >= 200)
var/mob/living/carbon/human/spare = new /mob/living/carbon/human(H.loc)
spare.underwear = "Nude"
H.dna.transfer_identity(spare, transfer_SE=1)
H.dna.features["mcolor"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
spare.real_name = spare.dna.real_name
spare.name = spare.dna.real_name
spare.updateappearance(mutcolor_update=1)
spare.domutcheck()
spare.Move(get_step(H.loc, pick(NORTH,SOUTH,EAST,WEST)))
S.volume = 80
H.notransform = 0
var/datum/action/innate/swap_body/callforward = new /datum/action/innate/swap_body()
var/datum/action/innate/swap_body/callback = new /datum/action/innate/swap_body()
callforward.body = spare
callforward.Grant(H)
callback.body = H
callback.Grant(spare)
H.mind.transfer_to(spare)
spare << "<span class='notice'>...and after a moment of disorentation, you're besides yourself!</span>"
return
H << "<span class='warning'>...but there is not enough of you to go around! You must attain more mass to split!</span>"
H.notransform = 0
/datum/action/innate/swap_body
name = "Swap Body"
check_flags = AB_CHECK_ALIVE
button_icon_state = "slimeswap"
background_icon_state = "bg_alien"
var/mob/living/carbon/human/body
/datum/action/innate/swap_body/CheckRemoval()
var/mob/living/carbon/human/H = owner
if(!ishuman(H) || !H.dna || !H.dna.species || H.dna.species.id != "slime")
return 1
return 0
/datum/action/innate/swap_body/Activate()
if(!body || !istype(body) || !body.dna || !body.dna.species || body.dna.species.id != "slime" || body.stat == DEAD || qdeleted(body))
owner << "<span class='warning'>Something is wrong, you cannot sense your other body!</span>"
Remove(owner)
return
if(body.stat == UNCONSCIOUS)
owner << "<span class='warning'>You sense this body has passed out for some reason. Best to stay away.</span>"
return
owner.mind.transfer_to(body)
/*
GOLEMS
*/
@@ -276,7 +337,7 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
speedmod = 3
armor = 55
punchmod = 5
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_head, slot_w_uniform)
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform)
nojumpsuit = 1
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem
@@ -429,14 +490,14 @@ var/global/image/plasmaman_on_fire = image("icon"='icons/mob/OnFire.dmi', "icon_
/datum/species/plasmaman/spec_life(mob/living/carbon/human/H)
var/datum/gas_mixture/environment = H.loc.return_air()
if(!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/hardsuit/plasmaman))
if(!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/plasmaman))
if(environment)
var/total_moles = environment.total_moles()
if(total_moles)
if((environment.oxygen /total_moles) >= 0.01)
if(!H.on_fire)
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")
H.adjust_fire_stacks(0.5)
if(!H.on_fire && H.fire_stacks > 0)
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")
H.IgniteMob()
else
if(H.fire_stacks)
@@ -392,9 +392,11 @@ Please contact me on #coderbus IRC. ~Carnie x
/mob/living/carbon/human/update_inv_legcuffed()
remove_overlay(LEGCUFF_LAYER)
clear_alert("legcuffed")
if(legcuffed)
overlays_standing[LEGCUFF_LAYER] = image("icon"='icons/mob/mob.dmi', "icon_state"="legcuff1", "layer"=-LEGCUFF_LAYER)
apply_overlay(LEGCUFF_LAYER)
apply_overlay(LEGCUFF_LAYER)
throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = src.legcuffed)
/mob/living/carbon/human/update_hud() //TODO: do away with this if possible
+36 -1
View File
@@ -197,9 +197,44 @@
/mob/living/carbon/proc/handle_changeling()
return
if(mind && hud_used)
if(mind.changeling)
mind.changeling.regenerate(src)
hud_used.lingchemdisplay.invisibility = 0
hud_used.lingchemdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#dd66dd'>[round(mind.changeling.chem_charges)]</font></div>"
else
hud_used.lingchemdisplay.invisibility = 101
/mob/living/carbon/handle_mutations_and_radiation()
if(dna && dna.temporary_mutations.len)
var/datum/mutation/human/HM
for(var/mut in dna.temporary_mutations)
if(dna.temporary_mutations[mut] < world.time)
if(mut == UI_CHANGED)
if(dna.previous["UI"])
dna.uni_identity = merge_text(dna.uni_identity,dna.previous["UI"])
updateappearance(mutations_overlay_update=1)
dna.previous.Remove("UI")
dna.temporary_mutations.Remove(mut)
continue
if(mut == UE_CHANGED)
if(dna.previous["name"])
real_name = dna.previous["name"]
name = real_name
dna.previous.Remove("name")
if(dna.previous["UE"])
dna.unique_enzymes = dna.previous["UE"]
dna.previous.Remove("UE")
if(dna.previous["blood_type"])
dna.blood_type = dna.previous["blood_type"]
dna.previous.Remove("blood_type")
dna.temporary_mutations.Remove(mut)
continue
HM = mutations_list[mut]
HM.force_lose(src)
dna.temporary_mutations.Remove(mut)
if(radiation)
switch(radiation)
@@ -143,16 +143,6 @@
emote("scratch")
return
/mob/living/carbon/monkey/handle_changeling()
if(mind && hud_used)
if(mind.changeling)
mind.changeling.regenerate(src)
hud_used.lingchemdisplay.invisibility = 0
hud_used.lingchemdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#dd66dd'>[round(mind.changeling.chem_charges)]</font></div>"
else
hud_used.lingchemdisplay.invisibility = 101
/mob/living/carbon/monkey/has_smoke_protection()
if(wear_mask)
if(wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)
@@ -39,22 +39,25 @@
//Prepare our med HUD...
..()
//...and display it.
for(var/datum/atom_hud/data/medical/hud in huds)
for(var/datum/atom_hud/data/human/medical/hud in huds)
hud.add_to_hud(src)
/mob/living/carbon/monkey/movement_delay()
var/tally = 0
if(reagents)
if(reagents.has_reagent("morphine")) return -1
if(reagents.has_reagent("morphine"))
return -1
if(reagents.has_reagent("nuka_cola")) return -1
if(reagents.has_reagent("nuka_cola"))
return -1
. = ..()
var/health_deficiency = (100 - health)
if(health_deficiency >= 45) tally += (health_deficiency / 25)
if(health_deficiency >= 45)
. += (health_deficiency / 25)
if (bodytemperature < 283.222)
tally += (283.222 - bodytemperature) / 10 * 1.75
return tally+config.monkey_delay
. += (283.222 - bodytemperature) / 10 * 1.75
return . + config.monkey_delay
/mob/living/carbon/monkey/attack_paw(mob/living/M)
if(..()) //successful monkey bite.
@@ -129,10 +129,12 @@
/mob/living/carbon/update_inv_handcuffed()
remove_overlay(HANDCUFF_LAYER)
clear_alert("handcuffed")
if(handcuffed)
drop_r_hand()
drop_l_hand()
stop_pulling() //TODO: should be handled elsewhere
throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
if(hud_used) //hud handcuff icons
var/obj/screen/inventory/R = hud_used.r_hand_hud_object
var/obj/screen/inventory/L = hud_used.l_hand_hud_object
+3
View File
@@ -144,6 +144,9 @@
m_type = 1
if ("me")
if(jobban_isbanned(src, "emote"))
src << "You cannot send custom emotes (banned)"
return
if (src.client)
if(client.prefs.muted & MUTE_IC)
src << "You cannot send IC messages (muted)."
+2 -2
View File
@@ -156,7 +156,7 @@
if(I.action_button_name)
if(!I.action)
if(istype(I, /obj/item/organ/internal))
I.action = new/datum/action/organ_action
I.action = new/datum/action/item_action/organ_action
else if(I.action_button_is_hands_free)
I.action = new/datum/action/item_action/hands_free
else
@@ -217,7 +217,7 @@
if (!( machine.check_eye(src) ))
reset_view(null)
else
if(!client.adminobs)
if(!remote_view && !client.adminobs)
reset_view(null)
/mob/living/proc/update_sight()
+14 -1
View File
@@ -577,6 +577,19 @@ Sorry Giacom. Please don't be mad :(
// It's ugly. But everything related to inventory/storage is. -- c0
s_active.close(src)
/mob/living/movement_delay()
. = ..()
if(isturf(loc))
var/turf/T = loc
. += T.slowdown
switch(m_intent)
if("run")
if(drowsyness > 0)
. += 6
. += config.run_speed
if("walk")
. += config.walk_speed
/mob/living/proc/makeTrail(turf/T, mob/living/M)
if(!has_gravity(M))
return
@@ -673,7 +686,7 @@ Sorry Giacom. Please don't be mad :(
return name
/mob/living/update_gravity(has_gravity)
if(!ticker)
if(!ticker || !ticker.mode)
return
if(has_gravity)
clear_alert("weightless")
+8 -4
View File
@@ -109,7 +109,10 @@
/mob/living/proc/IgniteMob()
if(fire_stacks > 0 && !on_fire)
on_fire = 1
src.visible_message("<span class='warning'>[src] catches fire!</span>", \
"<span class='userdanger'>You're set on fire!</span>")
src.AddLuminosity(3)
throw_alert("fire", /obj/screen/alert/fire)
update_fire()
/mob/living/proc/ExtinguishMob()
@@ -117,13 +120,14 @@
on_fire = 0
fire_stacks = 0
src.AddLuminosity(-3)
clear_alert("fire")
update_fire()
/mob/living/proc/update_fire()
return
/mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person
fire_stacks = Clamp(fire_stacks + add_fire_stacks, min = -20, max = 20)
fire_stacks = Clamp(fire_stacks + add_fire_stacks, -20, 20)
if(on_fire && fire_stacks <= 0)
ExtinguishMob()
@@ -195,7 +199,7 @@
/mob/living/attack_slime(mob/living/simple_animal/slime/M)
if (!ticker)
if(!ticker || !ticker.mode)
M << "You cannot attack people before the game has started."
return
@@ -226,7 +230,7 @@
/mob/living/attack_paw(mob/living/carbon/monkey/M)
if (!ticker)
if(!ticker || !ticker.mode)
M << "You cannot attack people before the game has started."
return 0
@@ -271,7 +275,7 @@
return 0
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
if (!ticker)
if(!ticker || !ticker.mode)
M << "You cannot attack people before the game has started."
return 0
@@ -42,7 +42,6 @@
var/metabolism_efficiency = 1 //more or less efficiency to metabolize helpful/harmful reagents and regulate body temperature..
var/list/image/staticOverlays = list()
var/has_limbs = 0 //does the mob have distinct limbs?(arms,legs, chest,head)
var/list/datum/action/actions = list()
var/list/pipes_shown = list()
var/last_played_vent
+1 -1
View File
@@ -476,7 +476,7 @@ var/list/ai_list = list()
/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M)
if (!ticker)
if(!ticker || !ticker.mode)
M << "You cannot attack people before the game has started."
return
@@ -177,3 +177,5 @@
health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss()
if(!fire_res_on_core)
health -= getFireLoss()
diag_hud_set_status()
diag_hud_set_health()
+1
View File
@@ -5,4 +5,5 @@
ticker.mode.remove_gangster(mind, remove_bosses=1)
ticker.mode.remove_thrall(mind,0)
ticker.mode.remove_shadowling(mind)
ticker.mode.remove_hog_follower(mind,0)
..()
@@ -9,7 +9,6 @@
/mob/living/silicon/pai/var/list/available_software = list(
"crew manifest" = 5,
"digital messenger" = 5,
"chatroom client" = 5,
"medical records" = 15,
"security records" = 15,
//"camera jack" = 10,
@@ -67,8 +66,6 @@
left_part = src.softwareCamera()
if("signaller")
left_part = src.softwareSignal()
if("chatroom")
src.chatroom() //snowflake? maybe, but it's less effort this way
//usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc
@@ -287,8 +284,6 @@
for(var/s in src.software)
if(s == "digital messenger")
dat += "<a href='byond://?src=\ref[src];software=pdamessage;sub=0'>Digital Messenger</a> <br>"
if(s == "chatroom client")
dat += "<a href='byond://?src=\ref[src];software=chatroom;sub=0'>Chatroom Client</a> <br>"
if(s == "crew manifest")
dat += "<a href='byond://?src=\ref[src];software=manifest;sub=0'>Crew Manifest</a> <br>"
if(s == "medical records")
@@ -645,7 +640,3 @@
dat += "<br><br>"
dat += "Messages: <hr> [pda.tnote]"
return dat
/mob/living/silicon/pai/proc/chatroom()
pda.mode = 5
pda.attack_self(src)
@@ -79,6 +79,13 @@
m_type = 2
if ("custom")
if(jobban_isbanned(src, "emote"))
src << "You cannot send custom emotes (banned)"
return
if(src.client)
if(client.prefs.muted & MUTE_IC)
src << "You cannot send IC messages (muted)."
return
var/input = copytext(sanitize(input("Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN)
if (!input)
return
@@ -135,6 +142,9 @@
message = "<B>[src]</B> looks."
if ("me")
if(jobban_isbanned(src, "emote"))
src << "You cannot send custom emotes (banned)"
return
if (src.client)
if(client.prefs.muted & MUTE_IC)
src << "You cannot send IC messages (muted)."
@@ -31,6 +31,7 @@
uneq_all()
stat = UNCONSCIOUS
update_headlamp(1)
diag_hud_set_borgcell()
/mob/living/silicon/robot/handle_regular_status_updates()
@@ -44,6 +45,7 @@
if(health <= -maxHealth) //die only once
death()
diag_hud_set_status()
return
if(health < maxHealth*0.5) //Gradual break down of modules as more damage is sustained
@@ -62,6 +64,8 @@
if (paralysis || stunned || weakened) //Stunned etc.
stat = UNCONSCIOUS
update_headlamp()
diag_hud_set_health()
diag_hud_set_status()
return 1
@@ -3,10 +3,12 @@
..()
regenerate_icons()
show_laws(0)
if(mind) ticker.mode.remove_revolutionary(mind)
if(mind) ticker.mode.remove_gangster(mind,1,remove_bosses=1)
if(mind) ticker.mode.remove_thrall(mind,0)
if(mind) ticker.mode.remove_shadowling(mind)
if(mind)
ticker.mode.remove_revolutionary(mind)
ticker.mode.remove_gangster(mind,1,remove_bosses=1)
ticker.mode.remove_thrall(mind,0)
ticker.mode.remove_shadowling(mind)
ticker.mode.remove_hog_follower(mind, 0)
/mob/living/silicon/robot/update_hotkey_mode()
winset(src, null, "mainwindow.macro=borghotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0")
@@ -68,6 +68,7 @@
var/lamp_recharging = 0 //Flag for if the lamp is on cooldown after being forcibly disabled.
var/updating = 0 //portable camera camerachunk update
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD)
/mob/living/silicon/robot/New(loc)
spark_system = new /datum/effect_system/spark_spread()
@@ -125,6 +126,7 @@
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
aicamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
toner = 40
diag_hud_set_borgcell()
//If there's an MMI in the robot, have it ejected when the mob goes away. --NEO
/mob/living/silicon/robot/Destroy()
@@ -480,6 +482,7 @@
cell = W
user << "<span class='notice'>You insert the power cell.</span>"
update_icons()
diag_hud_set_borgcell()
else if (wires.IsInteractionTool(W))
if (wiresexposed)
@@ -711,6 +714,7 @@
user << "<span class='notice'>You remove \the [cell].</span>"
cell = null
update_icons()
diag_hud_set_borgcell()
if(!opened)
if(..()) // hulk attack
@@ -6,13 +6,12 @@
if(..()) return 1
return 0
//No longer needed, but I'll leave it here incase we plan to re-use it.
/mob/living/silicon/robot/movement_delay()
var/tally = 0 //Incase I need to add stuff other than "speed" later
. = ..()
tally = speed
. += speed
return tally+config.robot_delay
. += config.robot_delay
/mob/living/silicon/robot/mob_negates_gravity()
return magpulse
+23 -1
View File
@@ -14,6 +14,8 @@
var/designation = ""
var/radiomod = "" //Radio character used before state laws/arrivals announce to allow department transmissions, default, or none at all.
var/obj/item/device/camera/siliconcam/aicamera = null //photography
//hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD)
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD)
var/obj/item/device/radio/borg/radio = null //AIs dont use this but this is at the silicon level to advoid copypasta in say()
@@ -25,9 +27,17 @@
var/med_hud = DATA_HUD_MEDICAL_ADVANCED //Determines the med hud to use
var/sec_hud = DATA_HUD_SECURITY_ADVANCED //Determines the sec hud to use
var/d_hud = DATA_HUD_DIAGNOSTIC //There is only one kind of diag hud
var/law_change_counter = 0
/mob/living/silicon/New()
..()
var/datum/atom_hud/data/diagnostic/diag_hud = huds[DATA_HUD_DIAGNOSTIC]
diag_hud.add_to_hud(src)
diag_hud_set_status()
diag_hud_set_health()
/mob/living/silicon/Destroy()
radio = null
aicamera = null
@@ -338,8 +348,10 @@
/mob/living/silicon/proc/remove_med_sec_hud()
var/datum/atom_hud/secsensor = huds[sec_hud]
var/datum/atom_hud/medsensor = huds[med_hud]
var/datum/atom_hud/diagsensor = huds[d_hud]
secsensor.remove_hud_from(src)
medsensor.remove_hud_from(src)
diagsensor.remove_hud_from(src)
/mob/living/silicon/proc/add_sec_hud()
var/datum/atom_hud/secsensor = huds[sec_hud]
@@ -349,9 +361,13 @@
var/datum/atom_hud/medsensor = huds[med_hud]
medsensor.add_hud_to(src)
/mob/living/silicon/proc/add_diag_hud()
var/datum/atom_hud/diagsensor = huds[d_hud]
diagsensor.add_hud_to(src)
/mob/living/silicon/proc/sensor_mode()
set name = "Set Sensor Augmentation"
var/sensor_type = input("Please select sensor type.", "Sensor Integration", null) in list("Security", "Medical","Disable")
var/sensor_type = input("Please select sensor type.", "Sensor Integration", null) in list("Security", "Medical","Diagnostic","Disable")
remove_med_sec_hud()
switch(sensor_type)
if ("Security")
@@ -360,6 +376,9 @@
if ("Medical")
add_med_hud()
src << "<span class='notice'>Life signs monitor overlay enabled.</span>"
if ("Diagnostic")
add_diag_hud()
src << "<span class='notice'>Robotics diagnostic overlay enabled.</span>"
if ("Disable")
src << "Sensor augmentations disabled."
@@ -450,6 +469,9 @@
if(affect_silicon)
return ..()
/mob/living/silicon/check_ear_prot()
return 1
/mob/living/silicon/update_transform()
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/changed = 0
@@ -6,7 +6,7 @@
icon_state = "swarmer_unactivated"
/obj/item/unactivated_swarmer/New()
notify_ghosts("An unactivated swarmer has been created in [get_area(src)]! <a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>")
notify_ghosts("An unactivated swarmer has been created in [get_area(src)]!", enter_link = "<a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>", source = src, attack_not_jump = 1)
..()
/obj/item/unactivated_swarmer/Topic(href, href_list)
@@ -14,6 +14,12 @@
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
ventcrawler = 2
pass_flags = PASSTABLE
mob_size = MOB_SIZE_SMALL
minbodytemp = 200
maxbodytemp = 400
unsuitable_atmos_damage = 1
species = /mob/living/simple_animal/pet/cat
childtype = /mob/living/simple_animal/pet/cat/kitten
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2)
@@ -15,10 +15,18 @@
origin_tech = "programming=2;biotech=4"
var/drone_type = /mob/living/simple_animal/drone //Type of drone that will be spawned
/obj/item/drone_shell/New()
..()
var/area/A = get_area(src)
if(A)
notify_ghosts("A drone shell has been created in \the [A.name].", source = src, attack_not_jump = 1)
/obj/item/drone_shell/attack_ghost(mob/user)
if(jobban_isbanned(user,"drone"))
return
if(!ticker.mode)
user << "Can't become a drone before the game has started."
return
var/be_drone = alert("Become a drone? (Warning, You can no longer be cloned!)",,"Yes","No")
if(be_drone == "No" || gc_destroyed)
return
@@ -33,7 +33,7 @@
/mob/living/simple_animal/hostile/retaliate/goat/Destroy()
qdel(udder)
udder = null
..()
return ..()
/mob/living/simple_animal/hostile/retaliate/goat/Life()
. = ..()
@@ -107,7 +107,7 @@
/mob/living/simple_animal/cow/Destroy()
qdel(udder)
udder = null
..()
return ..()
/mob/living/simple_animal/cow/attackby(obj/item/O, mob/user, params)
if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass))
@@ -292,4 +292,4 @@ var/global/chicken_count = 0
/obj/udder/Destroy()
qdel(reagents)
..()
return ..()
@@ -23,6 +23,7 @@
mob_size = MOB_SIZE_TINY
var/body_color //brown, gray and white, leave blank for random
gold_core_spawnable = 2
var/chew_probability = 1
/mob/living/simple_animal/mouse/New()
..()
@@ -38,11 +39,14 @@
src.icon_dead = "mouse_[body_color]_splat"
death()
/mob/living/simple_animal/mouse/death(gibbed)
/mob/living/simple_animal/mouse/death(gibbed, toast)
if(!ckey)
..(1)
var/obj/item/trash/deadmouse/M = new(src.loc)
M.icon_state = icon_dead
if(toast)
M.color = "#3A3A3A"
M.desc = "It's toast."
qdel(src)
else
..(gibbed)
@@ -55,6 +59,21 @@
playsound(src, 'sound/effects/mousesqueek.ogg', 100, 1)
..()
/mob/living/simple_animal/mouse/handle_automated_action()
if(prob(chew_probability))
var/turf/simulated/floor/F = get_turf(src)
if(istype(F) && !F.intact)
var/obj/structure/cable/C = locate() in F
if(C && prob(15))
if(C.avail())
visible_message("<span class='warning'>[src] chews through the [C]. It's toast!</span>")
playsound(src, 'sound/effects/sparks2.ogg', 100, 1)
C.Deconstruct()
death(toast=1)
else
C.Deconstruct()
visible_message("<span class='warning'>[src] chews through the [C].</span>")
/*
* Mouse types
*/
@@ -16,6 +16,7 @@
attack_sound = 'sound/weapons/punch1.ogg'
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = 10000000
attacktext = "punches"
maxHealth = 100000 //The spirit itself is invincible
health = 100000
@@ -39,12 +40,17 @@
if(summoner)
if(summoner.stat == DEAD)
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'><B>The [src] dies along with its user!</B></span>")
summoner.visible_message("<span class='danger'><B>[summoner]'s body is completely consumed by the strain of sustaining [src]!</B></span>")
for(var/obj/item/W in summoner)
if(!summoner.unEquip(W))
qdel(W)
summoner.dust()
ghostize()
qdel(src)
else
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'><B>The [src] dies along with its user!</B></span>")
ghostize()
qdel(src)
if(summoner)
@@ -74,7 +80,7 @@
summoner.adjustBruteLoss(damage)
if(damage)
summoner << "<span class='danger'><B>Your [name] is under attack! You take damage!</span></B>"
summoner.visible_message("<span class='danger'>Blood sprays from [summoner] as [src] takes damage!</span>")
summoner.visible_message("<span class='danger'><B>Blood sprays from [summoner] as [src] takes damage!</B></span>")
if(summoner.stat == UNCONSCIOUS)
summoner << "<span class='danger'><B>Your body can't take the strain of sustaining [src] in this condition, it begins to fall apart!</span></B>"
summoner.adjustCloneLoss(damage/2)
@@ -99,10 +105,7 @@
//Manifest, Recall, Communicate
/mob/living/simple_animal/hostile/guardian/verb/Manifest()
set name = "Manifest"
set category = "Guardian"
set desc = "Spring forth into battle!"
/mob/living/simple_animal/hostile/guardian/proc/Manifest()
if(cooldown > world.time)
return
if(loc == summoner)
@@ -114,20 +117,14 @@
spawn(6)
icon_state = end_icon
/mob/living/simple_animal/hostile/guardian/verb/Recall()
set name = "Recall"
set category = "Guardian"
set desc = "Return to your summoner."
/mob/living/simple_animal/hostile/guardian/proc/Recall()
if(cooldown > world.time)
return
loc = summoner
buckled = null
cooldown = world.time + 30
/mob/living/simple_animal/hostile/guardian/verb/Communicate()
set name = "Communicate"
set category = "Guardian"
set desc = "Communicate telepathically with your summoner."
/mob/living/simple_animal/hostile/guardian/proc/Communicate()
var/input = stripped_input(src, "Please enter a message to tell your summoner.", "Guardian", "")
if(!input) return
@@ -137,6 +134,10 @@
src << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
log_say("[src.real_name]/[src.key] : [input]")
/mob/living/simple_animal/hostile/guardian/proc/ToggleMode()
src << "<span class='danger'><B>You dont have another mode!</span></B>"
/mob/living/proc/guardian_comm()
set name = "Communicate"
set category = "Guardian"
@@ -155,6 +156,13 @@
log_say("[src.real_name]/[src.key] : [text]")
/mob/living/simple_animal/hostile/guardian/proc/ToggleLight()
if(!luminosity)
SetLuminosity(3)
else
SetLuminosity(0)
//////////////////////////TYPES OF GUARDIANS
@@ -182,7 +190,7 @@
/mob/living/simple_animal/hostile/guardian/fire/AttackingTarget()
..()
if(prob(30))
if(prob(45))
if(istype(target, /atom/movable))
var/atom/movable/M = target
if(!M.anchored && M != summoner)
@@ -203,8 +211,8 @@
/mob/living/simple_animal/hostile/guardian/fire/proc/collision_ignite(AM as mob|obj)
if(istype(AM, /mob/living/))
var/mob/living/M = AM
if(AM != summoner)
M.adjust_fire_stacks(7)
if(AM != summoner && M.fire_stacks < 7)
M.fire_stacks = 7
M.IgniteMob()
/mob/living/simple_animal/hostile/guardian/fire/Bump(AM as mob|obj)
@@ -277,10 +285,7 @@
C.adjustOxyLoss(-5)
C.adjustToxLoss(-5)
/mob/living/simple_animal/hostile/guardian/healer/verb/ToggleMode()
set name = "Toggle Mode"
set category = "Guardian"
set desc = "Toggle between combat and healing modes."
/mob/living/simple_animal/hostile/guardian/healer/ToggleMode()
if(src.loc == summoner)
if(toggle)
a_intent = "harm"
@@ -366,6 +371,7 @@
icon_state = "guardian"
damage = 5
damage_type = BRUTE
armour_penetration = 100
/mob/living/simple_animal/hostile/guardian/ranged
a_intent = "help"
@@ -385,10 +391,7 @@
var/list/snares = list()
var/toggle = FALSE
/mob/living/simple_animal/hostile/guardian/ranged/verb/ToggleMode()
set name = "Toggle Mode"
set category = "Guardian"
set desc = "Toggle between combat and scout modes."
/mob/living/simple_animal/hostile/guardian/ranged/ToggleMode()
if(src.loc == summoner)
if(toggle)
ranged = 1
@@ -475,11 +478,11 @@
if(bomb_cooldown <= world.time && !stat)
var/obj/item/weapon/guardian_bomb/B = new /obj/item/weapon/guardian_bomb(get_turf(A))
src << "<span class='danger'><B>Success! Bomb armed!</span></B>"
bomb_cooldown = world.time + 400
bomb_cooldown = world.time + 200
B.spawner = src
B.disguise (A)
else
src << "<span class='danger'><B>Your powers are on cooldown! You must wait 40 seconds between bombs.</span></B>"
src << "<span class='danger'><B>Your powers are on cooldown! You must wait 20 seconds between bombs.</span></B>"
/obj/item/weapon/guardian_bomb
name = "bomb"
@@ -551,7 +554,7 @@
return
used = TRUE
user << "[use_message]"
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the [mob_name] of [user.real_name]?", "pAI", null, FALSE, 100)
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100)
var/mob/dead/observer/theghost = null
if(candidates.len)
@@ -677,3 +680,100 @@
new /obj/item/weapon/guardiancreator/tech/choose(src)
new /obj/item/weapon/paper/guardian(src)
return
///HUD
/datum/hud/proc/guardian_hud(ui_style = 'icons/mob/screen_midnight.dmi')
adding = list()
var/obj/screen/using
using = new /obj/screen/guardian/Manifest()
using.screen_loc = ui_rhand
adding += using
using = new /obj/screen/guardian/Recall()
using.screen_loc = ui_lhand
adding += using
using = new /obj/screen/guardian/ToggleMode()
using.screen_loc = ui_storage1
adding += using
using = new /obj/screen/guardian/ToggleLight()
using.screen_loc = ui_inventory
adding += using
using = new /obj/screen/guardian/Communicate()
using.screen_loc = ui_back
adding += using
mymob.client.screen = list()
mymob.client.screen += mymob.client.void
mymob.client.screen += adding
//HUD BUTTONS
/obj/screen/guardian
icon = 'icons/mob/guardian.dmi'
/obj/screen/guardian/Manifest
icon_state = "manifest"
name = "Manifest"
desc = "Spring forth into battle!"
/obj/screen/guardian/Manifest/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.Manifest()
/obj/screen/guardian/Recall
icon_state = "recall"
name = "Recall"
desc = "Return to your user."
/obj/screen/guardian/Recall/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.Recall()
/obj/screen/guardian/ToggleMode
icon_state = "toggle"
name = "Toggle Mode"
desc = "Switch between ability modes."
/obj/screen/guardian/ToggleMode/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.ToggleMode()
/obj/screen/guardian/Communicate
icon_state = "communicate"
name = "Communicate"
desc = "Communicate telepathically with your user."
/obj/screen/guardian/Communicate/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.Communicate()
/obj/screen/guardian/ToggleLight
icon_state = "light"
name = "Toggle Light"
desc = "Glow like star dust."
/obj/screen/guardian/ToggleLight/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.ToggleLight()
@@ -2,8 +2,8 @@
name = "alien hunter"
desc = "Hiss!"
icon = 'icons/mob/alien.dmi'
icon_state = "alienh_running"
icon_living = "alienh_running"
icon_state = "alienh_s"
icon_living = "alienh_s"
icon_dead = "alienh_dead"
icon_gib = "syndicate_gib"
response_help = "pokes"
@@ -33,8 +33,8 @@
/mob/living/simple_animal/hostile/alien/drone
name = "alien drone"
icon_state = "aliend_running"
icon_living = "aliend_running"
icon_state = "aliend_s"
icon_living = "aliend_s"
icon_dead = "aliend_dead"
health = 60
melee_damage_lower = 15
@@ -53,8 +53,8 @@
/mob/living/simple_animal/hostile/alien/sentinel
name = "alien sentinel"
icon_state = "aliens_running"
icon_living = "aliens_running"
icon_state = "aliens_s"
icon_living = "aliens_s"
icon_dead = "aliens_dead"
health = 120
melee_damage_lower = 15
@@ -68,8 +68,8 @@
/mob/living/simple_animal/hostile/alien/queen
name = "alien queen"
icon_state = "alienq_running"
icon_living = "alienq_running"
icon_state = "alienq_s"
icon_living = "alienq_s"
icon_dead = "alienq_dead"
health = 250
maxHealth = 250
@@ -122,9 +122,9 @@
/mob/living/simple_animal/hostile/alien/queen/large
name = "alien empress"
icon = 'icons/mob/alienqueen.dmi'
icon_state = "queen_s"
icon_living = "queen_s"
icon_dead = "queen_dead"
icon_state = "alienq"
icon_living = "alienq"
icon_dead = "alienq_dead"
move_to_delay = 4
maxHealth = 400
health = 400
@@ -75,9 +75,6 @@
for(var/obj/item/organ/internal/I in src)
I.Insert(M, 1)
if(!origin && owner.mind)
origin = owner.mind
if(origin)
origin.transfer_to(M)
if(!origin.changeling)
@@ -110,6 +110,7 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca
var/mob/living/creator = null // the creator
var/destroy_objects = 0
var/knockdown_people = 0
var/image/googly_eyes = null
gold_core_spawnable = 0
/mob/living/simple_animal/hostile/mimic/copy/New(loc, obj/copy, mob/living/creator, destroy_original = 0)
@@ -150,6 +151,8 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca
icon_state = O.icon_state
icon_living = icon_state
overlays = O.overlays
googly_eyes = image('icons/mob/mob.dmi',"googly_eyes")
overlays += googly_eyes
if(istype(O, /obj/structure) || istype(O, /obj/machinery))
health = (anchored * 50) + 50
destroy_objects = 1
@@ -185,6 +188,9 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca
C.visible_message("<span class='danger'>\The [src] knocks down \the [C]!</span>", \
"<span class='userdanger'>\The [src] knocks you down!</span>")
/mob/living/simple_animal/hostile/mimic/copy/Aggro()
..()
googly_eyes.dir = get_dir(src,target)
/mob/living/simple_animal/hostile/mimic/copy/machine
@@ -50,22 +50,8 @@
attacktext = "slashes"
attack_sound = 'sound/weapons/bladeslice.ogg'
status_flags = 0
/mob/living/simple_animal/hostile/syndicate/melee/attackby(obj/item/O, mob/user, params)
if(O.force)
if(prob(80))
var/damage = O.force
if (O.damtype == STAMINA)
damage = 0
health -= damage
visible_message("<span class='danger'>[user] has attacked [src] with [O]!</span>")
else
visible_message("<span class='danger'>[src] blocks [O] with its shield!</span>")
playsound(loc, O.hitsound, 25, 1, -1)
else
usr << "<span class='warning'>This weapon is ineffective, it does no damage!</span>"
visible_message("<span class='warning'>[user] gently taps [src] with [O].</span>")
maxHealth = 150
health = 150
/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(obj/item/projectile/Proj)
if(!Proj) return
@@ -0,0 +1,162 @@
/mob/living/simple_animal/hostile/zombie
name = "zombie"
desc = "When Observe is full, the dead shall walk the station."
icon = 'icons/mob/human.dmi'
icon_state = "zombie_s"
icon_living = "zombie_s"
icon_dead = "zombie_dead"
turns_per_move = 5
speak_emote = list("groans")
emote_see = list("groans")
a_intent = "harm"
maxHealth = 100
health = 100
speed = 1
harm_intent_damage = 8
melee_damage_lower = 20
melee_damage_upper = 20
attacktext = "claws"
attack_sound = 'sound/hallucinations/growl1.ogg'
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = 350
unsuitable_atmos_damage = 10
environment_smash = 1
robust_searching = 1
stat_attack = 2
gold_core_spawnable = 1
faction = list("zombie")
var/mob/living/carbon/human/stored_corpse = null
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie = 3)
see_invisible = SEE_INVISIBLE_MINIMUM
see_in_dark = 8
layer = MOB_LAYER - 0.1
/mob/living/simple_animal/hostile/zombie/AttackingTarget()
..()
if(istype(target, /mob/living))
var/mob/living/L = target
if(ishuman(L) && L.stat)
var/mob/living/carbon/human/H = L
for(var/mob/living/simple_animal/hostile/zombie/holder/Z in H) //No instant heals for people who are already zombies
src << "<span class='userdanger'>They'll be getting up on their own, just give them a minute!</span>"
Z.faction = src.faction //Just in case zombies somehow ended up on different "teams"
H.faction = src.faction
return
Zombify(H)
else if (L.stat) //So they don't get stuck hitting a corpse
L.gib()
visible_message("<span class='danger'>[src] tears [L] to pieces!</span>")
src << "<span class='userdanger'>You feast on [L], restoring your health!</span>"
src.revive()
/mob/living/simple_animal/hostile/zombie/death()
..()
if(stored_corpse)
stored_corpse.loc = loc
if(ckey)
stored_corpse.ckey = src.ckey
stored_corpse << "<span class='userdanger'>You're down, but not quite out. You'll be back on your feet within a minute or two.</span>"
var/mob/living/simple_animal/hostile/zombie/holder/D = new/mob/living/simple_animal/hostile/zombie/holder(stored_corpse)
D.faction = src.faction
qdel(src)
return
src << "<span class='userdanger'>You're down, but not quite out. You'll be back on your feet within a minute or two.</span>"
spawn(rand(800,1200))
if(src)
visible_message("<span class='danger'>[src] staggers to their feet!</span>")
src.revive()
/mob/living/simple_animal/hostile/zombie/proc/Zombify(mob/living/carbon/human/H)
H.set_species(/datum/species/zombie)
if(H.head) //So people can see they're a zombie
var/obj/item/clothing/helmet = H.head
if(!H.unEquip(helmet))
qdel(helmet)
if(H.wear_mask)
var/obj/item/clothing/mask = H.wear_mask
if(!H.unEquip(mask))
qdel(mask)
var/mob/living/simple_animal/hostile/zombie/Z = new /mob/living/simple_animal/hostile/zombie(H.loc)
Z.faction = src.faction
Z.appearance = H.appearance
Z.transform = matrix()
Z.pixel_y = 0
for(var/mob/dead/observer/ghost in player_list)
if(H.real_name == ghost.real_name)
ghost.reenter_corpse()
break
Z.ckey = H.ckey
H.stat = DEAD
H.butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie = 3) //So now you can carve them up when you kill them. Maybe not a good idea for the human versions.
H.loc = Z
Z.stored_corpse = H
for(var/mob/living/simple_animal/hostile/zombie/holder/D in H) //Dont want to revive them twice
qdel(D)
visible_message("<span class='danger'>[Z] staggers to their feet!</span>")
Z << "<span class='userdanger'>You are now a zombie! Follow your creators lead!</span>"
/mob/living/simple_animal/hostile/spawner/zombie
name = "corpse pit"
desc = "A pit full of zombies."
icon_state = "tombstone"
icon_living = "tombstone"
icon = 'icons/mob/nest.dmi'
health = 400
maxHealth = 400
list/spawned_mobs = list()
max_mobs = 40
spawn_time = 100
mob_type = /mob/living/simple_animal/hostile/zombie
spawn_text = "emerges from"
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)
faction = list("zombie")
/mob/living/simple_animal/hostile/spawner/zombie/lesser
name = "lesser corpse pit"
desc = "A pit full of less zombies."
max_mobs = 10
spawn_time = 150
health = 200
maxHealth = 200
/mob/living/simple_animal/hostile/spawner/zombie/death()
visible_message("<span class='danger'>[src] collapes, stopping the flow of zombies!</span>")
qdel(src)
/obj/item/weapon/shovel/cursed
name = "cursed shovel"
desc = "You probably shouldn't use this particular shovel."
var/used = FALSE
force = 15
/obj/item/weapon/shovel/cursed/attack_self(mob/living/user)
if(used == FALSE)
visible_message("<span class='danger'>[user] digs a pit to Hell!</span>")
new /mob/living/simple_animal/hostile/spawner/zombie(get_turf(src.loc))
used = TRUE
else
user << "The unearthly energies that once powered this shovel are now dormant. Still sharp though."
/mob/living/simple_animal/hostile/zombie/holder
name = "infection holder"
desc = "You shouldn't be seeing this."
unsuitable_atmos_damage = 0
stat_attack = 2
gold_core_spawnable = 0
AIStatus = AI_OFF
stop_automated_movement = 1
/mob/living/simple_animal/hostile/zombie/holder/New()
..()
spawn(rand(800,1200))
if(src && istype(loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = loc
Zombify(H)
qdel(src)
@@ -129,6 +129,11 @@
visible_message("<span class='warning'>[src] twists and dissolves into a pile of green flesh!</span>", \
"<span class='userdanger'>Your skin ruptures! Your flesh breaks apart! No disguise can ward off de--</span>")
restore()
if(gibbed)
for(var/atom/movable/AM in src)
AM.loc = loc
if(prob(90))
step(AM, pick(alldirs))
..(gibbed)
/mob/living/simple_animal/hostile/morph/Aggro() // automated only
@@ -171,24 +176,6 @@
return
target.attack_animal(src)
/mob/living/simple_animal/hostile/morph/harvest(mob/living/user)
if(qdeleted(src))
return
if(contents.len)
var/amount = min(contents.len, 10)
for(var/atom/movable/AM in src)
if(amount)
amount--
AM.loc = loc
if(prob(90))
spawn(3)
step(AM, pick(alldirs))
else
break
visible_message("<span class='notice'>[user] [contents.len?"extracts some of":"empties"] the content of [src].</span>")
else
..()
/mob/living/simple_animal/hostile/morph/update_action_buttons() //So all eaten objects are not counted every life
return
@@ -206,7 +193,7 @@
/datum/round_event/morph/proc/get_morph(end_if_fail = 0)
key_of_morph = null
if(!key_of_morph)
var/list/candidates = get_candidates(BE_ALIEN)
var/list/candidates = get_candidates(ROLE_ALIEN)
if(!candidates.len)
if(end_if_fail)
return 0
@@ -112,7 +112,8 @@
/mob/living/simple_animal/parrot/proc/steal_from_mob, \
/mob/living/simple_animal/parrot/verb/drop_held_item_player, \
/mob/living/simple_animal/parrot/proc/perch_player, \
/mob/living/simple_animal/parrot/proc/toggle_mode)
/mob/living/simple_animal/parrot/proc/toggle_mode,
/mob/living/simple_animal/parrot/proc/perch_mob_player)
/mob/living/simple_animal/parrot/death(gibbed)
@@ -120,6 +121,13 @@
held_item.loc = src.loc
held_item = null
walk(src,0)
if(buckled)
buckled.buckled_mob = null
buckled = null
pixel_x = initial(pixel_x)
pixel_y = initial(pixel_y)
..(gibbed)
/mob/living/simple_animal/parrot/Stat()
@@ -587,7 +595,8 @@
/mob/living/simple_animal/parrot/movement_delay()
if(client && stat == CONSCIOUS && parrot_state != "parrot_fly")
icon_state = "parrot_fly"
..()
//Because the most appropriate place to set icon_state is movement_delay(), clearly
return ..()
/mob/living/simple_animal/parrot/proc/isStuck()
//Check to see if the parrot is stuck due to things like windows or doors or windowdoors
@@ -787,6 +796,46 @@
src << "<span class='warning'>There is no perch nearby to sit on!</span>"
return
/mob/living/simple_animal/parrot/proc/perch_mob_player()
set name = "Sit on Human's Shoulder"
set category = "Parrot"
set desc = "Sit on a nice comfy human being!"
if(stat || !client)
return
if(icon_state == "parrot_fly")
for(var/mob/living/carbon/human/H in view(src,1))
if(H.buckled_mob) //Already has a parrot, or is being eaten by a slime
continue
perch_on_human(H)
return
src << "<span class='warning'>There is nobody nearby that you can sit on!</span>"
else
icon_state = "parrot_fly"
parrot_state = PARROT_WANDER
if(buckled)
src << "<span class='notice'>You are no longer sitting on [buckled]'s shoulder.</span>"
buckled.buckled_mob = null
buckled = null
pixel_x = initial(pixel_x)
pixel_y = initial(pixel_y)
/mob/living/simple_animal/parrot/proc/perch_on_human(mob/living/carbon/human/H)
if(!H)
return
loc = get_turf(H)
H.buckle_mob(src, force=1)
pixel_y = 9
pixel_x = pick(-8,8) //pick left or right shoulder
icon_state = "parrot_sit"
parrot_state = PARROT_PERCH
src << "<span class='notice'>You sit on [H]'s shoulder.</span>"
/mob/living/simple_animal/parrot/proc/toggle_mode()
set name = "Toggle mode"
set category = "Parrot"
@@ -801,6 +850,7 @@
else
melee_damage_upper = parrot_damage_upper
a_intent = "harm"
src << "You will now [a_intent] others..."
return
/*
@@ -3,7 +3,7 @@
//Don't hear deadchat and are NOT normal ghosts
//Admin-spawn or random event
#define INVISIBILITY_REVENANT 30
#define INVISIBILITY_REVENANT 50
/mob/living/simple_animal/revenant
name = "revenant"
@@ -14,6 +14,7 @@
invisibility = INVISIBILITY_REVENANT
health = INFINITY //Revenants don't use health, they use essence instead
maxHealth = INFINITY
layer = 5
healable = 0
see_invisible = SEE_INVISIBLE_MINIMUM
see_in_dark = 8
@@ -22,6 +23,7 @@
response_disarm = "swings at"
response_harm = "punches through"
unsuitable_atmos_damage = 0
ignored_damage_types = list(BRUTE = 0, BURN = 0, TOX = 1, CLONE = 1, STAMINA = 1, OXY = 1) //I don't know how you'd apply those, but revenants no-sell them anyway.
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = INFINITY
@@ -32,6 +34,7 @@
density = 0
flying = 1
anchored = 1
unique_name = 1
var/essence = 75 //The resource, and health, of revenants.
var/essence_regen_cap = 75 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount.
@@ -45,22 +48,27 @@
var/essence_drained = 0 //How much essence the revenant will drain from the corpse it's feasting on.
var/draining = 0 //If the revenant is draining someone.
var/list/drained_mobs = list() //Cannot harvest the same mob twice
var/perfectsouls = 0 //How many perfect, regen-cap increasing souls the revenant has. //TODO, add objective for getting a perfect soul(s?)
/mob/living/simple_animal/revenant/Life()
ear_damage = 0
ear_deaf = 0 //YOU CAN'T DEAFEN A REVENANT
if(revealed && essence <= 0)
death()
if(unreveal_time && world.time >= unreveal_time)
unreveal_time = 0
revealed = 0
invisibility = INVISIBILITY_REVENANT
src << "<span class='boldnotice'>You are once more concealed.</span>"
src << "<span class='revenboldnotice'>You are once more concealed.</span>"
if(unstun_time && world.time >= unstun_time)
unstun_time = 0
notransform = 0
src << "<span class='boldnotice'>You can move again!</span>"
src << "<span class='revenboldnotice'>You can move again!</span>"
if(essence_regenerating && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate
essence = min(essence_regen_cap, essence+essence_regen_amount)
update_spooky_icon()
..()
/mob/living/simple_animal/revenant/proc/reveal(time)
@@ -71,10 +79,12 @@
revealed = 1
invisibility = 0
if(!unreveal_time)
src << "<span class='userdanger'>You have been revealed!</span>"
src << "<span class='revendanger'>You have been revealed!</span>"
unreveal_time = world.time + time
else
src << "<span class='warning'>You have been revealed!</span>"
unreveal_time = world.time + time
src << "<span class='revenwarning'>You have been revealed!</span>"
unreveal_time = unreveal_time + time
update_spooky_icon()
/mob/living/simple_animal/revenant/proc/stun(time)
if(!src)
@@ -83,10 +93,24 @@
return
notransform = 1
if(!unstun_time)
src << "<span class='userdanger'>You cannot move!</span>"
src << "<span class='revendanger'>You cannot move!</span>"
unstun_time = world.time + time
else
src << "<span class='warning'>You cannot move!</span>"
unstun_time = world.time + time
src << "<span class='revenwarning'>You cannot move!</span>"
unstun_time = unstun_time + time
update_spooky_icon()
/mob/living/simple_animal/revenant/proc/update_spooky_icon()
if(unreveal_time)
if(draining)
icon_state = "revenant_draining"
return
if(unstun_time)
icon_state = "revenant_stun"
return
icon_state = "revenant_revealed"
return
icon_state = "revenant_idle"
/mob/living/simple_animal/revenant/ex_act(severity, target)
return 1 //Immune to the effects of explosions.
@@ -102,12 +126,11 @@
return
essence = max(0, essence-amount)
if(essence == 0)
src << "<span class='userdanger'>You feel your essence fraying!</span>"
src << "<span class='revendanger'>You feel your essence fraying!</span>"
/mob/living/simple_animal/revenant/ClickOn(atom/A, params) //Copypaste from ghost code - revenants can't interact with the world directly.
if(client.inquisitive_ghost)
A.examine(src)
A.examine(src)
if(ishuman(A) && in_range(src, A))
Harvest(A)
@@ -115,72 +138,81 @@
if(!castcheck(0))
return
if(draining)
src << "<span class='warning'>You are already siphoning the essence of a soul!</span>"
src << "<span class='revenwarning'>You are already siphoning the essence of a soul!</span>"
return
if(target in drained_mobs)
src << "<span class='warning'>[target]'s soul is dead and empty.</span>"
src << "<span class='revenwarning'>[target]'s soul is dead and empty.</span>"
return
if(!target.stat)
src << "<span class='notice'>This being's soul is too strong to harvest.</span>"
src << "<span class='revennotice'>This being's soul is too strong to harvest.</span>"
if(prob(10))
target << "You feel as if you are being watched."
return
draining = 1
essence_drained = rand(15, 20)
src << "<span class='notice'>You search for the soul of [target].</span>"
essence_drained += rand(15, 20)
src << "<span class='revennotice'>You search for the soul of [target].</span>"
if(do_after(src, 10, 3, 0, target)) //did they get deleted in that second?
if(target.ckey)
src << "<span class='notice'>Their soul burns with intelligence.</span>"
src << "<span class='revennotice'>Their soul burns with intelligence.</span>"
essence_drained += rand(20, 30)
if(target.stat != DEAD)
src << "<span class='notice'>Their soul blazes with life!</span>"
src << "<span class='revennotice'>Their soul blazes with life!</span>"
essence_drained += rand(40, 50)
else
src << "<span class='notice'>Their soul is weak and faltering.</span>"
src << "<span class='revennotice'>Their soul is weak and faltering.</span>"
if(do_after(src, 20, 6, 0, target)) //did they get deleted NOW?
switch(essence_drained)
if(1 to 30)
src << "<span class='info'>[target] will not yield much essence. Still, every bit counts.</span>"
src << "<span class='revennotice'>[target] will not yield much essence. Still, every bit counts.</span>"
if(30 to 70)
src << "<span class='info'>[target] will yield an average amount of essence.</span>"
src << "<span class='revennotice'>[target] will yield an average amount of essence.</span>"
if(70 to 90)
src << "<span class='info'>Such a feast! [target] will yield much essence to you.</span>"
src << "<span class='revenboldnotice'>Such a feast! [target] will yield much essence to you.</span>"
if(90 to INFINITY)
src << "<span class='boldnotice'>Ah, the perfect soul. [target] will yield massive amounts of essence to you.</span>"
src << "<span class='revenbignotice'>Ah, the perfect soul. [target] will yield massive amounts of essence to you.</span>"
if(do_after(src, 20, 6, 0, target)) //how about now
if(!target.stat)
src << "<span class='warning'>They are now powerful enough to fight off your draining.</span>"
src << "<span class='revenwarning'>They are now powerful enough to fight off your draining.</span>"
target << "<span class='boldannounce'>You feel something tugging across your body before subsiding.</span>"
draining = 0
essence_drained = 0
return //hey, wait a minute...
src << "<span class='danger'>You begin siphoning essence from [target]'s soul.</span>"
src << "<span class='revenminor'>You begin siphoning essence from [target]'s soul.</span>"
if(target.stat != DEAD)
target << "<span class='warning'>You feel a horribly unpleasant draining sensation as your grip on life weakens...</span>"
icon_state = "revenant_draining"
reveal(30)
stun(30)
reveal(46)
stun(46)
target.visible_message("<span class='warning'>[target] suddenly rises slightly into the air, their skin turning an ashy gray.</span>")
target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=30)
if(target && in_range(src, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=44)
if(do_after(src, 50, 15, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
change_essence_amount(essence_drained, 0, target)
if(essence_drained <= 90 && target.stat != DEAD)
essence_regen_cap += 5
src << "<span class='revenboldnotice'>The absorption of [target]'s living soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap].</span>"
if(essence_drained > 90)
essence_regen_cap += 25
src << "<span class='info'>The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap].</span>"
src << "<span class='info'>[target]'s soul has been considerably weakened and will yield no more essence for the time being.</span>"
essence_regen_cap += 15
perfectsouls += 1
src << "<span class='revenboldnotice'>The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap].</span>"
src << "<span class='revennotice'>[target]'s soul has been considerably weakened and will yield no more essence for the time being.</span>"
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
"<span class='userdanger'>Violets lights, dancing in your vision, getting clo--</span>")
"<span class='revenwarning'>Violets lights, dancing in your vision, getting clo--</span>")
drained_mobs.Add(target)
target.death(0)
else
src << "<span class='warning'>[target] has been drawn out of your grasp. The link has been broken.</span>"
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
"<span class='userdanger'>Violets lights, dancing in your vision, receding--</span>")
icon_state = "revenant_idle"
src << "<span class='revenwarning'>[target ? "[target] has":"They have"] been drawn out of your grasp. The link has been broken.</span>"
draining = 0
essence_drained = 0
if(target) //Wait, target is WHERE NOW?
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
"<span class='revenwarning'>Violets lights, dancing in your vision, receding--</span>")
return
else
src << "<span class='warning'>You are not close enough to siphon [target]'s soul. The link has been broken.</span>"
src << "<span class='revenwarning'>You are not close enough to siphon [target ? "[target]'s":"their"] soul. The link has been broken.</span>"
draining = 0
essence_drained = 0
return
draining = 0
essence_drained = 0
return
@@ -189,7 +221,7 @@
if (istype(M, /mob/new_player))
continue
if(istype(M, /mob/living/simple_animal/revenant) || M.stat == DEAD)
M << "<span class='deadsay'><b>REVENANT: [src]</b> says, \"[message]\"" //Can commune with the dead
M << "<span class='revennotice'><b>[src]</b> says, \"[message]\"" //Can commune with the dead
return
@@ -198,6 +230,7 @@
if(statpanel("Status"))
stat(null, "Current essence: [essence]/[essence_regen_cap]E")
stat(null, "Stolen essence: [essence_accumulated]E")
stat(null, "Stolen perfect souls: [perfectsouls]")
/mob/living/simple_animal/revenant/New()
@@ -225,16 +258,16 @@
src << "<b>Objective #2</b>: [objective2.explanation_text]"
ticker.mode.traitors |= src.mind //Necessary for announcing
AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_light(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/overload(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction(null))
/mob/living/simple_animal/revenant/death()
if(!revealed) //Revenants cannot die if they aren't revealed
return 0
..(1)
src << "<span class='userdanger'>NO! No... it's too late, you can feel your essence breaking apart...</span>"
src << "<span class='revendanger'>NO! No... it's too late, you can feel your essence breaking apart...</span>"
notransform = 1
revealed = 1
invisibility = 0
@@ -255,7 +288,7 @@
/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/weapon/nullrod))
visible_message("<span class='warning'>[src] violently flinches!</span>", \
"<span class='userdanger'>As the null rod passes through you, you feel your essence draining away!</span>")
"<span class='revendanger'>As the null rod passes through you, you feel your essence draining away!</span>")
adjustBruteLoss(25) //hella effective
inhibited = 1
spawn(30)
@@ -267,13 +300,13 @@
return
var/turf/T = get_turf(src)
if(istype(T, /turf/simulated/wall))
src << "<span class='warning'>You cannot use abilities from inside of a wall.</span>"
src << "<span class='revenwarning'>You cannot use abilities from inside of a wall.</span>"
return 0
if(src.inhibited)
src << "<span class='warning'>Your powers have been suppressed by nulling energy!</span>"
src << "<span class='revenwarning'>Your powers have been suppressed by nulling energy!</span>"
return 0
if(!src.change_essence_amount(essence_cost, 1))
src << "<span class='warning'>You lack the essence to use that ability.</span>"
src << "<span class='revenwarning'>You lack the essence to use that ability.</span>"
return 0
return 1
@@ -287,9 +320,9 @@
essence_accumulated = max(0, essence_accumulated+essence_amt)
if(!silent)
if(essence_amt > 0)
src << "<span class='notice'>Gained [essence_amt]E from [source].</span>"
src << "<span class='revennotice'>Gained [essence_amt]E from [source].</span>"
else
src << "<span class='danger'>Lost [essence_amt]E from [source].</span>"
src << "<span class='revenminor'>Lost [essence_amt]E from [source].</span>"
return 1
/datum/objective/revenant
@@ -335,18 +368,18 @@
icon = 'icons/effects/effects.dmi'
icon_state = "revenantEctoplasm"
w_class = 2
var/reforming = 0
var/reforming = 1
var/inert = 0
var/client/client_to_revive
/obj/item/weapon/ectoplasm/revenant/New()
..()
reforming = 1
spawn(600) //1 minute
if(src && reforming)
reforming = 0
return reform()
if(src && !reforming)
reforming = 1
else
inert = 1
visible_message("<span class='warning'>[src] settles down and seems lifeless.</span>")
return
@@ -367,36 +400,39 @@
/obj/item/weapon/ectoplasm/revenant/examine(mob/user)
..()
if(reforming)
user << "<span class='warning'>It is shifting and distorted. It would be wise to destroy this.</span>"
else if(!reforming)
user << "<span class='notice'>It seems inert.</span>"
if(inert)
user << "<span class='revennotice'>It seems inert.</span>"
else if(reforming)
user << "<span class='revenwarning'>It is shifting and distorted. It would be wise to destroy this.</span>"
/obj/item/weapon/ectoplasm/revenant/proc/reform()
if(!reforming || !src)
if(inert || !src)
return
var/key_of_revenant
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and has reformed into a new revenant.")
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.")
loc = get_turf(src) //In case it's in a backpack or someone's hand
visible_message("<span class='boldannounce'>[src] suddenly rises into the air before fading away.</span>")
var/mob/living/simple_animal/revenant/R = new(get_turf(src))
if(client_to_revive)
for(var/mob/M in mob_list)
if(M.client == client_to_revive && M.stat == DEAD) //Only recreates the mob if the mob the client is in is dead
message_admins("[R.client] was a revenant and died. Re-making them into the new revenant formed by ectoplasm.")
for(var/mob/M in dead_mob_list)
if(M.client == client_to_revive) //Only recreates the mob if the mob the client is in is dead
R.client = client_to_revive
key_of_revenant = client_to_revive.key
break
if(!key_of_revenant)
message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
else
var/list/candidates = get_candidates(BE_REVENANT)
var/list/candidates = get_candidates(ROLE_REVENANT)
if(!candidates.len)
qdel(R)
message_admins("No candidates were found for the new revenant. Oh well!")
inert = 1
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return 0
var/client/C = pick(candidates)
key_of_revenant = C.key
if(!key_of_revenant)
qdel(R)
message_admins("No ckey was found for the new revenant. Oh well!")
inert = 1
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return 0
var/datum/mind/player_mind = new /datum/mind(key_of_revenant)
player_mind.active = 1
@@ -404,8 +440,9 @@
player_mind.assigned_role = "revenant"
player_mind.special_role = "Revenant"
ticker.mode.traitors |= player_mind
message_admins("[key_of_revenant] has been made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was spawned as a revenant by reforming ectoplasm.")
message_admins("[key_of_revenant] has been [client_to_revive ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was [client_to_revive ? "re":""]made as a revenant by reforming ectoplasm.")
visible_message("<span class='revenboldnotice'>[src] suddenly rises into the air before fading away.</span>")
qdel(src)
if(src) //Should never happen, but just in case
inert = 1
@@ -1,4 +1,4 @@
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob for 5E.
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob
/obj/effect/proc_holder/spell/targeted/revenant_transmit
name = "Transmit"
desc = "Telepathically transmits a message to the target."
@@ -17,171 +17,174 @@
if(!msg)
charge_counter = charge_max
return
usr << "<span class='info'><b>You transmit to [M]:</b> [msg]</span>"
M << "<span class='deadsay'><b>An alien voice resonates from all around...</b></span><i> [msg]</I>"
usr << "<span class='revennotice'><b>You transmit to [M]:</b> [msg]</span>"
M << "<span class='revennotice'><b>An alien voice resonates from all around...</b></span><i> [msg]</I>"
/obj/effect/proc_holder/spell/aoe_turf/revenant
clothes_req = 0
action_background_icon_state = "bg_revenant"
panel = "Revenant Abilities (Locked)"
name = "Report this to a coder"
var/reveal = 80 //How long it reveals the revenant in deciseconds
var/stun = 20 //How long it stuns the revenant in deciseconds
var/locked = 1 //If it's locked and needs to be unlocked before use
var/unlock_amount = 100 //How much essence it costs to unlock
var/cast_amount = 50 //How much essence it costs to use
/obj/effect/proc_holder/spell/aoe_turf/revenant/New()
..()
if(locked)
name = "[initial(name)] ([unlock_amount]E)"
else
name = "[initial(name)] ([cast_amount]E)"
/obj/effect/proc_holder/spell/aoe_turf/revenant/can_cast(mob/living/simple_animal/revenant/user = usr)
if(user.inhibited)
return 0
if(charge_counter < charge_max)
return 0
if(locked)
if(user.essence <= unlock_amount)
return 0
if(user.essence <= cast_amount)
return 0
return 1
/obj/effect/proc_holder/spell/aoe_turf/revenant/proc/attempt_cast(mob/living/simple_animal/revenant/user = usr)
if(locked)
if(!user.castcheck(-unlock_amount))
charge_counter = charge_max
return 0
name = "[initial(name)] ([cast_amount]E)"
user << "<span class='revennotice'>You have unlocked [initial(name)]!</span>"
panel = "Revenant Abilities"
locked = 0
charge_counter = charge_max
return 0
if(!user.castcheck(-cast_amount))
charge_counter = charge_max
return 0
name = "[initial(name)] ([cast_amount]E)"
user.reveal(reveal)
user.stun(stun)
user.update_action_buttons()
return 1
//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people.
/obj/effect/proc_holder/spell/aoe_turf/revenant_light
name = "Overload Lights (100E)"
/obj/effect/proc_holder/spell/aoe_turf/revenant/overload
name = "Overload Lights"
desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby."
panel = "Revenant Abilities (Locked)"
charge_max = 250
clothes_req = 0
charge_max = 200
range = 5
var/shock_range = 1
var/shock_damage = 20
var/reveal = 80
var/stun = 40
var/locked = 1
stun = 30
cast_amount = 45
var/shock_range = 2
var/shock_damage = 18
action_icon_state = "overload_lights"
action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(locked)
if(!user.castcheck(-100))
charge_counter = charge_max
return
user << "<span class='info'>You have unlocked Overload Lights!</span>"
name = "Overload Lights (50E)"
panel = "Revenant Abilities"
locked = 0
charge_counter = charge_max
return
if(!user.castcheck(-50))
charge_counter = charge_max
return
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/light/L in T.contents)
spawn(0)
if(!L.on)
return
L.visible_message("<span class='warning'><b>\The [L] suddenly flares brightly and begins to spark!</span>")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(4, 0, L)
sleep(10)
s.start()
new/obj/effect/overlay/temp/revenant(L.loc)
sleep(20)
for(var/mob/living/carbon/human/M in range(shock_range, L))
if(M == user)
/obj/effect/proc_holder/spell/aoe_turf/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(attempt_cast(user))
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/light/L in T.contents)
spawn(0)
if(!L.on)
return
spawn(0)
L.visible_message("<span class='warning'><b>\The [L] suddenly flares brightly and begins to spark!</span>")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(4, 0, L)
s.start()
new/obj/effect/overlay/temp/revenant(L.loc)
sleep(20)
if(!L.on) //wait, wait, don't shock me
return
flick("[L.base_state]2", L)
for(var/mob/living/carbon/human/M in view(shock_range, L))
if(M == user)
return
M.Beam(L,icon_state="purple_lightning",icon='icons/effects/effects.dmi',time=5)
M.electrocute_act(shock_damage, "[L.name]", safety=1)
var/datum/effect_system/spark_spread/z = new /datum/effect_system/spark_spread
z.set_up(4, 0, M)
z.start()
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
user.reveal(reveal)
user.stun(stun)
M.electrocute_act(shock_damage, "[L.name]", safety=1)
var/datum/effect_system/spark_spread/z = new /datum/effect_system/spark_spread
z.set_up(4, 0, M)
z.start()
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
//Defile: Corrupts nearby stuff, unblesses floor tiles.
/obj/effect/proc_holder/spell/aoe_turf/revenant_defile
name = "Defile (75E)"
desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors."
panel = "Revenant Abilities (Locked)"
charge_max = 200
clothes_req = 0
/obj/effect/proc_holder/spell/aoe_turf/revenant/defile
name = "Defile"
desc = "Twists and corrupts the nearby area as well as dispelling holy auras on floors."
charge_max = 150
range = 3
var/reveal = 80
var/stun = 20
var/locked = 1
unlock_amount = 75
cast_amount = 40
action_icon_state = "defile"
action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(locked)
if(!user.castcheck(-75))
charge_counter = charge_max
return
user << "<span class='info'>You have unlocked Defile!</span>"
name = "Defile (40E)"
panel = "Revenant Abilities"
locked = 0
charge_counter = charge_max
return
if(!user.castcheck(-40))
charge_counter = charge_max
return
for(var/turf/T in targets)
spawn(0)
if(T.flags & NOJAUNT)
T.flags -= NOJAUNT
new/obj/effect/overlay/temp/revenant(T)
for(var/mob/living/carbon/human/human in T.contents)
human << "<span class='warning'>You suddenly feel tired.</span>"
human.adjustStaminaLoss(40)
new/obj/effect/overlay/temp/revenant(human.loc)
if(!istype(T, /turf/simulated/wall/rust) && !istype(T, /turf/simulated/wall/r_wall) && istype(T, /turf/simulated/wall) && prob(15))
new/obj/effect/overlay/temp/revenant(T)
T.ChangeTurf(/turf/simulated/wall/rust)
if(!istype(T, /turf/simulated/wall/r_wall/rust) && istype(T, /turf/simulated/wall/r_wall) && prob(15))
new/obj/effect/overlay/temp/revenant(T)
T.ChangeTurf(/turf/simulated/wall/r_wall/rust)
for(var/obj/structure/window/window in T.contents)
window.hit(rand(50,100))
if(window && window.fulltile)
new/obj/effect/overlay/temp/revenant/cracks(window.loc)
for(var/obj/machinery/light/light in T.contents)
light.flicker(30) //spooky
user.reveal(reveal)
user.stun(stun)
var/stamdamage= 25
var/toxdamage = 5
var/confusion = 50
/obj/effect/proc_holder/spell/aoe_turf/revenant/defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(attempt_cast(user))
for(var/turf/T in targets)
spawn(0)
if(T.flags & NOJAUNT)
T.flags -= NOJAUNT
new/obj/effect/overlay/temp/revenant(T)
for(var/mob/living/carbon/human/human in T.contents)
human << "<span class='warning'>You suddenly feel [pick("sick and tired", "tired and confused", "nauseated", "dizzy")].</span>"
human.adjustStaminaLoss(stamdamage)
human.adjustToxLoss(toxdamage)
human.confused += confusion
new/obj/effect/overlay/temp/revenant(human.loc)
if(!istype(T, /turf/simulated/wall/shuttle) && !istype(T, /turf/simulated/wall/rust) && !istype(T, /turf/simulated/wall/r_wall) && istype(T, /turf/simulated/wall) && prob(15))
new/obj/effect/overlay/temp/revenant(T)
T.ChangeTurf(/turf/simulated/wall/rust)
if(!istype(T, /turf/simulated/wall/r_wall/rust) && istype(T, /turf/simulated/wall/r_wall) && prob(15))
new/obj/effect/overlay/temp/revenant(T)
T.ChangeTurf(/turf/simulated/wall/r_wall/rust)
for(var/obj/structure/window/window in T.contents)
window.hit(rand(50,90))
if(window && window.fulltile)
new/obj/effect/overlay/temp/revenant/cracks(window.loc)
for(var/obj/machinery/light/light in T.contents)
light.flicker(30) //spooky
//Malfunction: Makes bad stuff happen to robots and machines.
/obj/effect/proc_holder/spell/aoe_turf/revenant_malf
name = "Malfunction (150E)"
/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction
name = "Malfunction"
desc = "Corrupts and damages nearby machines and mechanical objects."
panel = "Revenant Abilities (Locked)"
charge_max = 250
clothes_req = 0
charge_max = 200
range = 4
var/reveal = 80
var/stun = 20
var/locked = 1
unlock_amount = 150
action_icon_state = "malfunction"
action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/aoe_turf/revenant_malf/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(locked)
if(!user.castcheck(-150))
charge_counter = charge_max
return
user << "<span class='info'>You have unlocked Malfunction!</span>"
name = "Malfunction (40E)"
panel = "Revenant Abilities"
locked = 0
charge_counter = charge_max
return
if(!user.castcheck(-40))
charge_counter = charge_max
return
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/bot/bot in T.contents)
if(!bot.emagged)
new/obj/effect/overlay/temp/revenant(bot.loc)
bot.locked = 0
bot.open = 1
bot.Emag(null)
for(var/obj/machinery/mach in T.contents)
if(istype(mach, /obj/machinery/dominator) || istype(mach, /obj/machinery/power/apc) || istype(mach, /obj/machinery/power/smes) || istype(mach, /obj/machinery/bot)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery //Also doesn't work on bots so they can go do stuff faster(god this is so ugly)
continue
if(prob(30))
new/obj/effect/overlay/temp/revenant(mach.loc)
mach.emag_act(null)
else
if(istype(mach, /obj/machinery/clonepod)) //I hate everything but mostly the fact there's no better way to do this without just not affecting it at all
mach.emp_act(1)
for(var/mob/living/silicon/robot/S in T.contents) //Only works on cyborgs, not AI
S << "<span class='warning'><b>ERROR $!(@ ERROR )#^! SENSORY OVERLOAD \[$(!@#</b></span>"
S << 'sound/misc/interference.ogg'
playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1)
new/obj/effect/overlay/temp/revenant(S.loc)
S.spark_system.start()
S.Weaken(6)
user.reveal(reveal)
user.stun(stun)
//A note to future coders: do not replace this with an EMP because it will wreck malf AIs and gang dominators and everyone will hate you.
/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(attempt_cast(user))
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/bot/bot in T.contents)
if(!bot.emagged)
new/obj/effect/overlay/temp/revenant(bot.loc)
bot.locked = 0
bot.open = 1
bot.Emag(null)
for(var/mob/living/carbon/human/human in T.contents)
human << "<span class='warning'>You feel [pick("your sense of direction flicker out", "a stabbing pain in your head", "your mind fill with static")].</span>"
new/obj/effect/overlay/temp/revenant(human.loc)
human.emp_act(1)
for(var/obj/thing in T.contents)
if(istype(thing, /obj/machinery/dominator) || istype(thing, /obj/machinery/power/apc) || istype(thing, /obj/machinery/power/smes) || istype(thing, /obj/machinery/bot)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery
continue
if(prob(20))
if(prob(50))
new/obj/effect/overlay/temp/revenant(thing.loc)
thing.emag_act(null)
else
if(!istype(thing, /obj/machinery/clonepod)) //I hate everything but mostly the fact there's no better way to do this without just not affecting it at all
thing.emp_act(1)
for(var/mob/living/silicon/robot/S in T.contents) //Only works on cyborgs, not AI
playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1)
new/obj/effect/overlay/temp/revenant(S.loc)
S.spark_system.start()
S.emp_act(1)
@@ -21,7 +21,7 @@
return
key_of_revenant = null
if(!key_of_revenant)
var/list/candidates = get_candidates(BE_REVENANT)
var/list/candidates = get_candidates(ROLE_REVENANT)
if(!candidates.len)
if(end_if_fail)
return 0
@@ -370,11 +370,11 @@
..()
/mob/living/simple_animal/movement_delay()
var/tally = 0 //Incase I need to add stuff other than "speed" later
. = ..()
tally = speed
. = speed
return tally+config.animal_delay
. += config.animal_delay
/mob/living/simple_animal/Stat()
..()
@@ -431,6 +431,7 @@
/mob/living/simple_animal/revive()
health = maxHealth
icon = initial(icon)
icon_state = icon_living
density = initial(density)
update_canmove()
@@ -15,7 +15,7 @@
/datum/round_event/slaughter/proc/get_slaughter(end_if_fail = 0)
key_of_slaughter = null
if(!key_of_slaughter)
var/list/candidates = get_candidates(BE_ALIEN)
var/list/candidates = get_candidates(ROLE_ALIEN)
if(!candidates.len)
if(end_if_fail)
return 0
@@ -9,6 +9,8 @@
M.regenerate_icons()
is_adult = 0
maxHealth = 150
var/datum/action/innate/slime/evolve/E = new
E.Grant(src)
revive()
regenerate_icons()
number = rand(1, 1000)
@@ -33,3 +35,10 @@
/mob/living/simple_animal/slime/gib()
death(1)
qdel(src)
/mob/living/simple_animal/slime/Destroy()
for(var/obj/machinery/computer/camera_advanced/xenobio/X in machines)
if(src in X.stored_slimes)
X.stored_slimes -= src
return ..()
@@ -222,11 +222,11 @@
if(prob(75))
adjustBruteLoss(rand(0,5))
else if (nutrition >= get_grow_nutrition() && amount_grown < 10)
else if (nutrition >= get_grow_nutrition() && amount_grown < SLIME_EVOLUTION_THRESHOLD)
nutrition -= 20
amount_grown++
if(amount_grown >= 10 && !buckled && !Target && !ckey)
if(amount_grown >= SLIME_EVOLUTION_THRESHOLD && !buckled && !Target && !ckey)
if(is_adult)
Reproduce()
else
@@ -1,3 +1,36 @@
#define SIZE_DOESNT_MATTER -1
#define BABIES_ONLY 0
#define ADULTS_ONLY 1
#define NO_GROWTH_NEEDED 0
#define GROWTH_NEEDED 1
/datum/action/innate/slime
check_flags = AB_CHECK_ALIVE
background_icon_state = "bg_alien"
var/adult_action = SIZE_DOESNT_MATTER
var/needs_growth = NO_GROWTH_NEEDED
/datum/action/innate/slime/CheckRemoval()
if(!isslime(owner))
return 1
var/mob/living/simple_animal/slime/S = owner
if(adult_action != SIZE_DOESNT_MATTER)
if(adult_action == ADULTS_ONLY && !S.is_adult)
return 1
else if(adult_action == BABIES_ONLY && S.is_adult)
return 1
return 0
/datum/action/innate/slime/IsAvailable()
if(..())
var/mob/living/simple_animal/slime/S = owner
if(needs_growth == GROWTH_NEEDED)
if(S.amount_grown >= SLIME_EVOLUTION_THRESHOLD)
return 1
return 0
return 1
/mob/living/simple_animal/slime/verb/Feed()
set category = "Slime"
set desc = "This will let you feed on any valid creature in the surrounding area. This should also be used to halt the feeding process."
@@ -16,6 +49,15 @@
Feedon(M)
return 1
/datum/action/innate/slime/feed
name = "Feed"
button_icon_state = "slimeeat"
/datum/action/innate/slime/feed/Activate()
var/mob/living/simple_animal/slime/S = owner
S.Feed()
/mob/living/simple_animal/slime/proc/CanFeedon(mob/living/M)
if(!Adjacent(M))
return 0
@@ -46,6 +88,7 @@
return 1
/mob/living/simple_animal/slime/proc/Feedon(mob/living/M)
M.unbuckle_mob(force=1) //Slimes rip other mobs (eg: shoulder parrots) off (Slimes Vs Slimes is already handled in CanFeedon())
if(M.buckle_mob(src, force=1))
M.visible_message("<span class='danger'>The [name] has latched onto [M]!</span>", \
"<span class='userdanger'>The [name] has latched onto [M]!</span>")
@@ -67,7 +110,7 @@
src << "<i>I must be conscious to do this...</i>"
return
if(!is_adult)
if(amount_grown >= 10)
if(amount_grown >= SLIME_EVOLUTION_THRESHOLD)
is_adult = 1
maxHealth = 200
amount_grown = 0
@@ -78,6 +121,19 @@
else
src << "<i>I have already evolved...</i>"
/datum/action/innate/slime/evolve
name = "Evolve"
button_icon_state = "slimegrow"
adult_action = BABIES_ONLY
needs_growth = GROWTH_NEEDED
/datum/action/innate/slime/evolve/Activate()
var/mob/living/simple_animal/slime/S = owner
S.Evolve()
if(S.is_adult)
var/datum/action/innate/slime/reproduce/A = new
A.Grant(S)
/mob/living/simple_animal/slime/verb/Reproduce()
set category = "Slime"
set desc = "This will make you split into four Slimes."
@@ -87,7 +143,7 @@
return
if(is_adult)
if(amount_grown >= 10)
if(amount_grown >= SLIME_EVOLUTION_THRESHOLD)
if(stat)
src << "<i>I must be conscious to do this...</i>"
return
@@ -122,4 +178,14 @@
else
src << "<i>I am not ready to reproduce yet...</i>"
else
src << "<i>I am not old enough to reproduce yet...</i>"
src << "<i>I am not old enough to reproduce yet...</i>"
/datum/action/innate/slime/reproduce
name = "Reproduce"
button_icon_state = "slimesplit"
adult_action = ADULTS_ONLY
needs_growth = GROWTH_NEEDED
/datum/action/innate/slime/reproduce/Activate()
var/mob/living/simple_animal/slime/S = owner
S.Reproduce()
@@ -70,9 +70,16 @@
var/list/slime_mutation[4]
/mob/living/simple_animal/slime/New()
var/datum/action/innate/slime/feed/F = new
F.Grant(src)
if(is_adult)
var/datum/action/innate/slime/reproduce/R = new
R.Grant(src)
health = 200
maxHealth = 200
else
var/datum/action/innate/slime/evolve/E = new
E.Grant(src)
create_reagents(100)
spawn (0)
number = rand(1, 1000)
@@ -101,26 +108,26 @@
if(bodytemperature >= 330.23) // 135 F
return -1 // slimes become supercharged at high temperatures
var/tally = 0
. = ..()
var/health_deficiency = (100 - health)
if(health_deficiency >= 45)
tally += (health_deficiency / 25)
. += (health_deficiency / 25)
if(bodytemperature < 183.222)
tally += (283.222 - bodytemperature) / 10 * 1.75
. += (283.222 - bodytemperature) / 10 * 1.75
if(reagents)
if(reagents.has_reagent("morphine")) // morphine slows slimes down
tally *= 2
. *= 2
if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow
tally *= 5
. *= 5
if(health <= 0) // if damaged, the slime moves twice as slow
tally *= 2
. *= 2
return tally + config.slime_delay
. += config.slime_delay
/mob/living/simple_animal/slime/ObjBump(obj/O)
if(!client && powerlevel > 0)
@@ -149,7 +156,7 @@
if(!docile)
stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]")
if(amount_grown >= 10)
if(amount_grown >= SLIME_EVOLUTION_THRESHOLD)
if(is_adult)
stat(null, "You can reproduce!")
else
@@ -298,9 +305,6 @@
discipline_slime(user)
..()
/mob/living/simple_animal/slime/show_inv(mob/user)
return
/mob/living/simple_animal/slime/proc/apply_water()
adjustBruteLoss(rand(15,20))
if(!client)
+4 -1
View File
@@ -51,10 +51,13 @@
//readd this mob's HUDs (antag, med, etc)
reload_huds()
if(ckey in deadmins)
verbs += /client/proc/readmin
client.screen += client.void
add_click_catcher()
sync_mind()
// Calling update_interface() in /mob/Login() causes the Cyborg to immediately be ghosted; because of winget().
// Calling it in the overriden Login, such as /mob/living/Login() doesn't cause this.
+25 -15
View File
@@ -24,7 +24,7 @@ var/next_mob_id = 0
prepare_huds()
..()
/mob/proc/prepare_huds()
/atom/proc/prepare_huds()
for(var/hud in hud_possible)
hud_list[hud] = image('icons/mob/hud.dmi', src, "")
@@ -325,17 +325,7 @@ var/list/slot_equipment_priority = list( \
/mob/proc/show_inv(mob/user)
user.set_machine(src)
var/dat = {"
<HR>
<B><FONT size=3>[name]</FONT></B>
<HR>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=[slot_l_hand]'> [(l_hand&&!(l_hand.flags&ABSTRACT)) ? l_hand : "Nothing"]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=[slot_r_hand]'> [(r_hand&&!(r_hand.flags&ABSTRACT)) ? r_hand : "Nothing"]</A>
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
"}
user << browse(dat, "window=mob\ref[src];size=325x500")
onclose(user, "mob\ref[src]")
return
//mob verbs are faster than object verbs. See http://www.byond.com/forum/?post=1326139&page=2#comment8198716 for why this isn't atom/verb/examine()
/mob/verb/examinate(atom/A as mob|obj|turf in view()) //It used to be oview(12), but I can't really say why
@@ -949,10 +939,10 @@ var/list/slot_equipment_priority = list( \
return G
break
/mob/proc/notify_ghost_cloning(var/message = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!", var/sound = 'sound/effects/genetics.ogg')
/mob/proc/notify_ghost_cloning(var/message = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!", var/sound = 'sound/effects/genetics.ogg', var/atom/source = null)
var/mob/dead/observer/ghost = get_ghost()
if(ghost)
ghost.notify_cloning(message, sound)
ghost.notify_cloning(message, sound, source)
return ghost
@@ -1019,4 +1009,24 @@ var/list/slot_equipment_priority = list( \
//can the mob be unbuckled from something by default?
/mob/proc/can_unbuckle()
return 1
return 1
//Can the mob see reagents inside of containers?
/mob/proc/can_see_reagents()
if(stat == DEAD) //Ghosts and such can always see reagents
return 1
if(has_unlimited_silicon_privilege) //Silicons can automatically view reagents
return 1
if(ishuman(src))
var/mob/living/carbon/human/H = src
if(H.head && istype(H.head, /obj/item/clothing))
var/obj/item/clothing/CL = H.head
if(CL.scan_reagents)
return 1
if(H.wear_mask && H.wear_mask.scan_reagents)
return 1
if(H.glasses && istype(H.glasses, /obj/item/clothing))
var/obj/item/clothing/CL = H.glasses
if(CL.scan_reagents)
return 1
return 0
+4 -5
View File
@@ -6,6 +6,7 @@
hud_possible = list(ANTAG_HUD)
pressure_resistance = 8
var/datum/mind/mind
var/list/datum/action/actions = list()
var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak
@@ -49,8 +50,6 @@
var/stuttering = null //Carbon
var/slurring = 0 //Carbon
var/real_name = null
var/bhunger = 0 //Carbon
var/ajourn = 0
var/druggy = 0 //Carbon
var/confused = 0 //Carbon
var/sleeping = 0 //Carbon
@@ -94,7 +93,7 @@
var/datum/hud/hud_used = null
var/research_scanner = 0 //For research scanner equipped mobs. Enable to show research data when examining.
var/datum/action/scan_mode/scanner = new
var/datum/action/innate/scan_mode/scanner = new
var/list/grabbed_by = list( )
var/list/requests = list( )
@@ -136,8 +135,6 @@
var/status_flags = CANSTUN|CANWEAKEN|CANPARALYSE|CANPUSH //bitflags defining which status effects can be inflicted (replaces canweaken, canstun, etc)
var/area/lastarea = null
var/digitalcamo = 0 // Can they be tracked by the AI?
var/digitalinvis = 0 //Are they ivisible to the AI?
var/image/digitaldisguise = null //what does the AI see instead of them?
@@ -151,6 +148,8 @@
var/obj/control_object //Used by admins to possess objects. All mobs should have this var
var/atom/movable/remote_control //Calls relaymove() to whatever it is
var/remote_view = 0 // Set to 1 to prevent view resets on Life
var/turf/listed_turf = null //the current turf being examined in the stat panel
var/list/permanent_huds = list()
+17 -137
View File
@@ -1,139 +1,5 @@
// fun if you want to typecast humans/monkeys/etc without writing long path-filled lines.
/proc/ishuman(A)
if(istype(A, /mob/living/carbon/human))
return 1
return 0
/proc/ismonkey(A)
if(A && istype(A, /mob/living/carbon/monkey))
return 1
return 0
/proc/isbrain(A)
if(A && istype(A, /mob/living/carbon/brain))
return 1
return 0
/proc/isalien(A)
if(istype(A, /mob/living/carbon/alien))
return 1
return 0
/proc/isalienadult(A)
if(istype(A, /mob/living/carbon/alien/humanoid))
return 1
return 0
/proc/islarva(A)
if(istype(A, /mob/living/carbon/alien/larva))
return 1
return 0
/proc/isslime(A)
if(istype(A, /mob/living/simple_animal/slime))
return 1
return 0
/proc/isrobot(A)
if(istype(A, /mob/living/silicon/robot))
return 1
return 0
/proc/isanimal(A)
if(istype(A, /mob/living/simple_animal))
return 1
return 0
/proc/iscorgi(A)
if(istype(A, /mob/living/simple_animal/pet/dog/corgi))
return 1
return 0
/proc/iscrab(A)
if(istype(A, /mob/living/simple_animal/crab))
return 1
return 0
/proc/iscat(A)
if(istype(A, /mob/living/simple_animal/pet/cat))
return 1
return 0
/proc/ismouse(A)
if(istype(A, /mob/living/simple_animal/mouse))
return 1
return 0
/proc/isbear(A)
if(istype(A, /mob/living/simple_animal/hostile/bear))
return 1
return 0
/proc/iscarp(A)
if(istype(A, /mob/living/simple_animal/hostile/carp))
return 1
return 0
/proc/isclown(A)
if(istype(A, /mob/living/simple_animal/hostile/retaliate/clown))
return 1
return 0
/proc/isAI(A)
if(istype(A, /mob/living/silicon/ai))
return 1
return 0
/proc/ispAI(A)
if(istype(A, /mob/living/silicon/pai))
return 1
return 0
/proc/iscarbon(A)
if(istype(A, /mob/living/carbon))
return 1
return 0
/proc/issilicon(A)
if(istype(A, /mob/living/silicon))
return 1
return 0
/proc/isliving(A)
if(istype(A, /mob/living))
return 1
return 0
/proc/isobserver(A)
if(istype(A, /mob/dead/observer))
return 1
return 0
/proc/isnewplayer(A)
if(istype(A, /mob/new_player))
return 1
return 0
/proc/isovermind(A)
if(istype(A, /mob/camera/blob))
return 1
return 0
/proc/isdrone(A)
if(istype(A, /mob/living/simple_animal/drone))
return 1
return 0
/proc/isswarmer(A)
if(istype(A, /mob/living/simple_animal/hostile/swarmer))
return 1
return 0
/proc/islimb(A)
if(istype(A, /obj/item/organ/limb))
return 1
return 0
// see _DEFINES/is_helpers.dm for mob type checks
/proc/isloyal(A) //Checks to see if the person contains a loyalty implant, then checks that the implant is actually inside of them
for(var/obj/item/weapon/implant/loyalty/L in A)
@@ -460,12 +326,26 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
/mob/proc/reagent_check(datum/reagent/R) // utilized in the species code
return 1
/proc/notify_ghosts(var/message, var/ghost_sound = null) //Easy notification of ghosts.
/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/image/alert_overlay = null, var/attack_not_jump = 0) //Easy notification of ghosts.
for(var/mob/dead/observer/O in player_list)
if(O.client)
O << "<span class='ghostalert'>[message]<span>"
O << "<span class='ghostalert'>[message][(enter_link) ? " [enter_link]" : ""]<span>"
if(ghost_sound)
O << sound(ghost_sound)
if(source)
var/obj/screen/alert/notify_jump/A = O.throw_alert("\ref[source]_notify_jump", /obj/screen/alert/notify_jump)
if(A)
A.desc = message
A.attack_not_jump = attack_not_jump
A.jump_target = source
if(!alert_overlay)
var/old_layer = source.layer
source.layer = FLOAT_LAYER
A.overlays += source
source.layer = old_layer
else
alert_overlay.layer = FLOAT_LAYER
A.overlays += alert_overlay
/proc/item_heal_robotic(mob/living/carbon/human/H, mob/user, brute, burn)
var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_sel.selecting))
+59 -82
View File
@@ -92,7 +92,7 @@
/client/Move(n, direct)
if(!mob)
if(!mob || !mob.loc)
return 0
if(mob.notransform)
return 0 //This is sota the goto stop mobs from moving var
@@ -127,10 +127,6 @@
if(!mob.canmove)
return 0
if(!mob.lastarea)
mob.lastarea = get_area(mob.loc)
if(isobj(mob.loc) || ismob(mob.loc)) //Inside an object, tell it we moved
var/atom/O = mob.loc
return O.relaymove(mob, direct)
@@ -138,89 +134,70 @@
if(!mob.Process_Spacemove(direct))
return 0
if(isturf(mob.loc))
var/turf/T = mob.loc
move_delay = world.time//set move delay
move_delay += T.slowdown
if(mob.restrained()) //Why being pulled while cuffed prevents you from moving
for(var/mob/M in range(1, mob))
if(M.pulling == mob)
if(!M.incapacitated() && mob.Adjacent(M))
src << "<span class='warning'>You're restrained! You can't move!</span>"
move_delay += 10
return 0
else
M.stop_pulling()
switch(mob.m_intent)
if("run")
if(mob.drowsyness > 0)
move_delay += 6
move_delay += config.run_speed
if("walk")
move_delay += config.walk_speed
move_delay += mob.movement_delay()
if(config.Tickcomp)
move_delay -= 1.3
var/tickcomp = (1 / (world.tick_lag)) * 1.3
move_delay = move_delay + tickcomp
//We are now going to move
moving = 1
//Something with pulling things
if(locate(/obj/item/weapon/grab, mob))
move_delay = max(move_delay, world.time + 7)
var/list/L = mob.ret_grab()
if(istype(L, /list))
if(L.len == 2)
L -= mob
var/mob/M = L[1]
if(M)
if ((get_dist(mob, M) <= 1 || M.loc == mob.loc))
. = ..()
if (isturf(M.loc))
var/diag = get_dir(mob, M)
if ((diag - 1) & diag)
else
diag = null
if ((get_dist(mob, M) > 1 || diag))
step(M, get_dir(M.loc, T))
if(mob.restrained()) //Why being pulled while cuffed prevents you from moving
for(var/mob/M in orange(1, mob))
if(M.pulling == mob)
if(!M.incapacitated() && mob.Adjacent(M))
src << "<span class='warning'>You're restrained! You can't move!</span>"
move_delay = world.time + 10
return 0
else
for(var/mob/M in L)
M.other_mobs = 1
if(mob != M)
M.animate_movement = 3
for(var/mob/M in L)
spawn( 0 )
step(M, direct)
return
spawn( 1 )
M.other_mobs = null
M.animate_movement = 2
return
M.stop_pulling()
if(mob.confused)
if(mob.confused > 40)
step(mob, pick(cardinal))
else if(prob(mob.confused * 1.5))
step(mob, angle2dir(dir2angle(direct) + pick(90, -90)))
else if(prob(mob.confused * 3))
step(mob, angle2dir(dir2angle(direct) + pick(45, -45)))
//We are now going to move
moving = 1
move_delay = mob.movement_delay() + world.time
//Something with pulling things
if(locate(/obj/item/weapon/grab, mob))
move_delay = max(move_delay, world.time + 7)
var/list/L = mob.ret_grab()
if(istype(L, /list))
if(L.len == 2)
L -= mob
var/mob/M = L[1]
if(M)
if ((get_dist(mob, M) <= 1 || M.loc == mob.loc))
. = ..()
if (isturf(M.loc))
var/diag = get_dir(mob, M)
if ((diag - 1) & diag)
else
diag = null
if ((get_dist(mob, M) > 1 || diag))
step(M, get_dir(M.loc, mob.loc))
else
step(mob, direct)
for(var/mob/M in L)
M.other_mobs = 1
if(mob != M)
M.animate_movement = 3
for(var/mob/M in L)
spawn( 0 )
step(M, direct)
return
spawn( 1 )
M.other_mobs = null
M.animate_movement = 2
return
if(mob.confused)
if(mob.confused > 40)
step(mob, pick(cardinal))
else if(prob(mob.confused * 1.5))
step(mob, angle2dir(dir2angle(direct) + pick(90, -90)))
else if(prob(mob.confused * 3))
step(mob, angle2dir(dir2angle(direct) + pick(45, -45)))
else
. = ..()
step(mob, direct)
else
. = ..()
moving = 0
if(mob && .)
mob.throwing = 0
moving = 0
if(mob && .)
mob.throwing = 0
return .
return .
///Process_Grab()
+3 -5
View File
@@ -1,5 +1,6 @@
/mob/new_player/Login()
update_Login_details() //handles setting lastKnownIP and computer_id for use by the ban systems as well as checking for multikeying
..()
if(join_motd)
src << "<div class=\"motd\">[join_motd]</div>"
@@ -18,10 +19,8 @@
loc = pick(newplayer_start)
else
loc = locate(1,1,1)
lastarea = loc
sight |= SEE_TURFS
player_list |= src
/*
var/list/watch_locations = list()
@@ -33,8 +32,7 @@
loc = pick(watch_locations)
*/
new_player_panel()
if(ckey in deadmins)
verbs += /client/proc/readmin
spawn(40)
if(client)
client.playtitlemusic()
+4 -3
View File
@@ -116,7 +116,10 @@
close_spawn_windows()
var/obj/O = locate("landmark*Observer-Start")
src << "<span class='notice'>Now teleporting.</span>"
observer.loc = O.loc
if (O)
observer.loc = O.loc
else
src << "<span class='notice'>Teleporting failed. You should be able to use ghost verbs to teleport somewhere useful</span>"
if(client.prefs.be_random_name)
client.prefs.real_name = random_unique_name(gender)
if(client.prefs.be_random_body)
@@ -279,7 +282,6 @@
continue
character.loc = D
character.lastarea = get_area(loc)
if(character.mind.assigned_role != "Cyborg")
data_core.manifest_inject(character)
@@ -361,7 +363,6 @@
close_spawn_windows()
var/mob/living/carbon/human/new_character = new(loc)
new_character.lastarea = get_area(loc)
if(config.force_random_names || appearance_isbanned(src))
client.prefs.random_character()
+17
View File
@@ -433,6 +433,23 @@
gib(src)
/mob/proc/become_god(var/side_colour)
var/mob/camera/god/G = new /mob/camera/god(loc)
G.side = side_colour
G.invisibility = 40
if(mind)
mind.transfer_to(G)
else
G.key = key
G.job = "Deity"
G.rename_self("deity", 0)
G.update_icons()
. = G
qdel(src)
/mob/living/carbon/human/proc/corgize()
if (notransform)