diff --git a/code/datums/action.dm b/code/datums/action.dm
index f14945fa247..6a6376659d9 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -345,6 +345,19 @@
/datum/action/item_action/change
name = "Change"
+/datum/action/item_action/nano_picket_sign
+ name = "Retext Nano Picket Sign"
+ var/obj/item/picket_sign/S
+
+/datum/action/item_action/nano_picket_sign/New(Target)
+ ..()
+ if(istype(Target, /obj/item/picket_sign))
+ S = Target
+
+/datum/action/item_action/nano_picket_sign/Trigger()
+ if(istype(S))
+ S.retext(owner)
+
/datum/action/item_action/adjust
/datum/action/item_action/adjust/New(Target)
diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm
index 916e6ba500a..3e322ea0fa1 100644
--- a/code/game/objects/items/cosmetics.dm
+++ b/code/game/objects/items/cosmetics.dm
@@ -8,7 +8,6 @@
var/colour = "red"
var/open = FALSE
-
/obj/item/lipstick/purple
name = "purple lipstick"
colour = "purple"
@@ -22,7 +21,6 @@
name = "black lipstick"
colour = "black"
-
/obj/item/lipstick/random
name = "lipstick"
icon_state = "random_lipstick"
@@ -33,8 +31,6 @@
colour = pick("red","purple","lime","black","green","blue","white")
name = "[colour] lipstick"
-
-
/obj/item/lipstick/attack_self(mob/user)
cut_overlays()
to_chat(user, "You twist \the [src] [open ? "closed" : "open"].")
@@ -103,7 +99,6 @@
else
..()
-
/obj/item/razor
name = "electric razor"
desc = "The latest and greatest power razor born from the science of shaving."
@@ -112,7 +107,6 @@
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_TINY
-
/obj/item/razor/proc/shave(mob/living/carbon/human/H, location = "mouth")
if(location == "mouth")
H.facial_hair_style = "Shaved"
diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm
index 5af62e093b7..dc0a2fe286a 100644
--- a/code/game/objects/items/pneumaticCannon.dm
+++ b/code/game/objects/items/pneumaticCannon.dm
@@ -125,14 +125,14 @@
loadedWeightClass += I.w_class
return TRUE
-/obj/item/pneumatic_cannon/afterattack(atom/target, mob/living/carbon/human/user, flag, params)
+/obj/item/pneumatic_cannon/afterattack(atom/target, mob/living/user, flag, params)
if(flag && user.a_intent == INTENT_HARM) //melee attack
return
if(!istype(user))
return
Fire(user, target)
-/obj/item/pneumatic_cannon/proc/Fire(mob/living/carbon/human/user, var/atom/target)
+/obj/item/pneumatic_cannon/proc/Fire(mob/living/user, var/atom/target)
if(!istype(user) && !target)
return
var/discharge = 0
@@ -147,9 +147,10 @@
if(tank && !tank.air_contents.remove(gasPerThrow * pressureSetting))
to_chat(user, "\The [src] lets out a weak hiss and doesn't react!")
return
- if(user.has_disability(CLUMSY) && prob(75) && clumsyCheck)
- user.visible_message("[user] loses their grip on [src], causing it to go off!", "[src] slips out of your hands and goes off!")
- user.dropItemToGround(src, TRUE)
+ if(user.has_disability(CLUMSY) && prob(75) && clumsyCheck && iscarbon(user))
+ var/mob/living/carbon/C = user
+ C.visible_message("[C] loses their grip on [src], causing it to go off!", "[src] slips out of your hands and goes off!")
+ C.dropItemToGround(src, TRUE)
if(prob(10))
target = get_turf(user)
else
@@ -163,9 +164,10 @@
var/turf/T = get_target(target, get_turf(src))
playsound(src.loc, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
fire_items(T, user)
- if(pressureSetting >= 3 && user)
- user.visible_message("[user] is thrown down by the force of the cannon!", "[src] slams into your shoulder, knocking you down!")
- user.Knockdown(60)
+ if(pressureSetting >= 3 && iscarbon(user))
+ var/mob/living/carbon/C = user
+ C.visible_message("[C] is thrown down by the force of the cannon!", "[src] slams into your shoulder, knocking you down!")
+ C.Knockdown(60)
/obj/item/pneumatic_cannon/proc/fire_items(turf/target, mob/user)
if(fire_mode == PCANNON_FIREALL)
@@ -271,3 +273,10 @@
selfcharge = TRUE
charge_type = /obj/item/reagent_containers/food/snacks/pie/cream
maxWeightClass = 60 //20 pies.
+
+/obj/item/pneumatic_cannon/pie/selfcharge/cyborg
+ name = "low velocity pie cannon"
+ automatic = FALSE
+ charge_type = /obj/item/reagent_containers/food/snacks/pie/cream/nostun
+ maxWeightClass = 6 //2 pies
+ charge_ticks = 2 //4 second/pie
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index 614989b7072..aae0937bb72 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -355,6 +355,9 @@
var/hitdamage = 0
var/emaggedhitdamage = 3
+/obj/item/borg/lollipop/clown
+ emaggedhitdamage = 0
+
/obj/item/borg/lollipop/equipped()
check_amount()
diff --git a/code/game/objects/items/signs.dm b/code/game/objects/items/signs.dm
index 350daa0fc3f..65716f2f305 100644
--- a/code/game/objects/items/signs.dm
+++ b/code/game/objects/items/signs.dm
@@ -10,13 +10,23 @@
var/label = ""
var/last_wave = 0
+/obj/item/picket_sign/cyborg
+ name = "metallic nano-sign"
+ desc = "A high tech picket sign used by silicons that can reprogram its surface at will. Probably hurts to get hit by, too."
+ force = 13
+ resistance_flags = NONE
+ actions_types = list(/datum/action/item_action/nano_picket_sign)
+
+/obj/item/picket_sign/proc/retext(mob/user)
+ var/txt = stripped_input(user, "What would you like to write on the sign?", "Sign Label", null , 30)
+ if(txt && Adjacent(user))
+ label = txt
+ name = "[label] sign"
+ desc = "It reads: [label]"
+
/obj/item/picket_sign/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pen) || istype(W, /obj/item/toy/crayon))
- var/txt = stripped_input(user, "What would you like to write on the sign?", "Sign Label", null , 30)
- if(txt)
- label = txt
- src.name = "[label] sign"
- desc = "It reads: [label]"
+ retext(user)
else
return ..()
diff --git a/code/modules/food_and_drinks/food/snacks_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm
index 1255b16f1ec..4ce942aadf8 100644
--- a/code/modules/food_and_drinks/food/snacks_pie.dm
+++ b/code/modules/food_and_drinks/food/snacks_pie.dm
@@ -27,6 +27,7 @@
list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2)
tastes = list("pie" = 1)
foodtype = GRAIN | DAIRY | SUGAR
+ var/stunning = TRUE
/obj/item/reagent_containers/food/snacks/pie/cream/throw_impact(atom/hit_atom)
. = ..()
@@ -46,15 +47,18 @@
creamoverlay.icon_state = "creampie_lizard"
else
creamoverlay.icon_state = "creampie_human"
- H.Knockdown(20) //splat!
+ if(stunning)
+ H.Knockdown(20) //splat!
H.adjust_blurriness(1)
H.visible_message("[H] is creamed by [src]!", "You've been creamed by [src]!")
playsound(H, "desceration", 50, TRUE)
- if (!H.creamed) // one layer at a time
+ if(!H.creamed) // one layer at a time
H.add_overlay(creamoverlay)
H.creamed = TRUE
qdel(src)
+/obj/item/reagent_containers/food/snacks/pie/cream/nostun
+ stunning = FALSE
/obj/item/reagent_containers/food/snacks/pie/berryclafoutis
name = "berry clafoutis"
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index be8607fc7b5..0a099443ddc 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -786,6 +786,9 @@
/mob/living/silicon/robot/modules/security
set_module = /obj/item/robot_module/security
+/mob/living/silicon/robot/modules/clown
+ set_module = /obj/item/robot_module/clown
+
/mob/living/silicon/robot/modules/peacekeeper
set_module = /obj/item/robot_module/peacekeeper
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 3359ce75d30..84f90a0c6df 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -424,6 +424,37 @@
if(CL)
CL.reagents.add_reagent("lube", 2 * coeff)
+/obj/item/robot_module/clown
+ name = "Clown"
+ basic_modules = list(
+ /obj/item/device/assembly/flash/cyborg,
+ /obj/item/toy/crayon/rainbow,
+ /obj/item/device/instrument/bikehorn,
+ /obj/item/stamp/clown,
+ /obj/item/bikehorn,
+ /obj/item/bikehorn/airhorn,
+ /obj/item/paint/anycolor,
+ /obj/item/soap/nanotrasen,
+ /obj/item/pneumatic_cannon/pie/selfcharge/cyborg,
+ /obj/item/razor, //killbait material
+ /obj/item/lipstick/purple,
+ /obj/item/reagent_containers/spray/waterflower/cyborg,
+ /obj/item/borg/cyborghug/peacekeeper,
+ /obj/item/borg/lollipop/clown,
+ /obj/item/picket_sign/cyborg,
+ /obj/item/reagent_containers/borghypo/clown,
+ /obj/item/extinguisher/mini)
+ emag_modules = list(
+ /obj/item/reagent_containers/borghypo/clown/hacked,
+ /obj/item/reagent_containers/spray/waterflower/cyborg/hacked)
+ ratvar_modules = list(
+ /obj/item/clockwork/slab/cyborg,
+ /obj/item/clockwork/weapon/ratvarian_spear,
+ /obj/item/clockwork/replica_fabricator/cyborg)
+ moduleselect_icon = "service"
+ cyborg_base_icon = "clown"
+ hat_offset = -2
+
/obj/item/robot_module/butler
name = "Service"
basic_modules = list(
diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
index b164fc0696d..0bb00f5b49c 100644
--- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
@@ -172,6 +172,22 @@
M.emote("laugh")
..()
+/datum/reagent/consumable/superlaughter
+ name = "Super Laughter"
+ id = "superlaughter"
+ description = "Funny until you're the one laughing."
+ metabolization_rate = 1.5 * REAGENTS_METABOLISM
+ color = "#FF4DD2"
+ taste_description = "laughter"
+
+/datum/reagent/consumable/superlaughter/on_mob_life(mob/living/carbon/M)
+ if(!iscarbon(M))
+ return
+ if(prob(30))
+ M.visible_message("[M] bursts out into a fit of uncontrollable laughter!", "You burst out in a fit of uncontrollable laughter!")
+ M.Stun(5)
+ ..()
+
/datum/reagent/consumable/potato_juice
name = "Potato Juice"
id = "potato"
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index 0a99d9da6ec..e736c344db1 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -130,6 +130,18 @@ Borg Hypospray
reagent_ids = list ("facid", "mutetoxin", "cyanide", "sodium_thiopental", "heparin", "lexorin")
accepts_reagent_upgrades = FALSE
+/obj/item/reagent_containers/borghypo/clown
+ name = "laughter injector"
+ desc = "Keeps the crew happy and productive!"
+ reagent_ids = list("laughter")
+ accepts_reagent_upgrades = FALSE
+
+/obj/item/reagent_containers/borghypo/clown/hacked
+ name = "laughter injector"
+ desc = "Keeps the crew so happy they don't work!"
+ reagent_ids = list("superlaughter")
+ accepts_reagent_upgrades = FALSE
+
/obj/item/reagent_containers/borghypo/syndicate
name = "syndicate cyborg hypospray"
desc = "An experimental piece of Syndicate technology used to produce powerful restorative nanites used to very quickly restore injuries of all types. Also metabolizes potassium iodide, for radiation poisoning, and morphine, for offense."
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index 000537befdc..87d5a4bb671 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -18,16 +18,16 @@
var/spray_range = 3 //the range of tiles the sprayer will reach when in spray mode.
var/stream_range = 1 //the range of tiles the sprayer will reach when in stream mode.
var/stream_amount = 10 //the amount of reagents transfered when in stream mode.
+ var/can_fill_from_container = TRUE
amount_per_transfer_from_this = 5
volume = 250
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
-
/obj/item/reagent_containers/spray/afterattack(atom/A, mob/user)
if(istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics))
return
- if((A.is_drainable() && !A.is_refillable()) && get_dist(src,A) <= 1)
+ if((A.is_drainable() && !A.is_refillable()) && get_dist(src,A) <= 1 && can_fill_from_container)
if(!A.reagents.total_volume)
to_chat(user, "[A] is empty.")
return
@@ -204,6 +204,46 @@
/obj/item/reagent_containers/spray/waterflower/attack_self(mob/user) //Don't allow changing how much the flower sprays
return
+/obj/item/reagent_containers/spray/waterflower/cyborg
+ container_type = NONE
+ volume = 100
+ list_reagents = list("water" = 100)
+ var/generate_amount = 5
+ var/generate_type = "water"
+ var/last_generate = 0
+ var/generate_delay = 10 //deciseconds
+ can_fill_from_container = FALSE
+
+/obj/item/reagent_containers/spray/waterflower/cyborg/hacked
+ name = "nova flower"
+ desc = "This doesn't look safe at all..."
+ list_reagents = list("clf3" = 3)
+ volume = 3
+ generate_type = "clf3"
+ generate_amount = 1
+ generate_delay = 40 //deciseconds
+
+/obj/item/reagent_containers/spray/waterflower/cyborg/Initialize()
+ . = ..()
+ START_PROCESSING(SSfastprocess, src)
+
+/obj/item/reagent_containers/spray/waterflower/cyborg/Destroy()
+ STOP_PROCESSING(SSfastprocess, src)
+ return ..()
+
+/obj/item/reagent_containers/spray/waterflower/cyborg/process()
+ if(world.time > last_generate + generate_delay)
+ return
+ last_generate = world.time
+ generate_reagents()
+
+/obj/item/reagent_containers/spray/waterflower/cyborg/empty()
+ to_chat(usr, "You can not empty this!")
+ return
+
+/obj/item/reagent_containers/spray/waterflower/cyborg/proc/generate_reagents()
+ reagents.add_reagent(generate_type, generate_amount)
+
//chemsprayer
/obj/item/reagent_containers/spray/chemsprayer
name = "chem sprayer"
diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi
index 5d8bfa629b1..fd145092a75 100644
Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ