Merge remote-tracking branch 'origin/master' into TGUI-3.0

This commit is contained in:
Artur
2020-06-09 11:07:39 +03:00
177 changed files with 249863 additions and 2481 deletions
-77
View File
@@ -1,77 +0,0 @@
/datum/component/decal
dupe_mode = COMPONENT_DUPE_ALLOWED
can_transfer = TRUE
var/cleanable
var/description
var/mutable_appearance/pic
var/first_dir // This only stores the dir arg from init
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255)
if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha))
return COMPONENT_INCOMPATIBLE
first_dir = _dir
description = _description
cleanable = _cleanable
apply()
/datum/component/decal/RegisterWithParent()
. = ..()
if(first_dir)
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
if(cleanable)
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
if(description)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
/datum/component/decal/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE))
/datum/component/decal/Destroy()
remove()
return ..()
/datum/component/decal/PreTransfer()
remove()
/datum/component/decal/PostTransfer()
remove()
apply()
/datum/component/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha)
if(!_icon || !_icon_state)
return FALSE
// It has to be made from an image or dir breaks because of a byond bug
var/temp_image = image(_icon, null, _icon_state, _layer, _dir)
pic = new(temp_image)
pic.color = _color
pic.alpha = _alpha
return TRUE
/datum/component/decal/proc/apply(atom/thing)
var/atom/master = thing || parent
master.add_overlay(pic, TRUE)
if(isitem(master))
addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
/datum/component/decal/proc/remove(atom/thing)
var/atom/master = thing || parent
master.cut_overlay(pic, TRUE)
if(isitem(master))
addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
/datum/component/decal/proc/rotate_react(datum/source, old_dir, new_dir)
if(old_dir == new_dir)
return
remove()
pic.dir = turn(pic.dir, dir2angle(old_dir) - dir2angle(new_dir))
apply()
/datum/component/decal/proc/clean_react(datum/source, strength)
if(strength >= cleanable)
qdel(src)
/datum/component/decal/proc/examine(datum/source, mob/user, list/examine_list)
examine_list += description
-13
View File
@@ -1,13 +0,0 @@
/datum/component/decal/blood
dupe_mode = COMPONENT_DUPE_UNIQUE
/datum/component/decal/blood/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_STRENGTH_BLOOD, _color, _layer=ABOVE_OBJ_LAYER)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
. = ..()
RegisterSignal(parent, COMSIG_ATOM_GET_EXAMINE_NAME, .proc/get_examine_name)
/datum/component/decal/blood/proc/get_examine_name(datum/source, mob/user, list/override)
var/atom/A = parent
return COMPONENT_EXNAME_CHANGED
+1 -1
View File
@@ -73,7 +73,7 @@
if(!material_amount)
to_chat(user, "<span class='warning'>[I] does not contain sufficient materials to be accepted by [parent].</span>")
return
if((!precise_insertion || !GLOB.typecache_stack[I]) && !has_space(material_amount))
if((!precise_insertion || !GLOB.typecache_stack[I.type]) && !has_space(material_amount))
to_chat(user, "<span class='warning'>[parent] has not enough space. Please remove materials from [parent] in order to insert more.</span>")
return
user_insert(I, user)
+5 -5
View File
@@ -25,7 +25,7 @@
var/mob/living/owner = parent
if(owner.stat != DEAD)
START_PROCESSING(SSdcs, src)
START_PROCESSING(SSobj, src)
RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event)
RegisterSignal(parent, COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event)
@@ -40,12 +40,12 @@
hud.show_hud(hud.hud_version)
/datum/component/mood/Destroy()
STOP_PROCESSING(SSdcs, src)
STOP_PROCESSING(SSobj, src)
unmodify_hud()
return ..()
/datum/component/mood/proc/stop_processing()
STOP_PROCESSING(SSdcs, src)
STOP_PROCESSING(SSobj, src)
/datum/component/mood/proc/print_mood(mob/user)
var/msg = "<span class='info'>*---------*\n<EM>Your current mood</EM>\n"
@@ -138,7 +138,7 @@
else
screen_obj.icon_state = "mood[mood_level]"
/datum/component/mood/process() //Called on SSdcs process
/datum/component/mood/process() //Called on SSobj process
if(QDELETED(parent)) // workaround to an obnoxious sneaky periodical runtime.
qdel(src)
return
@@ -345,7 +345,7 @@
///Called when parent is revived.
/datum/component/mood/proc/on_revive(datum/source, full_heal)
START_PROCESSING(SSdcs, src)
START_PROCESSING(SSobj, src)
if(!full_heal)
return
remove_temp_moods()
+4 -2
View File
@@ -62,7 +62,9 @@
orbiters[orbiter] = TRUE
orbiter.orbiting = src
RegisterSignal(orbiter, COMSIG_MOVABLE_MOVED, .proc/orbiter_move_react)
var/matrix/initial_transform = matrix(orbiter.transform)
orbiters[orbiter] = initial_transform
// Head first!
if(pre_rotation)
@@ -79,8 +81,6 @@
orbiter.SpinAnimation(rotation_speed, -1, clockwise, rotation_segments, parallel = FALSE)
//we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
orbiter.transform = initial_transform
orbiter.forceMove(get_turf(parent))
to_chat(orbiter, "<span class='notice'>Now orbiting [parent].</span>")
@@ -89,6 +89,8 @@
return
UnregisterSignal(orbiter, COMSIG_MOVABLE_MOVED)
orbiter.SpinAnimation(0, 0)
if(istype(orbiters[orbiter],/matrix)) //This is ugly.
orbiter.transform = orbiters[orbiter]
orbiters -= orbiter
orbiter.stop_orbit(src)
orbiter.orbiting = null
@@ -57,7 +57,7 @@
/obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper,
/obj/item/implanter, /obj/item/screwdriver, /obj/item/weldingtool/mini,
/obj/item/firing_pin, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/automatic/magrifle/pistol,
/obj/item/toy/plush/snakeplushie
/obj/item/toy/plush/snakeplushie, /obj/item/gun/energy/e_gun/mini
))
/datum/component/storage/concrete/pockets/shoes/clown/Initialize()
@@ -68,7 +68,7 @@
/obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector,
/obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper,
/obj/item/implanter, /obj/item/screwdriver, /obj/item/weldingtool/mini,
/obj/item/firing_pin, /obj/item/bikehorn, /obj/item/gun/ballistic/automatic/pistol))
/obj/item/firing_pin, /obj/item/bikehorn, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/energy/e_gun/mini))
/datum/component/storage/concrete/pockets/pocketprotector
max_items = 3
+10 -10
View File
@@ -163,24 +163,24 @@
if(-4 to -2) // glancing blow at best
user.visible_message("<span class='warning'>[user] lands a weak [tackle_word] on [target], briefly knocking [target.p_them()] off-balance!</span>", "<span class='userdanger'>You land a weak [tackle_word] on [target], briefly knocking [target.p_them()] off-balance!</span>", target)
to_chat(target, "<span class='userdanger'>[user] lands a weak [tackle_word] on you, briefly knocking you off-balance!</span>")
user.Knockdown(30)
target.adjustStaminaLoss(15)
target.apply_status_effect(STATUS_EFFECT_TASED_WEAK, 6 SECONDS)
if(-1 to 0) // decent hit, both parties are about equally inconvenienced
user.visible_message("<span class='warning'>[user] lands a passable [tackle_word] on [target], sending them both tumbling!</span>", "<span class='userdanger'>You land a passable [tackle_word] on [target], sending you both tumbling!</span>", target)
to_chat(target, "<span class='userdanger'>[user] lands a passable [tackle_word] on you, sending you both tumbling!</span>")
target.adjustStaminaLoss(stamina_cost)
target.adjustStaminaLoss(stamina_cost * 1.5)
target.Paralyze(5)
user.Knockdown(20)
target.Knockdown(25)
target.Knockdown(30)
if(1 to 2) // solid hit, tackler has a slight advantage
user.visible_message("<span class='warning'>[user] lands a solid [tackle_word] on [target], knocking them both down hard!</span>", "<span class='userdanger'>You land a solid [tackle_word] on [target], knocking you both down hard!</span>", target)
to_chat(target, "<span class='userdanger'>[user] lands a solid [tackle_word] on you, knocking you both down hard!</span>")
target.adjustStaminaLoss(30)
target.adjustStaminaLoss(40)
target.Paralyze(5)
user.Knockdown(10)
target.Knockdown(20)
@@ -192,9 +192,9 @@
user.SetKnockdown(0)
user.set_resting(FALSE, TRUE, FALSE)
user.forceMove(get_turf(target))
target.adjustStaminaLoss(40)
target.Paralyze(5)
target.Knockdown(30)
target.adjustStaminaLoss(50)
target.Paralyze(3) //Otherwise the victim can just instantly get out of the grab.
target.DefaultCombatKnockdown(20) //So they cant get up instantly.
if(ishuman(target) && iscarbon(user))
target.grabbedby(user)
@@ -205,9 +205,9 @@
user.SetKnockdown(0)
user.set_resting(FALSE, TRUE, FALSE)
user.forceMove(get_turf(target))
target.adjustStaminaLoss(40)
target.Paralyze(5)
target.Knockdown(30)
target.adjustStaminaLoss(65)
target.Paralyze(10)
target.DefaultCombatKnockdown(20)
if(ishuman(target) && iscarbon(user))
target.grabbedby(user)
target.grippedby(user, instant = TRUE)
-5
View File
@@ -175,11 +175,6 @@
name = "Trooper REAL_NAME"
desc = "That's not red paint. That's real corgi blood."
/datum/dog_fashion/head/colour
name = "Stylish REAL_NAME"
desc = "From the tips of their paws to the top of their head, they look like a made bed."
emote_see = list("tries to tap dances.","looks sadly at others outfits...","barks at bad fashion!")
/datum/dog_fashion/head/telegram
name = "Messenger REAL_NAME"
desc = "Dont shoot the messenger..."
+75
View File
@@ -0,0 +1,75 @@
/datum/element/decal
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
id_arg_index = 2
var/cleanable
var/description
var/mutable_appearance/pic
var/list/num_decals_per_atom
var/first_dir // This stores the direction of the decal compared to the parent facing NORTH
/datum/element/decal/Attach(datum/target, _icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255)
. = ..()
if(. == ELEMENT_INCOMPATIBLE || !_icon || !_icon_state || !isatom(target))
return ELEMENT_INCOMPATIBLE
var/atom/A = target
if(!pic)
// It has to be made from an image or dir breaks because of a byond bug
var/temp_image = image(_icon, null, _icon_state, _layer, _dir)
pic = new(temp_image)
pic.color = _color
pic.alpha = _alpha
first_dir = _dir
description = _description
cleanable = _cleanable
LAZYINITLIST(num_decals_per_atom)
if(!num_decals_per_atom[A])
if(first_dir)
RegisterSignal(A, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
if(cleanable)
RegisterSignal(A, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
if(description)
RegisterSignal(A, COMSIG_PARENT_EXAMINE, .proc/examine)
apply(A, TRUE)
num_decals_per_atom[A]++
/datum/element/decal/Detach(datum/target)
var/atom/A = target
remove(A, A.dir)
UnregisterSignal(A, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE))
LAZYREMOVE(num_decals_per_atom, A)
return ..()
/datum/element/decal/proc/remove(atom/target, old_dir)
pic.dir = first_dir == NORTH ? target.dir : turn(first_dir, dir2angle(old_dir))
for(var/i in 1 to num_decals_per_atom[target])
target.cut_overlay(pic, TRUE)
if(isitem(target))
addtimer(CALLBACK(target, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
/datum/element/decal/proc/apply(atom/target, init = FALSE)
pic.dir = first_dir == NORTH ? target.dir : turn(first_dir, dir2angle(target.dir))
if(init)
target.add_overlay(pic, TRUE)
else
for(var/i in 1 to num_decals_per_atom[target])
target.add_overlay(pic, TRUE)
if(isitem(target))
addtimer(CALLBACK(target, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
/datum/element/decal/proc/rotate_react(datum/source, old_dir, new_dir)
if(old_dir == new_dir)
return
remove(source, old_dir)
apply(source)
/datum/element/decal/proc/clean_react(datum/source, strength)
if(strength >= cleanable)
Detach(source)
/datum/element/decal/proc/examine(datum/source, mob/user, list/examine_list)
examine_list += description
+1 -1
View File
@@ -4,7 +4,7 @@
var/list/user_by_item = list()
/datum/element/earhealing/New()
START_PROCESSING(SSdcs, src)
START_PROCESSING(SSobj, src)
/datum/element/earhealing/Attach(datum/target)
. = ..()
+81
View File
@@ -0,0 +1,81 @@
/datum/element/photosynthesis
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
id_arg_index = 2
///how much brute damage (or integrity, for objects) is healed (taken if positive) at maximum luminosity. (if lum_minus were 0)
var/light_bruteheal = -1
///how much burn damage is restored/taken at maximum luminosity. Mobs only.
var/light_burnheal = -1
///how much tox damage is restored/taken at maximum luminosity. Mobs only.
var/light_toxheal = -1
///how much oxy damage is restored/taken at maximum luminosity. Mobs only.
var/light_oxyheal = -1
///how nutrition recovery/expenses factor, not affected by bonus_lum and malus_lum. Mobs only.
var/light_nutrition_gain = 4
///A value subtracted to the lum count, which allows targets to wilt or heal in the darkness.
var/lum_minus = 0.5
///the minimum lum count over which where the target damage is adjusted.
var/bonus_lum = 0.2
///the maximum lum count under which the target damage is inversely adjusted.
var/malus_lum = 0
///List of atoms this element is attached to. Doubles as a multiplier if the same element is attached multiple times to a target multiple times.
var/list/attached_atoms
/datum/element/photosynthesis/Attach(datum/target, brute = -1, burn = -1, tox = -1, oxy = -1, nutri = 4, minus = 0.2, bonus = 0.3, malus = -0.1)
. = ..()
if(. == ELEMENT_INCOMPATIBLE || !(isliving(target) || (isobj(target) && light_bruteheal)))
return ELEMENT_INCOMPATIBLE
light_bruteheal = brute
light_burnheal = burn
light_toxheal = tox
light_oxyheal = oxy
light_nutrition_gain = nutri
lum_minus = minus
bonus_lum = bonus
malus_lum = malus
if(!attached_atoms)
attached_atoms = list()
START_PROCESSING(SSobj, src)
attached_atoms[target]++
/datum/element/photosynthesis/Detach(datum/target)
attached_atoms[target]--
if(!attached_atoms[target])
attached_atoms -= target
if(!length(attached_atoms))
STOP_PROCESSING(SSobj, src)
attached_atoms = null
return ..()
/datum/element/photosynthesis/process()
for(var/A in attached_atoms)
var/atom/movable/AM = A
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
if(isturf(AM.loc)) //else, there's considered to be no light
var/turf/T = AM.loc
light_amount = (T.get_lumcount() - lum_minus)
if(isliving(AM))
var/mob/living/L = AM
if(L.stat == DEAD)
continue
if(light_nutrition_gain)
L.adjust_nutrition(light_amount * light_nutrition_gain * attached_atoms[AM], NUTRITION_LEVEL_FULL)
if(light_amount > bonus_lum || light_amount < malus_lum)
var/mult = ((light_amount > bonus_lum) ? 1 : -1) * attached_atoms[AM]
if(light_bruteheal)
L.adjustBruteLoss(light_bruteheal * mult)
if(light_burnheal)
L.adjustFireLoss(light_burnheal * mult)
if(light_toxheal)
L.adjustToxLoss(light_toxheal * mult)
if(light_oxyheal)
L.adjustOxyLoss(light_oxyheal * mult)
else if(light_amount > bonus_lum || light_amount < malus_lum)
var/obj/O = AM
var/damage = light_bruteheal * ((light_amount > bonus_lum) ? 1 : -1) * attached_atoms[AM]
if(damage < 0 && O.obj_integrity < O.max_integrity)
O.obj_integrity = min(O.obj_integrity + damage, O.max_integrity) //Till we get a obj heal proc...
else
O.take_damage(damage, BRUTE, FALSE, FALSE, null, 100)
+8 -2
View File
@@ -331,14 +331,20 @@
/datum/mind/proc/enslave_mind_to_creator(mob/living/creator)
if(iscultist(creator))
SSticker.mode.add_cultist(src)
if(iscultist(creator, TRUE))
SSticker.mode.add_cultist(src)
else
src.add_antag_datum(/datum/antagonist/cult/neutered/traitor)
else if(is_revolutionary(creator))
var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE)
converter.add_revolutionary(src,FALSE)
else if(is_servant_of_ratvar(creator))
add_servant_of_ratvar(current)
if(is_servant_of_ratvar(creator, TRUE))
add_servant_of_ratvar(current)
else
add_servant_of_ratvar(current, FALSE, FALSE, /datum/antagonist/clockcult/neutered/traitor)
else if(is_nuclear_operative(creator))
var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)
+9
View File
@@ -173,6 +173,11 @@
port_id = "snowdin"
can_be_bought = FALSE
/datum/map_template/shuttle/snow_taxi
port_id = "snow"
can_be_bought = FALSE
suffix = "taxi"
// Shuttles start here:
/datum/map_template/shuttle/emergency/backup
@@ -560,6 +565,10 @@
suffix = "cog"
name = "arrival shuttle (Cog)"
/datum/map_template/shuttle/arrival/snaxi
suffix = "snaxi"
name = "arrival shuttle (Snaxi)"
/datum/map_template/shuttle/aux_base/default
suffix = "default"
name = "auxilliary base (Default)"
+1 -1
View File
@@ -191,7 +191,7 @@
/datum/mind/proc/skill_html_readout()
var/list/out = list("<center><h1>Skills</h1></center><hr>")
out += "<table style=\"width:100%\"><tr><th><b>Skill</b><th><b>Value</b></tr>"
for(var/path in skill_holder.skills|skill_holder.skill_value_mods|skill_holder.skill_level_mods)
for(var/path in GLOB.skill_datums)
var/datum/skill/S = GLOB.skill_datums[path]
var/skill_value = get_skill_value(path)
var/skill_level = get_skill_level(path, round = TRUE)
@@ -18,7 +18,7 @@
area_type = /area
protected_areas = list(/area/maintenance, /area/ai_monitored/turret_protected/ai_upload, /area/ai_monitored/turret_protected/ai_upload_foyer,
/area/ai_monitored/turret_protected/ai, /area/storage/emergency/starboard, /area/storage/emergency/port, /area/shuttle, /area/security/prison, /area/ruin, /area/space/nearstation)
/area/ai_monitored/turret_protected/ai, /area/storage/emergency/starboard, /area/storage/emergency/port, /area/shuttle, /area/security/prison, /area/ruin, /area/space/nearstation, /area/icemoon)
target_trait = ZTRAIT_STATION
immunity_type = "rad"