Merge branch 'master' into upstream-merge-34894

This commit is contained in:
LetterJay
2018-01-24 21:17:35 -06:00
committed by GitHub
42 changed files with 461 additions and 272 deletions
+2 -2
View File
@@ -83,9 +83,9 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
#define RATVARIAN_SPEAR_COOLDOWN 300 //The cooldown period between summoning another Ratvarian spear
#define MARAUDER_SCRIPTURE_SCALING_THRESHOLD 200 //The amount of deciseconds that must pass before marauder scripture will not gain a recital penalty
#define MARAUDER_SCRIPTURE_SCALING_THRESHOLD 600 //The amount of deciseconds that must pass before marauder scripture will not gain a recital penalty
#define MARAUDER_SCRIPTURE_SCALING_TIME 50 //The amount of extra deciseconds tacked on to the marauder scripture recital time per recent marauder
#define MARAUDER_SCRIPTURE_SCALING_TIME 20 //The amount of extra deciseconds tacked on to the marauder scripture recital time per recent marauder
#define MARAUDER_SCRIPTURE_SCALING_MAX 300 //The maximum extra time applied to the marauder scripture
+2
View File
@@ -28,6 +28,8 @@
#define STATUS_EFFECT_BLOODDRUNK /datum/status_effect/blooddrunk //Stun immunity and greatly reduced damage taken
#define STATUS_EFFECT_FLESHMEND /datum/status_effect/fleshmend //Very fast healing; suppressed by fire, and heals less fire damage
/////////////
// DEBUFFS //
/////////////
+3 -1
View File
@@ -76,6 +76,8 @@
return 1
/datum/martial_art/proc/teach(mob/living/carbon/human/H,make_temporary=0)
if(!istype(H) || !H.mind)
return FALSE
if(H.mind.martial_art)
if(make_temporary)
if(!H.mind.martial_art.allow_temp_override)
@@ -98,7 +100,7 @@
base = M
/datum/martial_art/proc/remove(mob/living/carbon/human/H)
if(H.mind.martial_art != src)
if(!istype(H) || !H.mind || H.mind.martial_art != src)
return
on_remove(H)
if(base)
+24
View File
@@ -412,3 +412,27 @@
/datum/status_effect/sword_spin/on_remove()
owner.visible_message("<span class='warning'>[owner]'s inhuman strength dissipates and the sword's runes grow cold!</span>")
//Used by changelings to rapidly heal
//Heals 10 brute and oxygen damage every second, and 5 fire
//Being on fire will suppress this healing
/datum/status_effect/fleshmend
id = "fleshmend"
duration = 100
alert_type = /obj/screen/alert/status_effect/fleshmend
/datum/status_effect/fleshmend/tick()
if(owner.on_fire)
linked_alert.icon_state = "fleshmend_fire"
return
else
linked_alert.icon_state = "fleshmend"
owner.adjustBruteLoss(-10, FALSE)
owner.adjustFireLoss(-5, FALSE)
owner.adjustOxyLoss(-10)
/obj/screen/alert/status_effect/fleshmend
name = "Fleshmend"
desc = "Our wounds are rapidly healing. <i>This effect is prevented if we are on fire.</i>"
icon_state = "fleshmend"
@@ -1,52 +1,19 @@
/obj/effect/proc_holder/changeling/fleshmend
name = "Fleshmend"
desc = "Our flesh rapidly regenerates, healing our burns, bruises and shortness of breath. Effectiveness decreases with quick, repeated use."
helptext = "Heals a moderate amount of damage over a short period of time. Can be used while unconscious. Does not regrow limbs or restore lost blood."
chemical_cost = 20
dna_cost = 2
req_stat = UNCONSCIOUS
var/recent_uses = 1 //The factor of which the healing should be divided by
var/healing_ticks = 10
// The ideal total healing amount,
// divided by healing_ticks to get heal/tick
var/total_healing = 100
/obj/effect/proc_holder/changeling/fleshmend/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
/obj/effect/proc_holder/changeling/fleshmend/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/effect/proc_holder/changeling/fleshmend/process()
if(recent_uses > 1)
recent_uses = max(1, recent_uses - (1 / healing_ticks))
//Starts healing you every second for 10 seconds.
//Can be used whilst unconscious.
/obj/effect/proc_holder/changeling/fleshmend/sting_action(mob/living/user)
to_chat(user, "<span class='notice'>We begin to heal rapidly.</span>")
if(recent_uses > 1)
to_chat(user, "<span class='warning'>Our healing's effectiveness is reduced \
by quick repeated use!</span>")
recent_uses++
INVOKE_ASYNC(src, .proc/fleshmend, user)
return TRUE
/obj/effect/proc_holder/changeling/fleshmend/proc/fleshmend(mob/living/user)
// The healing itself - doesn't heal toxin damage
// (that's anatomic panacea) and the effectiveness decreases with
// each use in a short timespan
for(var/i in 1 to healing_ticks)
if(user)
var/healpertick = -(total_healing / healing_ticks)
user.adjustBruteLoss(healpertick / recent_uses, 0)
user.adjustOxyLoss(healpertick / recent_uses, 0)
user.adjustFireLoss(healpertick / recent_uses, 0)
user.updatehealth()
else
break
sleep(10)
/obj/effect/proc_holder/changeling/fleshmend
name = "Fleshmend"
desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath. Functions while unconscious."
helptext = "If we are on fire, the healing effect will not function. Does not regrow limbs or restore lost blood."
chemical_cost = 20
dna_cost = 2
req_stat = UNCONSCIOUS
//Starts healing you every second for 10 seconds.
//Can be used whilst unconscious.
/obj/effect/proc_holder/changeling/fleshmend/sting_action(mob/living/user)
if(user.has_status_effect(STATUS_EFFECT_FLESHMEND))
to_chat(user, "<span class='warning'>We are already fleshmending!</span>")
return
to_chat(user, "<span class='notice'>We begin to heal rapidly.</span>")
user.apply_status_effect(STATUS_EFFECT_FLESHMEND)
return TRUE
//Check buffs.dm for the fleshmend status effect code
@@ -73,8 +73,8 @@
name = "Clockwork Marauder"
desc = "Creates a shell for a clockwork marauder, a balanced frontline construct that can deflect projectiles with its shield."
invocations = list("Arise, avatar of Arbiter!", "Defend the Ark with vengeful zeal.")
channel_time = 50
power_cost = 1000
channel_time = 80
power_cost = 8000
creator_message = "<span class='brass'>Your slab disgorges several chunks of replicant alloy that form into a suit of thrumming armor.</span>"
usage_tip = "Reciting this scripture multiple times in a short period will cause it to take longer!"
tier = SCRIPTURE_APPLICATION
@@ -94,10 +94,13 @@
var/human_servants = 0
for(var/V in SSticker.mode.servants_of_ratvar)
var/datum/mind/M = V
if(ishuman(M.current))
var/mob/living/L = M.current
if(ishuman(L) && L.stat != DEAD)
human_servants++
construct_limit = human_servants / 4 //1 per 4 human servants, and a maximum of 3 marauders
construct_limit = CLAMP(construct_limit, 1, 3)
construct_limit = CLAMP(construct_limit - recent_marauders, 1, 3)
if(recent_marauders)
to_chat(invoker, "<span class='warning'>The Hierophant Network needs [MARAUDER_SCRIPTURE_SCALING_THRESHOLD / 10] seconds to recover from marauder summoning; recent summoning has limited the number of available marauders by [recent_marauders]!</span>")
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/pre_recital()
channel_time = initial(channel_time)
@@ -35,6 +35,13 @@
else
nomination(user)
/obj/structure/destructible/clockwork/eminence_spire/attack_drone(mob/living/simple_animal/drone/user)
if(!is_servant_of_ratvar(user))
..()
else
to_chat(user, "<span class='warning'>You feel the omniscient gaze turn into a puzzled frown. Perhaps you should just stick to building.</span>")
return
/obj/structure/destructible/clockwork/eminence_spire/attack_ghost(mob/user)
if(!IsAdminGhost(user))
return
+3 -1
View File
@@ -34,7 +34,9 @@
/obj/item/device/pda/ai,
/obj/item/device/pda/heads,
/obj/item/device/pda/clear,
/obj/item/device/pda/syndicate)
/obj/item/device/pda/syndicate,
/obj/item/device/pda/chameleon,
/obj/item/device/pda/chameleon/broken)
for(var/P in typesof(/obj/item/device/pda) - blocked)
var/obj/item/device/pda/D = new P
+2 -3
View File
@@ -170,8 +170,7 @@
if((materials.amount(MAT_METAL) >= metal_cost*multiplier*coeff) && (materials.amount(MAT_GLASS) >= glass_cost*multiplier*coeff))
busy = TRUE
use_power(power)
icon_state = "autolathe"
flick("autolathe_n",src)
icon_state = "autolathe_n"
var/time = is_stack ? 32 : 32*coeff*multiplier
addtimer(CALLBACK(src, .proc/make_item, power, metal_cost, glass_cost, multiplier, coeff, is_stack), time)
@@ -207,7 +206,7 @@
for(var/mat in materials_used)
new_item.materials[mat] = materials_used[mat] / multiplier
new_item.autolathe_crafted(src)
icon_state = "autolathe"
busy = FALSE
updateDialog()
+2 -2
View File
@@ -166,10 +166,10 @@
L[avoid_assoc_duplicate_keys(A.name, areaindex)] = R
for(var/obj/item/implant/tracking/I in GLOB.tracked_implants)
if(!I.imp_in || !ismob(I.loc))
if(!I.imp_in || !isliving(I.loc))
continue
else
var/mob/M = I.loc
var/mob/living/M = I.loc
if(M.stat == DEAD)
if(M.timeofdeath + 6000 < world.time)
continue
@@ -194,6 +194,10 @@
keyslot = new /obj/item/device/encryptionkey/headset_com
keyslot2 = new /obj/item/device/encryptionkey/headset_cent
/obj/item/device/radio/headset/headset_cent/empty
keyslot = null
keyslot2 = null
/obj/item/device/radio/headset/headset_cent/commander
keyslot = new /obj/item/device/encryptionkey/heads/captain
@@ -14,7 +14,7 @@
playsound(loc, 'sound/misc/sadtrombone.ogg', 50, 0)
/obj/item/implanter/sad_trombone
name = "implanter (sad_trombone)"
name = "implanter (sad trombone)"
imp_type = /obj/item/implant/sad_trombone
/obj/item/implantcase/sad_trombone
@@ -553,3 +553,16 @@
new /obj/item/reagent_containers/food/drinks/bottle/vodka/badminka(src)
new /obj/item/reagent_containers/syringe/stimulants(src)
new /obj/item/grenade/syndieminibomb(src)
// For ClownOps.
/obj/item/storage/backpack/duffelbag/clown/syndie
slowdown = 0
silent = TRUE
/obj/item/storage/backpack/duffelbag/clown/syndie/PopulateContents()
new /obj/item/device/pda/clown(src)
new /obj/item/clothing/under/rank/clown(src)
new /obj/item/clothing/shoes/clown_shoes(src)
new /obj/item/clothing/mask/gas/clown_hat(src)
new /obj/item/bikehorn(src)
new /obj/item/implanter/sad_trombone(src)
@@ -308,3 +308,27 @@
/obj/item/storage/box/syndie_kit/imp_radio/PopulateContents()
new /obj/item/implanter/radio(src)
/obj/item/storage/box/syndie_kit/centcom_costume/PopulateContents()
new /obj/item/clothing/under/rank/centcom_officer(src)
new /obj/item/clothing/shoes/sneakers/black(src)
new /obj/item/clothing/gloves/color/black(src)
new /obj/item/device/radio/headset/headset_cent/empty(src)
new /obj/item/clothing/glasses/sunglasses(src)
new /obj/item/storage/backpack/satchel(src)
new /obj/item/device/pda/heads(src)
new /obj/item/clipboard(src)
/obj/item/storage/box/syndie_kit/chameleon/broken/PopulateContents()
new /obj/item/clothing/under/chameleon/broken(src)
new /obj/item/clothing/suit/chameleon/broken(src)
new /obj/item/clothing/gloves/chameleon/broken(src)
new /obj/item/clothing/shoes/chameleon/broken(src)
new /obj/item/clothing/glasses/chameleon/broken(src)
new /obj/item/clothing/head/chameleon/broken(src)
new /obj/item/clothing/mask/chameleon/broken(src)
new /obj/item/storage/backpack/chameleon/broken(src)
new /obj/item/device/radio/headset/chameleon/broken(src)
new /obj/item/stamp/chameleon/broken(src)
new /obj/item/device/pda/chameleon/broken(src)
// No chameleon laser, they can't randomise for //REASONS//
+2 -2
View File
@@ -84,10 +84,10 @@ Frequency:
src.temp += "<B>Extranneous Signals:</B><BR>"
for (var/obj/item/implant/tracking/W in GLOB.tracked_implants)
if (!W.imp_in || !ismob(W.loc))
if (!W.imp_in || !isliving(W.loc))
continue
else
var/mob/M = W.loc
var/mob/living/M = W.loc
if (M.stat == DEAD)
if (M.timeofdeath + 6000 < world.time)
continue
+18 -9
View File
@@ -129,15 +129,24 @@
return
if(!M.buckled)
return
var/matrix/m180 = matrix(M.transform)
m180.Turn(180)
animate(M, transform = m180, time = 3)
M.pixel_y = M.get_standard_pixel_y_offset(180)
M.adjustBruteLoss(30)
src.visible_message(text("<span class='danger'>[M] falls free of [src]!</span>"))
unbuckle_mob(M,force=1)
M.emote("scream")
M.AdjustKnockdown(20)
release_mob(M)
/obj/structure/kitchenspike/proc/release_mob(mob/living/M)
var/matrix/m180 = matrix(M.transform)
m180.Turn(180)
animate(M, transform = m180, time = 3)
M.pixel_y = M.get_standard_pixel_y_offset(180)
M.adjustBruteLoss(30)
src.visible_message(text("<span class='danger'>[M] falls free of [src]!</span>"))
unbuckle_mob(M,force=1)
M.emote("scream")
M.AdjustKnockdown(20)
/obj/structure/kitchenspike/Destroy()
if(has_buckled_mobs())
for(var/mob/living/L in buckled_mobs)
release_mob(L)
return ..()
/obj/structure/kitchenspike/deconstruct(disassembled = TRUE)
if(disassembled)
+72 -28
View File
@@ -153,13 +153,15 @@
select_look(owner)
return 1
/datum/action/item_action/chameleon/change/proc/emp_randomise()
/datum/action/item_action/chameleon/change/proc/emp_randomise(var/amount = EMP_RANDOMISE_TIME)
if(istype(target, /obj/item/gun/energy/laser/chameleon))
return //Please no crash!
START_PROCESSING(SSprocessing, src)
random_look(owner)
emp_timer = world.time + EMP_RANDOMISE_TIME
var/new_value = world.time + amount
if(new_value > emp_timer)
emp_timer = new_value
/datum/action/item_action/chameleon/change/process()
if(world.time > emp_timer)
@@ -189,8 +191,8 @@
item_state = "engi_suit"
item_color = "engine"
/obj/item/clothing/under/chameleon/New()
..()
/obj/item/clothing/under/chameleon/Initialize()
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/under
chameleon_action.chameleon_name = "Jumpsuit"
@@ -200,6 +202,10 @@
/obj/item/clothing/under/chameleon/emp_act(severity)
chameleon_action.emp_randomise()
/obj/item/clothing/under/chameleon/broken/Initialize()
. = ..()
chameleon_action.emp_randomise(INFINITY)
/obj/item/clothing/suit/chameleon
name = "armor"
desc = "A slim armored vest that protects against most types of damage."
@@ -211,8 +217,8 @@
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/clothing/suit/chameleon/New()
..()
/obj/item/clothing/suit/chameleon/Initialize()
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/suit
chameleon_action.chameleon_name = "Suit"
@@ -222,6 +228,10 @@
/obj/item/clothing/suit/chameleon/emp_act(severity)
chameleon_action.emp_randomise()
/obj/item/clothing/suit/chameleon/broken/Initialize()
. = ..()
chameleon_action.emp_randomise(INFINITY)
/obj/item/clothing/glasses/chameleon
name = "Optical Meson Scanner"
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition."
@@ -232,8 +242,8 @@
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/clothing/glasses/chameleon/New()
..()
/obj/item/clothing/glasses/chameleon/Initialize()
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/glasses
chameleon_action.chameleon_name = "Glasses"
@@ -243,6 +253,10 @@
/obj/item/clothing/glasses/chameleon/emp_act(severity)
chameleon_action.emp_randomise()
/obj/item/clothing/glasses/chameleon/broken/Initialize()
. = ..()
chameleon_action.emp_randomise(INFINITY)
/obj/item/clothing/gloves/chameleon
desc = "These gloves will protect the wearer from electric shock."
name = "insulated gloves"
@@ -254,8 +268,8 @@
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/clothing/gloves/chameleon/New()
..()
/obj/item/clothing/gloves/chameleon/Initialize()
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/gloves
chameleon_action.chameleon_name = "Gloves"
@@ -265,6 +279,10 @@
/obj/item/clothing/gloves/chameleon/emp_act(severity)
chameleon_action.emp_randomise()
/obj/item/clothing/gloves/chameleon/broken/Initialize()
. = ..()
chameleon_action.emp_randomise(INFINITY)
/obj/item/clothing/head/chameleon
name = "grey cap"
desc = "It's a baseball hat in a tasteful grey colour."
@@ -276,8 +294,8 @@
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/clothing/head/chameleon/New()
..()
/obj/item/clothing/head/chameleon/Initialize()
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/head
chameleon_action.chameleon_name = "Hat"
@@ -287,6 +305,10 @@
/obj/item/clothing/head/chameleon/emp_act(severity)
chameleon_action.emp_randomise()
/obj/item/clothing/head/chameleon/broken/Initialize()
. = ..()
chameleon_action.emp_randomise(INFINITY)
/obj/item/clothing/head/chameleon/drone
// The camohat, I mean, holographic hat projection, is part of the
// drone itself.
@@ -294,8 +316,8 @@
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
// which means it offers no protection, it's just air and light
/obj/item/clothing/head/chameleon/drone/New()
..()
/obj/item/clothing/head/chameleon/drone/Initialize()
. = ..()
chameleon_action.random_look()
var/datum/action/item_action/chameleon/drone/togglehatmask/togglehatmask_action = new(src)
togglehatmask_action.UpdateButtonIcon()
@@ -320,8 +342,8 @@
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/clothing/mask/chameleon/New()
..()
/obj/item/clothing/mask/chameleon/Initialize()
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/mask
chameleon_action.chameleon_name = "Mask"
@@ -331,6 +353,10 @@
/obj/item/clothing/mask/chameleon/emp_act(severity)
chameleon_action.emp_randomise()
/obj/item/clothing/mask/chameleon/broken/Initialize()
. = ..()
chameleon_action.emp_randomise(INFINITY)
/obj/item/clothing/mask/chameleon/attack_self(mob/user)
vchange = !vchange
to_chat(user, "<span class='notice'>The voice changer is now [vchange ? "on" : "off"]!</span>")
@@ -343,8 +369,8 @@
// Can drones use the voice changer part? Let's not find out.
vchange = 0
/obj/item/clothing/mask/chameleon/drone/New()
..()
/obj/item/clothing/mask/chameleon/drone/Initialize()
. = ..()
chameleon_action.random_look()
var/datum/action/item_action/chameleon/drone/togglehatmask/togglehatmask_action = new(src)
togglehatmask_action.UpdateButtonIcon()
@@ -367,8 +393,8 @@
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/clothing/shoes/chameleon/New()
..()
/obj/item/clothing/shoes/chameleon/Initialize()
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/shoes
chameleon_action.chameleon_name = "Shoes"
@@ -378,6 +404,10 @@
/obj/item/clothing/shoes/chameleon/emp_act(severity)
chameleon_action.emp_randomise()
/obj/item/clothing/shoes/chameleon/broken/Initialize()
. = ..()
chameleon_action.emp_randomise(INFINITY)
/obj/item/gun/energy/laser/chameleon
name = "practice laser gun"
desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice."
@@ -405,8 +435,6 @@
chameleon_action.chameleon_blacklist = typecacheof(/obj/item/gun/magic, ignore_root_path = FALSE)
chameleon_action.initialize_disguises()
/obj/item/gun/energy/laser/chameleon/Initialize()
. = ..()
projectile_copy_vars = list("name", "icon", "icon_state", "item_state", "speed", "color", "hitsound", "forcedodge", "impact_effect_type", "range", "suppressed", "hitsound_wall", "impact_effect_type", "pass_flags")
chameleon_projectile_vars = list("name" = "practice laser", "icon" = 'icons/obj/projectiles.dmi', "icon_state" = "laser")
gun_copy_vars = list("fire_sound", "burst_size", "fire_delay")
@@ -505,8 +533,8 @@
name = "backpack"
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/storage/backpack/chameleon/New()
..()
/obj/item/storage/backpack/chameleon/Initialize()
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/storage/backpack
chameleon_action.chameleon_name = "Backpack"
@@ -515,14 +543,18 @@
/obj/item/storage/backpack/chameleon/emp_act(severity)
chameleon_action.emp_randomise()
/obj/item/storage/backpack/chameleon/broken/Initialize()
. = ..()
chameleon_action.emp_randomise(INFINITY)
/obj/item/storage/belt/chameleon
name = "toolbelt"
desc = "Holds tools."
silent = 1
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/storage/belt/chameleon/New()
..()
/obj/item/storage/belt/chameleon/Initialize()
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/storage/belt
chameleon_action.chameleon_name = "Belt"
@@ -531,6 +563,10 @@
/obj/item/storage/belt/chameleon/emp_act(severity)
chameleon_action.emp_randomise()
/obj/item/storage/belt/chameleon/broken/Initialize()
. = ..()
chameleon_action.emp_randomise(INFINITY)
/obj/item/device/radio/headset/chameleon
name = "radio headset"
var/datum/action/item_action/chameleon/change/chameleon_action
@@ -545,12 +581,16 @@
/obj/item/device/radio/headset/chameleon/emp_act(severity)
chameleon_action.emp_randomise()
/obj/item/device/radio/headset/chameleon/broken/Initialize()
. = ..()
chameleon_action.emp_randomise(INFINITY)
/obj/item/device/pda/chameleon
name = "PDA"
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/device/pda/chameleon/New()
..()
/obj/item/device/pda/chameleon/Initialize()
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/device/pda
chameleon_action.chameleon_name = "PDA"
@@ -560,3 +600,7 @@
/obj/item/device/pda/chameleon/emp_act(severity)
chameleon_action.emp_randomise()
/obj/item/device/pda/chameleon/broken/Initialize()
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -292,9 +292,9 @@
/obj/item/integrated_circuit/manipulation/grabber
name = "grabber"
desc = "A circuit with it's own inventory for tiny/small items, used to grab and store things."
desc = "A circuit which is used to grab and store tiny to small objects within it's self-contained inventory."
icon_state = "grabber"
extended_desc = "The circuit accepts a reference to thing to be grabbed. It can store up to 10 things. Modes: 1 for grab. 0 for eject the first thing. -1 for eject all."
extended_desc = "The circuit accepts a reference to an object to be grabbed and can store up to 10 objects. Modes: 1 to grab, 0 to eject the first object, and -1 to eject all objects."
w_class = WEIGHT_CLASS_SMALL
size = 3
@@ -3,6 +3,7 @@
pressure_resistance = 15
possible_a_intents = list(INTENT_HELP, INTENT_HARM)
hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD)
has_limbs = 1
var/list/stomach_contents = list()
var/list/internal_organs = list() //List of /obj/item/organ in the mob. They don't go in the contents for some reason I don't want to know.
var/list/internal_organs_slot= list() //Same as above, but stores "slot ID" - "organ" pairs for easy access.
@@ -33,7 +34,6 @@
var/co2overloadtime = null
var/temperature_resistance = T0C+75
has_limbs = 1
var/obj/item/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab
var/gib_type = /obj/effect/decal/cleanable/blood/gibs
@@ -57,3 +57,5 @@
var/obj/halitem
var/hal_screwyhud = SCREWYHUD_NONE
var/next_hallucination = 0
var/cpr_time = 1 //CPR cooldown.
var/damageoverlaytemp = 0
@@ -2,6 +2,8 @@
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD,GLAND_HUD)
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
pressure_resistance = 25
can_buckle = TRUE
buckle_lying = FALSE
//Hair colour and style
var/hair_color = "000"
var/hair_style = "Bald"
@@ -43,8 +45,7 @@
var/drunkenness = 0 //Overall drunkenness - check handle_alcohol() in life.dm for effects
var/datum/personal_crafting/handcrafting
can_buckle = TRUE
buckle_lying = FALSE
var/creamed = FALSE //to use with creampie overlays
var/static/list/can_ride_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot))
var/lastpuke = 0
+19
View File
@@ -5,6 +5,10 @@
hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD)
pressure_resistance = 10
var/resize = 1 //Badminnery resize
var/lastattacker = null
var/lastattackerckey = null
//Health and life related vars
var/maxHealth = 100 //Maximum health that should be possible.
var/health = 100 //A mob's health
@@ -17,10 +21,12 @@
var/cloneloss = 0 //Damage caused by being cloned or ejected from the cloner early. slimes also deal cloneloss damage to victims
var/staminaloss = 0 //Stamina damage, or exhaustion. You recover it slowly naturally, and are knocked down if it gets too high. Holodeck and hallucinations deal this.
var/confused = 0 //Makes the mob move in random directions.
var/hallucination = 0 //Directly affects how long a mob will hallucinate for
var/last_special = 0 //Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out.
var/timeofdeath = 0
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
var/incorporeal_move = FALSE //FALSE is off, INCORPOREAL_MOVE_BASIC is normal, INCORPOREAL_MOVE_SHADOW is for ninjas
@@ -69,7 +75,16 @@
var/blood_volume = 0 //how much blood the mob has
var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override
var/see_override = 0 //0 for no override, sets see_invisible = see_override in silicon & carbon life process via update_sight()
var/list/status_effects //a list of all status effects the mob has
var/druggy = 0
//Speech
var/stuttering = 0
var/slurring = 0
var/cultslurring = 0
var/derpspeech = 0
var/list/implants = null
@@ -83,3 +98,7 @@
var/registered_z
var/can_be_held = FALSE //whether this can be picked up and held.
var/radiation = 0 //If the mob is irradiated.
var/ventcrawl_layer = PIPING_LAYER_DEFAULT
var/losebreath = 0
+1 -25
View File
@@ -6,6 +6,7 @@
flags_1 = HEAR_1
hud_possible = list(ANTAG_HUD)
pressure_resistance = 8
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
var/datum/mind/mind
var/list/datum/action/actions = list()
@@ -22,10 +23,7 @@
*/
var/zone_selected = null
var/damageoverlaytemp = 0
var/computer_id = null
var/lastattacker = null
var/lastattackerckey = null
var/list/logging = list(INDIVIDUAL_ATTACK_LOG, INDIVIDUAL_SAY_LOG, INDIVIDUAL_EMOTE_LOG, INDIVIDUAL_OOC_LOG)
var/obj/machinery/machine = null
@@ -33,25 +31,15 @@
var/notransform = null //Carbon
var/eye_blind = 0 //Carbon
var/eye_blurry = 0 //Carbon
var/stuttering = 0 //Carbon
var/slurring = 0 //Carbon
var/cultslurring = 0 //Carbon
var/derpspeech = 0 //Carbon
var/real_name = null
var/spacewalk = FALSE
var/druggy = 0 //Carbon
var/confused = 0 //Carbon
var/resting = 0 //Carbon
var/lying = 0
var/lying_prev = 0
var/canmove = 1
var/lastpuke = 0
var/name_archive //For admin things like possession
var/timeofdeath = 0//Living
var/cpr_time = 1//Carbon
var/bodytemperature = BODYTEMP_NORMAL //310.15K / 98.6F
var/drowsyness = 0//Carbon
var/dizziness = 0//Carbon
@@ -60,7 +48,6 @@
var/satiety = 0//Carbon
var/overeatduration = 0 // How long this guy is overeating //Carbon
var/losebreath = 0//Carbon
var/a_intent = INTENT_HELP//Living
var/list/possible_a_intents = null//Living
var/m_intent = MOVE_INTENT_RUN//Living
@@ -75,8 +62,6 @@
var/obj/item/storage/s_active = null//Carbon
var/see_override = 0 //0 for no override, sets see_invisible = see_override in mob life process
var/datum/hud/hud_used = null
var/research_scanner = 0 //For research scanner equipped mobs. Enable to show research data when examining.
@@ -87,8 +72,6 @@
var/job = null//Living
var/radiation = 0//Carbon
var/list/faction = list("neutral") //A list of factions that this mob is currently in, for hostile mob targetting, amongst other things
var/move_on_shuttle = 1 // Can move on the shuttle.
@@ -104,9 +87,6 @@
var/list/viruses = list() // list of all diseases in a mob
var/list/resistances = list()
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
var/status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH //bitflags defining which status effects can be inflicted (replaces canknockdown, canstun, etc)
var/digitalcamo = 0 // Can they be tracked by the AI?
@@ -121,12 +101,8 @@
var/turf/listed_turf = null //the current turf being examined in the stat panel
var/resize = 1 //Badminnery resize
var/list/observers = null //The list of people observing this mob.
var/list/progressbars = null //for stacking do_after bars
var/list/mousemove_intercept_objects
var/ventcrawl_layer = PIPING_LAYER_DEFAULT
+5 -5
View File
@@ -89,17 +89,17 @@
move_delay = world.time
var/oldloc = mob.loc
if(mob.confused)
if(L.confused)
var/newdir = 0
if(mob.confused > 40)
if(L.confused > 40)
newdir = pick(GLOB.alldirs)
else if(prob(mob.confused * 1.5))
else if(prob(L.confused * 1.5))
newdir = angle2dir(dir2angle(direct) + pick(90, -90))
else if(prob(mob.confused * 3))
else if(prob(L.confused * 3))
newdir = angle2dir(dir2angle(direct) + pick(45, -45))
if(newdir)
direct = newdir
n = get_step(mob, direct)
n = get_step(L, direct)
. = ..()
+122 -111
View File
@@ -1,111 +1,122 @@
/obj/item/stamp
name = "\improper GRANTED rubber stamp"
desc = "A rubber stamp for stamping important documents."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "stamp-ok"
item_state = "stamp"
throwforce = 0
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=60)
item_color = "cargo"
pressure_resistance = 2
attack_verb = list("stamped")
/obj/item/stamp/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] stamps 'VOID' on [user.p_their()] forehead, then promptly falls over, dead.</span>")
return (OXYLOSS)
/obj/item/stamp/qm
name = "quartermaster's rubber stamp"
icon_state = "stamp-qm"
item_color = "qm"
/obj/item/stamp/law
name = "law office's rubber stamp"
icon_state = "stamp-law"
item_color = "cargo"
/obj/item/stamp/captain
name = "captain's rubber stamp"
icon_state = "stamp-cap"
item_color = "captain"
/obj/item/stamp/hop
name = "head of personnel's rubber stamp"
icon_state = "stamp-hop"
item_color = "hop"
/obj/item/stamp/hos
name = "head of security's rubber stamp"
icon_state = "stamp-hos"
item_color = "hosred"
/obj/item/stamp/ce
name = "chief engineer's rubber stamp"
icon_state = "stamp-ce"
item_color = "chief"
/obj/item/stamp/rd
name = "research director's rubber stamp"
icon_state = "stamp-rd"
item_color = "director"
/obj/item/stamp/cmo
name = "chief medical officer's rubber stamp"
icon_state = "stamp-cmo"
item_color = "cmo"
/obj/item/stamp/denied
name = "\improper DENIED rubber stamp"
icon_state = "stamp-deny"
item_color = "redcoat"
/obj/item/stamp/clown
name = "clown's rubber stamp"
icon_state = "stamp-clown"
item_color = "clown"
/obj/item/stamp/attack_paw(mob/user)
return attack_hand(user)
// Syndicate stamp to forge documents.
/obj/item/stamp/chameleon
actions_types = list(/datum/action/item_action/toggle)
var/list/stamp_types
var/list/stamp_names
/obj/item/stamp/chameleon/Initialize()
. = ..()
stamp_types = typesof(/obj/item/stamp) - type // Get all stamp types except our own
stamp_names = list()
// Generate them into a list
for(var/i in stamp_types)
var/obj/item/stamp/stamp_type = i
stamp_names += initial(stamp_type.name)
stamp_names = sortList(stamp_names)
/obj/item/stamp/chameleon/emp_act(severity)
change_to(pick(stamp_types))
/obj/item/stamp/chameleon/proc/change_to(obj/item/stamp/stamp_type)
name = initial(stamp_type.name)
icon_state = initial(stamp_type.icon_state)
item_color = initial(stamp_type.item_color)
/obj/item/stamp/chameleon/attack_self(mob/user)
var/input_stamp = input(user, "Choose a stamp to disguise as.",
"Choose a stamp.") as null|anything in stamp_names
if(user && (src in user.contents) && input_stamp)
var/obj/item/stamp/stamp_type
for(var/i in stamp_types)
stamp_type = i
if(initial(stamp_type.name) == input_stamp)
break
change_to(stamp_type)
/obj/item/stamp
name = "\improper GRANTED rubber stamp"
desc = "A rubber stamp for stamping important documents."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "stamp-ok"
item_state = "stamp"
throwforce = 0
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=60)
item_color = "cargo"
pressure_resistance = 2
attack_verb = list("stamped")
/obj/item/stamp/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] stamps 'VOID' on [user.p_their()] forehead, then promptly falls over, dead.</span>")
return (OXYLOSS)
/obj/item/stamp/qm
name = "quartermaster's rubber stamp"
icon_state = "stamp-qm"
item_color = "qm"
/obj/item/stamp/law
name = "law office's rubber stamp"
icon_state = "stamp-law"
item_color = "cargo"
/obj/item/stamp/captain
name = "captain's rubber stamp"
icon_state = "stamp-cap"
item_color = "captain"
/obj/item/stamp/hop
name = "head of personnel's rubber stamp"
icon_state = "stamp-hop"
item_color = "hop"
/obj/item/stamp/hos
name = "head of security's rubber stamp"
icon_state = "stamp-hos"
item_color = "hosred"
/obj/item/stamp/ce
name = "chief engineer's rubber stamp"
icon_state = "stamp-ce"
item_color = "chief"
/obj/item/stamp/rd
name = "research director's rubber stamp"
icon_state = "stamp-rd"
item_color = "director"
/obj/item/stamp/cmo
name = "chief medical officer's rubber stamp"
icon_state = "stamp-cmo"
item_color = "cmo"
/obj/item/stamp/denied
name = "\improper DENIED rubber stamp"
icon_state = "stamp-deny"
item_color = "redcoat"
/obj/item/stamp/clown
name = "clown's rubber stamp"
icon_state = "stamp-clown"
item_color = "clown"
/obj/item/stamp/attack_paw(mob/user)
return attack_hand(user)
// Syndicate stamp to forge documents.
/obj/item/stamp/chameleon
actions_types = list(/datum/action/item_action/toggle)
var/list/stamp_types
var/list/stamp_names
/obj/item/stamp/chameleon/Initialize()
. = ..()
stamp_types = typesof(/obj/item/stamp) - type // Get all stamp types except our own
stamp_names = list()
// Generate them into a list
for(var/i in stamp_types)
var/obj/item/stamp/stamp_type = i
stamp_names += initial(stamp_type.name)
stamp_names = sortList(stamp_names)
/obj/item/stamp/chameleon/emp_act(severity)
change_to(pick(stamp_types))
/obj/item/stamp/chameleon/proc/change_to(obj/item/stamp/stamp_type)
name = initial(stamp_type.name)
icon_state = initial(stamp_type.icon_state)
item_color = initial(stamp_type.item_color)
/obj/item/stamp/chameleon/attack_self(mob/user)
var/input_stamp = input(user, "Choose a stamp to disguise as.",
"Choose a stamp.") as null|anything in stamp_names
if(user && (src in user.contents) && input_stamp)
var/obj/item/stamp/stamp_type
for(var/i in stamp_types)
stamp_type = i
if(initial(stamp_type.name) == input_stamp)
break
change_to(stamp_type)
/obj/item/stamp/chameleon/broken/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
/obj/item/stamp/chameleon/broken/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/stamp/chameleon/broken/process()
change_to(pick(stamp_types))
@@ -28,7 +28,7 @@
return
for(var/V in mother.map)
var/turf/T = V
T.empty(deleteturfs? null : T.type, ignore_typecache = ignore_typecache, forceop = TRUE)
T.empty(deleteturfs? null : T.type, null, ignore_typecache, CHANGETURF_FORCEOP)
/datum/mapGeneratorModule/bottomLayer/massdelete/no_delete_mobs/New()
..()
@@ -126,6 +126,8 @@
sharpness = IS_SHARP
can_charge = 0
heat = 3800
usesound = 'sound/items/welder.ogg'
toolspeed = 0.7 //plasmacutters can be used as welders for a few things, and are faster than standard welders
/obj/item/gun/energy/plasmacutter/examine(mob/user)
@@ -1281,3 +1281,19 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "glass_yellow"
glass_name = "eggnog"
glass_desc = "For enjoying the most wonderful time of the year."
/datum/reagent/consumable/ethanol/narsour
name = "Nar'Sour"
id = "narsour"
description = "Side effects include self-mutilation and hoarding plasteel."
color = RUNE_COLOR_DARKRED
boozepwr = 10
taste_description = "bloody"
glass_icon_state = "narsour"
glass_name = "Nar'Sour"
glass_desc = "A new hit cocktail inspired by THE ARM Breweries will have you shouting Fuu ma'jin in no time!"
/datum/reagent/consumable/ethanol/narsour/on_mob_life(mob/living/M)
M.cultslurring = min(M.cultslurring + 3, 3)
M.stuttering = min(M.stuttering + 3, 3)
..()
@@ -1147,6 +1147,8 @@
addiction_threshold = 5
/datum/reagent/medicine/ketrazine/on_mob_life(mob/living/M)
M.status_flags |= IGNORESLOWDOWN
M.status_flags |= GOTTAGOFAST
M.adjustToxLoss(-3*REM, 0)
M.adjustBruteLoss(-5*REM, 0)
M.adjustFireLoss(-5*REM, 0)
@@ -1243,4 +1245,3 @@
M.Dizzy(7)
M.Jitter(7)
..()
@@ -244,8 +244,10 @@
toxpwr = 1
/datum/reagent/toxin/spore/on_mob_life(mob/living/M)
M.damageoverlaytemp = 60
M.update_damage_hud()
if(iscarbon(M))
var/mob/living/carbon/C = M
C.damageoverlaytemp = 60
C.update_damage_hud()
M.blur_eyes(3)
return ..()
@@ -232,4 +232,13 @@
id = "morphine"
results = list("morphine" = 3)
required_reagents = list("carbon" = 2, "hydrogen" = 2, "nitrogen" = 1, "oxygen" = 1)
required_temp = 480
required_temp = 480
/datum/chemical_reaction/ketrazine
name = "Ketrazine"
id = "ketrazine"
results = list("ketrazine" = 3)
required_reagents = list("epinephrine" = 1, "ephedrine" = 1, "tricordazine" = 1, "atropine" = 1)
required_catalysts = list("gold" = 1)
required_temp = 520
mix_message = "The solution fizzes and then settles into an oily, smooth, purple liquid."
+2 -2
View File
@@ -248,7 +248,7 @@
var/launch_status = NOLAUNCH
var/list/movement_force = list("KNOCKDOWN" = 3, "THROW" = 0)
var/list/movement_force = list("KNOCKDOWN" = 3, "THROW" = 2)
// A timid shuttle will not register itself with the shuttle subsystem
// All shuttle templates are timid
@@ -745,4 +745,4 @@
mode = SHUTTLE_ENDGAME
/obj/docking_port/mobile/emergency/on_emergency_dock()
return
return
+27 -13
View File
@@ -714,10 +714,6 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
exclude_modes = list(/datum/game_mode/nuclear)
player_minimum = 20
/datum/uplink_item/stealthy_tools/chameleon/nuke
cost = 6
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/stealthy_tools/syndigaloshes
name = "No-Slip Chameleon Shoes"
desc = "These shoes will allow the wearer to run on wet floors and slippery objects without falling down. \
@@ -727,6 +723,12 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
exclude_modes = list(/datum/game_mode/nuclear)
player_minimum = 20
/datum/uplink_item/stealthy_tools/syndigaloshes/nuke
item = /obj/item/clothing/shoes/chameleon
cost = 4
exclude_modes = list()
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/stealthy_tools/frame
name = "F.R.A.M.E. PDA Cartridge"
desc = "When inserted into a personal digital assistant, this cartridge gives you five PDA viruses which \
@@ -736,15 +738,6 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
item = /obj/item/cartridge/virus/frame
cost = 4
/datum/uplink_item/stealthy_tools/syndigaloshes/nuke
name = "Stealthy No-Slip Chameleon Shoes"
desc = "These shoes will allow the wearer to run on wet floors and slippery objects without falling down. \
They do not work on heavily lubricated surfaces. The manufacturer claims they are much more stealthy than the normal brand."
item = /obj/item/clothing/shoes/chameleon
cost = 4
exclude_modes = list()
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/stealthy_tools/agent_card
name = "Agent Identification Card"
desc = "Agent cards prevent artificial intelligences from tracking the wearer, and can copy access \
@@ -1328,6 +1321,27 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
cost = 20
cant_discount = TRUE
/datum/uplink_item/badass/costumes
surplus = 0
include_modes = list(/datum/game_mode/nuclear)
cost = 4
cant_discount = TRUE
/datum/uplink_item/badass/costumes/centcom_official
name = "Centcom Official Costume"
desc = "Ask the crew to \"inspect\" their nuclear disk and weapons system, and then when they decline, pull out a fully automatic rifle and gun down the Captain. Radio headset does not include key. No gun included."
item = /obj/item/storage/box/syndie_kit/centcom_costume
/datum/uplink_item/badass/costumes/clown
name = "Clown Costume"
desc = "Nothing is more terrifying than clowns with fully automatic weaponry."
item = /obj/item/storage/backpack/duffelbag/clown/syndie
/datum/uplink_item/badass/costumes/obvious_chameleon
name = "Broken Chameleon Kit"
desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! Please note that this kit did NOT pass quality control."
item = /obj/item/storage/box/syndie_kit/chameleon/broken
/datum/uplink_item/badass/bundle
name = "Syndicate Bundle"
desc = "Syndicate Bundles are specialized groups of items that arrive in a plain box. \
@@ -0,0 +1,4 @@
author: "Robustin"
delete-after: True
changes:
- rscadd: "A new cocktail: The Nar'Sour. Made from blood, demonsblood, and lemon juice, this cocktail is known to induce a slightly different type of slurring when imbibed."
@@ -0,0 +1,6 @@
author: "Robustin"
delete-after: True
changes:
- balance: "Clockwork marauders now take more time (+3s) and power (7x) to create."
- balance: "The \"recent marauder\" time limit is now 60 seconds, up from 20. The limit now has a significantly smaller effect on summon time but will act as a further cap on marauder summoning until it has passed."
- tweak: "The marauder cap will now only account for living cultists."
@@ -0,0 +1,6 @@
author: "Xhuis"
delete-after: True
changes:
- balance: "Fleshmend can no longer be stacked several times at once."
- balance: "Fleshmend no longer heals changelings who are on fire, and heals burn damage half as quickly as brute and oxygen damage."
- code_imp: "Fleshmend has been refactored into a status effect."
@@ -0,0 +1,6 @@
author: "coiax"
delete-after: True
changes:
- rscadd: "Nuclear operatives that wish to fail in style can purchase Centcom
Official and Clown costumes. They can also buy a defective chameleon
kit."
@@ -0,0 +1,4 @@
author: "Ordo"
delete-after: True
changes:
- rscadd: "Adds Ketrazine, a powerful but dangerous combat stim which the crew can synthesize"
@@ -0,0 +1,4 @@
author: "Dax Dupont"
delete-after: True
changes:
- imageadd: "Autolathe now repeats it's animation while printing."
@@ -0,0 +1,4 @@
author: "SPACE CONDUCTOR"
delete-after: True
changes:
- tweak: "Shuttles will throw you around if ya don't buckle in"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

@@ -179,7 +179,9 @@ function set_labels($payload, $labels, $remove) {
$tags = array_merge($labels, $existing);
$tags = array_unique($tags);
$tags = array_diff($tags, $remove);
if($remove) {
$tags = array_diff($tags, $remove);
}
$final = array();
foreach($tags as $t)