Tg port 2 15 (#230)
* defines/helpers * globalvars, onclick, controllers * datums and game * woooooooooorld. Uh. dm * modules sans mobs client admin * modules/admin * pref shit * modules/mob * icon updates * extra things * Cherrypicked fixes from open PRs * metastation.tgm fix * a better meta fix * reverts async breakings
This commit is contained in:
@@ -299,7 +299,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
/mob/dead/observer/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
stat(null, "Station Time: [worldtime2text()]")
|
||||
if(ticker && ticker.mode)
|
||||
for(var/datum/gang/G in ticker.mode.gangs)
|
||||
if(G.is_dominating)
|
||||
@@ -328,7 +327,9 @@ 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, var/atom/source)
|
||||
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source, flashwindow = TRUE)
|
||||
if(flashwindow)
|
||||
window_flash(client)
|
||||
if(message)
|
||||
src << "<span class='ghostalert'>[message]</span>"
|
||||
if(source)
|
||||
|
||||
@@ -148,15 +148,16 @@
|
||||
/mob/proc/can_equip(obj/item/I, slot, disable_warning = 0)
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/proc/put_in_hand(obj/item/I, hand_index)
|
||||
/mob/proc/can_put_in_hand(I, hand_index)
|
||||
if(!put_in_hand_check(I))
|
||||
return FALSE
|
||||
if(!has_hand_for_held_index(hand_index))
|
||||
return FALSE
|
||||
var/obj/item/curr = held_items[hand_index]
|
||||
if(!curr)
|
||||
I.loc = src
|
||||
return !held_items[hand_index]
|
||||
|
||||
/mob/proc/put_in_hand(obj/item/I, hand_index)
|
||||
if(can_put_in_hand(I, hand_index))
|
||||
I.forceMove(src)
|
||||
held_items[hand_index] = I
|
||||
I.layer = ABOVE_HUD_LAYER
|
||||
I.plane = ABOVE_HUD_PLANE
|
||||
@@ -255,6 +256,17 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/mob/proc/putItemFromInventoryInHandIfPossible(obj/item/I, hand_index, force_removal = FALSE)
|
||||
if(!can_put_in_hand(I, hand_index))
|
||||
return FALSE
|
||||
if(!temporarilyRemoveItemFromInventory(I, force_removal))
|
||||
return FALSE
|
||||
I.remove_item_from_storage(src)
|
||||
if(!put_in_hand(I, hand_index))
|
||||
qdel(I)
|
||||
CRASH("Assertion failure: putItemFromInventoryInHandIfPossible") //should never be possible
|
||||
return TRUE
|
||||
|
||||
//The following functions are the same save for one small difference
|
||||
|
||||
//for when you want the item to end up on the ground
|
||||
|
||||
@@ -37,7 +37,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/ping_ghosts(msg, newlymade)
|
||||
if(newlymade || !posibrain_notif_cooldown)
|
||||
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/effects/ghost2.ogg':null, enter_link = "<a href=?src=\ref[src];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK)
|
||||
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/effects/ghost2.ogg':null, enter_link = "<a href=?src=\ref[src];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK, flashwindow = FALSE)
|
||||
if(!newlymade)
|
||||
posibrain_notif_cooldown = 1
|
||||
addtimer(CALLBACK(src, .proc/reset_posibrain_cooldown), askDelay)
|
||||
|
||||
@@ -212,6 +212,12 @@
|
||||
if(lying)
|
||||
M.visible_message("<span class='notice'>[M] shakes [src] trying to get [p_them()] up!</span>", \
|
||||
"<span class='notice'>You shake [src] trying to get [p_them()] up!</span>")
|
||||
|
||||
else if(check_zone(M.zone_selected) == "head")
|
||||
M.visible_message("<span class='notice'>[M] gives [src] a pat on the head to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You give [src] a pat on the head to make [p_them()] feel better!</span>")
|
||||
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || (dna.features["tail_human"] != "None") || ("mam_tail" in dna.species.mutant_bodyparts)))
|
||||
emote("wag") //lewd
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
|
||||
@@ -305,4 +311,3 @@
|
||||
hit_clothes = head
|
||||
if(hit_clothes)
|
||||
hit_clothes.take_damage(damage_amount, damage_type, damage_flag, 0)
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
key_third_person = "screeches"
|
||||
message = "screeches."
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/living/carbon/sign
|
||||
key = "sign"
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
if(prob(martial_art.deflection_chance))
|
||||
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
|
||||
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
|
||||
playsound(src, pick("sound/weapons/bulletflyby.ogg","sound/weapons/bulletflyby2.ogg","sound/weapons/bulletflyby3.ogg"), 75, 1)
|
||||
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
|
||||
return 0
|
||||
|
||||
if(!(P.original == src && P.firer == src)) //can't block or reflect when shooting yourself
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
punchdamagehigh = 30//they are inhumanly strong
|
||||
punchstunthreshold = 25
|
||||
attack_verb = "smash"
|
||||
attack_sound = "sound/weapons/resonator_blast.ogg"
|
||||
attack_sound = 'sound/weapons/resonator_blast.ogg'
|
||||
blacklisted = 1
|
||||
use_skintones = 0
|
||||
species_traits = list(RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR,NODISMEMBER,NOHUNGER)
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
meat = /obj/item/weapon/ore/iron
|
||||
info_text = "As a <span class='danger'>Plasteel Golem</span>, you are slower, but harder to stun, and hit very hard when punching."
|
||||
attack_verb = "smash"
|
||||
attack_sound = "sound/effects/meteorimpact.ogg" //hits pretty hard
|
||||
attack_sound = 'sound/effects/meteorimpact.ogg' //hits pretty hard
|
||||
|
||||
//Immune to ash storms
|
||||
/datum/species/golem/titanium
|
||||
@@ -231,7 +231,7 @@
|
||||
burnmod = 3 //melts easily
|
||||
brutemod = 0.25
|
||||
info_text = "As a <span class='danger'>Sand Golem</span>, you are immune to physical bullets and take very little brute damage, but are extremely vulnerable to burn damage. You will also turn to sand when dying, preventing any form of recovery."
|
||||
attack_sound = "sound/effects/shovel_dig.ogg"
|
||||
attack_sound = 'sound/effects/shovel_dig.ogg'
|
||||
|
||||
/datum/species/golem/sand/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
H.visible_message("<span class='danger'>[H] turns into a pile of sand!</span>")
|
||||
@@ -244,7 +244,7 @@
|
||||
/datum/species/golem/sand/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
if(!(P.original == H && P.firer == H))
|
||||
if(P.flag == "bullet" || P.flag == "bomb")
|
||||
playsound(H, "sound/effects/shovel_dig.ogg", 70, 1)
|
||||
playsound(H, 'sound/effects/shovel_dig.ogg', 70, 1)
|
||||
H.visible_message("<span class='danger'>The [P.name] sinks harmlessly in [H]'s sandy body!</span>", \
|
||||
"<span class='userdanger'>The [P.name] sinks harmlessly in [H]'s sandy body!</span>")
|
||||
return 2
|
||||
@@ -260,7 +260,7 @@
|
||||
brutemod = 3 //very fragile
|
||||
burnmod = 0.25
|
||||
info_text = "As a <span class='danger'>Glass Golem</span>, you reflect lasers and energy weapons, and are very resistant to burn damage, but you are extremely vulnerable to brute damage. On death, you'll shatter beyond any hope of recovery."
|
||||
attack_sound = "sound/effects/Glassbr2.ogg"
|
||||
attack_sound = 'sound/effects/Glassbr2.ogg'
|
||||
|
||||
/datum/species/golem/glass/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
playsound(H, "shatter", 70, 1)
|
||||
@@ -300,7 +300,7 @@
|
||||
meat = /obj/item/weapon/ore/bluespace_crystal
|
||||
info_text = "As a <span class='danger'>Bluespace Golem</span>, are spatially unstable: you will teleport when hit, and you can teleport manually at a long distance."
|
||||
attack_verb = "bluespace punch"
|
||||
attack_sound = "sound/effects/phasein.ogg"
|
||||
attack_sound = 'sound/effects/phasein.ogg'
|
||||
|
||||
var/datum/action/innate/unstable_teleport/unstable_teleport
|
||||
var/teleport_cooldown = 100
|
||||
@@ -393,7 +393,7 @@
|
||||
meat = /obj/item/weapon/ore/bananium
|
||||
info_text = "As a <span class='danger'>Bananium Golem</span>, you are made for pranking. Your body emits natural honks, and you cannot hurt people when punching them. Your skin also emits bananas when damaged."
|
||||
attack_verb = "honk"
|
||||
attack_sound = "sound/items/AirHorn2.ogg"
|
||||
attack_sound = 'sound/items/AirHorn2.ogg'
|
||||
|
||||
var/last_honk = 0
|
||||
var/honkooldown = 0
|
||||
|
||||
@@ -10,8 +10,8 @@ var/global/image/plasmaman_on_fire = image("icon"='icons/mob/OnFire.dmi', "icon_
|
||||
mutantlungs = /obj/item/organ/lungs/plasmaman
|
||||
dangerous_existence = 1 //So so much
|
||||
blacklisted = 1 //See above
|
||||
burnmod = 2
|
||||
heatmod = 2
|
||||
burnmod = 1.5
|
||||
heatmod = 1.5
|
||||
breathid = "tox"
|
||||
speedmod = 1
|
||||
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
if(dir & (EAST|WEST)) //Facing east or west
|
||||
final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass
|
||||
|
||||
lying_prev = lying //so we don't try to animate until there's been another change.
|
||||
if(resize != RESIZE_DEFAULT_SIZE)
|
||||
changed++
|
||||
ntransform.Scale(resize)
|
||||
|
||||
@@ -462,5 +462,6 @@
|
||||
user.spin(20, 1)
|
||||
if(istype(user, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
R.riding_datum.force_dismount()
|
||||
if(R.riding_datum)
|
||||
R.riding_datum.force_dismount()
|
||||
..()
|
||||
@@ -608,7 +608,7 @@
|
||||
if(!override)
|
||||
float(!has_gravity)
|
||||
|
||||
/mob/living/proc/float(on)
|
||||
/mob/living/float(on)
|
||||
if(throwing)
|
||||
return
|
||||
var/fixed = 0
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
var/ventcrawler = 0 //0 No vent crawling, 1 vent crawling in the nude, 2 vent crawling always
|
||||
var/limb_destroyer = 0 //1 Sets AI behavior that allows mobs to target and dismember limbs with their basic attack.
|
||||
|
||||
var/floating = 0
|
||||
var/mob_size = MOB_SIZE_HUMAN
|
||||
var/metabolism_efficiency = 1 //more or less efficiency to metabolize helpful/harmful reagents and regulate body temperature..
|
||||
var/list/image/staticOverlays = list()
|
||||
@@ -75,4 +74,4 @@
|
||||
var/list/status_effects //a list of all status effects the mob has
|
||||
|
||||
var/list/implants = null
|
||||
var/tesla_ignore = FALSE
|
||||
var/tesla_ignore = FALSE
|
||||
|
||||
@@ -242,7 +242,6 @@ var/list/ai_list = list()
|
||||
if(statpanel("Status"))
|
||||
if(!stat)
|
||||
stat(null, text("System integrity: [(health+100)/2]%"))
|
||||
stat(null, "Station Time: [worldtime2text()]")
|
||||
stat(null, text("Connected cyborgs: [connected_robots.len]"))
|
||||
var/area/borg_area
|
||||
for(var/mob/living/silicon/robot/R in connected_robots)
|
||||
|
||||
@@ -235,4 +235,4 @@
|
||||
|
||||
/mob/living/silicon/pai/process()
|
||||
emitterhealth = Clamp((emitterhealth + emitterregen), -50, emittermaxhealth)
|
||||
hit_slowdown = Clamp((hit_slowdown - 1), 0, 100)
|
||||
hit_slowdown = Clamp((hit_slowdown - 1), 0, 100)
|
||||
|
||||
@@ -99,3 +99,7 @@
|
||||
else
|
||||
SetLuminosity(0)
|
||||
src << "<span class='notice'>You disable your integrated light.</span>"
|
||||
|
||||
/mob/living/silicon/pai/movement_delay()
|
||||
. = ..()
|
||||
. += 1 //A bit slower than humans, so they're easier to smash
|
||||
@@ -302,7 +302,6 @@
|
||||
else
|
||||
stat(null, text("No Cell Inserted!"))
|
||||
|
||||
stat("Station Time:", worldtime2text())
|
||||
if(module)
|
||||
for(var/datum/robot_energy_storage/st in module.storages)
|
||||
stat("[st.name]:", "[st.energy]/[st.max_energy]")
|
||||
@@ -598,6 +597,12 @@
|
||||
update_fire()
|
||||
|
||||
#define BORG_CAMERA_BUFFER 30
|
||||
|
||||
/mob/living/silicon/robot/proc/do_camera_update(oldLoc)
|
||||
if(oldLoc != src.loc)
|
||||
cameranet.updatePortableCamera(src.camera)
|
||||
updating = 0
|
||||
|
||||
/mob/living/silicon/robot/Move(a, b, flag)
|
||||
var/oldLoc = src.loc
|
||||
. = ..()
|
||||
@@ -605,10 +610,7 @@
|
||||
if(src.camera)
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(oldLoc != src.loc)
|
||||
cameranet.updatePortableCamera(src.camera)
|
||||
updating = 0
|
||||
addtimer(CALLBACK(.proc/do_camera_update, oldLoc), BORG_CAMERA_BUFFER)
|
||||
if(module)
|
||||
if(istype(module, /obj/item/weapon/robot_module/janitor))
|
||||
var/turf/tile = loc
|
||||
@@ -1083,4 +1085,4 @@
|
||||
if(selfdeleting)
|
||||
if(rider in ridden.buckled_mobs)
|
||||
ridden.unbuckle_mob(rider)
|
||||
. = ..()
|
||||
. = ..()
|
||||
@@ -21,4 +21,4 @@
|
||||
/mob/living/silicon/robot/Moved()
|
||||
. = ..()
|
||||
if(riding_datum)
|
||||
riding_datum.on_vehicle_move()
|
||||
riding_datum.on_vehicle_move()
|
||||
|
||||
@@ -410,4 +410,4 @@ Auto Patrol: []"},
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/secbot
|
||||
req_access = list(access_security)
|
||||
req_access = list(access_security)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
..()
|
||||
var/area/A = get_area(src)
|
||||
if(A)
|
||||
notify_ghosts("A drone shell has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK)
|
||||
notify_ghosts("A drone shell has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE)
|
||||
|
||||
/obj/item/drone_shell/attack_ghost(mob/user)
|
||||
if(jobban_isbanned(user,"drone"))
|
||||
|
||||
@@ -333,6 +333,11 @@
|
||||
Shoot(A)
|
||||
spawn(6)
|
||||
Shoot(A)
|
||||
/* var/datum/callback/cb = CALLBACK(A, .proc/Shoot)
|
||||
addtimer(cb, 1)
|
||||
addtimer(cb, 4)
|
||||
addtimer(cb, 6)*/
|
||||
|
||||
else
|
||||
Shoot(A)
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
|
||||
@@ -115,6 +115,12 @@ Difficulty: Hard
|
||||
bloodspell.phased = 1
|
||||
internal = new/obj/item/device/gps/internal/bubblegum(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/grant_achievement(medaltype,scoretype)
|
||||
..()
|
||||
SSshuttle.shuttle_purchase_requirements_met |= "bubblegum"
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon)
|
||||
if(!charging)
|
||||
..()
|
||||
@@ -153,7 +159,7 @@ Difficulty: Hard
|
||||
var/obj/effect/overlay/temp/decoy/D = new /obj/effect/overlay/temp/decoy(loc,src)
|
||||
animate(D, alpha = 0, color = "#FF0000", transform = matrix()*2, time = 3)
|
||||
sleep(3)
|
||||
throw_at(T, get_dist(src, T), 0.5, src, 0, callback = CALLBACK(src, .charge_end, bonus_charges))
|
||||
throw_at(T, get_dist(src, T), 1, src, 0, callback = CALLBACK(src, .charge_end, bonus_charges))
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge_end(bonus_charges)
|
||||
charging = 0
|
||||
|
||||
@@ -550,4 +550,4 @@
|
||||
|
||||
/mob/living/simple_animal/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1)
|
||||
. = ..()
|
||||
riding_datum = new/datum/riding/animal
|
||||
riding_datum = new/datum/riding/animal
|
||||
|
||||
@@ -550,7 +550,9 @@ var/next_mob_id = 0
|
||||
stat(null, "Map: [MAP_NAME]")
|
||||
if(nextmap && istype(nextmap))
|
||||
stat(null, "Next Map: [nextmap.friendlyname]")
|
||||
stat(null, "Server Time: [time2text(world.realtime, "YYYY-MM-DD hh:mm")]")
|
||||
stat(null, "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]")
|
||||
stat(null, "Station Time: [worldtime2text()]")
|
||||
stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)")
|
||||
if(SSshuttle.emergency)
|
||||
var/ETA = SSshuttle.emergency.getModeStr()
|
||||
if(ETA)
|
||||
@@ -676,6 +678,9 @@ var/next_mob_id = 0
|
||||
var/mob/living/L = src
|
||||
if(L.has_status_effect(/datum/status_effect/freon))
|
||||
canmove = 0
|
||||
if(!lying && lying_prev)
|
||||
if(client)
|
||||
client.move_delay = world.time + movement_delay()
|
||||
lying_prev = lying
|
||||
return canmove
|
||||
|
||||
@@ -739,10 +744,10 @@ var/next_mob_id = 0
|
||||
if(mind)
|
||||
return mind.grab_ghost(force = force)
|
||||
|
||||
/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)
|
||||
/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, flashwindow)
|
||||
var/mob/dead/observer/ghost = get_ghost()
|
||||
if(ghost)
|
||||
ghost.notify_cloning(message, sound, source)
|
||||
ghost.notify_cloning(message, sound, source, flashwindow)
|
||||
return ghost
|
||||
|
||||
/mob/proc/AddSpell(obj/effect/proc_holder/spell/S)
|
||||
|
||||
@@ -378,12 +378,14 @@ var/static/regex/firstname = new("^\[^\\s-\]+") //First word before whitespace o
|
||||
/mob/proc/reagent_check(datum/reagent/R) // utilized in the species code
|
||||
return 1
|
||||
|
||||
/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/image/alert_overlay = null, var/action = NOTIFY_JUMP) //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/action = NOTIFY_JUMP, flashwindow = TRUE) //Easy notification of ghosts.
|
||||
for(var/mob/dead/observer/O in player_list)
|
||||
if(O.client)
|
||||
O << "<span class='ghostalert'>[message][(enter_link) ? " [enter_link]" : ""]<span>"
|
||||
if(ghost_sound)
|
||||
O << sound(ghost_sound)
|
||||
if(flashwindow)
|
||||
window_flash(O.client)
|
||||
if(source)
|
||||
var/obj/screen/alert/notify_action/A = O.throw_alert("\ref[source]_notify_action", /obj/screen/alert/notify_action)
|
||||
if(A)
|
||||
|
||||
@@ -56,6 +56,5 @@
|
||||
M.key = key
|
||||
|
||||
if(delete_old_mob)
|
||||
spawn(1)
|
||||
qdel(src)
|
||||
QDEL_IN(src, 1)
|
||||
return M
|
||||
|
||||
@@ -27,7 +27,4 @@
|
||||
loc = pick(watch_locations)
|
||||
*/
|
||||
new_player_panel()
|
||||
|
||||
spawn(40)
|
||||
if(client)
|
||||
client.playtitlemusic()
|
||||
client.playtitlemusic()
|
||||
|
||||
Reference in New Issue
Block a user